separating paragraphs
separating paragraphs
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
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
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
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?
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?
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
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.
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.
No 1 is exactly what I want.MLefebvre wrote:Few (alternative) suggestions
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!
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 :
- 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 ...)
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);
- 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 ...)
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
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
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
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;
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;
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact: