Page 1 of 1

Programmatically changing font and font size.

Posted: Thu Dec 29, 2011 12:19 pm
by BennieC
I am transferring data from a rtf database to a new db but using rvf format. I noticed that the previous data was not always using the same font. Is there programmatic way to select all the data, change the font and font size, before saving the data. I do not want to lose other formatting such as bold and italics in the process.
Bennie

Posted: Thu Dec 29, 2011 1:58 pm
by Sergey Tkachenko
Do you want to assign the same font name and size to all the text?

There are two ways to do it.

1) Changing text styles:

Code: Select all

for i := 0 to RVStyle1.TextStyles.Count-1 do begin
  RVStyle1.TextStyles[i].FontName := 'Tahoma';
  RVStyle1.TextStyles[i].Size := 10;
end;
This code has one problem: after this, styles with identical properties may appear (and they cannot be removed by DeleteUnusedStyles - because they are used).
To remove identical styles, you can use this code:

Code: Select all

Stream.Clear;
rv.SaveRVFToStream(Stream, False);
Stream.Position := 0;
rv.Clear;
rv.DeleteUnusedStyles(True, True, True);
rv.InsertRVFFromStream(Stream, 0);
InsertRVFFromStream maps styles in RVF to existing styles, removing duplicates.

2) Alternative way: use editing methods: rve.SelectAll; rve.ApplyStyleConversion(...) + implementation of OnStyleConversion event for changing font. Or using RichViewActions:

Code: Select all

rve.SelectAll; 
with rvActionFontEx1 do begin
  UserInterface := False;
  ValidProperties := [rvfimFontName, rvfimFontSize];
  Font.Name := 'Tahoma';
  Font.Size := 10;
   Execute;
   UserInterface := True;
end;

Posted: Thu Dec 29, 2011 6:18 pm
by BennieC
Using method 1
It appears that I have to format the RV object before selecting it. As it is only a temporary object it is not assigned to a form and hence the format method fails with 'Control has no parent window'. To what could I assign the parent to.
Bennie

Posted: Thu Dec 29, 2011 6:42 pm
by Sergey Tkachenko
Yes, if you need to display this rv or work with its selection, you need to format it.
I thought you only need to save it.

Option one removes a space before special formatting

Posted: Sun Sep 20, 2015 6:15 pm
by shoebuddy
When I use option 1, anything that was bold or in italics looses the space that separates it from another word.

E.g.: this boy is here. Becomes: thisboyis here

Posted: Sun Sep 20, 2015 6:23 pm
by shoebuddy
Also with option 2
Cannot find rvfimFontSize ???

Posted: Sun Sep 20, 2015 6:38 pm
by shoebuddy
I have the same problem with option 2 (see above) with formatted text losing a space before and after

Posted: Sun Sep 20, 2015 7:00 pm
by shoebuddy
What I want to do is make sure anything I copy or drag into the TDBRichViewEdit is given the default text style: Times New Roman 12.

Maybe there is another way to do this that preserves formatting of bold and italics without removing a space before and after such formatted words?

Posted: Sun Sep 20, 2015 7:47 pm
by shoebuddy
Ok. the spaces were my error :oops:

But if there is a better way to do what I want, please let me know.

Also I figured out how to use fontdoublesize instead of fontsize

Posted: Thu Jan 14, 2016 2:22 pm
by Alexander_Dober
Hello,

has anything changed in the way of changing font and font size programmatically?

I'm trying the current RV version and my application seems to be "broken" partly.

I'm creating the rvActions and the controls for the ToolBar at run-time:

Code: Select all

myRVActionFont: TrvActionFontEx;

myRVActionFont := rvActionsResource.rvActionFontEx1;
myRVActionFont.Control := myRichViewEdit;

myRichViewEdit.OnCurTextStyleChanged := myRichViewEditCurTextStyleChanged;

procedure myRichViewEditCurTextStyleChanged(Sender: TObject);
var
   TempStyle: TFontInfo;
begin
	TempStyle := myRichViewEdit.Style.TextStyles[myRichViewEdit.CurTextStyleNo];
	cxFontNameComboBox.FontName := TempStyle.FontName;
	cxSpinEditFontSize.Value := TempStyle.Size;
end;
Then reading the font related user settings and setting them, if the RichViewEdit is empty:

Code: Select all

var
   myTextStyle: TFontInfo;
   myIndexNewTextStyle: integer;
begin
	myTextStyle := TFontInfo.Create(nil);

	try
		myTextStyle.FontName := DefaultUserFont; // Calibri
		myTextStyle.Size := DefaultUserFontSize; // 11
		myTextStyle.Color := DefaultUserFontColor; // clBlack

		if assigned(cxColorComboBoxSchriftfarbe) then begin
			cxColorComboBoxSchriftfarbe.ColorValue := myTextStyle.Color;
		end;
		cxFontNameComboBox.FontName := myTextStyle.FontName;
		cxSpinEditFontSize.Value := myTextStyle.Size;

		if assigned(myRichViewEdit.Style) then begin
			if myRichViewEdit.Style.TextStyles.FindSuchStyle(0, myTextStyle, RVAllFontInfoProperties) <= 0 then begin
				myRichViewEdit.Style.TextStyles.Add;
				myIndexNewTextStyle := myRichViewEdit.Style.TextStyles.Count-1;
				myRichViewEdit.Style.TextStyles[myIndexNewTextStyle].Assign(myTextStyle);
				myRichViewEdit.Style.TextStyles[myIndexNewTextStyle].Standard := false;
			end;

			with rvetRVActionSchriftart do begin
				UserInterface := False;
				ValidProperties := [rvfimFontName, rvfimColor, rvfimSize];
				Font.Name := myTextStyle.FontName;
				Font.Color := myTextStyle.Color;
				Font.Size := myTextStyle.Size;
				Execute;
				UserInterface := True;
			end;

			myRichViewEdit.ClearUndo;
		end;
	finally
		FreeAndNil(myTextStyle);
	end;
end;
After this my controls have correct values (color, font name, size) and also when I start to type, everything looks fine within the RichViewEdit, but when I do a right click -> "font" menu, the UserInterface of the font action shows, that the font size is 1, while the font name and color are correct here as well.

That's the first problem.

If the RichViewEdit is not empty, I'm calling the myRichViewEditCurTextStyleChanged procedure. The text that was saved with older versions looks fine, the controls too and also the UserInterface has correct values.

Once I add something after the existing text though, the new content has again the size of 1 (not always though, didn't figure out when exactly it happens, but it happens).

That's the second problem.

When I select some text - not matter if formatted correctly (size 11) or not (size 1) - and try to change the font size via the cxSpinEdit, nothing happens, while in the past the new size was applied correctly.

That's the third problem, although they all are probably related.

Changing the font name via the cxFontCombobox still works as before.

That's how I'm doing it:

Code: Select all

      with myRVActionFont do begin
         UserInterface := False;
			ValidProperties := [rvfimFontName];
         Font.Name := cxFontNameComboBox.FontName;
         Execute;
         UserInterface := True;
      end;

		
      TempInteger := Integer(cxSpinEditFontSize.EditValue);
      with myRVActionFont do begin
         UserInterface := False;
         ValidProperties := [rvfimSize];
         Font.Size := TempInteger;
         Execute;
         UserInterface := True;
      end;
The only difference I've noticed: when changing the size myRichViewEdit.OnCurTextStyleChanged isn't being fired anymore, while it still is being fired when changing the font name or the color.

I went through the changelogs and the only somewhat related change I've found is: "A new text property is added: FontSizeDouble." but judging by the description this shouldn't cause such a behaviour, I think.

Any idea what is going wrong and how to fix it?

Posted: Fri Jan 15, 2016 7:56 am
by Sergey Tkachenko
rvActionFontEx.Font.Size must not be used.
rvActionFontEx.FontSizeDouble must be used instead.

(Font sizes may be fractional, with the precision 0.5 pt.
For example font size may be "8.5". In this case, assign FontSizeDouble = 17)

Posted: Fri Jan 15, 2016 9:06 am
by Alexander_Dober
This part of the announcement thread did sound to me, as if it doesn't matter which property is being set:
The old Size property (size in points) still exists. Assigning value to one property changes value of another property.
Changed it to "FontSizeDouble" now and it works again, thanks for your help!