refactored TCEWritableComponent

inherits from new TCECustomWritableComponent
renamed as TCEWritableLfmTextComponent
added TCEWritableJsonComponent which derives from the same ancestor
This commit is contained in:
Basile Burg 2015-01-23 18:04:01 +01:00
parent 2f6a9736dc
commit 96c8c3ea7b
8 changed files with 137 additions and 39 deletions

View File

@ -16,7 +16,7 @@ type
* Completion, hints and declaration finder automatically work on the current
* document: ICEMultiDocObserver.
*)
TCEDcdWrapper = class(TWritableComponent, ICEProjectObserver, ICEMultiDocObserver)
TCEDcdWrapper = class(TWritableLfmTextComponent, ICEProjectObserver, ICEMultiDocObserver)
private
fTempLines: TStringList;
//fPortNum: Word;

View File

@ -27,7 +27,7 @@ type
(**
* Represents all the D libraries present on this system.
*)
TLibraryManager = class(TWritableComponent)
TLibraryManager = class(TWritableLfmTextComponent)
private
fCol: TCollection;
procedure setCol(const aValue: TCollection);

View File

@ -9,7 +9,7 @@ uses
type
TCEOptions = class(TWritableComponent)
TCEOptions = class(TWritableLfmTextComponent)
private
fSubjPersObservers: TCECustomSubject;
protected

View File

@ -21,7 +21,7 @@ type
*
* Basically it' s designed to provide the options for the dmd process.
*)
TCEProject = class(TWritableComponent)
TCEProject = class(TWritableLfmTextComponent)
private
fOnChange: TNotifyEvent;
fModified: boolean;

View File

@ -22,7 +22,7 @@ type
* Shift + SPACE works automatically on the right editor (ICEMultiDocObserver)
* Automatic insertion is handled in TCESynMemo.KeyUp()
*)
TCEStaticEditorMacro = class(TWritableComponent, ICEMultiDocObserver)
TCEStaticEditorMacro = class(TWritableLfmTextComponent, ICEMultiDocObserver)
private
fCompletor: TSynAutoComplete;
fMacros: TStringList;

View File

@ -24,7 +24,7 @@ type
property nestedIndex: Integer read fNestedIndex write fNestedIndex;
end;
TCESynMemoCache = class(TWritableComponent)
TCESynMemoCache = class(TWritableLfmTextComponent)
private
fMemo: TCESynMemo;
fFolds: TCollection;

View File

@ -45,7 +45,7 @@ type
destructor destroy; override;
end;
TCETools = class(TWritableComponent, ICEMainMenuProvider)
TCETools = class(TWritableLfmTextComponent, ICEMainMenuProvider)
private
fTools: TCollection;
function getTool(index: Integer): TCEToolItem;

View File

@ -5,17 +5,20 @@ unit ce_writableComponent;
interface
uses
Classes, SysUtils, ce_common;
Classes, SysUtils, ce_common, typinfo, fpjson, jsonparser, fpjsonrtti, fpjsondataset;
type
(**
* The ancestor of classes which can be saved or reloaded to/from
* a text file. It's used each time some options or data have to
* The ancestor of classes which can be saved or reloaded to/from a file.
* It's used each time some options or data have to
* persist from a cession to another, independently from the centralized
* system provided by the ICESessionOptionObserver/Subject mechanism.
*
* The descendants overrides customLoadFromFile and customSaveToFile
* to save/load to/from a specific format.
*)
TWritableComponent = class(TComponent)
TCustomWritableComponent = class(TComponent)
protected
fFilename: string;
fHasLoaded: boolean;
@ -25,10 +28,8 @@ type
procedure beforeSave; virtual;
procedure afterLoad; virtual;
procedure afterSave; virtual;
procedure readerPropNoFound(Reader: TReader; Instance: TPersistent;
var PropName: string; IsPath: boolean; var Handled, Skip: Boolean); virtual;
procedure readerError(Reader: TReader; const Message: string;
var Handled: Boolean); virtual;
procedure customLoadFromFile(const aFilename: string); virtual; abstract;
procedure customSaveToFile(const aFilename: string); virtual; abstract;
public
procedure saveToFile(const aFilename: string); virtual;
procedure loadFromFile(const aFilename: string); virtual;
@ -38,49 +39,66 @@ type
property hasSaved: boolean read fHasSaved;
end;
(**
* The ancestor of classes which can be saved or reloaded to/from
* a LFM text file.
* By default, reading errors are skipped and no exception is raised.
*)
TWritableLfmTextComponent = class(TCustomWritableComponent)
protected
procedure customLoadFromFile(const aFilename: string); override;
procedure customSaveToFile(const aFilename: string); override;
procedure readerPropNoFound(Reader: TReader; Instance: TPersistent;
var PropName: string; IsPath: boolean; var Handled, Skip: Boolean); virtual;
procedure readerError(Reader: TReader; const Message: string;
var Handled: Boolean); virtual;
end;
(**
* The ancestor of classes which can be saved or reloaded to/from
* a JSON file.
* By default, reading errors are skipped and no exception is raised.
*)
TWritableJsonComponent = class(TCustomWritableComponent)
protected
procedure propertyError(Sender : TObject; AObject : TObject; Info : PPropInfo;
AValue : TJSONData; Error : Exception; Var doContinue : Boolean); virtual;
procedure restoreProperty(Sender : TObject; AObject : TObject; Info : PPropInfo;
AValue : TJSONData; Var Handled : Boolean); virtual;
procedure customLoadFromFile(const aFilename: string); override;
procedure customSaveToFile(const aFilename: string); override;
end;
implementation
procedure TWritableComponent.beforeSave;
{$REGION TCustomWritableComponent ----------------------------------------------}
procedure TCustomWritableComponent.beforeSave;
begin
end;
procedure TWritableComponent.beforeLoad;
procedure TCustomWritableComponent.beforeLoad;
begin
end;
procedure TWritableComponent.afterLoad;
procedure TCustomWritableComponent.afterLoad;
begin
end;
procedure TWritableComponent.afterSave;
procedure TCustomWritableComponent.afterSave;
begin
end;
procedure TWritableComponent.setFilename(const aValue: string);
procedure TCustomWritableComponent.setFilename(const aValue: string);
begin
fFilename := aValue;
end;
procedure TWritableComponent.readerPropNoFound(Reader: TReader; Instance: TPersistent;
var PropName: string; IsPath: boolean; var Handled, Skip: Boolean);
begin
Handled := true;
Skip := true;
end;
procedure TWritableComponent.readerError(Reader: TReader; const Message: string;
var Handled: Boolean);
begin
Handled := true;
fHasLoaded := false;
end;
procedure TWritableComponent.saveToFile(const aFilename: string);
procedure TCustomWritableComponent.saveToFile(const aFilename: string);
begin
fHasSaved := true;
beforeSave;
try
saveCompToTxtFile(self, aFilename);
customSaveToFile(aFilename);
except
fHasSaved := false;
end;
@ -88,15 +106,95 @@ begin
afterSave;
end;
procedure TWritableComponent.loadFromFile(const aFilename: string);
procedure TCustomWritableComponent.loadFromFile(const aFilename: string);
begin
fHasLoaded := true;
beforeLoad;
setFilename(aFilename);
loadCompFromTxtFile(self, aFilename, @readerPropNoFound, @readerError);
customLoadFromFile(aFilename);
afterLoad;
end;
{$ENDREGION}
{$REGION TWritableLfmTextComponent ---------------------------------------------}
procedure TWritableLfmTextComponent.customSaveToFile(const aFilename: string);
begin
saveCompToTxtFile(self, aFilename);
end;
procedure TWritableLfmTextComponent.customLoadFromFile(const aFilename: string);
begin
loadCompFromTxtFile(self, aFilename, @readerPropNoFound, @readerError);
end;
procedure TWritableLfmTextComponent.readerPropNoFound(Reader: TReader; Instance: TPersistent;
var PropName: string; IsPath: boolean; var Handled, Skip: Boolean);
begin
Handled := true;
Skip := true;
end;
procedure TWritableLfmTextComponent.readerError(Reader: TReader; const Message: string;
var Handled: Boolean);
begin
Handled := true;
fHasLoaded := false;
end;
{$ENDREGION}
{$REGION TWritableJsonComponent ------------------------------------------------}
procedure TWritableJsonComponent.propertyError(Sender : TObject; AObject : TObject; Info : PPropInfo;
AValue : TJSONData; Error : Exception; Var doContinue : Boolean);
begin
doContinue := true;
end;
procedure TWritableJsonComponent.restoreProperty(Sender : TObject; AObject : TObject; Info : PPropInfo;
AValue : TJSONData; Var Handled : Boolean);
begin
Handled := true;
end;
procedure TWritableJsonComponent.customSaveToFile(const aFilename: string);
var
file_str: TMemoryStream;
json_str: TJSONStreamer;
json_dat: TJSONStringType;
begin
file_str := TMemoryStream.Create;
json_str := TJSONStreamer.Create(nil);
try
json_dat := json_str.ObjectToJSONString(self);
file_str.Write(json_dat[1], length(json_dat));
file_str.SaveToFile(aFilename);
finally
file_str.Free;
json_str.Free;
end;
end;
procedure TWritableJsonComponent.customLoadFromFile(const aFilename: string);
var
file_str: TMemoryStream;
json_str: TJSONDeStreamer;
json_dat: TJSONStringType;
begin
file_str := TMemoryStream.Create;
json_str := TJSONDeStreamer.Create(nil);
try
json_str.OnPropertyError:= @propertyError;
json_str.OnRestoreProperty := @restoreProperty;
file_str.LoadFromFile(aFilename);
setLength(json_dat, file_str.Size);
file_str.Read(json_dat[1], length(json_dat));
json_str.JSONToObject(json_dat, self);
finally
file_str.Free;
json_str.Free;
end;
end;
{$ENDREGION}
initialization
registerClasses([TWritableComponent]);
registerClasses([TCustomWritableComponent, TWritableLfmTextComponent, TWritableJsonComponent]);
end.