mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-10 10:28:21 +02:00
321 lines
8.0 KiB
ObjectPascal
321 lines
8.0 KiB
ObjectPascal
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.
|
|
|