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 <Looper.h> 21 #include <MessageFilter.h> 22 #include <MenuField.h> 23 #include <MenuItem.h> 24 #include <Message.h> 25 #include <Point.h> 26 #include <PopUpMenu.h> 27 #include <PrintJob.h> 28 #include <RadioButton.h> 29 #include <Rect.h> 30 #include <Slider.h> 31 #include <String.h> 32 #include <TextControl.h> 33 #include <TextView.h> 34 #include <View.h> 35 36 #include "HalftoneView.h" 37 #include "JobSetupDlg.h" 38 #include "JobData.h" 39 #include "JSDSlider.h" 40 #include "PagesView.h" 41 #include "PrinterData.h" 42 #include "PrinterCap.h" 43 #include "DbgMsg.h" 44 45 #if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) 46 using namespace std; 47 #else 48 #define std 49 #endif 50 51 //#define PRINT_COPIES 100 52 53 #define QUALITY_H 10 54 #define QUALITY_V 10 55 #define QUALITY_WIDTH 180 56 57 #define BPP_H 10 58 #define BPP_V 15 59 #define BPP_WIDTH 120 60 #define BPP_HEIGHT 16 61 62 #define DITHER_H BPP_H 63 #define DITHER_V BPP_V + BPP_HEIGHT + 10 64 #define DITHER_WIDTH BPP_WIDTH 65 #define DITHER_HEIGHT BPP_HEIGHT 66 67 #define GAMMA_H BPP_H 68 #define GAMMA_V DITHER_V + DITHER_HEIGHT + 10 69 #define GAMMA_WIDTH QUALITY_WIDTH - 20 70 #define GAMMA_HEIGHT 55 // BPP_HEIGHT 71 72 #define INK_DENSITY_H BPP_H 73 #define INK_DENSITY_V GAMMA_V + GAMMA_HEIGHT + 5 74 #define INK_DENSITY_WIDTH GAMMA_WIDTH 75 #define INK_DENSITY_HEIGHT 55 // BPP_HEIGHT 76 77 #define HALFTONE_H INK_DENSITY_H 78 #define HALFTONE_V INK_DENSITY_V + INK_DENSITY_HEIGHT + 5 79 #define HALFTONE_WIDTH 160 80 #define HALFTONE_HEIGHT 4*11 81 82 #define QUALITY_HEIGHT HALFTONE_V + HALFTONE_HEIGHT + 5 83 84 #define PAGERABGE_H QUALITY_H 85 #define PAGERABGE_V QUALITY_V + QUALITY_HEIGHT + 5 86 #define PAGERABGE_WIDTH QUALITY_WIDTH 87 #define PAGERABGE_HEIGHT 70 88 89 #define ALL_H 10 90 #define ALL_V 20 91 #define ALL_WIDTH 36 92 #define ALL_HEIGHT 16 93 94 #define SELECTION_H ALL_H 95 #define SELECTION_V ALL_V + ALL_HEIGHT + 4 96 #define SELECTION_WIDTH 16 97 #define SELECTION_HEIGHT 16 98 99 #define FROM_H (SELECTION_H + SELECTION_WIDTH + 1) 100 #define FROM_V ALL_V + 19 101 #define FROM_WIDTH 73 102 #define FROM_HEIGHT 16 103 104 #define TO_H (FROM_H + FROM_WIDTH + 7) 105 #define TO_V FROM_V 106 #define TO_WIDTH 59 107 #define TO_HEIGHT FROM_HEIGHT 108 109 #define PRINT_WIDTH 365 110 #define PRINT_HEIGHT QUALITY_HEIGHT + PAGERABGE_HEIGHT + 60 111 112 #define PAPERFEED_H QUALITY_H + QUALITY_WIDTH + 10 113 #define PAPERFEED_V QUALITY_V + 5 114 #define PAPERFEED_WIDTH 160 115 #define PAPERFEED_HEIGHT 16 116 117 #define NUP_H PAPERFEED_H 118 #define NUP_V PAPERFEED_V + PAPERFEED_HEIGHT + 7 119 #define NUP_WIDTH PAPERFEED_WIDTH 120 #define NUP_HEIGHT 16 121 #define MENU_HEIGHT 16 122 123 #define COPIES_H PAPERFEED_H 124 #define COPIES_V NUP_V + NUP_HEIGHT + 10 125 #define COPIES_WIDTH 140 126 #define COPIES_HEIGHT 16 127 128 #define DUPLEX_H PAPERFEED_H 129 #define DUPLEX_V COPIES_V + COPIES_HEIGHT + 7 130 #define DUPLEX_WIDTH PAPERFEED_WIDTH 131 #define DUPLEX_HEIGHT 16 132 133 #define COLLATE_H PAPERFEED_H 134 #define COLLATE_V DUPLEX_V + DUPLEX_HEIGHT + 5 135 #define COLLATE_WIDTH PAPERFEED_WIDTH 136 #define COLLATE_HEIGHT 16 137 138 #define REVERSE_H PAPERFEED_H 139 #define REVERSE_V COLLATE_V + COLLATE_HEIGHT + 5 140 #define REVERSE_WIDTH PAPERFEED_WIDTH 141 #define REVERSE_HEIGHT 16 142 143 #define PAGES_H PAPERFEED_H 144 #define PAGES_V REVERSE_V + REVERSE_HEIGHT + 5 145 #define PAGES_WIDTH PAPERFEED_WIDTH 146 #define PAGES_HEIGHT 40 147 148 #define PAGE_SELECTION_H PAPERFEED_H 149 #define PAGE_SELECTION_V PAGES_V + PAGES_HEIGHT + 5 150 #define PAGE_SELECTION_WIDTH PAPERFEED_WIDTH 151 #define PAGE_SELECTION_HEIGHT 3 * 16 + 30 152 153 #define PS_ALL_PAGES_H 10 154 #define PS_ALL_PAGES_V 20 155 #define PS_ALL_PAGES_WIDTH PAGE_SELECTION_WIDTH - 20 156 #define PS_ALL_PAGES_HEIGHT 16 157 158 #define PS_ODD_PAGES_H PS_ALL_PAGES_H 159 #define PS_ODD_PAGES_V PS_ALL_PAGES_V + PS_ALL_PAGES_HEIGHT 160 #define PS_ODD_PAGES_WIDTH PS_ALL_PAGES_WIDTH 161 #define PS_ODD_PAGES_HEIGHT PS_ALL_PAGES_HEIGHT 162 163 #define PS_EVEN_PAGES_H PS_ALL_PAGES_H 164 #define PS_EVEN_PAGES_V PS_ODD_PAGES_V + PS_ODD_PAGES_HEIGHT 165 #define PS_EVEN_PAGES_WIDTH PS_ALL_PAGES_WIDTH 166 #define PS_EVEN_PAGES_HEIGHT PS_ALL_PAGES_HEIGHT 167 168 #define PRINT_BUTTON_WIDTH 70 169 #define PRINT_BUTTON_HEIGHT 20 170 171 #define PRINT_LINE_V (PRINT_HEIGHT - PRINT_BUTTON_HEIGHT - 23) 172 173 #define PRINT_OK_BUTTON_H (PRINT_WIDTH - PRINT_BUTTON_WIDTH - 10) 174 #define PRINT_OK_BUTTON_V (PRINT_HEIGHT - PRINT_BUTTON_HEIGHT - 11) 175 176 #define PREVIEW_H (PRINT_OK_BUTTON_H - PRINT_BUTTON_WIDTH - 12) 177 #define PREVIEW_V (PRINT_OK_BUTTON_V) 178 179 #define PRINT_CANCEL_BUTTON_H (PREVIEW_H - PRINT_BUTTON_WIDTH - 12) 180 #define PRINT_CANCEL_BUTTON_V PRINT_OK_BUTTON_V 181 182 const BRect quality_rect( 183 QUALITY_H, 184 QUALITY_V, 185 QUALITY_H + QUALITY_WIDTH, 186 QUALITY_V + QUALITY_HEIGHT); 187 188 BRect bpp_rect( 189 BPP_H, 190 BPP_V, 191 BPP_H + BPP_WIDTH, 192 BPP_V + BPP_HEIGHT); 193 194 BRect dither_rect( 195 DITHER_H, 196 DITHER_V, 197 DITHER_H + DITHER_WIDTH, 198 DITHER_V + DITHER_HEIGHT); 199 200 const BRect ink_density_rect( 201 INK_DENSITY_H, 202 INK_DENSITY_V, 203 INK_DENSITY_H + INK_DENSITY_WIDTH, 204 INK_DENSITY_V + INK_DENSITY_HEIGHT); 205 206 const BRect halftone_rect( 207 HALFTONE_H, 208 HALFTONE_V, 209 HALFTONE_H + HALFTONE_WIDTH, 210 HALFTONE_V + HALFTONE_HEIGHT); 211 212 const BRect gamma_rect( 213 GAMMA_H, 214 GAMMA_V, 215 GAMMA_H + GAMMA_WIDTH, 216 GAMMA_V + GAMMA_HEIGHT); 217 218 const BRect pagerange_rect( 219 PAGERABGE_H, 220 PAGERABGE_V, 221 PAGERABGE_H + PAGERABGE_WIDTH, 222 PAGERABGE_V + PAGERABGE_HEIGHT); 223 224 const BRect all_button_rect( 225 ALL_H, 226 ALL_V, 227 ALL_H + ALL_WIDTH, 228 ALL_V + ALL_HEIGHT); 229 230 const BRect selection_rect( 231 SELECTION_H, 232 SELECTION_V, 233 SELECTION_H + SELECTION_WIDTH, 234 SELECTION_V + SELECTION_HEIGHT); 235 236 const BRect from_rect( 237 FROM_H, 238 FROM_V, 239 FROM_H + FROM_WIDTH, 240 FROM_V + FROM_HEIGHT); 241 242 const BRect to_rect( 243 TO_H, 244 TO_V, 245 TO_H + TO_WIDTH, 246 TO_V + TO_HEIGHT); 247 248 const BRect paperfeed_rect( 249 PAPERFEED_H, 250 PAPERFEED_V, 251 PAPERFEED_H + PAPERFEED_WIDTH, 252 PAPERFEED_V + PAPERFEED_HEIGHT); 253 254 BRect nup_rect( 255 NUP_H, 256 NUP_V, 257 NUP_H + NUP_WIDTH, 258 NUP_V + NUP_HEIGHT); 259 260 const BRect copies_rect( 261 COPIES_H, 262 COPIES_V, 263 COPIES_H + COPIES_WIDTH, 264 COPIES_V + COPIES_HEIGHT); 265 266 const BRect duplex_rect( 267 DUPLEX_H, 268 DUPLEX_V, 269 DUPLEX_H + DUPLEX_WIDTH, 270 DUPLEX_V + DUPLEX_HEIGHT); 271 272 const BRect collate_rect( 273 COLLATE_H, 274 COLLATE_V, 275 COLLATE_H + COLLATE_WIDTH, 276 COLLATE_V + COLLATE_HEIGHT); 277 278 const BRect reverse_rect( 279 REVERSE_H, 280 REVERSE_V, 281 REVERSE_H + REVERSE_WIDTH, 282 REVERSE_V + REVERSE_HEIGHT); 283 284 const BRect pages_rect( 285 PAGES_H, 286 PAGES_V, 287 PAGES_H + PAGES_WIDTH, 288 PAGES_V + PAGES_HEIGHT); 289 290 const BRect page_selection_rect( 291 PAGE_SELECTION_H, 292 PAGE_SELECTION_V, 293 PAGE_SELECTION_H + PAGE_SELECTION_WIDTH, 294 PAGE_SELECTION_V + PAGE_SELECTION_HEIGHT); 295 296 const BRect page_selection_all_pages_rect( 297 PS_ALL_PAGES_H, 298 PS_ALL_PAGES_V, 299 PS_ALL_PAGES_H + PS_ALL_PAGES_WIDTH, 300 PS_ALL_PAGES_V + PS_ALL_PAGES_HEIGHT); 301 302 const BRect page_selection_odd_pages_rect( 303 PS_ODD_PAGES_H, 304 PS_ODD_PAGES_V, 305 PS_ODD_PAGES_H + PS_ODD_PAGES_WIDTH, 306 PS_ODD_PAGES_V + PS_ODD_PAGES_HEIGHT); 307 308 const BRect page_selection_even_pages_rect( 309 PS_EVEN_PAGES_H, 310 PS_EVEN_PAGES_V, 311 PS_EVEN_PAGES_H + PS_EVEN_PAGES_WIDTH, 312 PS_EVEN_PAGES_V + PS_EVEN_PAGES_HEIGHT); 313 314 const BRect ok_rect( 315 PRINT_OK_BUTTON_H, 316 PRINT_OK_BUTTON_V, 317 PRINT_OK_BUTTON_H + PRINT_BUTTON_WIDTH, 318 PRINT_OK_BUTTON_V + PRINT_BUTTON_HEIGHT); 319 320 const BRect cancel_rect( 321 PRINT_CANCEL_BUTTON_H, 322 PRINT_CANCEL_BUTTON_V, 323 PRINT_CANCEL_BUTTON_H + PRINT_BUTTON_WIDTH, 324 PRINT_CANCEL_BUTTON_V + PRINT_BUTTON_HEIGHT); 325 326 const BRect preview_rect( 327 PREVIEW_H, 328 PREVIEW_V, 329 PREVIEW_H + PRINT_BUTTON_WIDTH, 330 PREVIEW_V + PRINT_BUTTON_HEIGHT); 331 332 333 334 struct SurfaceCap : public BaseCap { 335 color_space surface_type; 336 SurfaceCap(const string &s, bool d, color_space cs) : BaseCap(s, d), surface_type(cs) {} 337 }; 338 339 struct NupCap : public BaseCap { 340 int nup; 341 NupCap(const string &s, bool d, int n) : BaseCap(s, d), nup(n) {} 342 }; 343 344 struct DitherCap : public BaseCap { 345 Halftone::DitherType dither_type; 346 DitherCap(const string &s, bool d, Halftone::DitherType type) : BaseCap(s, d), dither_type(type) {} 347 }; 348 349 static const SurfaceCap gRGB32("RGB32", false, B_RGB32); 350 static const SurfaceCap gCMAP8("CMAP8", true, B_CMAP8); 351 static const SurfaceCap gGray8("GRAY8", false, B_GRAY8); 352 static const SurfaceCap gGray1("GRAY1", false, B_GRAY1); 353 354 static const NupCap gNup1("1", true, 1); 355 static const NupCap gNup2("2", false, 2); 356 static const NupCap gNup4("4", false, 4); 357 static const NupCap gNup8("8", false, 8); 358 static const NupCap gNup9("9", false, 9); 359 static const NupCap gNup16("16", false, 16); 360 static const NupCap gNup25("25", false, 25); 361 static const NupCap gNup32("32", false, 32); 362 static const NupCap gNup36("36", false, 36); 363 364 static const DitherCap gDitherType1("Crosshatch", false, Halftone::kType1); 365 static const DitherCap gDitherType2("Grid", false, Halftone::kType2); 366 static const DitherCap gDitherType3("Stipple", false, Halftone::kType3); 367 static const DitherCap gDitherFloydSteinberg("Floyd-Steinberg", false, Halftone::kTypeFloydSteinberg); 368 369 const SurfaceCap *gSurfaces[] = { 370 &gRGB32, 371 &gCMAP8, 372 &gGray8, 373 &gGray1 374 }; 375 376 const NupCap *gNups[] = { 377 &gNup1, 378 &gNup2, 379 &gNup4, 380 &gNup8, 381 &gNup9, 382 &gNup16, 383 &gNup25, 384 &gNup32, 385 &gNup36 386 }; 387 388 const DitherCap *gDitherTypes[] = { 389 &gDitherType1, 390 &gDitherType2, 391 &gDitherType3, 392 &gDitherFloydSteinberg 393 }; 394 395 enum { 396 kMsgRangeAll = 'JSdl', 397 kMsgRangeSelection, 398 kMsgPreview, 399 kMsgCancel, 400 kMsgOK, 401 kMsgQuality, 402 kMsgCollateChanged, 403 kMsgReverseChanged, 404 kMsgDuplexChanged, 405 }; 406 407 JobSetupView::JobSetupView(BRect frame, JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) 408 : BView(frame, "", B_FOLLOW_ALL, B_WILL_DRAW), fJobData(job_data), fPrinterData(printer_data), fPrinterCap(printer_cap) 409 { 410 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 411 } 412 413 BRadioButton* 414 JobSetupView::AddPageSelectionItem(BView* parent, BRect rect, const char* name, const char* label, 415 JobData::PageSelection pageSelection) 416 { 417 BRadioButton* button = new BRadioButton(rect, name, label, NULL); 418 if (fJobData->getPageSelection() == pageSelection) { 419 button->SetValue(B_CONTROL_ON); 420 } 421 parent->AddChild(button); 422 return button; 423 } 424 425 void 426 JobSetupView::AllowOnlyDigits(BTextView* textView, int maxDigits) 427 { 428 int num; 429 for (num = 0; num <= 255; num++) { 430 textView->DisallowChar(num); 431 } 432 for (num = 0; num <= 9; num++) { 433 textView->AllowChar('0' + num); 434 } 435 textView->SetMaxBytes(maxDigits); 436 } 437 438 void 439 JobSetupView::AttachedToWindow() 440 { 441 BBox *box; 442 BMenuItem *item = NULL; 443 BMenuField *menufield; 444 BButton *button; 445 float width; 446 bool marked; 447 int count; 448 449 /* quality */ 450 451 box = new BBox(quality_rect); 452 AddChild(box); 453 box->SetLabel("Quality"); 454 455 /* 456 // always B_RGB32 457 fSurfaceType = new BPopUpMenu(""); 458 fSurfaceType->SetRadioMode(true); 459 460 count = sizeof(gSurfaces) / sizeof(gSurfaces[0]); 461 const SurfaceCap **surface_cap = gSurfaces; 462 uint32 support_flags; 463 while (count--) { 464 if (bitmaps_support_space((*surface_cap)->surface_type, &support_flags)) { 465 item = new BMenuItem((*surface_cap)->label.c_str(), NULL); 466 fSurfaceType->AddItem(item); 467 if ((*surface_cap)->surface_type == fJobData->getSurfaceType()) { 468 item->SetMarked(true); 469 marked = true; 470 } 471 } 472 surface_cap++; 473 } 474 menufield = new BMenuField(bpp_rect, "", "Surface Type", fSurfaceType); 475 box->AddChild(menufield); 476 width = StringWidth("Color") + 10; 477 menufield->SetDivider(width); 478 */ 479 480 /* color */ 481 marked = false; 482 fColorType = new BPopUpMenu(""); 483 fColorType->SetRadioMode(true); 484 485 count = fPrinterCap->countCap(PrinterCap::kColor); 486 const ColorCap **color_cap = (const ColorCap **)fPrinterCap->enumCap(PrinterCap::kColor); 487 while (count--) { 488 item = new BMenuItem((*color_cap)->label.c_str(), new BMessage(kMsgQuality)); 489 fColorType->AddItem(item); 490 if ((*color_cap)->color == fJobData->getColor()) { 491 item->SetMarked(true); 492 marked = true; 493 } 494 color_cap++; 495 } 496 if (!marked && item) 497 item->SetMarked(true); 498 bpp_rect.right = bpp_rect.left + StringWidth("Color:") + fColorType->MaxContentWidth() + 10; 499 menufield = new BMenuField(bpp_rect, "color", "Color:", fColorType); 500 501 box->AddChild(menufield); 502 width = StringWidth("Color:") + 10; 503 menufield->SetDivider(width); 504 fColorType->SetTargetForItems(this); 505 506 /* dither type */ 507 marked = false; 508 fDitherType = new BPopUpMenu(""); 509 fDitherType->SetRadioMode(true); 510 511 count = sizeof(gDitherTypes) / sizeof(gDitherTypes[0]); 512 const DitherCap **dither_cap = gDitherTypes; 513 while (count--) { 514 item = new BMenuItem((*dither_cap)->label.c_str(), new BMessage(kMsgQuality)); 515 fDitherType->AddItem(item); 516 if ((*dither_cap)->dither_type == fJobData->getDitherType()) { 517 item->SetMarked(true); 518 marked = true; 519 } 520 dither_cap++; 521 } 522 if (!marked && item) 523 item->SetMarked(true); 524 dither_rect.right = dither_rect.left + StringWidth("Dot Pattern:") + fDitherType->MaxContentWidth() + 20; 525 menufield = new BMenuField(dither_rect, "dithering", "Dot Pattern:", fDitherType); 526 527 box->AddChild(menufield); 528 width = StringWidth("Dot Pattern:") + 10; 529 menufield->SetDivider(width); 530 fDitherType->SetTargetForItems(this); 531 532 /* halftone preview view */ 533 BRect rect(halftone_rect); 534 BBox* halftoneBorder = new BBox(rect.InsetByCopy(-1, -1)); 535 box->AddChild(halftoneBorder); 536 halftoneBorder->SetBorder(B_PLAIN_BORDER); 537 538 fHalftone = new HalftoneView(rect.OffsetToCopy(1, 1), "halftone", B_FOLLOW_ALL, B_WILL_DRAW); 539 halftoneBorder->AddChild(fHalftone); 540 fHalftone->preview(fJobData->getGamma(), fJobData->getInkDensity(), fJobData->getDitherType(), fJobData->getColor() != JobData::kMonochrome); 541 542 /* gamma */ 543 fGamma = new JSDSlider(gamma_rect, "gamma", "Gamma", new BMessage(kMsgQuality), -300, 300, B_BLOCK_THUMB); 544 545 fGamma->SetLimitLabels("Lighter", "Darker"); 546 fGamma->SetValue((int32)(100 * log(fJobData->getGamma()) / log(2.0))); 547 fGamma->SetHashMarks(B_HASH_MARKS_BOTH); 548 fGamma->SetHashMarkCount(7); 549 box->AddChild(fGamma); 550 fGamma->SetModificationMessage(new BMessage(kMsgQuality)); 551 fGamma->SetTarget(this); 552 553 /* ink density */ 554 fInkDensity = new JSDSlider(ink_density_rect, "inkDensity", "Ink Usage", new BMessage(kMsgQuality), 0, 127, B_BLOCK_THUMB); 555 556 fInkDensity->SetLimitLabels("Min", "Max"); 557 fInkDensity->SetValue((int32)fJobData->getInkDensity()); 558 fInkDensity->SetHashMarks(B_HASH_MARKS_BOTH); 559 fInkDensity->SetHashMarkCount(10); 560 box->AddChild(fInkDensity); 561 fInkDensity->SetModificationMessage(new BMessage(kMsgQuality)); 562 fInkDensity->SetTarget(this); 563 564 /* page range */ 565 566 box = new BBox(pagerange_rect); 567 AddChild(box); 568 box->SetLabel("Page Range"); 569 570 fAll = new BRadioButton(all_button_rect, "all", "All", new BMessage(kMsgRangeAll)); 571 box->AddChild(fAll); 572 573 BRadioButton *from = new BRadioButton(selection_rect, "selection", "", new BMessage(kMsgRangeSelection)); 574 box->AddChild(from); 575 576 fFromPage = new BTextControl(from_rect, "from", "From", "", NULL); 577 box->AddChild(fFromPage); 578 fFromPage->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); 579 fFromPage->SetDivider(StringWidth("From") + 7); 580 AllowOnlyDigits(fFromPage->TextView(), 6); 581 582 fToPage = new BTextControl(to_rect, "to", "To", "", NULL); 583 box->AddChild(fToPage); 584 fToPage->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); 585 fToPage->SetDivider(StringWidth("To") + 7); 586 AllowOnlyDigits(fToPage->TextView(), 6); 587 588 int first_page = fJobData->getFirstPage(); 589 int last_page = fJobData->getLastPage(); 590 591 if (first_page <= 1 && last_page <= 0) { 592 fAll->SetValue(B_CONTROL_ON); 593 } else { 594 from->SetValue(B_CONTROL_ON); 595 if (first_page < 1) 596 first_page = 1; 597 if (first_page > last_page) 598 last_page = -1; 599 600 BString oss1; 601 oss1 << first_page; 602 fFromPage->SetText(oss1.String()); 603 604 BString oss2; 605 oss2 << last_page; 606 fToPage->SetText(oss2.String()); 607 } 608 609 fAll->SetTarget(this); 610 from->SetTarget(this); 611 612 /* paper source */ 613 614 marked = false; 615 fPaperFeed = new BPopUpMenu(""); 616 fPaperFeed->SetRadioMode(true); 617 count = fPrinterCap->countCap(PrinterCap::kPaperSource); 618 const PaperSourceCap **paper_source_cap = (const PaperSourceCap **)fPrinterCap->enumCap(PrinterCap::kPaperSource); 619 while (count--) { 620 item = new BMenuItem((*paper_source_cap)->label.c_str(), NULL); 621 fPaperFeed->AddItem(item); 622 if ((*paper_source_cap)->paper_source == fJobData->getPaperSource()) { 623 item->SetMarked(true); 624 marked = true; 625 } 626 paper_source_cap++; 627 } 628 if (!marked) 629 item->SetMarked(true); 630 menufield = new BMenuField(paperfeed_rect, "paperSource", "Paper Source:", fPaperFeed); 631 AddChild(menufield); 632 width = StringWidth("Number of Copies:") + 7; 633 menufield->SetDivider(width); 634 635 /* Page Per Sheet */ 636 637 marked = false; 638 fNup = new BPopUpMenu(""); 639 fNup->SetRadioMode(true); 640 count = sizeof(gNups) / sizeof(gNups[0]); 641 const NupCap **nup_cap = gNups; 642 while (count--) { 643 item = new BMenuItem((*nup_cap)->label.c_str(), NULL); 644 fNup->AddItem(item); 645 if ((*nup_cap)->nup == fJobData->getNup()) { 646 item->SetMarked(true); 647 marked = true; 648 } 649 nup_cap++; 650 } 651 if (!marked) 652 item->SetMarked(true); 653 menufield = new BMenuField(nup_rect, "pagePerSheet", "Pages Per Sheet:", fNup); 654 menufield->SetDivider(StringWidth("Number of Copies:") + 7); 655 AddChild(menufield); 656 657 /* duplex */ 658 659 if (fPrinterCap->isSupport(PrinterCap::kPrintStyle)) { 660 fDuplex = new BCheckBox(duplex_rect, "duplex", "Duplex", new BMessage(kMsgDuplexChanged)); 661 AddChild(fDuplex); 662 if (fJobData->getPrintStyle() != JobData::kSimplex) { 663 fDuplex->SetValue(B_CONTROL_ON); 664 } 665 fDuplex->SetTarget(this); 666 } else { 667 fDuplex = NULL; 668 } 669 670 /* copies */ 671 672 fCopies = new BTextControl(copies_rect, "copies", "Number of Copies:", "", NULL); 673 AddChild(fCopies); 674 fCopies->SetDivider(width); 675 AllowOnlyDigits(fCopies->TextView(), 3); 676 677 BString oss4; 678 oss4 << fJobData->getCopies(); 679 fCopies->SetText(oss4.String()); 680 681 /* collate */ 682 683 fCollate = new BCheckBox(collate_rect, "collate", "Collate", new BMessage(kMsgCollateChanged)); 684 fCollate->ResizeToPreferred(); 685 AddChild(fCollate); 686 if (fJobData->getCollate()) { 687 fCollate->SetValue(B_CONTROL_ON); 688 } 689 fCollate->SetTarget(this); 690 691 /* reverse */ 692 693 fReverse = new BCheckBox(reverse_rect, "reverse", "Reverse Order", new BMessage(kMsgReverseChanged)); 694 fReverse->ResizeToPreferred(); 695 AddChild(fReverse); 696 if (fJobData->getReverse()) { 697 fReverse->SetValue(B_CONTROL_ON); 698 } 699 fReverse->SetTarget(this); 700 701 /* pages view */ 702 703 fPages = new PagesView(pages_rect, "pages", B_FOLLOW_ALL, B_WILL_DRAW); 704 AddChild(fPages); 705 fPages->setCollate(fJobData->getCollate()); 706 fPages->setReverse(fJobData->getReverse()); 707 708 /* page selection */ 709 BBox* pageSelectionBox = new BBox(page_selection_rect); 710 AddChild(pageSelectionBox); 711 pageSelectionBox->SetLabel("Page Selection"); 712 713 fAllPages = AddPageSelectionItem(pageSelectionBox, page_selection_all_pages_rect, "allPages", "All Pages", JobData::kAllPages); 714 fOddNumberedPages = AddPageSelectionItem(pageSelectionBox, page_selection_odd_pages_rect, "oddPages", "Odd-Numbered Pages", JobData::kOddNumberedPages); 715 fEvenNumberedPages = AddPageSelectionItem(pageSelectionBox, page_selection_even_pages_rect, "evenPages", "Even-Numbered Pages", JobData::kEvenNumberedPages); 716 717 718 719 /* preview */ 720 721 button = new BButton(preview_rect, "preview", "Preview" B_UTF8_ELLIPSIS, new BMessage(kMsgPreview)); 722 AddChild(button); 723 724 725 /* cancel */ 726 727 button = new BButton(cancel_rect, "cancel", "Cancel", new BMessage(kMsgCancel)); 728 AddChild(button); 729 730 /* ok */ 731 732 // TODO OK or "Print"? 733 button = new BButton(ok_rect, "ok", "OK", new BMessage(kMsgOK)); 734 AddChild(button); 735 button->MakeDefault(true); 736 737 UpdateButtonEnabledState(); 738 } 739 740 void 741 JobSetupView::UpdateButtonEnabledState() 742 { 743 bool pageRangeEnabled = fAll->Value() != B_CONTROL_ON; 744 fFromPage->SetEnabled(pageRangeEnabled); 745 fToPage->SetEnabled(pageRangeEnabled); 746 747 bool pageSelectionEnabled = fDuplex == NULL || 748 fDuplex->Value() != B_CONTROL_ON; 749 fAllPages->SetEnabled(pageSelectionEnabled); 750 fOddNumberedPages->SetEnabled(pageSelectionEnabled); 751 fEvenNumberedPages->SetEnabled(pageSelectionEnabled); 752 } 753 754 void 755 JobSetupView::MessageReceived(BMessage *msg) 756 { 757 switch (msg->what) { 758 case kMsgRangeAll: 759 case kMsgRangeSelection: 760 case kMsgDuplexChanged: 761 UpdateButtonEnabledState(); 762 break; 763 764 case kMsgQuality: 765 fHalftone->preview(getGamma(), getInkDensity(), getDitherType(), getColor() != JobData::kMonochrome); 766 break; 767 768 case kMsgCollateChanged: 769 fPages->setCollate(fCollate->Value() == B_CONTROL_ON); 770 break; 771 772 case kMsgReverseChanged: 773 fPages->setReverse(fReverse->Value() == B_CONTROL_ON); 774 break; 775 } 776 } 777 778 JobData::Color 779 JobSetupView::getColor() 780 { 781 int count = fPrinterCap->countCap(PrinterCap::kColor); 782 const ColorCap **color_cap = (const ColorCap**)fPrinterCap->enumCap(PrinterCap::kColor); 783 const char *color_label = fColorType->FindMarked()->Label(); 784 while (count--) { 785 if (!strcmp((*color_cap)->label.c_str(), color_label)) { 786 return (*color_cap)->color; 787 } 788 color_cap++; 789 } 790 return JobData::kMonochrome; 791 } 792 793 Halftone::DitherType 794 JobSetupView::getDitherType() 795 { 796 int count = sizeof(gDitherTypes) / sizeof(gDitherTypes[0]); 797 const DitherCap **dither_cap = gDitherTypes; 798 const char *dithering_label = fDitherType->FindMarked()->Label(); 799 while (count --) { 800 if (strcmp((*dither_cap)->label.c_str(), dithering_label) == 0) { 801 return (*dither_cap)->dither_type; 802 } 803 dither_cap ++; 804 } 805 return Halftone::kTypeFloydSteinberg; 806 } 807 808 float 809 JobSetupView::getGamma() 810 { 811 const float value = (float)fGamma->Value(); 812 return pow(2.0, value / 100.0); 813 } 814 815 float 816 JobSetupView::getInkDensity() 817 { 818 const float value = (float)(127 - fInkDensity->Value()); 819 return value; 820 } 821 822 bool 823 JobSetupView::UpdateJobData(bool showPreview) 824 { 825 int count; 826 827 /* 828 count = sizeof(gSurfaces) / sizeof(gSurfaces[0]); 829 const SurfaceCap **surface_cap = gSurfaces; 830 const char *surface_label = fSurfaceType->FindMarked()->Label(); 831 while (count--) { 832 if (!strcmp((*surface_cap)->label.c_str(), surface_label)) { 833 fJobData->setSurfaceType((*surface_cap)->surface_type); 834 break; 835 } 836 surface_cap++; 837 } 838 */ 839 fJobData->setShowPreview(showPreview); 840 fJobData->setColor(getColor()); 841 fJobData->setGamma(getGamma()); 842 fJobData->setInkDensity(getInkDensity()); 843 fJobData->setDitherType(getDitherType()); 844 845 int first_page; 846 int last_page; 847 848 if (B_CONTROL_ON == fAll->Value()) { 849 first_page = 1; 850 last_page = -1; 851 } else { 852 first_page = atoi(fFromPage->Text()); 853 last_page = atoi(fToPage->Text()); 854 } 855 856 fJobData->setFirstPage(first_page); 857 fJobData->setLastPage(last_page); 858 859 count = fPrinterCap->countCap(PrinterCap::kPaperSource); 860 const PaperSourceCap **paper_source_cap = (const PaperSourceCap **)fPrinterCap->enumCap(PrinterCap::kPaperSource); 861 const char *paper_source_label = fPaperFeed->FindMarked()->Label(); 862 while (count--) { 863 if (!strcmp((*paper_source_cap)->label.c_str(), paper_source_label)) { 864 fJobData->setPaperSource((*paper_source_cap)->paper_source); 865 break; 866 } 867 paper_source_cap++; 868 } 869 870 count = sizeof(gNups) / sizeof(gNups[0]); 871 const NupCap **nup_cap = gNups; 872 const char *nup_label = fNup->FindMarked()->Label(); 873 while (count--) { 874 if (!strcmp((*nup_cap)->label.c_str(), nup_label)) { 875 fJobData->setNup((*nup_cap)->nup); 876 break; 877 } 878 nup_cap++; 879 } 880 881 if (fPrinterCap->isSupport(PrinterCap::kPrintStyle)) { 882 fJobData->setPrintStyle((B_CONTROL_ON == fDuplex->Value()) ? JobData::kDuplex : JobData::kSimplex); 883 } 884 885 fJobData->setCopies(atoi(fCopies->Text())); 886 887 fJobData->setCollate((B_CONTROL_ON == fCollate->Value()) ? true : false); 888 fJobData->setReverse((B_CONTROL_ON == fReverse->Value()) ? true : false); 889 890 JobData::PageSelection pageSelection = JobData::kAllPages; 891 if (fOddNumberedPages->Value() == B_CONTROL_ON) 892 pageSelection = JobData::kOddNumberedPages; 893 if (fEvenNumberedPages->Value() == B_CONTROL_ON) 894 pageSelection = JobData::kEvenNumberedPages; 895 fJobData->setPageSelection(pageSelection); 896 897 fJobData->save(); 898 return true; 899 } 900 901 //==================================================================== 902 903 JobSetupDlg::JobSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) 904 : DialogWindow(BRect(100, 100, 100 + PRINT_WIDTH, 100 + PRINT_HEIGHT), 905 "PrintJob Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, 906 B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS) 907 { 908 SetResult(B_ERROR); 909 AddShortcut('W',B_COMMAND_KEY,new BMessage(B_QUIT_REQUESTED)); 910 911 fJobSetup = new JobSetupView(Bounds(), job_data, printer_data, printer_cap); 912 AddChild(fJobSetup); 913 } 914 915 void 916 JobSetupDlg::MessageReceived(BMessage *msg) 917 { 918 switch (msg->what) { 919 case kMsgOK: 920 case kMsgPreview: 921 fJobSetup->UpdateJobData(msg->what == kMsgPreview); 922 SetResult(B_NO_ERROR); 923 PostMessage(B_QUIT_REQUESTED); 924 break; 925 926 case kMsgCancel: 927 PostMessage(B_QUIT_REQUESTED); 928 break; 929 930 default: 931 DialogWindow::MessageReceived(msg); 932 break; 933 } 934 } 935