Implemented preview printer driver.

Based on PDF Writer (thanks Philippe).
To do: share code with PDF Writer.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5036 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer
2003-10-14 17:06:50 +00:00
parent 869850df64
commit d9b3e69ea4
21 changed files with 4061 additions and 0 deletions
@@ -0,0 +1,144 @@
/*
PDF Writer printer driver.
Copyright (c) 2001 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 <stdio.h>
#include <string.h>
#include <StorageKit.h>
#include "Driver.h"
#include "PrinterDriver.h"
// --------------------------------------------------
BMessage*
take_job(BFile *spoolFile, BNode *spoolDir, BMessage *msg)
{
PrinterDriver *driver;
driver = instanciate_driver(spoolDir);
if (driver->PrintJob(spoolFile, msg) == B_OK) {
msg = new BMessage('okok');
} else {
msg = new BMessage('baad');
}
delete driver;
return msg;
}
// --------------------------------------------------
BMessage*
config_page(BNode *spoolDir, BMessage *msg)
{
BMessage *pagesetupMsg = new BMessage(*msg);
PrinterDriver *driver;
const char *printerName;
char buffer[B_ATTR_NAME_LENGTH+1];
// retrieve the printer (spool) name.
printerName = NULL;
if (spoolDir->ReadAttr("Printer Name", B_STRING_TYPE, 1, buffer, B_ATTR_NAME_LENGTH+1) > 0) {
printerName = buffer;
}
driver = instanciate_driver(spoolDir);
if (driver->PageSetup(pagesetupMsg, printerName) == B_OK) {
pagesetupMsg->what = 'okok';
} else {
delete pagesetupMsg;
pagesetupMsg = NULL;
}
delete driver;
return pagesetupMsg;
}
// --------------------------------------------------
BMessage*
config_job(BNode *spoolDir, BMessage *msg)
{
BMessage *jobsetupMsg = new BMessage(*msg);
PrinterDriver *driver;
const char *printerName;
char buffer[B_ATTR_NAME_LENGTH+1];
// retrieve the printer (spool) name.
printerName = NULL;
if (spoolDir->ReadAttr("Printer Name", B_STRING_TYPE, 1, buffer, B_ATTR_NAME_LENGTH+1) > 0) {
printerName = buffer;
}
driver = instanciate_driver(spoolDir);
if (driver->JobSetup(jobsetupMsg, printerName) == B_OK) {
jobsetupMsg->what = 'okok';
} else {
delete jobsetupMsg;
jobsetupMsg = NULL;
}
delete driver;
return jobsetupMsg;
}
// --------------------------------------------------
char*
add_printer(char *printerName)
{
PrinterDriver* driver;
driver = instanciate_driver(NULL);
if (driver->PrinterSetup(printerName) == B_OK) {
return printerName;
} else {
return NULL;
}
}
/**
* default_settings
*
* @param BNode* printer spool directory
* @return BMessage* the settings
*/
BMessage*
default_settings(BNode* spoolDir)
{
PrinterDriver* driver;
BMessage* settings;
driver = instanciate_driver(spoolDir);
settings = driver->GetDefaultSettings();
delete driver;
return settings;
}
@@ -0,0 +1,47 @@
/*
PDF Writer printer driver.
Copyright (c) 2002 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 <AppKit.h>
extern "C"
{
__declspec(dllexport) BMessage * take_job(BFile * spool_file, BNode * spool_dir, BMessage * msg);
__declspec(dllexport) BMessage * config_page(BNode * spool_dir, BMessage * msg);
__declspec(dllexport) BMessage * config_job(BNode * spool_dir, BMessage * msg);
__declspec(dllexport) char * add_printer(char * printer_name);
__declspec(dllexport) BMessage * default_settings(BNode * printer);
}
class PrinterDriver;
// instanciate_driver has to be implemented by the printer driver
PrinterDriver *instanciate_driver(BNode *spoolDir);
@@ -0,0 +1,19 @@
extern "C" _EXPORT char * add_printer(char * printer_name) {
return printer_name;
}
extern "C" _EXPORT BMessage * config_page(BNode * spool_dir, BMessage * msg) {
return NULL;
}
extern "C" _EXPORT BMessage * config_job(BNode * spool_dir, BMessage * msg) {
return NULL;
}
extern "C" _EXPORT BMessage * default_settings(BNode * printer) {
return NULL;
}
extern "C" _EXPORT BMessage * take_job(BFile * spool_file, BNode * spool_dir, BMessage * msg) {
return NULL;
}
@@ -0,0 +1,341 @@
/*
InterfaceUtils.cpp
Copyright (c) 2002 OpenBeOS.
Author:
Michael Pfeiffer
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 <string.h>
#include <Debug.h>
#include "InterfaceUtils.h"
#include "Utils.h"
// Implementation of HWindow
// --------------------------------------------------
HWindow::HWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace, uint32 escape_msg)
: BWindow(frame, title, type, flags, workspace)
{
Init(escape_msg);
}
// --------------------------------------------------
HWindow::HWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace, uint32 escape_msg)
: BWindow(frame, title, look, feel, flags, workspace)
{
Init(escape_msg);
}
// --------------------------------------------------
void
HWindow::Init(uint32 escape_msg)
{
AddShortcut('i', 0, new BMessage(B_ABOUT_REQUESTED));
AddCommonFilter(new EscapeMessageFilter(this, escape_msg));
}
// --------------------------------------------------
void
HWindow::MessageReceived(BMessage* msg)
{
if (msg->what == B_ABOUT_REQUESTED) {
AboutRequested();
} else {
inherited::MessageReceived(msg);
}
}
// --------------------------------------------------
void
HWindow::AboutRequested()
{
BAlert *about = new BAlert("About Preview", kAbout, "Cool");
BTextView *v = about->TextView();
if (v) {
rgb_color red = {255, 0, 51, 255};
rgb_color blue = {0, 102, 255, 255};
v->SetStylable(true);
char *text = (char*)v->Text();
char *s = text;
// set all Be in blue and red
while ((s = strstr(s, "Be")) != NULL) {
int32 i = s - text;
v->SetFontAndColor(i, i+1, NULL, 0, &blue);
v->SetFontAndColor(i+1, i+2, NULL, 0, &red);
s += 2;
}
// first text line
s = strchr(text, '\n');
BFont font;
v->GetFontAndColor(0, &font);
font.SetSize(12); // font.SetFace(B_OUTLINED_FACE);
v->SetFontAndColor(0, s-text+1, &font, B_FONT_SIZE);
};
about->Go();
}
// Implementation of BlockingWindow
BlockingWindow::BlockingWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace, uint32 escape_msg)
: HWindow(frame, title, type, flags, workspace)
{
Init(title);
}
BlockingWindow::BlockingWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace, uint32 escape_msg)
: HWindow(frame, title, look, feel, flags, workspace)
{
Init(title);
}
BlockingWindow::~BlockingWindow()
{
delete_sem(fExitSem);
}
void
BlockingWindow::Init(const char* title)
{
fResult = NULL;
fExitSem = create_sem(0, title);
fReadyToQuit = false;
}
bool
BlockingWindow::QuitRequested() {
if (fReadyToQuit) {
return true;
} else {
release_sem(fExitSem);
return false;
}
}
void
BlockingWindow::Quit() {
fReadyToQuit = false; // finally allow window to quit
inherited::Quit(); // and quit it
}
void
BlockingWindow::Quit(status_t result) {
if (fResult) {
*fResult = result;
}
release_sem(fExitSem);
}
status_t
BlockingWindow::Go() {
status_t result = B_ERROR;
fResult = &result;
Show();
acquire_sem(fExitSem);
// here the window still exists, because QuitRequested returns false if fReadyToQuit is false
// now we can quit the window and am sure that the window thread dies before this thread
if (Lock()) {
Quit();
} else {
ASSERT(false); // should not reach here!!!
}
// here the window does not exist, good to have the result in a local variable
return result;
}
// Impelementation of TextView
// --------------------------------------------------
TextView::TextView(BRect frame,
const char *name,
BRect textRect,
uint32 rmask,
uint32 flags)
: BTextView(frame, name, textRect, rmask, flags)
{
}
// --------------------------------------------------
TextView::TextView(BRect frame,
const char *name,
BRect textRect,
const BFont *font, const rgb_color *color,
uint32 rmask,
uint32 flags)
: BTextView(frame, name, textRect, font, color, rmask, flags)
{
}
// --------------------------------------------------
void
TextView::KeyDown(const char *bytes, int32 numBytes)
{
if (numBytes == 1 && *bytes == B_TAB) {
BView::KeyDown(bytes, numBytes);
return;
}
inherited::KeyDown(bytes, numBytes);
}
// --------------------------------------------------
void
TextView::Draw(BRect update)
{
inherited::Draw(update);
if (IsFocus()) {
// stroke focus rectangle
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
StrokeRect(Bounds());
}
}
// --------------------------------------------------
void
TextView::MakeFocus(bool focus)
{
Invalidate();
inherited::MakeFocus(focus);
// notify TextControl
BView* parent = Parent(); // BBox
if (focus && parent) {
parent = parent->Parent(); // TextControl
TextControl* control = dynamic_cast<TextControl*>(parent);
if (control) control->FocusSetTo(this);
}
}
// Impelementation of TextControl
// --------------------------------------------------
TextControl::TextControl(BRect frame,
const char *name,
const char *label,
const char *initial_text,
BMessage *message,
uint32 rmask,
uint32 flags)
: BView(frame, name, rmask, flags)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BRect r(0, 0, frame.Width() / 2 -1, frame.Height());
fLabel = new BStringView(r, "", label);
BRect f(r);
f.OffsetTo(frame.Width() / 2 + 1, 0);
// box around TextView
BBox *box = new BBox(f, "", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
f.OffsetTo(0, 0);
f.InsetBy(1,1);
r.InsetBy(2,2);
fText = new TextView(f, "", r, rmask, flags | B_NAVIGABLE);
fText->SetWordWrap(false);
fText->DisallowChar('\n');
fText->Insert(initial_text);
AddChild(fLabel);
AddChild(box);
box->AddChild(fText);
}
// --------------------------------------------------
void
TextControl::ConvertToParent(BView* parent, BView* child, BRect &rect)
{
do {
child->ConvertToParent(&rect);
child = child->Parent();
} while (child != NULL && child != parent);
}
// --------------------------------------------------
void
TextControl::FocusSetTo(BView *child)
{
BRect r;
BView* parent = Parent(); // Table
if (parent) {
ConvertToParent(parent, child, r);
parent->ScrollTo(0, r.top);
}
}
// Impelementation of Implementation of Table
// --------------------------------------------------
Table::Table(BRect frame, const char *name, uint32 rmode, uint32 flags)
: BView(frame, name, rmode, flags)
{
}
// --------------------------------------------------
void
Table::ScrollTo(BPoint p)
{
float h = Frame().Height()+1;
if (Parent()) {
BScrollView* scrollView = dynamic_cast<BScrollView*>(Parent());
if (scrollView) {
BScrollBar *sb = scrollView->ScrollBar(B_VERTICAL);
float min, max;
sb->GetRange(&min, &max);
if (p.y < (h/2)) p.y = 0;
else if (p.y > max) p.y = max;
}
}
inherited::ScrollTo(p);
}
// Impelementation of DragListView
// --------------------------------------------------
DragListView::DragListView(BRect frame, const char *name,
list_view_type type,
uint32 resizingMode, uint32 flags)
: BListView(frame, name, type, resizingMode, flags)
{
}
// --------------------------------------------------
bool DragListView::InitiateDrag(BPoint point, int32 index, bool wasSelected)
{
BMessage m;
DragMessage(&m, ItemFrame(index), this);
return true;
}
@@ -0,0 +1,147 @@
/*
InterfaceUtils.cpp
Copyright (c) 2002 OpenBeOS.
Author:
Michael Pfeiffer
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 _INTERFACE_UTILS_H
#define _INTERFACE_UTILS_H
#include <InterfaceKit.h>
// Text to be displayed in About window, declared in the application
// that uses HWindow class!!!
extern const char* kAbout;
// --------------------------------------------------
class HWindow : public BWindow
{
protected:
void Init(uint32 escape_msg);
public:
typedef BWindow inherited;
HWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace = B_CURRENT_WORKSPACE, uint32 escape_msg = B_QUIT_REQUESTED);
HWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace = B_CURRENT_WORKSPACE, uint32 escape_msg = B_QUIT_REQUESTED);
virtual void MessageReceived(BMessage* m);
virtual void AboutRequested();
};
// --------------------------------------------------
class BlockingWindow : public HWindow
{
public:
BlockingWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace = B_CURRENT_WORKSPACE, uint32 escape_msg = B_QUIT_REQUESTED);
BlockingWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace = B_CURRENT_WORKSPACE, uint32 escape_msg = B_QUIT_REQUESTED);
~BlockingWindow();
bool QuitRequested();
// Quit() is called by child class with result code
void Quit(status_t result);
// Show window and wait for it to quit, returns result code
status_t Go();
// Or quit window e.g. something went wrong in constructor
void Quit();
typedef HWindow inherited;
private:
void Init(const char* title);
bool fReadyToQuit;
sem_id fExitSem;
status_t* fResult;
};
// --------------------------------------------------
class TextView : public BTextView
{
public:
typedef BTextView inherited;
TextView(BRect frame,
const char *name,
BRect textRect,
uint32 rmask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW | B_NAVIGABLE);
TextView(BRect frame,
const char *name,
BRect textRect,
const BFont *font, const rgb_color *color,
uint32 rmask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW | B_NAVIGABLE);
void KeyDown(const char *bytes, int32 numBytes);
void MakeFocus(bool focus = true);
void Draw(BRect r);
};
// --------------------------------------------------
class TextControl : public BView
{
BStringView *fLabel;
TextView *fText;
public:
TextControl(BRect frame,
const char *name,
const char *label,
const char *initial_text,
BMessage *message,
uint32 rmask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW | B_NAVIGABLE);
const char *Label() { return fLabel->Text(); }
const char *Text() { return fText->Text(); }
void MakeFocus(bool focus = true) { fText->MakeFocus(focus); }
void ConvertToParent(BView* parent, BView* child, BRect &rect);
void FocusSetTo(BView* child);
};
// --------------------------------------------------
class Table : public BView
{
public:
typedef BView inherited;
Table(BRect frame, const char *name, uint32 rmode, uint32 flags);
void ScrollTo(BPoint p);
};
class DragListView : public BListView
{
public:
DragListView(BRect frame, const char *name,
list_view_type type = B_SINGLE_SELECTION_LIST,
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS);
bool InitiateDrag(BPoint point, int32 index, bool wasSelected);
};
#endif
+20
View File
@@ -0,0 +1,20 @@
SubDir OBOS_TOP src add-ons print drivers preview ;
UsePrivateHeaders interface print ;
AddResources Preview : Preview.rsrc ;
Addon Preview : print :
Utils.cpp
InterfaceUtils.cpp
MarginView.cpp
PrinterSetupWindow.cpp
PageSetupWindow.cpp
JobSetupWindow.cpp
Driver.cpp
PrinterDriver.cpp
Preview.cpp
;
LinkSharedOSLibs Preview : be root libprint.a ;
@@ -0,0 +1,276 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 <InterfaceKit.h>
#include <SupportKit.h>
#include <stdlib.h>
#include "PrinterDriver.h"
#include "JobSetupWindow.h"
// --------------------------------------------------
JobSetupWindow::JobSetupWindow(BMessage *msg, const char * printerName)
: BlockingWindow(BRect(0, 0, 320, 160), "Job Setup", B_TITLED_WINDOW_LOOK,
B_MODAL_APP_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_MINIMIZABLE |
B_NOT_ZOOMABLE)
{
MoveTo(300, 300);
fSetupMsg = msg;
if (printerName) {
BString title;
title << printerName << " Job Setup";
SetTitle(title.String());
fPrinterName = printerName;
}
// ---- Ok, build a default job setup user interface
BRect r;
BBox *panel;
BBox *line;
BButton *ok;
BButton *cancel;
BStringView *sv;
float x, y, w, h;
float indent;
int32 copies;
int32 firstPage;
int32 lastPage;
bool allPages;
char buffer[80];
// PrinterDriver ensures that property exists
fSetupMsg->FindInt32("copies", &copies);
fSetupMsg->FindInt32("first_page", &firstPage);
fSetupMsg->FindInt32("last_page", &lastPage);
allPages = firstPage == 1 && lastPage == MAX_INT32;
r = Bounds();
// add a *dialog* background
panel = new BBox(r, "top_panel", B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
B_PLAIN_BORDER);
const int kMargin = 6;
//const char *kCopiesLabel = "Copies:";
const char *kCopiesLabelExtraSpace = "Copies:##";
const char *kPagesRangeLabel = "Pages:";
const char *kAllPagesLabel = "All";
const char *kPagesRangeSelectionLabel = "";
const char *kFromLabel = "From:";
const char *kFromLabelExtraSpace = "From:##";
const char *kToLabel = "To:";
const char *kToLabelExtraSpace = "To:##";
r = panel->Bounds();
x = r.left + kMargin;
y = r.top + kMargin;
// add a "copies" input field
/* Simon: temporarily removed this code
sprintf(buffer, "%d", (int)copies);
fCopies = new BTextControl(BRect(x, y, x+100, y+20), "copies", kCopiesLabel,
buffer, new BMessage(NB_COPIES_MSG));
fCopies->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT);
fCopies->ResizeToPreferred();
fCopies->GetPreferredSize(&w, &h);
panel->AddChild(fCopies);
y += h + kMargin; // "new line"
*/
// add a "pages" label
sv = new BStringView(BRect(x, y, x+100, y+20), "pages_range", kPagesRangeLabel);
panel->AddChild(sv);
sv->ResizeToPreferred();
sv->GetPreferredSize(&w, &h);
// align "copies" textcontrol field on the "allPages" radiobutton bellow...
indent = be_plain_font->StringWidth(kCopiesLabelExtraSpace);
w += kMargin;
if ( w > indent )
indent = w;
// fCopies->SetDivider(indent);
x += indent;
// add a "all" radiobutton
fAll = new BRadioButton(BRect(x, y, x+100, y+20), "all_pages", kAllPagesLabel,
new BMessage(ALL_PAGES_MGS));
fAll->ResizeToPreferred();
fAll->GetPreferredSize(&w, &h);
fAll->SetValue(allPages);
panel->AddChild(fAll);
y += h + kMargin; // "new line"
// add a range selection raddiobutton
fRange = new BRadioButton(BRect(x, y, x+100, y+20), "pages_range_selection", kPagesRangeSelectionLabel,
new BMessage(RANGE_SELECTION_MSG));
fRange->ResizeToPreferred();
fRange->GetPreferredSize(&w, &h);
fRange->SetValue(!allPages);
panel->AddChild(fRange);
x += w + kMargin;
// add a "from" field
if (allPages) {
buffer[0] = 0;
} else {
sprintf(buffer, "%d", (int)firstPage);
}
fFrom = new BTextControl(BRect(x, y, x+100, y+20), "from_field", kFromLabel, buffer,
new BMessage(RANGE_FROM_MSG));
fFrom->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT);
fFrom->SetDivider(be_plain_font->StringWidth(kFromLabelExtraSpace));
fFrom->ResizeToPreferred();
fFrom->GetPreferredSize(&w, &h);
panel->AddChild(fFrom);
x += w + kMargin;
// add a "to" field
if (allPages) {
buffer[0] = 0;
} else {
sprintf(buffer, "%d", (int)lastPage);
}
fTo = new BTextControl(BRect(x, y, x+100, y+20), "to_field", kToLabel, buffer,
new BMessage(RANGE_TO_MSG));
fTo->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT);
fTo->SetDivider(be_plain_font->StringWidth(kToLabelExtraSpace));
fTo->ResizeToPreferred();
fTo->GetPreferredSize(&w, &h);
panel->AddChild(fTo);
y += h + kMargin + kMargin; // "new line"
x = r.left + kMargin;
// add a separator line...
line = new BBox(BRect(r.left, y - 1, r.right, y), NULL,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
panel->AddChild(line);
y += 2 + kMargin + kMargin; // "new line"
// add a "OK" button, and make it default
ok = new BButton(BRect(x, y, x+100, y+20), NULL, "OK", new BMessage(OK_MSG), B_FOLLOW_RIGHT | B_FOLLOW_TOP);
ok->MakeDefault(true);
ok->ResizeToPreferred();
ok->GetPreferredSize(&w, &h);
x = r.right - w - kMargin;
ok->MoveTo(x, ok->Frame().top); // put the ok bottom at bottom right corner
panel->AddChild(ok);
// add a "Cancel" button
cancel = new BButton(BRect(x, y, x + 100, y + 20), NULL, "Cancel", new BMessage(CANCEL_MSG), B_FOLLOW_RIGHT | B_FOLLOW_TOP);
cancel->ResizeToPreferred();
cancel->GetPreferredSize(&w, &h);
cancel->MoveTo(x - w - kMargin, y); // put cancel button left next the ok button
panel->AddChild(cancel);
// Finally, add our panel to window
AddChild(panel);
// Auto resize window
ResizeTo(ok->Frame().right + kMargin, ok->Frame().bottom + kMargin);
}
// --------------------------------------------------
void
JobSetupWindow::UpdateJobMessage()
{
int32 copies = 1;
int32 from;
int32 to;
if (fAll->Value() == B_CONTROL_ON) {
from = 1; to = MAX_INT32;
} else {
from = atoi(fFrom->Text());
to = atoi(fTo->Text());
if (from <= 0) from = 1;
if (to < from) to = from;
}
if (fSetupMsg->HasInt32("copies")) {
fSetupMsg->ReplaceInt32("copies", copies);
} else {
fSetupMsg->AddInt32("copies", copies);
}
if (fSetupMsg->HasInt32("first_page")) {
fSetupMsg->ReplaceInt32("first_page", from);
} else {
fSetupMsg->AddInt32("first_page", from);
}
if (fSetupMsg->HasInt32("last_page")) {
fSetupMsg->ReplaceInt32("last_page", to);
} else {
fSetupMsg->AddInt32("last_page", to);
}
}
// --------------------------------------------------
void
JobSetupWindow::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case OK_MSG:
UpdateJobMessage();
Quit(B_OK);
break;
case CANCEL_MSG:
Quit(B_ERROR);
break;
case RANGE_FROM_MSG:
case RANGE_TO_MSG:
fRange->SetValue(B_CONTROL_ON);
break;
default:
inherited::MessageReceived(msg);
break;
}
}
@@ -0,0 +1,76 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 JOBSETUPWINDOW_H
#define JOBSETUPWINDOW_H
#include <InterfaceKit.h>
#include "InterfaceUtils.h"
#include "Utils.h"
class JobSetupWindow : public BlockingWindow
{
public:
// Constructors, destructors, operators...
JobSetupWindow(BMessage *msg, const char *printer_name = NULL);
typedef BlockingWindow inherited;
// public constantes
enum {
NB_COPIES_MSG = 'copy',
ALL_PAGES_MGS = 'all_',
RANGE_SELECTION_MSG = 'rnge',
RANGE_FROM_MSG = 'from',
RANGE_TO_MSG = 'to__',
OK_MSG = 'ok__',
CANCEL_MSG = 'cncl',
};
// Virtual function overrides
public:
virtual void MessageReceived(BMessage *msg);
// From here, it's none of your business! ;-)
private:
BString fPrinterName;
BMessage *fSetupMsg;
BRadioButton *fAll;
BRadioButton *fRange;
BTextControl *fFrom;
BTextControl *fTo;
void UpdateJobMessage();
};
#endif
@@ -0,0 +1,694 @@
/*
MarginView.cpp
Copyright (c) 2002 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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.
Todo:
2 Make Strings constants or UI resources
*/
#ifndef MARGIN_VIEW_H
#include "MarginView.h"
#endif
#include <AppKit.h>
#include <SupportKit.h>
#include <stdio.h>
#include <stdlib.h>
/*----------------- MarginView Private Constants --------------------*/
const int Y_OFFSET = 20;
const int X_OFFSET = 10;
const int STRING_SIZE = 50;
const int _WIDTH = 50;
const int NUM_COUNT = 10;
const static float _pointUnits = 1; // 1 point = 1 point
const static float _inchUnits = 72; // 1" = 72 points
const static float _cmUnits = 28.346; // 72/2.54 1cm = 28.346 points
const static float _minFieldWidth = 100; // pixels
const static float _minUnitHeight = 30; // pixels
const static float _drawInset = 10; // pixels
const static float unitFormat[] = { _inchUnits, _cmUnits, _pointUnits };
const static char *unitNames[] = { "Inch", "cm", "Points", NULL };
const static uint32 unitMsg[] = { MarginView::UNIT_INCH,
MarginView::UNIT_CM,
MarginView::UNIT_POINT };
const pattern dots = {{ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }};
const rgb_color black = { 0,0,0,0 };
const rgb_color red = { 255,0,0,0 };
const rgb_color white = { 255,255,255,0 };
const rgb_color gray = { 220,220,220,0 };
/*----------------- MarginView Public Methods --------------------*/
/**
* Constructor
*
* @param frame, BRect that is the size of the view passed to the superclase
* @param pageWidth, float that is the points value of the page width
* @param pageHeight, float that is the points value of the page height
* @param margins, BRect values of margins
* @param units, unit32 enum for units used in view
* @return void
*/
MarginView::MarginView(BRect frame,
int32 pageWidth,
int32 pageHeight,
BRect margins,
uint32 units)
:BBox(frame, NULL, B_FOLLOW_ALL)
{
fUnits = units;
fUnitValue = unitFormat[units];
SetLabel("Margins");
fMaxPageHeight = frame.Height() - _minUnitHeight - Y_OFFSET;
fMaxPageWidth = frame.Width() - _minFieldWidth - X_OFFSET;
fMargins = margins;
fPageWidth = pageWidth;
fPageHeight = pageHeight;
}
/**
* Destructor
*
* @param none
* @return void
*/
MarginView::~MarginView() {
}
/*----------------- MarginView Public BeOS Hook Methods --------------------*/
/**
* Draw
*
* @param BRect, the draw bounds
* @return void
*/
void MarginView::Draw(BRect rect)
{
BBox::Draw(rect);
float y_offset = (float)Y_OFFSET;
float x_offset = (float)X_OFFSET;
BRect r;
// Calculate offsets depending on orientation
if (fPageWidth < fPageHeight) { // Portrait
x_offset = (fMaxPageWidth/2 + X_OFFSET) - fViewWidth/2;
} else { // landscape
y_offset = (fMaxPageHeight/2 + Y_OFFSET) - fViewHeight/2;
}
// draw the page
SetHighColor(white);
r = BRect(0, 0, fViewWidth, fViewHeight);
r.OffsetBy(x_offset, y_offset);
FillRect(r);
SetHighColor(black);
StrokeRect(r);
// draw margin
SetHighColor(red);
SetLowColor(white);
r.top += fMargins.top;
r.right -= fMargins.right;
r.bottom -= fMargins.bottom;
r.left += fMargins.left;
StrokeRect(r, dots);
// draw the page size label
SetHighColor(black);
SetLowColor(gray);
char str[STRING_SIZE];
sprintf(str, "%2.1f x %2.1f", fPageWidth/fUnitValue, fPageHeight/fUnitValue);
SetFontSize(10);
DrawString((const char *)str, BPoint(x_offset, fMaxPageHeight + 40));
}
/**
* BeOS Hook Function, change the size of the margin display
*
* @param width of the page
* @param height the page
* @return void
*/
void MarginView::FrameResized(float width, float height)
{
fMaxPageHeight = height - _minUnitHeight - X_OFFSET;
fMaxPageWidth = width - _minFieldWidth - Y_OFFSET;
CalculateViewSize(MARGIN_CHANGED);
Invalidate();
}
/**
* AttachToWindow
*
* @param none
* @return void
*/
void MarginView::AttachedToWindow()
{
if (Parent()) {
SetViewColor(Parent()->ViewColor());
}
ConstructGUI();
}
/*----------------- MarginView Public Methods --------------------*/
/**
* GetUnits
*
* @param none
* @return uint32 enum, units in inches, cm, points
*/
uint32 MarginView::GetUnits(void) {
return fUnits;
}
/**
* UpdateView, recalculate and redraw the view
*
* @param msg is a message to the calculate size to tell which field caused
* the update to occur, or it is a general update.
* @return void
*/
void MarginView::UpdateView(uint32 msg)
{
Window()->Lock();
CalculateViewSize(msg);
Invalidate();
Window()->Unlock();
}
/**
* SetPageSize
*
* @param pageWidth, float that is the unit value of the page width
* @param pageHeight, float that is the unit value of the page height
* @return void
*/
void MarginView::SetPageSize(float pageWidth, float pageHeight)
{
fPageWidth = pageWidth;
fPageHeight = pageHeight;
}
/**
* GetPageSize
*
* @param none
* @return BPoint, contains actual point values of page in x, y of point
*/
BPoint MarginView::GetPageSize(void) {
return BPoint(fPageWidth, fPageHeight);
}
/**
* GetMargin
*
* @param none
* @return rect, return margin values always in points
*/
BRect MarginView::GetMargin(void)
{
BRect margin;
// convert the field text to values
float ftop = atof(fTop->Text());
float fright = atof(fRight->Text());
float fleft = atof(fLeft->Text());
float fbottom = atof(fBottom->Text());
// convert to units to points
switch (fUnits)
{
case UNIT_INCH:
// convert to points
ftop *= _inchUnits;
fright *= _inchUnits;
fleft *= _inchUnits;
fbottom *= _inchUnits;
break;
case UNIT_CM:
// convert to points
ftop *= _cmUnits;
fright *= _cmUnits;
fleft *= _cmUnits;
fbottom *= _cmUnits;
break;
}
margin.Set(fleft, ftop, fright, fbottom);
return margin;
}
/**
* MesssageReceived()
*
* Receive messages for the view
*
* @param BMessage* , the message being received
* @return void
*/
void MarginView::MessageReceived(BMessage *msg)
{
switch (msg->what)
{
case CHANGE_PAGE_SIZE: {
float w;
float h;
msg->FindFloat("width", &w);
msg->FindFloat("height", &h);
SetPageSize(w, h);
UpdateView(MARGIN_CHANGED);
}
break;
case FLIP_PAGE: {
BPoint p;
p = GetPageSize();
SetPageSize(p.y, p.x);
UpdateView(MARGIN_CHANGED);
}
break;
case MARGIN_CHANGED:
UpdateView(MARGIN_CHANGED);
break;
case TOP_MARGIN_CHANGED:
UpdateView(TOP_MARGIN_CHANGED);
break;
case LEFT_MARGIN_CHANGED:
UpdateView(LEFT_MARGIN_CHANGED);
break;
case RIGHT_MARGIN_CHANGED:
UpdateView(RIGHT_MARGIN_CHANGED);
break;
case BOTTOM_MARGIN_CHANGED:
UpdateView(BOTTOM_MARGIN_CHANGED);
break;
case UNIT_INCH:
case UNIT_CM:
case UNIT_POINT:
SetUnits(msg->what);
break;
default:
BView::MessageReceived(msg);
break;
}
}
/*----------------- MarginView Private Methods --------------------*/
/**
* ConstructGUI()
*
* Creates the GUI for the View. MUST be called AFTER the View is attached to
* the Window, or will crash and/or create strange behaviour
*
* @param none
* @return void
*/
void MarginView::ConstructGUI()
{
BMessage *msg;
BString str;
BMenuItem *item;
BMenuField *mf;
BPopUpMenu *menu;
// Create text fields
msg = new BMessage(MARGIN_CHANGED);
BRect r(Frame().Width() - be_plain_font->StringWidth("Top#") - _WIDTH,
Y_OFFSET, Frame().Width() - X_OFFSET, _WIDTH);
// top
msg = new BMessage(TOP_MARGIN_CHANGED);
str << fMargins.top/fUnitValue;
fTop = new BTextControl( r, "top", "Top", str.String(), msg,
B_FOLLOW_RIGHT);
fTop->SetDivider(be_plain_font->StringWidth("Top#"));
fTop->SetTarget(this);
AllowOnlyNumbers(fTop, NUM_COUNT);
AddChild(fTop);
//left
r.OffsetBy(0, Y_OFFSET);
r.left = Frame().Width() - be_plain_font->StringWidth("Left#") - _WIDTH;
str = "";
str << fMargins.left/fUnitValue;
msg = new BMessage(LEFT_MARGIN_CHANGED);
fLeft = new BTextControl( r, "left", "Left", str.String(), msg,
B_FOLLOW_RIGHT);
fLeft->SetDivider(be_plain_font->StringWidth("Left#"));
fLeft->SetTarget(this);
AllowOnlyNumbers(fLeft, NUM_COUNT);
AddChild(fLeft);
//bottom
r.OffsetBy(0, Y_OFFSET);
r.left = Frame().Width() - be_plain_font->StringWidth("Bottom#") - _WIDTH;
str = "";
str << fMargins.bottom/fUnitValue;
msg = new BMessage(BOTTOM_MARGIN_CHANGED);
fBottom = new BTextControl( r, "bottom", "Bottom", str.String(), msg,
B_FOLLOW_RIGHT);
fBottom->SetDivider(be_plain_font->StringWidth("Bottom#"));
fBottom->SetTarget(this);
AllowOnlyNumbers(fBottom, NUM_COUNT);
AddChild(fBottom);
//right
r.OffsetBy(0, Y_OFFSET);
r.left = Frame().Width() - be_plain_font->StringWidth("Right#") - _WIDTH;
str = "";
str << fMargins.right/fUnitValue;
msg = new BMessage(RIGHT_MARGIN_CHANGED);
fRight = new BTextControl( r, "right", "Right", str.String(), msg,
B_FOLLOW_RIGHT);
fRight->SetDivider(be_plain_font->StringWidth("Right#"));
fRight->SetTarget(this);
AllowOnlyNumbers(fRight, NUM_COUNT);
AddChild(fRight);
// Create Units popup
r.OffsetBy(-X_OFFSET,Y_OFFSET);
r.right += Y_OFFSET;
menu = new BPopUpMenu("units");
mf = new BMenuField(r, "units", "Units", menu,
B_FOLLOW_BOTTOM|B_FOLLOW_RIGHT|B_WILL_DRAW);
mf->ResizeToPreferred();
mf->SetDivider(be_plain_font->StringWidth("Units#"));
// Construct menu items
for (int i=0; unitNames[i] != NULL; i++ )
{
msg = new BMessage(unitMsg[i]);
menu->AddItem(item = new BMenuItem(unitNames[i], msg));
item->SetTarget(this);
if (fUnits == unitMsg[i]) {
item->SetMarked(true);
}
}
AddChild(mf);
// calculate the sizes for drawing page view
CalculateViewSize(MARGIN_CHANGED);
}
/**
* AllowOnlyNumbers()
*
* @param BTextControl, the control we want to only allow numbers
* @param maxNum, the maximun number of characters allowed
* @return void
*/
void MarginView::AllowOnlyNumbers(BTextControl *textControl, int maxNum)
{
BTextView *tv = textControl->TextView();
for (long i = 0; i < 256; i++) {
tv->DisallowChar(i);
}
for (long i = '0'; i <= '9'; i++) {
tv->AllowChar(i);
}
tv->AllowChar(B_BACKSPACE);
tv->AllowChar('.');
tv->SetMaxBytes(maxNum);
}
/**
* SetMargin
*
* @param brect, margin values in rect
* @return void
*/
void MarginView::SetMargin(BRect margin) {
fMargins = margin;
}
/**
* SetUnits, called by the MarginMgr when the units popup is selected
*
* @param uint32, the enum that identifies the units requested to change to.
* @return void
*/
void MarginView::SetUnits(uint32 unit)
{
// do nothing if the current units are the same as requested
if (unit == fUnits) {
return;
}
// set the units Format
fUnitValue = unitFormat[unit];
// convert the field text to values
float ftop = atof(fTop->Text());
float fright = atof(fRight->Text());
float fleft = atof(fLeft->Text());
float fbottom = atof(fBottom->Text());
// convert to target units
switch (fUnits)
{
case UNIT_INCH:
// convert to points
ftop *= _inchUnits;
fright *= _inchUnits;
fleft *= _inchUnits;
fbottom *= _inchUnits;
// check for target unit is cm
if (unit == UNIT_CM) {
ftop /= _cmUnits;
fright /= _cmUnits;
fleft /= _cmUnits;
fbottom /= _cmUnits;
}
break;
case UNIT_CM:
// convert to points
ftop *= _cmUnits;
fright *= _cmUnits;
fleft *= _cmUnits;
fbottom *= _cmUnits;
// check for target unit is inches
if (unit == UNIT_INCH) {
ftop /= _inchUnits;
fright /= _inchUnits;
fleft /= _inchUnits;
fbottom /= _inchUnits;
}
break;
case UNIT_POINT:
// check for target unit is cm
if (unit == UNIT_CM) {
ftop /= _cmUnits;
fright /= _cmUnits;
fleft /= _cmUnits;
fbottom /= _cmUnits;
}
// check for target unit is inches
if (unit == UNIT_INCH) {
ftop /= _inchUnits;
fright /= _inchUnits;
fleft /= _inchUnits;
fbottom /= _inchUnits;
}
break;
}
fUnits = unit;
// lock Window since these changes are from another thread
Window()->Lock();
// set the fields to new units
BString str;
str << ftop;
fTop->SetText(str.String());
str = "";
str << fleft;
fLeft->SetText(str.String());
str = "";
str << fright;
fRight->SetText(str.String());
str = "";
str << fbottom;
fBottom->SetText(str.String());
// update UI
CalculateViewSize(MARGIN_CHANGED);
Invalidate();
Window()->Unlock();
}
/**
* CalculateViewSize
*
* calculate the size of the view that is used
* to show the page inside the margin box. This is dependent
* on the size of the box and the room we have to show it and
* the units that we are using and the orientation of the page.
*
* @param msg, the message for which field changed to check value bounds
* @return void
*/
void MarginView::CalculateViewSize(uint32 msg)
{
// determine page orientation
if (fPageHeight < fPageWidth) { // LANDSCAPE
fViewWidth = fMaxPageWidth;
fViewHeight = fPageHeight * (fViewWidth/fPageWidth);
float hdiff = fViewHeight - fMaxPageHeight;
if (hdiff > 0) {
fViewHeight -= hdiff;
fViewWidth -= hdiff;
}
} else { // PORTRAIT
fViewHeight = fMaxPageHeight;
fViewWidth = fPageWidth * (fViewHeight/fPageHeight);
float wdiff = fViewWidth - fMaxPageWidth;
if (wdiff > 0) {
fViewHeight -= wdiff;
fViewWidth -= wdiff;
}
}
// calculate margins based on view size
// find the length of 1 pixel in points
// ex: 80px/800pt = 0.1px/pt
float pixelLength = fViewHeight/fPageHeight;
// convert the margins to points
// The text field will have a number that us in the current unit
// ex 0.2" * 72pt = 14.4pts
float ftop = atof(fTop->Text()) * fUnitValue;
float fright = atof(fRight->Text()) * fUnitValue;
float fbottom = atof(fBottom->Text()) * fUnitValue;
float fleft = atof(fLeft->Text()) * fUnitValue;
// Check that the margins don't overlap each other...
float ph = fPageHeight;
float pw = fPageWidth;
BString str;
// Bounds calculation rules:
if (msg == TOP_MARGIN_CHANGED)
{
// top must be <= bottom
if (ftop > (ph - fbottom)) {
ftop = ph - fbottom;
str = "";
str << ftop / fUnitValue;
Window()->Lock();
fTop->SetText(str.String());
Window()->Unlock();
}
}
if (msg == BOTTOM_MARGIN_CHANGED)
{
// bottom must be <= pageHeight
if (fbottom > (ph - ftop)) {
fbottom = ph - ftop;
str = "";
str << fbottom / fUnitValue;
Window()->Lock();
fBottom->SetText(str.String());
Window()->Unlock();
}
}
if (msg == LEFT_MARGIN_CHANGED)
{
// left must be <= right
if (fleft > (pw - fright)) {
fleft = pw - fright;
str = "";
str << fleft / fUnitValue;
Window()->Lock();
fLeft->SetText(str.String());
Window()->Unlock();
}
}
if (msg == RIGHT_MARGIN_CHANGED)
{
// right must be <= fPageWidth
if (fright > (pw - fleft)) {
fright = pw - fleft;
str = "";
str << fright / fUnitValue;
Window()->Lock();
fRight->SetText(str.String());
Window()->Unlock();
}
}
// convert the unit value to pixels
// ex: 14.4pt * 0.1px/pt = 1.44px
fMargins.top = ftop * pixelLength;
fMargins.right = fright * pixelLength;
fMargins.bottom = fbottom * pixelLength;
fMargins.left = fleft * pixelLength;
}
@@ -0,0 +1,226 @@
/*
MarginView.h
Copyright (c) 2002 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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.
Documentation:
The MarginView is designed to be a self contained component that manages
the display of a BBox control that shows a graphic of a page and its'
margings. The component also includes text fields that are used to mofify
the margin values and a popup to change the units used for the margins.
There are two interfaces for the MarginView component:
1) Set methods:
- page size
- orientation
Get methods to retrieve:
- margins
- page size
The method interface is available for the parent Component to call on
the MarginView in response to the Window receiveing messages from
other BControls that it contains, such as a Page Size popup. The
Get methods are used to extract the page size and margins so that
the printer driver may put these values into a BMessage for printing.
2) 'Optional' Message interface:
- Set Page Size
- Flip Orientation
The message interface is available for GUI Controls, BPopupMenu to send
messages to the MarginView if the parent Window is not used to handle
the messages.
General Use of MarginView component:
1) Simply construct a new MarginView object with the margins
you want as defaults and add this view to the parent view
of the dialog.
MarginView *mv;
mv = new MarginView(viewSizeRect, pageWidth, pageHeight);
parentView->AddChild(mv);
* you can also set the margins in the constructor, and the units:
mv = new MarginView(viewSizeRect, pageWidth, pageHeight
marginRect, UNIT_POINTS);
! but remeber to have the marginRect values match the UNITS :-)
2) Set Page Size with methods:
mv-SetPageSize( pageWidth, pageHeight );
mv->UpdateView();
3) Set Page Size with BMessage:
BMessage* msg = new BMessage(CHANGE_PAGE_SIZE);
msg->AddFloat("width", pageWidth);
msg->AddFloat("height", pageHeight);
mv->PostMessage(msg);
4) Flip Page with methods:
mv-SetPageSize( pageHeight, pageWidth );
mv->UpdateView();
5) Flip Page with BMessage:
BMessage* msg = new BMessage(FLIP_PAGE);
mv->Looper()->PostMessage(msg);
Note: the MarginView DOES NOT keep track of the orientation. This
should be done by the code for the Page setup dialog.
6) Get Page Size
BPoint pageSize = mv->GetPageSize();
7) Get Margins
BRect margins = mv->GetMargins();
8) Get Units
uint32 units = mv->GetUnits();
where units is one of:
UNIT_INCH, 72 points/in
UNIT_CM, 28.346 points/cm
UNIT_POINT, 1 point/point
*/
#ifndef MARGIN_VIEW_H
#define MARGIN_VIEW_H
#include <InterfaceKit.h>
#include <Looper.h>
class MarginManager;
// Messages that the MarginManager accepts
const uint32 TOP_MARGIN_CHANGED = 'tchg';
const uint32 RIGHT_MARGIN_CHANGED = 'rchg';
const uint32 LEFT_MARGIN_CHANGED = 'lchg';
const uint32 BOTTOM_MARGIN_CHANGED = 'bchg';
const uint32 MARGIN_CHANGED = 'mchg';
const uint32 CHANGE_PAGE_SIZE = 'chps';
const uint32 FLIP_PAGE = 'flip';
/**
* Class MarginView
*/
class MarginView : public BBox
{
friend MarginManager;
public:
// used to index unitFormat array
typedef enum {
UNIT_INCH = 0,
UNIT_CM,
UNIT_POINT
};
private:
// GUI components
BTextControl *fTop, *fBottom, *fLeft, *fRight;
// rect that holds the margins for the page as a set of point offsets
BRect fMargins;
// the maximum size of the page view calculated from the view size
float fMaxPageWidth;
float fMaxPageHeight;
// the actual size of the page in points
float fPageHeight;
float fPageWidth;
// the units used to calculate the page size
uint32 fUnits;
float fUnitValue;
// the size of the drawing area we have to draw the view in pixels
float fViewHeight;
float fViewWidth;
// Calculate the view size for the margins
void CalculateViewSize(uint32 msg);
// performed internally using the supplied popup
void SetUnits(uint32 unit);
// performed internally using text fields
void SetMargin(BRect margin);
// utility method
void AllowOnlyNumbers(BTextControl *textControl, int maxNum);
public:
MarginView(BRect rect,
int32 pageWidth = 0,
int32 pageHeight = 0,
BRect margins = BRect(1, 1, 1, 1), // default to 1 inch
uint32 units = UNIT_INCH);
~MarginView();
/// all the GUI construction code
void ConstructGUI();
// page size
void SetPageSize(float pageWidth, float pageHeight);
// point.x = width, point.y = height
BPoint GetPageSize(void);
// margin
BRect GetMargin(void);
// orientation
// None, this state should be saved elsewhere in the page setup code
// and not here. See the FLIP_PAGE message to perform this function.
// units
uint32 GetUnits(void);
// will cause a recalc and redraw
void UpdateView(uint32 msg);
// BeOS Hook methods
virtual void AttachedToWindow(void);
void Draw(BRect rect);
void FrameResized(float width, float height);
void MessageReceived(BMessage *msg);
};
#endif //MARGIN_VIEW_H
@@ -0,0 +1,379 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 <InterfaceKit.h>
#include <SupportKit.h>
#include "PrinterDriver.h"
#include "PageSetupWindow.h"
#include "MarginView.h"
// static global variables
static struct
{
char *label;
float width;
float height;
} pageFormat[] =
{
{"Letter", letter_width, letter_height },
{"Legal", legal_width, legal_height },
{"Ledger", ledger_width, ledger_height },
{"p11x17", p11x17_width, p11x17_height },
{"A0", a0_width, a0_height },
{"A1", a1_width, a1_height },
{"A2", a2_width, a2_height },
{"A3", a3_width, a3_height },
{"A4", a4_width, a4_height },
{"A5", a5_width, a5_height },
{"A6", a6_width, a6_height },
{"B5", b5_width, b5_height },
{NULL, 0.0, 0.0 }
};
static struct
{
char *label;
int32 orientation;
} orientation[] =
{
{"Portrait", PrinterDriver::PORTRAIT_ORIENTATION},
{"Landscape", PrinterDriver::LANDSCAPE_ORIENTATION},
{NULL, 0}
};
/**
* Constuctor
*
* @param
* @return
*/
PageSetupWindow::PageSetupWindow(BMessage *msg, const char *printerName)
: BlockingWindow(BRect(0,0,400,220), "Page Setup", B_TITLED_WINDOW_LOOK,
B_MODAL_APP_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_MINIMIZABLE |
B_NOT_ZOOMABLE)
{
MoveTo(300, 300);
fSetupMsg = msg;
if ( printerName ) {
BString title;
title << printerName << " Page Setup";
SetTitle( title.String() );
// save the printer name
fPrinterDirName = printerName;
}
// ---- Ok, build a default page setup user interface
BRect r(0, 0, letter_width, letter_height);
BBox *panel;
BButton *button;
float x, y, w, h;
int i;
BMenuItem *item;
float width, height;
int32 orient;
BRect page;
BRect margin(0,0,0,0);
int32 units = MarginView::UNIT_INCH;
BString setting_value;
// load orientation
fSetupMsg->FindInt32("orientation", &orient);
// (new BAlert("", "orientation not in msg", "Shit"))->Go();
// load page rect
fSetupMsg->FindRect("paper_rect", &r);
width = r.Width();
height = r.Height();
page = r;
// Load units
fSetupMsg->FindInt32("units", &units);
// add a *dialog* background
r = Bounds();
panel = new BBox(r, "top_panel", B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
B_PLAIN_BORDER);
////////////// Create the margin view //////////////////////
// re-calculate the margin from the printable rect in points
margin = page;
fSetupMsg->FindRect("printable_rect", &margin);
margin.top -= page.top;
margin.left -= page.left;
margin.right = page.right - margin.right;
margin.bottom = page.bottom - margin.bottom;
fMarginView = new MarginView(BRect(20,20,200,160), width, height,
margin, units);
panel->AddChild(fMarginView);
// add page format menu
// Simon Changed to OFFSET popups
x = r.left + kMargin * 2 + kOffset; y = r.top + kMargin * 2;
BPopUpMenu* m = new BPopUpMenu("page_size");
m->SetRadioMode(true);
// Simon changed width 200->140
BMenuField *mf = new BMenuField(BRect(x, y, x + 140, y + 20), "page_size",
"Page Size:", m);
fPageSizeMenu = mf;
mf->ResizeToPreferred();
mf->GetPreferredSize(&w, &h);
// Simon added: SetDivider
mf->SetDivider(be_plain_font->StringWidth("Page Size#"));
panel->AddChild(mf);
item = NULL;
for (i = 0; pageFormat[i].label != NULL; i++)
{
BMessage* msg = new BMessage('pgsz');
msg->AddFloat("width", pageFormat[i].width);
msg->AddFloat("height", pageFormat[i].height);
BMenuItem* mi = new BMenuItem(pageFormat[i].label, msg);
m->AddItem(mi);
if (width == pageFormat[i].width && height == pageFormat[i].height) {
item = mi;
}
if (height == pageFormat[i].width && width == pageFormat[i].height) {
item = mi;
}
}
mf->Menu()->SetLabelFromMarked(true);
if (!item) {
item = m->ItemAt(0);
}
item->SetMarked(true);
mf->MenuItem()->SetLabel(item->Label());
// add orientation menu
y += h + kMargin;
m = new BPopUpMenu("orientation");
m->SetRadioMode(true);
// Simon changed 200->140
mf = new BMenuField(BRect(x, y, x + 140, y + 20), "orientation", "Orientation:", m);
// Simon added: SetDivider
mf->SetDivider(be_plain_font->StringWidth("Orientation#"));
fOrientationMenu = mf;
mf->ResizeToPreferred();
panel->AddChild(mf);
r.top += h;
item = NULL;
for (int i = 0; orientation[i].label != NULL; i++)
{
BMessage* msg = new BMessage('ornt');
msg->AddInt32("orientation", orientation[i].orientation);
BMenuItem* mi = new BMenuItem(orientation[i].label, msg);
m->AddItem(mi);
if (orient == orientation[i].orientation) {
item = mi;
}
}
mf->Menu()->SetLabelFromMarked(true);
// SHOULD BE REMOVED
if (!item) {
item = m->ItemAt(0);
}
///////////////////
item->SetMarked(true);
mf->MenuItem()->SetLabel(item->Label());
// add a "OK" button, and make it default
button = new BButton(r, NULL, "OK", new BMessage(OK_MSG),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
button->ResizeToPreferred();
button->GetPreferredSize(&w, &h);
x = r.right - w - 8;
y = r.bottom - h - 8;
button->MoveTo(x, y);
panel->AddChild(button);
button->MakeDefault(true);
// add a "Cancel button
button = new BButton(r, NULL, "Cancel", new BMessage(CANCEL_MSG),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
button->GetPreferredSize(&w, &h);
button->ResizeToPreferred();
button->MoveTo(x - w - 8, y);
panel->AddChild(button);
// add a separator line...
BBox * line = new BBox(BRect(r.left, y - 9, r.right, y - 8), NULL,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM );
panel->AddChild(line);
// Finally, add our panel to window
AddChild(panel);
}
// --------------------------------------------------
void
PageSetupWindow::UpdateSetupMessage()
{
BMenuItem *item;
int32 orientation = 0;
item = fOrientationMenu->Menu()->FindMarked();
if (item) {
BMessage *msg = item->Message();
msg->FindInt32("orientation", &orientation);
if (fSetupMsg->HasInt32("orientation", orientation)) {
fSetupMsg->ReplaceInt32("orientation", orientation);
} else {
fSetupMsg->AddInt32("orientation", orientation);
}
}
item = fPageSizeMenu->Menu()->FindMarked();
if (item) {
float w, h;
BMessage *msg = item->Message();
msg->FindFloat("width", &w);
msg->FindFloat("height", &h);
BRect r;
if (orientation == 0)
r.Set(0, 0, w, h);
else
r.Set(0, 0, h, w);
if (fSetupMsg->HasRect("paper_rect")) {
fSetupMsg->ReplaceRect("paper_rect", r);
} else {
fSetupMsg->AddRect("paper_rect", r);
}
// Save the printable_rect
BRect margin = fMarginView->GetMargin();
if (orientation == 0) {
margin.right = w - margin.right;
margin.bottom = h - margin.bottom;
} else {
margin.right = h - margin.right;
margin.bottom = w - margin.bottom;
}
if (fSetupMsg->HasRect("printable_rect")) {
fSetupMsg->ReplaceRect("printable_rect", margin);
} else {
fSetupMsg->AddRect("printable_rect", margin);
}
// save the units used
int32 units = fMarginView->GetUnits();
if (fSetupMsg->HasInt32("units")) {
fSetupMsg->ReplaceInt32("units", units);
} else {
fSetupMsg->AddInt32("units", units);
}
}
}
// --------------------------------------------------
void
PageSetupWindow::MessageReceived(BMessage *msg)
{
switch (msg->what){
case OK_MSG:
UpdateSetupMessage();
Quit(B_OK);
break;
case CANCEL_MSG:
Quit(B_ERROR);
break;
// Simon added
case 'pgsz':
{
float w, h;
msg->FindFloat("width", &w);
msg->FindFloat("height", &h);
BMenuItem *item = fOrientationMenu->Menu()->FindMarked();
if (item) {
int32 orientation = 0;
BMessage *m = item->Message();
m->FindInt32("orientation", &orientation);
if (orientation == PrinterDriver::PORTRAIT_ORIENTATION) {
fMarginView->SetPageSize(w, h);
} else {
fMarginView->SetPageSize(h, w);
}
fMarginView->UpdateView(MARGIN_CHANGED);
}
}
break;
// Simon added
case 'ornt':
{
BPoint p = fMarginView->GetPageSize();
int32 orientation;
msg->FindInt32("orientation", &orientation);
if (orientation == PrinterDriver::LANDSCAPE_ORIENTATION
&& p.y > p.x) {
fMarginView->SetPageSize(p.y, p.x);
fMarginView->UpdateView(MARGIN_CHANGED);
}
if (orientation == PrinterDriver::PORTRAIT_ORIENTATION
&& p.x > p.y) {
fMarginView->SetPageSize(p.y, p.x);
fMarginView->UpdateView(MARGIN_CHANGED);
}
}
break;
default:
inherited::MessageReceived(msg);
break;
}
}
@@ -0,0 +1,84 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 PAGESETUPWINDOW_H
#define PAGESETUPWINDOW_H
#include <InterfaceKit.h>
#include <Message.h>
#include <Messenger.h>
#include <File.h>
#include <FindDirectory.h>
#include <Path.h>
#include <String.h>
#include "InterfaceUtils.h"
#include "Utils.h"
class MarginView;
class PageSetupWindow : public BlockingWindow
{
public:
// Constructors, destructors, operators...
PageSetupWindow(BMessage *msg, const char *printerName = NULL);
typedef BlockingWindow inherited;
// public constantes
enum {
OK_MSG = 'ok__',
CANCEL_MSG = 'cncl',
};
// Virtual function overrides
public:
virtual void MessageReceived(BMessage *msg);
// From here, it's none of your business! ;-)
private:
BMessage * fSetupMsg;
BMenuField * fPageSizeMenu;
BMenuField * fOrientationMenu;
void UpdateSetupMessage();
MarginView * fMarginView;
// used for saving settings
BString fPrinterDirName;
//private class constants
static const int kMargin = 10;
static const int kOffset = 200;
};
#endif
@@ -0,0 +1,400 @@
/*
Preview
Copyright (c) 2002, 2003 OpenBeOS.
Author:
Michael Pfeiffer
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 <Debug.h>
#include "Preview.h"
// Implementation of PreviewPage
PreviewPage::PreviewPage(int32 page, PrintJobPage* pjp)
: fPage(page)
, fPictures(NULL)
, fPoints(NULL)
, fRects(NULL)
{
fNumberOfPictures = pjp->NumberOfPictures();
fPictures = new BPicture[fNumberOfPictures];
fPoints = new BPoint[fNumberOfPictures];
fRects = new BRect[fNumberOfPictures];
status_t rc = B_ERROR;
for (int32 i = 0; i < fNumberOfPictures &&
(rc = pjp->NextPicture(fPictures[i], fPoints[i], fRects[i])) == B_OK; i ++);
fStatus = rc;
}
PreviewPage::~PreviewPage() {
delete []fPictures;
delete []fPoints;
delete []fRects;
}
status_t PreviewPage::InitCheck() const {
return fStatus;
}
void PreviewPage::Draw(BView* view) {
ASSERT(fStatus == B_OK);
for (int32 i = 0; i < fNumberOfPictures; i ++) {
view->DrawPicture(&fPictures[i], fPoints[i]);
}
}
// Implementation of PreviewView
const float kPreviewTopMargin = 10;
const float kPreviewBottomMargin = 30;
const float kPreviewLeftMargin = 10;
const float kPreviewRightMargin = 30;
PreviewView::PreviewView(BFile* jobFile, BRect rect)
: BView(rect, "PreviewView", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS)
, fPage(0)
, fZoom(0)
, fReader(jobFile)
, fCachedPage(NULL)
{
}
PreviewView::~PreviewView() {
delete fCachedPage;
}
// returns 2 ^ fZoom
float PreviewView::ZoomFactor() const {
const int32 b = 4;
int32 zoom;
if (fZoom > 0) zoom = (1 << b) << fZoom;
else zoom = (1 << b) >> -fZoom;
return zoom / (float)(1 << b);
}
BRect PreviewView::PageRect() const {
float f = ZoomFactor();
BRect r = fReader.PaperRect();
r.left *= f; r.right *= f; r.top *= f; r.bottom *= f;
return r;
}
BRect PreviewView::ViewRect() const {
BRect r(PageRect());
r.right += kPreviewLeftMargin + kPreviewRightMargin;
r.bottom += kPreviewTopMargin + kPreviewBottomMargin;
return r;
}
status_t PreviewView::InitCheck() const {
return fReader.InitCheck();
}
bool PreviewView::IsPageLoaded(int32 page) const {
return fCachedPage != NULL && fCachedPage->Page() == page;
}
bool PreviewView::IsPageValid() const {
return fCachedPage && fCachedPage->InitCheck() == B_OK;
}
void PreviewView::LoadPage(int32 page) {
delete fCachedPage; fCachedPage = NULL;
PrintJobPage pjp;
if (fReader.GetPage(page, pjp) == B_OK) {
fCachedPage = new PreviewPage(page, &pjp);
}
}
void PreviewView::DrawPageFrame(BRect rect) {
const float kShadowIndent = 3;
const float kShadowWidth = 3;
float x, y;
float right, bottom;
rgb_color frameColor = {0, 0, 0, 0};
rgb_color shadowColor = {90, 90, 90, 0};
BRect r(PageRect());
PushState();
// draw page border around page
r.InsetBy(-1, -1);
r.OffsetTo(kPreviewLeftMargin-1, kPreviewTopMargin-1);
SetHighColor(frameColor);
StrokeRect(r);
// draw page shadow
SetHighColor(shadowColor);
x = r.right + 1;
right = x + kShadowWidth;
bottom = r.bottom + 1 + kShadowWidth;
y = r.top + kShadowIndent;
FillRect(BRect(x, y, right, bottom));
x = r.left + kShadowIndent;
y = r.bottom + 1;
FillRect(BRect(x, y, r.right, bottom));
PopState();
}
void PreviewView::DrawPage(BRect rect) {
// constrain clipping region to paper dimensions
BRect r(PageRect());
r.OffsetBy(kPreviewLeftMargin, kPreviewTopMargin);
BRegion clip(r);
ConstrainClippingRegion(&clip);
// draw page contents
PushState();
SetOrigin(kPreviewLeftMargin, kPreviewTopMargin);
SetScale(ZoomFactor());
fCachedPage->Draw(this);
PopState();
}
void PreviewView::Draw(BRect rect) {
if (fReader.InitCheck() == B_OK) {
if (!IsPageLoaded(fPage)) {
LoadPage(fPage);
}
if (IsPageValid()) {
DrawPageFrame(rect);
DrawPage(rect);
}
}
}
void PreviewView::FrameResized(float width, float height) {
FixScrollbars();
}
bool PreviewView::ShowsFirstPage() const {
return fPage == 0;
}
bool PreviewView::ShowsLastPage() const {
return fPage == NumberOfPages() - 1;
}
int PreviewView::NumberOfPages() const {
return fReader.NumberOfPages();
}
void PreviewView::ShowNextPage() {
if (!ShowsLastPage()) {
fPage ++; Invalidate();
}
}
void PreviewView::ShowPrevPage() {
if (!ShowsFirstPage()) {
fPage --; Invalidate();
}
}
bool PreviewView::CanZoomIn() const {
return fZoom < 4;
}
bool PreviewView::CanZoomOut() const {
return fZoom > -2;
}
void PreviewView::ZoomIn() {
if (CanZoomIn()) {
fZoom ++; FixScrollbars(); Invalidate();
}
}
void PreviewView::ZoomOut() {
if (CanZoomOut()) {
fZoom --; FixScrollbars(); Invalidate();
}
}
void PreviewView::FixScrollbars() {
BRect frame = Bounds();
BScrollBar * scroll;
float x, y;
float bigStep, smallStep;
float width = PageRect().Width() + kPreviewLeftMargin + kPreviewRightMargin;
float height = PageRect().Height() + kPreviewTopMargin + kPreviewBottomMargin;
x = width - frame.Width();
if (x < 0.0) {
x = 0.0;
}
y = height - frame.Height();
if (y < 0.0) {
y = 0.0;
}
scroll = ScrollBar (B_HORIZONTAL);
scroll->SetRange (0.0, x);
scroll->SetProportion ((width - x) / width);
bigStep = frame.Width() - 2;
smallStep = bigStep / 10.;
scroll->SetSteps (smallStep, bigStep);
scroll = ScrollBar (B_VERTICAL);
scroll->SetRange (0.0, y);
scroll->SetProportion ((height - y) / height);
bigStep = frame.Height() - 2;
smallStep = bigStep / 10.;
scroll->SetSteps (smallStep, bigStep);
}
// Implementation of PreviewWindow
PreviewWindow::PreviewWindow(BFile* jobFile)
: BlockingWindow(BRect(20, 24, 400, 600), "Preview", B_DOCUMENT_WINDOW, 0)
{
float top = 7;
float left = 20;
float width, height;
BRect r = Frame();
r.right = r.IntegerWidth() - B_V_SCROLL_BAR_WIDTH; r.left = 0;
r.bottom = r.IntegerHeight() - B_H_SCROLL_BAR_HEIGHT; r.top = 0;
// add navigation and zoom buttons
fPrev = new BButton(BRect(left, top, left+10, top+10), "Prev", "Previous Page", new BMessage(MSG_PREV_PAGE));
AddChild(fPrev);
fPrev->ResizeToPreferred();
width = fPrev->Bounds().Width()+1;
height = fPrev->Bounds().Height()+1;
left = fPrev->Frame().right + 30;
fNext = new BButton(BRect(left, top, left+10, top+10), "Next", "Next Page", new BMessage(MSG_NEXT_PAGE));
AddChild(fNext);
fNext->ResizeTo(width, height);
left = fNext->Frame().right + 70;
fZoomIn = new BButton(BRect(left, top, left+10, top+10), "ZoomIn", "Zoom In", new BMessage(MSG_ZOOM_IN));
AddChild(fZoomIn);
fZoomIn->ResizeTo(width, height);
left = fZoomIn->Frame().right + 30;
fZoomOut = new BButton(BRect(left, top, left+10, top+10), "ZoomOut", "Zoom Out", new BMessage(MSG_ZOOM_OUT));
AddChild(fZoomOut);
fZoomOut->ResizeTo(width, height);
fButtonBarHeight = fZoomOut->Frame().bottom + 7;
// add preview view
r.top = fButtonBarHeight;
fPreview = new PreviewView(jobFile, r);
fPreviewScroller = new BScrollView("PreviewScroller", fPreview, B_FOLLOW_ALL, 0, true, true, B_FANCY_BORDER);
fPreviewScroller->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(fPreviewScroller);
if (fPreview->InitCheck() == B_OK) {
ResizeToPage();
fPreview->FixScrollbars();
UpdateControls();
}
}
void PreviewWindow::ResizeToPage() {
BScreen screen;
BRect r(fPreview->ViewRect());
float width, height;
float maxWidth, maxHeight, minWidth;
const float windowBorderWidth = 5;
const float windowBorderHeight = 5;
if (screen.Frame().right == 0.0) {
return; // invalid screen object
}
width = r.Width() + 1 + B_V_SCROLL_BAR_WIDTH;
height = r.Height() + 1 + fButtonBarHeight + B_H_SCROLL_BAR_HEIGHT;
// dimensions so that window does not reach outside of screen
maxWidth = screen.Frame().Width() + 1 - windowBorderWidth - Frame().left;
maxHeight = screen.Frame().Height() + 1 - windowBorderHeight - Frame().top;
// width so that all buttons are visible
minWidth = fZoomOut->Frame().right + 10;
if (width < minWidth) width = minWidth;
if (width > maxWidth) width = maxWidth;
if (height > maxHeight) height = maxHeight;
ResizeTo(width, height);
}
void PreviewWindow::UpdateControls() {
fPrev->SetEnabled(!fPreview->ShowsFirstPage());
fNext->SetEnabled(!fPreview->ShowsLastPage());
fZoomIn->SetEnabled(fPreview->CanZoomIn());
fZoomOut->SetEnabled(fPreview->CanZoomOut());
}
void PreviewWindow::MessageReceived(BMessage* m) {
switch (m->what) {
case MSG_NEXT_PAGE: fPreview->ShowNextPage();
break;
case MSG_PREV_PAGE: fPreview->ShowPrevPage();
break;
case MSG_ZOOM_IN: fPreview->ZoomIn(); ResizeToPage();
break;
case MSG_ZOOM_OUT: fPreview->ZoomOut(); ResizeToPage();
break;
default:
inherited::MessageReceived(m); return;
}
UpdateControls();
}
status_t PreviewDriver::PrintJob(BFile *jobFile, BMessage *jobMsg) {
PreviewWindow* w;
status_t st;
w = new PreviewWindow(jobFile);
st = w->InitCheck();
if (st == B_OK) {
w->Go();
} else {
w->Quit();
}
return st;
}
PrinterDriver* instanciate_driver(BNode *spoolDir)
{
return new PreviewDriver(spoolDir);
}
// About dialog text:
const char*
kAbout =
"Preview for BeOS\n"
"© 2003 OpenBeOS\n"
"by Michael Pfeiffer\n"
"\n"
"Based on PDF Writer by\nPhilippe Houdoin, Simon Gauvin, Michael Pfeiffer\n"
;
+119
View File
@@ -0,0 +1,119 @@
/*
Preview
Copyright (c) 2002, 2003 OpenBeOS.
Author:
Michael Pfeiffer
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 <InterfaceKit.h>
#include "PrintJobReader.h"
#include "PrinterDriver.h"
#include "InterfaceUtils.h"
class PreviewPage {
int32 fPage;
int32 fNumberOfPictures;
BPicture* fPictures;
BPoint* fPoints;
BRect* fRects;
status_t fStatus;
public:
PreviewPage(int32 page, PrintJobPage* pjp);
~PreviewPage();
status_t InitCheck() const;
int32 Page() const { return fPage; }
void Draw(BView* view);
};
class PreviewView : public BView {
int32 fPage;
int32 fZoom;
PrintJobReader fReader;
PreviewPage* fCachedPage;
float ZoomFactor() const;
BRect PageRect() const;
public:
PreviewView(BFile* jobFile, BRect rect);
~PreviewView();
status_t InitCheck() const;
BRect ViewRect() const;
bool IsPageLoaded(int32 page) const;
bool IsPageValid() const;
void LoadPage(int32 page);
void DrawPageFrame(BRect r);
void DrawPage(BRect r);
void Draw(BRect r);
void FrameResized(float width, float height);
void FixScrollbars();
bool ShowsFirstPage() const;
bool ShowsLastPage() const;
int NumberOfPages() const;
void ShowNextPage();
void ShowPrevPage();
bool CanZoomIn() const;
bool CanZoomOut() const;
void ZoomIn();
void ZoomOut();
};
class PreviewWindow : public BlockingWindow {
BButton *fNext, *fPrev, *fZoomIn, *fZoomOut;
PreviewView* fPreview;
BScrollView* fPreviewScroller;
float fButtonBarHeight;
enum {
MSG_NEXT_PAGE = 'pwnp',
MSG_PREV_PAGE = 'pwpp',
MSG_ZOOM_IN = 'pwzi',
MSG_ZOOM_OUT = 'pwzo'
};
void ResizeToPage();
void UpdateControls();
typedef BlockingWindow inherited;
public:
PreviewWindow(BFile* jobFile);
status_t InitCheck() const { return fPreview->InitCheck(); }
void MessageReceived(BMessage* m);
};
class PreviewDriver : public PrinterDriver {
public:
PreviewDriver(BNode* spoolDir) : PrinterDriver(spoolDir) {};
~PreviewDriver() {};
virtual status_t PrintJob(BFile *jobFile, BMessage *jobMsg);
};
Binary file not shown.
@@ -0,0 +1,401 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 <stdio.h>
#include <string.h> // for memset()
#include <StorageKit.h>
#include "PrinterDriver.h"
#include "PrinterSetupWindow.h"
#include "PageSetupWindow.h"
#include "JobSetupWindow.h"
// Private prototypes
// ------------------
#ifdef CODEWARRIOR
#pragma mark [Constructor & destructor]
#endif
// Constructor & destructor
// ------------------------
// --------------------------------------------------
PrinterDriver::PrinterDriver(BNode* printerNode)
: fJobFile(NULL),
fPrinterNode(printerNode),
fJobMsg(NULL),
fTransport(NULL),
fTransportAddOn(-1),
fTransportInitProc(NULL),
fTransportExitProc(NULL)
{
}
// --------------------------------------------------
PrinterDriver::~PrinterDriver()
{
}
#ifdef CODEWARRIOR
#pragma mark [Public methods]
#endif
#ifdef B_BEOS_VERSION_DANO
struct print_file_header {
int32 version;
int32 page_count;
off_t first_page;
int32 _reserved_3_;
int32 _reserved_4_;
int32 _reserved_5_;
};
#endif
// Public methods
// --------------
status_t
PrinterDriver::PrintJob
(
BFile *jobFile, // spool file
BMessage *jobMsg // job message
)
{
print_file_header pfh;
status_t status;
BMessage *msg;
int32 page;
uint32 copy;
uint32 copies;
const int32 passes = 2;
fJobFile = jobFile;
fJobMsg = jobMsg;
if (!fJobFile || !fPrinterNode)
return B_ERROR;
// open transport
if (OpenTransport() != B_OK) {
return B_ERROR;
}
if (PrintToFileCanceled()) {
return B_OK;
}
// read print file header
fJobFile->Seek(0, SEEK_SET);
fJobFile->Read(&pfh, sizeof(pfh));
// read job message
fJobMsg = msg = new BMessage();
msg->Unflatten(fJobFile);
if (msg->HasInt32("copies")) {
copies = msg->FindInt32("copies");
} else {
copies = 1;
}
status = BeginJob();
fPrinting = true;
for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) {
for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++)
{
for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) {
status = PrintPage(page, pfh.page_count);
}
// re-read job message for next page
fJobFile->Seek(sizeof(pfh), SEEK_SET);
msg->Unflatten(fJobFile);
}
}
status_t s = EndJob();
if (status == B_OK) status = s;
CloseTransport();
delete fJobMsg;
return status;
}
/**
* This will stop the printing loop
*
* @param none
* @return void
*/
void
PrinterDriver::StopPrinting()
{
fPrinting = false;
}
// --------------------------------------------------
status_t
PrinterDriver::BeginJob()
{
return B_OK;
}
// --------------------------------------------------
status_t
PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount)
{
char text[128];
sprintf(text, "Faking print of page %ld/%ld...", pageNumber, pageCount);
BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?");
alert->Go();
return B_OK;
}
// --------------------------------------------------
status_t
PrinterDriver::EndJob()
{
return B_OK;
}
BlockingWindow* PrinterDriver::NewPrinterSetupWindow(char* printerName) {
return NULL;
}
BlockingWindow* PrinterDriver::NewPageSetupWindow(BMessage *setupMsg, const char *printerName) {
return new PageSetupWindow(setupMsg, printerName);
}
BlockingWindow* PrinterDriver::NewJobSetupWindow(BMessage *jobMsg, const char *printerName) {
return new JobSetupWindow(jobMsg, printerName);
}
status_t PrinterDriver::Go(BlockingWindow* w) {
if (w) {
return w->Go();
} else {
return B_OK;
}
}
// --------------------------------------------------
status_t
PrinterDriver::PrinterSetup(char *printerName)
// name of printer, to attach printer settings
{
return Go(NewPrinterSetupWindow(printerName));
}
// --------------------------------------------------
status_t
PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName)
{
// check to see if the messag is built correctly...
if (setupMsg->HasFloat("scaling") != B_OK) {
#if HAS_PRINTER_SETTINGS
PrinterSettings *ps = new PrinterSettings(printerName);
if (ps->InitCheck() == B_OK) {
// first read the settings from the spool dir
if (ps->ReadSettings(setupMsg) != B_OK) {
// if there were none, then create a default set...
ps->GetDefaults(setupMsg);
// ...and save them
ps->WriteSettings(setupMsg);
}
}
#endif
}
return Go(NewPageSetupWindow(setupMsg, printerName));
}
// --------------------------------------------------
status_t
PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName)
{
// set default value if property not set
if (!jobMsg->HasInt32("copies"))
jobMsg->AddInt32("copies", 1);
if (!jobMsg->HasInt32("first_page"))
jobMsg->AddInt32("first_page", 1);
if (!jobMsg->HasInt32("last_page"))
jobMsg->AddInt32("last_page", MAX_INT32);
return Go(NewJobSetupWindow(jobMsg, printerName));
}
// --------------------------------------------------
BMessage*
PrinterDriver::GetDefaultSettings()
{
BMessage* msg = new BMessage();
BRect paperRect(0, 0, letter_width, letter_height);
BRect printableRect(paperRect);
printableRect.InsetBy(10, 10);
msg->AddRect("paper_rect", paperRect);
msg->AddRect("printable_rect", printableRect);
msg->AddInt32("orientation", 0);
msg->AddInt32("xres", 300);
msg->AddInt32("yres", 300);
return msg;
}
// --------------------------------------------------
status_t
PrinterDriver::OpenTransport()
{
char buffer[512];
BPath *path;
if (!fPrinterNode)
return B_ERROR;
// first, find & load transport add-on
path = new BPath();
// find name of this printer transport add-on
fPrinterNode->ReadAttr("transport", B_STRING_TYPE, 0, buffer, sizeof(buffer));
// try first on user add-ons directory
find_directory(B_USER_ADDONS_DIRECTORY, path);
path->Append("Print/transport");
path->Append(buffer);
fTransportAddOn = load_add_on(path->Path());
if (fTransportAddOn < 0) {
// add-on not in user add-ons directory. try system one
find_directory(B_BEOS_ADDONS_DIRECTORY, path);
path->Append("Print/transport");
path->Append(buffer);
fTransportAddOn = load_add_on(path->Path());
}
if (fTransportAddOn < 0) {
BAlert * alert = new BAlert("Uh oh!", "Couldn't find transport add-on.", "OK");
alert->Go();
return B_ERROR;
}
// get init & exit proc
get_image_symbol(fTransportAddOn, "init_transport", B_SYMBOL_TYPE_TEXT, (void **) &fTransportInitProc);
get_image_symbol(fTransportAddOn, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **) &fTransportExitProc);
if (!fTransportInitProc || !fTransportExitProc) {
BAlert * alert = new BAlert("Uh oh!", "Couldn't resolve transport symbols.", "OK");
alert->Go();
return B_ERROR;
}
delete path;
// now, init transport add-on
node_ref ref;
BDirectory dir;
fPrinterNode->GetNodeRef(&ref);
dir.SetTo(&ref);
path = new BPath(&dir, NULL);
strcpy(buffer, path->Path());
// create BMessage for init_transport()
BMessage *msg = new BMessage('TRIN');
msg->AddString("printer_file", buffer);
fTransport = (*fTransportInitProc)(msg);
delete msg;
delete path;
if (fTransport == 0) {
BAlert *alert = new BAlert("Uh oh!", "Couldn't open transport.", "OK");
alert->Go();
return B_ERROR;
}
return B_OK;
}
// --------------------------------------------------
bool
PrinterDriver::PrintToFileCanceled()
{
// The BeOS "Print To File" transport returns a non-NULL BDataIO *
// even after user filepanel cancellation!
BFile* file = dynamic_cast<BFile*>(fTransport);
return file && file->InitCheck() != B_OK;
}
// --------------------------------------------------
status_t
PrinterDriver::CloseTransport()
{
if (!fTransportAddOn)
return B_ERROR;
if (fTransportExitProc)
(*fTransportExitProc)();
unload_add_on(fTransportAddOn);
fTransportAddOn = 0;
fTransport = NULL;
return B_OK;
}
#ifdef CODEWARRIOR
#pragma mark [Privates routines]
#endif
// Private routines
// ----------------
@@ -0,0 +1,145 @@
/*
Preview printer driver.
Copyright (c) 2001 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 PRINTERDRIVER_H
#define PRINTERDRIVER_H
#include <AppKit.h>
#include <InterfaceKit.h>
#include "InterfaceUtils.h"
#ifndef ROUND_UP
#define ROUND_UP(x, y) (((x) + (y) - 1) & ~((y) - 1))
#endif
#define MAX_INT32 ((int32)0x7fffffffL)
/* copied from PDFlib.h: */
#define a0_width (float) 2380.0
#define a0_height (float) 3368.0
#define a1_width (float) 1684.0
#define a1_height (float) 2380.0
#define a2_width (float) 1190.0
#define a2_height (float) 1684.0
#define a3_width (float) 842.0
#define a3_height (float) 1190.0
#define a4_width (float) 595.0
#define a4_height (float) 842.0
#define a5_width (float) 421.0
#define a5_height (float) 595.0
#define a6_width (float) 297.0
#define a6_height (float) 421.0
#define b5_width (float) 501.0
#define b5_height (float) 709.0
#define letter_width (float) 612.0
#define letter_height (float) 792.0
#define legal_width (float) 612.0
#define legal_height (float) 1008.0
#define ledger_width (float) 1224.0
#define ledger_height (float) 792.0
#define p11x17_width (float) 792.0
#define p11x17_height (float) 1224.0
// transport add-on calls definition
extern "C" {
typedef BDataIO *(*init_transport_proc)(BMessage *);
typedef void (*exit_transport_proc)(void);
};
/**
* Class PrinterDriver
*/
class PrinterDriver
{
public:
// constructors / destructor
PrinterDriver(BNode* printerNode);
virtual ~PrinterDriver();
void StopPrinting();
virtual status_t PrintJob(BFile *jobFile, BMessage *jobMsg);
virtual status_t BeginJob();
virtual status_t PrintPage(int32 pageNumber, int32 pageCount);
virtual status_t EndJob();
// configuration window getters
virtual BlockingWindow* NewPrinterSetupWindow(char* printerName);
virtual BlockingWindow* NewPageSetupWindow(BMessage *setupMsg, const char *printerName);
virtual BlockingWindow* NewJobSetupWindow(BMessage *setupMsg, const char *printerName);
// configuration default methods
virtual status_t PrinterSetup(char *printerName);
virtual status_t PageSetup(BMessage *msg, const char *printerName = NULL);
virtual status_t JobSetup(BMessage *msg, const char *printerName = NULL);
virtual BMessage* GetDefaultSettings();
// transport-related methods
status_t OpenTransport();
status_t CloseTransport();
bool PrintToFileCanceled();
// accessors
inline BFile *JobFile() { return fJobFile; }
inline BNode *PrinterNode() { return fPrinterNode; }
inline BMessage *JobMsg() { return fJobMsg; }
inline BDataIO *Transport() { return fTransport; }
inline int32 Pass() const { return fPass; }
// publics status code
typedef enum {
PORTRAIT_ORIENTATION,
LANDSCAPE_ORIENTATION
} Orientation;
private:
status_t Go(BlockingWindow* w);
BFile *fJobFile;
BNode *fPrinterNode;
BMessage *fJobMsg;
volatile Orientation fOrientation;
bool fPrinting;
int32 fPass;
// transport-related
BDataIO *fTransport;
image_id fTransportAddOn;
init_transport_proc fTransportInitProc;
exit_transport_proc fTransportExitProc;
};
#endif // #ifndef PRINTERDRIVER_H
@@ -0,0 +1,215 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 <InterfaceKit.h>
#include <StorageKit.h>
#include <SupportKit.h>
#include "PrinterSetupWindow.h"
// --------------------------------------------------
PrinterSetupWindow::PrinterSetupWindow(char *printerName)
: BlockingWindow(BRect(0,0,300,300), printerName, B_TITLED_WINDOW_LOOK,
B_MODAL_APP_WINDOW_FEEL, B_NOT_ZOOMABLE)
{
MoveTo(300, 300);
fPrinterName = printerName;
if (printerName) {
BString title;
title << printerName << " Printer Setup";
SetTitle(title.String());
} else
SetTitle("Printer Setup");
// ---- Ok, build a default job setup user interface
BRect r;
BButton *button;
float x, y, w, h;
font_height fh;
r = Bounds();
// add a *dialog* background
BBox *panel = new BBox(r, "top_panel", B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
B_PLAIN_BORDER);
const int kInterSpace = 8;
const int kHorzMargin = 10;
const int kVertMargin = 10;
x = kHorzMargin;
y = kVertMargin;
// add a label before the list
const char *kModelLabel = "Printer model";
be_plain_font->GetHeight(&fh);
w = Bounds().Width();
w -= 2 * kHorzMargin;
h = 150;
BBox * model_group = new BBox(BRect(x, y, x+w, y+h), "model_group", B_FOLLOW_ALL_SIDES);
model_group->SetLabel(kModelLabel);
BRect rlv = model_group->Bounds();
rlv.InsetBy(kHorzMargin, kVertMargin);
rlv.top += fh.ascent + fh.descent + fh.leading;
rlv.right -= B_V_SCROLL_BAR_WIDTH;
fModelList = new BListView(rlv, "model_list",
B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES );
BScrollView * sv = new BScrollView( "model_list_scrollview", fModelList,
B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS, false, true );
model_group->AddChild(sv);
panel->AddChild(model_group);
y += (h + kInterSpace);
x = r.right - kHorzMargin;
// add a "OK" button, and make it default
fOkButton = new BButton(BRect(x, y, x + 400, y), NULL, "OK", new BMessage(OK_MSG), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
fOkButton->ResizeToPreferred();
fOkButton->GetPreferredSize(&w, &h);
x -= w;
fOkButton->MoveTo(x, y);
fOkButton->MakeDefault(true);
fOkButton->SetEnabled(false);
panel->AddChild(fOkButton);
x -= kInterSpace;
// add a "Cancel" button
button = new BButton(BRect(x, y, x + 400, y), NULL, "Cancel", new BMessage(CANCEL_MSG), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
button->ResizeToPreferred();
button->GetPreferredSize(&w, &h);
x -= w;
button->MoveTo(x, y);
panel->AddChild(button);
y += (h + kInterSpace);
panel->ResizeTo(Bounds().Width(), y);
ResizeTo(Bounds().Width(), y);
float minWidth, maxWidth, minHeight, maxHeight;
GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
SetSizeLimits(panel->Frame().Width(), panel->Frame().Width(),
panel->Frame().Height(), maxHeight);
// Finally, add our panel to window
AddChild(panel);
BDirectory Folder;
BEntry entry;
Folder.SetTo ("/boot/beos/etc/bubblejet");
if (Folder.InitCheck() != B_OK)
return;
while (Folder.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
char name[B_FILE_NAME_LENGTH];
if (entry.GetName(name) == B_NO_ERROR)
fModelList->AddItem (new BStringItem(name));
}
fModelList->SetSelectionMessage(new BMessage(MODEL_MSG));
fModelList->SetInvocationMessage(new BMessage(OK_MSG));
}
// --------------------------------------------------
void
PrinterSetupWindow::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case OK_MSG:
{
// Test model selection (if any), save it in printerName node and return
BNode spoolDir;
BPath * path;
status_t result = B_ERROR;
if (fModelList->CurrentSelection() < 0)
break;
BStringItem * item = dynamic_cast<BStringItem*>
(fModelList->ItemAt(fModelList->CurrentSelection()));
if (!item)
break;
path = new BPath();
find_directory(B_USER_SETTINGS_DIRECTORY, path);
path->Append("printers");
path->Append(fPrinterName);
spoolDir.SetTo(path->Path());
delete path;
if (spoolDir.InitCheck() != B_OK) {
BAlert * alert = new BAlert("Uh oh!",
"Couldn't find printer spool directory.", "OK");
alert->Go();
} else {
spoolDir.WriteAttr("printer_model", B_STRING_TYPE, 0, item->Text(),
strlen(item->Text()));
result = B_OK;
}
Quit(result);
break;
}
case CANCEL_MSG:
Quit(B_ERROR);
break;
case MODEL_MSG:
fOkButton->SetEnabled((fModelList->CurrentSelection() >= 0));
break;
default:
inherited::MessageReceived(msg);
break;
};
}
@@ -0,0 +1,66 @@
/*
Preview printer driver.
Copyright (c) 2003 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 PRINTERSETUPWINDOW_H
#define PRINTERSETUPWINDOW_H
#include <InterfaceKit.h>
#include "InterfaceUtils.h"
class PrinterSetupWindow : public BlockingWindow
{
public:
// Constructors, destructors, operators...
PrinterSetupWindow(char *printerName);
typedef BlockingWindow inherited;
// public constantes
enum {
OK_MSG = 'ok__',
CANCEL_MSG = 'cncl',
MODEL_MSG = 'modl'
};
// Virtual function overrides
public:
virtual void MessageReceived(BMessage *msg);
// From here, it's none of your business! ;-)
private:
BButton *fOkButton;
BListView *fModelList;
char *fPrinterName;
};
#endif
+107
View File
@@ -0,0 +1,107 @@
/*
PDF Writer printer driver.
Copyright (c) 2001, 2002 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 "Utils.h"
// --------------------------------------------------
EscapeMessageFilter::EscapeMessageFilter(BWindow *window, int32 what)
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, '_KYD')
, fWindow(window),
fWhat(what)
{
}
// --------------------------------------------------
filter_result
EscapeMessageFilter::Filter(BMessage *msg, BHandler **target)
{
int32 key;
// notify window with message fWhat if Escape key is hit
if (B_OK == msg->FindInt32("key", &key) && key == 1) {
fWindow->PostMessage(fWhat);
return B_SKIP_MESSAGE;
}
return B_DISPATCH_MESSAGE;
}
// --------------------------------------------------
// copied from BeUtils.cpp
static bool InList(const char* list[], const char* name) {
for (int i = 0; list[i] != NULL; i ++) {
if (strcmp(list[i], name) == 0) return true;
}
return false;
}
#include <stdio.h>
// --------------------------------------------------
// copied from BeUtils.cpp
void AddFields(BMessage* to, const BMessage* from, const char* excludeList[], const char* includeList[]) {
if (to == from) return;
char* name;
type_code type;
int32 count;
for (int32 i = 0; from->GetInfo(B_ANY_TYPE, i, &name, &type, &count) == B_OK; i ++) {
if (excludeList && InList(excludeList, name)) continue;
if (includeList && !InList(includeList, name)) continue;
// replace existing data
to->RemoveName(name);
const void* data;
ssize_t size;
for (int32 j = 0; j < count; j ++) {
if (from->FindData(name, type, j, &data, &size) == B_OK) {
// WTF why works AddData not for B_STRING_TYPE in R5.0.3?
if (type == B_STRING_TYPE) {
to->AddString(name, (const char*)data);
} else if (type == B_MESSAGE_TYPE) {
BMessage m;
from->FindMessage(name, j, &m);
to->AddMessage(name, &m);
} else {
to->AddData(name, type, data, size);
}
}
}
}
}
void AddString(BMessage* m, const char* name, const char* value) {
if (m->HasString(name, 0)) {
m->ReplaceString(name, value);
} else {
m->AddString(name, value);
}
}
+155
View File
@@ -0,0 +1,155 @@
/*
PDF Writer printer driver.
Copyright (c) 2001, 2002 OpenBeOS.
Authors:
Philippe Houdoin
Simon Gauvin
Michael Pfeiffer
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 _UTILS_H
#define _UTILS_H
#include <Window.h>
#include <Message.h>
#include <MessageFilter.h>
// adds fields to message or replaces existing fields (copy BeUtils.h)
void AddFields(BMessage* to, const BMessage* from, const char* excludeList[] = NULL, const char* includeList[] = NULL);
void AddString(BMessage* m, const char* name, const char* value);
class EscapeMessageFilter : public BMessageFilter
{
private:
BWindow *fWindow;
int32 fWhat;
public:
EscapeMessageFilter(BWindow *window, int32 what);
filter_result Filter(BMessage *msg, BHandler **target);
};
#define BEGINS_CHAR(byte) ((byte & 0xc0) != 0x80)
template <class T>
class TList {
private:
BList fList;
typedef int (*sort_func)(const void*, const void*);
public:
virtual ~TList();
void MakeEmpty();
int32 CountItems() const;
T* ItemAt(int32 index) const;
void AddItem(T* p);
T* RemoveItem(int i);
T* Items();
void SortItems(int (*comp)(const T**, const T**));
};
// TList
template<class T>
TList<T>::~TList() {
MakeEmpty();
}
template<class T>
void TList<T>::MakeEmpty() {
const int32 n = CountItems();
for (int i = 0; i < n; i++) {
delete ItemAt(i);
}
fList.MakeEmpty();
}
template<class T>
int32 TList<T>::CountItems() const {
return fList.CountItems();
}
template<class T>
T* TList<T>::ItemAt(int32 index) const {
return (T*)fList.ItemAt(index);
}
template<class T>
void TList<T>::AddItem(T* p) {
fList.AddItem(p);
}
template<class T>
T* TList<T>::RemoveItem(int i) {
return (T*)fList.RemoveItem(i);
}
template<class T>
T* TList<T>::Items() {
return (T*)fList.Items();
}
template<class T>
void TList<T>::SortItems(int (*comp)(const T**, const T**)) {
sort_func sort = (sort_func)comp;
fList.SortItems(sort);
}
// PDF coordinate system
class PDFSystem {
private:
float fHeight;
float fX;
float fY;
float fScale;
public:
PDFSystem()
: fHeight(0), fX(0), fY(0), fScale(1) { }
PDFSystem(float h, float x, float y, float s)
: fHeight(h), fX(x), fY(y), fScale(s) { }
void SetHeight(float h) { fHeight = h; }
void SetOrigin(float x, float y) { fX = x; fY = y; }
void SetScale(float scale) { fScale = scale; }
float Height() const { return fHeight; }
BPoint Origin() const { return BPoint(fX, fY); }
float Scale() const { return fScale; }
inline float tx(float x) { return fX + fScale*x; }
inline float ty(float y) { return fHeight - (fY + fScale * y); }
inline float scale(float f) { return fScale * f; }
};
#endif