1139734Simp/*
2139734Simp * Copyright 2002-2009, Haiku.
317773Swosch * Distributed under the terms of the MIT License.
417773Swosch *
517773Swosch * Authors:
617773Swosch *		Michael Pfeiffer
717773Swosch *		Philippe Houdoin
817773Swosch */
917773Swosch
1017773Swosch
1117773Swosch#include "AddPrinterDialog.h"
1217773Swosch
1317773Swosch#include <stdio.h>
1417773Swosch
1517773Swosch#include <Button.h>
1617773Swosch#include <Catalog.h>
1717773Swosch#include <FindDirectory.h>
1817773Swosch#include <GridLayout.h>
1917773Swosch#include <GridLayoutBuilder.h>
2017773Swosch#include <GroupLayoutBuilder.h>
2117773Swosch#include <Layout.h>
2217773Swosch#include <Locale.h>
2317773Swosch#include <MenuField.h>
2417773Swosch#include <MenuItem.h>
2517773Swosch#include <MimeType.h>
26146319Sru#include <NodeInfo.h>
27141580Sru#include <Path.h>
28141580Sru
29291754Sngie#include "pr_server.h"
3012823Sphk#include "Globals.h"
3179538Sru#include "Messages.h"
3212823Sphk#include "PrinterListView.h"
3314003Smpp#include "TransportMenu.h"
3475670Sru
3512823Sphk
3626192Speter#undef B_TRANSLATION_CONTEXT
3768716Sru#define B_TRANSLATION_CONTEXT "AddPrinterDialog"
3887529Sru
3987774Simp
4087773SimpAddPrinterDialog::AddPrinterDialog(BWindow *parent)
4187773Simp	:
4287858Sru	Inherited(BRect(78, 71, 400, 300), B_TRANSLATE("Add printer"),
4387773Simp		B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
4471895Sru		B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
4512823Sphk	fPrintersPrefletMessenger(parent)
4675820Sobrien{
4775820Sobrien	_BuildGUI(0);
4875820Sobrien
4975820Sobrien	Show();
5012823Sphk}
5112823Sphk
5212823Sphk
5312823Sphkbool
5412823SphkAddPrinterDialog::QuitRequested()
5512823Sphk{
5612823Sphk	fPrintersPrefletMessenger.SendMessage(kMsgAddPrinterClosed);
5712823Sphk	return Inherited::QuitRequested();
5812823Sphk}
5912951Sphk
6012951Sphk
6112823Sphkvoid
6214966SjoergAddPrinterDialog::MessageReceived(BMessage* msg)
6314966Sjoerg{
64139947Skeramida	switch(msg->what) {
65139725Simp		case B_OK:
66139725Simp			_AddPrinter(msg);
67139725Simp			PostMessage(B_QUIT_REQUESTED);
68166323Sjoel			break;
69166323Sjoel
70139725Simp		case B_CANCEL:
71175108Sgrog			PostMessage(B_QUIT_REQUESTED);
72139725Simp			break;
73139725Simp
74139947Skeramida		case kNameChangedMsg:
75139734Simp			fNameText = fName->Text();
76139734Simp			_Update();
77139734Simp			break;
78139734Simp
79140173Sru		case kPrinterSelectedMsg:
80139734Simp			_StorePrinter(msg);
81139734Simp			break;
82139734Simp
83146307Skeramida		case kTransportSelectedMsg:
84139734Simp			_HandleChangedTransport(msg);
85139725Simp			break;
8675820Sobrien
87146319Sru		default:
88146323Sobrien			Inherited::MessageReceived(msg);
8975820Sobrien	}
9090018Sbde}
9183041Sgrog
9283041Sgrog
9390018Sbdevoid
9483041SgrogAddPrinterDialog::_AddPrinter(BMessage *msg)
9576708Sobrien{
9690042Sobrien	BMessage m(PSRV_MAKE_PRINTER);
9792569Sru	BMessenger msgr;
9892569Sru	if (GetPrinterServerMessenger(msgr) != B_OK)
9990018Sbde		return;
10090018Sbde
10190018Sbde	BString transport;
10290018Sbde	BString transportPath;
10390018Sbde	if (fPrinterText != "Preview") {
10490018Sbde		// Preview printer does not use transport add-on
10590018Sbde		transport = fTransportText;
10675820Sobrien		transportPath = fTransportPathText;
10790018Sbde	}
10890018Sbde
10990018Sbde	m.AddString("driver", fPrinterText.String());
110112629Sjhb	m.AddString("transport", transport.String());
11190018Sbde	m.AddString("transport path", transportPath.String());
112131132Sbde	m.AddString("printer name", fNameText.String());
11383517Sobrien	m.AddString("connection", "Local");
11484307Sru	msgr.SendMessage(&m);
11575820Sobrien		// request print_server to create printer
11675820Sobrien}
11783041Sgrog
11875820Sobrien
11987529Sruvoid
12087529SruAddPrinterDialog::_StorePrinter(BMessage *msg)
12187529Sru{
122119893Sru	BString name;
12387529Sru	if (msg->FindString("name", &name) != B_OK)
124119893Sru		name = "";
12587529Sru
126119893Sru	fPrinterText = name;
12787529Sru	_Update();
128119893Sru}
12987529Sru
13071895Sru
13163324Sbenvoid
13214966SjoergAddPrinterDialog::_HandleChangedTransport(BMessage *msg)
13314966Sjoerg{
13483041Sgrog	BString name;
13571895Sru	if (msg->FindString("name", &name) != B_OK) {
13612823Sphk		name = "";
13712823Sphk	}
13812823Sphk	fTransportText = name;
13912823Sphk
14012823Sphk	BString path;
14114966Sjoerg	if (msg->FindString("path", &path) == B_OK) {
14214966Sjoerg		// transport path selected
14387773Simp		fTransportPathText = path;
14487773Simp
14587773Simp		// mark sub menu
14687773Simp		void* pointer;
14787529Sru		if (msg->FindPointer("source", &pointer) == B_OK) {
148130582Sru			BMenuItem* item = (BMenuItem*)pointer;
149120530Simp
15083041Sgrog			// Update printer name with Transport Path if not filled in
15171895Sru			if (strlen(fName->Text()) == 0)
15212823Sphk				fName->SetText(item->Label());
15314966Sjoerg
15414966Sjoerg			BMenu* menu = item->Menu();
15587529Sru			int32 index = fTransport->IndexOf(menu);
156119893Sru			item = fTransport->ItemAt(index);
15787529Sru			if (item != NULL)
15887529Sru				item->SetMarked(true);
15987529Sru		}
16087529Sru	} else {
16171895Sru		// transport selected
16212823Sphk		fTransportPathText = "";
16314966Sjoerg
16414966Sjoerg		// remove mark from item in sub menu of transport sub menu
16583041Sgrog		for (int32 i = fTransport->CountItems() - 1; i >= 0; i --) {
16671895Sru			BMenu* menu = fTransport->SubmenuAt(i);
16712951Sphk			if (menu != NULL) {
16814966Sjoerg				BMenuItem* item = menu->FindMarked();
16914966Sjoerg				if (item != NULL)
17087529Sru					item->SetMarked(false);
17187529Sru			}
17287529Sru		}
17364395Ssheldonh	}
17464395Ssheldonh	_Update();
17564395Ssheldonh}
17686725Sru
17764395Ssheldonh
17864395Ssheldonhvoid
17964395SsheldonhAddPrinterDialog::_BuildGUI(int stage)
18064395Ssheldonh{
18179727Sschweikh	// add a "printer name" input field
18287529Sru	fName = new BTextControl("printer_name", B_TRANSLATE("Printer name:"),
18379727Sschweikh		B_EMPTY_STRING, NULL);
18464395Ssheldonh	fName->SetFont(be_bold_font);
18564395Ssheldonh	fName->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
18664395Ssheldonh	fName->SetModificationMessage(new BMessage(kNameChangedMsg));
18764395Ssheldonh
18864395Ssheldonh	// add a "driver" popup menu field
18964395Ssheldonh	fPrinter = new BPopUpMenu(B_TRANSLATE("<pick one>"));
19063427Sben	BMenuField *printerMenuField = new BMenuField("drivers_list",
19149363Shoek		B_TRANSLATE("Printer type:"), fPrinter);
19231613Swollman	printerMenuField->SetAlignment(B_ALIGN_RIGHT);
19387529Sru	_FillMenu(fPrinter, "Print", kPrinterSelectedMsg);
19431613Swollman
19579727Sschweikh	// add a "connected to" (aka transports list) menu field
19687529Sru	fTransport = new BPopUpMenu(B_TRANSLATE("<pick one>"));
19731613Swollman	BMenuField *transportMenuField = new BMenuField("transports_list",
19831614Swollman		B_TRANSLATE("Connected to:"), fTransport);
19931613Swollman	transportMenuField->SetAlignment(B_ALIGN_RIGHT);
20031613Swollman	_FillTransportMenu(fTransport);
20171895Sru
20231613Swollman	// add a "OK" button
20312951Sphk	fOk = new BButton(NULL, B_TRANSLATE("Add"), new BMessage((uint32)B_OK),
20412951Sphk		B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
20591436Simp
20614966Sjoerg	// add a "Cancel button
20714966Sjoerg	BButton *cancel = new BButton(NULL, B_TRANSLATE("Cancel"),
208106302Srwatson		new BMessage(B_CANCEL));
209106092Srwatson
210106092Srwatson	SetLayout(new BGridLayout());
211106092Srwatson
212106092Srwatson	AddChild(BGridLayoutBuilder(0, 4)
213106092Srwatson		.Add(fName->CreateLabelLayoutItem(), 0, 0)
214106092Srwatson		.Add(fName->CreateTextViewLayoutItem(), 1, 0)
215106092Srwatson		.Add(printerMenuField->CreateLabelLayoutItem(), 0, 1)
216106302Srwatson		.Add(printerMenuField->CreateMenuBarLayoutItem(), 1, 1)
217106092Srwatson		.Add(transportMenuField->CreateLabelLayoutItem(), 0, 2)
218106092Srwatson		.Add(transportMenuField->CreateMenuBarLayoutItem(), 1, 2)
219106092Srwatson		.Add(BGroupLayoutBuilder(B_HORIZONTAL)
220106092Srwatson			.AddGlue()
221106092Srwatson			.Add(cancel)
222106302Srwatson			.Add(fOk)
223107383Sru			, 0, 3, 2)
224107383Sru		.SetInsets(8, 8, 8, 8)
225107383Sru		);
226106302Srwatson
227106092Srwatson	SetDefaultButton(fOk);
228106092Srwatson	fOk->MakeDefault(true);
229106092Srwatson
230106092Srwatson	fName->MakeFocus(true);
231106302Srwatson
232106092Srwatson	_Update();
233106092Srwatson// Stage == 0
234106092Srwatson// init_icon 64x114  Add a Local or Network Printer
235106092Srwatson//                   ------------------------------
236106302Srwatson//                   I would like to add a...
237106092Srwatson//                              Local Printer
238106092Srwatson//                              Network Printer
239106092Srwatson// ------------------------------------------------
240106092Srwatson//                                Cancel   Continue
241106092Srwatson
242106302Srwatson// Add local printer:
243106302Srwatson
244106302Srwatson// Stage == 1
245106092Srwatson// local_icon        Add a Local Printer
246106302Srwatson//                   ------------------------------
247106302Srwatson//                   Printer Name: ________________
248106302Srwatson//                   Printer Type: pick one
249106092Srwatson//                   Connected to: pick one
250106092Srwatson// ------------------------------------------------
251106092Srwatson//                                Cancel        Add
252106092Srwatson
253106092Srwatson// This seems to be hard coded into the preferences dialog:
254106092Srwatson// Don't show Network transport add-on in Printer Type menu.
255106092Srwatson// If Printer Type == Preview disable Connect to popup menu.
256106092Srwatson// If Printer Type == Serial Port add a submenu to menu item
257106092Srwatson//    with names in /dev/ports (if empty remove item from menu)
258106092Srwatson// If Printer Type == Parallel Port add a submenu to menu item
259106092Srwatson//    with names in /dev/parallel (if empty remove item from menu)
260106092Srwatson
261106092Srwatson// Printer Driver Setup
262106092Srwatson
263106302Srwatson// Dialog Info
264106092Srwatson// Would you like to make X the default printer?
265106092Srwatson//                                        No Yes
266106092Srwatson
267106092Srwatson// Add network printer:
268106092Srwatson
269106302Srwatson// Dialog Info
270106092Srwatson// Apple Talk networking isn't currenty enabled. If you
271106092Srwatson// wish to install a network printer you should enable
272130432Sle// AppleTalk in the Network preferences.
273106092Srwatson//                               Cancel   Open Network
274106092Srwatson
275130582Sru// Stage == 2
276130582Sru
277120530Simp// network_icon      Add a Network Printer
278130582Sru//                   ------------------------------
279130582Sru//                   Printer Name: ________________
280130582Sru//                   Printer Type: pick one
281130582Sru//              AppleTalk Printer: pick one
282130582Sru// ------------------------------------------------
283120530Simp//                                Cancel        Add
284120530Simp}
285130582Sru
286130582Sru
287120530Simpstatic directory_which gAddonDirs[] = {
288130582Sru	B_USER_ADDONS_DIRECTORY,
289120530Simp	B_COMMON_ADDONS_DIRECTORY,
290120530Simp	B_SYSTEM_ADDONS_DIRECTORY,
29131613Swollman};
29271895Sru
29312823Sphk
29414966Sjoergvoid
29514966SjoergAddPrinterDialog::_FillMenu(BMenu* menu, const char* path, uint32 what)
296209546Scperciva{
297209546Scperciva	for (uint32 i = 0; i < sizeof(gAddonDirs) / sizeof(directory_which); i++) {
298209546Scperciva		BPath addonPath;
299103189Srobert		if (find_directory(gAddonDirs[i], &addonPath) != B_OK)
300103189Srobert			continue;
301107383Sru
302107383Sru		if (addonPath.Append(path) != B_OK)
303107383Sru			continue;
304107383Sru
305107383Sru		BDirectory dir(addonPath.Path());
306108317Sschweikh		if (dir.InitCheck() != B_OK)
307103189Srobert			continue;
30814966Sjoerg
309138327Sdds		BEntry entry;
31087529Sru		while (dir.GetNextEntry(&entry, true) == B_OK) {
31187529Sru			if (!entry.IsFile())
31285367Sjulian				continue;
31385445Sjulian
31485480Sbde			BNode node(&entry);
31599240Simp			if (node.InitCheck() != B_OK)
31699240Simp				continue;
31785445Sjulian
31885480Sbde			BNodeInfo info(&node);
31914966Sjoerg			if (info.InitCheck() != B_OK)
32014966Sjoerg				continue;
32149363Shoek
32287529Sru			char type[B_MIME_TYPE_LENGTH + 1];
32387529Sru			info.GetType(type);
32487529Sru			BMimeType entryType(type);
32587529Sru			// filter non executable entries (like "transport" subfolder...)
32687529Sru			if (entryType == B_APP_MIME_TYPE) {
32771895Sru				BPath transportPath;
32812823Sphk				if (entry.GetPath(&transportPath) != B_OK)
32985445Sjulian					continue;
33085445Sjulian
33185445Sjulian				BMessage* msg = new BMessage(what);
33285445Sjulian				msg->AddString("name", transportPath.Leaf());
33312823Sphk				menu->AddItem(new BMenuItem(transportPath.Leaf(), msg));
33485445Sjulian			}
33531612Swollman		}
33631613Swollman	}
33731612Swollman}
33831612Swollman
33987529Sru
34087529Sruvoid
34131612SwollmanAddPrinterDialog::_FillTransportMenu(BMenu* menu)
34271895Sru{
34331612Swollman	BMessenger msgr;
34487529Sru	if (GetPrinterServerMessenger(msgr) != B_OK)
34582952Sobrien		return;
34685480Sbde
34785445Sjulian	for (long idx = 0; ; idx++) {
34885445Sjulian		BMessage reply, msg(B_GET_PROPERTY);
34985445Sjulian		msg.AddSpecifier("Transport", idx);
35031612Swollman		if (msgr.SendMessage(&msg, &reply) != B_OK)
35185445Sjulian			break;
35231612Swollman
35331612Swollman		BMessenger transport;
35487529Sru		if (reply.FindMessenger("result", &transport) != B_OK)
355122424Sfanf			break;
356122424Sfanf
357122424Sfanf		// Got messenger to transport now
358122424Sfanf		msg.MakeEmpty();
359122424Sfanf		msg.what = B_GET_PROPERTY;
360122424Sfanf		msg.AddSpecifier("Name");
361122424Sfanf		if (transport.SendMessage(&msg, &reply) != B_OK)
362122554Sfanf			continue;
363122424Sfanf
364122424Sfanf		BString transportName;
365122424Sfanf		if (reply.FindString("result", &transportName) != B_OK)
366122424Sfanf			continue;
36787529Sru
36887529Sru		// Now get ports...
36987529Sru		BString portId, portName;
37087529Sru		int32 error;
37187529Sru		msg.MakeEmpty();
372107282Sru		msg.what = B_GET_PROPERTY;
373107282Sru		msg.AddSpecifier("Ports");
37471895Sru		if (transport.SendMessage(&msg, &reply) != B_OK ||
37512823Sphk			reply.FindInt32("error", &error) != B_OK ||
37687569Sobrien			error != B_OK) {
37712951Sphk			// Transport does not provide list of ports
37812823Sphk			BMessage* menuMsg = new BMessage(kTransportSelectedMsg);
37987569Sobrien			menuMsg->AddString("name", transportName);
38087569Sobrien			menu->AddItem(new BMenuItem(transportName.String(), menuMsg));
38114966Sjoerg			continue;
38214966Sjoerg		}
38314966Sjoerg
38414966Sjoerg		// Create submenu
385131530Sru		BMenu* transportMenu = new TransportMenu(transportName.String(),
38687529Sru			kTransportSelectedMsg, transport, transportName);
38787529Sru		menu->AddItem(transportMenu);
38814966Sjoerg		transportMenu->SetRadioMode(true);
38987529Sru		menu->ItemAt(menu->IndexOf(transportMenu))->
39014966Sjoerg			SetMessage(new BMessage(kTransportSelectedMsg));
39114966Sjoerg	}
39214966Sjoerg}
393102212Simp
394103011Srobert
395102212Simpvoid
39614966SjoergAddPrinterDialog::_Update()
39714966Sjoerg{
39881449Sru	fOk->SetEnabled(fNameText != "" && fPrinterText != ""
39987529Sru		&& (fTransportText != "" || fPrinterText == "Preview"));
40014966Sjoerg
40190043Simp	fTransport->SetEnabled(fPrinterText != "Preview");
40287529Sru}
40390043Simp
40414966Sjoerg