1/*
2* Copyright 2010, Haiku. All rights reserved.
3* Distributed under the terms of the MIT License.
4*
5* Authors:
6*		Ithamar R. Adema <ithamar.adema@team-embedded.nl>
7*		Michael Pfeiffer
8*/
9
10
11#include "SelectPrinterDialog.h"
12
13#include <GroupLayout.h>
14#include <GroupLayoutBuilder.h>
15
16#include <Button.h>
17#include <Debug.h>
18#include <Directory.h>
19#include <Entry.h>
20#include <ListView.h>
21#include <Message.h>
22#include <Path.h>
23#include <ScrollBar.h>
24#include <ScrollView.h>
25#include <String.h>
26#include <StringItem.h>
27
28#include "GPBinding.h"
29
30
31enum {
32	kMsgCancel = 'stop',
33	kMsgOK = 'okok',
34
35	kMsgManufacturerSelected = 'msel',
36	kMsgPrinterSelected = 'psel',
37};
38
39
40class StringValueItem : public BStringItem {
41public:
42			StringValueItem(const BString& text, const BString& value)
43				:
44				BStringItem(text.String()),
45				fValue(value)
46				{
47				}
48
49	BString	fValue;
50};
51
52
53SelectPrinterDialog::SelectPrinterDialog(GPData* data)
54	:
55	DialogWindow(BRect(100, 100, 500, 500),
56		"Select Printer", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
57		B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
58			| B_CLOSE_ON_ESCAPE),
59	fData(data)
60{
61	SetResult(B_ERROR);
62
63	BButton* ok;
64	BButton* cancel;
65
66	ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK));
67	ok->MakeDefault(true);
68	ok->SetEnabled(false);
69	fOKButton = ok;
70
71	cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel));
72
73	BScrollView* manuScroller, *printerScroller;
74	fManufacturersListView = new BListView("olv:manufacturers");
75	manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView,
76		0, false, true);
77	fPrintersListView = new BListView("olv:printers");
78	printerScroller = new BScrollView("scr:printers", fPrintersListView, 0,
79		false, true);
80
81	fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected));
82	fManufacturersListView->SetSelectionMessage(
83		new BMessage(kMsgManufacturerSelected));
84	PopulateManufacturers();
85
86	// Build the layout
87	SetLayout(new BGroupLayout(B_VERTICAL));
88
89	AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
90		.AddGroup(B_HORIZONTAL, 5, 1.0f)
91			.Add(manuScroller)
92			.Add(printerScroller)
93		.End()
94		.AddGroup(B_HORIZONTAL, 5, 2.0f)
95			.AddGlue()
96			.Add(cancel)
97			.Add(ok)
98		.End()
99		.SetInsets(10, 10, 10, 10)
100	);
101}
102
103
104void
105SelectPrinterDialog::PopulateManufacturers()
106{
107	BMessage manufacturers;
108	GPBinding binding;
109	binding.GetPrinterManufacturers(manufacturers);
110
111	BString id;
112	BString displayName;
113	for (int32 index = 0; binding.ExtractManufacturer(manufacturers, index, id,
114		displayName); index ++) {
115		fManufacturersListView->AddItem(new StringValueItem(id, displayName));
116	}
117}
118
119
120void
121SelectPrinterDialog::PopulatePrinters()
122{
123	BString manufacturer = GetSelectedItemValue(fManufacturersListView).String();
124	if (manufacturer.Length() == 0)
125		return;
126
127	BMessage models;
128	GPBinding binding;
129	binding.GetPrinterModels(manufacturer, models);
130
131	BString displayName;
132	BString driver;
133	for (int32 index = 0; binding.ExtractModel(models, index, displayName, driver);
134		index ++) {
135		StringValueItem* item = new StringValueItem(displayName, driver);
136		fPrintersListView->AddItem(item);
137	}
138}
139
140
141BString
142SelectPrinterDialog::GetSelectedItemValue(BListView* listView)
143{
144	int32 index = listView->CurrentSelection();
145
146	// Bail out if no manufacturer is selected
147	if (index < 0)
148		return "";
149	BListItem* item = listView->ItemAt(index);
150	StringValueItem* valueItem = dynamic_cast<StringValueItem*>(item);
151	ASSERT(valueItem != NULL);
152
153	return valueItem->fValue;
154}
155
156void
157SelectPrinterDialog::PrinterSelected()
158{
159	int32 index = fPrintersListView->CurrentSelection();
160	fOKButton->SetEnabled(index >= 0);
161}
162
163
164void
165SelectPrinterDialog::Save()
166{
167	BString driverName = GetSelectedItemValue(fPrintersListView);
168	fData->fGutenprintDriverName = driverName;
169	fData->Save();
170}
171
172
173void
174SelectPrinterDialog::MessageReceived(BMessage* msg)
175{
176	switch (msg->what) {
177		case kMsgManufacturerSelected:
178			fPrintersListView->MakeEmpty();
179			PopulatePrinters();
180			PrinterSelected();
181			break;
182		case kMsgPrinterSelected:
183			PrinterSelected();
184			break;
185		case kMsgOK:
186			Save();
187			SetResult(B_NO_ERROR);
188			PostMessage(B_QUIT_REQUESTED);
189			break;
190		case kMsgCancel:
191			PostMessage(B_QUIT_REQUESTED);
192			break;
193		default:
194			DialogWindow::MessageReceived(msg);
195			break;
196	}
197}
198