[haiku-commits] r39473 - haiku/trunk/src/apps/terminal

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 18 Nov 2010 00:46:13 +0100 (CET)

Author: bonefish
Date: 2010-11-18 00:46:13 +0100 (Thu, 18 Nov 2010)
New Revision: 39473
Changeset: http://dev.haiku-os.org/changeset/39473

Added:
   haiku/trunk/src/apps/terminal/PatternEvaluator.cpp
   haiku/trunk/src/apps/terminal/PatternEvaluator.h
   haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.cpp
   haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.h
Modified:
   haiku/trunk/src/apps/terminal/AppearPrefView.cpp
   haiku/trunk/src/apps/terminal/AppearPrefView.h
   haiku/trunk/src/apps/terminal/Jamfile
   haiku/trunk/src/apps/terminal/PrefHandler.cpp
   haiku/trunk/src/apps/terminal/TermApp.cpp
   haiku/trunk/src/apps/terminal/TermApp.h
   haiku/trunk/src/apps/terminal/TermConst.h
   haiku/trunk/src/apps/terminal/TermWindow.cpp
   haiku/trunk/src/apps/terminal/TermWindow.h
Log:
Implemented support for dynamic tab and window titles:
* Added settings for tab and window titles. Both are strings with optional
  placeholders for tab/terminal index, currently active process name and
  current directory.
* Added a generic utility class PatternEvaluator that allows to expand this
  kind of pattern strings and callback classes
  [Tab,Window]TitlePlaceholderMapper that provide the specific expansion for
  the tab and window title placeholders.
* TermWindow:
  - Separated the notions of session (== tab) and window titles. The tty
    clients no longer set the window, but the session title.
  - Use the patterns instead of the hard-coded window/tab titles.
  - Recompute all titles once a second, so changes of running programs are
    reflected.
* The default patterns for tab and window titles are "%1d: %p" (last CWD
  component and name of the running process) and "Terminal %i: %t" (Terminal
  ID and active tab title). Unfortunately the space on the tabs is seriously
  limited, so that the tab title is virtually always truncated. Ideas welcome.



Modified: haiku/trunk/src/apps/terminal/AppearPrefView.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/AppearPrefView.cpp    2010-11-17 23:23:09 UTC 
(rev 39472)
+++ haiku/trunk/src/apps/terminal/AppearPrefView.cpp    2010-11-17 23:46:13 UTC 
(rev 39473)
@@ -106,17 +106,48 @@
                        colorsPopUp);
        fColorField->SetEnabled(false);
 
+       fTabTitle = new BTextControl("tabTitle", B_TRANSLATE("Tab title:"), "",
+               NULL);
+       fTabTitle->SetModificationMessage(
+               new BMessage(MSG_TAB_TITLE_SETTING_CHANGED));
+       fTabTitle->SetToolTip(B_TRANSLATE(
+               "The pattern specifying the tab titles. The following 
placeholders\n"
+               "can be used:\n"
+               "\t%d\t-\tThe current working directory of the active 
process.\n"
+               "\t\t\tOptionally the maximum number of path components can 
be\n"
+               "\t\t\tspecified. E.g. '%2d' for at most two components.\n"
+               "\t%i\t-\tThe index of the tab.\n"
+               "\t%p\t-\tThe name of the active process.\n"
+               "\t%%\t-\tThe character '%'."));
+
+       fWindowTitle = new BTextControl("windowTitle", B_TRANSLATE("Window 
title:"),
+               "", NULL);
+       fWindowTitle->SetModificationMessage(
+               new BMessage(MSG_WINDOW_TITLE_SETTING_CHANGED));
+       fWindowTitle->SetToolTip(B_TRANSLATE(
+               "The pattern specifying the window titles. The following 
placeholders\n"
+               "can be used:\n"
+               "\t%d\t-\tThe current working directory of the active process 
in the.\n"
+               "\t\t\tcurrent tab. Optionally the maximum number of path 
components\n"
+               "\t\t\tcan be specified. E.g. '%2d' for at most two 
components.\n"
+               "\t%i\t-\tThe index of the window.\n"
+               "\t%p\t-\tThe name of the active process in the current tab.\n"
+               "\t%t\t-\tThe title of the current tab.\n"
+               "\t%%\t-\tThe character '%'."));
+
        BLayoutBuilder::Group<>(this)
                .SetInsets(5, 5, 5, 5)
                .AddGrid(5, 5)
-                       .Add(fFont->CreateLabelLayoutItem(), 0, 0)
-                       .Add(fFont->CreateMenuBarLayoutItem(), 1, 0)
-                       .Add(fFontSize->CreateLabelLayoutItem(), 0, 1)
-                       .Add(fFontSize->CreateMenuBarLayoutItem(), 1, 1)
-                       .Add(fColorSchemaField->CreateLabelLayoutItem(), 0, 2)
-                       .Add(fColorSchemaField->CreateMenuBarLayoutItem(), 1, 2)
-                       .Add(fColorField->CreateLabelLayoutItem(), 0, 3)
-                       .Add(fColorField->CreateMenuBarLayoutItem(), 1, 3)
+                       .AddTextControl(fTabTitle, 0, 0, B_ALIGN_RIGHT)
+                       .AddTextControl(fWindowTitle, 0, 1, B_ALIGN_RIGHT)
+                       .Add(fFont->CreateLabelLayoutItem(), 0, 2)
+                       .Add(fFont->CreateMenuBarLayoutItem(), 1, 2)
+                       .Add(fFontSize->CreateLabelLayoutItem(), 0, 3)
+                       .Add(fFontSize->CreateMenuBarLayoutItem(), 1, 3)
+                       .Add(fColorSchemaField->CreateLabelLayoutItem(), 0, 4)
+                       .Add(fColorSchemaField->CreateMenuBarLayoutItem(), 1, 4)
+                       .Add(fColorField->CreateLabelLayoutItem(), 0, 5)
+                       .Add(fColorField->CreateMenuBarLayoutItem(), 1, 5)
                        .End()
                .AddGlue()
                .Add(fColorControl = new BColorControl(BPoint(10, 10),
@@ -128,6 +159,9 @@
        fColorField->SetAlignment(B_ALIGN_RIGHT);
        fColorSchemaField->SetAlignment(B_ALIGN_RIGHT);
 
+       fTabTitle->SetText(PrefHandler::Default()->getString(PREF_TAB_TITLE));
+       
fWindowTitle->SetText(PrefHandler::Default()->getString(PREF_WINDOW_TITLE));
+
        fColorControl->SetEnabled(false);
        fColorControl->SetValue(
                PrefHandler::Default()->getRGB(PREF_TEXT_FORE_COLOR));
@@ -158,6 +192,9 @@
 void
 AppearancePrefView::Revert()
 {
+       fTabTitle->SetText(PrefHandler::Default()->getString(PREF_TAB_TITLE));
+       
fWindowTitle->SetText(PrefHandler::Default()->getString(PREF_WINDOW_TITLE));
+
        fWarnOnExit->SetValue(PrefHandler::Default()->getBool(
                PREF_WARN_ON_EXIT));
 
@@ -175,6 +212,8 @@
 void
 AppearancePrefView::AttachedToWindow()
 {
+       fTabTitle->SetTarget(this);
+       fWindowTitle->SetTarget(this);
        fWarnOnExit->SetTarget(this);
 
        fFontSize->Menu()->SetTargetForItems(this);
@@ -271,6 +310,30 @@
                                        modified = true;
                        }
                        break;
+
+               case MSG_TAB_TITLE_SETTING_CHANGED:
+               {
+                       BString 
oldValue(PrefHandler::Default()->getString(PREF_TAB_TITLE));
+                       if (oldValue != fTabTitle->Text()) {
+                               
PrefHandler::Default()->setString(PREF_TAB_TITLE,
+                                       fTabTitle->Text());
+                               modified = true;
+                       }
+                       break;
+               }
+
+               case MSG_WINDOW_TITLE_SETTING_CHANGED:
+               {
+                       BString oldValue(PrefHandler::Default()->getString(
+                               PREF_WINDOW_TITLE));
+                       if (oldValue != fWindowTitle->Text()) {
+                               
PrefHandler::Default()->setString(PREF_WINDOW_TITLE,
+                                       fWindowTitle->Text());
+                               modified = true;
+                       }
+                       break;
+               }
+
                default:
                        BView::MessageReceived(msg);
                        return;

Modified: haiku/trunk/src/apps/terminal/AppearPrefView.h
===================================================================
--- haiku/trunk/src/apps/terminal/AppearPrefView.h      2010-11-17 23:23:09 UTC 
(rev 39472)
+++ haiku/trunk/src/apps/terminal/AppearPrefView.h      2010-11-17 23:46:13 UTC 
(rev 39473)
@@ -13,28 +13,31 @@
 #include <String.h>
 
 
-const ulong MSG_HALF_FONT_CHANGED      = 'mchf';
-const ulong MSG_HALF_SIZE_CHANGED      = 'mchs';
-const ulong MSG_FULL_FONT_CHANGED      = 'mcff';
-const ulong MSG_FULL_SIZE_CHANGED      = 'mcfs';
-const ulong MSG_COLOR_FIELD_CHANGED    = 'mccf';
-const ulong MSG_COLOR_CHANGED          = 'mcbc';
-const ulong MSG_COLOR_SCHEMA_CHANGED           = 'mccs';
+static const uint32 MSG_HALF_FONT_CHANGED                              = 
'mchf';
+static const uint32 MSG_HALF_SIZE_CHANGED                              = 
'mchs';
+static const uint32 MSG_FULL_FONT_CHANGED                              = 
'mcff';
+static const uint32 MSG_FULL_SIZE_CHANGED                              = 
'mcfs';
+static const uint32 MSG_COLOR_FIELD_CHANGED                            = 
'mccf';
+static const uint32 MSG_COLOR_CHANGED                                  = 
'mcbc';
+static const uint32 MSG_COLOR_SCHEMA_CHANGED                   = 'mccs';
 
-const ulong MSG_WARN_ON_EXIT_CHANGED   = 'mwec';
-const ulong MSG_COLS_CHANGED            = 'mccl';
-const ulong MSG_ROWS_CHANGED            = 'mcrw';
-const ulong MSG_HISTORY_CHANGED         = 'mhst';
+static const uint32 MSG_TAB_TITLE_SETTING_CHANGED              = 'mtts';
+static const uint32 MSG_WINDOW_TITLE_SETTING_CHANGED   = 'mwts';
+static const uint32 MSG_WARN_ON_EXIT_CHANGED                   = 'mwec';
+static const uint32 MSG_COLS_CHANGED                                   = 
'mccl';
+static const uint32 MSG_ROWS_CHANGED                                   = 
'mcrw';
+static const uint32 MSG_HISTORY_CHANGED                                = 
'mhst';
 
-const ulong MSG_PREF_MODIFIED          = 'mpmo';
+static const uint32 MSG_PREF_MODIFIED                                  = 
'mpmo';
 
 
 struct color_schema;
+class BCheckBox;
 class BColorControl;
 class BMenu;
 class BMenuField;
 class BPopUpMenu;
-class BCheckBox;
+class BTextControl;
 
 
 class AppearancePrefView : public BGroupView {
@@ -76,6 +79,9 @@
                        BMenuField*                     fColorField;
                        BColorControl*          fColorControl;
 
+                       BTextControl*           fTabTitle;
+                       BTextControl*           fWindowTitle;
+
                        BMessenger                      fTerminalMessenger;
 };
 

Modified: haiku/trunk/src/apps/terminal/Jamfile
===================================================================
--- haiku/trunk/src/apps/terminal/Jamfile       2010-11-17 23:23:09 UTC (rev 
39472)
+++ haiku/trunk/src/apps/terminal/Jamfile       2010-11-17 23:46:13 UTC (rev 
39473)
@@ -17,6 +17,7 @@
        Globals.cpp
        HistoryBuffer.cpp
        InlineInput.cpp
+       PatternEvaluator.cpp
        PrefHandler.cpp
        PrefWindow.cpp
        Shell.cpp
@@ -29,6 +30,7 @@
        TermScrollView.cpp
        TermView.cpp
        TermWindow.cpp
+       TitlePlaceholderMapper.cpp
        VTKeyTbl.c
        VTPrsTbl.c
        : be $(HAIKU_LOCALE_LIBS) tracker textencoding $(TARGET_LIBSUPC++)

Added: haiku/trunk/src/apps/terminal/PatternEvaluator.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/PatternEvaluator.cpp                          
(rev 0)
+++ haiku/trunk/src/apps/terminal/PatternEvaluator.cpp  2010-11-17 23:46:13 UTC 
(rev 39473)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "PatternEvaluator.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+// #pragma mark - PatternEvaluator
+
+
+/*static*/ BString
+PatternEvaluator::Evaluate(const char* pattern, PlaceholderMapper& mapper)
+{
+       BString result;
+
+       while (*pattern != '\0') {
+               // find next placeholder
+               const char* placeholder = strchr(pattern, '%');
+               if (placeholder == NULL)
+                       return result.Append(pattern);
+
+               // append skipped chars
+               if (placeholder != pattern)
+                       result.Append(pattern, placeholder - pattern);
+
+               pattern = placeholder + 1;
+
+               // check for an escaped '%'
+               if (*pattern == '%') {
+                       result += '%';
+                       pattern++;
+                       continue;
+               }
+
+               // parse a number, if there is one
+               int64 number = 0;
+               bool hasNumber = false;
+               if (isdigit(*pattern)) {
+                       char* numberEnd;
+                       number = strtoll(pattern, &numberEnd, 10);
+                       pattern = numberEnd;
+                       hasNumber = true;
+               }
+
+               BString mappedValue;
+               if (*pattern != '\0' && mapper.MapPlaceholder(*pattern,
+                               number, hasNumber, mappedValue)) {
+                       // mapped successfully -- append the replacement string
+                       result += mappedValue;
+                       pattern++;
+               } else {
+                       // something went wrong -- just append the literal part 
of the
+                       // pattern
+                       result.Append(placeholder, pattern - placeholder);
+               }
+       }
+
+       return result;
+}
+
+
+
+// #pragma mark - PlaceholderMapper
+
+
+PatternEvaluator::PlaceholderMapper::~PlaceholderMapper()
+{
+}

Added: haiku/trunk/src/apps/terminal/PatternEvaluator.h
===================================================================
--- haiku/trunk/src/apps/terminal/PatternEvaluator.h                            
(rev 0)
+++ haiku/trunk/src/apps/terminal/PatternEvaluator.h    2010-11-17 23:46:13 UTC 
(rev 39473)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef PATTERN_EVALUATOR_H
+#define PATTERN_EVALUATOR_H
+
+
+#include <String.h>
+
+
+class PatternEvaluator {
+public:
+       class PlaceholderMapper;
+
+public:
+       static  BString                         Evaluate(const char* pattern,
+                                                                       
PlaceholderMapper& mapper);
+
+};
+
+
+class PatternEvaluator::PlaceholderMapper {
+public:
+       virtual                                         ~PlaceholderMapper();
+
+       virtual bool                            MapPlaceholder(char placeholder,
+                                                                       int64 
number, bool numberGiven,
+                                                                       
BString& _string) = 0;
+};
+
+
+#endif // PATTERN_EVALUATOR_H

Modified: haiku/trunk/src/apps/terminal/PrefHandler.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/PrefHandler.cpp       2010-11-17 23:23:09 UTC 
(rev 39472)
+++ haiku/trunk/src/apps/terminal/PrefHandler.cpp       2010-11-17 23:46:13 UTC 
(rev 39473)
@@ -57,6 +57,8 @@
        { PREF_GUI_LANGUAGE,            "English"},
        { PREF_IM_AWARE,                        "0"},
 
+       { PREF_TAB_TITLE,                       "%1d: %p" },
+       { PREF_WINDOW_TITLE,            "Terminal %i: %t" },
        { PREF_WARN_ON_EXIT,            PREF_TRUE },
 
        { NULL, NULL},

Modified: haiku/trunk/src/apps/terminal/TermApp.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/TermApp.cpp   2010-11-17 23:23:09 UTC (rev 
39472)
+++ haiku/trunk/src/apps/terminal/TermApp.cpp   2010-11-17 23:46:13 UTC (rev 
39473)
@@ -59,6 +59,7 @@
 TermApp::TermApp()
        : BApplication(TERM_SIGNATURE),
        fStartFullscreen(false),
+       fWindowTitleUserDefined(false),
        fWindowNumber(-1),
        fTermWindow(NULL),
        fArgs(NULL)
@@ -222,8 +223,10 @@
                return;
        }
 
-       if (fArgs->Title() != NULL)
+       if (fArgs->Title() != NULL) {
                fWindowTitle = fArgs->Title();
+               fWindowTitleUserDefined = true;
+       }
 
        fStartFullscreen = fArgs->FullScreen();
 }
@@ -361,8 +364,8 @@
 TermApp::_MakeTermWindow(BRect &frame, uint32 workspaces)
 {
        try {
-               fTermWindow = new TermWindow(frame, fWindowTitle.String(), 
workspaces,
-                       fArgs);
+               fTermWindow = new TermWindow(frame, fWindowTitle,
+                       fWindowTitleUserDefined, fWindowNumber, workspaces, 
fArgs);
        } catch (int error) {
                return (status_t)error;
        } catch (...) {

Modified: haiku/trunk/src/apps/terminal/TermApp.h
===================================================================
--- haiku/trunk/src/apps/terminal/TermApp.h     2010-11-17 23:23:09 UTC (rev 
39472)
+++ haiku/trunk/src/apps/terminal/TermApp.h     2010-11-17 23:46:13 UTC (rev 
39473)
@@ -85,6 +85,7 @@
 private:
                        bool                            fStartFullscreen;
                        BString                         fWindowTitle;
+                       bool                            fWindowTitleUserDefined;
                        int32                           fWindowNumber;
 
                        BWindow*                        fTermWindow;

Modified: haiku/trunk/src/apps/terminal/TermConst.h
===================================================================
--- haiku/trunk/src/apps/terminal/TermConst.h   2010-11-17 23:23:09 UTC (rev 
39472)
+++ haiku/trunk/src/apps/terminal/TermConst.h   2010-11-17 23:46:13 UTC (rev 
39473)
@@ -131,6 +131,9 @@
 
 static const char* const PREF_WARN_ON_EXIT = "Warn on exit";
 
+static const char* const PREF_TAB_TITLE = "Tab title";
+static const char* const PREF_WINDOW_TITLE = "Window title";
+
 // Color type
 enum {
   TEXT_FOREGROUND_COLOR,

Modified: haiku/trunk/src/apps/terminal/TermWindow.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/TermWindow.cpp        2010-11-17 23:23:09 UTC 
(rev 39472)
+++ haiku/trunk/src/apps/terminal/TermWindow.cpp        2010-11-17 23:46:13 UTC 
(rev 39473)
@@ -44,6 +44,7 @@
 #include "TermConst.h"
 #include "TermScrollView.h"
 #include "TermView.h"
+#include "TitlePlaceholderMapper.h"
 
 
 const static int32 kMaxTabs = 6;
@@ -55,6 +56,7 @@
 const static uint32 kIncreaseFontSize = 'InFs';
 const static uint32 kDecreaseFontSize = 'DcFs';
 const static uint32 kSetActiveTab = 'STab';
+const static uint32 kUpdateTitles = 'UPti';
 
 
 #undef B_TRANSLATE_CONTEXT
@@ -100,8 +102,7 @@
 
 struct TermWindow::Session {
        int32                                   id;
-       BString                                 name;
-       BString                                 windowTitle;
+       Title                                   title;
        TermViewContainerView*  containerView;
 
        Session(int32 id, TermViewContainerView* containerView)
@@ -109,8 +110,9 @@
                id(id),
                containerView(containerView)
        {
-               name = B_TRANSLATE("Shell ");
-               name << id;
+               title.title = B_TRANSLATE("Shell ");
+               title.title << id;
+               title.patternUserDefined = false;
        }
 };
 
@@ -140,12 +142,14 @@
 };
 
 
-TermWindow::TermWindow(BRect frame, const char* title, uint32 workspaces,
+TermWindow::TermWindow(BRect frame, const BString& title,
+       bool isUserDefinedTitle, int32 windowIndex, uint32 workspaces,
        Arguments* args)
        :
        BWindow(frame, title, B_DOCUMENT_WINDOW,
                B_CURRENT_WORKSPACE | B_QUIT_ON_WINDOW_CLOSE, workspaces),
-       fInitialTitle(title),
+       fWindowIndex(windowIndex),
+       fTitleUpdateRunner(this, BMessage(kUpdateTitles), 1000000),
        fTabView(NULL),
        fMenubar(NULL),
        fFilemenu(NULL),
@@ -166,6 +170,12 @@
        fMatchWord(false),
        fFullScreen(false)
 {
+       // apply the title settings
+       fTitle.title = title;
+       fTitle.pattern = title;
+       fTitle.patternUserDefined = isUserDefinedTitle;
+       _TitleSettingsChanged();
+
        _InitWindow();
        _AddTab(args);
 }
@@ -189,15 +199,13 @@
 
 
 void
-TermWindow::SetSessionWindowTitle(TermView* termView, const char* title)
+TermWindow::SetSessionTitle(TermView* termView, const char* title)
 {
        int32 index = _IndexOfTermView(termView);
        if (Session* session = (Session*)fSessions.ItemAt(index)) {
-               session->windowTitle = title;
-               BTab* tab = fTabView->TabAt(index);
-               tab->SetLabel(session->windowTitle.String());
-               if (index == fTabView->Selection())
-                       SetTitle(session->windowTitle.String());
+               session->title.pattern = title;
+               session->title.patternUserDefined = true;
+               _UpdateSessionTitle(index);
        }
 }
 
@@ -205,9 +213,7 @@
 void
 TermWindow::SessionChanged()
 {
-       int32 index = fTabView->Selection();
-       if (Session* session = (Session*)fSessions.ItemAt(index))
-               SetTitle(session->windowTitle.String());
+       _UpdateSessionTitle(fTabView->Selection());
 }
 
 
@@ -509,6 +515,11 @@
                        fPrefWindow = NULL;
                        break;
 
+               case MSG_WINDOW_TITLE_SETTING_CHANGED:
+               case MSG_TAB_TITLE_SETTING_CHANGED:
+                       _TitleSettingsChanged();
+                       break;
+
                case MENU_FIND_STRING:
                        if (!fFindPanel) {
                                fFindPanel = new FindWindow(this, fFindString, 
fFindSelection,
@@ -755,6 +766,10 @@
                        break;
                }
 
+               case kUpdateTitles:
+                       _UpdateTitles();
+                       break;
+
                default:
                        BWindow::MessageReceived(message);
                        break;
@@ -870,7 +885,6 @@
                        fTabView->SetScrollView(scrollView);
 
                Session* session = new Session(_NewSessionID(), containerView);
-               session->windowTitle = fInitialTitle;
                fSessions.AddItem(session);
 
                BFont font;
@@ -905,10 +919,6 @@
 
                BTab* tab = new BTab;
                fTabView->AddTab(scrollView, tab);
-               tab->SetLabel(session->name.String());
-                       // TODO: Use a better name. For example, do like MacOS 
X's Terminal
-                       // and update the title using the last executed command 
?
-                       // Or like Gnome's Terminal and use the current path ?
                view->SetScrollBar(scrollView->ScrollBar(B_VERTICAL));
                view->SetMouseClipboard(gMouseClipboard);
                view->SetEncoding(EncodingID(
@@ -916,8 +926,10 @@
 
                _SetTermColors(containerView);
 
-               // TODO: No fTabView->Select(tab); ?
-               fTabView->Select(fTabView->CountTabs() - 1);
+               int32 tabIndex = fTabView->CountTabs() - 1;
+               fTabView->Select(tabIndex);
+
+               _UpdateSessionTitle(tabIndex);
        } catch (...) {
                // most probably out of memory. That's bad.
                // TODO: Should cleanup, I guess
@@ -1096,6 +1108,72 @@
 }
 
 
+void
+TermWindow::_TitleSettingsChanged()
+{
+       if (!fTitle.patternUserDefined)
+               fTitle.pattern = 
PrefHandler::Default()->getString(PREF_WINDOW_TITLE);
+
+       fSessionTitlePattern = 
PrefHandler::Default()->getString(PREF_TAB_TITLE);
+
+       _UpdateTitles();
+}
+
+
+void
+TermWindow::_UpdateTitles()
+{
+       int32 sessionCount = fSessions.CountItems();
+       for (int32 i = 0; i < sessionCount; i++)
+               _UpdateSessionTitle(i);
+}
+
+
+void
+TermWindow::_UpdateSessionTitle(int32 index)
+{
+       Session* session = (Session*)fSessions.ItemAt(index);
+       if (session == NULL)
+               return;
+
+       // get the active process info
+       ActiveProcessInfo activeProcessInfo;
+       if (!_TermViewAt(index)->GetActiveProcessInfo(activeProcessInfo))
+               return;
+
+       // evaluate the session title pattern
+       BString sessionTitlePattern = session->title.patternUserDefined
+               ? session->title.pattern : fSessionTitlePattern;
+       TabTitlePlaceholderMapper tabMapper(activeProcessInfo, session->id);
+       const BString& sessionTitle = PatternEvaluator::Evaluate(
+               sessionTitlePattern, tabMapper);
+
+       // set the tab title
+       if (sessionTitle != session->title.title) {
+               session->title.title = sessionTitle;
+               BTab* tab = fTabView->TabAt(index);
+               tab->SetLabel(session->title.title);
+               fTabView->Invalidate(fTabView->TabFrame(index));
+       }
+
+       // If this is the active tab, also recompute the window title.
+       if (index != fTabView->Selection())
+               return;
+
+       // evaluate the window title pattern
+       WindowTitlePlaceholderMapper windowMapper(activeProcessInfo, 
fWindowIndex,
+               sessionTitle);
+       const BString& windowTitle = PatternEvaluator::Evaluate(fTitle.pattern,
+               windowMapper);
+
+       // set the window title
+       if (windowTitle != fTitle.title) {
+               fTitle.title = windowTitle;
+               SetTitle(fTitle.title);
+       }
+}
+
+
 int32
 TermWindow::_NewSessionID()
 {
@@ -1152,6 +1230,6 @@
 void
 CustomTermView::SetTitle(const char* title)
 {
-       dynamic_cast<TermWindow*>(Window())->SetSessionWindowTitle(this, title);
+       dynamic_cast<TermWindow*>(Window())->SetSessionTitle(this, title);
 }
 

Modified: haiku/trunk/src/apps/terminal/TermWindow.h
===================================================================
--- haiku/trunk/src/apps/terminal/TermWindow.h  2010-11-17 23:23:09 UTC (rev 
39472)
+++ haiku/trunk/src/apps/terminal/TermWindow.h  2010-11-17 23:46:13 UTC (rev 
39473)
@@ -32,6 +32,7 @@
 #define TERM_WINDOW_H
 
 
+#include <MessageRunner.h>
 #include <String.h>
 #include <Window.h>
 
@@ -49,11 +50,12 @@
 
 class TermWindow : public BWindow {
 public:
-                                                               
TermWindow(BRect frame, const char* title,
+                                                               
TermWindow(BRect frame, const BString& title,
+                                                                       bool 
isUserDefinedTitle, int32 windowIndex,
                                                                        uint32 
workspaces, Arguments* args);
        virtual                                         ~TermWindow();
 
-                       void                            
SetSessionWindowTitle(TermView* termView,
+                       void                            
SetSessionTitle(TermView* termView,
                                                                        const 
char* title);
                        void                            SessionChanged();
 
@@ -66,6 +68,12 @@
        virtual void                            FrameResized(float newWidth, 
float newHeight);
 
 private:
+                       struct Title {
+                               BString                 title;
+                               BString                 pattern;
+                               bool                    patternUserDefined;
+                       };
+
                        struct Session;
                        class TabView;
                        friend class TabView;
@@ -92,10 +100,18 @@
                        void                            _CheckChildren();
                        void                            _ResizeView(TermView* 
view);
 
+                       void                            _TitleSettingsChanged();
+                       void                            _UpdateTitles();
+                       void                            
_UpdateSessionTitle(int32 index);
+
                        int32                           _NewSessionID();
 
 private:
-                       BString                         fInitialTitle;
+                       Title                           fTitle;
+                       BString                         fSessionTitlePattern;
+                       int32                           fWindowIndex;
+                       BMessageRunner          fTitleUpdateRunner;
+
                        BList                           fSessions;
 
                        TabView*                        fTabView;

Added: haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.cpp                    
        (rev 0)
+++ haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.cpp    2010-11-17 
23:46:13 UTC (rev 39473)
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "TitlePlaceholderMapper.h"
+
+
+// #pragma mark - TitlePlaceholderMapper
+
+
+TitlePlaceholderMapper::TitlePlaceholderMapper(
+       const ActiveProcessInfo& processInfo)
+       :
+       fProcessInfo(processInfo)
+{
+}
+
+
+#include <stdio.h>
+bool
+TitlePlaceholderMapper::MapPlaceholder(char placeholder, int64 number,
+       bool numberGiven, BString& _string)
+{
+       switch (placeholder) {
+               case 'd':
+               {
+                       // current working directory
+
+                       // If a number is given, extract the respective number 
of rightmost
+                       // components.
+                       BString directory(fProcessInfo.CurrentDirectory());
+                       if (numberGiven && number > 0) {
+                               int32 index = directory.Length();
+                               while (number > 0 && index > 0) {
+                                        index = directory.FindLast('/', index 
- 1);
+                                        number--;
+                               }
+
+                               if (index >= 0 && index + 1 < 
directory.Length())
+                                       directory.Remove(0, index + 1);
+                       }
+
+                       _string = directory;
+                       return true;
+               }
+
+               case 'p':
+                       // process name
+                       _string = fProcessInfo.Name();
+                       return true;
+       }
+
+       return false;
+}
+
+
+// #pragma mark - WindowTitlePlaceholderMapper
+
+
+WindowTitlePlaceholderMapper::WindowTitlePlaceholderMapper(
+       const ActiveProcessInfo& processInfo, int32 windowIndex,
+       const BString& tabTitle)
+       :
+       TitlePlaceholderMapper(processInfo),
+       fWindowIndex(windowIndex),
+       fTabTitle(tabTitle)
+{
+}
+
+
+bool
+WindowTitlePlaceholderMapper::MapPlaceholder(char placeholder, int64 number,
+       bool numberGiven, BString& _string)
+{
+       switch (placeholder) {
+               case 'i':
+                       // window index
+                       _string.Truncate(0);
+                       _string << fWindowIndex;
+                       return true;
+
+               case 't':
+                       // the tab title
+                       _string = fTabTitle;
+                       return true;
+       }
+
+       return TitlePlaceholderMapper::MapPlaceholder(placeholder, number,
+               numberGiven, _string);
+}
+
+
+// #pragma mark - TabTitlePlaceholderMapper
+
+
+TabTitlePlaceholderMapper::TabTitlePlaceholderMapper(
+       const ActiveProcessInfo& processInfo, int32 tabIndex)
+       :
+       TitlePlaceholderMapper(processInfo),
+       fTabIndex(tabIndex)
+{
+}
+
+
+bool
+TabTitlePlaceholderMapper::MapPlaceholder(char placeholder, int64 number,
+       bool numberGiven, BString& _string)
+{
+       switch (placeholder) {
+               case 'i':
+                       // tab index
+                       _string.Truncate(0);
+                       _string << fTabIndex;
+                       return true;
+       }
+
+       return TitlePlaceholderMapper::MapPlaceholder(placeholder, number,
+               numberGiven, _string);
+}

Added: haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.h
===================================================================
--- haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.h                      
        (rev 0)
+++ haiku/trunk/src/apps/terminal/TitlePlaceholderMapper.h      2010-11-17 
23:46:13 UTC (rev 39473)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef TITLE_PLACEHOLDER_MAPPER_H
+#define TITLE_PLACEHOLDER_MAPPER_H
+
+
+#include "ActiveProcessInfo.h"
+#include "PatternEvaluator.h"
+
+
+/*! Class mapping the placeholders common for window and tab titles.
+ */
+class TitlePlaceholderMapper : public PatternEvaluator::PlaceholderMapper {
+public:
+                                                               
TitlePlaceholderMapper(
+                                                                       const 
ActiveProcessInfo& processInfo);
+
+       virtual bool                            MapPlaceholder(char placeholder,
+                                                                       int64 
number, bool numberGiven,
+                                                                       
BString& _string);
+
+private:
+                       ActiveProcessInfo       fProcessInfo;
+};
+
+
+class WindowTitlePlaceholderMapper : public TitlePlaceholderMapper {
+public:
+                                                               
WindowTitlePlaceholderMapper(
+                                                                       const 
ActiveProcessInfo& processInfo,
+                                                                       int32 
windowIndex, const BString& tabTitle);
+
+       virtual bool                            MapPlaceholder(char placeholder,
+                                                                       int64 
number, bool numberGiven,
+                                                                       
BString& _string);
+
+private:
+                       int32                           fWindowIndex;
+                       BString                         fTabTitle;
+};
+
+
+class TabTitlePlaceholderMapper : public TitlePlaceholderMapper {
+public:
+                                                               
TabTitlePlaceholderMapper(
+                                                                       const 
ActiveProcessInfo& processInfo,
+                                                                       int32 
tabIndex);
+
+       virtual bool                            MapPlaceholder(char placeholder,
+                                                                       int64 
number, bool numberGiven,
+                                                                       
BString& _string);
+
+private:
+                       int32                           fTabIndex;
+};
+
+
+#endif // TITLE_PLACEHOLDER_MAPPER_H


Other related posts:

  • » [haiku-commits] r39473 - haiku/trunk/src/apps/terminal - ingo_weinhold