diff --git a/src/apps/terminal/Constants.h b/src/apps/terminal/Constants.h new file mode 100644 index 0000000000..52ed9af474 --- /dev/null +++ b/src/apps/terminal/Constants.h @@ -0,0 +1,38 @@ +/*Terminal: constants*/ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#include +#include + +#define APP_SIGNATURE "application/x-vnd.obos.terminal" + +const float TEXT_INSET = 3.0; + +// Messages for menu commands + +// Terminal +const uint32 TERMINAL_SWITCH_TERMINAL ='TSWT'; +const uint32 TERMINAL_START_NEW_TERMINAL='TSNT'; +const uint32 TERMINAL_LOG_TO_FILE ='TLTF'; +// Edit +const uint32 EDIT_WRITE_SELECTION ='EWSL'; +const uint32 EDIT_CLEAR_ALL ='ECLA'; +const uint32 EDIT_FIND ='EFND'; +const uint32 EDIT_FIND_BACKWARD ='EFBK'; +const uint32 EDIT_FIND_FORWARD ='EFFD'; +// Settings +const uint32 SETTINGS_WINDOW_SIZE ='SWSZ'; +const uint32 SETTINGS_FONT ='SFNT'; +const uint32 SETTINGS_FONT_SIZE ='SFSZ'; +const uint32 SETTINGS_FONT_ENCODING ='SFEN'; +const uint32 SETTINGS_TAB_WIDTH ='STBW'; +const uint32 SETTINGS_COLOR ='SCLR'; +const uint32 SETTINGS_SAVE_AS_DEFAULT ='SSAD'; +const uint32 SETTINGS_SAVE_AS_SETTINGS ='SSAS'; + +// Edit menu toggle +const uint32 ENABLE_ITEMS ='EDON'; +const uint32 DISABLE_ITEMS ='EDOF'; + +#endif // CONSTANTS_H diff --git a/src/apps/terminal/Jamfile b/src/apps/terminal/Jamfile index 03423ab616..f73db08417 100644 --- a/src/apps/terminal/Jamfile +++ b/src/apps/terminal/Jamfile @@ -4,12 +4,12 @@ SubDir OBOS_TOP src apps terminal ; # Terminal.rdef Terminal.icons.rdef Terminal.version.rdef # ; -# App Terminal : ; +App Terminal : + TerminalApp.cpp + TerminalView.cpp + TerminalWindow.cpp ; # ColorMenuItem.cpp # FindWindow.cpp # ReplaceWindow.cpp -# TerminalApp.cpp -# TerminalView.cpp -# TerminalWindow.cpp ; -# LinkSharedOSLibs Terminal : be translation tracker ; +LinkSharedOSLibs Terminal : be stdc++.r4 translation tracker ; diff --git a/src/apps/terminal/TerminalApp.cpp b/src/apps/terminal/TerminalApp.cpp new file mode 100644 index 0000000000..8ef0110cc8 --- /dev/null +++ b/src/apps/terminal/TerminalApp.cpp @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include "Constants.h" +#include "TerminalApp.h" +#include "TerminalWindow.h" + +BPoint windowPoint(7,26); +BPoint cascadeOffset(15,15); + +TerminalApp * terminal_app; + +TerminalApp::TerminalApp() + : BApplication(APP_SIGNATURE) +{ + fWindowCount = 0; + fNext_Terminal_Window = 1; + terminal_app = this; +} + +void TerminalApp::DispatchMessage(BMessage *msg, BHandler *handler) +{ + if ( msg->what == B_ARGV_RECEIVED ) { + int32 argc; + if (msg->FindInt32("argc",&argc) != B_OK) { + argc = 0; + } + const char ** argv = new (const char*)[argc]; + for (int arg = 0; (arg < argc) ; arg++) { + if (msg->FindString("argv",arg,&argv[arg]) != B_OK) { + argv[arg] = ""; + } + } + const char * cwd; + if (msg->FindString("cwd",&cwd) != B_OK) { + cwd = ""; + } + ArgvReceived(argc, argv, cwd); + } else { + BApplication::DispatchMessage(msg,handler); + } +} + + +void +TerminalApp::MessageReceived(BMessage *message) +{ + switch (message->what) { + case TERMINAL_START_NEW_TERMINAL: + OpenTerminal(); + break; + case B_SILENT_RELAUNCH: + OpenTerminal(); + break; + default: + BApplication::MessageReceived(message); + break; + } +} + +void +TerminalApp::OpenTerminal() +{ + new TerminalWindow(windowPoint,fNext_Terminal_Window++); + windowPoint += cascadeOffset; // TODO: wrap around screen + fWindowCount++; +} + +void +TerminalApp::OpenTerminal(entry_ref * ref) +{ + new TerminalWindow(ref,fNext_Terminal_Window++); + fWindowCount++; +} + +void +TerminalApp::CloseTerminal() +{ + fWindowCount--; + if (fWindowCount == 0) { + BAutolock lock(this); + Quit(); + } +} + +void +TerminalApp::RefsReceived(BMessage *message) +{ + int32 refNum; + entry_ref ref; + status_t err; + + refNum = 0; + do { + err = message->FindRef("refs", refNum, &ref); + if (err != B_OK) + return; + OpenTerminal(&ref); + refNum++; + } while (true); +} + +// TODO: find the arguments for Terminal and implement them all +void +TerminalApp::ArgvReceived(int32 argc, const char *argv[], const char * cwd) +{ + const char * execname = (argc >= 1 ? argv[0] : ""); + cout << execname << ": command line arguments not yet implemented" << endl; + return; +} + +void +TerminalApp::ReadyToRun() +{ + if (fWindowCount == 0) { + OpenTerminal(); + } +} + +int32 +TerminalApp::NumberOfWindows() +{ + return fWindowCount; +} + +int +main() +{ + TerminalApp terminal; + terminal.Run(); + return 0; +} diff --git a/src/apps/terminal/TerminalApp.h b/src/apps/terminal/TerminalApp.h new file mode 100644 index 0000000000..457e9a3974 --- /dev/null +++ b/src/apps/terminal/TerminalApp.h @@ -0,0 +1,35 @@ +#ifndef TERMINAL_APP_H +#define TERMINAL_APP_H + +#include +#include + +class TerminalWindow; + +class TerminalApp + : public BApplication +{ +public: + TerminalApp(); + virtual void MessageReceived(BMessage *message); + virtual void ArgvReceived(int32 argc, const char *argv[], const char * cwd); + virtual void RefsReceived(BMessage *message); + virtual void ReadyToRun(); + + virtual void DispatchMessage(BMessage *an_event, BHandler *handler); + + int32 NumberOfWindows(); + void OpenTerminal(); + void OpenTerminal(entry_ref * ref); + void CloseTerminal(); + +private: + int32 fWindowCount; + int32 fNext_Terminal_Window; + +}; + +extern TerminalApp * terminal_app; + +#endif // TERMINAL_APP_H + diff --git a/src/apps/terminal/TerminalView.cpp b/src/apps/terminal/TerminalView.cpp new file mode 100644 index 0000000000..939f55020d --- /dev/null +++ b/src/apps/terminal/TerminalView.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "TerminalView.h" +#include "Constants.h" + +TerminalView::TerminalView(BRect viewFrame, BRect textBounds, BHandler *handler) + : BTextView(viewFrame, "textview", textBounds, + B_FOLLOW_ALL, B_FRAME_EVENTS|B_WILL_DRAW) +{ + fHandler= handler; + fMessenger= new BMessenger(handler); +} + +TerminalView::~TerminalView(){ +} + +void +TerminalView::Select(int32 start, int32 finish) +{ + if(start==finish) + fChangeMessage= new BMessage(DISABLE_ITEMS); + else + fChangeMessage= new BMessage(ENABLE_ITEMS); + + fMessenger->SendMessage(fChangeMessage); + + BTextView::Select(start, finish); +} + diff --git a/src/apps/terminal/TerminalView.h b/src/apps/terminal/TerminalView.h new file mode 100644 index 0000000000..3aa06b7643 --- /dev/null +++ b/src/apps/terminal/TerminalView.h @@ -0,0 +1,21 @@ +#ifndef TERMINAL_VIEW_H +#define TERMINAL_VIEW_H + +#include +#include +#include + +class TerminalView : public BTextView { +public: + TerminalView(BRect viewframe, BRect textframe, BHandler *handler); + ~TerminalView(); + + virtual void Select(int32 start, int32 finish); + +private: + BHandler *fHandler; + BMessage *fChangeMessage; + BMessenger *fMessenger; +}; + +#endif // TERMINAL_VIEW_H diff --git a/src/apps/terminal/TerminalWindow.cpp b/src/apps/terminal/TerminalWindow.cpp new file mode 100644 index 0000000000..6b5d4b58e2 --- /dev/null +++ b/src/apps/terminal/TerminalWindow.cpp @@ -0,0 +1,306 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Constants.h" +#include "TerminalApp.h" +#include "TerminalView.h" +#include "TerminalWindow.h" + +TerminalWindow::TerminalWindow(BPoint topLeft, int32 id) + : BWindow(BRect(topLeft,topLeft+BPoint(560,390)), + "terminal",B_DOCUMENT_WINDOW,0) +{ + status_t status = InitWindow(id); + // TODO: handle error status + Show(); +} + +TerminalWindow::TerminalWindow(entry_ref *ref, int32 id) + : BWindow(BRect(7,16,567,406),"terminal",B_DOCUMENT_WINDOW,0) +{ + status_t status = InitWindow(id,ref); + // TODO: handle error status + Show(); +} + +TerminalWindow::~TerminalWindow() +{ + delete fLogToFilePanel; + delete fWriteSelectionPanel; + delete fSaveAsSettingsFilePanel; + +// if (fSaveMessage) +// delete fSaveMessage; +// if (fPrintSettings) +// delete fPrintSettings; +} + + +status_t +TerminalWindow::InitWindow(int32 id, entry_ref * settingsRef) +{ + BFile settingsFile; + if (settingsRef != 0) { + status_t status = settingsFile.SetTo(settingsRef,B_READ_ONLY); + if (status != B_OK) { + return status; + } + } else { + char settingsDirectory[B_PATH_NAME_LENGTH]; + status_t status = find_directory(B_USER_SETTINGS_DIRECTORY,0,true, + settingsDirectory,B_PATH_NAME_LENGTH); + if (status != B_OK) { + return status; + } + BPath settingsFilePath(settingsDirectory,"Terminal"); + status = settingsFilePath.InitCheck(); + if (status != B_OK) { + return status; + } + status = settingsFile.SetTo(settingsFilePath.Path(),B_READ_ONLY); + if (status != B_OK) { + return status; + } + } + // TODO : actually read the settings file + + BString unTitled; + unTitled.SetTo("Terminal "); + unTitled << id; + SetTitle(unTitled.String()); + + // Add menubar + fMenuBar = new BMenuBar(BRect(0,0,0,0),"menubar"); + + AddChild(fMenuBar); + + // Add textview and scrollview + BRect viewFrame; + BRect textBounds; + + viewFrame = Bounds(); + + viewFrame.top = fMenuBar->Bounds().Height()+1; + viewFrame.right -= B_V_SCROLL_BAR_WIDTH; + viewFrame.left = 0; + viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; + + textBounds = viewFrame; + textBounds.OffsetTo(B_ORIGIN); + textBounds.InsetBy(TEXT_INSET, TEXT_INSET); + + fTextView = new TerminalView(viewFrame, textBounds, this); + fTextView->SetStylable(true); + + fScrollView = new BScrollView("scrollview", fTextView, B_FOLLOW_ALL, 0, false, true, B_PLAIN_BORDER); + AddChild(fScrollView); + fTextView->MakeFocus(true); + + // Terminal menu + fTerminal = new BMenu("Terminal"); + fMenuBar->AddItem(fTerminal); + + fSwitchTerminals = new BMenuItem("Switch Terminals", new BMessage(TERMINAL_SWITCH_TERMINAL), 'G'); + fTerminal->AddItem(fSwitchTerminals); + fSwitchTerminals->SetTrigger('T'); + fSwitchTerminals->SetTarget(be_app); + + fStartNewTerminal = new BMenuItem("Start New Terminal", new BMessage(TERMINAL_START_NEW_TERMINAL), 'N'); + fTerminal->AddItem(fStartNewTerminal); + fStartNewTerminal->SetTarget(be_app); + + fLogToFile = new BMenuItem("Log to File...", new BMessage(TERMINAL_LOG_TO_FILE)); + fTerminal->AddItem(fLogToFile); + + // Edit menu + fEdit = new BMenu("Edit"); + fMenuBar->AddItem(fEdit); + + fCopy = new BMenuItem("Copy", new BMessage(B_COPY), 'C'); + fEdit->AddItem(fCopy); + fCopy->SetTarget(fTextView); + + fPaste = new BMenuItem("Paste", new BMessage(B_PASTE), 'V'); + fEdit->AddItem(fPaste); + fPaste->SetTarget(fTextView); + + fEdit->AddSeparatorItem(); + + fSelectAll = new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A'); + fEdit->AddItem(fSelectAll); + fSelectAll->SetTarget(fTextView); + + fWriteSelection = new BMenuItem("Write Selection...", new BMessage(EDIT_WRITE_SELECTION)); + fEdit->AddItem(fWriteSelection); + + fClearAll = new BMenuItem("Clear All", new BMessage(EDIT_CLEAR_ALL), 'L'); + fEdit->AddItem(fClearAll); + fClearAll->SetTarget(fTextView); + + fEdit->AddSeparatorItem(); + + fFind = new BMenuItem("Find...", new BMessage(EDIT_FIND),'F'); + fEdit->AddItem(fFind); + + fFindBackward = new BMenuItem("Find Backward",new BMessage(EDIT_FIND_BACKWARD),'['); + fEdit->AddItem(fFindBackward); + + fFindForward = new BMenuItem("Find Forward", new BMessage(EDIT_FIND_FORWARD),']'); + fEdit->AddItem(fFindForward); + + // Settings menu + fSettings = new BMenu("Settings"); + fMenuBar->AddItem(fSettings); + + fWindowSize = new BMenu("Window Size"); + fWindowSize->SetRadioMode(true); + fSettings->AddItem(fWindowSize); + + BMenuItem * menuItem; + BMessage * itemMessage; + fWindowSize->AddItem(menuItem = new BMenuItem("80x24", itemMessage = new BMessage(SETTINGS_WINDOW_SIZE))); + itemMessage->AddInt32("columns", 80); + itemMessage->AddInt32("lines", 24); + menuItem->SetMarked(true); + + fWindowSize->AddItem(menuItem = new BMenuItem("80x25", itemMessage = new BMessage(SETTINGS_WINDOW_SIZE))); + itemMessage->AddInt32("columns", 80); + itemMessage->AddInt32("lines", 25); + + fWindowSize->AddItem(menuItem = new BMenuItem("80x40", itemMessage = new BMessage(SETTINGS_WINDOW_SIZE))); + itemMessage->AddInt32("columns", 80); + itemMessage->AddInt32("lines", 40); + + fWindowSize->AddItem(menuItem = new BMenuItem("132x24", itemMessage = new BMessage(SETTINGS_WINDOW_SIZE))); + itemMessage->AddInt32("columns", 132); + itemMessage->AddInt32("lines", 24); + + fWindowSize->AddItem(menuItem = new BMenuItem("132x25", itemMessage = new BMessage(SETTINGS_WINDOW_SIZE))); + itemMessage->AddInt32("columns", 132); + itemMessage->AddInt32("lines", 25); + +// //Available fonts +// font_family plain_family; +// font_style plain_style; +// be_plain_font->GetFamilyAndStyle(&plain_family,&plain_style); +// fCurrentFontItem = 0; +// +// int32 numFamilies = count_font_families(); +// for ( int32 i = 0; i < numFamilies; i++ ) { +// font_family localfamily; +// if ( get_font_family ( i, &localfamily ) == B_OK ) { +// subMenu=new BMenu(localfamily); +// subMenu->SetRadioMode(true); +// fFontMenu->AddItem(menuItem = new BMenuItem(subMenu, new BMessage(FONT_FAMILY))); +// if (!strcmp(plain_family,localfamily)) { +// menuItem->SetMarked(true); +// fCurrentFontItem = menuItem; +// } +// int32 numStyles=count_font_styles(localfamily); +// for(int32 j = 0;jAddItem(menuItem = new BMenuItem(style, new BMessage(FONT_STYLE))); +// if (!strcmp(plain_style,style)) { +// menuItem->SetMarked(true); +// } +// } +// } +// } +// } + + // build file panels lazily + fLogToFilePanel = 0; + fWriteSelectionPanel = 0; + fSaveAsSettingsFilePanel = 0; +} + +void +TerminalWindow::MessageReceived(BMessage *message) +{ + switch(message->what){ + case B_COPY: + fTextView->Copy(be_clipboard); + break; + case B_PASTE: + fTextView->Paste(be_clipboard); + break; + case EDIT_CLEAR_ALL: + fTextView->Clear(); + break; +// case FONT_SIZE: +// { +// float fontSize; +// message->FindFloat("size",&fontSize); +// SetFontSize(fontSize); +// } +// break; +// case FONT_FAMILY: +// { +// const char * fontFamily = 0, * fontStyle = 0; +// void * ptr; +// if (message->FindPointer("source",&ptr) == B_OK) { +// fCurrentFontItem = static_cast(ptr); +// fontFamily = fCurrentFontItem->Label(); +// } +// SetFontStyle(fontFamily, fontStyle); +// } +// break; +// case FONT_STYLE: +// { +// const char * fontFamily = 0, * fontStyle = 0; +// void * ptr; +// if (message->FindPointer("source",&ptr) == B_OK) { +// BMenuItem * item = static_cast(ptr); +// fontStyle = item->Label(); +// BMenu * menu = item->Menu(); +// if (menu != 0) { +// fCurrentFontItem = menu->Superitem(); +// if (fCurrentFontItem != 0) { +// fontFamily = fCurrentFontItem->Label(); +// } +// } +// } +// SetFontStyle(fontFamily, fontStyle); +// } +// break; + default: + BWindow::MessageReceived(message); + break; + } +} + +void +TerminalWindow::MenusBeginning() +{ +} + +void +TerminalWindow::Quit() +{ + terminal_app->CloseTerminal(); + BWindow::Quit(); +} + +bool +TerminalWindow::QuitRequested() +{ + return true; +} + diff --git a/src/apps/terminal/TerminalWindow.h b/src/apps/terminal/TerminalWindow.h new file mode 100644 index 0000000000..24d19feb8c --- /dev/null +++ b/src/apps/terminal/TerminalWindow.h @@ -0,0 +1,80 @@ +#ifndef TERMINAL_WINDOW_H +#define TERMINAL_WINDOW_H + +#include +#include +#include +#include +#include +#include +#include + +class TerminalView; + +class TerminalWindow + : public BWindow +{ +public: + TerminalWindow(BPoint topLeft, int32 id); + TerminalWindow(entry_ref * ref, int32 id); + ~TerminalWindow(); + + virtual void Quit(); + virtual bool QuitRequested(); + virtual void MessageReceived(BMessage *message); + virtual void MenusBeginning(); + +private: + status_t InitWindow(int32 id, entry_ref * settingsRef = 0); + + // Menu variables + BMenuBar *fMenuBar; + + BMenu *fTerminal; + // ---------------------------------- + BMenuItem *fSwitchTerminals; + BMenuItem *fStartNewTerminal; + BMenuItem *fLogToFile; + + BMenu *fEdit; + // ---------------------------------- + BMenuItem *fCopy; + BMenuItem *fPaste; + // ---------------------------------- + BMenuItem *fSelectAll; + BMenuItem *fWriteSelection; + BMenuItem *fClearAll; + // ---------------------------------- + BMenuItem *fFind; + BMenuItem *fFindBackward; + BMenuItem *fFindForward; + + BMenu *fSettings; + // ---------------------------------- + BMenu *fWindowSize; + BMenu *fFont; + BMenuItem *fFontSize; + BMenu *fFontEncoding; + BMenuItem *fTabWidth; + BMenuItem *fColor; + // ---------------------------------- + BMenuItem *fSaveAsDefault; + BMenuItem *fSaveAsSettingsFile; + + // Main views + TerminalView *fTextView; + BScrollView *fScrollView; + + // File panels + BFilePanel *fLogToFilePanel; + BMenu *fLogToFilePanelEncodingMenu; + BFilePanel *fWriteSelectionPanel; + BMenu *fWriteSelectionPanelEncodingMenu; + BFilePanel *fSaveAsSettingsFilePanel; + BMenu *fSaveAsSettingsFilePanelEncodingMenu; + + BTextControl *fSavePanelTextView; + +}; + +#endif // TERMINAL_WINDOW_H