1 /* 2 * JobSetupDlg.cpp 3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved. 4 */ 5 6 #include <cstdio> 7 #include <cstring> 8 #include <cstdlib> 9 #include <string> 10 #include <fcntl.h> 11 #include <unistd.h> 12 #include <sys/stat.h> 13 #include <math.h> 14 15 #include <Alert.h> 16 #include <Bitmap.h> 17 #include <Box.h> 18 #include <Button.h> 19 #include <CheckBox.h> 20 #include <GridView.h> 21 #include <GroupLayout.h> 22 #include <GroupLayoutBuilder.h> 23 #include <Looper.h> 24 #include <MessageFilter.h> 25 #include <MenuField.h> 26 #include <MenuItem.h> 27 #include <Message.h> 28 #include <Point.h> 29 #include <PopUpMenu.h> 30 #include <PrintJob.h> 31 #include <RadioButton.h> 32 #include <Rect.h> 33 #include <Slider.h> 34 #include <String.h> 35 #include <TextControl.h> 36 #include <TextView.h> 37 #include <View.h> 38 39 #include "HalftoneView.h" 40 #include "JobSetupDlg.h" 41 #include "JobData.h" 42 #include "JSDSlider.h" 43 #include "PagesView.h" 44 #include "PrinterData.h" 45 #include "PrinterCap.h" 46 #include "DbgMsg.h" 47 48 49 using namespace std; 50 51 52 struct NupCap : public BaseCap { 53 NupCap(const string &label, bool isDefault, int nup) 54 : 55 BaseCap(label, isDefault), 56 fNup(nup) 57 {} 58 59 int fNup; 60 }; 61 62 63 struct DitherCap : public BaseCap { 64 DitherCap(const string &label, bool isDefault, 65 Halftone::DitherType ditherType) 66 : 67 BaseCap(label, isDefault), 68 fDitherType(ditherType) 69 {} 70 71 Halftone::DitherType fDitherType; 72 }; 73 74 75 static const NupCap gNup1("1", true, 1); 76 static const NupCap gNup2("2", false, 2); 77 static const NupCap gNup4("4", false, 4); 78 static const NupCap gNup8("8", false, 8); 79 static const NupCap gNup9("9", false, 9); 80 static const NupCap gNup16("16", false, 16); 81 static const NupCap gNup25("25", false, 25); 82 static const NupCap gNup32("32", false, 32); 83 static const NupCap gNup36("36", false, 36); 84 85 86 static const DitherCap gDitherType1("Crosshatch", false, Halftone::kType1); 87 static const DitherCap gDitherType2("Grid", false, Halftone::kType2); 88 static const DitherCap gDitherType3("Stipple", false, Halftone::kType3); 89 static const DitherCap gDitherFloydSteinberg("Floyd-Steinberg", false, 90 Halftone::kTypeFloydSteinberg); 91 92 93 const NupCap *gNups[] = { 94 &gNup1, 95 &gNup2, 96 &gNup4, 97 &gNup8, 98 &gNup9, 99 &gNup16, 100 &gNup25, 101 &gNup32, 102 &gNup36 103 }; 104 105 106 const DitherCap *gDitherTypes[] = { 107 &gDitherType1, 108 &gDitherType2, 109 &gDitherType3, 110 &gDitherFloydSteinberg 111 }; 112 113 114 enum { 115 kMsgRangeAll = 'JSdl', 116 kMsgRangeSelection, 117 kMsgPreview, 118 kMsgCancel, 119 kMsgOK, 120 kMsgQuality, 121 kMsgCollateChanged, 122 kMsgReverseChanged, 123 kMsgDuplexChanged, 124 }; 125 126 127 JobSetupView::JobSetupView(JobData *job_data, PrinterData *printer_data, 128 const PrinterCap *printer_cap) 129 : 130 BView("jobSetup", B_WILL_DRAW), 131 fJobData(job_data), 132 fPrinterData(printer_data), 133 fPrinterCap(printer_cap) 134 { 135 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 136 } 137 138 139 BRadioButton* 140 JobSetupView::CreatePageSelectionItem(const char* name, const char* label, 141 JobData::PageSelection pageSelection) 142 { 143 BRadioButton* button = new BRadioButton(name, label, NULL); 144 if (fJobData->getPageSelection() == pageSelection) { 145 button->SetValue(B_CONTROL_ON); 146 } 147 return button; 148 } 149 150 151 void 152 JobSetupView::AllowOnlyDigits(BTextView* textView, int maxDigits) 153 { 154 int num; 155 for (num = 0; num <= 255; num++) { 156 textView->DisallowChar(num); 157 } 158 for (num = 0; num <= 9; num++) { 159 textView->AllowChar('0' + num); 160 } 161 textView->SetMaxBytes(maxDigits); 162 } 163 164 165 void 166 JobSetupView::AttachedToWindow() 167 { 168 // quality 169 BBox* qualityBox = new BBox("quality"); 170 qualityBox->SetLabel("Quality"); 171 172 // color 173 fColorType = new BPopUpMenu("color"); 174 fColorType->SetRadioMode(true); 175 176 int count = fPrinterCap->countCap(PrinterCap::kColor); 177 const ColorCap **color_cap = (const ColorCap **)fPrinterCap->enumCap( 178 PrinterCap::kColor); 179 bool marked = false; 180 BMenuItem* item = NULL; 181 while (count--) { 182 item = new BMenuItem((*color_cap)->fLabel.c_str(), 183 new BMessage(kMsgQuality)); 184 fColorType->AddItem(item); 185 if ((*color_cap)->fColor == fJobData->getColor()) { 186 item->SetMarked(true); 187 marked = true; 188 } 189 color_cap++; 190 } 191 if (!marked && item) 192 item->SetMarked(true); 193 194 BMenuField* colorMenuField = new BMenuField("color", "Color:", fColorType); 195 fColorType->SetTargetForItems(this); 196 197 // dither type 198 fDitherType = new BPopUpMenu(""); 199 fDitherType->SetRadioMode(true); 200 201 count = sizeof(gDitherTypes) / sizeof(gDitherTypes[0]); 202 const DitherCap **dither_cap = gDitherTypes; 203 marked = false; 204 item = NULL; 205 while (count--) { 206 item = new BMenuItem((*dither_cap)->fLabel.c_str(), 207 new BMessage(kMsgQuality)); 208 fDitherType->AddItem(item); 209 if ((*dither_cap)->fDitherType == fJobData->getDitherType()) { 210 item->SetMarked(true); 211 marked = true; 212 } 213 dither_cap++; 214 } 215 if (!marked && item) 216 item->SetMarked(true); 217 BMenuField* ditherMenuField = new BMenuField("dithering", "Dot Pattern:", 218 fDitherType); 219 fDitherType->SetTargetForItems(this); 220 221 // halftone preview view 222 BBox* halftoneBox = new BBox("halftoneBox"); 223 halftoneBox->SetBorder(B_PLAIN_BORDER); 224 225 // TODO make layout compatible 226 BSize size(240, 14 * 4); 227 BRect rect(0, 0, size.width, size.height); 228 fHalftone = new HalftoneView(rect, "halftone", 229 B_FOLLOW_ALL, B_WILL_DRAW); 230 fHalftone->SetExplicitMinSize(size); 231 fHalftone->SetExplicitMaxSize(size); 232 233 // gamma 234 fGamma = new JSDSlider("gamma", "Gamma", new BMessage(kMsgQuality), 235 -300, 300); 236 237 fGamma->SetLimitLabels("Lighter", "Darker"); 238 fGamma->SetValue((int32)(100 * log(fJobData->getGamma()) / log(2.0))); 239 fGamma->SetHashMarks(B_HASH_MARKS_BOTH); 240 fGamma->SetHashMarkCount(7); 241 fGamma->SetModificationMessage(new BMessage(kMsgQuality)); 242 fGamma->SetTarget(this); 243 244 // ink density 245 fInkDensity = new JSDSlider("inkDensity", "Ink Usage", 246 new BMessage(kMsgQuality), 0, 127); 247 248 fInkDensity->SetLimitLabels("Min", "Max"); 249 fInkDensity->SetValue((int32)fJobData->getInkDensity()); 250 fInkDensity->SetHashMarks(B_HASH_MARKS_BOTH); 251 fInkDensity->SetHashMarkCount(10); 252 fInkDensity->SetModificationMessage(new BMessage(kMsgQuality)); 253 fInkDensity->SetTarget(this); 254 255 // page range 256 257 BBox* pageRangeBox = new BBox("pageRange"); 258 pageRangeBox->SetLabel("Page Range"); 259 260 fAll = new BRadioButton("all", "Print all Pages", new BMessage(kMsgRangeAll)); 261 262 BRadioButton *range = new BRadioButton("selection", "Print selected Pages:", 263 new BMessage(kMsgRangeSelection)); 264 265 fFromPage = new BTextControl("from", "From:", "", NULL); 266 fFromPage->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); 267 AllowOnlyDigits(fFromPage->TextView(), 6); 268 269 fToPage = new BTextControl("to", "To:", "", NULL); 270 fToPage->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); 271 AllowOnlyDigits(fToPage->TextView(), 6); 272 273 int first_page = fJobData->getFirstPage(); 274 int last_page = fJobData->getLastPage(); 275 276 if (first_page <= 1 && last_page <= 0) { 277 fAll->SetValue(B_CONTROL_ON); 278 } else { 279 range->SetValue(B_CONTROL_ON); 280 if (first_page < 1) 281 first_page = 1; 282 if (first_page > last_page) 283 last_page = -1; 284 285 BString oss1; 286 oss1 << first_page; 287 fFromPage->SetText(oss1.String()); 288 289 BString oss2; 290 oss2 << last_page; 291 fToPage->SetText(oss2.String()); 292 } 293 294 fAll->SetTarget(this); 295 range->SetTarget(this); 296 297 // paper source 298 fPaperFeed = new BPopUpMenu(""); 299 fPaperFeed->SetRadioMode(true); 300 count = fPrinterCap->countCap(PrinterCap::kPaperSource); 301 const PaperSourceCap **paper_source_cap = 302 (const PaperSourceCap **)fPrinterCap->enumCap(PrinterCap::kPaperSource); 303 marked = false; 304 item = NULL; 305 while (count--) { 306 item = new BMenuItem((*paper_source_cap)->fLabel.c_str(), NULL); 307 fPaperFeed->AddItem(item); 308 if ((*paper_source_cap)->fPaperSource == fJobData->getPaperSource()) { 309 item->SetMarked(true); 310 marked = true; 311 } 312 paper_source_cap++; 313 } 314 if (!marked) 315 item->SetMarked(true); 316 BMenuField* paperSourceMenufield = new BMenuField("paperSource", 317 "Paper Source:", fPaperFeed); 318 319 // Pages per sheet 320 fNup = new BPopUpMenu(""); 321 fNup->SetRadioMode(true); 322 count = sizeof(gNups) / sizeof(gNups[0]); 323 const NupCap **nup_cap = gNups; 324 marked = false; 325 item = NULL; 326 while (count--) { 327 item = new BMenuItem((*nup_cap)->fLabel.c_str(), NULL); 328 fNup->AddItem(item); 329 if ((*nup_cap)->fNup == fJobData->getNup()) { 330 item->SetMarked(true); 331 marked = true; 332 } 333 nup_cap++; 334 } 335 if (!marked) 336 item->SetMarked(true); 337 BMenuField* pagesPerSheet = new BMenuField("pagesPerSheet", 338 "Pages Per Sheet:", fNup); 339 340 // duplex 341 if (fPrinterCap->isSupport(PrinterCap::kPrintStyle)) { 342 fDuplex = new BCheckBox("duplex", "Duplex", 343 new BMessage(kMsgDuplexChanged)); 344 if (fJobData->getPrintStyle() != JobData::kSimplex) { 345 fDuplex->SetValue(B_CONTROL_ON); 346 } 347 fDuplex->SetTarget(this); 348 } else { 349 fDuplex = NULL; 350 } 351 352 // copies 353 fCopies = new BTextControl("copies", "Number of Copies:", "", NULL); 354 AllowOnlyDigits(fCopies->TextView(), 3); 355 356 BString copies; 357 copies << fJobData->getCopies(); 358 fCopies->SetText(copies.String()); 359 360 // collate 361 fCollate = new BCheckBox("collate", "Collate", 362 new BMessage(kMsgCollateChanged)); 363 if (fJobData->getCollate()) { 364 fCollate->SetValue(B_CONTROL_ON); 365 } 366 fCollate->SetTarget(this); 367 368 // reverse 369 fReverse = new BCheckBox("reverse", "Reverse Order", 370 new BMessage(kMsgReverseChanged)); 371 if (fJobData->getReverse()) { 372 fReverse->SetValue(B_CONTROL_ON); 373 } 374 fReverse->SetTarget(this); 375 376 // pages view 377 // TODO make layout API compatible 378 fPages = new PagesView(BRect(0, 0, 150, 40), "pages", B_FOLLOW_ALL, 379 B_WILL_DRAW); 380 fPages->setCollate(fJobData->getCollate()); 381 fPages->setReverse(fJobData->getReverse()); 382 fPages->SetExplicitMinSize(BSize(150, 40)); 383 fPages->SetExplicitMaxSize(BSize(150, 40)); 384 385 // page selection 386 BBox* pageSelectionBox = new BBox("pageSelection"); 387 pageSelectionBox->SetLabel("Page Selection"); 388 389 fAllPages = CreatePageSelectionItem("allPages", "All Pages", 390 JobData::kAllPages); 391 fOddNumberedPages = CreatePageSelectionItem("oddPages", 392 "Odd-Numbered Pages", JobData::kOddNumberedPages); 393 fEvenNumberedPages = CreatePageSelectionItem("evenPages", 394 "Even-Numbered Pages", JobData::kEvenNumberedPages); 395 396 // separator line 397 BBox *separator = new BBox("separator"); 398 separator->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1)); 399 400 // buttons 401 BButton* preview = new BButton("preview", "Preview" B_UTF8_ELLIPSIS, 402 new BMessage(kMsgPreview)); 403 BButton* cancel = new BButton("cancel", "Cancel", 404 new BMessage(kMsgCancel)); 405 BButton* ok = new BButton("ok", "OK", new BMessage(kMsgOK)); 406 ok->MakeDefault(true); 407 408 BGroupView* halftoneGroup = new BGroupView(B_VERTICAL, 0); 409 BGroupLayout* halftoneLayout = halftoneGroup->GroupLayout(); 410 halftoneLayout->AddView(fHalftone); 411 halftoneBox->AddChild(halftoneGroup); 412 413 BGridView* qualityGrid = new BGridView(); 414 BGridLayout* qualityGridLayout = qualityGrid->GridLayout(); 415 qualityGridLayout->AddItem(colorMenuField->CreateLabelLayoutItem(), 0, 0); 416 qualityGridLayout->AddItem(colorMenuField->CreateMenuBarLayoutItem(), 1, 0); 417 qualityGridLayout->AddItem(ditherMenuField->CreateLabelLayoutItem(), 0, 1); 418 qualityGridLayout->AddItem(ditherMenuField->CreateMenuBarLayoutItem(), 1, 419 1); 420 qualityGridLayout->AddView(fGamma, 0, 2, 2); 421 qualityGridLayout->AddView(fInkDensity, 0, 3, 2); 422 qualityGridLayout->AddView(halftoneBox, 0, 4, 2); 423 qualityGridLayout->SetSpacing(0, 0); 424 qualityGridLayout->SetInsets(5, 5, 5, 5); 425 qualityBox->AddChild(qualityGrid); 426 427 BGridView* pageRangeGrid = new BGridView(); 428 BGridLayout* pageRangeLayout = pageRangeGrid->GridLayout(); 429 pageRangeLayout->AddItem(fFromPage->CreateLabelLayoutItem(), 0, 0); 430 pageRangeLayout->AddItem(fFromPage->CreateTextViewLayoutItem(), 1, 0); 431 pageRangeLayout->AddItem(fToPage->CreateLabelLayoutItem(), 0, 1); 432 pageRangeLayout->AddItem(fToPage->CreateTextViewLayoutItem(), 1, 1); 433 pageRangeLayout->SetInsets(0, 0, 0, 0); 434 pageRangeLayout->SetSpacing(0, 0); 435 436 BGroupView* pageRangeGroup = new BGroupView(B_VERTICAL, 0); 437 BGroupLayout* pageRangeGroupLayout = pageRangeGroup->GroupLayout(); 438 pageRangeGroupLayout->AddView(fAll); 439 pageRangeGroupLayout->AddView(range); 440 pageRangeGroupLayout->AddView(pageRangeGrid); 441 pageRangeGroupLayout->SetInsets(5, 5, 5, 5); 442 pageRangeBox->AddChild(pageRangeGroup); 443 444 BGridView* settings = new BGridView(); 445 BGridLayout* settingsLayout = settings->GridLayout(); 446 settingsLayout->AddItem(paperSourceMenufield->CreateLabelLayoutItem(), 0, 447 0); 448 settingsLayout->AddItem(paperSourceMenufield->CreateMenuBarLayoutItem(), 1, 449 0); 450 settingsLayout->AddItem(pagesPerSheet->CreateLabelLayoutItem(), 0, 1); 451 settingsLayout->AddItem(pagesPerSheet->CreateMenuBarLayoutItem(), 1, 1); 452 int row = 2; 453 if (fDuplex != NULL) { 454 settingsLayout->AddView(fDuplex, 0, row, 2); 455 row ++; 456 } 457 settingsLayout->AddItem(fCopies->CreateLabelLayoutItem(), 0, row); 458 settingsLayout->AddItem(fCopies->CreateTextViewLayoutItem(), 1, row); 459 settingsLayout->SetSpacing(0, 0); 460 461 462 BGroupView* pageSelectionGroup = new BGroupView(B_VERTICAL, 0); 463 BGroupLayout* groupLayout = pageSelectionGroup->GroupLayout(); 464 groupLayout->AddView(fAllPages); 465 groupLayout->AddView(fOddNumberedPages); 466 groupLayout->AddView(fEvenNumberedPages); 467 groupLayout->SetInsets(5, 5, 5, 5); 468 pageSelectionBox->AddChild(pageSelectionGroup); 469 470 SetLayout(new BGroupLayout(B_VERTICAL)); 471 AddChild(BGroupLayoutBuilder(B_VERTICAL, 0) 472 .AddGroup(B_HORIZONTAL, 10, 1.0f) 473 .AddGroup(B_VERTICAL, 10, 1.0f) 474 .Add(qualityBox) 475 .Add(pageRangeBox) 476 .AddGlue() 477 .End() 478 .AddGroup(B_VERTICAL, 0, 1.0f) 479 .Add(settings) 480 .AddStrut(5) 481 .Add(fCollate) 482 .Add(fReverse) 483 .Add(fPages) 484 .AddStrut(5) 485 .Add(pageSelectionBox) 486 .AddGlue() 487 .End() 488 .End() 489 .AddGlue() 490 .Add(separator) 491 .AddGroup(B_HORIZONTAL, 10, 1.0f) 492 .AddGlue() 493 .Add(cancel) 494 .Add(preview) 495 .Add(ok) 496 .End() 497 .SetInsets(0, 0, 0, 0) 498 ); 499 500 fHalftone->preview(fJobData->getGamma(), fJobData->getInkDensity(), 501 fJobData->getDitherType(), fJobData->getColor() != JobData::kMonochrome); 502 503 UpdateButtonEnabledState(); 504 } 505 506 507 void 508 JobSetupView::UpdateButtonEnabledState() 509 { 510 bool pageRangeEnabled = fAll->Value() != B_CONTROL_ON; 511 fFromPage->SetEnabled(pageRangeEnabled); 512 fToPage->SetEnabled(pageRangeEnabled); 513 514 bool pageSelectionEnabled = fDuplex == NULL || 515 fDuplex->Value() != B_CONTROL_ON; 516 fAllPages->SetEnabled(pageSelectionEnabled); 517 fOddNumberedPages->SetEnabled(pageSelectionEnabled); 518 fEvenNumberedPages->SetEnabled(pageSelectionEnabled); 519 } 520 521 522 void 523 JobSetupView::MessageReceived(BMessage *msg) 524 { 525 switch (msg->what) { 526 case kMsgRangeAll: 527 case kMsgRangeSelection: 528 case kMsgDuplexChanged: 529 UpdateButtonEnabledState(); 530 break; 531 532 case kMsgQuality: 533 fHalftone->preview(getGamma(), getInkDensity(), getDitherType(), getColor() != JobData::kMonochrome); 534 break; 535 536 case kMsgCollateChanged: 537 fPages->setCollate(fCollate->Value() == B_CONTROL_ON); 538 break; 539 540 case kMsgReverseChanged: 541 fPages->setReverse(fReverse->Value() == B_CONTROL_ON); 542 break; 543 } 544 } 545 546 547 JobData::Color 548 JobSetupView::getColor() 549 { 550 int count = fPrinterCap->countCap(PrinterCap::kColor); 551 const ColorCap **color_cap = (const ColorCap**)fPrinterCap->enumCap(PrinterCap::kColor); 552 const char *color_label = fColorType->FindMarked()->Label(); 553 while (count--) { 554 if (!strcmp((*color_cap)->fLabel.c_str(), color_label)) { 555 return (*color_cap)->fColor; 556 } 557 color_cap++; 558 } 559 return JobData::kMonochrome; 560 } 561 562 563 Halftone::DitherType 564 JobSetupView::getDitherType() 565 { 566 int count = sizeof(gDitherTypes) / sizeof(gDitherTypes[0]); 567 const DitherCap **dither_cap = gDitherTypes; 568 const char *dithering_label = fDitherType->FindMarked()->Label(); 569 while (count --) { 570 if (strcmp((*dither_cap)->fLabel.c_str(), dithering_label) == 0) { 571 return (*dither_cap)->fDitherType; 572 } 573 dither_cap ++; 574 } 575 return Halftone::kTypeFloydSteinberg; 576 } 577 578 float 579 JobSetupView::getGamma() 580 { 581 const float value = (float)fGamma->Value(); 582 return pow(2.0, value / 100.0); 583 } 584 585 586 float 587 JobSetupView::getInkDensity() 588 { 589 const float value = (float)(127 - fInkDensity->Value()); 590 return value; 591 } 592 593 594 bool 595 JobSetupView::UpdateJobData(bool showPreview) 596 { 597 int count; 598 599 fJobData->setShowPreview(showPreview); 600 fJobData->setColor(getColor()); 601 fJobData->setGamma(getGamma()); 602 fJobData->setInkDensity(getInkDensity()); 603 fJobData->setDitherType(getDitherType()); 604 605 int first_page; 606 int last_page; 607 608 if (B_CONTROL_ON == fAll->Value()) { 609 first_page = 1; 610 last_page = -1; 611 } else { 612 first_page = atoi(fFromPage->Text()); 613 last_page = atoi(fToPage->Text()); 614 } 615 616 fJobData->setFirstPage(first_page); 617 fJobData->setLastPage(last_page); 618 619 count = fPrinterCap->countCap(PrinterCap::kPaperSource); 620 const PaperSourceCap **paper_source_cap = (const PaperSourceCap **)fPrinterCap->enumCap(PrinterCap::kPaperSource); 621 const char *paper_source_label = fPaperFeed->FindMarked()->Label(); 622 while (count--) { 623 if (!strcmp((*paper_source_cap)->fLabel.c_str(), paper_source_label)) { 624 fJobData->setPaperSource((*paper_source_cap)->fPaperSource); 625 break; 626 } 627 paper_source_cap++; 628 } 629 630 count = sizeof(gNups) / sizeof(gNups[0]); 631 const NupCap **nup_cap = gNups; 632 const char *nup_label = fNup->FindMarked()->Label(); 633 while (count--) { 634 if (!strcmp((*nup_cap)->fLabel.c_str(), nup_label)) { 635 fJobData->setNup((*nup_cap)->fNup); 636 break; 637 } 638 nup_cap++; 639 } 640 641 if (fPrinterCap->isSupport(PrinterCap::kPrintStyle)) { 642 fJobData->setPrintStyle((B_CONTROL_ON == fDuplex->Value()) ? JobData::kDuplex : JobData::kSimplex); 643 } 644 645 fJobData->setCopies(atoi(fCopies->Text())); 646 647 fJobData->setCollate((B_CONTROL_ON == fCollate->Value()) ? true : false); 648 fJobData->setReverse((B_CONTROL_ON == fReverse->Value()) ? true : false); 649 650 JobData::PageSelection pageSelection = JobData::kAllPages; 651 if (fOddNumberedPages->Value() == B_CONTROL_ON) 652 pageSelection = JobData::kOddNumberedPages; 653 if (fEvenNumberedPages->Value() == B_CONTROL_ON) 654 pageSelection = JobData::kEvenNumberedPages; 655 fJobData->setPageSelection(pageSelection); 656 657 fJobData->save(); 658 return true; 659 } 660 661 662 JobSetupDlg::JobSetupDlg(JobData *job_data, PrinterData *printer_data, 663 const PrinterCap *printer_cap) 664 : 665 DialogWindow(BRect(100, 100, 200, 200), "PrintJob Setup", 666 B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, 667 B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE 668 | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) 669 { 670 SetResult(B_ERROR); 671 AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED)); 672 673 fJobSetup = new JobSetupView(job_data, printer_data, printer_cap); 674 SetLayout(new BGroupLayout(B_VERTICAL)); 675 AddChild(BGroupLayoutBuilder(B_VERTICAL, 0) 676 .Add(fJobSetup) 677 .SetInsets(10, 10, 10, 10) 678 ); 679 } 680 681 682 void 683 JobSetupDlg::MessageReceived(BMessage *msg) 684 { 685 switch (msg->what) { 686 case kMsgOK: 687 case kMsgPreview: 688 fJobSetup->UpdateJobData(msg->what == kMsgPreview); 689 SetResult(B_NO_ERROR); 690 PostMessage(B_QUIT_REQUESTED); 691 break; 692 693 case kMsgCancel: 694 PostMessage(B_QUIT_REQUESTED); 695 break; 696 697 default: 698 DialogWindow::MessageReceived(msg); 699 break; 700 } 701 } 702