xref: /haiku/src/add-ons/print/drivers/postscript/SelectPPDDlg.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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 */
8 
9 
10 #include "SelectPPDDlg.h"
11 
12 #include <GroupLayout.h>
13 #include <GroupLayoutBuilder.h>
14 
15 #include <Button.h>
16 #include <Directory.h>
17 #include <Entry.h>
18 #include <ListView.h>
19 #include <Message.h>
20 #include <Path.h>
21 #include <ScrollBar.h>
22 #include <ScrollView.h>
23 #include <String.h>
24 #include <StringItem.h>
25 
26 #include "PPDParser.h"
27 
28 enum {
29 	kMsgCancel = 'stop',
30 	kMsgOK = 'okok',
31 
32 	kMsgManuSelected = 'msel',
33 	kMsgPrinterSelected = 'psel',
34 };
35 
36 
37 class PPDStringItem : public BStringItem {
38 public:
39 			PPDStringItem(const BString& text, const BString& path)
40 			:
41 			BStringItem(text.String()),
42 			fPPDPath(path)
43 			{
44 			}
45 
46 	BString	fPPDPath;
47 };
48 
49 
50 SelectPPDDlg::SelectPPDDlg(PSData* data)
51 	: DialogWindow(BRect(10, 10, 400, 400),
52 		"Select PPD", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
53 		B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
54 			| B_CLOSE_ON_ESCAPE),
55 		fPSData(data)
56 {
57 	SetResult(B_ERROR);
58 
59 	BButton* ok;
60 	BButton* cancel;
61 
62 	ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK));
63 	ok->MakeDefault(true);
64 	ok->SetEnabled(false);
65 	fOKButton = ok;
66 
67 	cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel));
68 
69 	BScrollView* manuScroller, *printerScroller;
70 	fManufacturersListView = new BListView("olv:manufacturers");
71 	manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView,
72 		0, false, true);
73 	fPrintersListView = new BListView("olv:printers");
74 	printerScroller = new BScrollView("scr:printers", fPrintersListView, 0,
75 		false, true);
76 
77 	fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected));
78 	fManufacturersListView->SetSelectionMessage(new BMessage(kMsgManuSelected));
79 	PopulateManufacturers(B_SYSTEM_DATA_DIRECTORY);
80 
81 	// Build the layout
82 	SetLayout(new BGroupLayout(B_VERTICAL));
83 
84 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
85 		.AddGroup(B_HORIZONTAL, 5)
86 			.Add(manuScroller)
87 			.Add(printerScroller)
88 		.End()
89 		.AddGroup(B_HORIZONTAL, 5)
90 			.AddGlue()
91 			.Add(cancel)
92 			.Add(ok)
93 		.End()
94 		.SetInsets(10, 10, 10, 10)
95 	);
96 }
97 
98 
99 void
100 SelectPPDDlg::PopulateManufacturers(directory_which data_dir)
101 {
102 	char name[1024];
103 	BDirectory dir;
104 	BEntry entry;
105 	BPath path;
106 
107 	if (find_directory(data_dir, &path) == B_OK
108 		&& path.Append("ppd") == B_OK
109 		&& dir.SetTo(path.Path()) == B_OK) {
110 		// Got the directory, now scan it
111 		while (dir.GetNextEntry(&entry) == B_OK)
112 			if (entry.IsDirectory()
113 				&& entry.GetName(name) == B_OK)
114 				fManufacturersListView->AddItem(new BStringItem(name));
115 	}
116 }
117 
118 
119 void
120 SelectPPDDlg::PopulatePrinters(directory_which data_dir)
121 {
122 	int32 idx = fManufacturersListView->CurrentSelection();
123 	char name[1024];
124 	BDirectory dir;
125 	BString manu;
126 	BEntry entry;
127 	BPath path;
128 
129 	// Bail out if no manufacturer is selected
130 	if (idx < 0)
131 		return;
132 
133 	manu = ((BStringItem*)fManufacturersListView->ItemAt(idx))->Text();
134 
135 	if (find_directory(data_dir, &path) == B_OK
136 		&& path.Append("ppd") == B_OK
137 		&& path.Append(manu) == B_OK
138 		&& dir.SetTo(path.Path()) == B_OK) {
139 		// Found manufacturer PPD directory, now fill our printer list
140 		while (dir.GetNextEntry(&entry) == B_OK)
141 			if (entry.GetName(name) == B_OK) {
142 				PPDParser parser(dir, name);
143 				if (parser.InitCheck() == B_OK) {
144 					BString modelName = parser.GetParameter("ModelName");
145 					BPath ppdPath = path;
146 					ppdPath.Append(name);
147 					fPrintersListView->AddItem(new PPDStringItem(modelName,
148 						ppdPath.Path()));
149 				}
150 			}
151 	}
152 }
153 
154 
155 void
156 SelectPPDDlg::PrinterSelected()
157 {
158 	int32 idx = fPrintersListView->CurrentSelection();
159 	fOKButton->SetEnabled(idx >= 0);
160 }
161 
162 
163 void
164 SelectPPDDlg::Save()
165 {
166 	BString ppdPath;
167 	int32 idx;
168 
169 	idx = fPrintersListView->CurrentSelection();
170 	if (idx >= 0)
171 		ppdPath = dynamic_cast<PPDStringItem*>
172 			(fPrintersListView->ItemAt(idx))->fPPDPath;
173 
174 	fPSData->fPPD = ppdPath;
175 	fPSData->Save();
176 }
177 
178 
179 void
180 SelectPPDDlg::MessageReceived(BMessage* msg)
181 {
182 	switch (msg->what) {
183 		case kMsgManuSelected:
184 			fPrintersListView->MakeEmpty();
185 			PopulatePrinters(B_SYSTEM_DATA_DIRECTORY);
186 			break;
187 		case kMsgPrinterSelected:
188 			PrinterSelected();
189 			break;
190 		case kMsgOK:
191 			Save();
192 			SetResult(B_NO_ERROR);
193 			PostMessage(B_QUIT_REQUESTED);
194 			break;
195 		case kMsgCancel:
196 			PostMessage(B_QUIT_REQUESTED);
197 			break;
198 		default:
199 			DialogWindow::MessageReceived(msg);
200 			break;
201 	}
202 }
203