/*
* PageSetupDlg.cpp
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
*/
#include <string>
#include <cstring>
#include <cstdlib>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <Alert.h>
#include <Bitmap.h>
#include <Box.h>
#include <Button.h>
#include <Debug.h>
#include <Font.h>
#include <GridView.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <Looper.h>
#include <MessageFilter.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Message.h>
#include <Point.h>
#include <PopUpMenu.h>
#include <PrintJob.h>
#include <RadioButton.h>
#include <Rect.h>
#include <String.h>
#include <SupportDefs.h>
#include <TextControl.h>
#include <View.h>
#include "DbgMsg.h"
#include "JobData.h"
#include "MarginView.h"
#include "PageSetupDlg.h"
#include "PrinterData.h"
#include "PrinterCap.h"
#include "PrintUtils.h"
using namespace std;
enum MSGS {
kMsgCancel = 1,
kMsgOK,
kMsgOrientationChanged,
kMsgPaperChanged,
};
PageSetupView::PageSetupView(JobData *job_data, PrinterData *printer_data,
const PrinterCap *printer_cap)
: BView("pageSetupView", B_WILL_DRAW)
, fJobData(job_data)
, fPrinterData(printer_data)
, fPrinterCap(printer_cap)
{
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
}
PageSetupView::~PageSetupView()
{
}
void
PageSetupView::AddOrientationItem(const char* name, JobData::Orientation orientation)
{
BMessage *msg = new BMessage(kMsgOrientationChanged);
msg->AddInt32("orientation", orientation);
BMenuItem *item = new BMenuItem(name, msg);
fOrientation->AddItem(item);
item->SetTarget(this);
if (fJobData->GetOrientation() == orientation) {
item->SetMarked(true);
} else if (fOrientation->CountItems() == 1) {
item->SetMarked(true);
}
}
void
PageSetupView::AttachedToWindow()
{
BMenuItem *item = NULL;
bool marked;
int count;
// margin
MarginUnit units = fJobData->GetMarginUnit();
BRect paper = fJobData->GetPaperRect();
BRect margin = fJobData->GetPrintableRect();
// re-calculate the margin from the printable rect in points
margin.top -= paper.top;
margin.left -= paper.left;
margin.right = paper.right - margin.right;
margin.bottom = paper.bottom - margin.bottom;
fMarginView = new MarginView(
paper.IntegerWidth(),
paper.IntegerHeight(),
margin, units);
// paper selection
marked = false;
fPaper = new BPopUpMenu("paperSize");
fPaper->SetRadioMode(true);
count = fPrinterCap->CountCap(PrinterCap::kPaper);
PaperCap **paper_cap = (PaperCap **)fPrinterCap->GetCaps(PrinterCap::kPaper);
while (count--) {
BMessage *msg = new BMessage(kMsgPaperChanged);
msg->AddPointer("paperCap", *paper_cap);
item = new BMenuItem((*paper_cap)->fLabel.c_str(), msg);
fPaper->AddItem(item);
item->SetTarget(this);
if ((*paper_cap)->fPaper == fJobData->GetPaper()) {
item->SetMarked(true);
marked = true;
}
paper_cap++;
}
if (!marked)
item->SetMarked(true);
BMenuField* paperSize = new BMenuField("paperSize", "Paper size:", fPaper);
// orientation
fOrientation = new BPopUpMenu("orientation");
fOrientation->SetRadioMode(true);
BMenuField* orientation = new BMenuField("orientation", "Orientation:", fOrientation);
count = fPrinterCap->CountCap(PrinterCap::kOrientation);
if (count == 0) {
AddOrientationItem("Portrait", JobData::kPortrait);
AddOrientationItem("Landscape", JobData::kLandscape);
} else {
OrientationCap **orientation_cap = (OrientationCap **)fPrinterCap->GetCaps(PrinterCap::kOrientation);
while (count--) {
AddOrientationItem((*orientation_cap)->fLabel.c_str(),
(*orientation_cap)->fOrientation);
orientation_cap++;
}
}
// resolution
marked = false;
fResolution = new BPopUpMenu("resolution");
fResolution->SetRadioMode(true);
count = fPrinterCap->CountCap(PrinterCap::kResolution);
ResolutionCap **resolution_cap = (ResolutionCap **)fPrinterCap->GetCaps(PrinterCap::kResolution);
while (count--) {
item = new BMenuItem((*resolution_cap)->fLabel.c_str(), NULL);
fResolution->AddItem(item);
item->SetTarget(this);
if (((*resolution_cap)->fXResolution == fJobData->GetXres()) &&
((*resolution_cap)->fYResolution == fJobData->GetYres())) {
item->SetMarked(true);
marked = true;
}
resolution_cap++;
}
if (!marked)
item->SetMarked(true);
BMenuField* resolution = new BMenuField("resolution", "Resolution:", fResolution);
// scale
BString scale;
scale << (int)fJobData->GetScaling();
fScaling = new BTextControl("scale", "Scale [%]:",
scale.String(),
NULL);
int num;
for (num = 0; num <= 255; num++) {
fScaling->TextView()->DisallowChar(num);
}
for (num = 0; num <= 9; num++) {
fScaling->TextView()->AllowChar('0' + num);
}
fScaling->TextView()->SetMaxBytes(3);
// cancel and ok
BButton* cancel = new BButton("cancel", "Cancel", new BMessage(kMsgCancel));
BButton* ok = new BButton("ok", "OK", new BMessage(kMsgOK));
ok->MakeDefault(true);
BGridView* settings = new BGridView();
BGridLayout* settingsLayout = settings->GridLayout();
settingsLayout->AddItem(paperSize->CreateLabelLayoutItem(), 0, 0);
settingsLayout->AddItem(paperSize->CreateMenuBarLayoutItem(), 1, 0);
settingsLayout->AddItem(orientation->CreateLabelLayoutItem(), 0, 1);
settingsLayout->AddItem(orientation->CreateMenuBarLayoutItem(), 1, 1);
settingsLayout->AddItem(resolution->CreateLabelLayoutItem(), 0, 2);
settingsLayout->AddItem(resolution->CreateMenuBarLayoutItem(), 1, 2);
settingsLayout->AddItem(fScaling->CreateLabelLayoutItem(), 0, 3);
settingsLayout->AddItem(fScaling->CreateTextViewLayoutItem(), 1, 3);
settingsLayout->SetSpacing(0, 0);
SetLayout(new BGroupLayout(B_VERTICAL));
AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
.AddGroup(B_HORIZONTAL, 5, 1.0f)
.AddGroup(B_VERTICAL, 0, 1.0f)
.Add(fMarginView)
.AddGlue()
.End()
.AddGroup(B_VERTICAL, 0, 1.0f)
.Add(settings)
.AddGlue()
.End()
.End()
.AddGroup(B_HORIZONTAL, 10, 1.0f)
.AddGlue()
.Add(cancel)
.Add(ok)
.End()
.SetInsets(10, 10, 10, 10)
);
}
inline void
swap(float *e1, float *e2)
{
float e = *e1;
*e1 = *e2;
*e2 = e;
}
JobData::Orientation
PageSetupView::GetOrientation()
{
BMenuItem *item = fOrientation->FindMarked();
int32 orientation;
if (item != NULL &&
item->Message()->FindInt32("orientation", &orientation) == B_OK) {
return (JobData::Orientation)orientation;
} else {
return JobData::kPortrait;
}
}
PaperCap *
PageSetupView::GetPaperCap()
{
BMenuItem *item = fPaper->FindMarked();
void *pointer;
if (item != NULL &&
item->Message()->FindPointer("paperCap", &pointer) == B_OK) {
return (PaperCap*)pointer;
} else {
return (PaperCap*)fPrinterCap->GetDefaultCap(PrinterCap::kPaper);
}
}
bool
PageSetupView::UpdateJobData()
{
fJobData->SetOrientation(GetOrientation());
PaperCap *paperCap = GetPaperCap();
BRect paper_rect = paperCap->fPaperRect;
BRect physical_rect = paperCap->fPhysicalRect;
fJobData->SetPaper(paperCap->fPaper);
const char *resolutionLabel = fResolution->FindMarked()->Label();
const ResolutionCap* resolution = static_cast<const ResolutionCap*>(
fPrinterCap->FindCap(PrinterCap::kResolution, resolutionLabel));
ASSERT(resolution != NULL);
if (resolution != NULL) {
fJobData->SetXres(resolution->fXResolution);
fJobData->SetYres(resolution->fYResolution);
fJobData->SetResolutionID(resolution->ID());
}
// rotate paper and physical rectangle if landscape orientation
if (JobData::kLandscape == fJobData->GetOrientation()) {
swap(&paper_rect.left, &paper_rect.top);
swap(&paper_rect.right, &paper_rect.bottom);
swap(&physical_rect.left, &physical_rect.top);
swap(&physical_rect.right, &physical_rect.bottom);
}
// adjust printable rect by margin
fJobData->SetMarginUnit(fMarginView->Unit());
BRect margin = fMarginView->Margin();
BRect printable_rect;
printable_rect.left = paper_rect.left + margin.left;
printable_rect.top = paper_rect.top + margin.top;
printable_rect.right = paper_rect.right - margin.right;
printable_rect.bottom = paper_rect.bottom - margin.bottom;
printable_rect.left = max_c(printable_rect.left, physical_rect.left);
printable_rect.top = max_c(printable_rect.top, physical_rect.top);
printable_rect.right = min_c(printable_rect.right, physical_rect.right);
printable_rect.bottom = min_c(printable_rect.bottom, physical_rect.bottom);
float scaling = atoi(fScaling->Text());
if (scaling <= 0.0) { // sanity check
scaling = 100.0;
}
if (scaling > 1000.0) {
scaling = 1000.0;
}
float scalingR = 100.0 / scaling;
fJobData->SetScaling(scaling);
fJobData->SetPaperRect(paper_rect);
fJobData->SetScaledPaperRect(ScaleRect(paper_rect, scalingR));
fJobData->SetPrintableRect(printable_rect);
fJobData->SetScaledPrintableRect(ScaleRect(printable_rect, scalingR));
fJobData->SetPhysicalRect(physical_rect);
fJobData->SetScaledPhysicalRect(ScaleRect(physical_rect, scalingR));
fJobData->Save();
return true;
}
void
PageSetupView::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case kMsgPaperChanged:
case kMsgOrientationChanged:
{
JobData::Orientation orientation = GetOrientation();
PaperCap *paperCap = GetPaperCap();
float width = paperCap->fPaperRect.Width();
float height = paperCap->fPaperRect.Height();
if (orientation != JobData::kPortrait) {
swap(&width, &height);
}
fMarginView->SetPageSize(width, height);
fMarginView->UpdateView(MARGIN_CHANGED);
}
break;
}
}
//====================================================================
// TODO center window on screen
PageSetupDlg::PageSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap)
: DialogWindow(BRect(100, 100, 160, 160),
"Paper setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE
| B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE)
{
AddShortcut('W',B_COMMAND_KEY,new BMessage(B_QUIT_REQUESTED));
fPageSetupView = new PageSetupView(job_data, printer_data,
printer_cap);
SetLayout(new BGroupLayout(B_HORIZONTAL));
AddChild(BGroupLayoutBuilder(B_HORIZONTAL, 0)
.Add(fPageSetupView)
);
SetResult(B_ERROR);
}
void
PageSetupDlg::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case kMsgOK:
Lock();
fPageSetupView->UpdateJobData();
Unlock();
SetResult(B_NO_ERROR);
PostMessage(B_QUIT_REQUESTED);
break;
case kMsgCancel:
PostMessage(B_QUIT_REQUESTED);
break;
default:
DialogWindow::MessageReceived(msg);
}
}
↑ V773 Visibility scope of the 'resolution' pointer was exited without releasing the memory. A memory leak is possible.
↑ V773 Visibility scope of the 'orientation' pointer was exited without releasing the memory. A memory leak is possible.
↑ V773 Visibility scope of the 'paperSize' pointer was exited without releasing the memory. A memory leak is possible.
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: fFilter.