/* * PageSetupDlg.cpp * Copyright 1999-2000 Y.Takagi. All Rights Reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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( 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); } }