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