2 * Copyright 2002-2011, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
10 #include "ConfigWindow.h"
17 #include <Application.h>
21 #include <GroupLayout.h>
22 #include <GroupLayoutBuilder.h>
23 #include <IconUtils.h>
26 #include <Resources.h>
29 #include "pr_server.h"
31 #include "PrintServerApp.h"
32 #include "PrintUtils.h"
35 #undef B_TRANSLATION_CONTEXT
36 #define B_TRANSLATION_CONTEXT "ConfigWindow"
39 static const float a0_width
= 2380.0;
40 static const float a0_height
= 3368.0;
41 static const float a1_width
= 1684.0;
42 static const float a1_height
= 2380.0;
43 static const float a2_width
= 1190.0;
44 static const float a2_height
= 1684.0;
45 static const float a3_width
= 842.0;
46 static const float a3_height
= 1190.0;
47 static const float a4_width
= 595.0;
48 static const float a4_height
= 842.0;
49 static const float a5_width
= 421.0;
50 static const float a5_height
= 595.0;
51 static const float a6_width
= 297.0;
52 static const float a6_height
= 421.0;
53 static const float b5_width
= 501.0;
54 static const float b5_height
= 709.0;
55 static const float letter_width
= 612.0;
56 static const float letter_height
= 792.0;
57 static const float legal_width
= 612.0;
58 static const float legal_height
= 1008.0;
59 static const float ledger_width
= 1224.0;
60 static const float ledger_height
= 792.0;
61 static const float tabloid_width
= 792.0;
62 static const float tabloid_height
= 1224.0;
63 static const float jis_b5_width
= 516.0;
64 static const float jis_b5_height
= 729.0;
67 static struct PageFormat
74 {B_TRANSLATE_MARK_COMMENT("Letter", "ANSI A (letter), a North American "
75 "paper size"), letter_width
, letter_height
},
76 {B_TRANSLATE_MARK_COMMENT("Legal", "A North American paper size (216 x 356"
77 " mm, or 8.5 x 14 in)"), legal_width
, legal_height
},
78 {B_TRANSLATE_MARK_COMMENT("Ledger", "ANSI B (ledger), a North American "
79 "paper size"), ledger_width
, ledger_height
},
80 {B_TRANSLATE_MARK_COMMENT("Tabloid", "ANSI B (tabloid), a North American "
81 "paper size"), tabloid_width
, tabloid_height
},
82 {B_TRANSLATE_MARK_COMMENT("A0", "ISO 216 paper size"),
83 a0_width
, a0_height
},
84 {B_TRANSLATE_MARK_COMMENT("A1", "ISO 216 paper size"),
85 a1_width
, a1_height
},
86 {B_TRANSLATE_MARK_COMMENT("A2", "ISO 216 paper size"),
87 a2_width
, a2_height
},
88 {B_TRANSLATE_MARK_COMMENT("A3", "ISO 216 paper size"),
89 a3_width
, a3_height
},
90 {B_TRANSLATE_MARK_COMMENT("A4", "ISO 216 paper size"),
91 a4_width
, a4_height
},
92 {B_TRANSLATE_MARK_COMMENT("A5", "ISO 216 paper size"),
93 a5_width
, a5_height
},
94 {B_TRANSLATE_MARK_COMMENT("A6", "ISO 216 paper size"),
95 a6_width
, a6_height
},
96 {B_TRANSLATE_MARK_COMMENT("B5", "ISO 216 paper size"),
97 b5_width
, b5_height
},
98 {B_TRANSLATE_MARK_COMMENT("B5 (JIS)", "JIS P0138 B5, a Japanese "
99 "paper size"), jis_b5_width
, jis_b5_height
},
104 GetPageFormat(float w
, float h
, BString
& label
)
106 w
= floor(w
+ 0.5); h
= floor(h
+ 0.5);
107 for (uint i
= 0; i
< sizeof(pageFormat
) / sizeof(struct PageFormat
); i
++) {
108 struct PageFormat
& pf
= pageFormat
[i
];
109 if ((pf
.width
== w
&& pf
.height
== h
) || (pf
.width
== h
110 && pf
.height
== w
)) {
111 label
= B_TRANSLATE_NOCOLLECT(pf
.label
);
116 float unit
= 72.0; // currently inches only
117 label
<< (w
/ unit
) << "x" << (h
/ unit
) << " in.";
121 static BGroupLayoutBuilder
122 LeftAlign(BView
* view
)
124 return BGroupLayoutBuilder(B_HORIZONTAL
)
127 .SetInsets(0, 0, 0, 0);
131 ConfigWindow::ConfigWindow(config_setup_kind kind
, Printer
* defaultPrinter
,
132 BMessage
* settings
, AutoReply
* sender
)
134 BWindow(ConfigWindow::GetWindowFrame(),
135 B_TRANSLATE("Page setup"),
137 B_NOT_RESIZABLE
| B_NOT_ZOOMABLE
| B_AUTO_UPDATE_SIZE_LIMITS
138 | B_CLOSE_ON_ESCAPE
),
140 fDefaultPrinter(defaultPrinter
),
143 fCurrentPrinter(NULL
),
144 fPageFormatText(NULL
),
147 MimeTypeForSender(settings
, fSenderMimeType
);
148 PrinterForMimeType();
150 if (kind
== kJobSetup
)
151 SetTitle(B_TRANSLATE("Print setup"));
153 BView
* panel
= new BBox(Bounds(), "temporary", B_FOLLOW_ALL
, B_WILL_DRAW
);
156 // print selection pop up menu
157 BPopUpMenu
* menu
= new BPopUpMenu(B_TRANSLATE("Select a printer"));
158 SetupPrintersMenu(menu
);
160 fPrinters
= new BMenuField(B_TRANSLATE("Printer:"), menu
);
162 // page format button
163 fPageSetup
= AddPictureButton(panel
, "Paper setup",
164 "PAGE_SETUP", MSG_PAGE_SETUP
);
166 // add description to button
167 BStringView
*pageFormatTitle
= new BStringView("paperSetupTitle",
168 B_TRANSLATE("Paper setup:"));
169 fPageFormatText
= new BStringView("pageSetupText", "");
171 // page selection button
173 BStringView
* jobSetupTitle
= NULL
;
174 if (kind
== kJobSetup
) {
175 fJobSetup
= AddPictureButton(panel
, "Job setup",
176 "JOB_SETUP", MSG_JOB_SETUP
);
177 // add description to button
178 jobSetupTitle
= new BStringView("jobSetupTitle",
179 B_TRANSLATE("Print job setup:"));
180 fJobSetupText
= new BStringView("jobSetupText", "");
184 BBox
* separator
= new BBox("separator");
185 separator
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, 1));
187 // Cancel & OK button
188 BButton
* cancel
= new BButton("Cancel", B_TRANSLATE("Cancel"),
189 new BMessage(B_QUIT_REQUESTED
));
190 fOk
= new BButton("OK", B_TRANSLATE("OK"), new BMessage(MSG_OK
));
194 SetLayout(new BGroupLayout(B_VERTICAL
));
195 BGroupLayoutBuilder
builder(B_VERTICAL
);
199 .Add(BGroupLayoutBuilder(B_HORIZONTAL
, 10)
201 .Add(BGroupLayoutBuilder(B_VERTICAL
, 0)
202 .Add(LeftAlign(pageFormatTitle
))
203 .Add(LeftAlign(fPageFormatText
))
204 .SetInsets(0, 0, 0, 0)
209 if (fJobSetup
!= NULL
) {
211 .Add(BGroupLayoutBuilder(B_HORIZONTAL
, 10)
213 .Add(BGroupLayoutBuilder(B_VERTICAL
, 0)
214 .Add(LeftAlign(jobSetupTitle
))
215 .Add(LeftAlign(fJobSetupText
))
216 .SetInsets(0, 0, 0, 0)
225 .Add(BGroupLayoutBuilder(B_HORIZONTAL
)
230 .SetInsets(5, 5, 5, 5);
234 AddShortcut('a', 0, new BMessage(B_ABOUT_REQUESTED
));
236 SetDefaultButton(fOk
);
238 fPrinters
->MakeFocus(true);
240 UpdateSettings(true);
244 ConfigWindow::~ConfigWindow()
247 fCurrentPrinter
->Release();
248 release_sem(fFinished
);
255 sem_id sid
= create_sem(0, "finished");
268 ConfigWindow::MessageReceived(BMessage
* m
)
277 case MSG_PRINTER_SELECTED
:
280 if (m
->FindString("name", &printer
) == B_OK
) {
281 UpdateAppSettings(fSenderMimeType
.String(), printer
.String());
282 PrinterForMimeType();
283 UpdateSettings(true);
288 UpdateSettings(false);
289 if (fKind
== kPageSetup
)
290 fSender
->SetReply(&fPageSettings
);
292 fSender
->SetReply(&fJobSettings
);
295 case B_ABOUT_REQUESTED
: AboutRequested();
298 BWindow::MessageReceived(m
);
304 ConfigWindow::AboutRequested()
306 BString text
= B_TRANSLATE("Printer server");
308 "© 2001-2010 Haiku, Inc.\n"
310 "\tIthamar R. Adema\n"
311 "\tMichael Pfeiffer\n";
313 BAlert
*about
= new BAlert("About printer server", text
.String(),
315 about
->SetFlags(about
->Flags() | B_CLOSE_ON_ESCAPE
);
321 ConfigWindow::FrameMoved(BPoint p
)
323 BRect frame
= GetWindowFrame();
325 SetWindowFrame(frame
);
330 ConfigWindow::GetWindowFrame()
332 BRect
frame(0, 0, 10, 10);
333 BAutolock
lock(gLock
);
335 frame
.OffsetBy(Settings::GetSettings()->ConfigWindowFrame().LeftTop());
337 frame
.OffsetBy(30, 30);
343 ConfigWindow::SetWindowFrame(BRect r
)
345 BAutolock
lock(gLock
);
347 Settings::GetSettings()->SetConfigWindowFrame(r
);
352 ConfigWindow::AddPictureButton(BView
* panel
, const char* name
,
353 const char* picture
, uint32 what
)
355 BResources
*res
= BApplication::AppResources();
360 const void *bits
= res
->LoadResource('VICN', picture
, &length
);
361 BButton
* button
= NULL
;
363 BBitmap
* onBM
= new BBitmap(BRect(0, 0, 24, 24), B_RGBA32
);
366 if (BIconUtils::GetVectorIcon((uint8
*)bits
, length
, onBM
) != B_OK
) {
371 button
= new BButton(name
, new BMessage(what
));
372 button
->SetIcon(onBM
, B_TRIM_ICON_BITMAP_KEEP_ASPECT
);
373 button
->SetViewColor(B_TRANSPARENT_COLOR
);
374 button
->SetLabel(NULL
);
384 ConfigWindow::PrinterForMimeType()
386 BAutolock
lock(gLock
);
387 if (fCurrentPrinter
) {
388 fCurrentPrinter
->Release();
389 fCurrentPrinter
= NULL
;
392 if (lock
.IsLocked()) {
393 Settings
* s
= Settings::GetSettings();
394 AppSettings
* app
= s
->FindAppSettings(fSenderMimeType
.String());
396 fPrinterName
= app
->GetPrinter();
398 fPrinterName
= fDefaultPrinter
? fDefaultPrinter
->Name() : "";
399 fCurrentPrinter
= Printer::Find(fPrinterName
);
401 fCurrentPrinter
->Acquire();
407 ConfigWindow::SetupPrintersMenu(BMenu
* menu
)
410 while (menu
->CountItems() != 0)
411 delete menu
->RemoveItem((int32
)0);
413 // fill menu with printer names
414 BAutolock
lock(gLock
);
415 if (lock
.IsLocked()) {
419 for (int i
= 0; i
< Printer::CountPrinters(); i
++) {
420 Printer::At(i
)->GetName(n
);
421 m
= new BMessage(MSG_PRINTER_SELECTED
);
422 m
->AddString("name", n
.String());
423 menu
->AddItem(item
= new BMenuItem(n
.String(), m
));
424 if (n
== fPrinterName
)
425 item
->SetMarked(true);
432 ConfigWindow::UpdateAppSettings(const char* mime
, const char* printer
)
434 BAutolock
lock(gLock
);
435 if (lock
.IsLocked()) {
436 Settings
* s
= Settings::GetSettings();
437 AppSettings
* app
= s
->FindAppSettings(mime
);
439 app
->SetPrinter(printer
);
441 s
->AddAppSettings(new AppSettings(mime
, printer
));
447 ConfigWindow::UpdateSettings(bool read
)
449 BAutolock
lock(gLock
);
450 if (lock
.IsLocked()) {
451 Settings
* s
= Settings::GetSettings();
452 PrinterSettings
* p
= s
->FindPrinterSettings(fPrinterName
.String());
454 p
= new PrinterSettings(fPrinterName
.String());
455 s
->AddPrinterSettings(p
);
459 fPageSettings
= *p
->GetPageSettings();
460 fJobSettings
= *p
->GetJobSettings();
462 p
->SetPageSettings(&fPageSettings
);
463 p
->SetJobSettings(&fJobSettings
);
471 ConfigWindow::UpdateUI()
473 if (fCurrentPrinter
== NULL
) {
474 fPageSetup
->SetEnabled(false);
476 fJobSetup
->SetEnabled(false);
477 fJobSetupText
->SetText(B_TRANSLATE("Undefined"));
479 fOk
->SetEnabled(false);
480 fPageFormatText
->SetText(B_TRANSLATE("Undefined"));
482 fPageSetup
->SetEnabled(true);
485 fJobSetup
->SetEnabled(fKind
== kJobSetup
486 && !fPageSettings
.IsEmpty());
488 fOk
->SetEnabled((fKind
== kJobSetup
&& !fJobSettings
.IsEmpty())
489 || (fKind
== kPageSetup
&& !fPageSettings
.IsEmpty()));
491 // display information about page format
494 if (fPageSettings
.FindRect(PSRV_FIELD_PAPER_RECT
, &paperRect
) == B_OK
) {
495 GetPageFormat(paperRect
.Width(), paperRect
.Height(), pageFormat
);
497 int32 orientation
= 0;
498 fPageSettings
.FindInt32(PSRV_FIELD_ORIENTATION
, &orientation
);
499 if (orientation
== 0)
500 pageFormat
<< ", " << B_TRANSLATE("Portrait");
502 pageFormat
<< ", " << B_TRANSLATE("Landscape");
504 pageFormat
<< B_TRANSLATE("Undefined");
506 fPageFormatText
->SetText(pageFormat
.String());
508 // display information about job
509 if (fKind
== kJobSetup
) {
511 int32 first
, last
, copies
;
512 if (fJobSettings
.FindInt32(PSRV_FIELD_FIRST_PAGE
, &first
) == B_OK
513 && fJobSettings
.FindInt32(PSRV_FIELD_LAST_PAGE
, &last
) ==
516 bool printRange
= first
>= 1 && first
<= last
&& last
!= INT_MAX
;
518 if (fJobSettings
.FindInt32(PSRV_FIELD_COPIES
, &copies
)
519 == B_OK
&& copies
> 1) {
521 job
= B_TRANSLATE("Page %1 to %2, %3 copies");
522 snprintf(number
, sizeof(number
), "%d", (int)first
);
523 job
.ReplaceFirst("%1", number
);
524 snprintf(number
, sizeof(number
), "%d", (int)last
);
525 job
.ReplaceFirst("%2", number
);
526 snprintf(number
, sizeof(number
), "%d", (int)copies
);
527 job
.ReplaceFirst("%3", number
);
529 job
= B_TRANSLATE("All pages, %1 copies");
530 snprintf(number
, sizeof(number
), "%d", (int)copies
);
531 job
.ReplaceFirst("%1", number
);
535 job
= B_TRANSLATE("Page %1 to %2");
536 snprintf(number
, sizeof(number
), "%d", (int)first
);
537 job
.ReplaceFirst("%1", number
);
538 snprintf(number
, sizeof(number
), "%d", (int)last
);
539 job
.ReplaceFirst("%2", number
);
541 job
= B_TRANSLATE("All pages");
544 job
<< B_TRANSLATE("Undefined");
546 fJobSetupText
->SetText(job
.String());
553 ConfigWindow::Setup(config_setup_kind kind
)
555 if (fCurrentPrinter
) {
557 if (kind
== kPageSetup
) {
558 BMessage settings
= fPageSettings
;
559 if (fCurrentPrinter
->ConfigurePage(settings
) == B_OK
) {
560 fPageSettings
= settings
;
561 if (!fJobSettings
.IsEmpty())
562 AddFields(&fJobSettings
, &fPageSettings
);
566 if (fJobSettings
.IsEmpty()) settings
= fPageSettings
;
567 else settings
= fJobSettings
;
569 if (fCurrentPrinter
->ConfigureJob(settings
) == B_OK
)
570 fJobSettings
= settings
;