* Added SetTitleDialog, a dialog to edit a tab/window title.
* Use the dialog to open the tab title. Opened on double-click on the tab. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39497 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b647673227
commit
135f173dce
@ -20,6 +20,7 @@ Application Terminal :
|
||||
PatternEvaluator.cpp
|
||||
PrefHandler.cpp
|
||||
PrefWindow.cpp
|
||||
SetTitleDialog.cpp
|
||||
Shell.cpp
|
||||
ShellParameters.cpp
|
||||
SmartTabView.cpp
|
||||
|
139
src/apps/terminal/SetTitleDialog.cpp
Normal file
139
src/apps/terminal/SetTitleDialog.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "SetTitleDialog.h"
|
||||
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
|
||||
static const uint32 kMessageOK = 'okok';
|
||||
static const uint32 kMessageDefault = 'dflt';
|
||||
static const uint32 kMessageTitleChanged = 'chng';
|
||||
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "Terminal SetTitleWindow"
|
||||
|
||||
|
||||
// #pragma mark - SetTitleDialog
|
||||
|
||||
|
||||
SetTitleDialog::SetTitleDialog(const char* dialogTitle, const char* label,
|
||||
const char* toolTip)
|
||||
:
|
||||
BWindow(BRect(0, 0, 0, 0), dialogTitle, B_BORDERED_WINDOW_LOOK,
|
||||
B_FLOATING_APP_WINDOW_FEEL,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
|
||||
fListener(NULL),
|
||||
fTitle(),
|
||||
fTitleUserDefined(false)
|
||||
{
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
||||
.SetInsets(10, 10, 10, 10)
|
||||
.Add(fTitleTextControl = new BTextControl("title", label, "", NULL))
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(fDefaultButton = new BButton("defaultButton",
|
||||
B_TRANSLATE("Use default"), new BMessage(kMessageDefault)))
|
||||
.AddGlue()
|
||||
.Add(fCancelButton = new BButton("cancelButton",
|
||||
B_TRANSLATE("Cancel"), new BMessage(B_QUIT_REQUESTED)))
|
||||
.Add(fOKButton = new BButton("okButton", B_TRANSLATE("OK"),
|
||||
new BMessage(kMessageOK)));
|
||||
|
||||
fTitleTextControl->SetToolTip(toolTip);
|
||||
|
||||
fOKButton->MakeDefault(true);
|
||||
|
||||
UpdateSizeLimits();
|
||||
// as a courtesy to our creator, who might want to place us
|
||||
}
|
||||
|
||||
|
||||
SetTitleDialog::~SetTitleDialog()
|
||||
{
|
||||
if (fListener != NULL) {
|
||||
// reset to old title
|
||||
fListener->TitleChanged(this, fOldTitle, fOldTitleUserDefined);
|
||||
|
||||
Listener* listener = fListener;
|
||||
fListener = NULL;
|
||||
listener->SetTitleDialogDone(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetTitleDialog::Go(const BString& title, bool titleUserDefined,
|
||||
Listener* listener)
|
||||
{
|
||||
fTitle = fOldTitle = title;
|
||||
fTitleUserDefined = fOldTitleUserDefined = titleUserDefined;
|
||||
|
||||
fDefaultButton->SetEnabled(titleUserDefined);
|
||||
|
||||
fTitleTextControl->SetText(fTitle);
|
||||
fTitleTextControl->SetModificationMessage(
|
||||
new BMessage(kMessageTitleChanged));
|
||||
fTitleTextControl->MakeFocus(true);
|
||||
|
||||
fListener = listener;
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetTitleDialog::Finish()
|
||||
{
|
||||
if (Listener* listener = fListener) {
|
||||
fListener = NULL;
|
||||
listener->SetTitleDialogDone(this);
|
||||
}
|
||||
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetTitleDialog::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMessageDefault:
|
||||
if (fListener != NULL)
|
||||
fListener->TitleChanged(this, BString(), false);
|
||||
// We're done now, fall through...
|
||||
|
||||
case kMessageOK:
|
||||
Finish();
|
||||
break;
|
||||
|
||||
case kMessageTitleChanged:
|
||||
fTitle = fTitleTextControl->Text();
|
||||
fTitleUserDefined = true;
|
||||
|
||||
fDefaultButton->SetEnabled(true);
|
||||
|
||||
if (fListener != NULL)
|
||||
fListener->TitleChanged(this, fTitle, fTitleUserDefined);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - SetTitleDialog
|
||||
|
||||
|
||||
SetTitleDialog::Listener::~Listener()
|
||||
{
|
||||
}
|
58
src/apps/terminal/SetTitleDialog.h
Normal file
58
src/apps/terminal/SetTitleDialog.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef SET_TITLE_DIALOG_H
|
||||
#define SET_TITLE_DIALOG_H
|
||||
|
||||
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
class BButton;
|
||||
class BTextControl;
|
||||
|
||||
|
||||
class SetTitleDialog : public BWindow {
|
||||
public:
|
||||
class Listener;
|
||||
|
||||
public:
|
||||
SetTitleDialog(const char* dialogTitle,
|
||||
const char* label, const char* toolTip);
|
||||
virtual ~SetTitleDialog();
|
||||
|
||||
void Go(const BString& title, bool titleUserDefined,
|
||||
Listener* listener);
|
||||
void Finish();
|
||||
// window must be locked
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
Listener* fListener;
|
||||
BTextControl* fTitleTextControl;
|
||||
BButton* fOKButton;
|
||||
BButton* fCancelButton;
|
||||
BButton* fDefaultButton;
|
||||
BString fOldTitle;
|
||||
BString fTitle;
|
||||
bool fOldTitleUserDefined;
|
||||
bool fTitleUserDefined;
|
||||
};
|
||||
|
||||
|
||||
class SetTitleDialog::Listener {
|
||||
public:
|
||||
virtual ~Listener();
|
||||
|
||||
// hooks called in the dialog thread with the window locked
|
||||
virtual void TitleChanged(SetTitleDialog* dialog,
|
||||
const BString& title,
|
||||
bool titleUserDefined) = 0;
|
||||
virtual void SetTitleDialogDone(SetTitleDialog* dialog) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // SET_TITLE_DIALOG_H
|
@ -93,6 +93,8 @@ static const uint32 MSG_REPORT_MOUSE_EVENT = 'mous';
|
||||
static const uint32 MSG_SAVE_WINDOW_POSITION = 'swps';
|
||||
static const uint32 MSG_MOVE_TAB_LEFT = 'mvtl';
|
||||
static const uint32 MSG_MOVE_TAB_RIGHT = 'mvtr';
|
||||
static const uint32 MSG_TAB_TITLE_CHANGED = 'ttch';
|
||||
static const uint32 MSG_WINDOW_TITLE_CHANGED = 'wtch';
|
||||
|
||||
// Preference Read/Write Keys
|
||||
static const char* const PREF_HALF_FONT_FAMILY = "Half Font Family";
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <Catalog.h>
|
||||
#include <Clipboard.h>
|
||||
#include <Dragger.h>
|
||||
#include <LayoutUtils.h>
|
||||
#include <Locale.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuBar.h>
|
||||
@ -40,6 +41,7 @@
|
||||
#include "Globals.h"
|
||||
#include "PrefWindow.h"
|
||||
#include "PrefHandler.h"
|
||||
#include "SetTitleDialog.h"
|
||||
#include "ShellParameters.h"
|
||||
#include "TermConst.h"
|
||||
#include "TermScrollView.h"
|
||||
@ -163,6 +165,7 @@ TermWindow::TermWindow(BRect frame, const BString& title,
|
||||
fPrefWindow(NULL),
|
||||
fFindPanel(NULL),
|
||||
fSavedFrame(0, 0, -1, -1),
|
||||
fSetTabTitleDialog(NULL),
|
||||
fFindString(""),
|
||||
fFindNextMenuItem(NULL),
|
||||
fFindPreviousMenuItem(NULL),
|
||||
@ -185,6 +188,8 @@ TermWindow::TermWindow(BRect frame, const BString& title,
|
||||
|
||||
TermWindow::~TermWindow()
|
||||
{
|
||||
_FinishTitleDialog();
|
||||
|
||||
if (fPrefWindow)
|
||||
fPrefWindow->PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
@ -279,6 +284,8 @@ TermWindow::_CanClose(int32 index)
|
||||
bool
|
||||
TermWindow::QuitRequested()
|
||||
{
|
||||
_FinishTitleDialog();
|
||||
|
||||
if (!_CanClose(-1))
|
||||
return false;
|
||||
|
||||
@ -688,6 +695,24 @@ TermWindow::MessageReceived(BMessage *message)
|
||||
message->what == MSG_MOVE_TAB_LEFT ? -1 : 1, true);
|
||||
break;
|
||||
|
||||
case MSG_TAB_TITLE_CHANGED:
|
||||
{
|
||||
// tab title changed message from SetTitleDialog
|
||||
SessionID sessionID(*message, "session");
|
||||
if (Session* session = _SessionForID(sessionID)) {
|
||||
BString title;
|
||||
if (message->FindString("title", &title) == B_OK) {
|
||||
session->title.pattern = title;
|
||||
session->title.patternUserDefined = true;
|
||||
} else {
|
||||
session->title.pattern.Truncate(0);
|
||||
session->title.patternUserDefined = false;
|
||||
}
|
||||
_UpdateSessionTitle(fSessions.IndexOf(session));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kSetActiveTab:
|
||||
{
|
||||
int32 index;
|
||||
@ -942,6 +967,9 @@ TermWindow::_AddTab(Arguments* args, const BString& currentDirectory)
|
||||
void
|
||||
TermWindow::_RemoveTab(int32 index)
|
||||
{
|
||||
_FinishTitleDialog();
|
||||
// always close to avoid confusion
|
||||
|
||||
if (fSessions.CountItems() > 1) {
|
||||
if (!_CanClose(index))
|
||||
return;
|
||||
@ -1032,6 +1060,18 @@ TermWindow::_IndexOfTermView(TermView* termView) const
|
||||
}
|
||||
|
||||
|
||||
TermWindow::Session*
|
||||
TermWindow::_SessionForID(const SessionID& sessionID) const
|
||||
{
|
||||
for (int32 i = 0; Session* session = (Session*)fSessions.ItemAt(i); i++) {
|
||||
if (session->id == sessionID)
|
||||
return session;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::_CheckChildren()
|
||||
{
|
||||
@ -1074,7 +1114,32 @@ void
|
||||
TermWindow::TabDoubleClicked(SmartTabView* tabView, BPoint point, int32 index)
|
||||
{
|
||||
if (index >= 0) {
|
||||
// TODO: Open the change title dialog!
|
||||
// If a dialog is active, finish it.
|
||||
_FinishTitleDialog();
|
||||
|
||||
BString toolTip = BString(B_TRANSLATE(
|
||||
"The pattern specifying the current tab title. The following "
|
||||
"placeholders\n"
|
||||
"can be used:\n")) << kTooTipSetTabTitlePlaceholders;
|
||||
fSetTabTitleDialog = new SetTitleDialog(
|
||||
B_TRANSLATE("Set tab title"), B_TRANSLATE("Tab title:"),
|
||||
toolTip);
|
||||
|
||||
Session* session = (Session*)fSessions.ItemAt(index);
|
||||
bool userDefined = session->title.patternUserDefined;
|
||||
const BString& title = userDefined
|
||||
? session->title.pattern : fSessionTitlePattern;
|
||||
fSetTabTitleSession = session->id;
|
||||
|
||||
// place the dialog window directly under the tab, but keep it on screen
|
||||
BPoint location = tabView->ConvertToScreen(
|
||||
tabView->TabFrame(index).LeftBottom() + BPoint(0, 1));
|
||||
BRect frame(fSetTabTitleDialog->Frame().OffsetToCopy(location));
|
||||
BSize screenSize(BScreen(fSetTabTitleDialog).Frame().Size());
|
||||
fSetTabTitleDialog->MoveTo(
|
||||
BLayoutUtils::MoveIntoFrame(frame, screenSize).LeftTop());
|
||||
|
||||
fSetTabTitleDialog->Go(title, userDefined, this);
|
||||
} else {
|
||||
// not clicked on a tab -- create a new one
|
||||
_NewTab();
|
||||
@ -1139,6 +1204,33 @@ TermWindow::SetTermViewTitle(TermView* view, const char* title)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::TitleChanged(SetTitleDialog* dialog, const BString& title,
|
||||
bool titleUserDefined)
|
||||
{
|
||||
if (dialog != fSetTabTitleDialog)
|
||||
return;
|
||||
|
||||
BMessage message(MSG_TAB_TITLE_CHANGED);
|
||||
fSetTabTitleSession.AddToMessage(message, "session");
|
||||
if (titleUserDefined)
|
||||
message.AddString("title", title);
|
||||
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::SetTitleDialogDone(SetTitleDialog* dialog)
|
||||
{
|
||||
if (dialog == fSetTabTitleDialog) {
|
||||
fSetTabTitleSession = SessionID();
|
||||
fSetTabTitleDialog = NULL;
|
||||
// assuming this is atomic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::PreviousTermView(TermView* view)
|
||||
{
|
||||
@ -1285,6 +1377,21 @@ TermWindow::_UpdateSessionTitle(int32 index)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermWindow::_FinishTitleDialog()
|
||||
{
|
||||
SetTitleDialog* oldDialog = fSetTabTitleDialog;
|
||||
if (oldDialog != NULL && oldDialog->Lock()) {
|
||||
// might have been unset in the meantime, so recheck
|
||||
if (fSetTabTitleDialog == oldDialog) {
|
||||
oldDialog->Finish();
|
||||
// this also unsets the variables
|
||||
}
|
||||
oldDialog->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TermWindow::SessionID
|
||||
TermWindow::_NewSessionID()
|
||||
{
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <Window.h>
|
||||
|
||||
#include "SmartTabView.h"
|
||||
#include "SetTitleDialog.h"
|
||||
#include "TermView.h"
|
||||
|
||||
|
||||
@ -50,7 +51,7 @@ class TermViewContainerView;
|
||||
|
||||
|
||||
class TermWindow : public BWindow, private SmartTabView::Listener,
|
||||
private TermView::Listener {
|
||||
private TermView::Listener, private SetTitleDialog::Listener {
|
||||
public:
|
||||
TermWindow(BRect frame, const BString& title,
|
||||
bool isUserDefinedTitle, int32 windowIndex,
|
||||
@ -85,6 +86,12 @@ private:
|
||||
virtual void PreviousTermView(TermView* view);
|
||||
virtual void NextTermView(TermView* view);
|
||||
|
||||
// SetTitleDialog::Listener
|
||||
virtual void TitleChanged(SetTitleDialog* dialog,
|
||||
const BString& title,
|
||||
bool titleUserDefined);
|
||||
virtual void SetTitleDialogDone(SetTitleDialog* dialog);
|
||||
|
||||
private:
|
||||
struct Title {
|
||||
BString title;
|
||||
@ -93,13 +100,18 @@ private:
|
||||
};
|
||||
|
||||
struct SessionID {
|
||||
SessionID(int32 id);
|
||||
SessionID(int32 id = -1);
|
||||
SessionID(const BMessage& message,
|
||||
const char* field);
|
||||
|
||||
status_t AddToMessage(BMessage& message,
|
||||
const char* field) const;
|
||||
|
||||
bool operator==(const SessionID& other) const
|
||||
{ return fID == other.fID; }
|
||||
bool operator!=(const SessionID& other) const
|
||||
{ return !(*this == other); }
|
||||
|
||||
private:
|
||||
int32 fID;
|
||||
};
|
||||
@ -125,17 +137,21 @@ private:
|
||||
bool move);
|
||||
|
||||
bool _CanClose(int32 index);
|
||||
|
||||
TermViewContainerView* _ActiveTermViewContainerView() const;
|
||||
TermViewContainerView* _TermViewContainerViewAt(int32 index) const;
|
||||
TermView* _ActiveTermView() const;
|
||||
TermView* _TermViewAt(int32 index) const;
|
||||
int32 _IndexOfTermView(TermView* termView) const;
|
||||
Session* _SessionForID(const SessionID& sessionID) const;
|
||||
|
||||
void _CheckChildren();
|
||||
void _ResizeView(TermView* view);
|
||||
|
||||
void _TitleSettingsChanged();
|
||||
void _UpdateTitles();
|
||||
void _UpdateSessionTitle(int32 index);
|
||||
void _FinishTitleDialog();
|
||||
|
||||
SessionID _NewSessionID();
|
||||
int32 _NewSessionIndex();
|
||||
@ -150,7 +166,6 @@ private:
|
||||
int32 fNextSessionID;
|
||||
|
||||
SmartTabView* fTabView;
|
||||
TermView* fTermView;
|
||||
|
||||
BMenuBar* fMenubar;
|
||||
BMenu* fFilemenu;
|
||||
@ -166,6 +181,9 @@ private:
|
||||
BRect fSavedFrame;
|
||||
window_look fSavedLook;
|
||||
|
||||
SetTitleDialog* fSetTabTitleDialog;
|
||||
SessionID fSetTabTitleSession;
|
||||
|
||||
// Saved search parameters
|
||||
BString fFindString;
|
||||
BMenuItem* fFindNextMenuItem;
|
||||
|
Loading…
x
Reference in New Issue
Block a user