1 /* 2 * Copyright (c) 2003-2004 Kian Duffy <myob@users.sourceforge.net> 3 * Copyright (C) 1998,99 Kazuho Okui and Takashi Murai. 4 * Copyright (c) 2004 Daniel Furrer <assimil8or@users.sourceforge.net> 5 * 6 * Distributed unter the terms of the MIT license. 7 */ 8 #include <app/Application.h> 9 #include <Menu.h> 10 #include <MenuBar.h> 11 #include <MenuItem.h> 12 #include <ScrollBar.h> 13 #include <TextControl.h> 14 #include <PrintJob.h> 15 #include <Alert.h> 16 #include <float.h> 17 #include <WindowScreen.h> 18 #include <PropertyInfo.h> 19 20 #include <stdio.h> 21 #include <sys/time.h> 22 #include <string> 23 #include <unistd.h> 24 25 26 #include "TermApp.h" 27 #include "TermParse.h" 28 #include "TermWindow.h" 29 #include "TermView.h" 30 #include "TermBuffer.h" 31 #include "TermBaseView.h" 32 #include "CodeConv.h" 33 #include "TermConst.h" 34 #include "PrefDlg.h" 35 #include "PrefView.h" 36 #include "PrefHandler.h" 37 #include "MenuUtil.h" 38 #include "spawn.h" 39 #include "ColorWindow.h" 40 41 42 // Global Preference Handler 43 extern PrefHandler *gTermPref; 44 // 45 // help and GPL URL 46 // 47 //#define URL_PREFIX "file:///boot/home/config/settings/MuTerminal/help/" 48 //#define INDEX_FILE "/index.html" 49 //#define GPL_FILE "/gpl.html" 50 //#define CHLP_FILE "file:///boot/beos/documentation/Shell%20Tools/index.html" 51 52 extern int gNowCoding; /* defined TermParce.cpp */ 53 char gWindowName[256] = "Terminal"; 54 55 void SetCoding (int); 56 57 /* 58 * 59 * CONSTRUCTOR and DESTRUCTOR 60 * 61 */ 62 63 //////////////////////////////////////////////////////////////////////////// 64 // TermWindow Constructer 65 // 66 //////////////////////////////////////////////////////////////////////////// 67 TermWindow::TermWindow( BRect frame, int32 windownumber) 68 : BWindow (frame, NULL, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE) 69 { 70 sprintf(gWindowName,"Terminal %ld",windownumber); 71 72 InitWindow(); 73 SetWindowTitle(); 74 fPrintSettings = NULL; 75 fPrefWindow = NULL; 76 fFindPanel = NULL; 77 78 } 79 //////////////////////////////////////////////////////////////////////////// 80 // Desctuctor 81 // 82 //////////////////////////////////////////////////////////////////////////// 83 TermWindow::~TermWindow() 84 { 85 if (fWindowUpdate != NULL) 86 delete (fWindowUpdate); 87 } 88 89 90 // #pragma mark - public methods 91 92 93 /** Initialize Window object. */ 94 95 void 96 TermWindow::InitWindow(void) 97 { 98 // make menu bar 99 SetupMenu(); 100 101 // Setup font. 102 103 const char *family = gTermPref->getString(PREF_HALF_FONT_FAMILY); 104 105 BFont halfFont; 106 halfFont.SetFamilyAndStyle(family, NULL); 107 halfFont.SetSize(gTermPref->getFloat(PREF_HALF_FONT_SIZE)); 108 halfFont.SetSpacing(B_FIXED_SPACING); 109 110 family = gTermPref->getString(PREF_FULL_FONT_FAMILY); 111 112 BFont fullFont; 113 fullFont.SetFamilyAndStyle(family, NULL); 114 fullFont.SetSize(gTermPref->getFloat(PREF_FULL_FONT_SIZE)); 115 fullFont.SetSpacing(B_FIXED_SPACING); 116 117 // Make Terminal text view. 118 119 BRect textframe = Bounds(); 120 textframe.top = fMenubar->Bounds().bottom + 1.0; 121 122 fCodeConv = new CodeConv(); 123 fTermView = new TermView(Bounds(), fCodeConv); 124 125 /* 126 * MuTerm has two views. BaseView is window base view. 127 * TermView is character Terminal view on BaseView. It has paste 128 * on BaseView shift as VIEW_OFFSET. 129 */ 130 fBaseView = new TermBaseView(textframe, fTermView); 131 132 // Initialize TermView. (font, size and color) 133 134 fTermView->SetTermFont(&halfFont, &fullFont); 135 BRect rect = fTermView->SetTermSize(gTermPref->getInt32(PREF_ROWS), 136 gTermPref->getInt32(PREF_COLS), 1); 137 138 int width, height; 139 140 fTermView->GetFontSize(&width, &height); 141 SetSizeLimits(MIN_COLS * width, MAX_COLS * width, 142 MIN_COLS * height, MAX_COLS * height); 143 144 fTermView->SetTermColor(); 145 fBaseView->SetViewColor(gTermPref->getRGB(PREF_TEXT_BACK_COLOR)); 146 147 // Add offset to baseview. 148 rect.InsetBy(-VIEW_OFFSET, -VIEW_OFFSET); 149 150 // Resize Window 151 152 ResizeTo(rect.Width()+ B_V_SCROLL_BAR_WIDTH, 153 rect.Height() + fMenubar->Bounds().Height()); 154 155 fBaseView->ResizeTo(rect.Width(), rect.Height()); 156 fBaseView->AddChild(fTermView); 157 fTermView->MoveBy(VIEW_OFFSET, VIEW_OFFSET); 158 159 // Make Scroll Bar. 160 161 BRect scrollRect(0, 0, B_V_SCROLL_BAR_WIDTH, 162 rect.Height() - B_H_SCROLL_BAR_HEIGHT + 1); 163 164 scrollRect.OffsetBy(rect.Width() + 1, fMenubar->Bounds().Height()); 165 166 BScrollBar *scrollBar = new BScrollBar(scrollRect, "scrollbar", 167 fTermView, 0, 0, B_VERTICAL); 168 fTermView->SetScrollBar(scrollBar); 169 170 AddChild(scrollBar); 171 AddChild(fBaseView); 172 173 // Set fEditmenu's target to fTermView. (Oh!...) 174 fEditmenu->SetTargetForItems(fTermView); 175 176 // Initialize TermParse 177 178 gNowCoding = longname2op(gTermPref->getString(PREF_TEXT_ENCODING)); 179 fTermParse = new TermParse(); 180 fTermParse->InitPtyReader(this); 181 fTermParse->InitTermParse(fTermView, fCodeConv); 182 183 // Set Coding. 184 185 // Initialize MessageRunner. 186 fWindowUpdate = new BMessageRunner(BMessenger(this), 187 new BMessage (MSGRUN_WINDOW), 500000); 188 } 189 190 191 void 192 TermWindow::MenusBeginning(void) 193 { 194 // Syncronize Encode Menu Pop-up menu and Preference. 195 (fEncodingmenu->FindItem(op2longname(gNowCoding)))->SetMarked(true); 196 BWindow::MenusBeginning(); 197 } 198 199 200 void 201 TermWindow::SetupMenu(void) 202 { 203 PrefHandler menuText; 204 205 LoadLocaleFile (&menuText); 206 207 // Menu bar object. 208 fMenubar = new BMenuBar(Bounds(), "mbar"); 209 210 /* 211 * Make Fiile Menu. 212 */ 213 fFilemenu = new BMenu("Terminal"); 214 fFilemenu->AddItem(new BMenuItem("Switch Terminals", new BMessage(MENU_SWITCH_TERM),'G')); 215 fFilemenu->AddItem(new BMenuItem("Start New Terminal", new BMessage(MENU_NEW_TREM), 'N')); 216 fFilemenu->AddSeparatorItem(); 217 fFilemenu->AddItem(new BMenuItem("Page Setup...", new BMessage(MENU_PAGE_SETUP))); 218 fFilemenu->AddItem(new BMenuItem("Print", new BMessage(MENU_PRINT),'P')); 219 fFilemenu->AddSeparatorItem(); 220 fFilemenu->AddItem(new BMenuItem("About Terminal...", new BMessage(B_ABOUT_REQUESTED))); 221 fFilemenu->AddSeparatorItem(); 222 fFilemenu->AddItem(new BMenuItem("Quit", new BMessage(MENU_FILE_QUIT), 'Q')); 223 fMenubar->AddItem(fFilemenu); 224 225 /* 226 * Make Edit Menu. 227 */ 228 fEditmenu = new BMenu ("Edit"); 229 fEditmenu->AddItem (new BMenuItem ("Copy", new BMessage (B_COPY),'C')); 230 fEditmenu->AddItem (new BMenuItem ("Paste", new BMessage (B_PASTE),'V')); 231 fEditmenu->AddSeparatorItem (); 232 fEditmenu->AddItem (new BMenuItem ("Select All", new BMessage (B_SELECT_ALL), 'A')); 233 fEditmenu->AddItem (new BMenuItem ("Clear All", new BMessage (MENU_CLEAR_ALL), 'L')); 234 235 /* 236 // TODO: Implement Finding 237 fEditmenu->AddSeparatorItem (); 238 fEditmenu->AddItem (new BMenuItem ("Find", new BMessage (MENU_FIND_STRING),'F')); 239 fEditmenu->AddItem (new BMenuItem ("Find Again", new BMessage (MENU_FIND_AGAIN), ']')); 240 */ 241 fMenubar->AddItem (fEditmenu); 242 243 244 /* 245 * Make Help Menu. 246 */ 247 fHelpmenu = new BMenu("Settings"); 248 fWindowSizeMenu = new BMenu("Window Size"); 249 fWindowSizeMenu->AddItem(new BMenuItem("80x24", new BMessage(EIGHTYTWENTYFOUR))); 250 fWindowSizeMenu->AddItem(new BMenuItem("80x25", new BMessage(EIGHTYTWENTYFIVE))); 251 fWindowSizeMenu->AddItem(new BMenuItem("80x40", new BMessage(EIGHTYFORTY))); 252 fWindowSizeMenu->AddItem(new BMenuItem("132x24", new BMessage(ONETHREETWOTWENTYFOUR))); 253 fWindowSizeMenu->AddItem(new BMenuItem("132x25", new BMessage(ONETHREETWOTWENTYFIVE))); 254 255 // Considering we have this in the preferences window, this menu is not 256 // needed and should not be shown if we are to not confuse the user 257 /* fNewFontMenu = new BMenu("Font"); 258 fNewFontMenu->SetRadioMode(true); 259 int32 numFamilies1 = count_font_families(); 260 for ( int32 i = 0; i < numFamilies1; i++ ) { 261 font_family family; 262 uint32 flags; 263 if ( get_font_family(i, &family, &flags) == B_OK ) { 264 fNewFontMenu->AddItem(item = new BMenuItem(family, new BMessage(MSG_FONT_CHANGED))); 265 // if (0 ==i) item->SetMarked(true); 266 } 267 } 268 fNewFontMenu->FindItem (gTermPref->getString(PREF_HALF_FONT_FAMILY))->SetMarked(true); 269 */ 270 271 fEncodingmenu = new BMenu("Font Encoding"); 272 fEncodingmenu->SetRadioMode(true); 273 MakeEncodingMenu(fEncodingmenu, gNowCoding, true); 274 fHelpmenu->AddItem(fWindowSizeMenu); 275 fHelpmenu->AddItem(fEncodingmenu); 276 // fHelpmenu->AddItem(fNewFontMenu); 277 fHelpmenu->AddSeparatorItem(); 278 fHelpmenu->AddItem(new BMenuItem("Preferences", new BMessage(MENU_PREF_OPEN))); 279 fMenubar->AddItem(fHelpmenu); 280 281 AddChild(fMenubar); 282 } 283 284 285 void 286 TermWindow::MessageReceived(BMessage *message) 287 { 288 int32 coding_id; 289 BRect r; 290 BFont halfFont; 291 BFont fullFont; 292 293 switch (message->what) { 294 295 case MENU_SWITCH_TERM: 296 be_app->PostMessage(MENU_SWITCH_TERM); 297 break; 298 299 case MENU_NEW_TREM: 300 be_app->PostMessage(MENU_NEW_TREM); 301 break; 302 303 case MENU_PREF_OPEN: 304 if (!fPrefWindow){ 305 fPrefWindow = new PrefDlg(this); 306 }else{ 307 fPrefWindow->Activate(); 308 } 309 break; 310 311 case MSG_PREF_CLOSED: 312 fPrefWindow = NULL; 313 break; 314 315 case MENU_FILE_QUIT: 316 be_app->PostMessage(B_QUIT_REQUESTED); 317 break; 318 case MENU_ENCODING: 319 message->FindInt32 ("op", &coding_id); 320 gNowCoding = coding_id; 321 SetCoding (coding_id); 322 this->SetWindowTitle (); 323 break; 324 325 /* 326 * Extended B_SET_PROPERTY. Dispatch this message, 327 * Set coding ID. 328 */ 329 case B_SET_PROPERTY: 330 { 331 int32 i; 332 BMessage spe; 333 message->GetCurrentSpecifier(&i, &spe); 334 if (!strcmp("encode", spe.FindString("property", i))){ 335 message->FindInt32 ("data", &coding_id); 336 gNowCoding = coding_id; 337 SetCoding (coding_id); 338 339 message->SendReply(B_REPLY); 340 }else{ 341 BWindow::MessageReceived(message); 342 } 343 break; 344 } 345 346 /* 347 * Extended B_GET_PROPERTY. Dispatch this message, 348 * reply now coding ID. 349 */ 350 case B_GET_PROPERTY: 351 { 352 int32 i; 353 BMessage spe; 354 message->GetCurrentSpecifier(&i, &spe); 355 if (!strcmp("encode", spe.FindString("property", i))){ 356 BMessage reply(B_REPLY); 357 reply.AddInt32("result", gNowCoding); 358 message->SendReply(&reply); 359 }else if (!strcmp("tty", spe.FindString("property", i))){ 360 BMessage reply(B_REPLY); 361 reply.AddString("result", &tty_name[8]); 362 message->SendReply(&reply); 363 }else{ 364 BWindow::MessageReceived(message); 365 } 366 break; 367 } 368 369 /* 370 * Message from Preference panel. 371 */ 372 case MSG_ROWS_CHANGED: 373 case MSG_COLS_CHANGED: 374 r = fTermView->SetTermSize (gTermPref->getInt32 (PREF_ROWS), 375 gTermPref->getInt32 (PREF_COLS), 376 0); 377 378 ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + VIEW_OFFSET * 2, 379 r.Height()+fMenubar->Bounds().Height() + VIEW_OFFSET *2); 380 break; 381 382 case MSG_HALF_FONT_CHANGED: 383 case MSG_FULL_FONT_CHANGED: 384 case MSG_HALF_SIZE_CHANGED: 385 case MSG_FULL_SIZE_CHANGED: 386 387 halfFont.SetFamilyAndStyle (gTermPref->getString(PREF_HALF_FONT_FAMILY), 388 NULL); 389 halfFont.SetSize (gTermPref->getFloat(PREF_HALF_FONT_SIZE)); 390 halfFont.SetSpacing (B_FIXED_SPACING); 391 392 fullFont.SetFamilyAndStyle (gTermPref->getString(PREF_FULL_FONT_FAMILY), 393 NULL); 394 fullFont.SetSize (gTermPref->getFloat(PREF_FULL_FONT_SIZE)); 395 fullFont.SetSpacing (B_FIXED_SPACING); 396 397 fTermView->SetTermFont (&halfFont, &fullFont); 398 r = fTermView->SetTermSize (0, 0, 0); 399 400 int width, height; 401 402 fTermView->GetFontSize (&width, &height); 403 404 SetSizeLimits (MIN_COLS * width, MAX_COLS * width, 405 MIN_COLS * height, MAX_COLS * height); 406 407 408 409 ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + VIEW_OFFSET * 2, 410 r.Height()+fMenubar->Bounds().Height() + VIEW_OFFSET * 2); 411 412 fTermView->Invalidate(); 413 break; 414 415 case EIGHTYTWENTYFOUR: 416 gTermPref->setString(PREF_COLS, "80"); 417 gTermPref->setString(PREF_ROWS, "24"); 418 this->PostMessage (MSG_ROWS_CHANGED); 419 this->PostMessage (MSG_COLS_CHANGED); 420 break; 421 422 case EIGHTYTWENTYFIVE: 423 gTermPref->setString(PREF_COLS, "80"); 424 gTermPref->setString(PREF_ROWS, "25"); 425 this->PostMessage (MSG_ROWS_CHANGED); 426 this->PostMessage (MSG_COLS_CHANGED); 427 break; 428 429 case EIGHTYFORTY: 430 gTermPref->setString(PREF_COLS, "80"); 431 gTermPref->setString(PREF_ROWS, "40"); 432 this->PostMessage (MSG_ROWS_CHANGED); 433 this->PostMessage (MSG_COLS_CHANGED); 434 break; 435 436 case ONETHREETWOTWENTYFOUR: 437 gTermPref->setString(PREF_COLS, "132"); 438 gTermPref->setString(PREF_ROWS, "24"); 439 this->PostMessage (MSG_ROWS_CHANGED); 440 this->PostMessage (MSG_COLS_CHANGED); 441 break; 442 443 case ONETHREETWOTWENTYFIVE: 444 gTermPref->setString(PREF_COLS, "132"); 445 gTermPref->setString(PREF_ROWS, "25"); 446 this->PostMessage (MSG_ROWS_CHANGED); 447 this->PostMessage (MSG_COLS_CHANGED); 448 break; 449 450 case MSG_FONT_CHANGED: 451 gTermPref->setString (PREF_HALF_FONT_FAMILY, fNewFontMenu->FindMarked()->Label()); 452 this->PostMessage (MSG_HALF_FONT_CHANGED); 453 break; 454 455 456 case MSG_COLOR_CHANGED: 457 fBaseView->SetViewColor (gTermPref->getRGB (PREF_TEXT_BACK_COLOR)); 458 fTermView->SetTermColor (); 459 fBaseView->Invalidate(); 460 fTermView->Invalidate(); 461 break; 462 463 case MENU_PAGE_SETUP: 464 DoPageSetup (); 465 break; 466 case MENU_PRINT: 467 DoPrint (); 468 break; 469 470 case MSGRUN_WINDOW: 471 fTermView->UpdateSIGWINCH (); 472 break; 473 474 case B_ABOUT_REQUESTED: 475 be_app->PostMessage(B_ABOUT_REQUESTED); 476 break; 477 478 default: 479 BWindow::MessageReceived(message); 480 break; 481 } 482 } 483 //////////////////////////////////////////////////////////////////////////// 484 // WindowActivated (bool) 485 // Dispatch Mesasge. 486 //////////////////////////////////////////////////////////////////////////// 487 void 488 TermWindow::WindowActivated (bool ) 489 { 490 491 } 492 493 //////////////////////////////////////////////////////////////////////////// 494 // Quit (void) 495 // Quit Application. 496 //////////////////////////////////////////////////////////////////////////// 497 //void 498 //TermWindow::colRequested() { 499 // colWindow *colW=new colWindow("Colours for Terminal"); 500 // colW->Show(); 501 // } 502 503 504 void 505 TermWindow::Quit(void) 506 { 507 delete fTermParse; 508 delete fCodeConv; 509 if(fPrefWindow) fPrefWindow->PostMessage (B_QUIT_REQUESTED); 510 be_app->PostMessage (B_QUIT_REQUESTED, be_app); 511 BWindow::Quit (); 512 } 513 514 515 bool 516 TermWindow::QuitRequested(void) 517 { 518 519 return true; 520 } 521 //////////////////////////////////////////////////////////////////////////// 522 // int GetTimeZone (void) 523 // Get Machine Timezone. 524 //////////////////////////////////////////////////////////////////////////// 525 int 526 TermWindow::GetTimeZone () 527 { 528 struct timeval tv; 529 struct timezone tm; 530 531 gettimeofday (&tv, &tm); 532 533 return -tm.tz_minuteswest / 60; 534 } 535 536 //////////////////////////////////////////////////////////////////////////// 537 // void SetWindowTitle (void) 538 // set window title bar (pty device name, and coding) 539 //////////////////////////////////////////////////////////////////////////// 540 541 #include "spawn.h" 542 543 void 544 TermWindow::SetWindowTitle (void) 545 { 546 char windowname[256]; 547 sprintf(windowname, gWindowName); 548 this->SetTitle (windowname); 549 550 } 551 //////////////////////////////////////////////////////////////////////////// 552 // GetSupoprtedSuites (BMessage *) 553 // 554 //////////////////////////////////////////////////////////////////////////// 555 void 556 TermWindow::TermWinActivate (void) 557 { 558 559 this->Activate(); 560 561 if (focus_follows_mouse()) { 562 BPoint aMouseLoc = this->Frame().LeftTop(); 563 set_mouse_position(int32(aMouseLoc.x + 16), int32(aMouseLoc.y + 2)); 564 be_app->SetCursor(B_HAND_CURSOR); 565 } 566 } 567 568 //////////////////////////////////////////////////////////////////////////// 569 // GetSupoprtedSuites (BMessage *) 570 // 571 //////////////////////////////////////////////////////////////////////////// 572 status_t 573 TermWindow::GetSupportedSuites(BMessage *msg) 574 { 575 static property_info prop_list[] = { 576 { "encode", 577 {B_GET_PROPERTY, 0}, 578 {B_DIRECT_SPECIFIER, 0}, 579 "get muterminal encode"}, 580 { "encode", 581 {B_SET_PROPERTY, 0}, 582 {B_DIRECT_SPECIFIER, 0}, 583 "set muterminal encode"}, 584 { "tty", 585 {B_GET_PROPERTY, 0}, 586 {B_DIRECT_SPECIFIER, 0}, 587 "get tty_name."}, 588 { 0 } 589 590 }; 591 msg->AddString("suites", "suite/vnd.naan-termwindow"); 592 BPropertyInfo prop_info(prop_list); 593 msg->AddFlat("messages", &prop_info); 594 return BWindow::GetSupportedSuites(msg); 595 } 596 //////////////////////////////////////////////////////////////////////////// 597 // ResolveSpecifier 598 // 599 //////////////////////////////////////////////////////////////////////////// 600 BHandler* 601 TermWindow::ResolveSpecifier(BMessage *msg, int32 index, 602 BMessage *specifier, int32 form, 603 const char *property) 604 { 605 if ( (strcmp(property, "encode") == 0) 606 && ((msg->what == B_SET_PROPERTY) || (msg->what == B_GET_PROPERTY) )) 607 return this; 608 else if ( (strcmp(property, "tty") == 0) 609 && (msg->what == B_GET_PROPERTY) ) 610 return this; 611 612 return BWindow::ResolveSpecifier(msg, index, specifier, form, property); 613 } 614 615 //////////////////////////////////////////////////////////////////////////// 616 // SetCoding 617 // Set coding utility functions. 618 //////////////////////////////////////////////////////////////////////////// 619 void SetCoding (int coding) 620 { 621 const etable *p = encoding_table; 622 p += coding; 623 624 gNowCoding = coding; 625 626 return; 627 } 628 //////////////////////////////////////////////////////////////////////////// 629 // DoPageSetUp () 630 // 631 //////////////////////////////////////////////////////////////////////////// 632 status_t 633 TermWindow::DoPageSetup() 634 { 635 status_t rv; 636 BPrintJob job("PageSetup"); 637 638 /* display the page configure panel */ 639 rv = job.ConfigPage(); 640 641 /* save a pointer to the settings */ 642 fPrintSettings = job.Settings(); 643 644 return rv; 645 } 646 647 //////////////////////////////////////////////////////////////////////////// 648 // DoPrint () 649 // 650 //////////////////////////////////////////////////////////////////////////// 651 void 652 TermWindow::DoPrint() 653 { 654 //#if B_BEOS_VERSION < 0x0460 655 BPrintJob job("Print"); 656 657 if((! fPrintSettings) && (DoPageSetup() != B_NO_ERROR)) { 658 (new BAlert("Cancel", "Print cancelled.", "OK"))->Go(); 659 return; 660 } 661 662 job.SetSettings(new BMessage(*fPrintSettings)); 663 664 BRect pageRect = job.PrintableRect(); 665 BRect curPageRect = pageRect; 666 667 int pHeight = (int)pageRect.Height(); 668 int pWidth = (int)pageRect.Width(); 669 float w,h; 670 fTermView->GetFrameSize (&w, &h); 671 int xPages = (int)ceil(w / pWidth); 672 int yPages = (int)ceil(h / pHeight); 673 674 /* engage the print server */ 675 job.BeginJob(); 676 677 /* loop through and draw each page, and write to spool */ 678 for(int x = 0; x < xPages; x++) 679 for(int y = 0; y < yPages; y++){ 680 curPageRect.OffsetTo(x * pWidth, y * pHeight); 681 job.DrawView(fTermView, curPageRect, BPoint(0, 0)); 682 job.SpoolPage(); 683 684 if(!job.CanContinue()){ 685 // It is likely that the only way that the job was cancelled is 686 // because the user hit 'Cancel' in the page setup window, in which 687 // case, the user does *not* need to be told that it was cancelled. 688 // He/she will simply expect that it was done. 689 // (new BAlert("Cancel", "Print job cancelled", "OK"))->Go(); 690 return; 691 } 692 } 693 694 /* commit the job, send the spool file */ 695 job.CommitJob(); 696 //#endif 697 } 698