git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36694 a95241bf-73f2-0310-859d-f6bbb57e9c96
409 lines
10 KiB
C++
409 lines
10 KiB
C++
/*
|
|
* Copyright 2002-2009, Haiku.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Michael Pfeiffer
|
|
* Philippe Houdoin
|
|
*/
|
|
|
|
|
|
#include "AddPrinterDialog.h"
|
|
#include "PrinterListView.h"
|
|
#include "pr_server.h"
|
|
#include "Globals.h"
|
|
#include "Messages.h"
|
|
|
|
#include <Box.h>
|
|
#include <Button.h>
|
|
#include <Catalog.h>
|
|
#include <TextControl.h>
|
|
#include <MenuField.h>
|
|
#include <MenuItem.h>
|
|
#include <PopUpMenu.h>
|
|
#include <StringView.h>
|
|
#include <ListView.h>
|
|
#include <ScrollView.h>
|
|
#include <Application.h>
|
|
#include <StorageKit.h>
|
|
|
|
#include <Layout.h>
|
|
#include <GridLayout.h>
|
|
#include <GridLayoutBuilder.h>
|
|
#include <GroupLayoutBuilder.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#undef TR_CONTEXT
|
|
#define TR_CONTEXT "AddPrinterDialog"
|
|
|
|
|
|
AddPrinterDialog::AddPrinterDialog(BWindow *parent)
|
|
:
|
|
Inherited(BRect(78.0, 71.0, 400, 300), B_TRANSLATE("Add printer"),
|
|
B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
|
B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
|
fPrintersPrefletMessenger(parent)
|
|
{
|
|
BuildGUI(0);
|
|
|
|
Show();
|
|
}
|
|
|
|
|
|
bool
|
|
AddPrinterDialog::QuitRequested()
|
|
{
|
|
fPrintersPrefletMessenger.SendMessage(kMsgAddPrinterClosed);
|
|
return Inherited::QuitRequested();
|
|
}
|
|
|
|
|
|
void
|
|
AddPrinterDialog::MessageReceived(BMessage* msg)
|
|
{
|
|
switch(msg->what) {
|
|
case B_OK:
|
|
AddPrinter(msg);
|
|
PostMessage(B_QUIT_REQUESTED);
|
|
break;
|
|
|
|
case B_CANCEL:
|
|
PostMessage(B_QUIT_REQUESTED);
|
|
break;
|
|
|
|
case kNameChangedMsg:
|
|
fNameText = fName->Text();
|
|
Update();
|
|
break;
|
|
|
|
case kPrinterSelectedMsg:
|
|
StorePrinter(msg);
|
|
break;
|
|
|
|
case kTransportSelectedMsg:
|
|
HandleChangedTransport(msg);
|
|
break;
|
|
|
|
|
|
default:
|
|
Inherited::MessageReceived(msg);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
AddPrinterDialog::AddPrinter(BMessage *msg)
|
|
{
|
|
BMessage m(PSRV_MAKE_PRINTER);
|
|
BMessenger msgr;
|
|
if (GetPrinterServerMessenger(msgr) != B_OK)
|
|
return;
|
|
|
|
BString transport;
|
|
BString transportPath;
|
|
if (fPrinterText != "Preview") {
|
|
// Preview printer does not use transport add-on
|
|
transport = fTransportText;
|
|
transportPath = fTransportPathText;
|
|
}
|
|
|
|
m.AddString("driver", fPrinterText.String());
|
|
m.AddString("transport", transport.String());
|
|
m.AddString("transport path", transportPath.String());
|
|
m.AddString("printer name", fNameText.String());
|
|
m.AddString("connection", "Local");
|
|
msgr.SendMessage(&m);
|
|
// request print_server to create printer
|
|
}
|
|
|
|
|
|
void
|
|
AddPrinterDialog::StorePrinter(BMessage *msg)
|
|
{
|
|
BString name;
|
|
if (msg->FindString("name", &name) != B_OK)
|
|
name = "";
|
|
|
|
fPrinterText = name;
|
|
Update();
|
|
}
|
|
|
|
|
|
void
|
|
AddPrinterDialog::HandleChangedTransport(BMessage *msg)
|
|
{
|
|
BString name;
|
|
if (msg->FindString("name", &name) != B_OK) {
|
|
name = "";
|
|
}
|
|
fTransportText = name;
|
|
|
|
BString path;
|
|
if (msg->FindString("path", &path) == B_OK) {
|
|
// transport path selected
|
|
fTransportPathText = path;
|
|
|
|
// mark sub menu
|
|
void* pointer;
|
|
if (msg->FindPointer("source", &pointer) == B_OK) {
|
|
BMenuItem* item = (BMenuItem*)pointer;
|
|
|
|
// Update printer name with Transport Path if not filled in
|
|
if (strlen(fName->Text()) == 0)
|
|
fName->SetText(item->Label());
|
|
|
|
BMenu* menu = item->Menu();
|
|
int32 index = fTransport->IndexOf(menu);
|
|
item = fTransport->ItemAt(index);
|
|
if (item != NULL)
|
|
item->SetMarked(true);
|
|
}
|
|
} else {
|
|
// transport selected
|
|
fTransportPathText = "";
|
|
|
|
// remove mark from item in sub menu of transport sub menu
|
|
for (int32 i = fTransport->CountItems()-1; i >= 0; i --) {
|
|
BMenu* menu = fTransport->SubmenuAt(i);
|
|
if (menu != NULL) {
|
|
BMenuItem* item = menu->FindMarked();
|
|
if (item != NULL)
|
|
item->SetMarked(false);
|
|
}
|
|
}
|
|
}
|
|
Update();
|
|
}
|
|
|
|
|
|
void
|
|
AddPrinterDialog::BuildGUI(int stage)
|
|
{
|
|
// add a "printer name" input field
|
|
fName = new BTextControl("printer_name", B_TRANSLATE("Printer name:"),
|
|
B_EMPTY_STRING, NULL);
|
|
fName->SetFont(be_bold_font);
|
|
fName->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
|
fName->SetModificationMessage(new BMessage(kNameChangedMsg));
|
|
|
|
// add a "driver" popup menu field
|
|
fPrinter = new BPopUpMenu(B_TRANSLATE("<pick one>"));
|
|
BMenuField *printerMenuField = new BMenuField("drivers_list",
|
|
B_TRANSLATE("Printer type:"), fPrinter);
|
|
printerMenuField->SetAlignment(B_ALIGN_RIGHT);
|
|
FillMenu(fPrinter, "Print", kPrinterSelectedMsg);
|
|
|
|
// add a "connected to" (aka transports list) menu field
|
|
fTransport = new BPopUpMenu(B_TRANSLATE("<pick one>"));
|
|
BMenuField *transportMenuField = new BMenuField("transports_list",
|
|
B_TRANSLATE("Connected to:"), fTransport);
|
|
transportMenuField->SetAlignment(B_ALIGN_RIGHT);
|
|
FillTransportMenu(fTransport);
|
|
|
|
// add a "OK" button
|
|
fOk = new BButton(NULL, B_TRANSLATE("Add"), new BMessage((uint32)B_OK),
|
|
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
|
|
// add a "Cancel button
|
|
BButton *cancel = new BButton(NULL, B_TRANSLATE("Cancel"), new BMessage(B_CANCEL));
|
|
|
|
SetLayout(new BGridLayout());
|
|
|
|
AddChild(BGridLayoutBuilder(0, 4)
|
|
.Add(fName->CreateLabelLayoutItem(), 0, 0)
|
|
.Add(fName->CreateTextViewLayoutItem(), 1, 0)
|
|
.Add(printerMenuField->CreateLabelLayoutItem(), 0, 1)
|
|
.Add(printerMenuField->CreateMenuBarLayoutItem(), 1, 1)
|
|
.Add(transportMenuField->CreateLabelLayoutItem(), 0, 2)
|
|
.Add(transportMenuField->CreateMenuBarLayoutItem(), 1, 2)
|
|
.Add(BGroupLayoutBuilder(B_HORIZONTAL)
|
|
.AddGlue()
|
|
.Add(cancel)
|
|
.Add(fOk)
|
|
, 0, 3, 2)
|
|
.SetInsets(8, 8, 8, 8)
|
|
);
|
|
|
|
SetDefaultButton(fOk);
|
|
fOk->MakeDefault(true);
|
|
|
|
fName->MakeFocus(true);
|
|
|
|
Update();
|
|
// Stage == 0
|
|
// init_icon 64x114 Add a Local or Network Printer
|
|
// ------------------------------
|
|
// I would like to add a...
|
|
// Local Printer
|
|
// Network Printer
|
|
// ------------------------------------------------
|
|
// Cancel Continue
|
|
|
|
// Add local printer:
|
|
|
|
// Stage == 1
|
|
// local_icon Add a Local Printer
|
|
// ------------------------------
|
|
// Printer Name: ________________
|
|
// Printer Type: pick one
|
|
// Connected to: pick one
|
|
// ------------------------------------------------
|
|
// Cancel Add
|
|
|
|
// This seems to be hard coded into the preferences dialog:
|
|
// Don't show Network transport add-on in Printer Type menu.
|
|
// If Printer Type == Preview disable Connect to popup menu.
|
|
// If Printer Type == Serial Port add a submenu to menu item
|
|
// with names in /dev/ports (if empty remove item from menu)
|
|
// If Printer Type == Parallel Port add a submenu to menu item
|
|
// with names in /dev/parallel (if empty remove item from menu)
|
|
|
|
// Printer Driver Setup
|
|
|
|
// Dialog Info
|
|
// Would you like to make X the default printer?
|
|
// No Yes
|
|
|
|
// Add network printer:
|
|
|
|
// Dialog Info
|
|
// Apple Talk networking isn't currenty enabled. If you
|
|
// wish to install a network printer you should enable
|
|
// AppleTalk in the Network preferences.
|
|
// Cancel Open Network
|
|
|
|
// Stage == 2
|
|
|
|
// network_icon Add a Network Printer
|
|
// ------------------------------
|
|
// Printer Name: ________________
|
|
// Printer Type: pick one
|
|
// AppleTalk Printer: pick one
|
|
// ------------------------------------------------
|
|
// Cancel Add
|
|
}
|
|
|
|
static directory_which gAddonDirs[] = {
|
|
B_BEOS_ADDONS_DIRECTORY,
|
|
B_COMMON_ADDONS_DIRECTORY,
|
|
B_USER_ADDONS_DIRECTORY
|
|
};
|
|
|
|
void
|
|
AddPrinterDialog::FillMenu(BMenu* menu, const char* path, uint32 what)
|
|
{
|
|
for (uint32 i = 0; i < sizeof(gAddonDirs) / sizeof(directory_which); i ++) {
|
|
BPath addonPath;
|
|
if (find_directory(gAddonDirs[i], &addonPath) != B_OK)
|
|
continue;
|
|
|
|
if (addonPath.Append(path) != B_OK)
|
|
continue;
|
|
|
|
BDirectory dir(addonPath.Path());
|
|
if (dir.InitCheck() != B_OK)
|
|
continue;
|
|
|
|
BEntry entry;
|
|
while (dir.GetNextEntry(&entry, true) == B_OK) {
|
|
if (!entry.IsFile())
|
|
continue;
|
|
|
|
BNode node(&entry);
|
|
if (node.InitCheck() != B_OK)
|
|
continue;
|
|
|
|
BNodeInfo info(&node);
|
|
if (info.InitCheck() != B_OK)
|
|
continue;
|
|
|
|
char type[B_MIME_TYPE_LENGTH + 1];
|
|
info.GetType(type);
|
|
if (strcmp(type, B_APP_MIME_TYPE) != 0)
|
|
continue;
|
|
|
|
BPath path;
|
|
if (entry.GetPath(&path) != B_OK)
|
|
continue;
|
|
|
|
BMessage* msg = new BMessage(what);
|
|
msg->AddString("name", path.Leaf());
|
|
menu->AddItem(new BMenuItem(path.Leaf(), msg));
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddPrinterDialog::FillTransportMenu(BMenu* menu)
|
|
{
|
|
BMessenger msgr;
|
|
if (GetPrinterServerMessenger(msgr) != B_OK)
|
|
return;
|
|
|
|
for (long idx=0; ; idx++) {
|
|
BMessage reply, msg(B_GET_PROPERTY);
|
|
msg.AddSpecifier("Transport", idx);
|
|
if (msgr.SendMessage(&msg,&reply) != B_OK)
|
|
break;
|
|
|
|
BMessenger transport;
|
|
if (reply.FindMessenger("result", &transport) != B_OK)
|
|
break;
|
|
|
|
// Got messenger to transport now
|
|
msg.MakeEmpty();
|
|
msg.what = B_GET_PROPERTY;
|
|
msg.AddSpecifier("Name");
|
|
if (transport.SendMessage(&msg,&reply) != B_OK)
|
|
continue;
|
|
|
|
BString transportName;
|
|
if (reply.FindString("result",&transportName) != B_OK)
|
|
continue;
|
|
|
|
// Now get ports...
|
|
BString portId, portName;
|
|
msg.MakeEmpty();
|
|
msg.what = B_GET_PROPERTY;
|
|
msg.AddSpecifier("Ports");
|
|
if (transport.SendMessage(&msg,&reply) != B_OK ||
|
|
reply.FindString("port_id", &portId) != B_OK) {
|
|
// Can't find ports; so just show transport item, no menu
|
|
BMessage* menuMsg = new BMessage(kTransportSelectedMsg);
|
|
menuMsg->AddString("name", transportName);
|
|
menu->AddItem(new BMenuItem(transportName.String(), menuMsg));
|
|
continue;
|
|
}
|
|
|
|
// We have at least one port; so create submenu
|
|
BMenu* transportMenu = new BMenu(transportName.String());
|
|
menu->AddItem(transportMenu);
|
|
transportMenu->SetRadioMode(true);
|
|
menu->ItemAt(menu->IndexOf(transportMenu))->
|
|
SetMessage(new BMessage(kTransportSelectedMsg));
|
|
|
|
for (int32 pidx=0; reply.FindString("port_id", pidx, &portId) == B_OK; pidx++) {
|
|
if (reply.FindString("port_name", pidx, &portName) != B_OK ||
|
|
!portName.Length())
|
|
portName = portId;
|
|
|
|
// Create menu item in submenu for port
|
|
BMessage* portMsg = new BMessage(kTransportSelectedMsg);
|
|
portMsg->AddString("name", transportName);
|
|
portMsg->AddString("path", portId);
|
|
transportMenu->AddItem(new BMenuItem(portName.String(), portMsg));
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
AddPrinterDialog::Update()
|
|
{
|
|
fOk->SetEnabled(fNameText != "" && fPrinterText != "" &&
|
|
(fTransportText != "" || fPrinterText == "Preview"));
|
|
|
|
fTransport->SetEnabled(fPrinterText != "Preview");
|
|
}
|
|
|