Page 2 of 2
Re: Protected section not set automatically on RTF file loading
Posted: Wed May 10, 2017 11:13 am
by filo
At first, thank you for your explanation above.
We are using of quite deeply customized Delphi's TRTFEdit along with our own toolbar (font, bullets, aligning).
My task is to find out a suitable rich text editor which has a zooming capabilities and cover all of our needs. It will be a long way but your TScaleRichView looks like a great solution for this.
Back to "protect" tag:
Sergey Tkachenko wrote: ↑Tue May 09, 2017 1:40 pm
If you describe how you want to change text properties of the protected text, I will try to help.
What is available in our RTF Edit for users now:
Switch:
- "Highlight protected text"
on: all protected text is rendered with specified background color
off: remove background color of protected text
Methods:
- "Mark selected text as protected" (add caProtected tag and set background color according to the switch mentioned above)
- "Mark selected text as unprotected" (remove caProtected tag and remove background color)
- "Jump after next protected text" (Move caret behind the closest protected text - forward direction)
- "Jump after previous protected text" (Move caret behind the closest protected text - backward direction)
In addition, as a programmer I need to know if character just before and just after the caret is protected.
I'm not familiar with all possibilities of your TRichView yet so I will wait for your proposals.
Thank you!
Re: Protected section not set automatically on RTF file loading
Posted: Wed May 10, 2017 7:01 pm
by Sergey Tkachenko
I'll post these functions tomorrow.
Re: Protected section not set automatically on RTF file loading
Posted: Thu May 11, 2017 6:20 pm
by Sergey Tkachenko
How to highlight protected text.
It's simple, you even do not need to search for protected text. You can check text styles and color them.
To clear highlights, call with Color = clNone.
Code: Select all
procedure HighlightProtectedText(RVStyle: TRVStyle; Color: TColor);
var
i: Integer;
begin
for i := 0 to RVStyle.TextStyles.Count - 1 do
if rvprModifyProtect in RVStyle.TextStyles[i].Protection then
RVStyle.TextStyles[i].BackColor := Color;
end;
procedure HighlightAllProtectedText(SRV: TSRichViewEdit; Color: TColor);
var
i: TSRVHeaderFooterType;
begin
HighlightProtectedText(SRV.RichViewEdit.Style, Color);
HighlightProtectedText(SRV.RVHeader.Style, Color);
HighlightProtectedText(SRV.RVFooter.Style, Color);
for i := Low(TSRVHeaderFooterType) to High(TSRVHeaderFooterType) do
HighlightProtectedText(SRV.SubDocuments[i].GetRVStyle, Color);
if SRV.RVNote <> nil then
HighlightProtectedText(SRV.RVNote.Style, Color);
SRV.UpdateBuffer;
end;
Re: Protected section not set automatically on RTF file loading
Posted: Thu May 11, 2017 6:46 pm
by Sergey Tkachenko
How to mark selected text as protected and unprotected.
This example assume that you have ProtectedHighlightColor variable, specifying highlight color for protected text (clNone for no highlighting).
Code: Select all
const
ProtectionOptions = [rvprModifyProtect, rvprDeleteProtect, rvprSticking,
rvprStyleProtect, rvprDoNotAutoSwitch];
procedure TForm3.ProtectConversion(Sender: TCustomRichViewEdit; StyleNo,
UserData: Integer; AppliedToText: Boolean; var NewStyleNo: Integer);
var
TextStyle: TFontInfo;
begin
TextStyle := nil;
case UserData of
ord(True): // applying protection
if (ProtectionOptions * Sender.Style.TextStyles[StyleNo].Protection) <>
ProtectionOptions then
begin
TextStyle := TFontInfo.Create(nil);
TextStyle.Assign(Sender.Style.TextStyles[StyleNo]);
TextStyle.Protection := ProtectionOptions;
TextStyle.BackColor := ProtectedHighlightColor;
end;
ord(False): // clearing protection
if (ProtectionOptions * Sender.Style.TextStyles[StyleNo].Protection) <>
[] then
begin
TextStyle := TFontInfo.Create(nil);
TextStyle.Assign(Sender.Style.TextStyles[StyleNo]);
TextStyle.Protection := [];
TextStyle.BackColor := clNone;
end;
end;
if TextStyle <> nil then
begin
NewStyleNo := Sender.Style.FindTextStyle(TextStyle);
TextStyle.Free;
end;
end;
procedure TForm3.ApplyProtection(srv: TSRichViewEdit; Protect: Boolean);
var
OldStyleConversion: TRVStyleConversionEvent;
begin
OldStyleConversion := srv.OnStyleConversion;
try
srv.OnStyleConversion := ProtectConversion;
srv.ActiveEditor.ApplyStyleConversion(ord(Protect));
finally
srv.OnStyleConversion := OldStyleConversion;
end;
end;
Call ApplyProtection(srv, True) to protect, ApplyProtection(srv, False) to remove protection.
The rest of functions will be tomorrow.
Re: Protected section not set automatically on RTF file loading
Posted: Thu May 11, 2017 8:08 pm
by filo
Hi Sergey,
i have already tried your methods in my demo and all of them works like a charm.
Thank you!
Re: Protected section not set automatically on RTF file loading
Posted: Fri May 12, 2017 9:37 am
by filo
The common font RV actions (bold, italic, strike, ..) reacts to protected as I expect and want, but unfortunately I'm still able to change protected text with changing of style (with TRVStyleTemplateComboBox) or with paragraph actions (ParaBullets, ParaNumbering, ParaList ...).
Maybe there are even more possibilities how to change style which I don't know yet.
From my perspective, the right behavior for changing of protected text is:
- Disable style changing when paragraph or selected area contains protected text
- Disable Para* actions if paragraph or selected area contains protected text
Is it possible or am I miss something crucial and there is another way?
Thank you.
Re: Protected section not set automatically on RTF file loading
Posted: Fri May 12, 2017 7:40 pm
by Sergey Tkachenko
I'll check how the protection option affects applying style templates.
Expected: style templates must not be assigned to text items having rvprStyleProtect protection. However, this option does not prevent assigning styles to paragraphs, and styles of paragraphs may contain font properties affecting even protected text. It's by design: protected text is not changed, but its context is changed.
TRichView also supportы paragraph protection options (see
http://www.trichview.com/help/idh_tcust ... tions.html)
rvpaoReadOnly - disallowing editing content of this paragraph
rvpaoStyleProtect - disallows changing paragraph properties
rvpaoDoNotWantReturns - disallowing processing Enter (rvpaoReadOnly does not protect from adding new paragraphs by pressing Enter at the beginning or at the end).
But I am not sure that these options must be applied only because paragraphs contain protected text.
I'll check applications of paragraph lists to protected paragraphs.
Expected: no list markers may be inserted between text items having rvprSticking protection. However, existing list markers are not protected from changes.
Re: Protected section not set automatically on RTF file loading
Posted: Sat May 13, 2017 7:49 pm
by Sergey Tkachenko
We uploaded an update, it fixes the problem with caret moving when attempting to insert/paste RVF or press DELETE in the protected text.
About moving to the next/previous occurrence of the protected text.
The simplest way is using functions from RVGoToItem.pas unit, included in RichViewActions:
Code: Select all
function GoToNextItemEx(rve: TCustomRichViewEdit; UserData: Pointer;
Func: TCheckItemFunction; IncludeCurrentItem: Boolean;
Select: Boolean = False): Boolean;
function GoToPrevItemEx(rve: TCustomRichViewEdit; UserData: Pointer;
Func: TCheckItemFunction; IncludeCurrentItem: Boolean;
Select: Boolean = False): Boolean;
As the Func parameter, use:
Code: Select all
function IsProtectedText(RVData: TCustomRVData; ItemNo: Integer;
UserData: Pointer): Boolean;
var
StyleNo: Integer;
begin
StyleNo := RVData.GetItemStyle(ItemNo);
Result := (StyleNo >= 0) and
(rvprModifyProtect in RVData.GetRVStyle.TextStyles[StyleNo].Protection)
end;
Re: Protected section not set automatically on RTF file loading
Posted: Sat May 13, 2017 7:55 pm
by Sergey Tkachenko
As for the function returning "protected" state around the caret:
What should it return at the beginning/end of a document? Of a paragraph? Non-text items (pictures, tables) are treated as characters (TRichView can protect them from deletion only)?
Re: Protected section not set automatically on RTF file loading
Posted: Sun May 14, 2017 8:05 pm
by filo
Sergey,
thanks to your latest three posts I'm convinced that my request
I need to know if character just before and just after the caret is protected.
is on a too low level and unnecessary.
I see I can use the TCustomRichViewEdit.OnChanging (CanEdit variable) for refusing any user's action.
Can I obtain an information what type of change (text style, para style, font change) is prepared to apply?
If answer is yes, then from my point of view it would be enough to have a method like
"Is there any protected character inside of selected area or in a current paragraph (in case when no text is selected) ?"
With this function I could easily manage changes inside of OnChanging event or maybe there is even more suitable method/event (TRvAction*.ExecuteTarget, TRVStyleTemplateComboBox.DoUpdateSelection ...).
I believe that we are very close to the final solution.
Thank you for your effort, I really appreciate it.
Re: Protected section not set automatically on RTF file loading
Posted: Mon May 15, 2017 9:00 am
by filo
Sergey, is this information still valid?
Sergey Tkachenko wrote: ↑Fri Aug 17, 2007 2:09 pm
In TRichView,
there are no end-of-line characters. There is only a flag "this item starts a new line/paragraph".
I'm asking because of your methods GoToNextItemEx, GoToPrevItemEx for jumping after the protected text.
May I suggest a little improvement?
If the protected text is a paragraph or it is located at the end of paragraph, it would be better to immediately move caret to the next item (new line) and not stay at the end of paragraph, because user will have to use enter on arrow key anyway.
Re: Protected section not set automatically on RTF file loading
Posted: Wed May 17, 2017 8:48 am
by Sergey Tkachenko
As for checking selection for the protection, you can use RichViewEdit.CanDelete method.
Yes, this information (no special end-of-paragraph characters) is still valid.
The function below moves the caret to the beginning of the next paragraph, if it is at the end of a paragraph
(more exactly, paragraph section, breaks may be added by Shift+Enter)
Code: Select all
procedure MoveToNextParagraph(rve: TCustomRichViewEdit);
var
ItemNo, Offs: Integer;
begin
rve := rve.TopLevelEditor;
ItemNo := rve.CurItemNo;
Offs := rve.OffsetInCurItem;
if (ItemNo < rve.ItemCount - 1) and (Offs >= rve.GetOffsAfterItem(ItemNo)) and
rve.IsFromNewLine(ItemNo + 1) then
begin
inc(ItemNo);
Offs := rve.GetOffsBeforeItem(ItemNo);
rve.SetSelectionBounds(ItemNo, Offs, ItemNo, Offs);
end;
end;
Re: Protected section not set automatically on RTF file loading
Posted: Wed May 17, 2017 8:41 pm
by filo
Sergey,
thank you very much, my "custom" jumps have needed some small changes, but together with your code work perfectly just as I want.
I have also tried CanDelete inside of OnChanging event, it works too, but I'm a little bit confused about behavior. Due to lack of source code I can't check a reason, but when I do Ctrl+V from clipboard the OnChanging event is fired more than once (mostly twice, rarely three times). I can reproduce this even with one line simple text, such as
The similar situation is for Ctrl+X.
Can you explain why is it happened, please?
Re: Protected section not set automatically on RTF file loading
Posted: Mon May 22, 2017 1:34 pm
by Sergey Tkachenko
It's not guaranteed that OnChanging is called only once. Some operations may consist of several smaller operations, each of them testing the editor for possibility to change.
When pasting, the first check occurs at very beginning (if the editor cannot be modified, it makes no sense to get something from the Clipboard). The second check is performed by the insertion procedure.
When cutting, the first check occurs at very beginning (if the editor cannot be modified, the fragment must not be copied). The second check occurs after copying, in the selection deletion procedure.
Re: Protected section not set automatically on RTF file loading
Posted: Tue May 23, 2017 10:57 am
by filo
OK, understand, thank you.