From a23fac81148df41a710b5869cf23f6631eb12915 Mon Sep 17 00:00:00 2001 From: Carlo Barazzetta Date: Sun, 13 Sep 2020 22:54:10 +0200 Subject: [PATCH] *Fixed empty editor when writing incorrect svg code. --- Packages/SVGIconImageListEditorUnit.dfm | 13 +++++ Packages/SVGIconImageListEditorUnit.pas | 63 +++++++++++++++++++++++-- Source/D2DSVGFactory.pas | 8 +++- Source/SVGIconItems.pas | 2 +- Svg/SVG.pas | 31 ++++++++---- 5 files changed, 102 insertions(+), 15 deletions(-) diff --git a/Packages/SVGIconImageListEditorUnit.dfm b/Packages/SVGIconImageListEditorUnit.dfm index 2f0c175d..20103be0 100644 --- a/Packages/SVGIconImageListEditorUnit.dfm +++ b/Packages/SVGIconImageListEditorUnit.dfm @@ -370,6 +370,16 @@ object SVGIconImageListEditor: TSVGIconImageListEditor TabOrder = 3 OnClick = HelpButtonClick end + object SVGErrorStaticText: TStaticText + Left = 6 + Top = 3 + Width = 406 + Height = 30 + Anchors = [akLeft, akTop, akRight] + AutoSize = False + TabOrder = 4 + Transparent = False + end end object paIcon: TPanel Left = 0 @@ -501,6 +511,9 @@ object SVGIconImageListEditor: TSVGIconImageListEditor ScrollBars = ssBoth TabOrder = 6 OnChange = SVGTextChange + OnEnter = SVGTextEnter + OnExit = SVGTextExit + OnKeyDown = SVGTextKeyDown end object FixedColorItemComboBox: TColorBox Left = 415 diff --git a/Packages/SVGIconImageListEditorUnit.pas b/Packages/SVGIconImageListEditorUnit.pas index cc2772d2..b38c4c2f 100644 --- a/Packages/SVGIconImageListEditorUnit.pas +++ b/Packages/SVGIconImageListEditorUnit.pas @@ -121,6 +121,7 @@ TSVGIconImageListEditor = class(TForm) DeleteButton: TButton; CategoryEdit: TEdit; CategoryLabel: TLabel; + SVGErrorStaticText: TStaticText; procedure FormCreate(Sender: TObject); procedure ApplyButtonClick(Sender: TObject); procedure ClearAllButtonClick(Sender: TObject); @@ -156,7 +157,12 @@ TSVGIconImageListEditor = class(TForm) procedure SetCategoriesButtonClick(Sender: TObject); procedure DeleteButtonClick(Sender: TObject); procedure CategoryEditExit(Sender: TObject); + procedure SVGTextExit(Sender: TObject); + procedure SVGTextEnter(Sender: TObject); + procedure SVGTextKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); private + FOldSVGText: string; FOpenDialog: TOpenPictureDialogSvg; FSelectedCategory: string; FSourceList, FEditingList: TSVGIconImageList; @@ -173,6 +179,7 @@ TSVGIconImageListEditor = class(TForm) procedure UpdateSizeGUI; procedure AddNewItem; procedure DeleteSelectedItems; + procedure ResetError; public property Modified: Boolean read FModified; property SVGIconImageList: TSVGIconImageList read FEditingList; @@ -538,7 +545,7 @@ procedure TSVGIconImageListEditor.ReplaceButtonClick(Sender: TObject); finally end; end; - BuildList(ImageView.ItemIndex); + BuildList(ImageView.Items[ImageView.ItemIndex].ImageIndex); finally FEditingList.EndUpdate; Screen.Cursor := crDefault; @@ -606,13 +613,61 @@ procedure TSVGIconImageListEditor.SizeSpinEditChange(Sender: TObject); end; procedure TSVGIconImageListEditor.SVGTextChange(Sender: TObject); +var + LOldText: string; begin if FUpdating then Exit; - SelectedIcon.SVGText := SVGText.Lines.Text; - IconImage.Invalidate; + LOldText := SelectedIcon.SVGText; + try + SelectedIcon.SVGText := SVGText.Lines.Text; + ResetError; + IconImage.Repaint; + UpdateGUI; + except + on E: Exception do + begin + SVGErrorStaticText.Caption := E.Message; + SVGErrorStaticText.Hint := E.Message; + SelectedIcon.SVGText := ''; + FEditingList.RecreateBitmaps; + IconImage.Repaint; + ImageView.Invalidate; + end; + end; +end; + +procedure TSVGIconImageListEditor.ResetError; +begin + SVGErrorStaticText.Caption := ''; + SVGErrorStaticText.Hint := ''; +end; + +procedure TSVGIconImageListEditor.SVGTextEnter(Sender: TObject); +begin + FOldSVGText := SVGText.Lines.Text; +end; + +procedure TSVGIconImageListEditor.SVGTextExit(Sender: TObject); +begin + ResetError; UpdateGUI; end; +procedure TSVGIconImageListEditor.SVGTextKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var + LSelStart: Integer; +begin + if (Key = VK_ESCAPE) or ((upcase(Char(Key)) = 'Z') and (ssCtrl in Shift)) then + begin + LSelStart := SVGText.SelStart; + SVGText.Lines.Text := FOldSVGText; + SVGText.SelStart := LSelStart; + SVGText.SelLength := 0; + SelectedIcon.SVGText := FOldSVGText; + end; +end; + procedure TSVGIconImageListEditor.BuildList(Selected: Integer); begin FEditingList.BeginUpdate; @@ -725,6 +780,8 @@ procedure TSVGIconImageListEditor.FormCreate(Sender: TObject); FModified := False; SVGText.Font.Name := 'Courier New'; Caption := Format(Caption, [SVGIconImageListVersion]); + SVGErrorStaticText.Font.Color := clRed; + SVGErrorStaticText.Font.Style := [fsBold]; end; procedure TSVGIconImageListEditor.Apply; diff --git a/Source/D2DSVGFactory.pas b/Source/D2DSVGFactory.pas index 04e6923e..1fa15310 100644 --- a/Source/D2DSVGFactory.pas +++ b/Source/D2DSVGFactory.pas @@ -18,6 +18,9 @@ function RenderTarget: ID2D1DCRenderTarget; // Support functions function WinSvgSupported: Boolean; +resourcestring + D2D_ERROR_PARSING_SVG_TEXT = 'Error parsing SVG Text: %s'; + implementation Uses @@ -166,8 +169,9 @@ procedure TD2DSVG.LoadFromSource; MStream.Free; end; except - fSource := ''; - end; + on E: Exception do + raise Exception.CreateFmt(D2D_ERROR_PARSING_SVG_TEXT, [E.Message]); + end; end; function TD2DSVG.GetFixedColor: TColor; diff --git a/Source/SVGIconItems.pas b/Source/SVGIconItems.pas index 14b37f7a..46b6801a 100644 --- a/Source/SVGIconItems.pas +++ b/Source/SVGIconItems.pas @@ -135,8 +135,8 @@ procedure TSVGIconItem.Assign(Source: TPersistent); constructor TSVGIconItem.Create(Collection: TCollection); begin - inherited Create(Collection); FSVG := GlobalSVGFactory.NewSvg; + inherited Create(Collection); FFixedColor := SVG_INHERIT_COLOR; end; diff --git a/Svg/SVG.pas b/Svg/SVG.pas index 5971fc91..4fab0873 100644 --- a/Svg/SVG.pas +++ b/Svg/SVG.pas @@ -59,6 +59,9 @@ interface SVGStyle, SVGColor; +resourcestring + SVG_ERROR_PARSING_SVG_TEXT = 'Error parsing SVG Text: %s'; + SVG_ERROR_TAG_SVG = 'Error: Tag "svg" not found.'; type TSVG = class; TSVGObject = class; @@ -1991,10 +1994,11 @@ procedure TSVG.LoadFromText(const Text: string); NodeType: XmlNodeType; Name: PWideChar; Len: LongWord; + LOldText: string; begin + LOldText := FSource; Clear; if Text = '' then Exit; - try Reader := CreateXmlLite.Data(Text).Reader; while not Reader.IsEOF do @@ -2003,18 +2007,27 @@ procedure TSVG.LoadFromText(const Text: string); if NodeType = XmlNodeType.Element then begin Reader.GetLocalName(Name, Len); - if Name = 'svg' then - begin - FSource := Text; - ReadIn(Reader); - break; - end - else - Exit; + try + if Name = 'svg' then + begin + FSource := Text; + ReadIn(Reader); + break; + end + else + raise Exception.Create(SVG_ERROR_TAG_SVG); + except + on E: Exception do + begin + FSource := LOldText; + raise Exception.CreateFmt(SVG_ERROR_PARSING_SVG_TEXT, [E.Message]); + end; + end; end; end; except FSource := ''; + raise; end; end;