Assorted whitespace cleanup and typo fixes.
[haiku.git] / src / preferences / printers / AddPrinterDialog.cpp
blobcf4c74a821d00d7ec3754f4d07784fa427f6d7de
1 /*
2 * Copyright 2002-2009, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Michael Pfeiffer
7 * Philippe Houdoin
8 */
11 #include "AddPrinterDialog.h"
13 #include <stdio.h>
15 #include <Button.h>
16 #include <Catalog.h>
17 #include <FindDirectory.h>
18 #include <GridLayout.h>
19 #include <GridLayoutBuilder.h>
20 #include <GroupLayoutBuilder.h>
21 #include <Layout.h>
22 #include <Locale.h>
23 #include <MenuField.h>
24 #include <MenuItem.h>
25 #include <MimeType.h>
26 #include <NodeInfo.h>
27 #include <Path.h>
29 #include "pr_server.h"
30 #include "Globals.h"
31 #include "Messages.h"
32 #include "PrinterListView.h"
33 #include "TransportMenu.h"
36 #undef B_TRANSLATION_CONTEXT
37 #define B_TRANSLATION_CONTEXT "AddPrinterDialog"
40 AddPrinterDialog::AddPrinterDialog(BWindow *parent)
42 Inherited(BRect(78, 71, 400, 300), B_TRANSLATE("Add printer"),
43 B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
44 B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
45 fPrintersPrefletMessenger(parent)
47 _BuildGUI(0);
49 Show();
53 bool
54 AddPrinterDialog::QuitRequested()
56 fPrintersPrefletMessenger.SendMessage(kMsgAddPrinterClosed);
57 return Inherited::QuitRequested();
61 void
62 AddPrinterDialog::MessageReceived(BMessage* msg)
64 switch(msg->what) {
65 case B_OK:
66 _AddPrinter(msg);
67 PostMessage(B_QUIT_REQUESTED);
68 break;
70 case B_CANCEL:
71 PostMessage(B_QUIT_REQUESTED);
72 break;
74 case kNameChangedMsg:
75 fNameText = fName->Text();
76 _Update();
77 break;
79 case kPrinterSelectedMsg:
80 _StorePrinter(msg);
81 break;
83 case kTransportSelectedMsg:
84 _HandleChangedTransport(msg);
85 break;
87 default:
88 Inherited::MessageReceived(msg);
93 void
94 AddPrinterDialog::_AddPrinter(BMessage *msg)
96 BMessage m(PSRV_MAKE_PRINTER);
97 BMessenger msgr;
98 if (GetPrinterServerMessenger(msgr) != B_OK)
99 return;
101 BString transport;
102 BString transportPath;
103 if (fPrinterText != "Preview") {
104 // Preview printer does not use transport add-on
105 transport = fTransportText;
106 transportPath = fTransportPathText;
109 m.AddString("driver", fPrinterText.String());
110 m.AddString("transport", transport.String());
111 m.AddString("transport path", transportPath.String());
112 m.AddString("printer name", fNameText.String());
113 m.AddString("connection", "Local");
114 msgr.SendMessage(&m);
115 // request print_server to create printer
119 void
120 AddPrinterDialog::_StorePrinter(BMessage *msg)
122 BString name;
123 if (msg->FindString("name", &name) != B_OK)
124 name = "";
126 fPrinterText = name;
127 _Update();
131 void
132 AddPrinterDialog::_HandleChangedTransport(BMessage *msg)
134 BString name;
135 if (msg->FindString("name", &name) != B_OK) {
136 name = "";
138 fTransportText = name;
140 BString path;
141 if (msg->FindString("path", &path) == B_OK) {
142 // transport path selected
143 fTransportPathText = path;
145 // mark sub menu
146 void* pointer;
147 if (msg->FindPointer("source", &pointer) == B_OK) {
148 BMenuItem* item = (BMenuItem*)pointer;
150 // Update printer name with Transport Path if not filled in
151 if (strlen(fName->Text()) == 0)
152 fName->SetText(item->Label());
154 BMenu* menu = item->Menu();
155 int32 index = fTransport->IndexOf(menu);
156 item = fTransport->ItemAt(index);
157 if (item != NULL)
158 item->SetMarked(true);
160 } else {
161 // transport selected
162 fTransportPathText = "";
164 // remove mark from item in sub menu of transport sub menu
165 for (int32 i = fTransport->CountItems() - 1; i >= 0; i --) {
166 BMenu* menu = fTransport->SubmenuAt(i);
167 if (menu != NULL) {
168 BMenuItem* item = menu->FindMarked();
169 if (item != NULL)
170 item->SetMarked(false);
174 _Update();
178 void
179 AddPrinterDialog::_BuildGUI(int stage)
181 // add a "printer name" input field
182 fName = new BTextControl("printer_name", B_TRANSLATE("Printer name:"),
183 B_EMPTY_STRING, NULL);
184 fName->SetFont(be_bold_font);
185 fName->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
186 fName->SetModificationMessage(new BMessage(kNameChangedMsg));
188 // add a "driver" popup menu field
189 fPrinter = new BPopUpMenu(B_TRANSLATE("<pick one>"));
190 BMenuField *printerMenuField = new BMenuField("drivers_list",
191 B_TRANSLATE("Printer type:"), fPrinter);
192 printerMenuField->SetAlignment(B_ALIGN_RIGHT);
193 _FillMenu(fPrinter, "Print", kPrinterSelectedMsg);
195 // add a "connected to" (aka transports list) menu field
196 fTransport = new BPopUpMenu(B_TRANSLATE("<pick one>"));
197 BMenuField *transportMenuField = new BMenuField("transports_list",
198 B_TRANSLATE("Connected to:"), fTransport);
199 transportMenuField->SetAlignment(B_ALIGN_RIGHT);
200 _FillTransportMenu(fTransport);
202 // add a "OK" button
203 fOk = new BButton(NULL, B_TRANSLATE("Add"), new BMessage((uint32)B_OK),
204 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
206 // add a "Cancel button
207 BButton *cancel = new BButton(NULL, B_TRANSLATE("Cancel"),
208 new BMessage(B_CANCEL));
210 SetLayout(new BGridLayout());
212 AddChild(BGridLayoutBuilder(0, 4)
213 .Add(fName->CreateLabelLayoutItem(), 0, 0)
214 .Add(fName->CreateTextViewLayoutItem(), 1, 0)
215 .Add(printerMenuField->CreateLabelLayoutItem(), 0, 1)
216 .Add(printerMenuField->CreateMenuBarLayoutItem(), 1, 1)
217 .Add(transportMenuField->CreateLabelLayoutItem(), 0, 2)
218 .Add(transportMenuField->CreateMenuBarLayoutItem(), 1, 2)
219 .Add(BGroupLayoutBuilder(B_HORIZONTAL)
220 .AddGlue()
221 .Add(cancel)
222 .Add(fOk)
223 , 0, 3, 2)
224 .SetInsets(8, 8, 8, 8)
227 SetDefaultButton(fOk);
228 fOk->MakeDefault(true);
230 fName->MakeFocus(true);
232 _Update();
233 // Stage == 0
234 // init_icon 64x114 Add a Local or Network Printer
235 // ------------------------------
236 // I would like to add a...
237 // Local Printer
238 // Network Printer
239 // ------------------------------------------------
240 // Cancel Continue
242 // Add local printer:
244 // Stage == 1
245 // local_icon Add a Local Printer
246 // ------------------------------
247 // Printer Name: ________________
248 // Printer Type: pick one
249 // Connected to: pick one
250 // ------------------------------------------------
251 // Cancel Add
253 // This seems to be hard coded into the preferences dialog:
254 // Don't show Network transport add-on in Printer Type menu.
255 // If Printer Type == Preview disable Connect to popup menu.
256 // If Printer Type == Serial Port add a submenu to menu item
257 // with names in /dev/ports (if empty remove item from menu)
258 // If Printer Type == Parallel Port add a submenu to menu item
259 // with names in /dev/parallel (if empty remove item from menu)
261 // Printer Driver Setup
263 // Dialog Info
264 // Would you like to make X the default printer?
265 // No Yes
267 // Add network printer:
269 // Dialog Info
270 // Apple Talk networking isn't currenty enabled. If you
271 // wish to install a network printer you should enable
272 // AppleTalk in the Network preferences.
273 // Cancel Open Network
275 // Stage == 2
277 // network_icon Add a Network Printer
278 // ------------------------------
279 // Printer Name: ________________
280 // Printer Type: pick one
281 // AppleTalk Printer: pick one
282 // ------------------------------------------------
283 // Cancel Add
287 static directory_which gAddonDirs[] = {
288 B_USER_NONPACKAGED_ADDONS_DIRECTORY,
289 B_USER_ADDONS_DIRECTORY,
290 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
291 B_SYSTEM_ADDONS_DIRECTORY,
295 void
296 AddPrinterDialog::_FillMenu(BMenu* menu, const char* path, uint32 what)
298 for (uint32 i = 0; i < sizeof(gAddonDirs) / sizeof(directory_which); i++) {
299 BPath addonPath;
300 if (find_directory(gAddonDirs[i], &addonPath) != B_OK)
301 continue;
303 if (addonPath.Append(path) != B_OK)
304 continue;
306 BDirectory dir(addonPath.Path());
307 if (dir.InitCheck() != B_OK)
308 continue;
310 BEntry entry;
311 while (dir.GetNextEntry(&entry, true) == B_OK) {
312 if (!entry.IsFile())
313 continue;
315 BNode node(&entry);
316 if (node.InitCheck() != B_OK)
317 continue;
319 BNodeInfo info(&node);
320 if (info.InitCheck() != B_OK)
321 continue;
323 char type[B_MIME_TYPE_LENGTH + 1];
324 info.GetType(type);
325 BMimeType entryType(type);
326 // filter non executable entries (like "transport" subfolder...)
327 if (entryType == B_APP_MIME_TYPE) {
328 BPath transportPath;
329 if (entry.GetPath(&transportPath) != B_OK)
330 continue;
332 BMessage* msg = new BMessage(what);
333 msg->AddString("name", transportPath.Leaf());
334 menu->AddItem(new BMenuItem(transportPath.Leaf(), msg));
341 void
342 AddPrinterDialog::_FillTransportMenu(BMenu* menu)
344 BMessenger msgr;
345 if (GetPrinterServerMessenger(msgr) != B_OK)
346 return;
348 for (long idx = 0; ; idx++) {
349 BMessage reply, msg(B_GET_PROPERTY);
350 msg.AddSpecifier("Transport", idx);
351 if (msgr.SendMessage(&msg, &reply) != B_OK)
352 break;
354 BMessenger transport;
355 if (reply.FindMessenger("result", &transport) != B_OK)
356 break;
358 // Got messenger to transport now
359 msg.MakeEmpty();
360 msg.what = B_GET_PROPERTY;
361 msg.AddSpecifier("Name");
362 if (transport.SendMessage(&msg, &reply) != B_OK)
363 continue;
365 BString transportName;
366 if (reply.FindString("result", &transportName) != B_OK)
367 continue;
369 // Now get ports...
370 BString portId, portName;
371 int32 error;
372 msg.MakeEmpty();
373 msg.what = B_GET_PROPERTY;
374 msg.AddSpecifier("Ports");
375 if (transport.SendMessage(&msg, &reply) != B_OK ||
376 reply.FindInt32("error", &error) != B_OK ||
377 error != B_OK) {
378 // Transport does not provide list of ports
379 BMessage* menuMsg = new BMessage(kTransportSelectedMsg);
380 menuMsg->AddString("name", transportName);
381 menu->AddItem(new BMenuItem(transportName.String(), menuMsg));
382 continue;
385 // Create submenu
386 BMenu* transportMenu = new TransportMenu(transportName.String(),
387 kTransportSelectedMsg, transport, transportName);
388 menu->AddItem(transportMenu);
389 transportMenu->SetRadioMode(true);
390 menu->ItemAt(menu->IndexOf(transportMenu))->
391 SetMessage(new BMessage(kTransportSelectedMsg));
396 void
397 AddPrinterDialog::_Update()
399 fOk->SetEnabled(fNameText != "" && fPrinterText != ""
400 && (fTransportText != "" || fPrinterText == "Preview"));
402 fTransport->SetEnabled(fPrinterText != "Preview");