/components/printers/unix/framepagesetup.pas
http://github.com/graemeg/lazarus · Pascal · 320 lines · 262 code · 41 blank · 17 comment · 22 complexity · 2729cb1c7fa75c1361ca1c3b8ae3ade3 MD5 · raw file
- unit framePageSetup;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, Graphics, FileUtil, LResources, Forms, ExtCtrls, StdCtrls,
- Printers, OsPrinters, LCLIntf, LCLProc, Controls, CupsLCL;
- type
- TPageSetupMode = (psmFull, psmPapers, psmMargins);
- TPageSetupOption = (
- psoMargins, // margins and preview are visible
- psoPapers, // papers group visible
- psoOrientation // orientation group visible
- );
- TPageSetupOptions = set of TPageSetupOption;
- { TframePageSetup }
- TframePageSetup = class(TFrame)
- cbPaper: TComboBox;
- cbSource: TComboBox;
- panMargins: TPanel;
- txtLeft: TEdit;
- txtRight: TEdit;
- txtTop: TEdit;
- txtBottom: TEdit;
- gpPaper: TGroupBox;
- gpOrientation: TGroupBox;
- gpMargins: TGroupBox;
- lblSource: TLabel;
- lblPaper: TLabel;
- lblLeft: TLabel;
- lblRight: TLabel;
- lblTop: TLabel;
- lblBottom: TLabel;
- pbPreview: TPaintBox;
- panSetup: TPanel;
- panPreview: TPanel;
- radLandscape: TRadioButton;
- radPortrait: TRadioButton;
- procedure cbPaperChange(Sender: TObject);
- procedure panPreviewResize(Sender: TObject);
- procedure pbPreviewMouseDown(Sender: TObject; Button: TMouseButton;
- {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
- procedure pbPreviewMouseWheelDown(Sender: TObject; {%H-}Shift: TShiftState;
- {%H-}MousePos: TPoint; var Handled: Boolean);
- procedure pbPreviewMouseWheelUp(Sender: TObject; {%H-}Shift: TShiftState;
- {%H-}MousePos: TPoint; var Handled: Boolean);
- procedure pbPreviewPaint(Sender: TObject);
- procedure radPortraitClick(Sender: TObject);
- private
- { private declarations }
- FHeightTallest: Integer;
- FHardMargins: TRect;
- FKw,FKh,FZoom: Double;
- FOptions: TPageSetupOptions;
- public
- { public declarations }
- procedure Initialize(AMode: TPageSetupMode);
- procedure UpdatePageSize;
- end;
- implementation
- {$R framepagesetup.lfm}
- { TframePageSetup }
- procedure TframePageSetup.pbPreviewPaint(Sender: TObject);
- var
- R: TRect;
- procedure DrawMargin(AIndex: Integer; ASize: Integer);
- begin
- with pbPreview do
- case AIndex of
- 0: // Left
- begin
- Canvas.MoveTo(ASize, 1);
- Canvas.LineTo(ASize, Height-1);
- end;
- 1: //Top
- begin
- Canvas.MoveTo(1,ASize);
- Canvas.LineTo(Width-1, ASize);
- end;
- 2: // Right
- begin
- Canvas.MoveTo(Width-1-ASize, 1);
- Canvas.LineTo(Width-1-ASize,Height-1);
- end;
- 3: // Bottom
- begin
- Canvas.MoveTo(1,Height-1-Asize);
- Canvas.LineTo(Width-1, Height-1-ASize);
- end;
- end;
- end;
- begin
- if Sender=nil then ;
- if not (psoMargins in FOptions) then
- exit;
- with pbPreview do
- begin
- // page frame
- R := Rect(0,0,Width,Height);
- Canvas.Pen.Color := clBlack;
- Canvas.Brush.Color:=clWhite;
- Canvas.Rectangle(R);
- // hard margins
- Canvas.Pen.Color := RGBToColor(255,204,204);
- DrawMargin(0, FHardMargins.Left );
- DrawMargin(1, FHardMargins.Top );
- DrawMargin(2, FHardMargins.Right );
- DrawMargin(3, FHardMargins.Bottom);
- end;
- end;
- procedure TframePageSetup.radPortraitClick(Sender: TObject);
- begin
- if sender=nil then ;
- if radPortrait.Checked then
- Printer.Orientation := poPortrait
- else
- Printer.Orientation := poLandsCape;
- UpdatePageSize;
- end;
- procedure TframePageSetup.cbPaperChange(Sender: TObject);
- begin
- if Printer.PaperSize.DefaultPapers then
- begin
- if cbPaper.ItemIndex>=0 then
- Printer.PaperSize.PaperName := cbPaper.Items[cbPaper.ItemIndex];
- end else
- Printer.PaperSize.PaperName := GetCupsComboKeyValue(cbPaper);
- UpdatePageSize;
- end;
- procedure TframePageSetup.panPreviewResize(Sender: TObject);
- var
- TallH: Integer;
- begin
- if not (psoMargins in FOptions) then
- exit;
- TallH := Round(FheightTallest * FKh);
- with PanPreview do
- if (Height<>C_BOTHSPACES) and (TallH>(Height-C_BOTHSPACES)) then
- FZoom := (Height-C_BOTHSPACES)/TallH
- else
- FZoom := 1.0;
- end;
- procedure TframePageSetup.pbPreviewMouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if Button=mbMiddle then
- begin
- FZoom := 1;
- UpdatePageSize;
- end;
- end;
- procedure TframePageSetup.pbPreviewMouseWheelDown(Sender: TObject;
- Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
- begin
- FZoom := FZoom - 0.2;
- if FZoom<0.5 then
- FZoom := 0.5;
- UpdatePageSize;
- Handled := true;
- end;
- procedure TframePageSetup.pbPreviewMouseWheelUp(Sender: TObject;
- Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
- begin
- FZoom := FZoom + 0.2;
- UpdatePageSize;
- Handled := true;
- end;
- procedure TframePageSetup.UpdatePageSize;
- begin
- if not (psoMargins in FOptions) then
- exit;
- with Printer.PaperSize.PaperRect.PhysicalRect do
- begin
- PbPreview.Width := Round(Fkw * (Right - Left) * FZoom) + 2;
- PbPreview.Height := Round(FKh * (Bottom - Top) * FZoom) + 2;
- end;
- with Printer.PaperSize.PaperRect do
- begin
- FHardMargins.Left := Round(Fkw * (WorkRect.Left-PhysicalRect.Left) * FZoom);
- FHardMargins.Right := Round(Fkw * (Physicalrect.Right-WorkRect.Right) * FZoom);
- FHardMargins.Top := Round(FkH * (WorkRect.Top-PhysicalRect.Top) * FZoom);
- FHardMargins.Bottom := Round(FkH * (PhysicalRect.Bottom-WorkRect.Bottom) * FZoom);
- end;
- {$IFDEF DebugCUPS}
- with FHardMargins do
- begin
- DebugLn(' Kh=%.2f Kw=%.2f',[FKh,FKw]);
- DebugLn(' BoxLimits L=0 T=0 R=%d B=%d',[PbPreview.Width-1,PbPreview.Height-1]);
- DebugLn('OrgMargins L=%d T=%d R=%d B=%d',[Left,Top,Right,Bottom]);
- end;
- {$ENDIF}
- end;
- procedure TframePageSetup.Initialize(AMode: TPageSetupMode);
- var
- i,j:Integer;
- R: TPaperRect;
- begin
- case AMode of
- psmMargins:
- FOptions := [psoMargins];
- psmPapers:
- FOptions := [psoPapers,psoOrientation];
- else
- FOptions := [psoMargins,psoPapers,psoOrientation];
- end;
- if [psoMargins,psoPapers]*FOptions<>[] then
- begin
- SetupCupsCombo(cbPaper, nil, 'PageSize');
- if (cbPaper.Items.Count=0) then
- begin
- // no cups printer papers, use default ones
- cbPaper.Items := Printer.PaperSize.SupportedPapers;
- cbPaper.ItemIndex:= cbPaper.Items.IndexOf(Printer.PaperSize.PaperName);
- cbPaper.Enabled:=true;
- end;
- end;
- if psoPapers in FOptions then
- SetupCupsCOmbo(cbSource, nil, 'InputSlot')
- else
- gpPaper.Visible := false;
- //TODO: support reverse variants too?
- gpOrientation.Visible := (psoOrientation in FOptions);
- case Printer.Orientation of
- poPortrait,poReversePortrait:
- radPortrait.Checked := true;
- poLandscape,poReverseLandscape:
- radLandscape.Checked := true;
- end;
- if psoMargins in FOptions then
- begin
- // assume 100 pix = 8.5 inch (IOW, letter size width = 100 pixels)
- with ScreenInfo do
- begin
- FKw := (100/8.5)/Printer.XDPI;
- FKh := (100/8.5)*(PixelsPerInchY/PixelsPerInchX)/Printer.YDPI;
- end;
- // find the tallest paper
- FHeightTallest := 0;
- j := -1;
- if cbPaper.Enabled then
- for i:=0 to cbPaper.Items.Count-1 do
- begin
- if Printer.PaperSize.DefaultPapers then
- R := Printer.PaperSize.PaperRectOf[cbPaper.Items[i]]
- else
- R := Printer.PaperSize.PaperRectOf[GetCupsComboKeyValue(cbPaper, i)];
- with R.PhysicalRect do
- if FHeightTallest<(Bottom-Top) then
- begin
- FHeightTallest := (Bottom-Top);
- j := i;
- end;
- end;
- if j>=0 then
- begin
- {$IFDEF DebugCUPS}
- DebugLn(' Tallest Paper is: %s Height=%d %.2f Inch',
- [cbPaper.Items[j],FHeightTallest,FHeightTallest/Printer.YDPI]);
- {$ENDIF}
- end;
- // zoom factor
- FZoom := 1.0;
- UpdatePageSize;
- end else
- begin
- panPreview.Visible:=false;
- gpMargins.Visible:=false;
- end;
- if AMode=psmPapers then
- begin
- gpOrientation.Anchors:=[akTop,akRight,akBottom];
- gpOrientation.Align:=alRight;
- gpPaper.Anchors:=[akTop,akLeft];
- gpPaper.Align:=alClient;
- PanSetup.Align:=alClient;
- end else
- if AMode=psmMargins then
- PanSetup.Height:=gpMargins.Height+C_BOTHSPACES;
- end;
- end.