Page 1 of 1
separating paragraphs
Posted: Mon Mar 27, 2006 1:48 pm
by alexro
I need to visually separate the first paragraph (make it kind of annotation) from the rest of the document. I think to implement this with a line similar to a page break. The problems I'm facing are:
1) how to draw this line
2) how to prevent it from deletion
3) how to update in case first paragraph will be deleted (the line should go after the first available paragraph)
If such line is very complicated (not possible) I will go with changing the first paragraph's background. Maybe other solution exists?
Please advice
Many thanks
Posted: Mon Mar 27, 2006 5:58 pm
by Sergey Tkachenko
You can use a paragraph boder - hide all border sides except for the bottom side.
Posted: Mon Mar 27, 2006 10:34 pm
by alexro
Yes, this will be sufficient. Could you advice on how to ensure the style is applied to the first paragraph and only to the first paragraph regardless of the document changes?
Is it better to use OnIdle event or trap OnChange?
And how to enumerate the paragraphs?
Many thanks!
Posted: Tue Mar 28, 2006 6:16 pm
by Sergey Tkachenko
I am afraid it's not possible to use some style only for the first paragraph.
User can copy-paste or drag&drop it, so you'll need to forbid drag&drop and pasting in RVF and RTF formats. I do not know if it's ok for your application.
You can set NextParaNo property of this heading paragraph style to the index of another paragraph style (for example, to 0). When the user presses Enter key at the end of header, a new paragraph will be added with this style.
Or, probably, you can edit this header in another RichViewEdit (with forbidden d&d and RVF/RTF copying). Something like WinHelp.
About enumerating paragraphs... What exactly do you want to enumerate?
Posted: Tue Mar 28, 2006 11:54 pm
by alexro
Sergey Tkachenko wrote: What exactly do you want to enumerate?
I'm looking for something like:
Paragraphs[0].Style:= SpecialStyle;
for I:= 1 to Paragraphs.Count - 1 do
begin
Paragraphs
.Style:= GeneralStyle;
end
This will solve copy/pasting/dragging issue ...
Posted: Wed Mar 29, 2006 2:35 pm
by Sergey Tkachenko
List of all paragraph attributes in document is RVStyle.ParaStyles collection.
Posted: Thu Mar 30, 2006 5:15 am
by MLefebvre
Few (alternative) suggestions :
1/ If your need is only at visual level, you might use the RVStyle.OnDrawStyleText / OnDrawParaBack events, to draw an additional horizontal line after the first paragraph whatever it is. To find the end of 1st paragraph, just loop on RV items and check IsParaStart(i). This may be used when printing as well.
2/ If you want to introduce a logical difference in this 1st paragraph, another solution is to insert a 1x1 table at the start of the document (with bottom border only), make this table non-deletable, and use a "do-not-want returns" style in the cell. You will have also to prevent from inserting anything before the table (using the OnChanging event). A drawback there is that this introduces a definite limit between the document "header" and the rest, that the end user will have to know about. Also, introducing Tables requires some more knowledge of RV if you have not done that before.
3/ Applying a specific para style to the 1st paragraph in all cases is more complex. May be you can do this in the OnChange event :
- Freeze display update
- Save caret location (see functions in RVLinear.pas)
- Select start of item 0 (with SetSelectionBounds)
- Disable onChange temporarily (or use BeginUpdate)
- ApplyParaStyle (SpecificParaStyle)
- Re-enable OnChange (or EndUpdate)
- Restore saved caret location
- Unfreeze and update display
Yet there is a remaining problem with the Undo. Ideally you should embed the user action and the complementary change above in one single Undo group so that they cannot be undone individually. And unfortunately I have not found a 100% safe solution for that (except disabling the Undo, which is a pity).
I hope this will help.
Posted: Sat Apr 01, 2006 9:45 pm
by alexro
MLefebvre wrote:Few (alternative) suggestions
No 1 is exactly what I want.
But I'm a bit lost: in DrawParaBack ParaNo is always 0, so it cant point to the first paragraph. And if I find the first paragraph looping through RVData.ItemCount/RVData.GetItem, how I get its canvas to draw a line?
Many thanks!
Posted: Mon Apr 03, 2006 6:59 am
by MLefebvre
ParaNo is not the paragraph number in the document, it is the index of the paragraph style that applies to the considered RV item.
Anyway I apologize, OnDrawParaBack is not the solution by itself, since it gives no information on the source item being drawn. Here is what I can suggest :
- Define a global int variable LastItemOf1stPara
- Create a procedure to update this variable :
Code: Select all
LastItemOf1stPara := 0;
with MyRV do
while (LastItemOf1stPara < ItemCount-1)
and not IsParaStart(LastItemOf1stPara+1) do
Inc(LastItemOf1stPara);
- Call this procedure after you set up the initial content, and within the OnChange event.
- In the OnDrawStyleText, check whether Sender.ItemNo is equal to LastItemOf1stPara, and if so draw your line at Top+Height.
I hope this will help (yet probably Sergey could suggest a much smarter solution ...)
Posted: Mon Apr 03, 2006 7:38 am
by Sergey Tkachenko
OnDrawParaBack has hidden parameters
Sender.RVData and Sender.ItemNo define the last item in the drawn paragraph.
Example using these parameters:
http://www.trichview.com/forums/viewtopic.php?t=60
Posted: Sun Apr 09, 2006 10:31 pm
by alexro
It turned out to be less complicated as I thought initially:
procedure TrvActionsResource.txtStyleDrawParaBack(Sender: TRVStyle; Canvas: TCanvas; ParaNo: Integer; ARect: TRect; var DoDefault: Boolean);
var
I: Integer;
Data: TRichViewRVData;
begin
Data:= TRichViewRVData(Sender.RVData);
for I:= 1 to Data.ItemCount - 1 do
begin
if Data.IsParaStart(I) then
Break;
end;
if Sender.ItemNo < I then
begin
Canvas.Brush.Color:= $f5f5f5;
Canvas.FillRect(ARect);
Canvas.MoveTo(ARect.Left, ARect.Bottom);
Canvas.LineTo(ARect.Right, ARect.Bottom);
end
end;
Posted: Mon Apr 10, 2006 9:46 am
by Sergey Tkachenko
It's ok, but some comments.
1) Sender.RVData is not neccessary TRichViewRVData (it's not so for cells). It's better to typecast it to TCustomRVData.
2) While it works, it's better to avoid using a for-loop variable (I) after the cycle.