1/*
2 * Copyright 2008-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Julun, <host.haiku@gmx.de>
7 */
8
9#include <JobSetupPanel.h>
10
11#include <Box.h>
12#include <Button.h>
13#include <CheckBox.h>
14#include <GridLayoutBuilder.h>
15#include <GroupLayoutBuilder.h>
16#include <GroupView.h>
17#include <MenuField.h>
18#include <MenuItem.h>
19#include <PopUpMenu.h>
20#include <Printer.h>
21#include <PrinterRoster.h>
22#include <RadioButton.h>
23#include <StringView.h>
24#include <TextControl.h>
25
26
27#include <stdlib.h>
28
29
30namespace BPrivate {
31	namespace Print {
32
33
34BJobSetupPanel::BJobSetupPanel(BPrinter* printer)
35	: BPrintPanel("Print document")
36	, fPrinter(printer)
37	, fPrinterRoster(NULL)
38	, fPrintRange(B_ALL_PAGES)
39	, fJobPanelFlags(B_NO_OPTIONS)
40{
41	_InitObject();
42	_SetupInterface();
43}
44
45
46BJobSetupPanel::BJobSetupPanel(BPrinter* printer, uint32 flags)
47	: BPrintPanel("Print document")
48	, fPrinter(printer)
49	, fPrinterRoster(NULL)
50	, fPrintRange(B_ALL_PAGES)
51	, fJobPanelFlags(flags)
52{
53	_InitObject();
54	_SetupInterface();
55}
56
57
58BJobSetupPanel::~BJobSetupPanel()
59{
60	delete fPrinterRoster;
61}
62
63
64BJobSetupPanel::BJobSetupPanel(BMessage* data)
65	: BPrintPanel(data)
66{
67	// TODO: implement
68}
69
70
71BArchivable*
72BJobSetupPanel::Instantiate(BMessage* data)
73{
74	// TODO: implement
75	return NULL;
76}
77
78
79status_t
80BJobSetupPanel::Archive(BMessage* data, bool deep) const
81{
82	// TODO: implement
83	return B_ERROR;
84}
85
86
87void
88BJobSetupPanel::MessageReceived(BMessage* message)
89{
90
91	BPrintPanel::MessageReceived(message);
92}
93
94
95status_t
96BJobSetupPanel::Go()
97{
98	status_t status = ShowPanel();
99
100	if (status == B_OK) {
101		// TODO: check if we did work on an real printer
102		// TODO: set all selected values on printer object
103	}
104
105	if (Lock())
106		Quit();
107
108	return status;
109}
110
111
112BPrinter*
113BJobSetupPanel::Printer() const
114{
115	return fPrinter;
116}
117
118
119void
120BJobSetupPanel::SetPrinter(BPrinter* printer, bool keepSettings)
121{
122	// TODO: implement
123}
124
125
126print_range
127BJobSetupPanel::PrintRange() const
128{
129	return fPrintRange;
130}
131
132
133void
134BJobSetupPanel::SetPrintRange(print_range range)
135{
136	switch (range) {
137		case B_ALL_PAGES: {
138			fPrintRange = range;
139			fPrintAll->SetValue(B_CONTROL_ON);
140		}	break;
141
142		case B_SELECTION: {
143			fPrintRange = range;
144			SetOptionFlags(OptionFlags() | B_PRINT_SELECTION);
145			fSelection->SetValue(B_CONTROL_ON);
146		}	break;
147
148		case B_PAGE_RANGE: {
149			fPrintRange = range;
150			SetOptionFlags(OptionFlags() | B_PRINT_PAGE_RANGE);
151			fPagesFrom->SetValue(B_CONTROL_ON);
152		}	break;
153	}
154}
155
156
157int32
158BJobSetupPanel::FirstPage() const
159{
160	BString text(fFirstPage->Text());
161	if (text.Length() <= 0)
162		return 0;
163
164	return atoi(text.String());
165}
166
167
168int32
169BJobSetupPanel::LastPage() const
170{
171	BString text(fLastPage->Text());
172	if (text.Length() <= 0)
173		return LONG_MAX;
174
175	return atoi(text.String());
176}
177
178
179void
180BJobSetupPanel::SetPageRange(int32 firstPage, int32 lastPage)
181{
182	BString text;
183	SetPrintRange(B_PAGE_RANGE);
184
185	text << firstPage;
186	fFirstPage->SetText(text.String());
187
188	text << lastPage;
189	fLastPage->SetText(text.String());
190}
191
192
193uint32
194BJobSetupPanel::OptionFlags() const
195{
196	return fJobPanelFlags;
197}
198
199
200void
201BJobSetupPanel::SetOptionFlags(uint32 flags)
202{
203	bool value = false;
204	if (flags & B_PRINT_TO_FILE)
205		value = true;
206	fPrintToFile->SetEnabled(value);
207
208	value = false;
209	if (flags & B_PRINT_PAGE_RANGE)
210		value = true;
211	fPagesFrom->SetEnabled(value);
212	fFirstPage->SetEnabled(value);
213	fLastPage->SetEnabled(value);
214
215	value = false;
216	if (flags & B_PRINT_SELECTION)
217		value = true;
218	fSelection->SetEnabled(value);
219
220	value = false;
221	if (flags & B_PRINT_COLLATE_COPIES)
222		value = true;
223	fCollate->SetEnabled(value);
224
225	fJobPanelFlags = flags;
226}
227
228
229void
230BJobSetupPanel::_InitObject()
231{
232	fPrinterRoster = new BPrinterRoster();
233	fPrinterRoster->StartWatching(this);
234
235	if (!fPrinter->IsValid()) {
236		BPrinter defaultPrinter;
237		fPrinterRoster->GetDefaultPrinter(&defaultPrinter);
238		*fPrinter = defaultPrinter;
239	}
240}
241
242
243void
244BJobSetupPanel::_SetupInterface()
245{
246	BGroupView* groupView = new BGroupView(B_VERTICAL, 10.0);
247
248	// printers
249	fPrinterPopUp = new BPopUpMenu("");
250	fPrinterPopUp->SetRadioMode(true);
251	fPrinterMenuField = new BMenuField("", fPrinterPopUp);
252	fPrinterMenuField->Menu()->SetLabelFromMarked(true);
253
254	BPrinter printer;
255	while (fPrinterRoster->GetNextPrinter(&printer) == B_OK) {
256		BMenuItem* item = new BMenuItem(printer.Name().String(), NULL);
257		fPrinterPopUp->AddItem(item);
258		if (printer == *fPrinter)
259			item->SetMarked(true);
260	}
261
262	if (fPrinterRoster->CountPrinters() > 0)
263		fPrinterPopUp->AddItem(new BSeparatorItem);
264
265	BMenuItem* pdf = new BMenuItem("Save as PDF file" , NULL);
266	fPrinterPopUp->AddItem(pdf);
267	if (fPrinterPopUp->FindMarked() == NULL)
268		pdf->SetMarked(true);
269
270	fProperties = new BButton("Properties" B_UTF8_ELLIPSIS , new BMessage('prop'));
271	fPrinterInfo = new BStringView("label", "");
272	fPrinterInfo->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
273	BBox* divider = new BBox(B_FANCY_BORDER, NULL);
274	divider->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
275	fPrintToFile = new BCheckBox("Print to file");
276
277	BView* view = BGroupLayoutBuilder(B_VERTICAL, 5.0)
278		.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10.0)
279			.Add(fPrinterMenuField->CreateMenuBarLayoutItem())
280			.Add(fProperties))
281		.Add(BGroupLayoutBuilder(B_HORIZONTAL,5.0)
282			.Add(new BStringView("label", "Printer info:"))
283			.Add(fPrinterInfo))
284		.Add(divider)
285		.Add(fPrintToFile)
286		.SetInsets(10.0, 5.0, 10.0, 5.0);
287
288	BBox *box = new BBox(B_FANCY_BORDER, view);
289	box->SetLabel(BGroupLayoutBuilder()
290		.Add(new BStringView("", "Printer"))
291		.SetInsets(2.0, 0.0, 2.0, 0.0));
292	groupView->AddChild(box);
293
294	// page range
295	fPrintAll = new BRadioButton("Print all", new BMessage('prrg'));
296	fPrintAll->SetValue(B_CONTROL_ON);
297	fPagesFrom = new BRadioButton("Pages from:", new BMessage('prrg'));
298	fFirstPage = new BTextControl("", "", NULL);
299	_DisallowChar(fFirstPage->TextView());
300	fLastPage = new BTextControl("to:", "", NULL);
301	_DisallowChar(fLastPage->TextView());
302	fSelection = new BRadioButton("Print selection", new BMessage('prrg'));
303
304	fFirstPage->CreateLabelLayoutItem();
305	view = BGroupLayoutBuilder(B_VERTICAL, 5.0)
306		.Add(fPrintAll)
307		.Add(BGroupLayoutBuilder(B_HORIZONTAL, 5.0)
308			.Add(fPagesFrom)
309			.Add(fFirstPage->CreateTextViewLayoutItem())
310			.Add(fLastPage->CreateLabelLayoutItem())
311			.Add(fLastPage->CreateTextViewLayoutItem()))
312		.Add(fSelection)
313		.SetInsets(10.0, 5.0, 10.0, 5.0);
314
315	box = new BBox(B_FANCY_BORDER, view);
316	box->SetLabel(BGroupLayoutBuilder()
317		.Add(new BStringView("", "Page range"))
318		.SetInsets(2.0, 0.0, 2.0, 0.0));
319
320	// copies
321	fNumberOfCopies = new BTextControl("Number of copies:", "1", NULL);
322	_DisallowChar(fNumberOfCopies->TextView());
323	fCollate = new BCheckBox("Collate");
324	fReverse = new BCheckBox("Reverse");
325
326	BView* view2 = BGroupLayoutBuilder(B_VERTICAL, 5.0)
327		.Add(BGroupLayoutBuilder(B_HORIZONTAL, 5.0)
328			.Add(fNumberOfCopies->CreateLabelLayoutItem())
329			.Add(fNumberOfCopies->CreateTextViewLayoutItem()))
330		.Add(fCollate)
331		.Add(fReverse)
332		.SetInsets(10.0, 5.0, 10.0, 5.0);
333
334	BBox* box2 = new BBox(B_FANCY_BORDER, view2);
335	box2->SetLabel(BGroupLayoutBuilder()
336		.Add(new BStringView("", "Copies"))
337		.SetInsets(2.0, 0.0, 2.0, 0.0));
338
339	groupView->AddChild(BGroupLayoutBuilder(B_HORIZONTAL, 10.0)
340		.Add(box)
341		.Add(box2));
342
343	// other
344	fColor = new BCheckBox("Print in color");
345	fDuplex = new BCheckBox("Double side printing");
346
347	view = BGroupLayoutBuilder(B_VERTICAL, 5.0)
348		.Add(fColor)
349		.Add(fDuplex)
350		.SetInsets(10.0, 5.0, 10.0, 5.0);
351
352	box = new BBox(B_FANCY_BORDER, view);
353	box->SetLabel(BGroupLayoutBuilder()
354		.Add(new BStringView("", "Other"))
355		.SetInsets(2.0, 0.0, 2.0, 0.0));
356	groupView->AddChild(box);
357
358	AddPanel(groupView);
359	SetOptionFlags(fJobPanelFlags);
360}
361
362
363void
364BJobSetupPanel::_DisallowChar(BTextView* textView)
365{
366	for (uint32 i = 0; i < '0'; ++i)
367		textView->DisallowChar(i);
368
369	for (uint32 i = '9' + 1; i < 255; ++i)
370		textView->DisallowChar(i);
371}
372
373
374	}	// namespace Print
375}	// namespace BPrivate
376