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:
Michael Pfeiffer 2002-10-22 16:03:31 +00:00
parent 5108df6e12
commit 7977efcf98
9 changed files with 757 additions and 89 deletions

View 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();
}
}
}

View 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

View File

@ -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);
}

View File

@ -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);
}

View 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);

View File

@ -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)

View File

@ -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);

View 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));
}
}
}

View 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