diff --git a/headers/private/print/JobSetupPanel.h b/headers/private/print/JobSetupPanel.h new file mode 100644 index 0000000000..31ed54f2f0 --- /dev/null +++ b/headers/private/print/JobSetupPanel.h @@ -0,0 +1,108 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, + + +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_ diff --git a/headers/private/print/PrintPanel.h b/headers/private/print/PrintPanel.h new file mode 100644 index 0000000000..97eae257e8 --- /dev/null +++ b/headers/private/print/PrintPanel.h @@ -0,0 +1,93 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, +#include +#include + + +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_ diff --git a/headers/private/print/Printer.h b/headers/private/print/Printer.h new file mode 100755 index 0000000000..f2f64a4a9b --- /dev/null +++ b/headers/private/print/Printer.h @@ -0,0 +1,83 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, +#include +#include +#include +#include +#include +#include + + +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_ diff --git a/headers/private/print/PrinterRoster.h b/headers/private/print/PrinterRoster.h new file mode 100644 index 0000000000..50a7061e01 --- /dev/null +++ b/headers/private/print/PrinterRoster.h @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, +#include +#include +#include + + +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_ diff --git a/src/kits/print/JobSetupPanel.cpp b/src/kits/print/JobSetupPanel.cpp new file mode 100644 index 0000000000..e1fe9d3900 --- /dev/null +++ b/src/kits/print/JobSetupPanel.cpp @@ -0,0 +1,375 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + + +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 diff --git a/src/kits/print/PrintPanel.cpp b/src/kits/print/PrintPanel.cpp new file mode 100644 index 0000000000..9395566fc8 --- /dev/null +++ b/src/kits/print/PrintPanel.cpp @@ -0,0 +1,277 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, + +#include +#include +#include +#include + + +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 (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 diff --git a/src/kits/print/Printer.cpp b/src/kits/print/Printer.cpp new file mode 100755 index 0000000000..bd1953623d --- /dev/null +++ b/src/kits/print/Printer.cpp @@ -0,0 +1,457 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, + +#include +#include +#include + + +#include + + +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 diff --git a/src/kits/print/PrinterRoster.cpp b/src/kits/print/PrinterRoster.cpp new file mode 100644 index 0000000000..88574fec54 --- /dev/null +++ b/src/kits/print/PrinterRoster.cpp @@ -0,0 +1,168 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun, + +#include +#include +#include +#include +#include + + +#include + + +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