xref: /haiku/src/add-ons/print/drivers/postscript/SelectPPDDlg.cpp (revision e0ef64750f3169cd634bb2f7a001e22488b05231)
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 		fPSData(data)
55 {
56 	SetResult(B_ERROR);
57 
58 	BButton* ok;
59 	BButton* cancel;
60 
61 	ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK));
62 	ok->MakeDefault(true);
63 	ok->SetEnabled(false);
64 	fOKButton = ok;
65 
66 	cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel));
67 
68 	BScrollView* manuScroller, *printerScroller;
69 	fManufacturersListView = new BListView("olv:manufacturers");
70 	manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView,
71 		0, false, true);
72 	fPrintersListView = new BListView("olv:printers");
73 	printerScroller = new BScrollView("scr:printers", fPrintersListView, 0,
74 		false, true);
75 
76 	fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected));
77 	fManufacturersListView->SetSelectionMessage(new BMessage(kMsgManuSelected));
78 	PopulateManufacturers(B_SYSTEM_DATA_DIRECTORY);
79 
80 	// Build the layout
81 	SetLayout(new BGroupLayout(B_VERTICAL));
82 
83 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
84 		.AddGroup(B_HORIZONTAL, 5)
85 			.Add(manuScroller)
86 			.Add(printerScroller)
87 		.End()
88 		.AddGroup(B_HORIZONTAL, 5)
89 			.AddGlue()
90 			.Add(cancel)
91 			.Add(ok)
92 		.End()
93 		.SetInsets(10, 10, 10, 10)
94 	);
95 }
96 
97 
98 void
99 SelectPPDDlg::PopulateManufacturers(directory_which data_dir)
100 {
101 	char name[1024];
102 	BDirectory dir;
103 	BEntry entry;
104 	BPath path;
105 
106 	if (find_directory(data_dir, &path) == B_OK
107 		&& path.Append("ppd") == B_OK
108 		&& dir.SetTo(path.Path()) == B_OK) {
109 		// Got the directory, now scan it
110 		while (dir.GetNextEntry(&entry) == B_OK)
111 			if (entry.IsDirectory()
112 				&& entry.GetName(name) == B_OK)
113 				fManufacturersListView->AddItem(new BStringItem(name));
114 	}
115 }
116 
117 
118 void
119 SelectPPDDlg::PopulatePrinters(directory_which data_dir)
120 {
121 	int32 idx = fManufacturersListView->CurrentSelection();
122 	char name[1024];
123 	BDirectory dir;
124 	BString manu;
125 	BEntry entry;
126 	BPath path;
127 
128 	// Bail out if no manufacturer is selected
129 	if (idx < 0)
130 		return;
131 
132 	manu = ((BStringItem*)fManufacturersListView->ItemAt(idx))->Text();
133 
134 	if (find_directory(data_dir, &path) == B_OK
135 		&& path.Append("ppd") == B_OK
136 		&& path.Append(manu) == B_OK
137 		&& dir.SetTo(path.Path()) == B_OK) {
138 		// Found manufacturer PPD directory, now fill our printer list
139 		while (dir.GetNextEntry(&entry) == B_OK)
140 			if (entry.GetName(name) == B_OK) {
141 				PPDParser parser(dir, name);
142 				if (parser.InitCheck() == B_OK) {
143 					BString modelName = parser.GetParameter("ModelName");
144 					BPath ppdPath = path;
145 					ppdPath.Append(name);
146 					fPrintersListView->AddItem(new PPDStringItem(modelName,
147 						ppdPath.Path()));
148 				}
149 			}
150 	}
151 }
152 
153 
154 void
155 SelectPPDDlg::PrinterSelected()
156 {
157 	int32 idx = fPrintersListView->CurrentSelection();
158 	fOKButton->SetEnabled(idx >= 0);
159 }
160 
161 
162 void
163 SelectPPDDlg::Save()
164 {
165 	BString ppdPath;
166 	int32 idx;
167 
168 	idx = fPrintersListView->CurrentSelection();
169 	if (idx >= 0)
170 		ppdPath = dynamic_cast<PPDStringItem*>
171 			(fPrintersListView->ItemAt(idx))->fPPDPath;
172 
173 	fPSData->fPPD = ppdPath;
174 	fPSData->save();
175 }
176 
177 
178 void
179 SelectPPDDlg::MessageReceived(BMessage* msg)
180 {
181 	switch (msg->what) {
182 		case kMsgManuSelected:
183 			fPrintersListView->MakeEmpty();
184 			PopulatePrinters(B_SYSTEM_DATA_DIRECTORY);
185 			break;
186 		case kMsgPrinterSelected:
187 			PrinterSelected();
188 			break;
189 		case kMsgOK:
190 			Save();
191 			SetResult(B_NO_ERROR);
192 			PostMessage(B_QUIT_REQUESTED);
193 			break;
194 		case kMsgCancel:
195 			PostMessage(B_QUIT_REQUESTED);
196 			break;
197 		default:
198 			DialogWindow::MessageReceived(msg);
199 			break;
200 	}
201 }
202