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