Added ability to select printer inside of application.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1598 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5108df6e12
commit
7977efcf98
235
src/servers/print/ConfigWindow.cpp
Normal file
235
src/servers/print/ConfigWindow.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
/*****************************************************************************/
|
||||
// ConfigWindow
|
||||
//
|
||||
// Author
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#include "Printer.h"
|
||||
#include "PrintServerApp.h"
|
||||
#include "ConfigWindow.h"
|
||||
|
||||
// posix
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// BeOS
|
||||
#include <Application.h>
|
||||
#include <Autolock.h>
|
||||
#include <Window.h>
|
||||
|
||||
ConfigWindow::ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMessage* settings, AutoReply* sender)
|
||||
: BWindow(BRect(30, 30, 200, 125), "Printer Setup",
|
||||
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
|
||||
, fKind(kind)
|
||||
, fDefaultPrinter(defaultPrinter)
|
||||
, fSettings(settings)
|
||||
, fSender(sender)
|
||||
, fCurrentPrinter(NULL)
|
||||
{
|
||||
MimeTypeForSender(settings, fSenderMimeType);
|
||||
PrinterForMimeType();
|
||||
|
||||
BView* panel = new BBox(Bounds(), "top_panel", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
|
||||
B_PLAIN_BORDER);
|
||||
|
||||
AddChild(panel);
|
||||
|
||||
float left = 10, top = 5;
|
||||
BRect r(left, top, 160, 15);
|
||||
|
||||
BPopUpMenu* menu = new BPopUpMenu("PrinterMenu");
|
||||
SetupPrintersMenu(menu);
|
||||
|
||||
fPrinters = new BMenuField(r, "Printer", "Printer", menu);
|
||||
fPrinters->SetDivider(60);
|
||||
panel->AddChild(fPrinters);
|
||||
top += fPrinters->Bounds().Height() + 5;
|
||||
|
||||
r.OffsetTo(left, top);
|
||||
fPageSetup = new BButton(r, "Page Setup", "Page Setup", new BMessage(MSG_PAGE_SETUP));
|
||||
panel->AddChild(fPageSetup);
|
||||
fPageSetup->ResizeToPreferred();
|
||||
top += fPageSetup->Bounds().Height() + 5;
|
||||
|
||||
fJobSetup = NULL;
|
||||
if (kind == kJobSetup) {
|
||||
r.OffsetTo(left, top);
|
||||
fJobSetup = new BButton(r, "Job Setup", "Job Setup", new BMessage(MSG_JOB_SETUP));
|
||||
panel->AddChild(fJobSetup);
|
||||
fJobSetup->SetEnabled(fKind == kJobSetup);
|
||||
fJobSetup->ResizeToPreferred();
|
||||
top += fJobSetup->Bounds().Height() + 5;
|
||||
}
|
||||
|
||||
ResizeTo(Bounds().Width(), top);
|
||||
|
||||
UpdateSettings(true);
|
||||
}
|
||||
|
||||
ConfigWindow::~ConfigWindow() {
|
||||
if (fCurrentPrinter) fCurrentPrinter->Release();
|
||||
release_sem(fFinished);
|
||||
}
|
||||
|
||||
void ConfigWindow::Go() {
|
||||
sem_id sid = create_sem(0, "finished");
|
||||
if (sid >= 0) {
|
||||
fFinished = sid;
|
||||
Show();
|
||||
acquire_sem(sid);
|
||||
delete_sem(sid);
|
||||
} else {
|
||||
Quit();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::MessageReceived(BMessage* m) {
|
||||
switch (m->what) {
|
||||
case MSG_PAGE_SETUP: PageSetup(m);
|
||||
break;
|
||||
case MSG_JOB_SETUP: JobSetup(m);
|
||||
break;
|
||||
case MSG_PRINTER_SELECTED: {
|
||||
BString printer;
|
||||
if (m->FindString("name", &printer) == B_OK) {
|
||||
UpdateAppSettings(fSenderMimeType.String(), printer.String());
|
||||
PrinterForMimeType();
|
||||
UpdateSettings(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
inherited::MessageReceived(m);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::PrinterForMimeType() {
|
||||
BAutolock lock(gLock);
|
||||
if (fCurrentPrinter) {
|
||||
fCurrentPrinter->Release(); fCurrentPrinter = NULL;
|
||||
}
|
||||
if (lock.IsLocked()) {
|
||||
Settings* s = Settings::GetSettings();
|
||||
AppSettings* app = s->FindAppSettings(fSenderMimeType.String());
|
||||
if (app) {
|
||||
fPrinterName = app->GetPrinter();
|
||||
} else {
|
||||
fPrinterName = fDefaultPrinter ? fDefaultPrinter->Name() : "";
|
||||
}
|
||||
fCurrentPrinter = Printer::Find(fPrinterName);
|
||||
if (fCurrentPrinter) fCurrentPrinter->Acquire();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::SetupPrintersMenu(BMenu* menu) {
|
||||
// clear menu
|
||||
for (int i = menu->CountItems() - 1; i >= 0; i --) {
|
||||
delete menu->RemoveItem(i);
|
||||
}
|
||||
// fill menu with printer names
|
||||
BAutolock lock(gLock);
|
||||
if (lock.IsLocked()) {
|
||||
BString n;
|
||||
Printer* p;
|
||||
BMessage* m;
|
||||
BMenuItem* item;
|
||||
for (int i = 0; i < Printer::CountPrinters(); i ++) {
|
||||
Printer::At(i)->GetName(n);
|
||||
m = new BMessage(MSG_PRINTER_SELECTED);
|
||||
m->AddString("name", n.String());
|
||||
menu->AddItem(item = new BMenuItem(n.String(), m));
|
||||
if (n == fPrinterName) item->SetMarked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::UpdateAppSettings(const char* mime, const char* printer) {
|
||||
BAutolock lock(gLock);
|
||||
if (lock.IsLocked()) {
|
||||
Settings* s = Settings::GetSettings();
|
||||
AppSettings* app = s->FindAppSettings(mime);
|
||||
if (app) app->SetPrinter(printer);
|
||||
else s->AddAppSettings(new AppSettings(mime, printer));
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::UpdateSettings(bool read) {
|
||||
BAutolock lock(gLock);
|
||||
if (lock.IsLocked()) {
|
||||
Settings* s = Settings::GetSettings();
|
||||
PrinterSettings* p = s->FindPrinterSettings(fPrinterName.String());
|
||||
if (p == NULL) {
|
||||
p = new PrinterSettings(fPrinterName.String());
|
||||
s->AddPrinterSettings(p);
|
||||
}
|
||||
ASSERT(p != NULL);
|
||||
if (read) {
|
||||
fPageSettings = *p->GetPageSettings();
|
||||
fJobSettings = *p->GetJobSettings();
|
||||
} else {
|
||||
if (fJobSettings.IsEmpty()) fJobSettings = fPageSettings;
|
||||
p->SetPageSettings(&fPageSettings);
|
||||
p->SetJobSettings(&fJobSettings);
|
||||
}
|
||||
if (fJobSetup) {
|
||||
fJobSetup->SetEnabled(fKind == kJobSetup && !fPageSettings.IsEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::PageSetup(BMessage* m) {
|
||||
if (fCurrentPrinter) {
|
||||
Hide();
|
||||
UpdateSettings(true);
|
||||
bool ok = fCurrentPrinter->ConfigurePage(fPageSettings) == B_OK;
|
||||
if (ok) UpdateSettings(false);
|
||||
if (ok && fKind == kPageSetup) {
|
||||
fSender->SetReply(&fJobSettings);
|
||||
Quit();
|
||||
} else {
|
||||
Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWindow::JobSetup(BMessage* m) {
|
||||
if (fCurrentPrinter) {
|
||||
Hide();
|
||||
UpdateSettings(true);
|
||||
bool ok = fCurrentPrinter->ConfigureJob(fJobSettings) == B_OK;
|
||||
if (ok) UpdateSettings(false);
|
||||
if (ok && fKind == kJobSetup) {
|
||||
fSender->SetReply(&fJobSettings);
|
||||
Quit();
|
||||
} else {
|
||||
Show();
|
||||
}
|
||||
}
|
||||
}
|
85
src/servers/print/ConfigWindow.h
Normal file
85
src/servers/print/ConfigWindow.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*****************************************************************************/
|
||||
// ConfigWindow
|
||||
//
|
||||
// Author
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef _CONFIG_WINDOW_H
|
||||
#define _CONFIG_WINDOW_H
|
||||
|
||||
#include "BeUtils.h"
|
||||
#include "ObjectList.h"
|
||||
|
||||
#include <InterfaceKit.h>
|
||||
|
||||
enum config_setup_kind {
|
||||
kPageSetup,
|
||||
kJobSetup,
|
||||
};
|
||||
|
||||
class ConfigWindow : public BWindow {
|
||||
enum {
|
||||
MSG_PAGE_SETUP = 'cwps',
|
||||
MSG_JOB_SETUP = 'cwjs',
|
||||
MSG_PRINTER_SELECTED = 'cwpr',
|
||||
};
|
||||
|
||||
public:
|
||||
ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMessage* settings, AutoReply* sender);
|
||||
~ConfigWindow();
|
||||
void Go();
|
||||
|
||||
void MessageReceived(BMessage* m);
|
||||
|
||||
private:
|
||||
void PrinterForMimeType();
|
||||
void SetupPrintersMenu(BMenu* menu);
|
||||
void UpdateAppSettings(const char* mime, const char* printer);
|
||||
void UpdateSettings(bool read);
|
||||
void PageSetup(BMessage* m);
|
||||
void JobSetup(BMessage* m);
|
||||
|
||||
config_setup_kind fKind;
|
||||
Printer* fDefaultPrinter;
|
||||
BMessage* fSettings;
|
||||
AutoReply* fSender;
|
||||
BString fSenderMimeType;
|
||||
|
||||
BString fPrinterName;
|
||||
Printer* fCurrentPrinter;
|
||||
BMessage fPageSettings;
|
||||
BMessage fJobSettings;
|
||||
|
||||
sem_id fFinished;
|
||||
|
||||
BMenuField* fPrinters;
|
||||
BButton* fPageSetup;
|
||||
BButton* fJobSetup;
|
||||
};
|
||||
|
||||
#endif
|
@ -14,7 +14,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@ -39,26 +39,35 @@
|
||||
|
||||
#include "pr_server.h"
|
||||
#include "Printer.h"
|
||||
#include "ConfigWindow.h"
|
||||
|
||||
// BeOS API
|
||||
#include <PrintJob.h>
|
||||
#include <Alert.h>
|
||||
|
||||
// TODO:
|
||||
// Somehow block application that wants to show page/printer config dialog
|
||||
// Handle situation where there are pending print jobs but printer is requested for deletion
|
||||
#include <Autolock.h>
|
||||
#include <PrintJob.h>
|
||||
|
||||
struct AsyncThreadParams {
|
||||
PrintServerApp* app;
|
||||
Printer* printer;
|
||||
BMessage* message;
|
||||
|
||||
AsyncThreadParams(Printer* p, BMessage* m)
|
||||
: printer(p)
|
||||
AsyncThreadParams(PrintServerApp* app, Printer* p, BMessage* m)
|
||||
: app(app)
|
||||
, printer(p)
|
||||
, message(m)
|
||||
{ }
|
||||
{
|
||||
app->Acquire();
|
||||
if (printer) printer->Acquire();
|
||||
}
|
||||
|
||||
~AsyncThreadParams() {
|
||||
if (printer) printer->Release();
|
||||
delete message;
|
||||
app->Release();
|
||||
}
|
||||
|
||||
BMessage* AcquireMessage() {
|
||||
BMessage* m = message; message = NULL; return m;
|
||||
}
|
||||
};
|
||||
|
||||
@ -67,62 +76,61 @@ status_t PrintServerApp::async_thread(void* data)
|
||||
AsyncThreadParams* p = (AsyncThreadParams*)data;
|
||||
|
||||
Printer* printer = p->printer;
|
||||
BMessage* msg = p->message;
|
||||
BMessage* msg = p->AcquireMessage();
|
||||
|
||||
{
|
||||
AutoReply sender(msg, 'stop');
|
||||
switch (msg->what) {
|
||||
// Handle showing the page config dialog
|
||||
case PSRV_SHOW_PAGE_SETUP: {
|
||||
if (p->app->fUseConfigWindow) {
|
||||
ConfigWindow* w = new ConfigWindow(kPageSetup, printer, msg, &sender);
|
||||
w->Go();
|
||||
} else if (printer != NULL) {
|
||||
BMessage reply(*msg);
|
||||
if (printer->ConfigurePage(reply) == B_OK) {
|
||||
sender.SetReply(&reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If no default printer, give user choice of aborting or setting up a printer
|
||||
BAlert* alert = new BAlert("Info", "Hang on there! You don't have any printers set up!\nYou'll need to do that before trying to print\n\nWould you like to set up a printer now?", "No thanks", "Sure!");
|
||||
if (alert->Go() == 1) {
|
||||
run_add_printer_panel();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
switch (msg->what) {
|
||||
// Handle showing the page config dialog
|
||||
case PSRV_SHOW_PAGE_SETUP: {
|
||||
// Handle showing the print config dialog
|
||||
case PSRV_SHOW_PRINT_SETUP: {
|
||||
if (p->app->fUseConfigWindow) {
|
||||
ConfigWindow* w = new ConfigWindow(kJobSetup, printer, msg, &sender);
|
||||
w->Go();
|
||||
} else if (printer != NULL) {
|
||||
BMessage reply(*msg);
|
||||
if (printer->ConfigureJob(reply) == B_OK) {
|
||||
sender.SetReply(&reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Retrieve default configuration message from printer add-on
|
||||
case PSRV_GET_DEFAULT_SETTINGS:
|
||||
if (printer != NULL) {
|
||||
BMessage reply(*msg);
|
||||
if (printer->ConfigurePage(reply) == B_OK) {
|
||||
msg->SendReply(&reply);
|
||||
BMessage reply;
|
||||
if (printer->GetDefaultSettings(reply) == B_OK) {
|
||||
sender.SetReply(&reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If no default printer, give user choice of aborting or setting up a printer
|
||||
BAlert* alert = new BAlert("Info", "Hang on there! You don't have any printers set up!\nYou'll need to do that before trying to print\n\nWould you like to set up a printer now?", "No thanks", "Sure!");
|
||||
if (alert->Go() == 1) {
|
||||
run_add_printer_panel();
|
||||
}
|
||||
|
||||
}
|
||||
// Always stop dialog flow
|
||||
BMessage reply('stop');
|
||||
msg->SendReply(&reply);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle showing the print config dialog
|
||||
case PSRV_SHOW_PRINT_SETUP: {
|
||||
if (printer != NULL) {
|
||||
BMessage reply(*msg);
|
||||
if (printer->ConfigureJob(reply) == B_OK) {
|
||||
msg->SendReply(&reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BMessage reply('stop');
|
||||
msg->SendReply(&reply);
|
||||
}
|
||||
break;
|
||||
|
||||
// Retrieve default configuration message from printer add-on
|
||||
case PSRV_GET_DEFAULT_SETTINGS:
|
||||
if (printer != NULL) {
|
||||
BMessage reply;
|
||||
if (printer->GetDefaultSettings(reply) == B_OK) {
|
||||
msg->SendReply(&reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BMessage reply('stop');
|
||||
msg->SendReply(&reply);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (printer) printer->Release();
|
||||
delete p;
|
||||
}
|
||||
|
||||
@ -130,12 +138,11 @@ status_t PrintServerApp::async_thread(void* data)
|
||||
// Async. processing of received message
|
||||
void PrintServerApp::AsyncHandleMessage(BMessage* msg)
|
||||
{
|
||||
AsyncThreadParams* data = new AsyncThreadParams(fDefaultPrinter, msg);
|
||||
AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg);
|
||||
|
||||
thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY, (void*)data);
|
||||
|
||||
if (tid > 0) {
|
||||
if (fDefaultPrinter) fDefaultPrinter->Acquire();
|
||||
resume_thread(tid);
|
||||
} else {
|
||||
delete data;
|
||||
@ -148,7 +155,17 @@ void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
|
||||
// Get currently selected printer
|
||||
case PSRV_GET_ACTIVE_PRINTER: {
|
||||
BMessage reply('okok');
|
||||
reply.AddString("printer_name", fDefaultPrinter ? fDefaultPrinter->Name() : "");
|
||||
BString printerName = fDefaultPrinter ? fDefaultPrinter->Name() : "";
|
||||
BString mime;
|
||||
if (fUseConfigWindow && MimeTypeForSender(msg, mime)) {
|
||||
BAutolock lock(gLock);
|
||||
if (lock.IsLocked()) {
|
||||
// override with printer for application
|
||||
PrinterSettings* p = fSettings->FindPrinterSettings(mime.String());
|
||||
if (p) printerName = p->GetPrinter();
|
||||
}
|
||||
}
|
||||
reply.AddString("printer_name", printerName);
|
||||
reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER); // BeOS knows not if color or not, so always color
|
||||
msg->SendReply(&reply);
|
||||
}
|
||||
|
@ -119,12 +119,15 @@ PrintServerApp::PrintServerApp(status_t* err)
|
||||
: Inherited(PSRV_SIGNATURE_TYPE, err),
|
||||
fSelectedIconMini(NULL),
|
||||
fSelectedIconLarge(NULL),
|
||||
fNumberOfPrinters(0),
|
||||
fNoPrinterAvailable(0)
|
||||
fReferences(0),
|
||||
fHasReferences(0),
|
||||
fUseConfigWindow(true)
|
||||
{
|
||||
fSettings = Settings::GetSettings();
|
||||
LoadSettings();
|
||||
// If our superclass initialized ok
|
||||
if (*err == B_OK) {
|
||||
fNoPrinterAvailable = create_sem(1, "");
|
||||
fHasReferences = create_sem(1, "has_references");
|
||||
|
||||
// let us try as well
|
||||
SetupPrinterList();
|
||||
@ -143,6 +146,11 @@ PrintServerApp::PrintServerApp(status_t* err)
|
||||
}
|
||||
}
|
||||
|
||||
PrintServerApp::~PrintServerApp() {
|
||||
SaveSettings();
|
||||
delete fSettings;
|
||||
}
|
||||
|
||||
bool PrintServerApp::QuitRequested()
|
||||
{
|
||||
bool rc = Inherited::QuitRequested();
|
||||
@ -167,10 +175,10 @@ bool PrintServerApp::QuitRequested()
|
||||
}
|
||||
|
||||
// Wait for printers
|
||||
if (fNoPrinterAvailable > 0) {
|
||||
acquire_sem(fNoPrinterAvailable);
|
||||
delete_sem(fNoPrinterAvailable);
|
||||
fNoPrinterAvailable = 0;
|
||||
if (fHasReferences > 0) {
|
||||
acquire_sem(fHasReferences);
|
||||
delete_sem(fHasReferences);
|
||||
fHasReferences = 0;
|
||||
}
|
||||
|
||||
ASSERT(fSelectedIconMini != NULL);
|
||||
@ -182,6 +190,13 @@ bool PrintServerApp::QuitRequested()
|
||||
return rc;
|
||||
}
|
||||
|
||||
void PrintServerApp::Acquire() {
|
||||
if (atomic_add(&fReferences, 1) == 0) acquire_sem(fHasReferences);
|
||||
}
|
||||
|
||||
void PrintServerApp::Release() {
|
||||
if (atomic_add(&fReferences, -1) == 1) release_sem(fHasReferences);
|
||||
}
|
||||
|
||||
void PrintServerApp::RegisterPrinter(BDirectory* printer) {
|
||||
BString transport, address, connection;
|
||||
@ -195,8 +210,7 @@ void PrintServerApp::RegisterPrinter(BDirectory* printer) {
|
||||
Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String());
|
||||
Printer* p = new Printer(printer, r);
|
||||
AddHandler(p);
|
||||
if (fNumberOfPrinters == 0) acquire_sem(fNoPrinterAvailable);
|
||||
fNumberOfPrinters ++;
|
||||
Acquire();
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,9 +223,8 @@ void PrintServerApp::UnregisterPrinter(Printer* printer) {
|
||||
void PrintServerApp::NotifyPrinterDeletion(Printer* printer) {
|
||||
BAutolock lock(gLock);
|
||||
if (lock.IsLocked()) {
|
||||
fNumberOfPrinters --;
|
||||
fResourceManager.Free(printer->GetResource());
|
||||
if (fNumberOfPrinters == 0) release_sem(fNoPrinterAvailable);
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,9 +312,6 @@ status_t PrintServerApp::SetupPrinterList()
|
||||
void
|
||||
PrintServerApp::MessageReceived(BMessage* msg)
|
||||
{
|
||||
// fprintf(stdout, "PrintServerApp\n");
|
||||
// msg->PrintToStream(); printf("\n\n");
|
||||
// fflush(stdout);
|
||||
switch(msg->what) {
|
||||
case PSRV_GET_ACTIVE_PRINTER:
|
||||
case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY:
|
||||
@ -592,3 +602,22 @@ PrintServerApp::FindPrinterDriver(const char* name, BPath& outPath)
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool PrintServerApp::OpenSettings(BFile& file, bool forReading) {
|
||||
BPath path;
|
||||
uint32 openMode = forReading ? B_READ_ONLY : B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY;
|
||||
return find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK &&
|
||||
path.Append("print_server_settings") == B_OK &&
|
||||
file.SetTo(path.Path(), openMode) == B_OK;
|
||||
}
|
||||
|
||||
void PrintServerApp::LoadSettings() {
|
||||
BFile file;
|
||||
if (OpenSettings(file, true)) fSettings->Load(&file);
|
||||
}
|
||||
|
||||
void PrintServerApp::SaveSettings() {
|
||||
BFile file;
|
||||
if (OpenSettings(file, false)) fSettings->Save(&file);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define PRINTSERVERAPP_H
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "Settings.h"
|
||||
|
||||
class PrintServerApp;
|
||||
|
||||
@ -61,6 +62,10 @@ class PrintServerApp : public BApplication
|
||||
typedef BApplication Inherited;
|
||||
public:
|
||||
PrintServerApp(status_t* err);
|
||||
~PrintServerApp();
|
||||
|
||||
void Acquire();
|
||||
void Release();
|
||||
|
||||
bool QuitRequested();
|
||||
void MessageReceived(BMessage* msg);
|
||||
@ -73,6 +78,10 @@ public:
|
||||
BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec,
|
||||
int32 form, const char* prop);
|
||||
private:
|
||||
bool OpenSettings(BFile& file, bool forReading);
|
||||
void LoadSettings();
|
||||
void SaveSettings();
|
||||
|
||||
status_t SetupPrinterList();
|
||||
|
||||
void HandleSpooledJobs();
|
||||
@ -96,8 +105,10 @@ private:
|
||||
Printer* fDefaultPrinter;
|
||||
BBitmap* fSelectedIconMini;
|
||||
BBitmap* fSelectedIconLarge;
|
||||
int fNumberOfPrinters; // number of existing Printer objects
|
||||
sem_id fNoPrinterAvailable; // can be acquired if number of printers == 0
|
||||
vint32 fReferences;
|
||||
sem_id fHasReferences;
|
||||
Settings*fSettings;
|
||||
bool fUseConfigWindow;
|
||||
|
||||
// "Classic" BeOS R5 support, see PrintServerApp.R5.cpp
|
||||
static status_t async_thread(void* data);
|
||||
|
@ -226,9 +226,10 @@ status_t Printer::ConfigurePage(BMessage& settings)
|
||||
if ((rc=get_image_symbol(id, "config_page", B_SYMBOL_TYPE_TEXT, (void**)&func)) == B_OK) {
|
||||
// call the function and check its result
|
||||
BMessage* new_settings = (*func)(SpoolDir(), &settings);
|
||||
if (new_settings != NULL && new_settings->what != 'baad')
|
||||
if (new_settings != NULL && new_settings->what != 'baad') {
|
||||
settings = *new_settings;
|
||||
else
|
||||
AddCurrentPrinter(&settings);
|
||||
} else
|
||||
rc = B_ERROR;
|
||||
delete new_settings;
|
||||
}
|
||||
@ -264,9 +265,10 @@ status_t Printer::ConfigureJob(BMessage& settings)
|
||||
if ((rc=get_image_symbol(id, "config_job", B_SYMBOL_TYPE_TEXT, (void**)&func)) == B_OK) {
|
||||
// call the function and check its result
|
||||
BMessage* new_settings = (*func)(SpoolDir(), &settings);
|
||||
if ((new_settings != NULL) && (new_settings->what != 'baad'))
|
||||
if ((new_settings != NULL) && (new_settings->what != 'baad')) {
|
||||
settings = *new_settings;
|
||||
else
|
||||
AddCurrentPrinter(&settings);
|
||||
} else
|
||||
rc = B_ERROR;
|
||||
delete new_settings;
|
||||
}
|
||||
@ -315,6 +317,7 @@ status_t Printer::GetDefaultSettings(BMessage& settings) {
|
||||
BMessage* new_settings = (*func)(SpoolDir());
|
||||
if (new_settings) {
|
||||
settings = *new_settings;
|
||||
AddCurrentPrinter(&settings);
|
||||
} else {
|
||||
rc = B_ERROR;
|
||||
}
|
||||
@ -367,12 +370,19 @@ status_t Printer::LoadPrinterAddon(image_id& id)
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Printer::AddCurrentPrinter(BMessage* msg)
|
||||
{
|
||||
BString name;
|
||||
GetName(name);
|
||||
if (msg->HasString(PSRV_FIELD_CURRENT_PRINTER)) {
|
||||
msg->ReplaceString(PSRV_FIELD_CURRENT_PRINTER, name.String());
|
||||
} else {
|
||||
msg->AddString(PSRV_FIELD_CURRENT_PRINTER, name.String());
|
||||
}
|
||||
}
|
||||
|
||||
void Printer::MessageReceived(BMessage* msg)
|
||||
{
|
||||
printf("Printer::MessageReceived(): ");
|
||||
msg->PrintToStream();
|
||||
|
||||
|
||||
switch(msg->what) {
|
||||
case B_GET_PROPERTY:
|
||||
case B_SET_PROPERTY:
|
||||
@ -388,10 +398,49 @@ void Printer::MessageReceived(BMessage* msg)
|
||||
}
|
||||
}
|
||||
|
||||
void Printer::GetName(BString& name) {
|
||||
if (B_OK != SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_PRT_NAME, &name))
|
||||
name = "Unknown Printer";
|
||||
}
|
||||
|
||||
bool Printer::HasCurrentPrinter(BString& name) {
|
||||
BMessage settings;
|
||||
// read settings from spool file and get printer name
|
||||
BFile jobFile(&fJob->EntryRef(), B_READ_WRITE);
|
||||
return jobFile.InitCheck() == B_OK &&
|
||||
jobFile.Seek(sizeof(print_file_header), SEEK_SET) == sizeof(print_file_header) &&
|
||||
settings.Unflatten(&jobFile) == B_OK &&
|
||||
settings.FindString(PSRV_FIELD_CURRENT_PRINTER, &name) == B_OK;
|
||||
}
|
||||
|
||||
bool Printer::MoveJob(const BString& name) {
|
||||
BPath file(&fJob->EntryRef());
|
||||
BPath path;
|
||||
file.GetParent(&path);
|
||||
path.Append(".."); path.Append(name.String());
|
||||
BDirectory dir(path.Path());
|
||||
BEntry entry(&fJob->EntryRef());
|
||||
// try to move job file to proper directory
|
||||
return entry.MoveTo(&dir) == B_OK;
|
||||
}
|
||||
|
||||
bool Printer::FindSpooledJob() {
|
||||
fJob = fPrinter.GetNextJob();
|
||||
if (fJob) fJob->SetPrinter(this);
|
||||
return fJob;
|
||||
BString name2;
|
||||
GetName(name2);
|
||||
do {
|
||||
fJob = fPrinter.GetNextJob();
|
||||
if (fJob) {
|
||||
BString name;
|
||||
if (HasCurrentPrinter(name) && name != name2 && MoveJob(name)) {
|
||||
fJob->SetStatus(kUnknown, false); // so that fPrinter.GetNextJob skips it
|
||||
fJob->Release();
|
||||
} else {
|
||||
fJob->SetPrinter(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while (fJob != NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
status_t Printer::PrintSpooledJob(BFile* spoolFile)
|
||||
|
@ -95,10 +95,12 @@ public:
|
||||
BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec,
|
||||
int32 form, const char* prop);
|
||||
|
||||
void GetName(BString& name);
|
||||
Resource* GetResource() { return fResource; }
|
||||
|
||||
private:
|
||||
status_t LoadPrinterAddon(image_id& id);
|
||||
void AddCurrentPrinter(BMessage* m);
|
||||
|
||||
Folder fPrinter; // the printer spooling directory
|
||||
Resource* fResource; // the resource required for processing a print job
|
||||
@ -112,6 +114,8 @@ private:
|
||||
// Accessor
|
||||
BDirectory* SpoolDir() { return fPrinter.GetSpoolDir(); }
|
||||
|
||||
bool HasCurrentPrinter(BString& name);
|
||||
bool MoveJob(const BString& name);
|
||||
// Get next spooled job if any
|
||||
bool FindSpooledJob();
|
||||
status_t PrintSpooledJob(BFile* spoolFile);
|
||||
|
137
src/servers/print/Settings.cpp
Normal file
137
src/servers/print/Settings.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/*****************************************************************************/
|
||||
// Settings
|
||||
//
|
||||
// Author
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
#include <StorageKit.h>
|
||||
|
||||
// Implementation of AppSettings
|
||||
|
||||
AppSettings::AppSettings(const char* mimetype, const char* printer)
|
||||
: fMimeType(mimetype)
|
||||
{
|
||||
if (printer) fPrinter = printer;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of PrinterSettings
|
||||
|
||||
PrinterSettings::PrinterSettings(const char* printer, BMessage* pageSettings, BMessage* jobSettings)
|
||||
: fPrinter(printer)
|
||||
{
|
||||
if (pageSettings) fPageSettings = *pageSettings;
|
||||
if (jobSettings) fJobSettings = *jobSettings;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of Settings
|
||||
|
||||
Settings* Settings::fSingleton = NULL;
|
||||
|
||||
Settings::~Settings() {
|
||||
fSingleton = NULL;
|
||||
|
||||
for (int i = 0; i < AppSettingsCount(); i++) {
|
||||
AppSettings* app = AppSettingsAt(i);
|
||||
app->Release();
|
||||
}
|
||||
for (int i = 0; i < PrinterSettingsCount(); i++) {
|
||||
PrinterSettings* p = PrinterSettingsAt(i);
|
||||
p->Release();
|
||||
}
|
||||
}
|
||||
|
||||
Settings* Settings::GetSettings() {
|
||||
if (fSingleton == NULL) fSingleton = new Settings();
|
||||
return fSingleton;
|
||||
}
|
||||
|
||||
void Settings::RemoveAppSettings(int i) {
|
||||
delete fApps.RemoveItemAt(i);
|
||||
}
|
||||
|
||||
void Settings::RemovePrinterSettings(int i) {
|
||||
delete fPrinters.RemoveItemAt(i);
|
||||
}
|
||||
|
||||
AppSettings* Settings::FindAppSettings(const char* mimeType) {
|
||||
for (int i = AppSettingsCount()-1; i >= 0; i --) {
|
||||
if (strcmp(AppSettingsAt(i)->GetMimeType(), mimeType) == 0)
|
||||
return AppSettingsAt(i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PrinterSettings* Settings::FindPrinterSettings(const char* printer) {
|
||||
for (int i = PrinterSettingsCount()-1; i >= 0; i --) {
|
||||
if (strcmp(PrinterSettingsAt(i)->GetPrinter(), printer) == 0)
|
||||
return PrinterSettingsAt(i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Settings::Save(BFile* file) {
|
||||
BMessage m;
|
||||
// store application settings
|
||||
for (int i = 0; i < AppSettingsCount(); i++) {
|
||||
AppSettings* app = AppSettingsAt(i);
|
||||
m.AddString("m", app->GetMimeType());
|
||||
m.AddString("p", app->GetPrinter());
|
||||
}
|
||||
// store printer settings
|
||||
for (int i = 0; i < PrinterSettingsCount(); i++) {
|
||||
PrinterSettings* p = PrinterSettingsAt(i);
|
||||
m.AddString("P", p->GetPrinter());
|
||||
m.AddMessage("S", p->GetPageSettings());
|
||||
m.AddMessage("J", p->GetJobSettings());
|
||||
}
|
||||
m.Flatten(file);
|
||||
}
|
||||
|
||||
void Settings::Load(BFile* file) {
|
||||
BMessage m;
|
||||
if (m.Unflatten(file) == B_OK) {
|
||||
// restore application settings
|
||||
BString mimetype, printer;
|
||||
for (int i = 0; m.FindString("m", i, &mimetype) == B_OK &&
|
||||
m.FindString("p", i, &printer ) == B_OK; i ++) {
|
||||
AddAppSettings(new AppSettings(mimetype.String(), printer.String()));
|
||||
}
|
||||
// restore printer settings
|
||||
BMessage page, job;
|
||||
for (int i = 0; m.FindString("P", i, &printer) == B_OK &&
|
||||
m.FindMessage("S", i, &page) == B_OK &&
|
||||
m.FindMessage("J", i, &job) == B_OK; i ++) {
|
||||
AddPrinterSettings(new PrinterSettings(printer.String(), &page, &job));
|
||||
}
|
||||
}
|
||||
}
|
101
src/servers/print/Settings.h
Normal file
101
src/servers/print/Settings.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*****************************************************************************/
|
||||
// Settings
|
||||
//
|
||||
// Author
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef _SETTINGS_H
|
||||
#define _SETTINGS_H
|
||||
|
||||
#include "BeUtils.h"
|
||||
#include "ObjectList.h"
|
||||
|
||||
#include <String.h>
|
||||
|
||||
class AppSettings : public Object {
|
||||
private:
|
||||
BString fMimeType;
|
||||
BString fPrinter;
|
||||
|
||||
public:
|
||||
AppSettings(const char* mimeType, const char* printer = NULL);
|
||||
|
||||
const char* GetMimeType() const { return fMimeType.String(); }
|
||||
bool UsesDefaultPrinter() const { return fMimeType.Length() == 0; }
|
||||
const char* GetPrinter() const { return fPrinter.String(); }
|
||||
void SetPrinter(const char* printer) { fPrinter = printer; }
|
||||
void SetDefaultPrinter() { fPrinter = ""; }
|
||||
};
|
||||
|
||||
|
||||
class PrinterSettings : public Object {
|
||||
private:
|
||||
BString fPrinter;
|
||||
BMessage fPageSettings;
|
||||
BMessage fJobSettings;
|
||||
|
||||
public:
|
||||
PrinterSettings(const char* printer, BMessage* pageSettings = NULL, BMessage* jobSettings = NULL);
|
||||
|
||||
const char* GetPrinter() const { return fPrinter.String(); }
|
||||
BMessage* GetPageSettings() { return &fPageSettings; }
|
||||
BMessage* GetJobSettings() { return &fJobSettings; }
|
||||
void SetPrinter(const char* p) { fPrinter = p; }
|
||||
void SetPageSettings(BMessage* s) { fPageSettings = *s; }
|
||||
void SetJobSettings(BMessage* s) { fJobSettings = *s; }
|
||||
};
|
||||
|
||||
class Settings {
|
||||
private:
|
||||
BObjectList<AppSettings> fApps;
|
||||
BObjectList<PrinterSettings> fPrinters;
|
||||
|
||||
static Settings* fSingleton;
|
||||
Settings() { }
|
||||
|
||||
public:
|
||||
static Settings* GetSettings();
|
||||
~Settings();
|
||||
|
||||
int AppSettingsCount() const { return fApps.CountItems(); }
|
||||
AppSettings* AppSettingsAt(int i) { return fApps.ItemAt(i); }
|
||||
void AddAppSettings(AppSettings* s) { fApps.AddItem(s); }
|
||||
void RemoveAppSettings(int i);
|
||||
AppSettings* FindAppSettings(const char* mimeType);
|
||||
|
||||
int PrinterSettingsCount() const { return fPrinters.CountItems(); }
|
||||
PrinterSettings* PrinterSettingsAt(int i) { return fPrinters.ItemAt(i); }
|
||||
void AddPrinterSettings(PrinterSettings* s) { fPrinters.AddItem(s); }
|
||||
void RemovePrinterSettings(int i);
|
||||
PrinterSettings* FindPrinterSettings(const char* printer);
|
||||
|
||||
void Save(BFile* settings_file);
|
||||
void Load(BFile* settings_file);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user