3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
20 #include <GroupLayout.h>
21 #include <GroupLayoutBuilder.h>
23 #include <MessageFilter.h>
24 #include <MenuField.h>
28 #include <PopUpMenu.h>
30 #include <RadioButton.h>
33 #include <SupportDefs.h>
34 #include <TextControl.h>
40 #include "MarginView.h"
41 #include "PageSetupDlg.h"
42 #include "PrinterData.h"
43 #include "PrinterCap.h"
44 #include "PrintUtils.h"
53 kMsgOrientationChanged
,
57 PageSetupView::PageSetupView(JobData
*job_data
, PrinterData
*printer_data
,
58 const PrinterCap
*printer_cap
)
59 : BView("pageSetupView", B_WILL_DRAW
)
61 , fPrinterData(printer_data
)
62 , fPrinterCap(printer_cap
)
64 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
67 PageSetupView::~PageSetupView()
72 PageSetupView::AddOrientationItem(const char* name
, JobData::Orientation orientation
)
74 BMessage
*msg
= new BMessage(kMsgOrientationChanged
);
75 msg
->AddInt32("orientation", orientation
);
76 BMenuItem
*item
= new BMenuItem(name
, msg
);
78 fOrientation
->AddItem(item
);
79 item
->SetTarget(this);
80 if (fJobData
->GetOrientation() == orientation
) {
81 item
->SetMarked(true);
82 } else if (fOrientation
->CountItems() == 1) {
83 item
->SetMarked(true);
88 PageSetupView::AttachedToWindow()
90 BMenuItem
*item
= NULL
;
95 MarginUnit units
= fJobData
->GetMarginUnit();
96 BRect paper
= fJobData
->GetPaperRect();
97 BRect margin
= fJobData
->GetPrintableRect();
99 // re-calculate the margin from the printable rect in points
100 margin
.top
-= paper
.top
;
101 margin
.left
-= paper
.left
;
102 margin
.right
= paper
.right
- margin
.right
;
103 margin
.bottom
= paper
.bottom
- margin
.bottom
;
105 fMarginView
= new MarginView(
106 paper
.IntegerWidth(),
107 paper
.IntegerHeight(),
112 fPaper
= new BPopUpMenu("paperSize");
113 fPaper
->SetRadioMode(true);
114 count
= fPrinterCap
->CountCap(PrinterCap::kPaper
);
115 PaperCap
**paper_cap
= (PaperCap
**)fPrinterCap
->GetCaps(PrinterCap::kPaper
);
117 BMessage
*msg
= new BMessage(kMsgPaperChanged
);
118 msg
->AddPointer("paperCap", *paper_cap
);
119 item
= new BMenuItem((*paper_cap
)->fLabel
.c_str(), msg
);
120 fPaper
->AddItem(item
);
121 item
->SetTarget(this);
122 if ((*paper_cap
)->fPaper
== fJobData
->GetPaper()) {
123 item
->SetMarked(true);
129 item
->SetMarked(true);
130 BMenuField
* paperSize
= new BMenuField("paperSize", "Paper size:", fPaper
);
133 fOrientation
= new BPopUpMenu("orientation");
134 fOrientation
->SetRadioMode(true);
136 BMenuField
* orientation
= new BMenuField("orientation", "Orientation:", fOrientation
);
138 count
= fPrinterCap
->CountCap(PrinterCap::kOrientation
);
140 AddOrientationItem("Portrait", JobData::kPortrait
);
141 AddOrientationItem("Landscape", JobData::kLandscape
);
143 OrientationCap
**orientation_cap
= (OrientationCap
**)fPrinterCap
->GetCaps(PrinterCap::kOrientation
);
145 AddOrientationItem((*orientation_cap
)->fLabel
.c_str(),
146 (*orientation_cap
)->fOrientation
);
153 fResolution
= new BPopUpMenu("resolution");
154 fResolution
->SetRadioMode(true);
155 count
= fPrinterCap
->CountCap(PrinterCap::kResolution
);
156 ResolutionCap
**resolution_cap
= (ResolutionCap
**)fPrinterCap
->GetCaps(PrinterCap::kResolution
);
158 item
= new BMenuItem((*resolution_cap
)->fLabel
.c_str(), NULL
);
159 fResolution
->AddItem(item
);
160 item
->SetTarget(this);
161 if (((*resolution_cap
)->fXResolution
== fJobData
->GetXres()) &&
162 ((*resolution_cap
)->fYResolution
== fJobData
->GetYres())) {
163 item
->SetMarked(true);
169 item
->SetMarked(true);
170 BMenuField
* resolution
= new BMenuField("resolution", "Resolution:", fResolution
);
174 scale
<< (int)fJobData
->GetScaling();
175 fScaling
= new BTextControl("scale", "Scale [%]:",
179 for (num
= 0; num
<= 255; num
++) {
180 fScaling
->TextView()->DisallowChar(num
);
182 for (num
= 0; num
<= 9; num
++) {
183 fScaling
->TextView()->AllowChar('0' + num
);
185 fScaling
->TextView()->SetMaxBytes(3);
188 BButton
* cancel
= new BButton("cancel", "Cancel", new BMessage(kMsgCancel
));
189 BButton
* ok
= new BButton("ok", "OK", new BMessage(kMsgOK
));
191 ok
->MakeDefault(true);
193 BGridView
* settings
= new BGridView();
194 BGridLayout
* settingsLayout
= settings
->GridLayout();
195 settingsLayout
->AddItem(paperSize
->CreateLabelLayoutItem(), 0, 0);
196 settingsLayout
->AddItem(paperSize
->CreateMenuBarLayoutItem(), 1, 0);
197 settingsLayout
->AddItem(orientation
->CreateLabelLayoutItem(), 0, 1);
198 settingsLayout
->AddItem(orientation
->CreateMenuBarLayoutItem(), 1, 1);
199 settingsLayout
->AddItem(resolution
->CreateLabelLayoutItem(), 0, 2);
200 settingsLayout
->AddItem(resolution
->CreateMenuBarLayoutItem(), 1, 2);
201 settingsLayout
->AddItem(fScaling
->CreateLabelLayoutItem(), 0, 3);
202 settingsLayout
->AddItem(fScaling
->CreateTextViewLayoutItem(), 1, 3);
203 settingsLayout
->SetSpacing(0, 0);
205 SetLayout(new BGroupLayout(B_VERTICAL
));
206 AddChild(BGroupLayoutBuilder(B_VERTICAL
, 0)
207 .AddGroup(B_HORIZONTAL
, 5, 1.0f
)
208 .AddGroup(B_VERTICAL
, 0, 1.0f
)
212 .AddGroup(B_VERTICAL
, 0, 1.0f
)
217 .AddGroup(B_HORIZONTAL
, 10, 1.0f
)
222 .SetInsets(10, 10, 10, 10)
227 swap(float *e1
, float *e2
)
235 PageSetupView::GetOrientation()
237 BMenuItem
*item
= fOrientation
->FindMarked();
240 item
->Message()->FindInt32("orientation", &orientation
) == B_OK
) {
241 return (JobData::Orientation
)orientation
;
243 return JobData::kPortrait
;
248 PageSetupView::GetPaperCap()
250 BMenuItem
*item
= fPaper
->FindMarked();
253 item
->Message()->FindPointer("paperCap", &pointer
) == B_OK
) {
254 return (PaperCap
*)pointer
;
256 return (PaperCap
*)fPrinterCap
->GetDefaultCap(PrinterCap::kPaper
);
261 PageSetupView::UpdateJobData()
263 fJobData
->SetOrientation(GetOrientation());
265 PaperCap
*paperCap
= GetPaperCap();
266 BRect paper_rect
= paperCap
->fPaperRect
;
267 BRect physical_rect
= paperCap
->fPhysicalRect
;
268 fJobData
->SetPaper(paperCap
->fPaper
);
270 const char *resolutionLabel
= fResolution
->FindMarked()->Label();
271 const ResolutionCap
* resolution
= static_cast<const ResolutionCap
*>(
272 fPrinterCap
->FindCap(PrinterCap::kResolution
, resolutionLabel
));
273 ASSERT(resolution
!= NULL
);
274 if (resolution
!= NULL
) {
275 fJobData
->SetXres(resolution
->fXResolution
);
276 fJobData
->SetYres(resolution
->fYResolution
);
277 fJobData
->SetResolutionID(resolution
->ID());
280 // rotate paper and physical rectangle if landscape orientation
281 if (JobData::kLandscape
== fJobData
->GetOrientation()) {
282 swap(&paper_rect
.left
, &paper_rect
.top
);
283 swap(&paper_rect
.right
, &paper_rect
.bottom
);
284 swap(&physical_rect
.left
, &physical_rect
.top
);
285 swap(&physical_rect
.right
, &physical_rect
.bottom
);
288 // adjust printable rect by margin
289 fJobData
->SetMarginUnit(fMarginView
->Unit());
290 BRect margin
= fMarginView
->Margin();
291 BRect printable_rect
;
292 printable_rect
.left
= paper_rect
.left
+ margin
.left
;
293 printable_rect
.top
= paper_rect
.top
+ margin
.top
;
294 printable_rect
.right
= paper_rect
.right
- margin
.right
;
295 printable_rect
.bottom
= paper_rect
.bottom
- margin
.bottom
;
297 printable_rect
.left
= max_c(printable_rect
.left
, physical_rect
.left
);
298 printable_rect
.top
= max_c(printable_rect
.top
, physical_rect
.top
);
299 printable_rect
.right
= min_c(printable_rect
.right
, physical_rect
.right
);
300 printable_rect
.bottom
= min_c(printable_rect
.bottom
, physical_rect
.bottom
);
302 float scaling
= atoi(fScaling
->Text());
303 if (scaling
<= 0.0) { // sanity check
306 if (scaling
> 1000.0) {
310 float scalingR
= 100.0 / scaling
;
312 fJobData
->SetScaling(scaling
);
313 fJobData
->SetPaperRect(paper_rect
);
314 fJobData
->SetScaledPaperRect(ScaleRect(paper_rect
, scalingR
));
315 fJobData
->SetPrintableRect(printable_rect
);
316 fJobData
->SetScaledPrintableRect(ScaleRect(printable_rect
, scalingR
));
317 fJobData
->SetPhysicalRect(physical_rect
);
318 fJobData
->SetScaledPhysicalRect(ScaleRect(physical_rect
, scalingR
));
325 PageSetupView::MessageReceived(BMessage
*msg
)
328 case kMsgPaperChanged
:
329 case kMsgOrientationChanged
:
331 JobData::Orientation orientation
= GetOrientation();
332 PaperCap
*paperCap
= GetPaperCap();
333 float width
= paperCap
->fPaperRect
.Width();
334 float height
= paperCap
->fPaperRect
.Height();
335 if (orientation
!= JobData::kPortrait
) {
336 swap(&width
, &height
);
338 fMarginView
->SetPageSize(width
, height
);
339 fMarginView
->UpdateView(MARGIN_CHANGED
);
346 //====================================================================
348 // TODO center window on screen
349 PageSetupDlg::PageSetupDlg(JobData
*job_data
, PrinterData
*printer_data
, const PrinterCap
*printer_cap
)
350 : DialogWindow(BRect(100, 100, 160, 160),
351 "Paper setup", B_TITLED_WINDOW_LOOK
, B_MODAL_APP_WINDOW_FEEL
,
352 B_NOT_RESIZABLE
| B_NOT_MINIMIZABLE
| B_NOT_ZOOMABLE
353 | B_AUTO_UPDATE_SIZE_LIMITS
| B_CLOSE_ON_ESCAPE
)
355 AddShortcut('W',B_COMMAND_KEY
,new BMessage(B_QUIT_REQUESTED
));
357 fPageSetupView
= new PageSetupView(job_data
, printer_data
,
360 SetLayout(new BGroupLayout(B_HORIZONTAL
));
361 AddChild(BGroupLayoutBuilder(B_HORIZONTAL
, 0)
369 PageSetupDlg::MessageReceived(BMessage
*msg
)
374 fPageSetupView
->UpdateJobData();
376 SetResult(B_NO_ERROR
);
377 PostMessage(B_QUIT_REQUESTED
);
381 PostMessage(B_QUIT_REQUESTED
);
385 DialogWindow::MessageReceived(msg
);