Undo of set editor background
Undo of set editor background
Is there a way to implement undo/redo for changes to the editor background?
Nick Sullivan
AHA! Software
Nick Sullivan
AHA! Software
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
This function is not implemented, but I can show how to implement it.
How to use:
Assignment of other background properties (BackgroundBitmap, BackgroundStyle) can be implemented in the same way (for bitmap, do not forget to implement destructor freeing the stored bitmap)
Code: Select all
uses RVUndo, RVRVData, RVERVData;
type
TRVUndoBackgroundColor = class (TRVUndoInfo)
private
FBackgroundColor: TColor;
public
function RequiresFormat: Boolean; override;
procedure Undo(RVData: TRichViewRVData); override;
end;
procedure DoChangeBackgroundColor(RVData: TRichViewRVData; Color: TColor);
var UndoItem: TRVUndoBackgroundColor;
List: TRVUndoList;
Edit: TCustomRichViewEdit;
begin
Edit := TRichViewRVData(RVData.GetAbsoluteRootData).RichView as TCustomRichViewEdit;
List := TRVEditRVData(RVData).GetUndoList;
if List<>nil then begin
UndoItem := TRVUndoBackgroundColor.Create;
UndoItem.Action := rvuMisc;
UndoItem.FBackgroundColor := Edit.Color;
List.AddInfo(UndoItem, Edit);
end;
Edit.Color := Color;
end;
procedure ChangeBackgroundColor(Edit: TCustomRichViewEdit; Color: TColor);
begin
Edit.BeginUndoCustomGroup('Change Background Color');
DoChangeBackgroundColor(Edit.RVData, Color);
while Edit<>nil do begin
Edit.Invalidate;
Edit := TCustomRichViewEdit(Edit.InplaceEditor);
end;
end;
procedure TRVUndoBackgroundColor.Undo(RVData: TRichViewRVData);
begin
DoChangeBackgroundColor(RVData, FBackgroundColor);
end;
function TRVUndoBackgroundColor.RequiresFormat: Boolean;
begin
Result := False;
end;
Code: Select all
ChangeBackgroundColor(RichViewEdit1, clRed);
Below you find the translation to C++. Have fun!
UndoBackgroundColorUnit.h
UndoBackgroundColorUnit.cpp
How to use:
UndoBackgroundColorUnit.h
Code: Select all
//---------------------------------------------------------------------------
#include "RVUndo.hpp"
#include "RVRVData.hpp"
#include "RVERVData.hpp"
//---------------------------------------------------------------------------
class TRVUndoBackgroundColor : public TRVUndoInfo
{
private:
TColor FBackgroundColor;
public:
DYNAMIC bool __fastcall RequiresFormat(void);
DYNAMIC void __fastcall Undo(Rvrvdata::TRichViewRVData* RVData);
void __fastcall DoChangeBackgroundColor(TRichViewRVData *RVData, TColor Color);
};
//---------------------------------------------------------------------------
Code: Select all
void __fastcall TRVUndoBackgroundColor::Undo(Rvrvdata::TRichViewRVData* RVData)
{
DoChangeBackgroundColor(RVData, FBackgroundColor);
}
//---------------------------------------------------------------------------
bool __fastcall TRVUndoBackgroundColor::RequiresFormat()
{
return false;
}
//---------------------------------------------------------------------------
void __fastcall TRVUndoBackgroundColor::DoChangeBackgroundColor(TRichViewRVData *RVData, TColor Color)
{
TCustomRichViewEdit *Edit = (TCustomRichViewEdit *) ((TRichViewRVData *)RVData->GetAbsoluteRootData())->RichView;
TRVUndoList *List = ((TRVEditRVData *)RVData)->GetUndoList();
if(List != NULL)
{
TRVUndoBackgroundColor *UndoItem = new TRVUndoBackgroundColor();
UndoItem->Action = rvuMisc;
UndoItem->FBackgroundColor = Edit->Color;
List->AddInfo(UndoItem, Edit);
}
Edit->Color = Color;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ChangeBackgroundColor(TCustomRichViewEdit *Edit, TColor Color)
{
Edit->BeginUndoCustomGroup("Change Background Color");
TRVUndoBackgroundColor *pUndoColor = new TRVUndoBackgroundColor();
try
{
pUndoColor->DoChangeBackgroundColor(Edit->RVData, Color);
while(Edit != NULL)
{
Edit->Invalidate();
Edit = (TCustomRichViewEdit *) Edit->InplaceEditor;
}
}
__finally
{
pUndoColor->Free();
}
}
//---------------------------------------------------------------------------
Code: Select all
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ChangeBackgroundColor(rve, clRed);
}
//---------------------------------------------------------------------------
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Hello Sergey!
I have problem with undo/redo. I'm edit inserted image in my image Editor. But if base image changes undo does't work.
-----------------------
var
gr: TGraphic;
bmp: TBitmap;
----------------------
gr := RVE.GetSelectedImage;
if gr = nil then exit;
bmp := TBitmap.Create;
bmp.Assign(gr);
// now change image in outer image editor
gr.Assign(bmp);
(Еще на русском напишу, мой английский к сожалению далек от совершенства.
Редактирую изображение, после редактирования возвращаю его обратно. Но отменить эту операцию TRichViewEdit уже нельзя (конечно можно дополнительно сохранять копию изображения и т.д.), но хотелось бы что бы изменения те что касаются и изображения ставали в очередь операций "Отменить/Вернуть".
Заранее спасибо!
)
I have problem with undo/redo. I'm edit inserted image in my image Editor. But if base image changes undo does't work.
-----------------------
var
gr: TGraphic;
bmp: TBitmap;
----------------------
gr := RVE.GetSelectedImage;
if gr = nil then exit;
bmp := TBitmap.Create;
bmp.Assign(gr);
// now change image in outer image editor
gr.Assign(bmp);
(Еще на русском напишу, мой английский к сожалению далек от совершенства.
Редактирую изображение, после редактирования возвращаю его обратно. Но отменить эту операцию TRichViewEdit уже нельзя (конечно можно дополнительно сохранять копию изображения и т.д.), но хотелось бы что бы изменения те что касаются и изображения ставали в очередь операций "Отменить/Вернуть".
Заранее спасибо!
)
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Since this old topic is revived, I want to say that the new version of TRichViewEdit you can change background properties as an editing operation. The methods are SetBackgroundImageEd for changing image, SetIntPropertyEd for changing background style and color.
As for the last question. If you simply change an image, this operation cannot be undone. You need to create a new image and call SetCurrentPicture or SetPictureEd to assign this new image to the item.
If you want to work with the selected picture, you cannot use SetCurrentPicture, because the current item is not necessary the selected item (the current item is item to the left of the caret; if the selection was made from bottom to top, the previous item is current).
If you want to use only documented methods, you should get the selection using RVE.TopLevelEditor.GetSelectionBounds and check, if a single image is selected.
I simplify this task by using undocumented GetSingleSelectedItem method
As for the last question. If you simply change an image, this operation cannot be undone. You need to create a new image and call SetCurrentPicture or SetPictureEd to assign this new image to the item.
If you want to work with the selected picture, you cannot use SetCurrentPicture, because the current item is not necessary the selected item (the current item is item to the left of the caret; if the selection was made from bottom to top, the previous item is current).
If you want to use only documented methods, you should get the selection using RVE.TopLevelEditor.GetSelectionBounds and check, if a single image is selected.
I simplify this task by using undocumented GetSingleSelectedItem method
Code: Select all
uses CRVFData, RVTypes;
var RVData: TCustomRVFormattedData;
ItemNo: Integer;
AVAlign: TRVValign;
AName: TRVAnsiString;
ATag: TRVTag;
gr := RVE.GetSelectedImage;
if gr = nil then
exit;
bmp := TBitmap.Create;
bmp.Assign(gr);
RVE.RVData.GetSingleSelectedItem(RVData, ItemNo);
// we can use TopLevelEditor, because the selected image can be only in it
RVE.TopLevelEditor.GetPictureInfo(ItemNo, AName, gr, AVAlign, ATag);
RVE.TopLevelEditor.SetPictureInfoEd(ItemNo, AName, bmp, AVAlign, ATag);
Re:
Доброго дня суток!Sergey Tkachenko wrote: ↑Tue Oct 24, 2006 9:06 am This function is not implemented, but I can show how to implement it.
How to use:Code: Select all
uses RVUndo, RVRVData, RVERVData; type TRVUndoBackgroundColor = class (TRVUndoInfo) private FBackgroundColor: TColor; public function RequiresFormat: Boolean; override; procedure Undo(RVData: TRichViewRVData); override; end; procedure DoChangeBackgroundColor(RVData: TRichViewRVData; Color: TColor); var UndoItem: TRVUndoBackgroundColor; List: TRVUndoList; Edit: TCustomRichViewEdit; begin Edit := TRichViewRVData(RVData.GetAbsoluteRootData).RichView as TCustomRichViewEdit; List := TRVEditRVData(RVData).GetUndoList; if List<>nil then begin UndoItem := TRVUndoBackgroundColor.Create; UndoItem.Action := rvuMisc; UndoItem.FBackgroundColor := Edit.Color; List.AddInfo(UndoItem, Edit); end; Edit.Color := Color; end; procedure ChangeBackgroundColor(Edit: TCustomRichViewEdit; Color: TColor); begin Edit.BeginUndoCustomGroup('Change Background Color'); DoChangeBackgroundColor(Edit.RVData, Color); while Edit<>nil do begin Edit.Invalidate; Edit := TCustomRichViewEdit(Edit.InplaceEditor); end; end; procedure TRVUndoBackgroundColor.Undo(RVData: TRichViewRVData); begin DoChangeBackgroundColor(RVData, FBackgroundColor); end; function TRVUndoBackgroundColor.RequiresFormat: Boolean; begin Result := False; end;
Assignment of other background properties (BackgroundBitmap, BackgroundStyle) can be implemented in the same way (for bitmap, do not forget to implement destructor freeing the stored bitmap)Code: Select all
ChangeBackgroundColor(RichViewEdit1, clRed);
Не совсем понял Ваш пример.
При добавлении TRVUndoBackgroundColor в очередь Undo, вроде бы логично почистить очередь Redo?
{проверяется так набрать несколько символов нажать несколько раз Undo, выполнить ChangeBackgroundColor, результат Redo доступно}
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Undo of set editor background
Чтобы все было правильно, в конец DoChangeBackgroundColor нужно добавить Editor.Change.
Как я писал выше, теперь рекомендованный способ поменять цвет фона с возможностью отмены это
MyRichViewEdit.SetIntPropertyEd(rvipColor, ord(clYellow), True);
Приведенный код может быть полезен только если вы хотите на его основе реализовать отмену своих нестандартных операций.
---
The question was about not clearing a redo buffer. The fix is adding the line Editor.Change to the end of DoChangeBackgroundColor.
But as I wrote above, the new version has a special function to change background color as an editing operation:
MyRichViewEdit.SetIntPropertyEd(rvipColor, ord(clYellow), True);
The code sample is this topic is only useful as an example of implementation of undo of your own operations.
Как я писал выше, теперь рекомендованный способ поменять цвет фона с возможностью отмены это
MyRichViewEdit.SetIntPropertyEd(rvipColor, ord(clYellow), True);
Приведенный код может быть полезен только если вы хотите на его основе реализовать отмену своих нестандартных операций.
---
The question was about not clearing a redo buffer. The fix is adding the line Editor.Change to the end of DoChangeBackgroundColor.
But as I wrote above, the new version has a special function to change background color as an editing operation:
MyRichViewEdit.SetIntPropertyEd(rvipColor, ord(clYellow), True);
The code sample is this topic is only useful as an example of implementation of undo of your own operations.
Re: Undo of set editor background
в этом случае Redo очередь не активизируетсяSergey Tkachenko wrote: ↑Fri Jun 14, 2019 11:32 am Чтобы все было правильно, в конец DoChangeBackgroundColor нужно добавить Editor.Change.
есть какое нибудь решение?
в лоб вижу класс добавить TRedoBackColor
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Undo of set editor background
My mistake, Edit.Change must be in ChangeBackgroundColor, not in DoChangeBackgroundColor.
Also, I added CanChange check (it is especially important for TDBRichViewEdit).
(Я ошибся, Edit.Change нужно добавить в ChangeBackgroundColor, а не в DoChangeBackgroundColor.
Кроме того, следует добавить проверку на CanChange, это особенно важно, если код будет использоваться в TDBRichViewEdit).
Also, I added CanChange check (it is especially important for TDBRichViewEdit).
(Я ошибся, Edit.Change нужно добавить в ChangeBackgroundColor, а не в DoChangeBackgroundColor.
Кроме того, следует добавить проверку на CanChange, это особенно важно, если код будет использоваться в TDBRichViewEdit).
Code: Select all
procedure DoChangeBackgroundColor(RVData: TRichViewRVData; Color: TColor);
var UndoItem: TRVUndoBackgroundColor;
List: TRVUndoList;
Edit: TCustomRichViewEdit;
begin
Edit := TRichViewRVData(RVData.GetAbsoluteRootData).RichView as TCustomRichViewEdit;
List := TRVEditRVData(RVData).GetUndoList;
if List<>nil then begin
UndoItem := TRVUndoBackgroundColor.Create;
UndoItem.Action := rvuMisc;
UndoItem.FBackgroundColor := Edit.Color;
List.AddInfo(UndoItem, Edit);
end;
Edit.Color := Color;
end;
procedure ChangeBackgroundColor(Edit: TCustomRichViewEdit; Color: TColor);
begin
if Edit.CanChange then
begin
Edit.BeginUndoCustomGroup('Change Background Color');
DoChangeBackgroundColor(Edit.RVData, Color);
Edit.Change;
Edit.RefreshAll;
end;
end;