* Tried to fix the usual deadlock on quit, but suspending the thread (to interrupt read()) doesn't have the expected outcome (might be a kernel bug). * Removed superfluous MENU_FILE_QUIT and send a B_QUIT_REQUESTED instead. * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20816 a95241bf-73f2-0310-859d-f6bbb57e9c96
764 lines
21 KiB
C++
764 lines
21 KiB
C++
/*
|
|
* Copyright (c) 2003-2004 Kian Duffy <[email protected]>
|
|
* Copyright (C) 1998,99 Kazuho Okui and Takashi Murai.
|
|
* Copyright (c) 2004 Daniel Furrer <[email protected]>
|
|
*
|
|
* Distributed unter the terms of the MIT license.
|
|
*/
|
|
#include <Alert.h>
|
|
#include <Application.h>
|
|
#include <Menu.h>
|
|
#include <MenuBar.h>
|
|
#include <MenuItem.h>
|
|
#include <Path.h>
|
|
#include <PrintJob.h>
|
|
#include <PropertyInfo.h>
|
|
#include <Roster.h>
|
|
#include <Screen.h>
|
|
#include <ScrollBar.h>
|
|
#include <String.h>
|
|
#include <TextControl.h>
|
|
#include <WindowScreen.h>
|
|
|
|
#include <float.h>
|
|
#include <stdio.h>
|
|
#include <string>
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "CodeConv.h"
|
|
#include "ColorWindow.h"
|
|
#include "MenuUtil.h"
|
|
#include "FindWindow.h"
|
|
#include "PrefWindow.h"
|
|
#include "PrefView.h"
|
|
#include "PrefHandler.h"
|
|
#include "TermApp.h"
|
|
#include "TermBaseView.h"
|
|
#include "TermBuffer.h"
|
|
#include "TermParse.h"
|
|
#include "TermView.h"
|
|
#include "TermWindow.h"
|
|
#include "TermConst.h"
|
|
#include "spawn.h"
|
|
|
|
|
|
// Global Preference Handler
|
|
extern PrefHandler *gTermPref;
|
|
//
|
|
// help and GPL URL
|
|
//
|
|
//#define URL_PREFIX "file:///boot/home/config/settings/MuTerminal/help/"
|
|
//#define INDEX_FILE "/index.html"
|
|
//#define GPL_FILE "/gpl.html"
|
|
//#define CHLP_FILE "file:///boot/beos/documentation/Shell%20Tools/index.html"
|
|
|
|
extern int gNowCoding; /* defined TermParce.cpp */
|
|
|
|
void SetCoding(int);
|
|
|
|
|
|
TermWindow::TermWindow(BRect frame, const char* title, int fd)
|
|
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
|
fPfd(fd)
|
|
{
|
|
InitWindow();
|
|
|
|
fPrintSettings = NULL;
|
|
fPrefWindow = NULL;
|
|
fFindPanel = NULL;
|
|
}
|
|
|
|
|
|
TermWindow::~TermWindow()
|
|
{
|
|
close(fPfd);
|
|
delete fTermParse;
|
|
delete fCodeConv;
|
|
if (fPrefWindow)
|
|
fPrefWindow->PostMessage(B_QUIT_REQUESTED);
|
|
|
|
if (fFindPanel && fFindPanel->Lock()) {
|
|
fFindPanel->Quit();
|
|
fFindPanel = NULL;
|
|
}
|
|
|
|
delete fWindowUpdate;
|
|
}
|
|
|
|
|
|
// #pragma mark - public methods
|
|
|
|
|
|
/** Initialize Window object. */
|
|
|
|
void
|
|
TermWindow::InitWindow(void)
|
|
{
|
|
// make menu bar
|
|
SetupMenu();
|
|
|
|
// Setup font.
|
|
|
|
const char *family = gTermPref->getString(PREF_HALF_FONT_FAMILY);
|
|
|
|
BFont halfFont;
|
|
halfFont.SetFamilyAndStyle(family, NULL);
|
|
float size = gTermPref->getFloat(PREF_HALF_FONT_SIZE);
|
|
if (size < 6.0f)
|
|
size = 6.0f;
|
|
halfFont.SetSize(size);
|
|
halfFont.SetSpacing(B_FIXED_SPACING);
|
|
|
|
family = gTermPref->getString(PREF_FULL_FONT_FAMILY);
|
|
|
|
BFont fullFont;
|
|
fullFont.SetFamilyAndStyle(family, NULL);
|
|
size = gTermPref->getFloat(PREF_FULL_FONT_SIZE);
|
|
if (size < 6.0f)
|
|
size = 6.0f;
|
|
fullFont.SetSize(size);
|
|
fullFont.SetSpacing(B_FIXED_SPACING);
|
|
|
|
// Make Terminal text view.
|
|
|
|
BRect textframe = Bounds();
|
|
textframe.top = fMenubar->Bounds().bottom + 1.0;
|
|
|
|
fCodeConv = new CodeConv();
|
|
fTermView = new TermView(Bounds(), fCodeConv, fPfd);
|
|
|
|
/*
|
|
* MuTerm has two views. BaseView is window base view.
|
|
* TermView is character Terminal view on BaseView. It has paste
|
|
* on BaseView shift as VIEW_OFFSET.
|
|
*/
|
|
fBaseView = new TermBaseView(textframe, fTermView);
|
|
|
|
// Initialize TermView. (font, size and color)
|
|
|
|
fTermView->SetTermFont(&halfFont, &fullFont);
|
|
|
|
BRect rect = fTermView->SetTermSize(gTermPref->getInt32(PREF_ROWS),
|
|
gTermPref->getInt32(PREF_COLS), 1);
|
|
|
|
int width, height;
|
|
fTermView->GetFontSize(&width, &height);
|
|
SetSizeLimits(MIN_COLS * width, MAX_COLS * width,
|
|
MIN_COLS * height, MAX_COLS * height);
|
|
|
|
fTermView->SetTermColor();
|
|
fBaseView->SetViewColor(gTermPref->getRGB(PREF_TEXT_BACK_COLOR));
|
|
|
|
// Add offset to baseview.
|
|
rect.InsetBy(-VIEW_OFFSET, -VIEW_OFFSET);
|
|
|
|
// Resize Window
|
|
|
|
ResizeTo(rect.Width()+ B_V_SCROLL_BAR_WIDTH,
|
|
rect.Height() + fMenubar->Bounds().Height());
|
|
|
|
fBaseView->ResizeTo(rect.Width(), rect.Height());
|
|
fBaseView->AddChild(fTermView);
|
|
fTermView->MoveBy(VIEW_OFFSET, VIEW_OFFSET);
|
|
|
|
// Make Scroll Bar.
|
|
|
|
BRect scrollRect(0, 0, B_V_SCROLL_BAR_WIDTH,
|
|
rect.Height() - B_H_SCROLL_BAR_HEIGHT + 1);
|
|
|
|
scrollRect.OffsetBy(rect.Width() + 1, fMenubar->Bounds().Height());
|
|
|
|
BScrollBar *scrollBar = new BScrollBar(scrollRect, "scrollbar",
|
|
fTermView, 0, 0, B_VERTICAL);
|
|
fTermView->SetScrollBar(scrollBar);
|
|
|
|
AddChild(scrollBar);
|
|
AddChild(fBaseView);
|
|
|
|
// Set fEditmenu's target to fTermView. (Oh!...)
|
|
fEditmenu->SetTargetForItems(fTermView);
|
|
|
|
// Initialize TermParse
|
|
gNowCoding = longname2op(gTermPref->getString(PREF_TEXT_ENCODING));
|
|
fTermParse = new TermParse(fPfd, this, fTermView, fCodeConv);
|
|
if (fTermParse->StartThreads() < B_OK)
|
|
return;
|
|
|
|
// Set Coding.
|
|
|
|
// Init find parameters
|
|
fMatchCase = false;
|
|
fMatchWord = false;
|
|
fFindSelection = false;
|
|
fForwardSearch = false;
|
|
|
|
// Initialize MessageRunner.
|
|
fWindowUpdate = new BMessageRunner(BMessenger(this),
|
|
new BMessage (MSGRUN_WINDOW), 500000);
|
|
}
|
|
|
|
|
|
void
|
|
TermWindow::MenusBeginning(void)
|
|
{
|
|
// Syncronize Encode Menu Pop-up menu and Preference.
|
|
(fEncodingmenu->FindItem(op2longname(gNowCoding)))->SetMarked(true);
|
|
BWindow::MenusBeginning();
|
|
}
|
|
|
|
|
|
void
|
|
TermWindow::SetupMenu(void)
|
|
{
|
|
PrefHandler menuText;
|
|
|
|
LoadLocaleFile (&menuText);
|
|
|
|
// Menu bar object.
|
|
fMenubar = new BMenuBar(Bounds(), "mbar");
|
|
|
|
// Make File Menu.
|
|
fFilemenu = new BMenu("Terminal");
|
|
fFilemenu->AddItem(new BMenuItem("Switch Terminals", new BMessage(MENU_SWITCH_TERM),'G'));
|
|
fFilemenu->AddItem(new BMenuItem("Start New Terminal", new BMessage(MENU_NEW_TERM), 'N'));
|
|
fFilemenu->AddSeparatorItem();
|
|
fFilemenu->AddItem(new BMenuItem("Page Setup...", new BMessage(MENU_PAGE_SETUP)));
|
|
fFilemenu->AddItem(new BMenuItem("Print", new BMessage(MENU_PRINT),'P'));
|
|
fFilemenu->AddSeparatorItem();
|
|
fFilemenu->AddItem(new BMenuItem("About Terminal...", new BMessage(B_ABOUT_REQUESTED)));
|
|
fFilemenu->AddSeparatorItem();
|
|
fFilemenu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
|
|
fMenubar->AddItem(fFilemenu);
|
|
|
|
// Make Edit Menu.
|
|
fEditmenu = new BMenu ("Edit");
|
|
fEditmenu->AddItem (new BMenuItem ("Copy", new BMessage (B_COPY),'C'));
|
|
fEditmenu->AddItem (new BMenuItem ("Paste", new BMessage (B_PASTE),'V'));
|
|
fEditmenu->AddSeparatorItem ();
|
|
fEditmenu->AddItem (new BMenuItem ("Select All", new BMessage (B_SELECT_ALL), 'A'));
|
|
fEditmenu->AddItem (new BMenuItem ("Clear All", new BMessage (MENU_CLEAR_ALL), 'L'));
|
|
fEditmenu->AddSeparatorItem ();
|
|
fEditmenu->AddItem (new BMenuItem ("Find", new BMessage (MENU_FIND_STRING),'F'));
|
|
fFindBackwardMenuItem = new BMenuItem ("Find Backward", new BMessage (MENU_FIND_BACKWARD), '[');
|
|
fEditmenu->AddItem (fFindBackwardMenuItem);
|
|
fFindBackwardMenuItem->SetEnabled(false);
|
|
fFindForwardMenuItem = new BMenuItem ("Find Forward", new BMessage (MENU_FIND_FORWARD), ']');
|
|
fEditmenu->AddItem (fFindForwardMenuItem);
|
|
fFindForwardMenuItem->SetEnabled(false);
|
|
|
|
fMenubar->AddItem (fEditmenu);
|
|
|
|
// Make Help Menu.
|
|
fHelpmenu = new BMenu("Settings");
|
|
fWindowSizeMenu = new BMenu("Window Size");
|
|
fWindowSizeMenu->AddItem(new BMenuItem("80x24", new BMessage(EIGHTYTWENTYFOUR)));
|
|
fWindowSizeMenu->AddItem(new BMenuItem("80x25", new BMessage(EIGHTYTWENTYFIVE)));
|
|
fWindowSizeMenu->AddItem(new BMenuItem("80x40", new BMessage(EIGHTYFORTY)));
|
|
fWindowSizeMenu->AddItem(new BMenuItem("132x24", new BMessage(ONETHREETWOTWENTYFOUR)));
|
|
fWindowSizeMenu->AddItem(new BMenuItem("132x25", new BMessage(ONETHREETWOTWENTYFIVE)));
|
|
fWindowSizeMenu->AddItem(new BMenuItem("Fullscreen", new BMessage(FULLSCREEN), B_ENTER));
|
|
|
|
// Considering we have this in the preferences window, this menu is not
|
|
// needed and should not be shown if we are to not confuse the user
|
|
/* fNewFontMenu = new BMenu("Font");
|
|
fNewFontMenu->SetRadioMode(true);
|
|
int32 numFamilies1 = count_font_families();
|
|
for ( int32 i = 0; i < numFamilies1; i++ ) {
|
|
font_family family;
|
|
uint32 flags;
|
|
if ( get_font_family(i, &family, &flags) == B_OK ) {
|
|
fNewFontMenu->AddItem(item = new BMenuItem(family, new BMessage(MSG_FONT_CHANGED)));
|
|
// if (0 ==i) item->SetMarked(true);
|
|
}
|
|
}
|
|
fNewFontMenu->FindItem (gTermPref->getString(PREF_HALF_FONT_FAMILY))->SetMarked(true);
|
|
*/
|
|
|
|
fEncodingmenu = new BMenu("Font Encoding");
|
|
fEncodingmenu->SetRadioMode(true);
|
|
MakeEncodingMenu(fEncodingmenu, gNowCoding, true);
|
|
fHelpmenu->AddItem(fWindowSizeMenu);
|
|
fHelpmenu->AddItem(fEncodingmenu);
|
|
// fHelpmenu->AddItem(fNewFontMenu);
|
|
fHelpmenu->AddSeparatorItem();
|
|
fHelpmenu->AddItem(new BMenuItem("Preferences", new BMessage(MENU_PREF_OPEN)));
|
|
fHelpmenu->AddSeparatorItem();
|
|
fHelpmenu->AddItem(new BMenuItem("Save as default", new BMessage(SAVE_AS_DEFAULT)));
|
|
fMenubar->AddItem(fHelpmenu);
|
|
|
|
AddChild(fMenubar);
|
|
}
|
|
|
|
|
|
void
|
|
TermWindow::MessageReceived(BMessage *message)
|
|
{
|
|
int32 coding_id;
|
|
BRect r;
|
|
BFont halfFont;
|
|
BFont fullFont;
|
|
bool findresult;
|
|
|
|
switch (message->what) {
|
|
case MENU_SWITCH_TERM: {
|
|
be_app->PostMessage(MENU_SWITCH_TERM);
|
|
break;
|
|
}
|
|
case MENU_NEW_TERM: {
|
|
app_info info;
|
|
be_app->GetAppInfo(&info);
|
|
|
|
// try launching two different ways to work around possible problems
|
|
if (be_roster->Launch(&info.ref)!=B_OK)
|
|
be_roster->Launch(TERM_SIGNATURE);
|
|
break;
|
|
}
|
|
case MENU_PREF_OPEN: {
|
|
if (!fPrefWindow)
|
|
fPrefWindow = new PrefWindow(this);
|
|
else
|
|
fPrefWindow->Activate();
|
|
break;
|
|
}
|
|
case MSG_PREF_CLOSED: {
|
|
fPrefWindow = NULL;
|
|
break;
|
|
}
|
|
case MENU_FIND_STRING: {
|
|
if (!fFindPanel) {
|
|
BRect r = Frame();
|
|
r.left += 20;
|
|
r.top += 20;
|
|
r.right = r.left + 260;
|
|
r.bottom = r.top + 190;
|
|
fFindPanel = new FindWindow(r, this, fFindString, fFindSelection, fMatchWord, fMatchCase, fForwardSearch);
|
|
}
|
|
else
|
|
fFindPanel->Activate();
|
|
break;
|
|
}
|
|
case MSG_FIND: {
|
|
fFindPanel->PostMessage(B_QUIT_REQUESTED);
|
|
message->FindBool("findselection", &fFindSelection);
|
|
if (!fFindSelection)
|
|
message->FindString("findstring", &fFindString);
|
|
else
|
|
fTermView->GetSelection(fFindString);
|
|
|
|
if (fFindString.Length() == 0) {
|
|
BAlert *alert = new BAlert("find failed", "No search string.", "Okay", NULL,
|
|
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
alert->Go();
|
|
fFindBackwardMenuItem->SetEnabled(false);
|
|
fFindForwardMenuItem->SetEnabled(false);
|
|
break;
|
|
}
|
|
|
|
message->FindBool("forwardsearch", &fForwardSearch);
|
|
message->FindBool("matchcase", &fMatchCase);
|
|
message->FindBool("matchword", &fMatchWord);
|
|
findresult = fTermView->Find(fFindString, fForwardSearch, fMatchCase, fMatchWord);
|
|
|
|
if (!findresult) {
|
|
BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL,
|
|
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
alert->Go();
|
|
fFindBackwardMenuItem->SetEnabled(false);
|
|
fFindForwardMenuItem->SetEnabled(false);
|
|
break;
|
|
}
|
|
|
|
// Enable the menu items Find Forward and Find Backward
|
|
fFindBackwardMenuItem->SetEnabled(true);
|
|
fFindForwardMenuItem->SetEnabled(true);
|
|
break;
|
|
}
|
|
case MENU_FIND_FORWARD: {
|
|
findresult = fTermView->Find(fFindString, true, fMatchCase, fMatchWord);
|
|
if (!findresult) {
|
|
BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL,
|
|
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
alert->Go();
|
|
}
|
|
break;
|
|
}
|
|
case MENU_FIND_BACKWARD: {
|
|
findresult = fTermView->Find(fFindString, false, fMatchCase, fMatchWord);
|
|
if (!findresult) {
|
|
BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL,
|
|
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
alert->Go();
|
|
}
|
|
break;
|
|
}
|
|
case MSG_FIND_CLOSED:
|
|
fFindPanel = NULL;
|
|
break;
|
|
|
|
case MENU_ENCODING: {
|
|
message->FindInt32 ("op", &coding_id);
|
|
gNowCoding = coding_id;
|
|
SetCoding(coding_id);
|
|
break;
|
|
}
|
|
// Extended B_SET_PROPERTY. Dispatch this message,
|
|
// Set coding ID.
|
|
case B_SET_PROPERTY: {
|
|
int32 i;
|
|
BMessage spe;
|
|
message->GetCurrentSpecifier(&i, &spe);
|
|
if (!strcmp("encode", spe.FindString("property", i))){
|
|
message->FindInt32 ("data", &coding_id);
|
|
gNowCoding = coding_id;
|
|
SetCoding (coding_id);
|
|
|
|
message->SendReply(B_REPLY);
|
|
} else {
|
|
BWindow::MessageReceived(message);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Extended B_GET_PROPERTY. Dispatch this message, reply now coding ID.
|
|
case B_GET_PROPERTY: {
|
|
int32 i;
|
|
BMessage spe;
|
|
message->GetCurrentSpecifier(&i, &spe);
|
|
if (!strcmp("encode", spe.FindString("property", i))){
|
|
BMessage reply(B_REPLY);
|
|
reply.AddInt32("result", gNowCoding);
|
|
message->SendReply(&reply);
|
|
}
|
|
else if (!strcmp("tty", spe.FindString("property", i))) {
|
|
BMessage reply(B_REPLY);
|
|
reply.AddString("result", ttyname(fPfd));
|
|
message->SendReply(&reply);
|
|
} else {
|
|
BWindow::MessageReceived(message);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Message from Preference panel.
|
|
case MSG_ROWS_CHANGED:
|
|
case MSG_COLS_CHANGED: {
|
|
r = fTermView->SetTermSize (gTermPref->getInt32 (PREF_ROWS),
|
|
gTermPref->getInt32 (PREF_COLS), 0);
|
|
|
|
ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + VIEW_OFFSET * 2,
|
|
r.Height()+fMenubar->Bounds().Height() + VIEW_OFFSET *2);
|
|
|
|
BPath path;
|
|
if (PrefHandler::GetDefaultPath(path) == B_OK)
|
|
gTermPref->SaveAsText(path.Path(), PREFFILE_MIMETYPE);
|
|
break;
|
|
}
|
|
case MSG_HALF_FONT_CHANGED:
|
|
case MSG_FULL_FONT_CHANGED:
|
|
case MSG_HALF_SIZE_CHANGED:
|
|
case MSG_FULL_SIZE_CHANGED: {
|
|
|
|
halfFont.SetFamilyAndStyle (gTermPref->getString(PREF_HALF_FONT_FAMILY),NULL);
|
|
halfFont.SetSize (gTermPref->getFloat(PREF_HALF_FONT_SIZE));
|
|
halfFont.SetSpacing (B_FIXED_SPACING);
|
|
|
|
fullFont.SetFamilyAndStyle (gTermPref->getString(PREF_FULL_FONT_FAMILY),NULL);
|
|
fullFont.SetSize (gTermPref->getFloat(PREF_FULL_FONT_SIZE));
|
|
fullFont.SetSpacing (B_FIXED_SPACING);
|
|
|
|
fTermView->SetTermFont (&halfFont, &fullFont);
|
|
r = fTermView->SetTermSize (0, 0, 0);
|
|
|
|
int width, height;
|
|
|
|
fTermView->GetFontSize (&width, &height);
|
|
|
|
SetSizeLimits (MIN_COLS * width, MAX_COLS * width,
|
|
MIN_COLS * height, MAX_COLS * height);
|
|
|
|
ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + VIEW_OFFSET * 2,
|
|
r.Height()+fMenubar->Bounds().Height() + VIEW_OFFSET * 2);
|
|
|
|
fTermView->Invalidate();
|
|
break;
|
|
}
|
|
case EIGHTYTWENTYFOUR: {
|
|
gTermPref->setString(PREF_COLS, "80");
|
|
gTermPref->setString(PREF_ROWS, "24");
|
|
this->PostMessage (MSG_ROWS_CHANGED);
|
|
this->PostMessage (MSG_COLS_CHANGED);
|
|
break;
|
|
}
|
|
case EIGHTYTWENTYFIVE: {
|
|
gTermPref->setString(PREF_COLS, "80");
|
|
gTermPref->setString(PREF_ROWS, "25");
|
|
this->PostMessage (MSG_ROWS_CHANGED);
|
|
this->PostMessage (MSG_COLS_CHANGED);
|
|
break;
|
|
}
|
|
case EIGHTYFORTY: {
|
|
gTermPref->setString(PREF_COLS, "80");
|
|
gTermPref->setString(PREF_ROWS, "40");
|
|
this->PostMessage (MSG_ROWS_CHANGED);
|
|
this->PostMessage (MSG_COLS_CHANGED);
|
|
break;
|
|
}
|
|
case ONETHREETWOTWENTYFOUR: {
|
|
gTermPref->setString(PREF_COLS, "132");
|
|
gTermPref->setString(PREF_ROWS, "24");
|
|
this->PostMessage (MSG_ROWS_CHANGED);
|
|
this->PostMessage (MSG_COLS_CHANGED);
|
|
break;
|
|
}
|
|
case ONETHREETWOTWENTYFIVE: {
|
|
gTermPref->setString(PREF_COLS, "132");
|
|
gTermPref->setString(PREF_ROWS, "25");
|
|
this->PostMessage (MSG_ROWS_CHANGED);
|
|
this->PostMessage (MSG_COLS_CHANGED);
|
|
break;
|
|
}
|
|
case FULLSCREEN: {
|
|
if (!fSavedFrame.IsValid()) { // go fullscreen
|
|
float mbHeight = fMenubar->Bounds().Height() + 1;
|
|
fSavedFrame = Frame();
|
|
BScreen screen(this);
|
|
fTermView->ScrollBar()->Hide();
|
|
fMenubar->Hide();
|
|
fBaseView->MoveTo(0,0);
|
|
fBaseView->ResizeBy(B_V_SCROLL_BAR_WIDTH, mbHeight);
|
|
fSavedLook = Look();
|
|
// done before ResizeTo to work around a Dano bug (not erasing the decor)
|
|
SetLook(B_NO_BORDER_WINDOW_LOOK);
|
|
ResizeTo(screen.Frame().Width()+1, screen.Frame().Height()+1);
|
|
MoveTo(screen.Frame().left, screen.Frame().top);
|
|
} else { // exit fullscreen
|
|
float mbHeight = fMenubar->Bounds().Height() + 1;
|
|
fMenubar->Show();
|
|
fTermView->ScrollBar()->Show();
|
|
ResizeTo(fSavedFrame.Width(), fSavedFrame.Height());
|
|
MoveTo(fSavedFrame.left, fSavedFrame.top);
|
|
fBaseView->ResizeBy(-B_V_SCROLL_BAR_WIDTH, -mbHeight);
|
|
fBaseView->MoveTo(0,mbHeight);
|
|
SetLook(fSavedLook);
|
|
fSavedFrame = BRect(0,0,-1,-1);
|
|
}
|
|
break;
|
|
}
|
|
case MSG_FONT_CHANGED: {
|
|
gTermPref->setString (PREF_HALF_FONT_FAMILY, fNewFontMenu->FindMarked()->Label());
|
|
this->PostMessage (MSG_HALF_FONT_CHANGED);
|
|
break;
|
|
}
|
|
case MSG_COLOR_CHANGED: {
|
|
fBaseView->SetViewColor (gTermPref->getRGB (PREF_TEXT_BACK_COLOR));
|
|
fTermView->SetTermColor ();
|
|
fBaseView->Invalidate();
|
|
fTermView->Invalidate();
|
|
break;
|
|
}
|
|
case SAVE_AS_DEFAULT: {
|
|
BPath path;
|
|
if (PrefHandler::GetDefaultPath(path) == B_OK)
|
|
gTermPref->SaveAsText(path.Path(), PREFFILE_MIMETYPE);
|
|
break;
|
|
}
|
|
case MENU_PAGE_SETUP: {
|
|
DoPageSetup ();
|
|
break;
|
|
}
|
|
case MENU_PRINT: {
|
|
DoPrint ();
|
|
break;
|
|
}
|
|
case MSGRUN_WINDOW: {
|
|
fTermView->UpdateSIGWINCH ();
|
|
break;
|
|
}
|
|
case B_ABOUT_REQUESTED: {
|
|
be_app->PostMessage(B_ABOUT_REQUESTED);
|
|
break;
|
|
}
|
|
default: {
|
|
BWindow::MessageReceived(message);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// WindowActivated (bool)
|
|
// Dispatch Mesasge.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
TermWindow::WindowActivated (bool )
|
|
{
|
|
|
|
}
|
|
|
|
|
|
bool
|
|
TermWindow::QuitRequested()
|
|
{
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
return true;
|
|
}
|
|
|
|
|
|
//! Get Machine Timezone.
|
|
int
|
|
TermWindow::GetTimeZone()
|
|
{
|
|
struct timeval tv;
|
|
struct timezone tm;
|
|
|
|
gettimeofday (&tv, &tm);
|
|
|
|
return -tm.tz_minuteswest / 60;
|
|
}
|
|
|
|
|
|
void
|
|
TermWindow::TermWinActivate()
|
|
{
|
|
Activate();
|
|
|
|
#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
|
|
if (focus_follows_mouse()) {
|
|
BPoint aMouseLoc = Frame().LeftTop();
|
|
set_mouse_position(int32(aMouseLoc.x + 16), int32(aMouseLoc.y + 2));
|
|
be_app->SetCursor(B_HAND_CURSOR);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
status_t
|
|
TermWindow::GetSupportedSuites(BMessage *msg)
|
|
{
|
|
static property_info prop_list[] = {
|
|
{ "encode",
|
|
{B_GET_PROPERTY, 0},
|
|
{B_DIRECT_SPECIFIER, 0},
|
|
"get muterminal encode"},
|
|
{ "encode",
|
|
{B_SET_PROPERTY, 0},
|
|
{B_DIRECT_SPECIFIER, 0},
|
|
"set muterminal encode"},
|
|
{ "tty",
|
|
{B_GET_PROPERTY, 0},
|
|
{B_DIRECT_SPECIFIER, 0},
|
|
"get tty_name."},
|
|
{ 0 }
|
|
|
|
};
|
|
msg->AddString("suites", "suite/vnd.naan-termwindow");
|
|
BPropertyInfo prop_info(prop_list);
|
|
msg->AddFlat("messages", &prop_info);
|
|
return BWindow::GetSupportedSuites(msg);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// ResolveSpecifier
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BHandler*
|
|
TermWindow::ResolveSpecifier(BMessage *msg, int32 index,
|
|
BMessage *specifier, int32 form,
|
|
const char *property)
|
|
{
|
|
if ( (strcmp(property, "encode") == 0)
|
|
&& ((msg->what == B_SET_PROPERTY) || (msg->what == B_GET_PROPERTY) ))
|
|
return this;
|
|
else if ( (strcmp(property, "tty") == 0)
|
|
&& (msg->what == B_GET_PROPERTY) )
|
|
return this;
|
|
|
|
return BWindow::ResolveSpecifier(msg, index, specifier, form, property);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// SetCoding
|
|
// Set coding utility functions.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void SetCoding (int coding)
|
|
{
|
|
const etable *p = encoding_table;
|
|
p += coding;
|
|
|
|
gNowCoding = coding;
|
|
|
|
return;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// DoPageSetUp ()
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
status_t
|
|
TermWindow::DoPageSetup()
|
|
{
|
|
status_t rv;
|
|
BPrintJob job("PageSetup");
|
|
|
|
/* display the page configure panel */
|
|
rv = job.ConfigPage();
|
|
|
|
/* save a pointer to the settings */
|
|
fPrintSettings = job.Settings();
|
|
|
|
return rv;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// DoPrint ()
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
TermWindow::DoPrint()
|
|
{
|
|
//#if B_BEOS_VERSION < 0x0460
|
|
BPrintJob job("Print");
|
|
|
|
if((! fPrintSettings) || (DoPageSetup() != B_NO_ERROR)) {
|
|
(new BAlert("Cancel", "Print cancelled.", "OK"))->Go();
|
|
return;
|
|
}
|
|
|
|
job.SetSettings(new BMessage(*fPrintSettings));
|
|
|
|
BRect pageRect = job.PrintableRect();
|
|
BRect curPageRect = pageRect;
|
|
|
|
int pHeight = (int)pageRect.Height();
|
|
int pWidth = (int)pageRect.Width();
|
|
float w,h;
|
|
fTermView->GetFrameSize (&w, &h);
|
|
int xPages = (int)ceil(w / pWidth);
|
|
int yPages = (int)ceil(h / pHeight);
|
|
|
|
/* engage the print server */
|
|
job.BeginJob();
|
|
|
|
/* loop through and draw each page, and write to spool */
|
|
for(int x = 0; x < xPages; x++)
|
|
for(int y = 0; y < yPages; y++){
|
|
curPageRect.OffsetTo(x * pWidth, y * pHeight);
|
|
job.DrawView(fTermView, curPageRect, BPoint(0, 0));
|
|
job.SpoolPage();
|
|
|
|
if(!job.CanContinue()){
|
|
// It is likely that the only way that the job was cancelled is
|
|
// because the user hit 'Cancel' in the page setup window, in which
|
|
// case, the user does *not* need to be told that it was cancelled.
|
|
// He/she will simply expect that it was done.
|
|
// (new BAlert("Cancel", "Print job cancelled", "OK"))->Go();
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* commit the job, send the spool file */
|
|
job.CommitJob();
|
|
//#endif
|
|
}
|
|
|
|
|
|
|