Ga naar de hoofdnavigatie Ga naar de hoofdinhoud Ga naar de voettekst van de pagina
pascal
 1// {$I RLReport.inc}
 2unit RLPreviewForm;
 3
 4interface
 5
 6uses
 7  Windows, Messages, SysUtils, Math, Contnrs, Classes, ComCtrls, Types, Controls, Forms, Dialogs, Vcl.VirtualImageList,
 8  SVGIconVirtualImageList, Vcl.BaseImageCollection, SVGIconImageCollection, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Buttons,
 9  Graphics, TL.Components, Vcl.Printers, System.StrUtils,
10
11  RLConsts, RLMetaFile, RLPreview, RLFilters, RLUtils, RLPrintDialog, RLSaveDialog, RLPrinters, RLTypes, RLFindDialog,
12  RLComponentFactory, RLAbout, RLSpoolFilter, RLPDFFilter, System.ImageList, Vcl.ImgList, Vcl.Samples.Spin;
13
14type
15  TRLPreviewForm = class(TLForm)
16    ButtonAfdrukken: TButton;
17    ButtonAnnuleren: TButton;
18    ComboBoxDuplex: TComboBox;
19    ComboBoxPrinter: TComboBoxEx;
20    ComboBoxZoom: TComboBox;
21    EditPageNo: TEdit;
22    EditPageSelection: TEdit;
23    Label1: TLabel;
24    Label2: TLabel;
25    Label3: TLabel;
26    Label5: TLabel;
27    Label6: TLabel;
28    PanelComboBoxZoom: TPanel;
29    PanelContainer: TPanel;
30    PanelEditPageNo: TPanel;
31    PanelLeft: TPanel;
32    PanelOf: TPanel;
33    PanelPage: TPanel;
34    PanelPageCount: TPanel;
35    PanelRight: TPanel;
36    PanelTools: TPanel;
37    RadioGroupLayout: TRadioGroup;
38    RadioGroupPages: TRadioGroup;
39    SVGIconImageCollection: TSVGIconImageCollection;
40    SVGIconImageCollectionPrinter: TSVGIconImageCollection;
41    SVGIconVirtualImageList: TSVGIconVirtualImageList;
42    SVGIconVirtualImageListPrinter: TSVGIconVirtualImageList;
43    SpeedButtonFirst: TSpeedButton;
44    SpeedButtonLast: TSpeedButton;
45    SpeedButtonNext: TSpeedButton;
46    SpeedButtonPrior: TSpeedButton;
47    SpeedButtonSearch: TSpeedButton;
48    SpeedButtonViews: TSpeedButton;
49    SpeedButtonZoomDown: TSpeedButton;
50    SpeedButtonZoomUp: TSpeedButton;
51    SpinEditCopies: TSpinEdit;
52    procedure ButtonAnnulerenClick(Sender: TObject);
53    procedure ComboBoxDuplexChange(Sender: TObject);
54    procedure ComboBoxDuplexDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
55    procedure ComboBoxPrinterChange(Sender: TObject);
56    procedure ComboBoxZoomChange(Sender: TObject);
57    procedure EditPageSelectionChange(Sender: TObject);
58    procedure EditPageNoChange(Sender: TObject);
59    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
60    procedure FormResize(Sender: TObject);
61    procedure FormShow(Sender: TObject);
62    procedure SpeedButtonAfdrukkenClick(Sender: TObject);
63    procedure SpeedButtonEditClick(Sender: TObject);
64    procedure SpeedButtonFirstClick(Sender: TObject);
65    procedure SpeedButtonLastClick(Sender: TObject);
66    procedure SpeedButtonSaveClick(Sender: TObject);
67    procedure SpeedButtonSearchClick(Sender: TObject);
68    procedure SpeedButtonSendClick(Sender: TObject);
69    procedure SpeedButtonViewsClick(Sender: TObject);
70    procedure SpeedButtonZoomDownClick(Sender: TObject);
71    procedure SpeedButtonZoomUpClick(Sender: TObject);
72    procedure rpvDefaultChangeView(Sender: TObject);
73    procedure SpinEditCopiesChange(Sender: TObject);
74  private
75    { Private declarations }
76    FEditingPageNo: Boolean;
77    FEditingZoom: Boolean;
78    FFindDialog: TfrmRLFindDialog;
79    FPreviewIndex: Integer;
80    FPreviewList: TObjectList;
81    FSpeedButtonCustomAction: TSpeedButton;
82
83    Device, Driver, Port: string;
84    hDeviceMode: THandle;
85    printCommand: string;
86    printerInfo: string;
87
88    SpeedButtonWidth: Integer;
89    ToolBarHeight: Integer;
90    ToolbarWidth: Integer;
91
92    procedure WMActivate(var Message: TWMActivate); message WM_ACTIVATE;
93
94    procedure InitIcons(var SVGIconVirtualImageList: TSVGIconVirtualImageList);
95
96    function InitLabel(ATop: Integer; ACaption: string): TLabel;
97    function InitPanel(AParent: TWinControl; AName: string; ALeft, AWidth: Integer; ACaption: string;
98      AAlign: TAlign): TPanel;
99    function InitRadioGroup(ATop, Aheight: Integer): TRadioGroup;
100    function InitSpeedButton(AName: string; ALeft, AWidth: Integer; ACaption: string; AImage: string;
101      AOnClick: TNotifyEvent): TSpeedButton;
102
103    procedure Init;
104    procedure NewPreview;
105    procedure ReleasePreview;
106    procedure OrganizePreviews;
107    procedure SetPreview(APreview: TRLPreview);
108    function GetPreview: TRLPreview;
109    procedure PreviewEnter(Sender: TObject);
110    procedure CreateShortCuts;
111    procedure UpdateComboBoxZoom;
112    procedure UpdateEditPageNo;
113    procedure ShowFindDialog;
114    procedure OnFindHandler(Sender: TObject; const AText: string; Options: TRLFindOptions; var Found: Boolean);
115    procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL;
116  protected
117    { Protected declarations }
118    procedure DoClose(var Action: TCloseAction); override;
119    procedure CreateParams(var Params: TCreateParams); override;
120    procedure OnClickRLAbout(Sender: TObject);
121  public
122    { Public declarations }
123    constructor Create(AOwner: TComponent); reintroduce;
124    destructor Destroy; override;
125    procedure SpeedButtonNextClick(Sender: TObject);
126    procedure SpeedButtonPriorClick(Sender: TObject);
127    property Preview: TRLPreview read GetPreview;
128  end;
129
130  TRLPreviewFormButtons = (pbPrint, pbSave, pbSend, pbCustom);
131  TRLPreviewFormButtonsSet = set of TRLPreviewFormButtons;
132  TRLPreviewEditOptions = (eoCanReposition, eoCanResizeItems, eoCanEditText, eoCanDeleteItems, eoCanPointOut);
133  TRLPreviewEditOptionsSet = set of TRLPreviewEditOptions;
134
135  { Standaard preview-opties.
136    Rapporten die geen eigen preview-instellingen hebben,
137    volgen de regels die in dit onderdeel worden beschreven. }
138
139  [ComponentPlatformsAttribute(pidWin32 or pidWin64)]
140  TRLPreviewSetup = class(TComponent)
141  private
142    FBeforePrint: TNotifyEvent;
143    FAfterPrint: TNotifyEvent;
144    FBeforeSave: TNotifyEvent;
145    FAfterSave: TNotifyEvent;
146    FBeforeSend: TNotifyEvent;
147    FOnSend: TNotifyEvent;
148    FAfterSend: TNotifyEvent;
149    FEnabledButtons: TRLPreviewFormButtonsSet;
150    FEditOptions: TRLPreviewEditOptionsSet;
151    FCustomActionText: string;
152    FOnCustomAction: TNotifyEvent;
153    function GetBorderIcons: TBorderIcons;
154    function GetCaption: string;
155    function GetFormStyle: TFormStyle;
156    function GetHelpContext: Integer;
157    function GetHelpFile: string;
158    function GetPosition: TPosition;
159    function GetSentToPrinter: Boolean;
160    function GetShowModal: Boolean;
161    function GetWindowBounds: TRect;
162    function GetWindowState: TWindowState;
163    function GetZoomFactor: Double;
164    procedure SetBorderIcons(const Value: TBorderIcons);
165    procedure SetCaption(const Value: string);
166    procedure SetFormStyle(const Value: TFormStyle);
167    procedure SetHelpContext(const Value: Integer);
168    procedure SetHelpFile(const Value: string);
169    procedure SetPosition(const Value: TPosition);
170    procedure SetSentToPrinter(const Value: Boolean);
171    procedure SetShowModal(const Value: Boolean);
172    procedure SetWindowBounds(const Value: TRect);
173    procedure SetWindowState(const Value: TWindowState);
174    procedure SetZoomFactor(const Value: Double);
175    function IsZoomFactor: Boolean;
176    procedure SetEnabledButtons(const Value: TRLPreviewFormButtonsSet);
177    procedure SetEditOptions(const Value: TRLPreviewEditOptionsSet);
178  public
179    { Public declarations }
180    constructor Create(AOwner: TComponent); override;
181    destructor Destroy; override;
182
183    { Geeft aan of het rapport minstens één keer is afgedrukt. :/ }
184    property SentToPrinter: Boolean read GetSentToPrinter write SetSentToPrinter;
185
186    { Specificeert of bepaalt de standaardafmetingen van het venster wanneer het niet gemaximaliseerd is. :/ }
187    property WindowBounds: TRect read GetWindowBounds write SetWindowBounds;
188  published
189    { Geeft de begintoestand van het voorbeeldvenster aan. :/ }
190    property WindowState: TWindowState read GetWindowState write SetWindowState default wsMaximized;
191
192    { Geeft de stijl van het voorbeeldvenster aan. :/ }
193    property FormStyle: TFormStyle read GetFormStyle write SetFormStyle default fsNormal;
194
195    { Geeft aan of het voorbeeldvenster modaal wordt weergegeven. :/ }
196    property ShowModal: Boolean read GetShowModal write SetShowModal default False;
197
198    { Geeft de positie van het voorbeeldvenster aan. :/ }
199    property Position: TPosition read GetPosition write SetPosition default poScreenCenter;
200
201    { Selecteert de knoppen in het voorbeeldvenster. :/ }
202    property BorderIcons: TBorderIcons read GetBorderIcons write SetBorderIcons
203      default [biSystemMenu, biMinimize, biMaximize];
204
205    { Naam van het helpbestand voor het voorbeeldvenster, indien aanwezig. :/ }
206    property HelpFile: string read GetHelpFile write SetHelpFile;
207
208    { Helpcontext voor het voorbeeldvenster, indien aanwezig. :/ }
209    property HelpContext: Integer read GetHelpContext write SetHelpContext default 0;
210
211    { Titel van het voorbeeldvenster. :/ }
212    property Caption: string read GetCaption write SetCaption;
213
214    { Initiële zoomfactor (percentage). :/ }
215    property ZoomFactor: Double read GetZoomFactor write SetZoomFactor stored IsZoomFactor;
216
217    { Ingeschakelde knoppen.
218      Met deze prop kun je knoppen op de werkbalk weergeven of verbergen.
219      @links TRLPreviewFormButtonsSet. :/ }
220    property EnabledButtons: TRLPreviewFormButtonsSet read FEnabledButtons write SetEnabledButtons
221      default [pbPrint, pbSave, pbSend];
222
223    property CustomActionText: string read FCustomActionText write FCustomActionText;
224    property OnCustomAction: TNotifyEvent read FOnCustomAction write FOnCustomAction;
225
226    { Bewerkingsopties (nog niet beschikbaar).
227      Bepaalt welke bewerkingen door de gebruiker kunnen worden uitgevoerd op de inhoud van het
228      reeds voorbereide rapport.
229      @links TRLPreviewEditOptions,TRLPreviewEditOptionsSet. :/ }
230    property EditOptions: TRLPreviewEditOptionsSet read FEditOptions write SetEditOptions default [];
231
232    { Altijd vóór het afdrukken of wanneer de gebruiker op de knop "Afdrukken" drukt. :/ }
233    property BeforePrint: TNotifyEvent read FBeforePrint write FBeforePrint;
234
235    { Altijd na het afdrukken of wanneer het afdrukfilter alle pagina's heeft verwerkt. :/ }
236    property AfterPrint: TNotifyEvent read FAfterPrint write FAfterPrint;
237
238    { Altijd vóór het opslaan/exporteren of wanneer de gebruiker op de knop "Opslaan" klikt. :/ }
239    property BeforeSave: TNotifyEvent read FBeforeSave write FBeforeSave;
240
241    { Altijd na het opslaan/exporteren of wanneer het opslagfilter alle pagina's heeft verwerkt. :/ }
242    property AfterSave: TNotifyEvent read FAfterSave write FAfterSave;
243
244    { Altijd voordat het rapport via e-mail wordt verzonden of wanneer de gebruiker op de knop 'Verzenden' klikt. :/ }
245    property BeforeSend: TNotifyEvent read FBeforeSend write FBeforeSend;
246
247    { Altijd bij het verzenden van een rapport via e-mail.
248      De programmeur moet deze gebeurtenis implementeren en ervoor zorgen dat het rapport wordt verzonden.
249      FortesReport biedt deze routine niet, maar alleen de interface ervoor }
250    property OnSend: TNotifyEvent read FOnSend write FOnSend;
251
252    { Altijd nadat het rapport via e-mail is verzonden. :/ }
253    property AfterSend: TNotifyEvent read FAfterSend write FAfterSend;
254  end;
255
256const
257  ZoomFactorFullWidth = -1;
258  ZoomFactorFullPage = -2;
259  ZoomFactorMultiplePages = -3;
260
261type
262  TOnCreatePreviewFormProc = procedure(PreviewForm: TRLPreviewForm);
263
264var
265  DefaultWindowState: TWindowState = wsMaximized;
266  DefaultWindowBounds: TRect;
267  DefaultFormStyle: TFormStyle = fsNormal;
268  DefaultShowModal: Boolean = False;
269  DefaultPosition: TPosition = poScreenCenter;
270  DefaultBorderIcons: TBorderIcons = [biSystemMenu, biMinimize, biMaximize];
271  DefaultHelpFile: string = '';
272  DefaultHelpContext: Integer = 0;
273  DefaultCaption: string = '';
274  DefaultZoomFactor: Double = 100;
275  SentToPrinter: Boolean = False;
276  OnCreatePreviewForm: TOnCreatePreviewFormProc = nil;
277  ShowPreviewOnWindowsTaskBar: Boolean = False;
278
279  { Geeft het standaardvoorbeeldformulier weer met opties }
280procedure PreviewPagesWithOptions(APages: TRLGraphicStorage; AShowModal: Boolean; AFormStyle: TFormStyle;
281  APosition: TPosition; AWindowState: TWindowState; ABorderIcons: TBorderIcons; const AHelpFile: string;
282  AHelpContext: Integer; ACaption: TCaption);
283
284{ Geeft het standaardvoorbeeldformulier weer met standaardopties }
285procedure PreviewPages(APages: TRLGraphicStorage);
286
287{ Laadt het rapportbestand en geeft het standaardvoorbeeldformulier weer }
288procedure PreviewFromFile(const AFileName: string);
289
290{ Laadt de rapportstream en geeft het standaardvoorbeeldformulier weer }
291procedure PreviewFromStream(AStream: TStream);
292
293{ Geeft een dialoogvenster weer voor het laden van een rapportbestand en
294  geeft het standaardvoorbeeld weer }
295procedure PreviewFromFileDialog;
296
297implementation
298
299{$R *.dfm}
300
301var
302  SetupInstance: TRLPreviewSetup = nil;
303
304procedure PreviewPagesWithOptions(APages: TRLGraphicStorage; AShowModal: Boolean; AFormStyle: TFormStyle;
305  APosition: TPosition; AWindowState: TWindowState; ABorderIcons: TBorderIcons; const AHelpFile: string;
306  AHelpContext: Integer; ACaption: TCaption);
307begin
308  SentToPrinter:= False;
309  with TRLPreviewForm.Create(nil) do
310    begin
311      name:= 'frmPreview';
312      Preview.Pages:= APages;
313      if DefaultZoomFactor = ZoomFactorFullWidth then
314        Preview.ZoomFullWidth
315      else if DefaultZoomFactor = ZoomFactorFullPage then
316        Preview.ZoomFullPage
317      else if DefaultZoomFactor = ZoomFactorMultiplePages then
318        Preview.ZoomMultiplePages
319      else if DefaultZoomFactor > 0 then
320        Preview.ZoomFactor:= DefaultZoomFactor;
321      UpdateComboBoxZoom;
322
323      { Will be handled bij TLForm }
324      // Position:= APosition;
325      // WindowState:= AWindowState;
326
327      BorderIcons:= ABorderIcons;
328      HelpFile:= AHelpFile;
329      HelpContext:= AHelpContext;
330      if ACaption <> '' then
331        Caption:= ACaption;
332      FormStyle:= AFormStyle;
333      if AShowModal then
334        ShowModal
335      else if Visible then
336        BringToFront
337      else
338        Show;
339    end;
340end;
341
342procedure PreviewPages(APages: TRLGraphicStorage);
343begin
344  PreviewPagesWithOptions(APages, DefaultShowModal, DefaultFormStyle, DefaultPosition, DefaultWindowState,
345    DefaultBorderIcons, DefaultHelpFile, DefaultHelpContext, DefaultCaption);
346end;
347
348procedure PreviewFromFile(const AFileName: string);
349var
350  savecursor: TCursor;
351  Pages: TRLGraphicStorage;
352begin
353  if not FileExists(AFileName) then
354    raise Exception.Create(GetLocalizeStr(LocaleStrings.LS_FileNotFoundStr + ' "' + AFileName + '"'));
355  Pages:= TRLGraphicStorage.Create;
356  try
357    savecursor:= Screen.Cursor;
358    Screen.Cursor:= crHourGlass;
359    try
360      Pages.LoadFromFile(AFileName);
361    finally
362      Screen.Cursor:= savecursor;
363    end;
364    PreviewPages(Pages);
365  finally
366    Pages.Unlink;
367  end;
368end;
369
370procedure PreviewFromStream(AStream: TStream);
371var
372  savecursor: TCursor;
373  Pages: TRLGraphicStorage;
374begin
375  Pages:= TRLGraphicStorage.Create;
376  try
377    savecursor:= Screen.Cursor;
378    Screen.Cursor:= crHourGlass;
379    try
380      Pages.LoadFromStream(AStream);
381    finally
382      Screen.Cursor:= savecursor;
383    end;
384    PreviewPages(Pages);
385  finally
386    Pages.Unlink;
387  end;
388end;
389
390procedure PreviewFromFileDialog;
391var
392  OpenDialog: TOpenDialog;
393begin
394  TRLComponentFactory.CreateComponent(TOpenDialog, nil, OpenDialog);
395  with OpenDialog do
396    try
397      DefaultExt:= FormatFileExt(ReportFileExt);
398      Filter:= AddFileFilter('', CS_ProductTitleStr, ReportFileExt);
399      FilterIndex:= 1;
400      Title:= GetLocalizeStr(LocaleStrings.LS_LoadReportStr);
401      if Execute then
402        PreviewFromFile(FileName);
403    finally
404      Free;
405    end;
406end;
407
408constructor TRLPreviewForm.Create(AOwner: TComponent);
409begin
410  DoCreate;
411  if ShowPreviewOnWindowsTaskBar then
412    ParentWindow:= 0;
413  FPreviewList:= nil;
414  FPreviewIndex:= 0;
415  FEditingZoom:= False;
416  FEditingPageNo:= False;
417  FFindDialog:= nil;
418  FSpeedButtonCustomAction:= nil;
419  inherited CreateNew(AOwner);
420  FPreviewList:= TObjectList.Create;
421  Init;
422  CreateShortCuts;
423  NewPreview;
424  OrganizePreviews;
425end;
426
427destructor TRLPreviewForm.Destroy;
428begin
429  // DoDestroy;
430  FPreviewList.Free;
431  if Assigned(FFindDialog) then
432    FFindDialog.Free;
433  inherited;
434end;
435
436procedure TRLPreviewForm.CreateShortCuts;
437var
438  L: TStringList;
439  B: TSpeedButton;
440  ch: Char;
441  K, N: string;
442  I, J: Integer;
443  function IsValidCaption(const ACaption: string): Boolean;
444  var
445    I: Integer;
446  begin
447    Result:= False;
448    for I:= 1 to Length(ACaption) do
449      if CharInSet(ACaption[I], ['A' .. 'Z', 'a' .. 'z', '0' .. '9']) then
450        begin
451          Result:= True;
452          Break;
453        end;
454  end;
455
456begin
457  L:= TStringList.Create;
458  try
459    //
460    for I:= 0 to ComponentCount - 1 do
461      if Components[I] is TSpeedButton then
462        begin
463          B:= TSpeedButton(Components[I]);
464          if IsValidCaption(B.Caption) then
465            L.AddObject(B.Caption, B);
466        end;
467    K:= '';
468    for I:= 0 to L.Count - 1 do
469      begin
470        N:= L[I];
471        for J:= 1 to Length(N) do
472          begin
473            ch:= UpCase(N[J]);
474            if CharInSet(ch, ['A' .. 'Z', '0' .. '9']) and (Pos(ch, K) = 0) then
475              begin
476                Insert('&', N, J);
477                L[I]:= N;
478                K:= K + ch;
479                Break;
480              end;
481          end;
482      end;
483    for I:= 0 to L.Count - 1 do
484      TSpeedButton(L.Objects[I]).Caption:= L[I];
485  finally
486    L.Free;
487  end;
488end;
489
490procedure TRLPreviewForm.OrganizePreviews;
491var
492  I, T, W: Integer;
493  N: TControl;
494  S: TSplitter;
495begin
496  if FPreviewList.Count > 0 then
497    begin
498      for I:= FPreviewList.Count - 1 downto 0 do
499        begin
500          N:= TControl(TRLPreview(FPreviewList[I]));
501          S:= TSplitter(N.Tag);
502          S.Align:= alNone;
503          N.Align:= alNone;
504        end;
505      W:= ClientHeight div FPreviewList.Count;
506      T:= 0;
507      for I:= 0 to FPreviewList.Count - 1 do
508        begin
509          N:= TControl(TRLPreview(FPreviewList[I]));
510          S:= TSplitter(N.Tag);
511          N.Height:= W;
512          if I = FPreviewList.Count - 1 then
513            begin
514              N.Align:= alClient;
515              S.Hide;
516            end
517          else
518            begin
519              N.Align:= alTop;
520              N.Height:= W;
521              N.Top:= T;
522              Inc(T, N.Height);
523              S.Align:= alTop;
524              S.Height:= 3;
525              S.Visible:= True;
526              S.Top:= T;
527              Inc(T, S.Height);
528            end;
529        end;
530    end;
531end;
532
533procedure TRLPreviewForm.NewPreview;
534var
535  N: TRLPreview;
536  S: TSplitter;
537begin
538  N:= TRLPreview.Create(nil);
539  with N do
540    begin
541      Width:= 0;
542      OnChangeView:= rpvDefaultChangeView;
543      OnEnter:= PreviewEnter;
544    end;
545  TControl(N).Parent:= PanelContainer;
546  TRLComponentFactory.CreateComponent(TSplitter, Self, S);
547  with S do
548    begin
549      AutoSnap:= False;
550      Width:= 0;
551      Parent:= PanelContainer;
552    end;
553  N.Tag:= PtrInt(S);
554  FPreviewList.Add(N);
555  if FPreviewList.Count > 1 then
556    N.Pages:= TRLPreview(FPreviewList[0]).Pages;
557end;
558
559procedure TRLPreviewForm.ReleasePreview;
560begin
561  if FPreviewList.Count > 1 then
562    begin
563      FPreviewList.Delete(FPreviewList.Count - 1);
564      if FPreviewIndex > FPreviewList.Count - 1 then
565        SetPreview(TRLPreview(FPreviewList[FPreviewList.Count - 1]));
566    end;
567end;
568
569procedure TRLPreviewForm.InitIcons(var SVGIconVirtualImageList: TSVGIconVirtualImageList);
570var
571  SvgIconItem: TSVGIconItem;
572begin
573  SVGIconImageCollection:= TSVGIconImageCollection.Create(nil);
574  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
575  with SvgIconItem do
576    begin
577      IconName:= 'actions-caret-bar-left';
578      SVGText:= // the text of image in SVG format
579        '<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> '
580        + '<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> ' +
581        '<path d="M10 12L9.64645 11.6464L9.29289 12L9.64645 12.3536L10 12ZM20 12.5C20.2761 12.5 20.5 12.2761 20.5 12C20.5 11.7239 20.2761 11.5 20 11.5V12.5ZM15.6464 5.64645L9.64645 11.6464L10.3536 12.3536L16.3536 6.35355L15.6464 5.64645ZM9.64645 12.3536L15.6464 18.3536L16.3536 17.6464L10.3536 11.6464L9.64645 12.3536ZM10 12.5H20V11.5H10V12.5Z" fill="#222222"/> '
582        + '<path d="M4 5L4 19" stroke="#222222"/> ' + '</svg> ';
583    end;
584  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
585  with SvgIconItem do
586    begin
587      IconName:= 'actions-caret-bar-right';
588      SVGText:= '<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> '
589        + '<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> ' +
590        '<path d="M14 12L14.3536 11.6464L14.7071 12L14.3536 12.3536L14 12ZM4 12.5C3.72386 12.5 3.5 12.2761 3.5 12C3.5 11.7239 3.72386 11.5 4 11.5V12.5ZM8.35355 5.64645L14.3536 11.6464L13.6464 12.3536L7.64645 6.35355L8.35355 5.64645ZM14.3536 12.3536L8.35355 18.3536L7.64645 17.6464L13.6464 11.6464L14.3536 12.3536ZM14 12.5H4V11.5H14V12.5Z" fill="#222222"/> '
591        + '<path d="M20 5L20 19" stroke="#222222"/> ' + '</svg> ';
592    end;
593  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
594  with SvgIconItem do
595    begin
596      IconName:= 'actions-caret-left';
597      SVGText:= '<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> '
598        + '<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> ' +
599        '<path d="M4 12L3.64645 11.6464L3.29289 12L3.64645 12.3536L4 12ZM19 12.5C19.2761 12.5 19.5 12.2761 19.5 12C19.5 11.7239 19.2761 11.5 19 11.5V12.5ZM9.64645 5.64645L3.64645 11.6464L4.35355 12.3536L10.3536 6.35355L9.64645 5.64645ZM3.64645 12.3536L9.64645 18.3536L10.3536 17.6464L4.35355 11.6464L3.64645 12.3536ZM4 12.5H19V11.5H4V12.5Z" fill="#222222"/> '
600        + '</svg> ';
601    end;
602  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
603  with SvgIconItem do
604    begin
605      IconName:= 'actions-caret-right';
606      SVGText:= '<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> '
607        + '<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> ' +
608        '<path d="M20 12L20.3536 11.6464L20.7071 12L20.3536 12.3536L20 12ZM5 12.5C4.72386 12.5 4.5 12.2761 4.5 12C4.5 11.7239 4.72386 11.5 5 11.5V12.5ZM14.3536 5.64645L20.3536 11.6464L19.6464 12.3536L13.6464 6.35355L14.3536 5.64645ZM20.3536 12.3536L14.3536 18.3536L13.6464 17.6464L19.6464 11.6464L20.3536 12.3536ZM20 12.5H5V11.5H20V12.5Z" fill="#222222"/> '
609        + '</svg> ';
610    end;
611  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
612  with SvgIconItem do
613    begin
614      IconName:= 'zoom-in';
615      SVGText:= '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" '
616        + '	 width="800px" height="800px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"> '
617        + '<g> ' +
618        '	<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="12" y1="21" x2="30" y2="21"/> '
619        + '	<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="21" y1="12" x2="21" y2="30"/> '
620        + '</g> ' + '<g> ' +
621        '	<circle fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" cx="21" cy="21" r="20"/> ' +
622        '	<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="35" y1="35" x2="41" y2="41"/> '
623        + ' ' + '		<rect x="46.257" y="37.065" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 121.9178 50.5)" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" width="8.485" height="26.87"/> '
624        + '</g> ' + '</svg> ';
625
626    end;
627  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
628  with SvgIconItem do
629    begin
630      IconName:= 'zoom-out';
631      SVGText:= '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" '
632        + '	 width="800px" height="800px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"> '
633        + '<g> ' +
634        '	<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="12" y1="21" x2="30" y2="21"/> '
635        + '</g> ' + '<g> ' +
636        '	<circle fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" cx="21" cy="21" r="20"/> ' +
637        '	<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="35" y1="35" x2="41" y2="41"/> '
638        + ' ' + '		<rect x="46.257" y="37.065" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 121.9178 50.5)" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" width="8.485" height="26.87"/> '
639        + '</g> ' + '</svg> ';
640
641    end;
642  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
643  with SvgIconItem do
644    begin
645      IconName:= 'component-divider-vertical';
646      SVGText:= '<svg height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" '
647        + '	 viewBox="0 0 513.151 513.151" xml:space="preserve"> ' + '<g> ' +
648        '	<path style="fill:#010002;" d="M466.985,166.637c-0.036-0.531-0.137-1.044-0.31-1.545c-0.066-0.191-0.113-0.37-0.197-0.555 '
649        + '		c-0.292-0.632-0.656-1.235-1.169-1.748L304.269,1.742c-0.513-0.513-1.11-0.877-1.742-1.164c-0.185-0.09-0.376-0.137-0.573-0.203 '
650        + '		c-0.495-0.167-0.991-0.269-1.51-0.298C300.307,0.066,300.187,0,300.056,0H135.597c-3.294,0-5.967,2.673-5.967,5.967v70.111H52.061 '
651        + '		c-3.294,0-5.967,2.673-5.967,5.967v425.139c0,3.3,2.673,5.967,5.967,5.967h325.493c3.3,0,5.967-2.667,5.967-5.967v-70.111h77.569 '
652        + '		c3.3,0,5.967-2.667,5.967-5.967V167.001C467.057,166.875,466.991,166.762,466.985,166.637z M141.564,11.928h152.519v139.243 '
653        + '		L220.732,77.82c-0.513-0.513-1.11-0.877-1.742-1.164c-0.185-0.09-0.376-0.137-0.573-0.203c-0.495-0.167-0.991-0.269-1.51-0.298 '
654        + '		c-0.137-0.012-0.257-0.078-0.388-0.078h-74.956V11.928z M371.587,425.134v11.934v64.144H58.028V88.005h71.602h11.934h68.983 '
655        + '		v155.073c0,3.294,2.673,5.967,5.967,5.967h155.073V425.134z M455.123,425.134h-71.602V243.078c0-0.125-0.066-0.239-0.072-0.364 '
656        + '		c-0.036-0.531-0.137-1.044-0.31-1.545c-0.066-0.191-0.113-0.37-0.197-0.555c-0.292-0.632-0.656-1.235-1.169-1.748l-65.892-65.898 '
657        + '		h139.243V425.134z"/> ' + '</g> ' + '</svg> ';
658
659    end;
660  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
661  with SvgIconItem do
662    begin
663      IconName:= 'print-outline';
664      SVGText:= '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"' +
665        ' viewBox="0 0 24 24"><path fill="currentColor" d="M16 8.616v-3H8' +
666        'v3H7v-4h10v4zm-11.423 1h14.846zm13.038 2.5q.425 0 .713-.288t.287' +
667        '-.712t-.287-.713t-.713-.288t-.712.288t-.288.713t.288.712t.713.28' +
668        '8M16 19v-4.538H8V19zm1 1H7v-4H3.577v-5.384q0-.85.577-1.425t1.423' +
669        '-.576h12.846q.85 0 1.425.576t.575 1.424V16H17zm2.423-5v-4.384q0-' +
670        '.425-.287-.713t-.713-.288H5.577q-.425 0-.712.288t-.288.713V15H7v' + '-1.538h10V15z"/></svg>';
671    end;
672  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
673  with SvgIconItem do
674    begin
675      IconName:= 'find-filled';
676      SVGText:= '<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M17 16h-5.525a5.95 5.95 0 0 0-.172-1H17zm2-7h-9v1h9zm0 3h-9v.544q.193.22.364.456H19zm3 8H11.818l-.913-.913c.014-.028.023-.059.037-.087H21V7h-4V3H8v8.053a5.945 5.945 0 0 0-1-.356V2h11.4L22 5.6zM21 5.69L18.31 3H18v3h3zM8.926 19.23l3.085 3.084a.476.476 0 0 1 0 .674l-.017.017a.476.476 0 0 1-.673 0L8.237 19.92A4.383 4.383 0 1 1 9.9 16.5a4.358 4.358 0 0 1-.974 2.73zM5.5 19.9a3.4 3.4 0 1 0-3.4-3.4 3.404 3.404 0 0 0 3.4 3.4z"/><path fill="none" d="M0 0h24v24H0z"/></svg> ';
677    end;
678  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
679  with SvgIconItem do
680    begin
681      IconName:= 'save';
682      SVGText:= '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"' +
683        ' viewBox="0 0 32 32"><path fill="currentColor" d="m27.71 9.29l-5' +
684        '-5A1 1 0 0 0 22 4H6a2 2 0 0 0-2 2v20a2 2 0 0 0 2 2h20a2 2 0 0 0 ' +
685        '2-2V10a1 1 0 0 0-.29-.71M12 6h8v4h-8Zm8 20h-8v-8h8Zm2 0v-8a2 2 0' +
686        ' 0 0-2-2h-8a2 2 0 0 0-2 2v8H6V6h4v4a2 2 0 0 0 2 2h8a2 2 0 0 0 2-' + '2V6.41l4 4V26Z"/></svg>';
687    end;
688  SvgIconItem:= SVGIconImageCollection.SVGIconItems.Add;
689  with SvgIconItem do
690    begin
691      IconName:= 'close-light';
692
693      SVGText:= '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"' +
694        ' viewBox="0 0 24 24"><path fill="none" stroke="currentColor" str' +
695        'oke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d' + '="m7 7l10 10M7 17L17 7"/></svg>';
696    end;
697
698  SVGIconImageCollectionPrinter:= TSVGIconImageCollection.Create(nil);
699  // Add SVG icons to the collection
700  SvgIconItem:= SVGIconImageCollectionPrinter.SVGIconItems.Add;
701  with SvgIconItem do
702    begin
703      IconName:= 'printer-storing';
704      SVGText:= '<svg viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="h' +
705        'ttp://www.w3.org/2000/svg" fill="#000000"><g id="SVGRepo_bgCarri' +
706        'er" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-li' +
707        'necap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCar' +
708        'rier"><path d="M276.8 302.3h470.4v212.3H276.8z" fill="#FFD632"><' +
709        '/path><path d="M752.7 520.1H271.3V296.8h481.4v223.3z m-470.4-11h' +
710        '459.4V307.8H282.3v201.3z" fill="#333336"></path><path d="M363.8 ' +
711        '192.8h296.5v271.6H363.8z" fill="#ECEFE8"></path><path d="M665.7 ' +
712        '470H358.3V187.3h307.5V470z m-296.4-11h285.5V198.3H369.3V459z" fi' +
713        'll="#333336"></path><path d="M842.7 781.8H181.3c-19.1 0-34.6-15.' +
714        '5-34.6-34.6V460.9c0-19.1 15.5-34.6 34.6-34.6h661.4c19.1 0 34.6 1' +
715        '5.5 34.6 34.6v286.3c0 19.1-15.5 34.6-34.6 34.6z" fill="#ff0000">' +
716        '</path><path d="M842.7 787.3H181.3c-22.1 0-40.1-18-40.1-40.1V460' +
717        '.9c0-22.1 18-40.1 40.1-40.1h661.4c22.1 0 40.1 18 40.1 40.1v286.3' +
718        'c0 22.1-18 40.1-40.1 40.1zM181.3 431.8c-16 0-29.1 13.1-29.1 29.1' +
719        'v286.3c0 16 13.1 29.1 29.1 29.1h661.4c16 0 29.1-13.1 29.1-29.1V4' +
720        '60.9c0-16-13.1-29.1-29.1-29.1H181.3z" fill="#333336"></path><pat' +
721        'h d="M822 831.2H202l-11.3-49.4h642.6z" fill="#D5D9CF"></path><pa' +
722        'th d="M826.4 836.7H197.6l-13.7-60.4h656.3l-13.8 60.4z m-620-11h6' +
723        '11.3l8.7-38.4H197.6l8.8 38.4z" fill="#333336"></path><path d="M7' +
724        '58.5 781.8h-493V667.1c0-19.7 16-35.7 35.7-35.7h421.6c19.7 0 35.7' +
725        ' 16 35.7 35.7v114.7z" fill="#D5D9CF"></path><path d="M764 787.3H' +
726        '260V667.1c0-22.7 18.5-41.2 41.2-41.2h421.6c22.7 0 41.2 18.5 41.2' +
727        ' 41.2v120.2z m-493-11h482V667.1c0-16.6-13.5-30.2-30.2-30.2H301.2' +
728        'c-16.6 0-30.2 13.5-30.2 30.2v109.2z" fill="#333336"></path><path' +
729        ' d="M265.5 738h493v43.8h-493z" fill="#ff0000"></path><path d="M7' +
730        '64 787.3H260v-54.8h504v54.8z m-493-11h482v-32.8H271v32.8z" fill=' +
731        '"#333336"></path><path d="M575.2 584.3V482.1c0-12.8 10.4-23.3 23' +
732        '.3-23.3h220c12.8 0 23.3 10.4 23.3 23.3v102.1" fill="#FFD632"></p' +
733        'ath><path d="M847.2 584.3h-11V482.1c0-9.8-8-17.8-17.8-17.8h-220c' +
734        '-9.8 0-17.8 8-17.8 17.8v102.1h-11V482.1c0-15.9 12.9-28.8 28.8-28' +
735        '.8h220c15.9 0 28.8 12.9 28.8 28.8v102.2z" fill="#333336"></path>' +
736        '<path d="M145.1 578.8h730.6v11H145.1z" fill="#333336"></path><pa' +
737        'th d="M784.5 523.1m-23 0a23 23 0 1 0 46 0 23 23 0 1 0-46 0Z" fil' +
738        'l="#ECEFE8"></path><path d="M784.5 550.1c-14.9 0-27-12.1-27-27s1' +
739        '2.1-27 27-27 27 12.1 27 27-12.1 27-27 27z m0-46c-10.5 0-19 8.5-1' +
740        '9 19s8.5 19 19 19 19-8.5 19-19-8.5-19-19-19z" fill="#333336"></p' +
741        'ath><path d="M627.7 545.8l-16.6-16.6c-3.6-3.6-3.6-9.4 0-13l16.6-' +
742        '16.6c5.8-5.8 15.7-1.7 15.7 6.5v33.2c0 8.2-9.9 12.3-15.7 6.5z" fi' +
743        'll="#ECEFE8"></path><path d="M634.1 552.5c-3.4 0-6.7-1.3-9.3-3.9' +
744        'L608.2 532c-2.5-2.5-3.9-5.8-3.9-9.3 0-3.5 1.4-6.9 3.9-9.3l16.6-1' +
745        '6.6c3.9-3.9 9.4-5 14.4-2.9s8.2 6.8 8.2 12.2v33.2c0 5.4-3.1 10.1-' +
746        '8.2 12.2-1.6 0.7-3.4 1-5.1 1z m0-51.7c-1.1 0-2.4 0.3-3.6 1.5L613' +
747        '.9 519c-1 1-1.5 2.3-1.5 3.7 0 1.4 0.5 2.7 1.5 3.7l16.6 16.6c2.3 ' +
748        '2.3 4.9 1.4 5.7 1.1 0.8-0.3 3.2-1.6 3.2-4.8v-33.2c0-3.2-2.5-4.5-' +
749        '3.2-4.8-0.4-0.2-1.1-0.5-2.1-0.5z" fill="#333336"></path><path d=' +
750        '"M699 545.8l16.6-16.6c3.6-3.6 3.6-9.4 0-13L699 499.5c-5.8-5.8-15' +
751        '.7-1.7-15.7 6.5v33.2c-0.1 8.3 9.8 12.4 15.7 6.6z" fill="#ECEFE8"' +
752        '></path><path d="M692.5 552.5c-1.7 0-3.5-0.3-5.1-1-5-2.1-8.2-6.8' +
753        '-8.2-12.2v-33.2c0-5.4 3.1-10.1 8.2-12.2 5-2.1 10.6-1 14.4 2.9l16' +
754        '.6 16.6c5.2 5.2 5.2 13.5 0 18.7l-16.6 16.6c-2.6 2.5-5.9 3.8-9.3 ' +
755        '3.8z m0-51.7c-1 0-1.7 0.3-2.1 0.4-0.8 0.3-3.2 1.6-3.2 4.8v33.2c0' +
756        ' 3.2 2.5 4.5 3.2 4.8 0.8 0.3 3.4 1.2 5.7-1.1l16.6-16.6c2-2 2-5.3' +
757        ' 0-7.4l-16.6-16.6c-1.2-1.1-2.5-1.5-3.6-1.5z" fill="#333336"></pa' + 'th></g></svg>'
758
759    end;
760
761  SvgIconItem:= SVGIconImageCollectionPrinter.SVGIconItems.Add;
762  with SvgIconItem do
763    begin
764      IconName:= 'printer-beschikbaar';
765      SVGText:= '<svg viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="h' +
766        'ttp://www.w3.org/2000/svg" fill="#000000"><g id="SVGRepo_bgCarri' +
767        'er" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-li' +
768        'necap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCar' +
769        'rier"><path d="M276.8 302.3h470.4v212.3H276.8z" fill="#FFD632"><' +
770        '/path><path d="M752.7 520.1H271.3V296.8h481.4v223.3z m-470.4-11h' +
771        '459.4V307.8H282.3v201.3z" fill="#333336"></path><path d="M363.8 ' +
772        '192.8h296.5v271.6H363.8z" fill="#ECEFE8"></path><path d="M665.7 ' +
773        '470H358.3V187.3h307.5V470z m-296.4-11h285.5V198.3H369.3V459z" fi' +
774        'll="#333336"></path><path d="M842.7 781.8H181.3c-19.1 0-34.6-15.' +
775        '5-34.6-34.6V460.9c0-19.1 15.5-34.6 34.6-34.6h661.4c19.1 0 34.6 1' +
776        '5.5 34.6 34.6v286.3c0 19.1-15.5 34.6-34.6 34.6z" fill="#68A"></p' +
777        'ath><path d="M842.7 787.3H181.3c-22.1 0-40.1-18-40.1-40.1V460.9c' +
778        '0-22.1 18-40.1 40.1-40.1h661.4c22.1 0 40.1 18 40.1 40.1v286.3c0 ' +
779        '22.1-18 40.1-40.1 40.1zM181.3 431.8c-16 0-29.1 13.1-29.1 29.1v28' +
780        '6.3c0 16 13.1 29.1 29.1 29.1h661.4c16 0 29.1-13.1 29.1-29.1V460.' +
781        '9c0-16-13.1-29.1-29.1-29.1H181.3z" fill="#333336"></path><path d' +
782        '="M822 831.2H202l-11.3-49.4h642.6z" fill="#D5D9CF"></path><path ' +
783        'd="M826.4 836.7H197.6l-13.7-60.4h656.3l-13.8 60.4z m-620-11h611.' +
784        '3l8.7-38.4H197.6l8.8 38.4z" fill="#333336"></path><path d="M758.' +
785        '5 781.8h-493V667.1c0-19.7 16-35.7 35.7-35.7h421.6c19.7 0 35.7 16' +
786        ' 35.7 35.7v114.7z" fill="#D5D9CF"></path><path d="M764 787.3H260' +
787        'V667.1c0-22.7 18.5-41.2 41.2-41.2h421.6c22.7 0 41.2 18.5 41.2 41' +
788        '.2v120.2z m-493-11h482V667.1c0-16.6-13.5-30.2-30.2-30.2H301.2c-1' +
789        '6.6 0-30.2 13.5-30.2 30.2v109.2z" fill="#333336"></path><path d=' +
790        '"M265.5 738h493v43.8h-493z" fill="#68A"></path><path d="M764 787' +
791        '.3H260v-54.8h504v54.8z m-493-11h482v-32.8H271v32.8z" fill="#3333' +
792        '36"></path><path d="M575.2 584.3V482.1c0-12.8 10.4-23.3 23.3-23.' +
793        '3h220c12.8 0 23.3 10.4 23.3 23.3v102.1" fill="#FFD632"></path><p' +
794        'ath d="M847.2 584.3h-11V482.1c0-9.8-8-17.8-17.8-17.8h-220c-9.8 0' +
795        '-17.8 8-17.8 17.8v102.1h-11V482.1c0-15.9 12.9-28.8 28.8-28.8h220' +
796        'c15.9 0 28.8 12.9 28.8 28.8v102.2z" fill="#333336"></path><path ' +
797        'd="M145.1 578.8h730.6v11H145.1z" fill="#333336"></path><path d="' +
798        'M784.5 523.1m-23 0a23 23 0 1 0 46 0 23 23 0 1 0-46 0Z" fill="#EC' +
799        'EFE8"></path><path d="M784.5 550.1c-14.9 0-27-12.1-27-27s12.1-27' +
800        ' 27-27 27 12.1 27 27-12.1 27-27 27z m0-46c-10.5 0-19 8.5-19 19s8' +
801        '.5 19 19 19 19-8.5 19-19-8.5-19-19-19z" fill="#333336"></path><p' +
802        'ath d="M627.7 545.8l-16.6-16.6c-3.6-3.6-3.6-9.4 0-13l16.6-16.6c5' +
803        '.8-5.8 15.7-1.7 15.7 6.5v33.2c0 8.2-9.9 12.3-15.7 6.5z" fill="#E' +
804        'CEFE8"></path><path d="M634.1 552.5c-3.4 0-6.7-1.3-9.3-3.9L608.2' +
805        ' 532c-2.5-2.5-3.9-5.8-3.9-9.3 0-3.5 1.4-6.9 3.9-9.3l16.6-16.6c3.' +
806        '9-3.9 9.4-5 14.4-2.9s8.2 6.8 8.2 12.2v33.2c0 5.4-3.1 10.1-8.2 12' +
807        '.2-1.6 0.7-3.4 1-5.1 1z m0-51.7c-1.1 0-2.4 0.3-3.6 1.5L613.9 519' +
808        'c-1 1-1.5 2.3-1.5 3.7 0 1.4 0.5 2.7 1.5 3.7l16.6 16.6c2.3 2.3 4.' +
809        '9 1.4 5.7 1.1 0.8-0.3 3.2-1.6 3.2-4.8v-33.2c0-3.2-2.5-4.5-3.2-4.' +
810        '8-0.4-0.2-1.1-0.5-2.1-0.5z" fill="#333336"></path><path d="M699 ' +
811        '545.8l16.6-16.6c3.6-3.6 3.6-9.4 0-13L699 499.5c-5.8-5.8-15.7-1.7' +
812        '-15.7 6.5v33.2c-0.1 8.3 9.8 12.4 15.7 6.6z" fill="#ECEFE8"></pat' +
813        'h><path d="M692.5 552.5c-1.7 0-3.5-0.3-5.1-1-5-2.1-8.2-6.8-8.2-1' +
814        '2.2v-33.2c0-5.4 3.1-10.1 8.2-12.2 5-2.1 10.6-1 14.4 2.9l16.6 16.' +
815        '6c5.2 5.2 5.2 13.5 0 18.7l-16.6 16.6c-2.6 2.5-5.9 3.8-9.3 3.8z m' +
816        '0-51.7c-1 0-1.7 0.3-2.1 0.4-0.8 0.3-3.2 1.6-3.2 4.8v33.2c0 3.2 2' +
817        '.5 4.5 3.2 4.8 0.8 0.3 3.4 1.2 5.7-1.1l16.6-16.6c2-2 2-5.3 0-7.4' +
818        'l-16.6-16.6c-1.2-1.1-2.5-1.5-3.6-1.5z" fill="#333336"></path></g' + '></svg>'
819    end;
820
821  SvgIconItem:= SVGIconImageCollectionPrinter.SVGIconItems.Add;
822  with SvgIconItem do
823    begin
824      IconName:= 'printer-default';
825      SVGText:= '<svg viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="h' +
826        'ttp://www.w3.org/2000/svg" fill="#000000"><g id="SVGRepo_bgCarri' +
827        'er" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-li' +
828        'necap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCar' +
829        'rier"><path d="M276.8 302.3h470.4v212.3H276.8z" fill="#FFD632"><' +
830        '/path><path d="M752.7 520.1H271.3V296.8h481.4v223.3z m-470.4-11h' +
831        '459.4V307.8H282.3v201.3z" fill="#333336"></path><path d="M363.8 ' +
832        '192.8h296.5v271.6H363.8z" fill="#ECEFE8"></path><path d="M665.7 ' +
833        '470H358.3V187.3h307.5V470z m-296.4-11h285.5V198.3H369.3V459z" fi' +
834        'll="#333336"></path><path d="M842.7 781.8H181.3c-19.1 0-34.6-15.' +
835        '5-34.6-34.6V460.9c0-19.1 15.5-34.6 34.6-34.6h661.4c19.1 0 34.6 1' +
836        '5.5 34.6 34.6v286.3c0 19.1-15.5 34.6-34.6 34.6z" fill="#68A240">' +
837        '</path><path d="M842.7 787.3H181.3c-22.1 0-40.1-18-40.1-40.1V460' +
838        '.9c0-22.1 18-40.1 40.1-40.1h661.4c22.1 0 40.1 18 40.1 40.1v286.3' +
839        'c0 22.1-18 40.1-40.1 40.1zM181.3 431.8c-16 0-29.1 13.1-29.1 29.1' +
840        'v286.3c0 16 13.1 29.1 29.1 29.1h661.4c16 0 29.1-13.1 29.1-29.1V4' +
841        '60.9c0-16-13.1-29.1-29.1-29.1H181.3z" fill="#333336"></path><pat' +
842        'h d="M822 831.2H202l-11.3-49.4h642.6z" fill="#D5D9CF"></path><pa' +
843        'th d="M826.4 836.7H197.6l-13.7-60.4h656.3l-13.8 60.4z m-620-11h6' +
844        '11.3l8.7-38.4H197.6l8.8 38.4z" fill="#333336"></path><path d="M7' +
845        '58.5 781.8h-493V667.1c0-19.7 16-35.7 35.7-35.7h421.6c19.7 0 35.7' +
846        ' 16 35.7 35.7v114.7z" fill="#D5D9CF"></path><path d="M764 787.3H' +
847        '260V667.1c0-22.7 18.5-41.2 41.2-41.2h421.6c22.7 0 41.2 18.5 41.2' +
848        ' 41.2v120.2z m-493-11h482V667.1c0-16.6-13.5-30.2-30.2-30.2H301.2' +
849        'c-16.6 0-30.2 13.5-30.2 30.2v109.2z" fill="#333336"></path><path' +
850        ' d="M265.5 738h493v43.8h-493z" fill="#68A240"></path><path d="M7' +
851        '64 787.3H260v-54.8h504v54.8z m-493-11h482v-32.8H271v32.8z" fill=' +
852        '"#333336"></path><path d="M575.2 584.3V482.1c0-12.8 10.4-23.3 23' +
853        '.3-23.3h220c12.8 0 23.3 10.4 23.3 23.3v102.1" fill="#FFD632"></p' +
854        'ath><path d="M847.2 584.3h-11V482.1c0-9.8-8-17.8-17.8-17.8h-220c' +
855        '-9.8 0-17.8 8-17.8 17.8v102.1h-11V482.1c0-15.9 12.9-28.8 28.8-28' +
856        '.8h220c15.9 0 28.8 12.9 28.8 28.8v102.2z" fill="#333336"></path>' +
857        '<path d="M145.1 578.8h730.6v11H145.1z" fill="#333336"></path><pa' +
858        'th d="M784.5 523.1m-23 0a23 23 0 1 0 46 0 23 23 0 1 0-46 0Z" fil' +
859        'l="#ECEFE8"></path><path d="M784.5 550.1c-14.9 0-27-12.1-27-27s1' +
860        '2.1-27 27-27 27 12.1 27 27-12.1 27-27 27z m0-46c-10.5 0-19 8.5-1' +
861        '9 19s8.5 19 19 19 19-8.5 19-19-8.5-19-19-19z" fill="#333336"></p' +
862        'ath><path d="M627.7 545.8l-16.6-16.6c-3.6-3.6-3.6-9.4 0-13l16.6-' +
863        '16.6c5.8-5.8 15.7-1.7 15.7 6.5v33.2c0 8.2-9.9 12.3-15.7 6.5z" fi' +
864        'll="#ECEFE8"></path><path d="M634.1 552.5c-3.4 0-6.7-1.3-9.3-3.9' +
865        'L608.2 532c-2.5-2.5-3.9-5.8-3.9-9.3 0-3.5 1.4-6.9 3.9-9.3l16.6-1' +
866        '6.6c3.9-3.9 9.4-5 14.4-2.9s8.2 6.8 8.2 12.2v33.2c0 5.4-3.1 10.1-' +
867        '8.2 12.2-1.6 0.7-3.4 1-5.1 1z m0-51.7c-1.1 0-2.4 0.3-3.6 1.5L613' +
868        '.9 519c-1 1-1.5 2.3-1.5 3.7 0 1.4 0.5 2.7 1.5 3.7l16.6 16.6c2.3 ' +
869        '2.3 4.9 1.4 5.7 1.1 0.8-0.3 3.2-1.6 3.2-4.8v-33.2c0-3.2-2.5-4.5-' +
870        '3.2-4.8-0.4-0.2-1.1-0.5-2.1-0.5z" fill="#333336"></path><path d=' +
871        '"M699 545.8l16.6-16.6c3.6-3.6 3.6-9.4 0-13L699 499.5c-5.8-5.8-15' +
872        '.7-1.7-15.7 6.5v33.2c-0.1 8.3 9.8 12.4 15.7 6.6z" fill="#ECEFE8"' +
873        '></path><path d="M692.5 552.5c-1.7 0-3.5-0.3-5.1-1-5-2.1-8.2-6.8' +
874        '-8.2-12.2v-33.2c0-5.4 3.1-10.1 8.2-12.2 5-2.1 10.6-1 14.4 2.9l16' +
875        '.6 16.6c5.2 5.2 5.2 13.5 0 18.7l-16.6 16.6c-2.6 2.5-5.9 3.8-9.3 ' +
876        '3.8z m0-51.7c-1 0-1.7 0.3-2.1 0.4-0.8 0.3-3.2 1.6-3.2 4.8v33.2c0' +
877        ' 3.2 2.5 4.5 3.2 4.8 0.8 0.3 3.4 1.2 5.7-1.1l16.6-16.6c2-2 2-5.3' +
878        ' 0-7.4l-16.6-16.6c-1.2-1.1-2.5-1.5-3.6-1.5z" fill="#333336"></pa' + 'th></g></svg>'
879    end;
880
881  SvgIconItem:= SVGIconImageCollectionPrinter.SVGIconItems.Add;
882  with SvgIconItem do
883    begin
884      IconName:= 'printer-offline';
885      SVGText:= '<svg viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="h' +
886        'ttp://www.w3.org/2000/svg" fill="#000000"><g id="SVGRepo_bgCarri' +
887        'er" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-li' +
888        'necap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCar' +
889        'rier"><path d="M276.8 302.3h470.4v212.3H276.8z" fill="#FFD632"><' +
890        '/path><path d="M752.7 520.1H271.3V296.8h481.4v223.3z m-470.4-11h' +
891        '459.4V307.8H282.3v201.3z" fill="#333336"></path><path d="M363.8 ' +
892        '192.8h296.5v271.6H363.8z" fill="#ECEFE8"></path><path d="M665.7 ' +
893        '470H358.3V187.3h307.5V470z m-296.4-11h285.5V198.3H369.3V459z" fi' +
894        'll="#333336"></path><path d="M842.7 781.8H181.3c-19.1 0-34.6-15.' +
895        '5-34.6-34.6V460.9c0-19.1 15.5-34.6 34.6-34.6h661.4c19.1 0 34.6 1' +
896        '5.5 34.6 34.6v286.3c0 19.1-15.5 34.6-34.6 34.6z" fill="#aaaaaa">' +
897        '</path><path d="M842.7 787.3H181.3c-22.1 0-40.1-18-40.1-40.1V460' +
898        '.9c0-22.1 18-40.1 40.1-40.1h661.4c22.1 0 40.1 18 40.1 40.1v286.3' +
899        'c0 22.1-18 40.1-40.1 40.1zM181.3 431.8c-16 0-29.1 13.1-29.1 29.1' +
900        'v286.3c0 16 13.1 29.1 29.1 29.1h661.4c16 0 29.1-13.1 29.1-29.1V4' +
901        '60.9c0-16-13.1-29.1-29.1-29.1H181.3z" fill="#333336"></path><pat' +
902        'h d="M822 831.2H202l-11.3-49.4h642.6z" fill="#D5D9CF"></path><pa' +
903        'th d="M826.4 836.7H197.6l-13.7-60.4h656.3l-13.8 60.4z m-620-11h6' +
904        '11.3l8.7-38.4H197.6l8.8 38.4z" fill="#333336"></path><path d="M7' +
905        '58.5 781.8h-493V667.1c0-19.7 16-35.7 35.7-35.7h421.6c19.7 0 35.7' +
906        ' 16 35.7 35.7v114.7z" fill="#D5D9CF"></path><path d="M764 787.3H' +
907        '260V667.1c0-22.7 18.5-41.2 41.2-41.2h421.6c22.7 0 41.2 18.5 41.2' +
908        ' 41.2v120.2z m-493-11h482V667.1c0-16.6-13.5-30.2-30.2-30.2H301.2' +
909        'c-16.6 0-30.2 13.5-30.2 30.2v109.2z" fill="#333336"></path><path' +
910        ' d="M265.5 738h493v43.8h-493z" fill="#aaaaaa"></path><path d="M7' +
911        '64 787.3H260v-54.8h504v54.8z m-493-11h482v-32.8H271v32.8z" fill=' +
912        '"#333336"></path><path d="M575.2 584.3V482.1c0-12.8 10.4-23.3 23' +
913        '.3-23.3h220c12.8 0 23.3 10.4 23.3 23.3v102.1" fill="#FFD632"></p' +
914        'ath><path d="M847.2 584.3h-11V482.1c0-9.8-8-17.8-17.8-17.8h-220c' +
915        '-9.8 0-17.8 8-17.8 17.8v102.1h-11V482.1c0-15.9 12.9-28.8 28.8-28' +
916        '.8h220c15.9 0 28.8 12.9 28.8 28.8v102.2z" fill="#333336"></path>' +
917        '<path d="M145.1 578.8h730.6v11H145.1z" fill="#333336"></path><pa' +
918        'th d="M784.5 523.1m-23 0a23 23 0 1 0 46 0 23 23 0 1 0-46 0Z" fil' +
919        'l="#ECEFE8"></path><path d="M784.5 550.1c-14.9 0-27-12.1-27-27s1' +
920        '2.1-27 27-27 27 12.1 27 27-12.1 27-27 27z m0-46c-10.5 0-19 8.5-1' +
921        '9 19s8.5 19 19 19 19-8.5 19-19-8.5-19-19-19z" fill="#333336"></p' +
922        'ath><path d="M627.7 545.8l-16.6-16.6c-3.6-3.6-3.6-9.4 0-13l16.6-' +
923        '16.6c5.8-5.8 15.7-1.7 15.7 6.5v33.2c0 8.2-9.9 12.3-15.7 6.5z" fi' +
924        'll="#ECEFE8"></path><path d="M634.1 552.5c-3.4 0-6.7-1.3-9.3-3.9' +
925        'L608.2 532c-2.5-2.5-3.9-5.8-3.9-9.3 0-3.5 1.4-6.9 3.9-9.3l16.6-1' +
926        '6.6c3.9-3.9 9.4-5 14.4-2.9s8.2 6.8 8.2 12.2v33.2c0 5.4-3.1 10.1-' +
927        '8.2 12.2-1.6 0.7-3.4 1-5.1 1z m0-51.7c-1.1 0-2.4 0.3-3.6 1.5L613' +
928        '.9 519c-1 1-1.5 2.3-1.5 3.7 0 1.4 0.5 2.7 1.5 3.7l16.6 16.6c2.3 ' +
929        '2.3 4.9 1.4 5.7 1.1 0.8-0.3 3.2-1.6 3.2-4.8v-33.2c0-3.2-2.5-4.5-' +
930        '3.2-4.8-0.4-0.2-1.1-0.5-2.1-0.5z" fill="#333336"></path><path d=' +
931        '"M699 545.8l16.6-16.6c3.6-3.6 3.6-9.4 0-13L699 499.5c-5.8-5.8-15' +
932        '.7-1.7-15.7 6.5v33.2c-0.1 8.3 9.8 12.4 15.7 6.6z" fill="#ECEFE8"' +
933        '></path><path d="M692.5 552.5c-1.7 0-3.5-0.3-5.1-1-5-2.1-8.2-6.8' +
934        '-8.2-12.2v-33.2c0-5.4 3.1-10.1 8.2-12.2 5-2.1 10.6-1 14.4 2.9l16' +
935        '.6 16.6c5.2 5.2 5.2 13.5 0 18.7l-16.6 16.6c-2.6 2.5-5.9 3.8-9.3 ' +
936        '3.8z m0-51.7c-1 0-1.7 0.3-2.1 0.4-0.8 0.3-3.2 1.6-3.2 4.8v33.2c0' +
937        ' 3.2 2.5 4.5 3.2 4.8 0.8 0.3 3.4 1.2 5.7-1.1l16.6-16.6c2-2 2-5.3' +
938        ' 0-7.4l-16.6-16.6c-1.2-1.1-2.5-1.5-3.6-1.5z" fill="#333336"></pa' + 'th></g></svg>'
939    end;
940
941  // Link the collection to an image list
942  SVGIconVirtualImageList:= TSVGIconVirtualImageList.Create(nil);
943  SVGIconVirtualImageList.Height:= MulDiv(48, Screen.PixelsPerInch, 240);
944  SVGIconVirtualImageList.Width:= MulDiv(48, Screen.PixelsPerInch, 240);
945  SVGIconVirtualImageList.ImageCollection:= SVGIconImageCollection;
946  SVGIconVirtualImageList.Add('actions-caret-bar-left', 'actions-caret-bar-left');
947  SVGIconVirtualImageList.Add('actions-caret-bar-right', 'actions-caret-bar-right');
948  SVGIconVirtualImageList.Add('actions-caret-left', 'actions-caret-left');
949  SVGIconVirtualImageList.Add('actions-caret-right', 'actions-caret-right');
950  SVGIconVirtualImageList.Add('zoom-in', 'zoom-in');
951  SVGIconVirtualImageList.Add('zoom-out', 'zoom-out');
952  SVGIconVirtualImageList.Add('component-divider-vertical', 'component-divider-vertical');
953  SVGIconVirtualImageList.Add('print-outline', 'print-outline');
954  SVGIconVirtualImageList.Add('find-filled', 'find-filled');
955  SVGIconVirtualImageList.Add('save', 'save');
956  SVGIconVirtualImageList.Add('close-light', 'close-light');
957
958  SVGIconVirtualImageListPrinter:= TSVGIconVirtualImageList.Create(nil);
959  SVGIconVirtualImageListPrinter.Height:= MulDiv(96, Screen.PixelsPerInch, 240);
960  SVGIconVirtualImageListPrinter.Width:= MulDiv(96, Screen.PixelsPerInch, 240);
961  SVGIconVirtualImageListPrinter.ImageCollection:= SVGIconImageCollectionPrinter;
962  SVGIconVirtualImageListPrinter.Add('printer-storing', 'printer-storing');
963  SVGIconVirtualImageListPrinter.Add('printer-beschikbaar', 'printer-beschikbaar');
964  SVGIconVirtualImageListPrinter.Add('printer-default', 'printer-default');
965  SVGIconVirtualImageListPrinter.Add('printer-offline', 'printer-offline');
966end;
967
968function TRLPreviewForm.InitSpeedButton(AName: string; ALeft, AWidth: Integer; ACaption: string; AImage: string;
969  AOnClick: TNotifyEvent): TSpeedButton;
970begin
971  Result:= TSpeedButton.Create(Self);
972  with Result do
973    begin
974      name:= AName;
975      Parent:= PanelTools;
976      Left:= ALeft; // Already High DPI aware
977      Top:= 1;
978      Width:= AWidth; // Already High DPI aware
979      Height:= ToolBarHeight; // Already High DPI aware
980      Margins.Left:= MulDiv(4, Screen.PixelsPerInch, 144);
981      Margins.Top:= MulDiv(4, Screen.PixelsPerInch, 144);
982      Margins.Right:= MulDiv(4, Screen.PixelsPerInch, 144);
983      Margins.Bottom:= MulDiv(4, Screen.PixelsPerInch, 144);
984      Caption:= ACaption;
985      Flat:= True;
986      StyleName:= 'Windows';
987      OnClick:= AOnClick;
988      Images:= SVGIconVirtualImageList;
989      ImageName:= AImage;
990    end;
991end;
992
993function TRLPreviewForm.InitPanel(AParent: TWinControl; AName: string; ALeft, AWidth: Integer; ACaption: string;
994  AAlign: TAlign): TPanel;
995begin
996  Result:= TPanel.Create(PanelTools);
997  with Result do
998    begin
999      name:= AName;
1000      Parent:= AParent;
1001      Left:= ALeft; // Already High DPI aware
1002      Top:= MulDiv(0, Screen.PixelsPerInch, 144);
1003      Width:= MulDiv(AWidth, Screen.PixelsPerInch, 144);
1004      Height:= ToolBarHeight; // Already High DPI aware
1005      Caption:= ACaption;
1006      Align:= AAlign;
1007      BevelOuter:= bvNone;
1008      BevelInner:= bvNone;
1009      BevelKind:= bkNone;
1010    end;
1011end;
1012
1013function TRLPreviewForm.InitLabel(ATop: Integer; ACaption: string): TLabel;
1014begin
1015  Result:= TLabel.Create(PanelLeft);
1016  with Result do
1017    begin
1018      Parent:= PanelLeft;
1019      Left:= MulDiv(58, Screen.PixelsPerInch, 240);
1020      Top:= MulDiv(ATop, Screen.PixelsPerInch, 240);
1021      Width:= MulDiv(115, Screen.PixelsPerInch, 240);
1022      Height:= ToolBarHeight; // Already High DPI aware
1023      Caption:= ACaption;
1024      Font.Charset:= DEFAULT_CHARSET;
1025      Font.Color:= clWindowText;
1026      Font.Height:= MulDiv(-30, Screen.PixelsPerInch, 240);
1027      Font.Name:= 'Segoe UI';
1028      Font.Pitch:= fpVariable;
1029      Font.Style:= [fsBold];
1030      ParentFont:= False;
1031    end;
1032end;
1033
1034function TRLPreviewForm.InitRadioGroup(ATop, Aheight: Integer): TRadioGroup;
1035begin
1036  Result:= TRadioGroup.Create(PanelLeft);
1037  with Result do
1038    begin
1039      Parent:= PanelLeft;
1040      Left:= MulDiv(58, Screen.PixelsPerInch, 240);
1041      Top:= MulDiv(ATop, Screen.PixelsPerInch, 240);
1042      Width:= MulDiv(463, Screen.PixelsPerInch, 240);
1043      Height:= MulDiv(Aheight, Screen.PixelsPerInch, 144);
1044      Font.Charset:= DEFAULT_CHARSET;
1045      Font.Color:= clWindowText;
1046      Font.Height:= MulDiv(-30, Screen.PixelsPerInch, 240);
1047      Font.Name:= 'Segoe UI';
1048      Font.Pitch:= fpVariable;
1049      Font.Style:= [];
1050      ItemIndex:= 0;
1051      ParentFont:= False;
1052      ShowFrame:= False;
1053      TabOrder:= 4;
1054    end;
1055end;
1056
1057procedure TRLPreviewForm.Init;
1058begin
1059  InitIcons(SVGIconVirtualImageList);
1060
1061  Name:= 'frmPreview';
1062  LoadConfig; // Load settings from Registry (TLForm)
1063  Caption:= 'Report Preview';
1064  Color:= clWindow;
1065  OnShow:= FormShow;
1066
1067  { Panel Left ============================================================================== }
1068  // Printer settings
1069
1070  PanelLeft:= InitPanel(Self, 'LeftPanel', 0, 493, '', alLeft);
1071
1072  ComboBoxPrinter:= TComboBoxEx.Create(PanelLeft);
1073  with ComboBoxPrinter do
1074    begin
1075      Parent:= PanelLeft;
1076      name:= 'ComboBoxExPrinter';
1077      Left:= MulDiv(58, Screen.PixelsPerInch, 240);
1078      Top:= MulDiv(80, Screen.PixelsPerInch, 240);
1079      Width:= MulDiv(700, Screen.PixelsPerInch, 240);
1080      Items.Assign(Printer.Printers);
1081      ItemIndex:= Printer.PrinterIndex;
1082      ItemHeight:= MulDiv(88, Screen.PixelsPerInch, 240);
1083      TabOrder:= 0;
1084      Images:= SVGIconVirtualImageListPrinter;
1085      OnChange:= ComboBoxPrinterChange;
1086    end;
1087  for var I:= 0 to ComboBoxPrinter.ItemsEx.Count - 1 do
1088    begin
1089      ComboBoxPrinter.ItemsEx[I].ImageIndex:= 1;
1090    end;
1091  ComboBoxPrinter.ItemsEx[ComboBoxPrinter.ItemIndex].ImageIndex:= 2;
1092  ComboBoxPrinter.ItemsEx[0].ImageIndex:= 1; // 0 nog een keer anders pakt ie het icon niet????
1093
1094  ComboBoxDuplex:= TComboBox.Create(PanelLeft);
1095  with ComboBoxDuplex do
1096    begin
1097      Parent:= PanelLeft;
1098      name:= 'ComboBoxDuplex';
1099      Left:= MulDiv(58, Screen.PixelsPerInch, 240);
1100      Top:= MulDiv(1077, Screen.PixelsPerInch, 240);
1101      Width:= MulDiv(700, Screen.PixelsPerInch, 240);
1102      Height:= MulDiv(49, Screen.PixelsPerInch, 240);
1103      ItemIndex:= 0;
1104      TabOrder:= 0;
1105      ItemHeight:= MulDiv(96, Screen.PixelsPerInch, 240);
1106      Items.Add('Enkelzijdig afdrukken;Afdrukken op slechts één zijde van de pagina');
1107      Items.Add('Dubbelzijdig afdrukken;Over lange zijde omslaan');
1108      Items.Add('Dubbelzijdig afdrukken;Over korte zijde omslaan');
1109      ItemIndex:= 0;
1110      Style:= csOwnerDrawFixed;
1111      OnDrawItem:= ComboBoxDuplexDrawItem;
1112      OnChange:= ComboBoxDuplexChange;
1113      Enabled:= RLPrinter.SupportsDuplex;
1114    end;
1115
1116  Label1:= InitLabel(200, 'Kopie'#235'n');
1117  Label2:= InitLabel(360, 'Indeling');
1118  Label3:= InitLabel(617, 'Pagina'#39's');
1119  Label5:= InitLabel(1020, 'Dubbelzijdig afdrukken');
1120  Label6:= InitLabel(23, 'Printer');
1121
1122  ButtonAnnuleren:= TButton.Create(PanelLeft);
1123  with ButtonAnnuleren do
1124    begin
1125      Parent:= PanelLeft;
1126      Left:= MulDiv(440, Screen.PixelsPerInch, 240);
1127      Top:= MulDiv(1260, Screen.PixelsPerInch, 240);
1128      Width:= MulDiv(318, Screen.PixelsPerInch, 240);
1129      Height:= MulDiv(63, Screen.PixelsPerInch, 240);
1130      Caption:= 'Annuleren';
1131      TabOrder:= 2;
1132      OnClick:= ButtonAnnulerenClick;
1133    end;
1134
1135  ButtonAfdrukken:= TButton.Create(PanelLeft);
1136  with ButtonAfdrukken do
1137    begin
1138      Parent:= PanelLeft;
1139      Left:= MulDiv(58, Screen.PixelsPerInch, 240);
1140      Top:= MulDiv(1260, Screen.PixelsPerInch, 240);
1141      Width:= MulDiv(318, Screen.PixelsPerInch, 240);
1142      Height:= MulDiv(63, Screen.PixelsPerInch, 240);
1143      Caption:= 'Afdrukken';
1144      TabOrder:= 1;
1145      // default:= True;
1146      OnClick:= SpeedButtonAfdrukkenClick;
1147    end;
1148
1149  SpinEditCopies:= TSpinEdit.Create(PanelLeft);
1150  with SpinEditCopies do
1151    begin
1152      Parent:= PanelLeft;
1153      Left:= MulDiv(58, Screen.PixelsPerInch, 240);
1154      Top:= MulDiv(257, Screen.PixelsPerInch, 240);
1155      Width:= MulDiv(221, Screen.PixelsPerInch, 240);
1156      Height:= MulDiv(49, Screen.PixelsPerInch, 240);
1157      TabOrder:= 3;
1158      MinValue:= 1;
1159      MaxValue:= 99;
1160      Value:= 1;
1161      RLPrinter.Copies:= StrToInt(Text);
1162      OnChange:= SpinEditCopiesChange;
1163    end;
1164
1165  RadioGroupLayout:= InitRadioGroup(360, 121);
1166  with RadioGroupLayout do
1167    begin
1168      Items.Add('  Staand');
1169      Items.Add('  Liggend');
1170    end;
1171
1172  RadioGroupPages:= InitRadioGroup(617, 207);
1173  with RadioGroupPages do
1174    begin
1175      Items.Add('  Alle');
1176      Items.Add('  Alleen oneven pagina'#39's');
1177      Items.Add('  Alleen even pagina'#39's');
1178      Items.Add('');
1179    end;
1180  RadioGroupPages.ItemIndex:= 0;
1181
1182  EditPageSelection:= TEdit.Create(PanelLeft);
1183  with EditPageSelection do
1184    begin
1185      Parent:= PanelLeft;
1186      Left:= MulDiv(125, Screen.PixelsPerInch, 240);
1187      Top:= MulDiv(897, Screen.PixelsPerInch, 240);
1188      Width:= MulDiv(633, Screen.PixelsPerInch, 240);
1189      TabOrder:= 6;
1190      TextHint:= 'bijv. 1-5, 8, 11-13';
1191      Text:= '';
1192      OnChange:= EditPageSelectionChange;
1193    end;
1194
1195  { Panel Right ============================================================================== }
1196  // Preview container with attached ToolBar
1197
1198  PanelRight:= InitPanel(Self, 'RightPanel', 401, 500, '', alClient);
1199
1200  { Preview container }
1201  PanelContainer:= InitPanel(PanelRight, 'PanelContainer', 0, 807, '', alClient);
1202  PanelContainer.BevelOuter:= bvNone;
1203
1204  { Toolbar }
1205
1206  ToolBarHeight:= MulDiv(56, Screen.PixelsPerInch, 144);
1207  SpeedButtonWidth:= MulDiv(56, Screen.PixelsPerInch, 144);
1208  var
1209  SpeedButtonExWidth:= MulDiv(48, Screen.PixelsPerInch, 144); // For smaller arrow buttons
1210
1211  // Attach Toolbar at the bottom
1212  PanelTools:= InitPanel(PanelRight, 'PanelTools', 401, 0, '', alBottom);
1213
1214  // tbv centreren Toolbar onder het preview document
1215  with PanelTools do
1216    begin
1217      AlignWithMargins:= True;
1218      Margins.Top:= 0;
1219      Margins.Bottom:= 0;
1220      Margins.Left:= 0;
1221      Margins.Right:= 0;
1222    end;
1223
1224  SpeedButtonFirst:= InitSpeedButton('SpeedButtonFirst', 0, SpeedButtonExWidth, '', 'actions-caret-bar-left',
1225    SpeedButtonFirstClick);
1226  SpeedButtonPrior:= InitSpeedButton('SpeedButtonPrior', SpeedButtonFirst.Left + SpeedButtonFirst.Width,
1227    SpeedButtonExWidth, '', 'actions-caret-left', SpeedButtonPriorClick);
1228
1229  PanelPage:= InitPanel(PanelTools, 'PanelPage', SpeedButtonPrior.Left + SpeedButtonPrior.Width, 0, 'Page', alNone);
1230  PanelPage.Top:= 0;
1231
1232  PanelEditPageNo:= InitPanel(PanelTools, 'PanelEditPageNo', PanelPage.Left + PanelPage.Width, 48, '', alNone);
1233  with PanelEditPageNo do
1234    begin
1235      Parent:= PanelTools;
1236    end;
1237
1238  EditPageNo:= TEdit.Create(PanelEditPageNo);
1239  with EditPageNo do
1240    begin
1241      Parent:= PanelEditPageNo;
1242      name:= 'EditPageNo';
1243      Left:= 0;
1244      Top:= 0;
1245      Width:= 70;
1246      AlignWithMargins:= True;
1247      Margins.Left:= 0;
1248      Margins.Top:= MulDiv(15, Screen.PixelsPerInch, 144);
1249      Margins.Right:= 0;
1250      Margins.Bottom:= MulDiv(15, Screen.PixelsPerInch, 144);
1251      Align:= alClient;
1252      TabOrder:= 0;
1253      Text:= '';
1254      OnChange:= EditPageNoChange;
1255    end;
1256
1257  PanelOf:= InitPanel(PanelTools, 'PanelOf', PanelEditPageNo.Left + PanelEditPageNo.Width, 48, '/', alNone);
1258  PanelPageCount:= InitPanel(PanelTools, 'PanelPageCount', PanelOf.Left + PanelOf.Width, 32, '999', alNone);
1259  PanelPageCount.Alignment:= taLeftJustify;
1260
1261  SpeedButtonNext:= InitSpeedButton('SpeedButtonNext', PanelPageCount.Left + PanelPageCount.Width, SpeedButtonExWidth, '',
1262    'actions-caret-right', SpeedButtonNextClick);
1263  SpeedButtonLast:= InitSpeedButton('SpeedButtonLast', SpeedButtonNext.Left + SpeedButtonNext.Width, SpeedButtonExWidth,
1264    '', 'actions-caret-bar-right', SpeedButtonLastClick);
1265
1266  PanelComboBoxZoom:= InitPanel(PanelTools, 'PanelComboBoxZoom', SpeedButtonLast.Left + SpeedButtonLast.Width, 250,
1267    '', alNone);
1268  PanelComboBoxZoom.BorderWidth:= MulDiv(6, Screen.PixelsPerInch, 240);
1269  ComboBoxZoom:= TComboBox.Create(PanelComboBoxZoom);
1270  with ComboBoxZoom do
1271    begin
1272      name:= 'ComboBoxZoom';
1273      Parent:= PanelComboBoxZoom;
1274      BevelKind:= bkNone;
1275      AlignWithMargins:= True;
1276      Margins.Left:= MulDiv(72, Screen.PixelsPerInch, 144);
1277      Margins.Top:= MulDiv(12, Screen.PixelsPerInch, 144);
1278      Margins.Right:= MulDiv(0, Screen.PixelsPerInch, 144);
1279      Align:= alClient;
1280      TabOrder:= 0;
1281      DropDownCount:= 11;
1282      TabOrder:= 0;
1283      Items.Text:= '500%' + sLineBreak + '200%' + sLineBreak + '150%' + sLineBreak + '100%' + sLineBreak + '75%' +
1284        sLineBreak + '50%' + sLineBreak + '25%' + sLineBreak + '10%' + sLineBreak + 'Paginabreedte' + sLineBreak +
1285        'Volledige pagina' + sLineBreak + 'Meerdere pagina''s' + sLineBreak;
1286      OnChange:= ComboBoxZoomChange;
1287    end;
1288
1289  SpeedButtonZoomDown:= InitSpeedButton('SpeedButtonZoomDown', PanelComboBoxZoom.Left + PanelComboBoxZoom.Width,
1290    SpeedButtonWidth, '', 'zoom-out', SpeedButtonZoomDownClick);
1291  SpeedButtonZoomUp:= InitSpeedButton('SpeedButtonZoomUp', SpeedButtonZoomDown.Left + SpeedButtonWidth,
1292    SpeedButtonWidth, '', 'zoom-in', SpeedButtonZoomUpClick);
1293  SpeedButtonViews:= InitSpeedButton('SpeedButtonViews', SpeedButtonZoomUp.Left + SpeedButtonWidth, SpeedButtonWidth,
1294    '', 'component-divider-vertical', SpeedButtonViewsClick);
1295  SpeedButtonSearch:= InitSpeedButton('SpeedButtonSearch', SpeedButtonViews.Left + SpeedButtonWidth, SpeedButtonWidth,
1296    '', 'find-filled', SpeedButtonSearchClick);
1297
1298  ToolbarWidth:= SpeedButtonSearch.Left + SpeedButtonWidth;
1299
1300  // Prevent Left Toolbar from hiding
1301  Constraints.MinHeight:= ButtonAfdrukken.Top + 2 * ButtonAfdrukken.Height + MulDiv(64, Screen.PixelsPerInch, 144);
1302  // Prevent Toolbar from hiding
1303  Constraints.MinWidth:= PanelLeft.Width + ToolbarWidth + MulDiv(64, Screen.PixelsPerInch, 144);
1304  // Keep toolbar centered below preview document
1305  OnResize:= FormResize;
1306end;
1307
1308procedure TRLPreviewForm.OnClickRLAbout(Sender: TObject);
1309var
1310  LFormRLAbout: TFormRLAbout;
1311begin
1312  LFormRLAbout:= TFormRLAbout.Create(Self);
1313  try
1314    LFormRLAbout.ShowModal;
1315  finally
1316    LFormRLAbout.Free;
1317  end;
1318end;
1319
1320procedure TRLPreviewForm.DoClose(var Action: TCloseAction);
1321begin
1322  DefaultWindowState:= WindowState;
1323  DefaultWindowBounds:= BoundsRect;
1324  Action:= caFree;
1325end;
1326
1327procedure TRLPreviewForm.ComboBoxDuplexChange(Sender: TObject);
1328var
1329  Device, Driver, Port: string;
1330  DriverHandle: THandle;
1331  DevModeRef: PDeviceMode;
1332begin
1333  Printer.GetPrinter(Device, Driver, Port, DriverHandle);
1334  if DriverHandle <> 0 then
1335    begin
1336      DevModeRef:= GlobalLock(DriverHandle);
1337      if DevModeRef <> nil then
1338        try
1339          case ComboBoxDuplex.ItemIndex of
1340            0:
1341              begin
1342
1343                DevModeRef^.dmDuplex:= DMDUP_SIMPLEX; // Simplex
1344                DevModeRef^.dmFields:= DevModeRef^.dmFields and not DWORD(DM_DUPLEX);
1345              end;
1346            1:
1347              begin
1348
1349                DevModeRef^.dmDuplex:= DMDUP_VERTICAL; // Duplex lange zijde
1350                DevModeRef^.dmFields:= DevModeRef^.dmFields or DM_DUPLEX;
1351              end;
1352            2:
1353              begin
1354                DevModeRef^.dmDuplex:= DMDUP_HORIZONTAL; // Duplex Korte zijde
1355                DevModeRef^.dmFields:= DevModeRef^.dmFields or DM_DUPLEX;
1356              end;
1357          end;
1358        finally
1359          GlobalUnlock(DriverHandle);
1360        end;
1361    end;
1362  Printer.SetPrinter(Device, Driver, Port, DriverHandle);
1363end;
1364
1365procedure TRLPreviewForm.ComboBoxDuplexDrawItem(Control: TWinControl; Index: Integer; Rect: TRect;
1366  State: TOwnerDrawState);
1367var
1368  TextLine1, TextLine2: string;
1369  TextHeight: Integer;
1370  DrawRect: TRect;
1371  Delimiter: string;
1372  ResultArray: TArray<string>;
1373begin
1374  with Control as TComboBox do
1375    begin
1376      Canvas.FillRect(Rect); // Clear the background
1377
1378      // Items comprising two lines 'Line 1;Line 2'
1379      // First line printed bold, Second line printed normal and a slightly smaller fontsize
1380
1381      // Split the string
1382      Delimiter:= ';';
1383      ResultArray:= SplitString(Items[index], Delimiter);
1384
1385      // Define two lines of text for each item
1386      TextLine1:= ResultArray[0]; // First line
1387      TextLine2:= ResultArray[1]; // Second line
1388
1389      // Calculate the height of each text line
1390      TextHeight:= Canvas.TextHeight(TextLine1);
1391
1392      // Draw the first line
1393      DrawRect:= Rect;
1394      DrawRect.Top:= Rect.Top + 2; // Add padding
1395      DrawRect.Left:= Rect.Left + 11;
1396      Canvas.Font.Style:= [fsBold];
1397      Canvas.TextOut(DrawRect.Left + 2, DrawRect.Top, TextLine1);
1398
1399      // Draw the second line below the first
1400      DrawRect.Top:= DrawRect.Top + TextHeight + 2; // Adjust for line height
1401      Canvas.Font.Style:= [];
1402      Canvas.Font.Size:= 8;
1403      Canvas.TextOut(DrawRect.Left + 2, DrawRect.Top, TextLine2);
1404    end;
1405end;
1406
1407procedure TRLPreviewForm.ComboBoxPrinterChange(Sender: TObject);
1408begin
1409  with Sender as TComboBoxEx do
1410    begin
1411      if Printer.PrinterIndex = ItemIndex then
1412        begin
1413          printCommand:= 'print';
1414          printerInfo:= '';
1415        end
1416      else
1417        begin
1418          printCommand:= 'printto';
1419          Printer.PrinterIndex:= ItemIndex;
1420          Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
1421          printerInfo:= Format('"%s" "%s" "%s"', [Device, Driver, Port]);
1422        end;
1423      // ShellExecute(Application.Handle, PChar(printCommand), PChar(documentToPrint), PChar(printerInfo), nil, SW_HIDE) ;
1424    end;
1425  if Assigned(ComboBoxDuplex) then
1426    ComboBoxDuplex.Enabled:= RLPrinter.SupportsDuplex;
1427  if Assigned(Label5) then
1428    Label5.Enabled:= RLPrinter.SupportsDuplex;
1429end;
1430
1431procedure TRLPreviewForm.ComboBoxZoomChange(Sender: TObject);
1432var
1433  Z: Double;
1434  I, E: Integer;
1435begin
1436  FEditingZoom:= True;
1437  try
1438    I:= ComboBoxZoom.Items.IndexOf(ComboBoxZoom.Text);
1439    if I <> -1 then
1440      Z:= 0
1441    else
1442      begin
1443        Val(StringReplace(StringReplace(ComboBoxZoom.Text, '%', '', []), ',', '.', []), Z, E);
1444        if E <> 0 then
1445          Z:= 0;
1446        I:= ComboBoxZoom.ItemIndex;
1447      end;
1448    if Z >= 10 then
1449      Preview.ZoomFactor:= Z
1450    else
1451      case I of
1452        0:
1453          Preview.ZoomFactor:= 500;
1454        1:
1455          Preview.ZoomFactor:= 200;
1456        2:
1457          Preview.ZoomFactor:= 150;
1458        3:
1459          Preview.ZoomFactor:= 100;
1460        4:
1461          Preview.ZoomFactor:= 75;
1462        5:
1463          Preview.ZoomFactor:= 50;
1464        6:
1465          Preview.ZoomFactor:= 25;
1466        7:
1467          Preview.ZoomFactor:= 10;
1468        8:
1469          Preview.ZoomFullWidth;
1470        9:
1471          Preview.ZoomFullPage;
1472        10:
1473          Preview.ZoomMultiplePages;
1474      end;
1475  finally
1476    FEditingZoom:= False;
1477  end;
1478end;
1479
1480procedure TRLPreviewForm.EditPageSelectionChange(Sender: TObject);
1481begin
1482  if (Sender as TEdit).Text <> '' then
1483    RadioGroupPages.ItemIndex:= 3;
1484end;
1485
1486procedure TRLPreviewForm.EditPageNoChange(Sender: TObject);
1487begin
1488  FEditingPageNo:= True;
1489  try
1490    Preview.PageIndex:= StrToIntDef(EditPageNo.Text, Preview.PageIndex) - 1;
1491  finally
1492    FEditingPageNo:= False;
1493  end;
1494end;
1495
1496procedure TRLPreviewForm.SpeedButtonAfdrukkenClick(Sender: TObject);
1497var
1498  priorfocus: TWinControl;
1499  firstpg: Integer;
1500  lastpg: Integer;
1501  selection: string;
1502  oddp: Integer;
1503  Prn: TRLCustomFilter;
1504
1505begin
1506  priorfocus:= Screen.ActiveControl;
1507  try
1508    selection:= '';
1509    oddp:= PrintOddAndEvenPages;
1510    case RadioGroupPages.ItemIndex of
1511      1:
1512        oddp:= PrintOddPagesOnly;
1513      2:
1514        oddp:= PrintEvenPagesOnly;
1515      3:
1516        selection:= EditPageSelection.Text;
1517    end;
1518    firstpg:= 1;
1519    lastpg:= Preview.Pages.PageCount;
1520
1521    Prn:= SpoolFilter;
1522    Prn.ClassOptions:=  Prn.ClassOptions - [foEmulateCopies];
1523
1524    FilterPages(Preview.Pages, Prn {nil}, firstpg, lastpg, selection, oddp);
1525    SentToPrinter:= True;
1526  finally
1527    // focuscontrole voor CLX
1528    if not Assigned(priorfocus) or not((priorfocus is TCustomEdit) or (priorfocus is TCustomComboBox)) then
1529      priorfocus:= EditPageNo;
1530    priorfocus.SetFocus;
1531  end;
1532  if Assigned(SetupInstance) and Assigned(SetupInstance.AfterPrint) then
1533    SetupInstance.AfterPrint(Self);
1534end;
1535
1536procedure TRLPreviewForm.SpeedButtonFirstClick(Sender: TObject);
1537begin
1538  Preview.FirstPage;
1539end;
1540
1541procedure TRLPreviewForm.SpeedButtonLastClick(Sender: TObject);
1542begin
1543  Preview.LastPage;
1544end;
1545
1546procedure TRLPreviewForm.SpeedButtonNextClick(Sender: TObject);
1547begin
1548  Preview.NextPage;
1549end;
1550
1551function FileNameFromText(const AText: string): string;
1552var
1553  I: Integer;
1554begin
1555  Result:= Trim(AText);
1556  for I:= Length(Result) downto 1 do
1557    if CharInSet(Result[I], [#0 .. #31, #127, '?', '*', ':', '/', '\', '>', '<', '|', '"', '.']) then
1558      Delete(Result, I, 1);
1559end;
1560
1561procedure TRLPreviewForm.SpeedButtonSaveClick(Sender: TObject);
1562var
1563  priorfocus: TWinControl;
1564  filt: TRLCustomSaveFilter;
1565  fname: string;
1566  fext: string;
1567  firstpg: Integer;
1568  lastpg: Integer;
1569begin
1570  if Assigned(SetupInstance) and Assigned(SetupInstance.BeforeSave) then
1571    SetupInstance.BeforeSave(Self);
1572  priorfocus:= Screen.ActiveControl;
1573  try
1574    with TRLSaveDialog.CreateNew(nil) do
1575      try
1576        MaxPage:= Preview.Pages.PageCount;
1577        filt:= nil;
1578        if (SelectedFilter <> nil) and (SelectedFilter is TRLCustomSaveFilter) then
1579          filt:= TRLCustomSaveFilter(SelectedFilter);
1580
1581        if Self.Preview.Pages.Title <> '' then
1582          FileName:= ExpandFileName(FileNameFromText(Self.Preview.Pages.Title))
1583        else if (filt <> nil) then
1584          FileName:= filt.FileName
1585        else
1586          FileName:= '';
1587
1588        if not Execute then
1589          exit;
1590
1591        if (FileName = '') then
1592          raise Exception.Create(GetLocalizeStr(LocaleStrings.LS_FileNameIsEmpty));
1593
1594        firstpg:= FromPage;
1595        lastpg:= ToPage;
1596        fname:= FileName;
1597        fext:= ExtractFileExt(fname);
1598        if fext = '' then
1599          begin
1600            ApplyExt(fname);
1601            fext:= ExtractFileExt(fname);
1602          end;
1603
1604        if (filt = nil) or (LowerCase(filt.DefaultExt) <> LowerCase(fext)) then
1605          filt:= SaveFilterByFileName(fname);
1606
1607        if filt <> nil then
1608          begin
1609            filt.FileName:= fname;
1610            filt.FilterPages(Preview.Pages, firstpg, lastpg, '', PrintOddAndEvenPages);
1611          end
1612        else
1613          Preview.Pages.SaveToFile(fname);
1614      finally
1615        Free;
1616      end;
1617  finally
1618    // focuscontrole voor CLX
1619    if not Assigned(priorfocus) or not((priorfocus is TCustomEdit) or (priorfocus is TCustomComboBox)) then
1620      priorfocus:= EditPageNo;
1621    priorfocus.SetFocus;
1622  end;
1623  if Assigned(SetupInstance) and Assigned(SetupInstance.AfterSave) then
1624    SetupInstance.AfterSave(Self);
1625end;
1626
1627procedure TRLPreviewForm.SpeedButtonSendClick(Sender: TObject);
1628begin
1629  if Assigned(SetupInstance) and Assigned(SetupInstance.BeforeSend) then
1630    SetupInstance.BeforeSend(Self);
1631  if Assigned(SetupInstance) and Assigned(SetupInstance.OnSend) then
1632    SetupInstance.OnSend(Self);
1633  if Assigned(SetupInstance) and Assigned(SetupInstance.AfterSend) then
1634    SetupInstance.AfterSend(Self);
1635end;
1636
1637procedure TRLPreviewForm.SpeedButtonSearchClick(Sender: TObject);
1638begin
1639  ShowFindDialog;
1640end;
1641
1642procedure TRLPreviewForm.ShowFindDialog;
1643begin
1644  if not Assigned(FFindDialog) then
1645    begin
1646      FFindDialog:= TfrmRLFindDialog.CreateNew(nil);
1647      FFindDialog.OnFind:= OnFindHandler;
1648    end;
1649  FFindDialog.ActiveControl:= FFindDialog.EditTextToFind;
1650  FFindDialog.Show;
1651end;
1652
1653procedure TRLPreviewForm.OnFindHandler(Sender: TObject; const AText: string; Options: TRLFindOptions;
1654  var Found: Boolean);
1655begin
1656  Found:= Preview.FindText(AText, foWholeWords in Options, foMatchCase in Options, foFindBackward in Options);
1657end;
1658
1659procedure TRLPreviewForm.UpdateComboBoxZoom;
1660var
1661  savedevent: TNotifyEvent;
1662begin
1663  if FEditingZoom then
1664    exit;
1665  savedevent:= ComboBoxZoom.OnChange;
1666  try
1667    ComboBoxZoom.ItemIndex:= -1;
1668    ComboBoxZoom.Text:= FloatToStr(Preview.ZoomFactor) + '%';
1669  finally
1670    ComboBoxZoom.OnChange:= savedevent;
1671  end;
1672end;
1673
1674procedure TRLPreviewForm.UpdateEditPageNo;
1675var
1676  savedevent: TNotifyEvent;
1677begin
1678  if FEditingPageNo then
1679    exit;
1680  savedevent:= EditPageNo.OnChange;
1681  try
1682    EditPageNo.Text:= IntToStr(Preview.PageIndex + 1);
1683  finally
1684    EditPageNo.OnChange:= savedevent;
1685  end;
1686end;
1687
1688procedure TRLPreviewForm.rpvDefaultChangeView(Sender: TObject);
1689begin
1690  PanelPageCount.Caption:= IntToStr(Preview.Pages.PageCount);
1691  UpdateEditPageNo;
1692  UpdateComboBoxZoom;
1693end;
1694
1695procedure TRLPreviewForm.SpeedButtonPriorClick(Sender: TObject);
1696begin
1697  Preview.PriorPage;
1698end;
1699
1700procedure TRLPreviewForm.SpeedButtonZoomUpClick(Sender: TObject);
1701begin
1702  Preview.ZoomFactor:= Preview.ZoomFactor + 10;
1703  UpdateComboBoxZoom;
1704end;
1705
1706procedure TRLPreviewForm.SpinEditCopiesChange(Sender: TObject);
1707begin
1708   RLPrinter.Copies:= SpinEditCopies.Value;
1709end;
1710
1711procedure TRLPreviewForm.SpeedButtonZoomDownClick(Sender: TObject);
1712begin
1713  Preview.ZoomFactor:= Max(10, Preview.ZoomFactor - 10);
1714  UpdateComboBoxZoom;
1715end;
1716
1717procedure TRLPreviewForm.SpeedButtonViewsClick(Sender: TObject);
1718begin
1719  if FPreviewList.Count > 1 then
1720    ReleasePreview
1721  else
1722    NewPreview;
1723  OrganizePreviews;
1724end;
1725
1726procedure TRLPreviewForm.SpeedButtonEditClick(Sender: TObject);
1727begin
1728  Preview.Editing:= not Preview.Editing;
1729end;
1730
1731function TRLPreviewForm.GetPreview: TRLPreview;
1732begin
1733  Result:= TRLPreview(FPreviewList[FPreviewIndex]);
1734end;
1735
1736procedure TRLPreviewForm.PreviewEnter(Sender: TObject);
1737begin
1738  SetPreview(TRLPreview(Sender));
1739end;
1740
1741procedure TRLPreviewForm.SetPreview(APreview: TRLPreview);
1742begin
1743  FPreviewIndex:= FPreviewList.IndexOf(APreview);
1744  UpdateEditPageNo;
1745  UpdateComboBoxZoom;
1746end;
1747
1748{ TRLPreviewSetup }
1749
1750constructor TRLPreviewSetup.Create(AOwner: TComponent);
1751begin
1752  FBeforePrint:= nil;
1753  FAfterPrint:= nil;
1754  FBeforeSave:= nil;
1755  FAfterSave:= nil;
1756  FBeforeSend:= nil;
1757  FOnSend:= nil;
1758  FAfterSend:= nil;
1759  FEnabledButtons:= [pbPrint, pbSave, pbSend];
1760  FEditOptions:= [];
1761  FCustomActionText:= '';
1762  FOnCustomAction:= nil;
1763  inherited;
1764  if not(csDesigning in ComponentState) then
1765    begin
1766      if Assigned(SetupInstance) then
1767        raise Exception.Create(Format(GetLocalizeStr(LocaleStrings.LS_OnlyOneInstance), [ClassName]));
1768      SetupInstance:= Self;
1769    end;
1770end;
1771
1772destructor TRLPreviewSetup.Destroy;
1773begin
1774  if SetupInstance = Self then
1775    SetupInstance:= nil;
1776  inherited;
1777end;
1778
1779function TRLPreviewSetup.GetBorderIcons: TBorderIcons;
1780begin
1781  Result:= DefaultBorderIcons;
1782end;
1783
1784function TRLPreviewSetup.GetCaption: string;
1785begin
1786  Result:= DefaultCaption;
1787end;
1788
1789function TRLPreviewSetup.GetFormStyle: TFormStyle;
1790begin
1791  Result:= DefaultFormStyle;
1792end;
1793
1794function TRLPreviewSetup.GetHelpContext: Integer;
1795begin
1796  Result:= DefaultHelpContext;
1797end;
1798
1799function TRLPreviewSetup.GetHelpFile: string;
1800begin
1801  Result:= DefaultHelpFile;
1802end;
1803
1804function TRLPreviewSetup.GetPosition: TPosition;
1805begin
1806  Result:= DefaultPosition;
1807end;
1808
1809function TRLPreviewSetup.GetSentToPrinter: Boolean;
1810begin
1811  Result:= RLPreviewForm.SentToPrinter;
1812end;
1813
1814function TRLPreviewSetup.GetShowModal: Boolean;
1815begin
1816  Result:= DefaultShowModal;
1817end;
1818
1819function TRLPreviewSetup.GetWindowBounds: TRect;
1820begin
1821  Result:= DefaultWindowBounds;
1822end;
1823
1824function TRLPreviewSetup.GetWindowState: TWindowState;
1825begin
1826  Result:= DefaultWindowState;
1827end;
1828
1829function TRLPreviewSetup.GetZoomFactor: Double;
1830begin
1831  Result:= DefaultZoomFactor;
1832end;
1833
1834function TRLPreviewSetup.IsZoomFactor: Boolean;
1835begin
1836  Result:= (DefaultZoomFactor <> 100);
1837end;
1838
1839procedure TRLPreviewSetup.SetBorderIcons(const Value: TBorderIcons);
1840begin
1841  DefaultBorderIcons:= Value;
1842end;
1843
1844procedure TRLPreviewSetup.SetCaption(const Value: string);
1845begin
1846  DefaultCaption:= Value;
1847end;
1848
1849procedure TRLPreviewSetup.SetEditOptions(const Value: TRLPreviewEditOptionsSet);
1850begin
1851  FEditOptions:= Value;
1852end;
1853
1854procedure TRLPreviewSetup.SetEnabledButtons(const Value: TRLPreviewFormButtonsSet);
1855begin
1856  FEnabledButtons:= Value;
1857end;
1858
1859procedure TRLPreviewSetup.SetFormStyle(const Value: TFormStyle);
1860begin
1861  DefaultFormStyle:= Value;
1862end;
1863
1864procedure TRLPreviewSetup.SetHelpContext(const Value: Integer);
1865begin
1866  DefaultHelpContext:= Value;
1867end;
1868
1869procedure TRLPreviewSetup.SetHelpFile(const Value: string);
1870begin
1871  DefaultHelpFile:= Value;
1872end;
1873
1874procedure TRLPreviewSetup.SetPosition(const Value: TPosition);
1875begin
1876  DefaultPosition:= Value;
1877end;
1878
1879procedure TRLPreviewSetup.SetSentToPrinter(const Value: Boolean);
1880begin
1881  RLPreviewForm.SentToPrinter:= Value;
1882end;
1883
1884procedure TRLPreviewSetup.SetShowModal(const Value: Boolean);
1885begin
1886  DefaultShowModal:= Value;
1887end;
1888
1889procedure TRLPreviewSetup.SetWindowBounds(const Value: TRect);
1890begin
1891  DefaultWindowBounds:= Value;
1892end;
1893
1894procedure TRLPreviewSetup.SetWindowState(const Value: TWindowState);
1895begin
1896  DefaultWindowState:= Value;
1897end;
1898
1899procedure TRLPreviewSetup.SetZoomFactor(const Value: Double);
1900begin
1901  DefaultZoomFactor:= Value;
1902end;
1903
1904procedure TRLPreviewForm.CreateParams(var Params: TCreateParams);
1905begin
1906  inherited CreateParams(Params);
1907  if ShowPreviewOnWindowsTaskBar then
1908    begin
1909      Params.ExStyle:= Params.ExStyle or WS_EX_APPWINDOW or WS_EX_NOPARENTNOTIFY;
1910      Params.WndParent:= GetDesktopwindow;
1911    end;
1912end;
1913
1914procedure TRLPreviewForm.WMActivate(var Message: TWMActivate);
1915begin
1916  inherited;
1917  if ShowPreviewOnWindowsTaskBar and not IsWindowEnabled(Handle) then
1918    EnableWindow(Handle, True);
1919end;
1920
1921procedure TRLPreviewForm.ButtonAnnulerenClick(Sender: TObject);
1922begin
1923  Close;
1924end;
1925
1926procedure TRLPreviewForm.CMMouseWheel(var Message: TCMMouseWheel);
1927begin
1928  if GetKeyState(VK_CONTROL) < 0 then
1929    begin
1930      if message.WheelDelta > 0 then
1931        Preview.ZoomIn
1932      else
1933        Preview.ZoomOut;
1934    end
1935  else if message.WheelDelta > 0 then
1936    Preview.ScrollUp
1937  else
1938    Preview.ScrollDown;
1939end;
1940
1941procedure TRLPreviewForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
1942begin
1943  case Key of
1944    VK_CONTROL:
1945      Preview.DisableCapture;
1946  end;
1947end;
1948
1949procedure TRLPreviewForm.FormResize(Sender: TObject);
1950var
1951  PaddingLeftRight: Integer;
1952begin
1953  // Center Toolbar below preview document
1954  with PanelTools do
1955    begin
1956      AlignWithMargins:= True;
1957      Margins.Top:= 0;
1958      Margins.Bottom:= 0;
1959      PaddingLeftRight:= (PanelRight.Width - ToolbarWidth) div 2;
1960      if PaddingLeftRight >= 0 then
1961        begin
1962          Margins.Left:= PaddingLeftRight;
1963          Margins.Right:= PaddingLeftRight;
1964        end;
1965    end;
1966end;
1967
1968procedure TRLPreviewForm.FormShow(Sender: TObject);
1969
1970  procedure GetDuplexMode;
1971  var
1972    Device, Driver, Port: string;
1973    DriverHandle: THandle;
1974    DevModeRef: PDeviceMode;
1975  begin
1976    Printer.GetPrinter(Device, Driver, Port, DriverHandle);
1977    if DriverHandle <> 0 then
1978      begin
1979        DevModeRef:= GlobalLock(DriverHandle);
1980        if DevModeRef <> nil then
1981          try
1982            case DevModeRef^.dmDuplex of
1983              DMDUP_SIMPLEX:
1984                ComboBoxDuplex.ItemIndex:= 0;
1985              DMDUP_VERTICAL:
1986                ComboBoxDuplex.ItemIndex:= 1;
1987              DMDUP_HORIZONTAL:
1988                ComboBoxDuplex.ItemIndex:= 2;
1989            end;
1990          finally
1991            GlobalUnlock(DriverHandle);
1992          end;
1993      end;
1994  end;
1995
1996begin
1997  if Preview.Pages.Orientation = MetaOrientationLandscape then
1998    RadioGroupLayout.ItemIndex:= 1
1999  else
2000    RadioGroupLayout.ItemIndex:= 0;
2001  SpinEditCopies.Value:= 1;
2002  EditPageSelection.Text:= '';
2003  if RLPrinter.SupportsDuplex then
2004    GetDuplexMode;
2005  ButtonAfdrukken.SetFocus;
2006end;
2007
2008end.
2009