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:
@@ -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
|
||||
@@ -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"
|
||||
;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user