docs/ikteam: Delete most files.
[haiku.git] / src / preferences / printers / AddPrinterDialog.cpp
blob395b692454070bf88fafd843b3660bff238142f8
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 <GroupLayoutBuilder.h>
19 #include <Layout.h>
20 #include <LayoutBuilder.h>
21 #include <Locale.h>
22 #include <MenuField.h>
23 #include <MenuItem.h>
24 #include <MimeType.h>
25 #include <NodeInfo.h>
26 #include <Path.h>
28 #include "pr_server.h"
29 #include "Globals.h"
30 #include "Messages.h"
31 #include "PrinterListView.h"
32 #include "TransportMenu.h"
35 #undef B_TRANSLATION_CONTEXT
36 #define B_TRANSLATION_CONTEXT "AddPrinterDialog"
39 AddPrinterDialog::AddPrinterDialog(BWindow *parent)
41 Inherited(BRect(78, 71, 400, 300), B_TRANSLATE("Add printer"),
42 B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
43 B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
44 fPrintersPrefletMessenger(parent)
46 _BuildGUI(0);
48 Show();
52 bool
53 AddPrinterDialog::QuitRequested()
55 fPrintersPrefletMessenger.SendMessage(kMsgAddPrinterClosed);
56 return Inherited::QuitRequested();
60 void
61 AddPrinterDialog::MessageReceived(BMessage* msg)
63 switch(msg->what) {
64 case B_OK:
65 _AddPrinter(msg);
66 PostMessage(B_QUIT_REQUESTED);
67 break;
69 case B_CANCEL:
70 PostMessage(B_QUIT_REQUESTED);
71 break;
73 case kNameChangedMsg:
74 fNameText = fName->Text();
75 _Update();
76 break;
78 case kPrinterSelectedMsg:
79 _StorePrinter(msg);
80 break;
82 case kTransportSelectedMsg:
83 _HandleChangedTransport(msg);
84 break;
86 default:
87 Inherited::MessageReceived(msg);
92 void
93 AddPrinterDialog::_AddPrinter(BMessage *msg)
95 BMessage m(PSRV_MAKE_PRINTER);
96 BMessenger msgr;
97 if (GetPrinterServerMessenger(msgr) != B_OK)
98 return;
100 BString transport;
101 BString transportPath;
102 if (fPrinterText != "Preview") {
103 // Preview printer does not use transport add-on
104 transport = fTransportText;
105 transportPath = fTransportPathText;
108 m.AddString("driver", fPrinterText.String());
109 m.AddString("transport", transport.String());
110 m.AddString("transport path", transportPath.String());
111 m.AddString("printer name", fNameText.String());
112 m.AddString("connection", "Local");
113 msgr.SendMessage(&m);
114 // request print_server to create printer
118 void
119 AddPrinterDialog::_StorePrinter(BMessage *msg)
121 BString name;
122 if (msg->FindString("name", &name) != B_OK)
123 name = "";
125 fPrinterText = name;
126 _Update();
130 void
131 AddPrinterDialog::_HandleChangedTransport(BMessage *msg)
133 BString name;
134 if (msg->FindString("name", &name) != B_OK) {
135 name = "";
137 fTransportText = name;
139 BString path;
140 if (msg->FindString("path", &path) == B_OK) {
141 // transport path selected
142 fTransportPathText = path;
144 // mark sub menu
145 void* pointer;
146 if (msg->FindPointer("source", &pointer) == B_OK) {
147 BMenuItem* item = (BMenuItem*)pointer;
149 // Update printer name with Transport Path if not filled in
150 if (strlen(fName->Text()) == 0)
151 fName->SetText(item->Label());
153 BMenu* menu = item->Menu();
154 int32 index = fTransport->IndexOf(menu);
155 item = fTransport->ItemAt(index);
156 if (item != NULL)
157 item->SetMarked(true);
159 } else {
160 // transport selected
161 fTransportPathText = "";
163 // remove mark from item in sub menu of transport sub menu
164 for (int32 i = fTransport->CountItems() - 1; i >= 0; i --) {
165 BMenu* menu = fTransport->SubmenuAt(i);
166 if (menu != NULL) {
167 BMenuItem* item = menu->FindMarked();
168 if (item != NULL)
169 item->SetMarked(false);
173 _Update();
177 void
178 AddPrinterDialog::_BuildGUI(int stage)
180 // add a "printer name" input field
181 fName = new BTextControl("printer_name", B_TRANSLATE("Printer name:"),
182 B_EMPTY_STRING, NULL);
183 fName->SetFont(be_bold_font);
184 fName->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
185 fName->SetModificationMessage(new BMessage(kNameChangedMsg));
187 // add a "driver" popup menu field
188 fPrinter = new BPopUpMenu(B_TRANSLATE("<pick one>"));
189 BMenuField *printerMenuField = new BMenuField("drivers_list",
190 B_TRANSLATE("Printer type:"), fPrinter);
191 printerMenuField->SetAlignment(B_ALIGN_RIGHT);
192 _FillMenu(fPrinter, "Print", kPrinterSelectedMsg);
194 // add a "connected to" (aka transports list) menu field
195 fTransport = new BPopUpMenu(B_TRANSLATE("<pick one>"));
196 BMenuField *transportMenuField = new BMenuField("transports_list",
197 B_TRANSLATE("Connected to:"), fTransport);
198 transportMenuField->SetAlignment(B_ALIGN_RIGHT);
199 _FillTransportMenu(fTransport);
201 // add a "OK" button
202 fOk = new BButton(NULL, B_TRANSLATE("Add"), new BMessage((uint32)B_OK),
203 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
205 // add a "Cancel button
206 BButton *cancel = new BButton(NULL, B_TRANSLATE("Cancel"),
207 new BMessage(B_CANCEL));
209 BLayoutBuilder::Grid<>(this, B_USE_ITEM_SPACING, B_USE_ITEM_SPACING)
210 .Add(fName->CreateLabelLayoutItem(), 0, 0)
211 .Add(fName->CreateTextViewLayoutItem(), 1, 0)
212 .Add(printerMenuField->CreateLabelLayoutItem(), 0, 1)
213 .Add(printerMenuField->CreateMenuBarLayoutItem(), 1, 1)
214 .Add(transportMenuField->CreateLabelLayoutItem(), 0, 2)
215 .Add(transportMenuField->CreateMenuBarLayoutItem(), 1, 2)
216 .Add(BGroupLayoutBuilder(B_HORIZONTAL)
217 .AddGlue()
218 .Add(cancel)
219 .Add(fOk)
220 , 0, 3, 2)
221 .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
222 B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING);
224 SetDefaultButton(fOk);
225 fOk->MakeDefault(true);
227 fName->MakeFocus(true);
229 _Update();
230 // Stage == 0
231 // init_icon 64x114 Add a Local or Network Printer
232 // ------------------------------
233 // I would like to add a...
234 // Local Printer
235 // Network Printer
236 // ------------------------------------------------
237 // Cancel Continue
239 // Add local printer:
241 // Stage == 1
242 // local_icon Add a Local Printer
243 // ------------------------------
244 // Printer Name: ________________
245 // Printer Type: pick one
246 // Connected to: pick one
247 // ------------------------------------------------
248 // Cancel Add
250 // This seems to be hard coded into the preferences dialog:
251 // Don't show Network transport add-on in Printer Type menu.
252 // If Printer Type == Preview disable Connect to popup menu.
253 // If Printer Type == Serial Port add a submenu to menu item
254 // with names in /dev/ports (if empty remove item from menu)
255 // If Printer Type == Parallel Port add a submenu to menu item
256 // with names in /dev/parallel (if empty remove item from menu)
258 // Printer Driver Setup
260 // Dialog Info
261 // Would you like to make X the default printer?
262 // No Yes
264 // Add network printer:
266 // Dialog Info
267 // Apple Talk networking isn't currenty enabled. If you
268 // wish to install a network printer you should enable
269 // AppleTalk in the Network preferences.
270 // Cancel Open Network
272 // Stage == 2
274 // network_icon Add a Network Printer
275 // ------------------------------
276 // Printer Name: ________________
277 // Printer Type: pick one
278 // AppleTalk Printer: pick one
279 // ------------------------------------------------
280 // Cancel Add
284 static directory_which gAddonDirs[] = {
285 B_USER_NONPACKAGED_ADDONS_DIRECTORY,
286 B_USER_ADDONS_DIRECTORY,
287 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
288 B_SYSTEM_ADDONS_DIRECTORY,
292 void
293 AddPrinterDialog::_FillMenu(BMenu* menu, const char* path, uint32 what)
295 for (uint32 i = 0; i < sizeof(gAddonDirs) / sizeof(directory_which); i++) {
296 BPath addonPath;
297 if (find_directory(gAddonDirs[i], &addonPath) != B_OK)
298 continue;
300 if (addonPath.Append(path) != B_OK)
301 continue;
303 BDirectory dir(addonPath.Path());
304 if (dir.InitCheck() != B_OK)
305 continue;
307 BEntry entry;
308 while (dir.GetNextEntry(&entry, true) == B_OK) {
309 if (!entry.IsFile())
310 continue;
312 BNode node(&entry);
313 if (node.InitCheck() != B_OK)
314 continue;
316 BNodeInfo info(&node);
317 if (info.InitCheck() != B_OK)
318 continue;
320 char type[B_MIME_TYPE_LENGTH + 1];
321 info.GetType(type);
322 BMimeType entryType(type);
323 // filter non executable entries (like "transport" subfolder...)
324 if (entryType == B_APP_MIME_TYPE) {
325 BPath transportPath;
326 if (entry.GetPath(&transportPath) != B_OK)
327 continue;
329 BMessage* msg = new BMessage(what);
330 msg->AddString("name", transportPath.Leaf());
331 menu->AddItem(new BMenuItem(transportPath.Leaf(), msg));
338 void
339 AddPrinterDialog::_FillTransportMenu(BMenu* menu)
341 BMessenger msgr;
342 if (GetPrinterServerMessenger(msgr) != B_OK)
343 return;
345 for (long idx = 0; ; idx++) {
346 BMessage reply, msg(B_GET_PROPERTY);
347 msg.AddSpecifier("Transport", idx);
348 if (msgr.SendMessage(&msg, &reply) != B_OK)
349 break;
351 BMessenger transport;
352 if (reply.FindMessenger("result", &transport) != B_OK)
353 break;
355 // Got messenger to transport now
356 msg.MakeEmpty();
357 msg.what = B_GET_PROPERTY;
358 msg.AddSpecifier("Name");
359 if (transport.SendMessage(&msg, &reply) != B_OK)
360 continue;
362 BString transportName;
363 if (reply.FindString("result", &transportName) != B_OK)
364 continue;
366 // Now get ports...
367 BString portId, portName;
368 int32 error;
369 msg.MakeEmpty();
370 msg.what = B_GET_PROPERTY;
371 msg.AddSpecifier("Ports");
372 if (transport.SendMessage(&msg, &reply) != B_OK ||
373 reply.FindInt32("error", &error) != B_OK ||
374 error != B_OK) {
375 // Transport does not provide list of ports
376 BMessage* menuMsg = new BMessage(kTransportSelectedMsg);
377 menuMsg->AddString("name", transportName);
378 menu->AddItem(new BMenuItem(transportName.String(), menuMsg));
379 continue;
382 // Create submenu
383 BMenu* transportMenu = new TransportMenu(transportName.String(),
384 kTransportSelectedMsg, transport, transportName);
385 menu->AddItem(transportMenu);
386 transportMenu->SetRadioMode(true);
387 menu->ItemAt(menu->IndexOf(transportMenu))->
388 SetMessage(new BMessage(kTransportSelectedMsg));
393 void
394 AddPrinterDialog::_Update()
396 fOk->SetEnabled(fNameText != "" && fPrinterText != ""
397 && (fTransportText != "" || fPrinterText == "Preview"));
399 fTransport->SetEnabled(fPrinterText != "Preview");