Recent

Author Topic: Basic Text Editor Problem  (Read 3345 times)

db32

  • Newbie
  • Posts: 6
Basic Text Editor Problem
« on: April 13, 2020, 11:46:49 am »
Hello, first time post! first time programming aswell, I think it's pretty cool so far I'm enjoying it but I'm very stuck right now.

I'm following a tutorial http://lazplanet.blogspot.com/2013/12/create-rich-text-editor-for-yourself.html.

I cant seem to have the editor change fonts and right here is where the problem is, I think.
Code: Pascal  [Select][+][-]
  1.   procedure TForm2.cboFontSelect(Sender: TObject);
  2.   begin
  3.     SelFontFormat.Name:=cboFont.Items[cboFont.ItemIndex];
  4.     RichMemo1.SetTextAttributes(RichMemo1.SelStart, RichMemo1.SelLength, SelFontFormat);
  5.     RichMemo1.SetFocus; // get focus to the rich memo
  6.   end;  

Experimenting with this I changed RichMemo1.SelStart and RichMemo1.SelLength and I can get the font to change within the integer range but what I want is to select a font and then begin writing in that font. It is not changing the font at all the way it is. The bold, italics and underline buttons do the same thing aswell.

Here's all the code if you need it. Any help would be appreciated!
Code: Pascal  [Select][+][-]
  1. unit Unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls,
  9.   ExtCtrls, Spin, RichMemo;
  10.  
  11. type
  12.  
  13.   { TForm2 }
  14.  
  15.   TForm2 = class(TForm)
  16.     Button1: TButton;
  17.     cboFont: TComboBox;
  18.     ImageList1: TImageList;
  19.     Label1: TLabel;
  20.     Label2: TLabel;
  21.     OpenDialog1: TOpenDialog;
  22.     Panel1: TPanel;
  23.     Panel2: TPanel;
  24.     RichMemo1: TRichMemo;
  25.     SaveDialog1: TSaveDialog;
  26.     SpinEdit1: TSpinEdit;
  27.     StatusBar1: TStatusBar;
  28.     TabControl1: TTabControl;
  29.     ToolBar1: TToolBar;
  30.     btnNew: TToolButton;
  31.     btnOpen: TToolButton;
  32.     btnSave: TToolButton;
  33.     Seperate: TToolButton;
  34.     BtnBold: TToolButton;
  35.     BtnItalic: TToolButton;
  36.     BtnUnderline: TToolButton;
  37.     procedure BtnBoldClick(Sender: TObject);
  38.     procedure BtnItalicClick(Sender: TObject);
  39.     procedure btnNewClick(Sender: TObject);
  40.     procedure btnOpenClick(Sender: TObject);
  41.     procedure btnSaveClick(Sender: TObject);
  42.     procedure BtnUnderlineClick(Sender: TObject);
  43.     procedure Button1Click(Sender: TObject);
  44.     procedure cboFontSelect(Sender: TObject);
  45.     procedure cboFontSizeSelect(Sender: TObject);
  46.     procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
  47.     procedure FormCreate(Sender: TObject);
  48.     procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  49.     procedure RichMemo1Change(Sender: TObject);
  50.     procedure PrepareToolbar();
  51.     procedure RichMemo1Click(Sender: TObject);
  52.     procedure SpinEdit1Change(Sender: TObject);
  53.   private
  54.  
  55.   public
  56.  
  57.   end;
  58.  
  59. var
  60.   SelFontFormat: TFontParams;
  61.   Form2: TForm2;
  62.   Filename: String = 'Untitled';
  63.   Filepath: String;
  64.   Saved: Boolean;
  65.  
  66.   implementation
  67. {$R *.lfm}
  68.  
  69. { TForm2 }
  70.  
  71.  
  72.  procedure TForm2.PrepareToolbar();
  73. var
  74.   Down: Boolean;
  75. begin
  76.   cboFont.Caption:=SelFontFormat.Name;
  77.   SpinEdit1.Caption:=inttostr(SelFontFormat.Size);
  78.  
  79.   if (fsBold in SelFontFormat.Style = true) then
  80.     btnBold.Down:=True
  81.   else
  82.     btnBold.Down:=False;
  83.  
  84.   if (fsItalic in SelFontFormat.Style = true) then
  85.     btnItalic.Down:=True
  86.   else
  87.     btnItalic.Down:=False;
  88.  
  89.   if (fsUnderline in SelFontFormat.Style = true) then
  90.     btnUnderline.Down:=True
  91.   else
  92.     btnUnderline.Down:=False;
  93. end;
  94.  
  95. procedure TForm2.RichMemo1Click(Sender: TObject);
  96. begin
  97. RichMemo1.GetTextAttributes(RichMemo1.SelStart, SelFontFormat);
  98.   PrepareToolbar;
  99. end;
  100.  
  101. procedure TForm2.SpinEdit1Change(Sender: TObject);
  102. begin
  103.  
  104. end;
  105.  
  106.   procedure TForm2.cboFontSelect(Sender: TObject);
  107.   begin
  108.     SelFontFormat.Name:=cboFont.Items[cboFont.ItemIndex];
  109.     RichMemo1.SetTextAttributes(RichMemo1.SelStart, RichMemo1.SelLength, SelFontFormat);
  110.     RichMemo1.SetFocus; // get focus to the rich memo
  111.   end;
  112.  
  113. procedure TForm2.cboFontSizeSelect(Sender: TObject);
  114. begin
  115.  
  116. end;
  117.  
  118. procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: boolean);
  119.    var
  120.   Response: Integer;
  121. begin
  122.  
  123.   if not Saved then begin
  124.  
  125.     Response:=MessageDlg('Save?', 'Do you wish to Save?',
  126.               mtConfirmation, mbYesNoCancel,0);
  127.  
  128.     if Response = mrYes then begin
  129.       btnSaveClick(Sender); // we save it
  130.       CanClose:=True; // we let it close
  131.     end else if Response = mrNo then begin
  132.       CanClose:=True; // we let it close (but not save)
  133.     end else begin
  134.       CanClose:=False; // we don't need to close
  135.     end;
  136.  
  137.   end;
  138.  
  139. end;
  140.  
  141. procedure TForm2.FormCreate(Sender: TObject);
  142. begin
  143.   cboFont.Items.Assign(Screen.Fonts);
  144.   cboFont.ItemIndex:=0;
  145. end;
  146.  
  147. procedure TForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  148.   Y: Integer);
  149. begin
  150.     RichMemo1.GetTextAttributes(RichMemo1.SelStart, SelFontFormat);
  151.   PrepareToolbar;
  152. end;
  153.  
  154.  
  155. procedure TForm2.btnNewClick(Sender: TObject);
  156. begin
  157.   RichMemo1.Clear;
  158.   Saved:=False;
  159.   Filename:='Untitled.rtf';
  160.   Filepath:='';
  161.   Caption:=Filename;
  162. end;
  163.  
  164. procedure TForm2.BtnBoldClick(Sender: TObject);
  165. begin
  166. if (fsBold in SelFontFormat.Style = False) then
  167. SelFontFormat.Style:=SelFontFormat.Style + [fsBold]
  168.   else
  169.    SelFontFormat.Style:=SelFontFormat.Style - [fsBold];
  170.  
  171.   RichMemo1.SetTextAttributes(RichMemo1.SelStart,
  172.               RichMemo1.SelLength, SelFontFormat);
  173. end;
  174.  
  175. procedure TForm2.BtnItalicClick(Sender: TObject);
  176. begin
  177.      if (fsItalic in SelFontFormat.Style = False) then
  178.     SelFontFormat.Style:=SelFontFormat.Style + [fsItalic]
  179.   else
  180.     SelFontFormat.Style:=SelFontFormat.Style - [fsItalic];
  181.  
  182.   RichMemo1.SetTextAttributes(RichMemo1.SelStart,
  183.               RichMemo1.SelLength, SelFontFormat);
  184. end;
  185.  
  186. procedure TForm2.btnOpenClick(Sender: TObject);
  187. var
  188.   fs : TFileStream;
  189. begin
  190.   if OpenDialog1.Execute then begin
  191.     fs := nil;
  192.     try
  193.       // Utf8ToAnsi is required for windows
  194.       fs := TFileStream.Create(Utf8ToAnsi(OpenDialog1.FileName), fmOpenRead or fmShareDenyNone);
  195.       RichMemo1.LoadRichText(fs);
  196.       Saved:=True; // since we opened a saved file
  197.       Filename:=ExtractFileName(OpenDialog1.FileName);
  198.       Filepath:=ExtractFilePath(OpenDialog1.FileName);
  199.       Caption:=Filename;
  200.     except
  201.     end;
  202.     fs.Free;
  203.   end;
  204. end;
  205.  
  206. procedure TForm2.btnSaveClick(Sender: TObject);
  207. var
  208.   fs : TFileStream;
  209. begin
  210.   if SaveDialog1.Execute then begin
  211.     fs := nil;
  212.     try
  213.       fs := TFileStream.Create( Utf8ToAnsi(SaveDialog1.FileName), fmCreate);
  214.       RichMemo1.SaveRichText(fs);
  215.       Saved:=True;
  216.       Filename:=ExtractFileName(SaveDialog1.FileName);
  217.       Filepath:=ExtractFilePath(SaveDialog1.FileName);
  218.       Caption:=Filename;
  219.     except
  220.     end;
  221.     fs.Free;
  222.   end;
  223. end;
  224.  
  225. procedure TForm2.BtnUnderlineClick(Sender: TObject);
  226. begin
  227.         if (fsUnderline in SelFontFormat.Style = False) then
  228.     SelFontFormat.Style:=SelFontFormat.Style + [fsUnderline]
  229.   else
  230.     SelFontFormat.Style:=SelFontFormat.Style - [fsUnderline];
  231.  
  232.   RichMemo1.SetTextAttributes(RichMemo1.SelStart,
  233.               RichMemo1.SelLength, SelFontFormat);
  234. end;
  235.  
  236. procedure TForm2.Button1Click(Sender: TObject);
  237. begin
  238. end;
  239.  
  240.  
  241.  
  242.  
  243. procedure TForm2.RichMemo1Change(Sender: TObject);
  244. begin
  245.   RichMemo1.GetTextAttributes(RichMemo1.SelStart, SelFontFormat);
  246.   Saved:=False;
  247. end;
  248.  
  249. end.
  250.  
« Last Edit: April 17, 2020, 05:02:04 am by db32 »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: Basic Text Editor Problem (Help!)
« Reply #1 on: April 14, 2020, 03:32:14 am »
There's a dedicated forum here for RichMemo - see this forum .

You might also want to check out How to use the Forums.

Finally, Welcome :)

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Basic Text Editor Problem (Help!)
« Reply #2 on: April 14, 2020, 03:54:33 am »
... but what I want is to select a font and then begin writing in that font.
you might want to try to change the text attribute of the last character.
Try this:
Code: Pascal  [Select][+][-]
  1. RichMemo1.SetTextAttributes(RichMemo1.GetTextLen, 1, SelFontFormat);
see if it helps.


db32

  • Newbie
  • Posts: 6
Re: Basic Text Editor Problem (Help!)
« Reply #3 on: April 17, 2020, 05:01:49 am »
Unfortunately that piece of code skalogryz, doesnt appear to work correctly for me. I may not be understanding it correctly though. It just reverts back to the rich memo's default font.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Basic Text Editor Problem
« Reply #4 on: April 17, 2020, 05:14:41 am »
how about this code?
Code: Pascal  [Select][+][-]
  1.     SelFontFormat.Name:=cboFont.Items[cboFont.ItemIndex];
  2.     RichMemo1.SetTextAttributes(RichMemo1.SelStart, 0, SelFontFormat);
  3.  

db32

  • Newbie
  • Posts: 6
Re: Basic Text Editor Problem
« Reply #5 on: April 17, 2020, 06:47:09 am »
It's still not working correctly for me.

on form create we populate the TComboBox via
Code: Pascal  [Select][+][-]
  1. procedure TForm2.FormCreate(Sender: TObject);
  2. begin
  3.   cboFont.Items.Assign(Screen.Fonts);
  4.   cboFont.ItemIndex:=0; // we select the first font
  5. end;    

then a selection by the user is made.
Code: Pascal  [Select][+][-]
  1. procedure TForm2.cboFontSelect(Sender: TObject);
  2. begin
  3.         SelFontFormat.Name:=cboFont.Items[cboFont.ItemIndex];
  4.         RichMemo1.SetTextAttributes(RichMemo1.SelStart, 0, SelFontFormat);
  5.         RichMemo1.SetFocus;
  6.         Writeln(SelFontFormat.name);
  7.  
  8. end;                  
  9.  

The Writeln shows that the right font is being selected. but the font will not change. This piece of working code changes the selected font.

Code: Pascal  [Select][+][-]
  1. procedure TForm2.FontButtonClick(Sender: TObject);
  2. begin
  3.     if FontDialog1.Execute then begin
  4.         RichMemo1.SetTextAttributes(RichMemo1.SelStart, RichMemo1.SelLength, FontDialog1.Font);
  5.  
  6.     end;
  7. end;  

I don't think this matters but I am using linux, Elementary OS-Ubuntu Based.

The major thing I am noticing is that SelFontFormat.Name is a string while FontDialog1.Font is a TFont.
« Last Edit: April 17, 2020, 06:54:46 am by db32 »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Basic Text Editor Problem
« Reply #6 on: April 17, 2020, 04:25:24 pm »
I don't think this matters but I am using linux, Elementary OS-Ubuntu Based.
that does matter.
I do believe you're using gtk2.

db32

  • Newbie
  • Posts: 6
Re: Basic Text Editor Problem
« Reply #7 on: April 17, 2020, 10:35:42 pm »
I'm not sure what that means how do I work around that?

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: Basic Text Editor Problem
« Reply #8 on: April 18, 2020, 07:13:36 am »
First off, this is the code I have been using. I forget why exactly, I think I wanted some properties of the font params (bold or something) to stay when the font is changed.

moEditor being the RichMemo
cbFont being the ComboBox

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.cbFontChange(Sender: TObject);
  2. var
  3.   fontParams: TFontParams;
  4. begin
  5.   if not(cbFont.Text = '') then
  6.   begin
  7.     moEditor.GetTextAttributes(moEditor.SelStart, fontParams);
  8.     fontParams.Name := cbFont.Text;
  9.     moEditor.SetTextAttributes(moEditor.SelStart, moEditor.SelLength, fontParams);
  10.   end;
  11. end;

This should be more or less functionally identical to what you already have.

I downloaded elementaryOS to test this (and used latest Lazarus 2.0.8). First of all, it's weird but it wouldn't let me install RichMemo into IDE as a visual component... anyway

The problem on Linux (not just elementaryOS) is that if the ComboBox is editable, it will remove your selection inside the RichMemo. You must make it ReadOnly. To do so, use the "Style" property and set it to "csDropDownList"

Be sure to also use some font very visually distinct from the default (a lot of these elementaryOS fonts looks similar to me!) I used HVD Bodedo.


By the way, I discovered a bunch of differences and small "errors" maybe among Windows and Linux GTK2. I made a relatively basic text editor using RichMemo you can find the source here: https://github.com/dazappa/matthews-daily-writer

I recommend opening "main.pas" and searching for "HACK" for some of the workarounds I developed to try to get the behavior the same across Windows and Linux. Well, it might not matter to you anyway...
« Last Edit: April 18, 2020, 07:24:50 am by daz »

 

TinyPortal © 2005-2018