Templates - frustrated
Templates - frustrated
Hi there,
since many days I struggle with a problem and in the meantime I am realy very frustrated.
In TRvStyle there are 12 constant templates. 0-4 for individual normal Text and that works pretty good.
5-12 are special formattings for storybooks (characters name, characters text, stage direction, sound, music, stage setting ...). Klick on a button of a tool window should put the cursor at the end of a new line, initialize with the related template. Template 7-12 is simple text (stage direction, sound, music, stage setting ...) and that works - usually.
......................Text
(...... is left indent 130 and first indent -130 - works)
But 5 and 6 are a combination for character in that way:
NAME ........ tab ..... What the char says
whatever I try, insert a combined string (Name + #9 + ' ') or AddNL(Name ...), AddTab(), AddNL() and afterwards reformat to get the proper template - all possible things happen but never what I wish.
So my question: what is the correct way to preset a new item with a spcified template??
Thanks
Martin
since many days I struggle with a problem and in the meantime I am realy very frustrated.
In TRvStyle there are 12 constant templates. 0-4 for individual normal Text and that works pretty good.
5-12 are special formattings for storybooks (characters name, characters text, stage direction, sound, music, stage setting ...). Klick on a button of a tool window should put the cursor at the end of a new line, initialize with the related template. Template 7-12 is simple text (stage direction, sound, music, stage setting ...) and that works - usually.
......................Text
(...... is left indent 130 and first indent -130 - works)
But 5 and 6 are a combination for character in that way:
NAME ........ tab ..... What the char says
whatever I try, insert a combined string (Name + #9 + ' ') or AddNL(Name ...), AddTab(), AddNL() and afterwards reformat to get the proper template - all possible things happen but never what I wish.
So my question: what is the correct way to preset a new item with a spcified template??
Thanks
Martin
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Templates - frustrated
By "templates", do you need RVStyle.TextStyles?
Do you want to add new content to the very end of existing document, starting from a new line? Or do you want insert in the middle of document?
Should this operation be undoable by user?
Do you want to add new content to the very end of existing document, starting from a new line? Or do you want insert in the middle of document?
Should this operation be undoable by user?
Re: Templates - frustrated
Yes, add new content, but with a certain style template. They not are TextStyles or ParaStyles but StyleTemplates. Usually it works, but in this special case I assign StyleTemplate No 5 by rv.ApplyStyleTemplate(5, True) but afterwards StyleTemplate 4 is assigned. This paragraph has three items (text - tab - text, see below). Unfortunately it is too much code to post all methods too. So only the main routine.
EDIT sorry, not true, that works. But e.g. first Character is okay and with secon text style not taken from template ...
I think myy solution is too complicated. Because of that: What is the most simple way?
EDIT sorry, not true, that works. But e.g. first Character is okay and with secon text style not taken from template ...
Code: Select all
var ItS, OfS, ItE, OfE: Integer;
VS: Integer;
Curr: Integer;
begin
fMain.FScreenplayConv := True;
fMain.rv.BeginUpdate;
fMain.rv.BeginUndoCustomGroup('Figur');
fMain.rv.SetUndoGroupMode(True);
try
fMain.paRV.Visible := False;
VS := fMain.rv.VScrollPos;
fMain.rv.GetSelectionBounds(ItS, OfS, ItE, OfE, False);
// New text inserted
if (ItS = ItE) and (OfS = OfE) then
begin
// If at end automatically new paragraph
Curr := fMain.rv.ItemCount;
if OfE > 1 then
// this
// begin
// fMain.rv.AddNL(AnsiUppercase(tlJ.FocusedNode.Strings[tcJ.Index]), 0, 0);
// fMain.rv.AddTab(0, -1);
// fMain.rv.Add(' ', 0);
// fMain.rv.FormatTail;
// end;
// or this
fMain.rv.InsertText(#13#10 + AnsiUppercase(tlJ.FocusedNode.Strings[tcJ.Index]+#9+' '));
// reformat
fMain.rv.SetSelectionBounds(Curr, fMain.rv.GetOffsBeforeItem(Curr), Curr+2, fMain.rv.GetOffsAfterItem(Curr+2));
end;
fTemplates.LoadTemplateData;
fMain.UpdateTemplates(fMain.CurrentNode, True);
fMain.rv.ApplyStyleTemplate(5, True);
fMain.rv.SetSelectionBounds(Curr+1, fMain.rv.GetOffsBeforeItem(Curr+1), Curr+2, fMain.rv.GetOffsAfterItem(Curr+2));
fMain.rv.ApplyStyleTemplate(6, True);
fMain.rv.Format;
fMain.rv.VScrollPos := VS;
fMain.rv.SetSelectionBounds(Curr+2, fMain.rv.GetOffsAfterItem(Curr+2), Curr+2, fMain.rv.GetOffsAfterItem(Curr+2));
finally
fMain.FScreenplayConv := False;
fMain.rv.SetUndoGroupMode(False);
fMain.rv.EndUpdate;
end;
if fMain.rv.CanFocus then
fMain.rv.SetFocus;
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Templates - frustrated
I can see two possible problems with this code.
1) StyleTemplates can be applied either to a text or to a paragraph. As I can understand, you want to apply to the selected text, not to its paragraph.
You use ApplyStyleTemplate method which applies style depending on the selection and the StyleTemplate.Kind. Kind=rvstkPara is always applied to a paragraph. Kind=rvstkText is always applied to a text. But Kind=rvstkParaText is applied depending on the selection. If the whole paragraph is selected (your first call), it is applied to the paragraph. If a fragment inside a paragraph is selected (your second call), it is applied to the selected text. If nothing is selected (your third call), it is applied to the paragraph.
Solution: If you want to make sure that it is applied to the text, use ApplyTextStyleTemplate instead of ApplyStyleTemplate
2) You call Format after the last ApplyStyleTemplate. Format resets values of the current text and paragraph style, they are read from the text at the position of the caret. So this last assignment does nothing (it is applied to the empty selection, so it does not modify the document, it only changes the current text style). Then you call SetSelectionBounds, which agains resets values of the current text and paragraph style.
Solution: call the last Apply*StyleTemplate after Format/SetSelectionBounds. Actually, Format is not needed here, because InsertText and Apply*StyleTemplate are editing methods, they do all necessary reformatting themselves.
Below is my test. I took the demo from TRichView\Demos\DelphiUnicode\Editors\StyleTemplates\.
I added a button that adds the text 'Test'#9' ' from the new line, applies the style template 'heading 1' to 'Test', applies 'heading 2' to #9' ', moves the caret at the end of this text and applies 'heading 3' to the current text:
1) StyleTemplates can be applied either to a text or to a paragraph. As I can understand, you want to apply to the selected text, not to its paragraph.
You use ApplyStyleTemplate method which applies style depending on the selection and the StyleTemplate.Kind. Kind=rvstkPara is always applied to a paragraph. Kind=rvstkText is always applied to a text. But Kind=rvstkParaText is applied depending on the selection. If the whole paragraph is selected (your first call), it is applied to the paragraph. If a fragment inside a paragraph is selected (your second call), it is applied to the selected text. If nothing is selected (your third call), it is applied to the paragraph.
Solution: If you want to make sure that it is applied to the text, use ApplyTextStyleTemplate instead of ApplyStyleTemplate
2) You call Format after the last ApplyStyleTemplate. Format resets values of the current text and paragraph style, they are read from the text at the position of the caret. So this last assignment does nothing (it is applied to the empty selection, so it does not modify the document, it only changes the current text style). Then you call SetSelectionBounds, which agains resets values of the current text and paragraph style.
Solution: call the last Apply*StyleTemplate after Format/SetSelectionBounds. Actually, Format is not needed here, because InsertText and Apply*StyleTemplate are editing methods, they do all necessary reformatting themselves.
Below is my test. I took the demo from TRichView\Demos\DelphiUnicode\Editors\StyleTemplates\.
I added a button that adds the text 'Test'#9' ' from the new line, applies the style template 'heading 1' to 'Test', applies 'heading 2' to #9' ', moves the caret at the end of this text and applies 'heading 3' to the current text:
Code: Select all
procedure TfrmMain.Button1Click(Sender: TObject);
var
ItemNo: Integer;
rve: TCustomRichViewEdit;
begin
rve := Self.rve.TopLevelEditor;
rve.SetFocus;
rve.BeginUndoGroup(rvutStyleTemplate);
rve.SetUndoGroupMode(True);
rve.BeginUpdate;
try
rve.InsertText(#13#10 +'Test'#9' ');
ItemNo := rve.CurItemNo - 2;
rve.SetSelectionBounds(
ItemNo, rve.GetOffsBeforeItem(ItemNo),
ItemNo+2, rve.GetOffsAfterItem(ItemNo+2));
rve.ApplyTextStyleTemplate(rve.Style.StyleTemplates.FindItemByName('heading 1').Index, True);
rve.SetSelectionBounds(
ItemNo+1, rve.GetOffsBeforeItem(ItemNo+1),
ItemNo+2, rve.GetOffsAfterItem(ItemNo+2));
rve.ApplyTextStyleTemplate(rve.Style.StyleTemplates.FindItemByName('heading 2').Index, True);
rve.SetSelectionBounds(
ItemNo+2, rve.GetOffsAfterItem(ItemNo+2),
ItemNo+2, rve.GetOffsAfterItem(ItemNo+2));
rve.ApplyTextStyleTemplate(rve.Style.StyleTemplates.FindItemByName('heading 3').Index, True);
finally
rve.EndUpdate;
rve.SetUndoGroupMode(False);
end;
end;
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Templates - frustrated
And here is the alternative code doing the same thing.
Instead of inserting and then applying style, we construct a proper text style, assign it to the current text style, and then insert text. A new text will be formatted accordingly.
Visually, results are the same. But this code is more efficient: it peforms (and record to undo buffer) only insertion operations.
Instead of inserting and then applying style, we construct a proper text style, assign it to the current text style, and then insert text. A new text will be formatted accordingly.
Code: Select all
function GetTextStyleWithTemplate(rvs: TRVStyle; StyleNo: Integer;
StyleTemplate: TRVStyleTemplate): Integer;
var
TextStyle: TFontInfo;
begin
Result := StyleNo;
if (StyleTemplate <> nil) and (StyleTemplate.Kind = rvstkPara) then
exit;
TextStyle := TFontInfo.Create(nil);
try
TextStyle.Assign(rvs.TextStyles[StyleNo]);
StyleTemplate.ApplyToTextStyle(TextStyle,
rvs.StyleTemplates.FindItemById(TextStyle.StyleTemplateId));
Result := rvs.FindTextStyle(TextStyle);
finally
TextStyle.Free;
end;
end;
procedure TfrmMain.Button1Click(Sender: TObject);
var
rve: TCustomRichViewEdit;
begin
rve := Self.rve.TopLevelEditor;
rve.SetFocus;
rve.BeginUndoGroup(rvutStyleTemplate);
rve.SetUndoGroupMode(True);
rve.BeginUpdate;
try
rve.CurTextStyleNo := GetTextStyleWithTemplate(rve.Style,
rve.CurTextStyleNo, rve.Style.StyleTemplates.FindItemByName('heading 1'));
rve.InsertText(#13#10'Test');
rve.CurTextStyleNo := GetTextStyleWithTemplate(rve.Style,
rve.CurTextStyleNo, rve.Style.StyleTemplates.FindItemByName('heading 2'));
rve.InsertText(#9' ');
rve.CurTextStyleNo := GetTextStyleWithTemplate(rve.Style,
rve.CurTextStyleNo, rve.Style.StyleTemplates.FindItemByName('heading 3'));
finally
rve.EndUpdate;
rve.SetUndoGroupMode(False);
end;
end;
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Templates - frustrated
And here is a version of this code that does not use editing methods (so it is not undoable).
It adds new content to the very end of the document. The code uses GetTextStyleWithTemplate from the previous code sample.
This code still creates styles basing on CurTextStyleNo and CurParaStyleNo, so the new line inherits text and paragraph attributes of the current text.
It adds new content to the very end of the document. The code uses GetTextStyleWithTemplate from the previous code sample.
This code still creates styles basing on CurTextStyleNo and CurParaStyleNo, so the new line inherits text and paragraph attributes of the current text.
Code: Select all
procedure TfrmMain.Button1Click(Sender: TObject);
begin
rve.SetFocus;
rve.AddNL('Test', GetTextStyleWithTemplate(rve.Style,
rve.CurTextStyleNo, rve.Style.StyleTemplates.FindItemByName('heading 1')),
rve.CurParaStyleNo);
rve.AddTextNL(#9' ', GetTextStyleWithTemplate(rve.Style,
rve.CurTextStyleNo, rve.Style.StyleTemplates.FindItemByName('heading 2')),
-1, 0);
rve.FormatTail;
rve.SetSelectionBounds(
rve.ItemCount - 1, rve.GetOffsAfterItem(rve.ItemCount - 1),
rve.ItemCount - 1, rve.GetOffsAfterItem(rve.ItemCount - 1));
rve.CurTextStyleNo := GetTextStyleWithTemplate(rve.Style,
rve.CurTextStyleNo, rve.Style.StyleTemplates.FindItemByName('heading 3'));
end;
Re: Templates - frustrated
Thank you very much for the very detailed information!
If that works (and I think it does ), it's a load off my mind!
Great illumination
Martin
If that works (and I think it does ), it's a load off my mind!
Great illumination
Martin
Re: Templates - frustrated
Now implemented, works fine! Helps a lot with handling StyleTemplates.
Until now that has been my area of ignorance concerning TRichViewEdit. Seems to change ...
Until now that has been my area of ignorance concerning TRichViewEdit. Seems to change ...