* first steps towards a new printer api...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26925 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Karsten Heimrich
2008-08-10 23:26:38 +00:00
parent 92e47f6dbc
commit 4b7da592ee
8 changed files with 1618 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]
*/
#ifndef _JOB_SETUP_PANEL_H_
#define _JOB_SETUP_PANEL_H_
#include <PrintPanel.h>
class BButton;
class BCheckBox;
class BMenuField;
class BPopUpMenu;
class BRadioButton;
class BStringView;
class BTextControl;
class BTextView;
namespace BPrivate {
namespace Print {
class BPrinter;
class BPrinterRoster;
enum print_range {
B_ALL_PAGES = 0,
B_SELECTION = 1,
B_PAGE_RANGE = 2
};
const uint32 B_NO_OPTIONS = 0x00000000;
const uint32 B_PRINT_TO_FILE = 0x00000001;
const uint32 B_PRINT_SELECTION = 0x00000002;
const uint32 B_PRINT_PAGE_RANGE = 0x00000004;
const uint32 B_PRINT_COLLATE_COPIES = 0x00000008;
class BJobSetupPanel : public BPrintPanel {
public:
BJobSetupPanel(BPrinter* printer);
BJobSetupPanel(BPrinter* printer, uint32 flags);
virtual ~BJobSetupPanel();
BJobSetupPanel(BMessage* data);
static BArchivable* Instantiate(BMessage* data);
virtual status_t Archive(BMessage* data, bool deep = true) const;
virtual void MessageReceived(BMessage* message);
virtual status_t Go();
BPrinter* Printer() const;
void SetPrinter(BPrinter* printer, bool keepSettings);
print_range PrintRange() const;
void SetPrintRange(print_range range);
int32 FirstPage() const;
int32 LastPage() const;
void SetPageRange(int32 firstPage, int32 lastPage);
uint32 OptionFlags() const;
void SetOptionFlags(uint32 flags);
private:
void _InitObject();
void _SetupInterface();
void _DisallowChar(BTextView* textView);
private:
BPrinter* fPrinter;
BPrinterRoster* fPrinterRoster;
print_range fPrintRange;
uint32 fJobPanelFlags;
BPopUpMenu* fPrinterPopUp;
BMenuField* fPrinterMenuField;
BButton* fProperties;
BStringView* fPrinterInfo;
BCheckBox* fPrintToFile;
BRadioButton* fPrintAll;
BRadioButton* fPagesFrom;
BTextControl* fFirstPage;
BTextControl* fLastPage;
BRadioButton* fSelection;
BTextControl* fNumberOfCopies;
BCheckBox* fCollate;
BCheckBox* fReverse;
BCheckBox* fColor;
BCheckBox* fDuplex;
};
} // namespace Print
} // namespace BPrivate
#endif // _JOB_SETUP_PANEL_H_
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]
*/
#ifndef _PRINT_PANEL_H_
#define _PRINT_PANEL_H_
#include <MessageFilter.h>
#include <String.h>
#include <Window.h>
class BArchivable;
class BGroupView;
class BHandler;
class BMessage;
class BView;
namespace BPrivate {
namespace Print {
class BPrintPanel : public BWindow {
public:
BPrintPanel(const BString& title);
virtual ~BPrintPanel();
BPrintPanel(BMessage* data);
static BArchivable* Instantiate(BMessage* data);
virtual status_t Archive(BMessage* data, bool deep = true) const;
virtual status_t Go() = 0;
BView* Panel() const;
void AddPanel(BView* panel);
bool RemovePanel(BView* child);
virtual void MessageReceived(BMessage* message);
virtual void FrameResized(float newWidth, float newHeight);
virtual BHandler* ResolveSpecifier(BMessage* message, int32 index,
BMessage* specifier, int32 form,
const char* property);
virtual status_t GetSupportedSuites(BMessage* data);
virtual status_t Perform(perform_code d, void* arg);
virtual void Quit();
virtual bool QuitRequested();
virtual void DispatchMessage(BMessage* message, BHandler* handler);
protected:
virtual status_t ShowPanel();
private:
void AddChild(BView* child, BView* before = NULL);
bool RemoveChild(BView* child);
BView* ChildAt(int32 index) const;
class _BPrintPanelFilter_ : public BMessageFilter {
public:
_BPrintPanelFilter_(BPrintPanel* panel);
filter_result Filter(BMessage* msg, BHandler** target);
private:
BPrintPanel* fPrintPanel;
};
private:
virtual void _ReservedBPrintPanel1();
virtual void _ReservedBPrintPanel2();
virtual void _ReservedBPrintPanel3();
virtual void _ReservedBPrintPanel4();
virtual void _ReservedBPrintPanel5();
private:
BGroupView* fPanel;
sem_id fPrintPanelSem;
status_t fPrintPanelResult;
uint32 _reserved[5];
};
} // namespace Print
} // namespace BPrivate
#endif // _PRINT_PANEL_H_
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]
*/
#ifndef _PRINTER_H_
#define _PRINTER_H_
#include <Directory.h>
#include <Entry.h>
#include <image.h>
#include <Message.h>
#include <Node.h>
#include <Path.h>
#include <String.h>
namespace BPrivate {
namespace Print {
class BPrinter {
public:
BPrinter();
BPrinter(const BEntry& entry);
BPrinter(const BPrinter& printer);
BPrinter(const node_ref& nodeRef);
BPrinter(const entry_ref& entryRef);
BPrinter(const BDirectory& directory);
~BPrinter();
status_t SetTo(const BEntry& entry);
status_t SetTo(const node_ref& nodeRef);
status_t SetTo(const entry_ref& entryRef);
status_t SetTo(const BDirectory& directory);
void Unset();
bool IsValid() const;
status_t InitCheck() const;
bool IsFree() const;
bool IsDefault() const;
bool IsShareable() const;
BString Name() const;
BString State() const;
BString Driver() const;
BString Comments() const;
BString Transport() const;
BString TransportAddress() const;
status_t DefaultSettings(BMessage& settings);
status_t StartWatching(const BMessenger& listener);
void StopWatching();
BPrinter& operator=(const BPrinter& printer);
bool operator==(const BPrinter& printer) const;
bool operator!=(const BPrinter& printer) const;
private:
status_t _Configure() const;
status_t _ConfigureJob(BMessage& settings);
status_t _ConfigurePage(BMessage& settings);
BPath _DriverPath() const;
image_id _LoadDriver() const;
void _AddPrinterName(BMessage& settings);
BString _ReadAttribute(const char* attribute) const;
private:
BMessenger* fListener;
entry_ref fPrinterEntryRef;
};
} // namespace Print
} // namespace BPrivate
#endif // _PRINTER_H_
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]
*/
#ifndef _PRINTER_ROSTER_H_
#define _PRINTER_ROSTER_H_
#include <Directory.h>
#include <Messenger.h>
#include <Node.h>
#include <String.h>
namespace BPrivate {
namespace Print {
class BPrinter;
class BPrinterRoster {
public:
BPrinterRoster();
~BPrinterRoster();
int32 CountPrinters();
status_t GetNextPrinter(BPrinter* printer);
status_t GetDefaultPrinter(BPrinter* printer);
status_t FindPrinter(const BString& name, BPrinter* printer);
status_t Rewind();
status_t StartWatching(const BMessenger& listener);
void StopWatching();
private:
BPrinterRoster(const BPrinterRoster& printerRoster);
BPrinterRoster& operator=(const BPrinterRoster& printerRoster);
private:
BMessenger* fListener;
node_ref fUserPrintersNodRef;
BDirectory fUserPrintersDirectory;
};
} // namespace Print
} // namespace BPrivate
#endif // _PRINTER_ROSTER_H_
+375
View File
@@ -0,0 +1,375 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]>
*/
#include <JobSetupPanel.h>
#include <Box.h>
#include <Button.h>
#include <CheckBox.h>
#include <GridLayoutBuilder.h>
#include <GroupLayoutBuilder.h>
#include <GroupView.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <Printer.h>
#include <PrinterRoster.h>
#include <RadioButton.h>
#include <StringView.h>
#include <TextControl.h>
#include <stdlib.h>
namespace BPrivate {
namespace Print {
BJobSetupPanel::BJobSetupPanel(BPrinter* printer)
: BPrintPanel("Print Document")
, fPrinter(printer)
, fPrinterRoster(NULL)
, fPrintRange(B_ALL_PAGES)
, fJobPanelFlags(B_NO_OPTIONS)
{
_InitObject();
_SetupInterface();
}
BJobSetupPanel::BJobSetupPanel(BPrinter* printer, uint32 flags)
: BPrintPanel("Print Document")
, fPrinter(printer)
, fPrinterRoster(NULL)
, fPrintRange(B_ALL_PAGES)
, fJobPanelFlags(flags)
{
_InitObject();
_SetupInterface();
}
BJobSetupPanel::~BJobSetupPanel()
{
delete fPrinterRoster;
}
BJobSetupPanel::BJobSetupPanel(BMessage* data)
: BPrintPanel(data)
{
// TODO: implement
}
BArchivable*
BJobSetupPanel::Instantiate(BMessage* data)
{
// TODO: implement
return NULL;
}
status_t
BJobSetupPanel::Archive(BMessage* data, bool deep) const
{
// TODO: implement
return B_ERROR;
}
void
BJobSetupPanel::MessageReceived(BMessage* message)
{
BPrintPanel::MessageReceived(message);
}
status_t
BJobSetupPanel::Go()
{
status_t status = ShowPanel();
if (status == B_OK) {
// TODO: check if we did work on an real printer
// TODO: set all selected values on printer object
}
if (Lock())
Quit();
return status;
}
BPrinter*
BJobSetupPanel::Printer() const
{
return fPrinter;
}
void
BJobSetupPanel::SetPrinter(BPrinter* printer, bool keepSettings)
{
// TODO: implement
}
print_range
BJobSetupPanel::PrintRange() const
{
return fPrintRange;
}
void
BJobSetupPanel::SetPrintRange(print_range range)
{
switch (range) {
case B_ALL_PAGES: {
fPrintRange = range;
fPrintAll->SetValue(B_CONTROL_ON);
} break;
case B_SELECTION: {
fPrintRange = range;
SetOptionFlags(OptionFlags() | B_PRINT_SELECTION);
fSelection->SetValue(B_CONTROL_ON);
} break;
case B_PAGE_RANGE: {
fPrintRange = range;
SetOptionFlags(OptionFlags() | B_PRINT_PAGE_RANGE);
fPagesFrom->SetValue(B_CONTROL_ON);
} break;
}
}
int32
BJobSetupPanel::FirstPage() const
{
BString text(fFirstPage->Text());
if (text.Length() <= 0)
return 0;
return atoi(text.String());
}
int32
BJobSetupPanel::LastPage() const
{
BString text(fLastPage->Text());
if (text.Length() <= 0)
return LONG_MAX;
return atoi(text.String());
}
void
BJobSetupPanel::SetPageRange(int32 firstPage, int32 lastPage)
{
BString text;
SetPrintRange(B_PAGE_RANGE);
text << firstPage;
fFirstPage->SetText(text.String());
text << lastPage;
fLastPage->SetText(text.String());
}
uint32
BJobSetupPanel::OptionFlags() const
{
return fJobPanelFlags;
}
void
BJobSetupPanel::SetOptionFlags(uint32 flags)
{
bool value = false;
if (flags & B_PRINT_TO_FILE)
value = true;
fPrintToFile->SetEnabled(value);
value = false;
if (flags & B_PRINT_PAGE_RANGE)
value = true;
fPagesFrom->SetEnabled(value);
fFirstPage->SetEnabled(value);
fLastPage->SetEnabled(value);
value = false;
if (flags & B_PRINT_SELECTION)
value = true;
fSelection->SetEnabled(value);
value = false;
if (flags & B_PRINT_COLLATE_COPIES)
value = true;
fCollate->SetEnabled(value);
fJobPanelFlags = flags;
}
void
BJobSetupPanel::_InitObject()
{
fPrinterRoster = new BPrinterRoster();
fPrinterRoster->StartWatching(this);
if (!fPrinter->IsValid()) {
BPrinter defaultPrinter;
fPrinterRoster->GetDefaultPrinter(&defaultPrinter);
*fPrinter = defaultPrinter;
}
}
void
BJobSetupPanel::_SetupInterface()
{
BGroupView* groupView = new BGroupView(B_VERTICAL, 10.0);
// printers
fPrinterPopUp = new BPopUpMenu("");
fPrinterPopUp->SetRadioMode(true);
fPrinterMenuField = new BMenuField("", fPrinterPopUp);
fPrinterMenuField->Menu()->SetLabelFromMarked(true);
BPrinter printer;
while (fPrinterRoster->GetNextPrinter(&printer) == B_OK) {
BMenuItem* item = new BMenuItem(printer.Name().String(), NULL);
fPrinterPopUp->AddItem(item);
if (printer == *fPrinter)
item->SetMarked(true);
}
if (fPrinterRoster->CountPrinters() > 0)
fPrinterPopUp->AddItem(new BSeparatorItem);
BMenuItem* pdf = new BMenuItem("Save as PDF file" , NULL);
fPrinterPopUp->AddItem(pdf);
if (fPrinterPopUp->FindMarked() == NULL)
pdf->SetMarked(true);
fProperties = new BButton("Properties"B_UTF8_ELLIPSIS , new BMessage('prop'));
fPrinterInfo = new BStringView("label", "");
fPrinterInfo->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
BBox* divider = new BBox(B_FANCY_BORDER, NULL);
divider->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
fPrintToFile = new BCheckBox("Print to file");
BView* view = BGroupLayoutBuilder(B_VERTICAL, 5.0)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10.0)
.Add(fPrinterMenuField->CreateMenuBarLayoutItem())
.Add(fProperties))
.Add(BGroupLayoutBuilder(B_HORIZONTAL,5.0)
.Add(new BStringView("label", "Printer info:"))
.Add(fPrinterInfo))
.Add(divider)
.Add(fPrintToFile)
.SetInsets(10.0, 5.0, 10.0, 5.0);
BBox *box = new BBox(B_FANCY_BORDER, view);
box->SetLabel(BGroupLayoutBuilder()
.Add(new BStringView("", "Printer"))
.SetInsets(2.0, 0.0, 2.0, 0.0));
groupView->AddChild(box);
// page range
fPrintAll = new BRadioButton("Print all", new BMessage('prrg'));
fPrintAll->SetValue(B_CONTROL_ON);
fPagesFrom = new BRadioButton("Pages from:", new BMessage('prrg'));
fFirstPage = new BTextControl("", "", NULL);
_DisallowChar(fFirstPage->TextView());
fLastPage = new BTextControl("to:", "", NULL);
_DisallowChar(fLastPage->TextView());
fSelection = new BRadioButton("Print selection", new BMessage('prrg'));
fFirstPage->CreateLabelLayoutItem();
view = BGroupLayoutBuilder(B_VERTICAL, 5.0)
.Add(fPrintAll)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 5.0)
.Add(fPagesFrom)
.Add(fFirstPage->CreateTextViewLayoutItem())
.Add(fLastPage->CreateLabelLayoutItem())
.Add(fLastPage->CreateTextViewLayoutItem()))
.Add(fSelection)
.SetInsets(10.0, 5.0, 10.0, 5.0);
box = new BBox(B_FANCY_BORDER, view);
box->SetLabel(BGroupLayoutBuilder()
.Add(new BStringView("", "Page Range"))
.SetInsets(2.0, 0.0, 2.0, 0.0));
// copies
fNumberOfCopies = new BTextControl("Number of copies:", "1", NULL);
_DisallowChar(fNumberOfCopies->TextView());
fCollate = new BCheckBox("Collate");
fReverse = new BCheckBox("Reverse");
BView* view2 = BGroupLayoutBuilder(B_VERTICAL, 5.0)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 5.0)
.Add(fNumberOfCopies->CreateLabelLayoutItem())
.Add(fNumberOfCopies->CreateTextViewLayoutItem()))
.Add(fCollate)
.Add(fReverse)
.SetInsets(10.0, 5.0, 10.0, 5.0);
BBox* box2 = new BBox(B_FANCY_BORDER, view2);
box2->SetLabel(BGroupLayoutBuilder()
.Add(new BStringView("", "Copies"))
.SetInsets(2.0, 0.0, 2.0, 0.0));
groupView->AddChild(BGroupLayoutBuilder(B_HORIZONTAL, 10.0)
.Add(box)
.Add(box2));
// other
fColor = new BCheckBox("Print in color");
fDuplex = new BCheckBox("Double side printing");
view = BGroupLayoutBuilder(B_VERTICAL, 5.0)
.Add(fColor)
.Add(fDuplex)
.SetInsets(10.0, 5.0, 10.0, 5.0);
box = new BBox(B_FANCY_BORDER, view);
box->SetLabel(BGroupLayoutBuilder()
.Add(new BStringView("", "Other"))
.SetInsets(2.0, 0.0, 2.0, 0.0));
groupView->AddChild(box);
AddPanel(groupView);
SetOptionFlags(fJobPanelFlags);
}
void
BJobSetupPanel::_DisallowChar(BTextView* textView)
{
for (uint32 i = 0; i < '0'; ++i)
textView->DisallowChar(i);
for (uint32 i = '9' + 1; i < 255; ++i)
textView->DisallowChar(i);
}
} // namespace Print
} // namespace BPrivate
+277
View File
@@ -0,0 +1,277 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]
*/
#include <PrintPanel.h>
#include <Button.h>
#include <GroupLayoutBuilder.h>
#include <GroupView.h>
#include <Screen.h>
namespace BPrivate {
namespace Print {
// #pragma mark -- _BPrintPanelFilter_
BPrintPanel::_BPrintPanelFilter_::_BPrintPanelFilter_(BPrintPanel* panel)
: BMessageFilter(B_KEY_DOWN)
, fPrintPanel(panel)
{
}
filter_result
BPrintPanel::_BPrintPanelFilter_::Filter(BMessage* msg, BHandler** target)
{
int32 key;
filter_result result = B_DISPATCH_MESSAGE;
if (msg->FindInt32("key", &key) == B_OK && key == 1) {
fPrintPanel->PostMessage(B_QUIT_REQUESTED);
result = B_SKIP_MESSAGE;
}
return result;
}
// #pragma mark -- BPrintPanel
BPrintPanel::BPrintPanel(const BString& title)
: BWindow(BRect(0, 0, 640, 480), title.String(), B_TITLED_WINDOW_LOOK,
B_MODAL_APP_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_RESIZABLE |
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE)
, fPanel(new BGroupView)
, fPrintPanelSem(-1)
, fPrintPanelResult(B_CANCEL)
{
BButton* ok = new BButton("OK", new BMessage('_ok_'));
BButton* cancel = new BButton("Cancel", new BMessage('_cl_'));
BGroupLayout *layout = new BGroupLayout(B_HORIZONTAL);
SetLayout(layout);
AddChild(BGroupLayoutBuilder(B_VERTICAL, 10.0)
.Add(fPanel)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10.0)
.AddGlue()
.Add(cancel)
.Add(ok)
.SetInsets(0.0, 0.0, 0.0, 0.0))
.SetInsets(10.0, 10.0, 10.0, 10.0)
);
ok->MakeDefault(true);
AddCommonFilter(new _BPrintPanelFilter_(this));
}
BPrintPanel::~BPrintPanel()
{
if (fPrintPanelSem > 0)
delete_sem(fPrintPanelSem);
}
BPrintPanel::BPrintPanel(BMessage* data)
: BWindow(data)
{
// TODO: implement
}
BArchivable*
BPrintPanel::Instantiate(BMessage* data)
{
// TODO: implement
return NULL;
}
status_t
BPrintPanel::Archive(BMessage* data, bool deep) const
{
// TODO: implement
return B_ERROR;
}
BView*
BPrintPanel::Panel() const
{
return fPanel->ChildAt(0);
}
void
BPrintPanel::AddPanel(BView* panel)
{
BView* child = Panel();
if (child) {
RemovePanel(child);
delete child;
}
fPanel->AddChild(panel);
BSize size = GetLayout()->PreferredSize();
ResizeTo(size.Width(), size.Height());
}
bool
BPrintPanel::RemovePanel(BView* child)
{
BView* panel = Panel();
if (child == panel)
return fPanel->RemoveChild(child);
return false;
}
void
BPrintPanel::MessageReceived(BMessage* message)
{
switch (message->what) {
case '_ok_': {
fPrintPanelResult = B_OK;
// fall through
case '_cl_':
delete_sem(fPrintPanelSem);
fPrintPanelSem = -1;
} break;
default:
BWindow::MessageReceived(message);
}
}
void
BPrintPanel::FrameResized(float newWidth, float newHeight)
{
BWindow::FrameResized(newWidth, newHeight);
}
BHandler*
BPrintPanel::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier,
int32 form, const char* property)
{
return BWindow::ResolveSpecifier(message, index, specifier, form, property);
}
status_t
BPrintPanel::GetSupportedSuites(BMessage* data)
{
return BWindow::GetSupportedSuites(data);
}
status_t
BPrintPanel::Perform(perform_code d, void* arg)
{
return BWindow::Perform(d, arg);
}
void
BPrintPanel::Quit()
{
BWindow::Quit();
}
bool
BPrintPanel::QuitRequested()
{
return BWindow::QuitRequested();
}
void
BPrintPanel::DispatchMessage(BMessage* message, BHandler* handler)
{
BWindow::DispatchMessage(message, handler);
}
status_t
BPrintPanel::ShowPanel()
{
fPrintPanelSem = create_sem(0, "PrintPanel");
if (fPrintPanelSem < 0) {
Quit();
return B_CANCEL;
}
BWindow* window = dynamic_cast<BWindow*> (BLooper::LooperForThread(find_thread(NULL)));
{
BRect bounds(Bounds());
BRect frame(BScreen(B_MAIN_SCREEN_ID).Frame());
MoveTo((frame.Width() - bounds.Width()) / 2.0,
(frame.Height() - bounds.Height()) / 2.0);
}
Show();
if (window) {
status_t err;
while (true) {
do {
err = acquire_sem_etc(fPrintPanelSem, 1, B_RELATIVE_TIMEOUT, 50000);
} while (err == B_INTERRUPTED);
if (err == B_BAD_SEM_ID)
break;
window->UpdateIfNeeded();
}
} else {
while (acquire_sem(fPrintPanelSem) == B_INTERRUPTED) {}
}
return fPrintPanelResult;
}
void
BPrintPanel::AddChild(BView* child, BView* before)
{
BWindow::AddChild(child, before);
}
bool
BPrintPanel::RemoveChild(BView* child)
{
return BWindow::RemoveChild(child);
}
BView*
BPrintPanel::ChildAt(int32 index) const
{
return BWindow::ChildAt(index);
}
void BPrintPanel::_ReservedBPrintPanel1() {}
void BPrintPanel::_ReservedBPrintPanel2() {}
void BPrintPanel::_ReservedBPrintPanel3() {}
void BPrintPanel::_ReservedBPrintPanel4() {}
void BPrintPanel::_ReservedBPrintPanel5() {}
} // namespace Print
} // namespace BPrivate
+457
View File
@@ -0,0 +1,457 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <[email protected]
*/
#include <Printer.h>
#include <FindDirectory.h>
#include <NodeInfo.h>
#include <NodeMonitor.h>
#include <new>
namespace BPrivate {
namespace Print {
// TODO: remove, after pr_server.h cleanup
// mime file types
#define PSRV_PRINTER_MIMETYPE "application/x-vnd.Be.printer"
// printer attributes
#define PSRV_PRINTER_ATTR_STATE "state"
#define PSRV_PRINTER_ATTR_COMMENTS "Comments"
#define PSRV_PRINTER_ATTR_TRANSPORT "transport"
#define PSRV_PRINTER_ATTR_DRIVER_NAME "Driver Name"
#define PSRV_PRINTER_ATTR_PRINTER_NAME "Printer Name"
#define PSRV_PRINTER_ATTR_DEFAULT_PRINTER "Default Printer"
#define PSRV_PRINTER_ATTR_TRANSPORT_ADDRESS "transport_address"
// message fields
#define PSRV_FIELD_CURRENT_PRINTER "current_printer"
BPrinter::BPrinter()
: fListener(NULL)
{
memset(&fPrinterEntryRef, 0, sizeof(entry_ref));
}
BPrinter::BPrinter(const BEntry& entry)
: fListener(NULL)
{
SetTo(entry);
}
BPrinter::BPrinter(const BPrinter& printer)
{
*this = printer;
}
BPrinter::BPrinter(const node_ref& nodeRef)
: fListener(NULL)
{
SetTo(nodeRef);
}
BPrinter::BPrinter(const entry_ref& entryRef)
: fListener(NULL)
, fPrinterEntryRef(entryRef)
{
}
BPrinter::BPrinter(const BDirectory& directory)
: fListener(NULL)
{
SetTo(directory);
}
BPrinter::~BPrinter()
{
StopWatching();
}
status_t
BPrinter::SetTo(const BEntry& entry)
{
StopWatching();
entry.GetRef(&fPrinterEntryRef);
return InitCheck();
}
status_t
BPrinter::SetTo(const node_ref& nodeRef)
{
SetTo(BDirectory(&nodeRef));
return InitCheck();
}
status_t
BPrinter::SetTo(const entry_ref& entryRef)
{
StopWatching();
fPrinterEntryRef = entryRef;
return InitCheck();
}
status_t
BPrinter::SetTo(const BDirectory& directory)
{
StopWatching();
BEntry entry;
directory.GetEntry(&entry);
entry.GetRef(&fPrinterEntryRef);
return InitCheck();
}
void
BPrinter::Unset()
{
StopWatching();
memset(&fPrinterEntryRef, 0, sizeof(entry_ref));
}
bool
BPrinter::IsValid() const
{
BDirectory spoolDir(&fPrinterEntryRef);
if (spoolDir.InitCheck() != B_OK)
return false;
BNode node(spoolDir);
char type[B_MIME_TYPE_LENGTH];
BNodeInfo(&node).GetType(type);
if (strcmp(type, PSRV_PRINTER_MIMETYPE) != 0)
return false;
return true;
}
status_t
BPrinter::InitCheck() const
{
BDirectory spoolDir(&fPrinterEntryRef);
return spoolDir.InitCheck();
}
bool
BPrinter::IsFree() const
{
return (State() == "free");
}
bool
BPrinter::IsDefault() const
{
bool isDefault = false;
BDirectory spoolDir(&fPrinterEntryRef);
if (spoolDir.InitCheck() == B_OK)
spoolDir.ReadAttr(PSRV_PRINTER_ATTR_DEFAULT_PRINTER, B_BOOL_TYPE, 0,
&isDefault, sizeof(bool));
return isDefault;
}
bool
BPrinter::IsShareable() const
{
if (Name() == "Preview")
return true;
return false;
}
BString
BPrinter::Name() const
{
return _ReadAttribute(PSRV_PRINTER_ATTR_PRINTER_NAME);
}
BString
BPrinter::State() const
{
return _ReadAttribute(PSRV_PRINTER_ATTR_STATE);
}
BString
BPrinter::Driver() const
{
return _ReadAttribute(PSRV_PRINTER_ATTR_DRIVER_NAME);
}
BString
BPrinter::Comments() const
{
return _ReadAttribute(PSRV_PRINTER_ATTR_COMMENTS);
}
BString
BPrinter::Transport() const
{
return _ReadAttribute(PSRV_PRINTER_ATTR_TRANSPORT);
}
BString
BPrinter::TransportAddress() const
{
return _ReadAttribute(PSRV_PRINTER_ATTR_TRANSPORT_ADDRESS);
}
status_t
BPrinter::DefaultSettings(BMessage& settings)
{
status_t status = B_ERROR;
image_id id = _LoadDriver();
if (id < 0)
return status;
typedef BMessage* (*default_settings_func_t)(BNode*);
default_settings_func_t default_settings;
if (get_image_symbol(id, "default_settings", B_SYMBOL_TYPE_TEXT
, (void**)&default_settings) == B_OK) {
BNode printerNode(&fPrinterEntryRef);
BMessage *newSettings = default_settings(&printerNode);
if (newSettings) {
status = B_OK;
settings = *newSettings;
_AddPrinterName(settings);
}
delete newSettings;
}
unload_add_on(id);
return status;
}
status_t
BPrinter::StartWatching(const BMessenger& listener)
{
StopWatching();
if (!listener.IsValid())
return B_BAD_VALUE;
fListener = new(std::nothrow) BMessenger(listener);
if (!fListener)
return B_NO_MEMORY;
node_ref nodeRef;
nodeRef.device = fPrinterEntryRef.device;
nodeRef.node = fPrinterEntryRef.directory;
return watch_node(&nodeRef, B_WATCH_DIRECTORY, *fListener);
}
void
BPrinter::StopWatching()
{
if (fListener) {
stop_watching(*fListener);
delete fListener;
fListener = NULL;
}
}
BPrinter&
BPrinter::operator=(const BPrinter& printer)
{
if (this != &printer) {
Unset();
fPrinterEntryRef = printer.fPrinterEntryRef;
if (printer.fListener)
StartWatching(*printer.fListener);
}
return *this;
}
bool
BPrinter::operator==(const BPrinter& printer) const
{
return (fPrinterEntryRef == printer.fPrinterEntryRef);
}
bool
BPrinter::operator!=(const BPrinter& printer) const
{
return (fPrinterEntryRef != printer.fPrinterEntryRef);
}
status_t
BPrinter::_Configure() const
{
status_t status = B_ERROR;
image_id id = _LoadDriver();
if (id < 0)
return status;
BString printerName(_ReadAttribute(PSRV_PRINTER_ATTR_PRINTER_NAME));
if (printerName.Length() > 0) {
typedef char* (*add_printer_func_t)(const char*);
add_printer_func_t add_printer;
if (get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT
, (void**)&add_printer) == B_OK) {
if (add_printer(printerName.String()) != NULL)
status = B_OK;
}
} else {
status = B_ERROR;
}
unload_add_on(id);
return status;
}
status_t
BPrinter::_ConfigureJob(BMessage& settings)
{
status_t status = B_ERROR;
image_id id = _LoadDriver();
if (id < 0)
return status;
typedef BMessage* (*config_job_func_t)(BNode*, const BMessage*);
config_job_func_t configure_job;
if (get_image_symbol(id, "config_job", B_SYMBOL_TYPE_TEXT
, (void**)&configure_job) == B_OK) {
BNode printerNode(&fPrinterEntryRef);
BMessage *newSettings = configure_job(&printerNode, &settings);
if (newSettings && (newSettings->what == 'okok')) {
status = B_OK;
settings = *newSettings;
_AddPrinterName(settings);
}
delete newSettings;
}
unload_add_on(id);
return status;
}
status_t
BPrinter::_ConfigurePage(BMessage& settings)
{
status_t status = B_ERROR;
image_id id = _LoadDriver();
if (id < 0)
return status;
typedef BMessage* (*config_page_func_t)(BNode*, const BMessage*);
config_page_func_t configure_page;
if (get_image_symbol(id, "config_page", B_SYMBOL_TYPE_TEXT
, (void**)&configure_page) == B_OK) {
BNode printerNode(&fPrinterEntryRef);
BMessage *newSettings = configure_page(&printerNode, &settings);
if (newSettings && (newSettings->what == 'okok')) {
status = B_OK;
settings = *newSettings;
_AddPrinterName(settings);
}
delete newSettings;
}
unload_add_on(id);
return status;
}
BPath
BPrinter::_DriverPath() const
{
BString driverName(_ReadAttribute(PSRV_PRINTER_ATTR_DRIVER_NAME));
if (driverName.Length() <= 0)
return BPath();
directory_which directorys[] = { B_USER_ADDONS_DIRECTORY,
B_COMMON_ADDONS_DIRECTORY, B_BEOS_ADDONS_DIRECTORY };
BPath path;
driverName.Prepend("Print/");
for (int32 i = 0; i < 3; ++i) {
if (find_directory(directorys[i], &path) == B_OK) {
path.Append(driverName.String());
BEntry driver(path.Path());
if (driver.InitCheck() == B_OK && driver.Exists() && driver.IsFile())
return path;
}
}
return BPath();
}
image_id
BPrinter::_LoadDriver() const
{
BPath driverPath(_DriverPath());
if (driverPath.InitCheck() != B_OK)
return -1;
return load_add_on(driverPath.Path());
}
void
BPrinter::_AddPrinterName(BMessage& settings)
{
settings.RemoveName(PSRV_FIELD_CURRENT_PRINTER);
settings.AddString(PSRV_FIELD_CURRENT_PRINTER, Name());
}
BString
BPrinter::_ReadAttribute(const char* attribute) const
{
BString value;
BDirectory spoolDir(&fPrinterEntryRef);
if (spoolDir.InitCheck() == B_OK)
spoolDir.ReadAttrString(attribute, &value);
return value;
}
} // namespace Print
} // namespace BPrivate
+168
View File
@@ -0,0 +1,168 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Julun, <host.haiku@gmx.de
*/
#include <PrinterRoster.h>
#include <FindDirectory.h>
#include <Node.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <Printer.h>
#include <new>
namespace BPrivate {
namespace Print {
BPrinterRoster::BPrinterRoster()
: fListener(NULL)
{
BPath path;
find_directory(B_USER_PRINTERS_DIRECTORY, &path, true);
BNode(path.Path()).GetNodeRef(&fUserPrintersNodRef);
fUserPrintersDirectory.SetTo(&fUserPrintersNodRef);
}
BPrinterRoster::~BPrinterRoster()
{
StopWatching();
}
int32
BPrinterRoster::CountPrinters()
{
Rewind();
int32 i = 0;
BPrinter printer;
while (GetNextPrinter(&printer) == B_OK)
i++;
Rewind();
return i;
}
status_t
BPrinterRoster::GetNextPrinter(BPrinter* printer)
{
if (!printer)
return B_BAD_VALUE;
status_t status = fUserPrintersDirectory.InitCheck();
if (!status == B_OK)
return status;
BEntry entry;
bool next = true;
while (status == B_OK && next) {
status = fUserPrintersDirectory.GetNextEntry(&entry);
if (status == B_OK) {
printer->SetTo(entry);
next = !printer->IsValid();
} else {
printer->Unset();
}
}
return status;
}
status_t
BPrinterRoster::GetDefaultPrinter(BPrinter* printer)
{
if (!printer)
return B_BAD_VALUE;
BDirectory dir(&fUserPrintersNodRef);
status_t status = dir.InitCheck();
if (!status == B_OK)
return status;
BEntry entry;
while (dir.GetNextEntry(&entry) == B_OK) {
if (!entry.IsDirectory())
continue;
printer->SetTo(entry);
if (printer->IsValid() && printer->IsDefault())
return B_OK;
}
printer->Unset();
return B_ERROR;
}
status_t
BPrinterRoster::FindPrinter(const BString& name, BPrinter* printer)
{
if (name.Length() <= 0 || !printer)
return B_BAD_VALUE;
BDirectory dir(&fUserPrintersNodRef);
status_t status = dir.InitCheck();
if (!status == B_OK)
return status;
BEntry entry;
while (dir.GetNextEntry(&entry) == B_OK) {
if (!entry.IsDirectory())
continue;
printer->SetTo(entry);
if (printer->IsValid() && printer->Name() == name)
return B_OK;
}
printer->Unset();
return B_ERROR;
}
status_t
BPrinterRoster::Rewind()
{
return fUserPrintersDirectory.Rewind();
}
status_t
BPrinterRoster::StartWatching(const BMessenger& listener)
{
StopWatching();
if (!listener.IsValid())
return B_BAD_VALUE;
fListener = new(std::nothrow) BMessenger(listener);
if (!fListener)
return B_NO_MEMORY;
return watch_node(&fUserPrintersNodRef, B_WATCH_DIRECTORY, *fListener);
}
void
BPrinterRoster::StopWatching()
{
if (fListener) {
stop_watching(*fListener);
delete fListener;
fListener = NULL;
}
}
} // namespace Print
} // namespace BPrivate