diff --git a/source/DScpComp.cbproj b/source/DScpComp.cbproj
index 34dcdd95f..fa124eb4f 100644
--- a/source/DScpComp.cbproj
+++ b/source/DScpComp.cbproj
@@ -49,8 +49,8 @@
WinSCP components
true
true
- components\;$(ILINK_LibraryPath)
- components\;core;packages\filemng;packages\dragndrop;packages\my;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)
+ components\;$(INTERM_PATH)\Win32\Debug;$(ILINK_LibraryPath)
+ components\;core;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)
$(INTERM_PATH)\$(Platform)\$(Config)
rtl.lib;vcl.lib;vclx.lib
true
@@ -116,6 +116,9 @@
20
1
+
+ 8
+
23
0
diff --git a/source/RScpComp.cbproj b/source/RScpComp.cbproj
index 0ca26b8df..a621ed4d1 100644
--- a/source/RScpComp.cbproj
+++ b/source/RScpComp.cbproj
@@ -38,7 +38,7 @@
System;Xml;Data;Datasnap;Web;Soap;Vcl;$(DCC_Namespace)
$(INTERM_PATH)\$(Platform)\$(Config)
$(BDS)\lib;$(ILINK_LibraryPath)
- components\;core;windows;packages\filemng;packages\dragndrop;packages\my;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)
+ components\;core;windows;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)
$(INTERM_PATH)\$(Platform)\$(Config)
None
true
diff --git a/source/components/ThemePageControl.cpp b/source/components/ThemePageControl.cpp
index 67e4cb151..92c9d274a 100644
--- a/source/components/ThemePageControl.cpp
+++ b/source/components/ThemePageControl.cpp
@@ -5,6 +5,8 @@
#include
#include
#include
+#include
+#include
#include "ThemePageControl.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
@@ -39,6 +41,20 @@ __fastcall TThemeTabSheet::TThemeTabSheet(TComponent * Owner) :
TTabSheet(Owner)
{
FShadowed = false;
+ FShowCloseButton = false;
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemeTabSheet::Invalidate()
+{
+ TThemePageControl * ThemePageControl = dynamic_cast(Parent);
+ if (DebugAlwaysTrue(ThemePageControl != NULL))
+ {
+ ThemePageControl->InvalidateTab(TabIndex);
+ }
+ else
+ {
+ Parent->Invalidate();
+ }
}
//----------------------------------------------------------------------------------------------------------
void __fastcall TThemeTabSheet::SetShadowed(bool Value)
@@ -46,16 +62,16 @@ void __fastcall TThemeTabSheet::SetShadowed(bool Value)
if (Shadowed != Value)
{
FShadowed = Value;
-
- TThemePageControl * ThemePageControl = dynamic_cast(Parent);
- if (DebugAlwaysTrue(ThemePageControl != NULL))
- {
- ThemePageControl->InvalidateTab(TabIndex);
- }
- else
- {
- Parent->Invalidate();
- }
+ Invalidate();
+ }
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemeTabSheet::SetShowCloseButton(bool Value)
+{
+ if (ShowCloseButton != Value)
+ {
+ FShowCloseButton = Value;
+ Invalidate();
}
}
//----------------------------------------------------------------------------------------------------------
@@ -64,6 +80,7 @@ __fastcall TThemePageControl::TThemePageControl(TComponent * Owner) :
TPageControl(Owner)
{
FOldTabIndex = -1;
+ FHotCloseButton = -1;
}
//----------------------------------------------------------------------------------------------------------
int __fastcall TThemePageControl::GetTabsHeight()
@@ -116,32 +133,48 @@ void __fastcall TThemePageControl::PaintWindow(HDC DC)
// 2nd paint the inactive tabs
- TPoint Point = ScreenToClient(Mouse->CursorPos);
- int HotIndex = IndexOfTabAt(Point.X, Point.Y);
- int SelectedIndex = TabIndex;
+ int SelectedIndex = TabIndex; // optimization
for (int Tab = 0; Tab < PageCount; Tab++)
{
if (Tab != SelectedIndex)
{
- TThemeTabSheet * ThemeTabSheet = dynamic_cast(Pages[Tab]);
- bool Shadowed = (ThemeTabSheet != NULL) ? ThemeTabSheet->Shadowed : false;
- TRect Rect = TabRect(Tab);
- int State = (Tab == HotIndex ? TIS_HOT : (Shadowed ? TIS_DISABLED : TIS_NORMAL));
- DrawThemesXpTabItem(DC, Tab, Rect, false, State);
+ DrawThemesXpTab(DC, Tab);
}
}
if (SelectedIndex >= 0)
{
- // 3rd paint the active selected tab
- TRect Rect = TabRect(SelectedIndex);
- Rect.Inflate(2, 2);
- Rect.Bottom--;
- DrawThemesXpTabItem(DC, SelectedIndex, Rect, false, TIS_SELECTED);
+ DrawThemesXpTab(DC, TabIndex);
}
}
//----------------------------------------------------------------------------------------------------------
+bool __fastcall TThemePageControl::HasTabCloseButton(int Index)
+{
+ TThemeTabSheet * ThemeTabSheet = dynamic_cast(Pages[Index]);
+ return (ThemeTabSheet != NULL) ? ThemeTabSheet->ShowCloseButton : false;
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemePageControl::DrawThemesXpTab(HDC DC, int Tab)
+{
+ TThemeTabSheet * ThemeTabSheet = dynamic_cast(Pages[Tab]);
+ bool Shadowed = (ThemeTabSheet != NULL) ? ThemeTabSheet->Shadowed : false;
+ TRect Rect = TabRect(Tab);
+ ItemTabRect(Tab, Rect);
+ int State;
+ if (Tab != TabIndex)
+ {
+ TPoint Point = ScreenToClient(Mouse->CursorPos);
+ int HotIndex = IndexOfTabAt(Point.X, Point.Y);
+ State = (Tab == HotIndex ? TIS_HOT : (Shadowed ? TIS_DISABLED : TIS_NORMAL));
+ }
+ else
+ {
+ State = TIS_SELECTED;
+ }
+ DrawThemesXpTabItem(DC, Tab, Rect, false, State);
+}
+//----------------------------------------------------------------------------------------------------------
// This function draws Themes Tab control parts: a) Tab-Body and b) Tab-tabs
void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
const TRect & Rect, bool Body, int State)
@@ -154,6 +187,7 @@ void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
HBITMAP BitmapOld = (HBITMAP)SelectObject(DCMem, BitmapMem);
TRect RectMem(0, 0, Size.Width, Size.Height);
+ TRect RectItemMem(RectMem);
if (!Body && (State == TIS_SELECTED))
{
RectMem.Bottom++;
@@ -183,12 +217,7 @@ void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
if (!Body && (Item >= 0))
{
- if ((State == TIS_SELECTED))
- {
- RectMem.Bottom--;
- }
-
- DrawTabItem(DCMem, Item, RectMem, (State == TIS_SELECTED), (State == TIS_DISABLED));
+ DrawTabItem(DCMem, Item, Rect, RectItemMem, (State == TIS_SELECTED), (State == TIS_DISABLED));
}
// Blit image to the screen
@@ -198,25 +227,78 @@ void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
DeleteDC(DCMem);
}
//----------------------------------------------------------------------------------------------------------
-// draw tab item context: possible icon and text
-void __fastcall TThemePageControl::DrawTabItem(HDC DC, int Item, TRect Rect,
- bool Selected, bool Shadowed)
+void __fastcall TThemePageControl::ItemTabRect(int Item, TRect & Rect)
{
+ if (Item == TabIndex)
+ {
+ // Countered in CloseButtonRect
+ Rect.Inflate(2, 2);
+ Rect.Bottom--;
+ }
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemePageControl::ItemContentsRect(int Item, TRect & Rect)
+{
+ bool Selected = (Item == TabIndex);
+
+ Rect.Left += 6;
+ Rect.Top += 2;
+
if (Selected)
{
- Rect.Bottom -= 1;
+ Rect.Bottom -= 2;
+ Rect.Top += 1;
}
else
{
Rect.Bottom += 2;
+ Rect.Top += 3;
}
-
- Rect.Left += 6;
- Rect.Top += 2 + (Selected ? 1 : 3);
+}
+//----------------------------------------------------------------------------------------------------------
+bool __fastcall TThemePageControl::HasItemImage(int Item)
+{
+ return (Images != NULL) && (Pages[Item]->ImageIndex >= 0);
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemePageControl::ItemTextRect(int Item, TRect & Rect)
+{
+ if (HasItemImage(Item))
+ {
+ Rect.Left += Images->Width + 3;
+ }
+ else
+ {
+ Rect.Left -= 2;
+ }
+ Rect.Right -= 3;
+ OffsetRect(&Rect, 0, ((Item == TabIndex) ? 0 : -2));
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemePageControl::DrawCross(HDC DC, int Width, COLORREF Color, const TRect & Rect)
+{
+ HPEN Pen = CreatePen(PS_SOLID, Width, Color);
+ HPEN OldPen = static_cast(SelectObject(DC, Pen));
+ // To-and-back - to make both ends look the same
+ MoveToEx(DC, Rect.Left, Rect.Bottom - 1, NULL);
+ LineTo(DC, Rect.Right - 1, Rect.Top);
+ LineTo(DC, Rect.Left, Rect.Bottom - 1);
+ MoveToEx(DC, Rect.Left, Rect.Top, NULL);
+ LineTo(DC, Rect.Right - 1, Rect.Bottom - 1);
+ LineTo(DC, Rect.Left, Rect.Top);
+ SelectObject(DC, OldPen);
+ DeleteObject(Pen);
+}
+//----------------------------------------------------------------------------------------------------------
+// draw tab item context: possible icon and text
+void __fastcall TThemePageControl::DrawTabItem(
+ HDC DC, int Item, TRect TabRect, TRect Rect, bool Selected, bool Shadowed)
+{
+ ItemContentsRect(Item, Rect);
UnicodeString Text = Pages[Item]->Caption;
- if ((Images != NULL) && (Pages[Item]->ImageIndex >= 0))
+ if (HasItemImage(Item))
{
int Left;
if (!Text.IsEmpty())
@@ -231,32 +313,132 @@ void __fastcall TThemePageControl::DrawTabItem(HDC DC, int Item, TRect Rect,
std::unique_ptr Canvas(new TCanvas());
Canvas->Handle = DC;
Images->Draw(Canvas.get(), Left, Y, Pages[Item]->ImageIndex, !Shadowed);
- Rect.Left += Images->Width + 3;
- }
- else
- {
- Rect.Left -= 2;
}
+ int TextHeight = 20;
int OldMode = SetBkMode(DC, TRANSPARENT);
if (!Text.IsEmpty())
{
+ ItemTextRect(Item, Rect);
HFONT OldFont = (HFONT)SelectObject(DC, Font->Handle);
- Rect.Right -= 3;
wchar_t * Buf = new wchar_t[Text.Length() + 1 + 4];
wcscpy(Buf, Text.c_str());
- TRect TextRect(0, 0, Rect.Right - Rect.Left, 20);
+ TRect TextRect(0, 0, Rect.Right - Rect.Left, TextHeight);
+ // Truncates too long texts with ellipsis
::DrawText(DC, Buf, -1, &TextRect, DT_CALCRECT | DT_SINGLELINE | DT_MODIFYSTRING | DT_END_ELLIPSIS);
- OffsetRect(&Rect, 0, (Selected ? 0 : -2));
DrawText(DC, Buf, -1, &Rect, DT_NOPREFIX | DT_CENTER);
delete[] Buf;
+
+ if (HasTabCloseButton(Item))
+ {
+ Rect = CloseButtonRect(Item);
+ Rect.Offset(-TabRect.Left, -TabRect.Top);
+
+ if (FHotCloseButton == Item)
+ {
+ HBRUSH Brush = CreateSolidBrush(GetSelectedBodyColor());
+ FillRect(DC, &Rect, Brush);
+ DeleteObject(Brush);
+
+ HPEN Pen = CreatePen(PS_SOLID, 1, ColorToRGB(clHighlight));
+ HPEN OldPen = static_cast(SelectObject(DC, Pen));
+ Rectangle(DC, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
+ SelectObject(DC, OldPen);
+ DeleteObject(Pen);
+ }
+
+ int CrossPadding = GetCrossPadding();
+
+ COLORREF BackColor = GetPixel(DC, Rect.Left + (Rect.Width() / 2), Rect.Top + (Rect.Height() / 2));
+ COLORREF CrossColor = ColorToRGB(Font->Color);
+ #define BlendValue(FN) (((4 * static_cast(FN(BackColor))) + static_cast(FN(CrossColor))) / 5)
+ COLORREF BlendColor = RGB(BlendValue(GetRValue), BlendValue(GetGValue), BlendValue(GetBValue));
+ #undef BlendValue
+
+ TRect CrossRect(Rect);
+ CrossRect.Inflate(-CrossPadding, -CrossPadding);
+
+ int CrossWidth = ScaleByTextHeight(this, 1);
+ DrawCross(DC, CrossWidth + 1, BlendColor, CrossRect);
+ DrawCross(DC, CrossWidth, CrossColor, CrossRect);
+ }
+
SelectObject(DC, OldFont);
}
SetBkMode(DC, OldMode);
}
//----------------------------------------------------------------------------------------------------------
+int __fastcall TThemePageControl::CloseButtonSize()
+{
+ return ScaleByTextHeight(this, 16);
+}
+//----------------------------------------------------------------------------------------------------------
+int __fastcall TThemePageControl::GetCrossPadding()
+{
+ return ScaleByTextHeight(this, 4);
+}
+//----------------------------------------------------------------------------------------------------------
+TRect __fastcall TThemePageControl::CloseButtonRect(int Index)
+{
+ TRect Rect = TabRect(Index);
+ ItemTabRect(Index, Rect);
+ ItemContentsRect(Index, Rect);
+ ItemTextRect(Index, Rect);
+
+ int ACloseButtonSize = CloseButtonSize();
+ int CrossPadding = GetCrossPadding();
+
+ TEXTMETRIC TextMetric;
+ Canvas->Font = Font;
+ GetTextMetrics(Canvas->Handle, &TextMetric);
+
+ Rect.Top += TextMetric.tmAscent - ACloseButtonSize + CrossPadding;
+ Rect.Left = Rect.Right - ACloseButtonSize - ScaleByTextHeight(this, 1);
+ if (Index == TabIndex)
+ {
+ // To counter Inflate(2, 2) in ItemTabRect
+ Rect.Left -= 2;
+ }
+ Rect.Right = Rect.Left + ACloseButtonSize;
+ Rect.Bottom = Rect.Top + ACloseButtonSize;
+ return Rect;
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemePageControl::SetHotCloseButton(int Index)
+{
+ if (Index != FHotCloseButton)
+ {
+ if (FHotCloseButton >= 0)
+ {
+ InvalidateTab(FHotCloseButton);
+ }
+ FHotCloseButton = Index;
+ if (FHotCloseButton >= 0)
+ {
+ InvalidateTab(FHotCloseButton);
+ }
+ }
+}
+//----------------------------------------------------------------------------------------------------------
+void __fastcall TThemePageControl::MouseMove(TShiftState /*Shift*/, int X, int Y)
+{
+ SetHotCloseButton(IndexOfCloseButtonAt(X, Y));
+}
+//----------------------------------------------------------------------------------------------------------
+int __fastcall TThemePageControl::IndexOfCloseButtonAt(int X, int Y)
+{
+ int Result = IndexOfTabAt(X, Y);
+ if ((Result < 0) ||
+ !HasTabCloseButton(Result) ||
+ !CloseButtonRect(Result).Contains(TPoint(X, Y)))
+ {
+ Result = -1;
+ }
+ return Result;
+}
+//----------------------------------------------------------------------------------------------------------
void __fastcall TThemePageControl::DrawThemesPart(HDC DC, int PartId,
int StateId, LPCWSTR PartNameID, LPRECT Rect)
{
@@ -267,8 +449,7 @@ void __fastcall TThemePageControl::DrawThemesPart(HDC DC, int PartId,
CloseThemeData(Theme);
}
}
-//==========================================================================================================
-// these two messages are necessary only to properly redraw deselected tab background, because
+//----------------------------------------------------------------------------------------------------------
bool __fastcall TThemePageControl::CanChange()
{
FOldTabIndex = ActivePageIndex;
@@ -303,6 +484,53 @@ void __fastcall TThemePageControl::Change()
TPageControl::Change();
}
//----------------------------------------------------------------------------------------------------------
+UnicodeString __fastcall TThemePageControl::FormatCaptionWithCloseButton(const UnicodeString & Caption)
+{
+ int OrigWidth = Canvas->TextWidth(Caption);
+ UnicodeString Result = Caption;
+ int CloseButtonWidth = CloseButtonSize();
+ while (Canvas->TextWidth(Result) < OrigWidth + CloseButtonWidth)
+ {
+ Result += L" ";
+ }
+ return Result;
+}
+//---------------------------------------------------------------------------
+void __fastcall TThemePageControl::WMLButtonDown(TWMLButtonDown & Message)
+{
+ int Index = IndexOfCloseButtonAt(Message.XPos, Message.YPos);
+ if (Index >= 0)
+ {
+ Message.Result = 1;
+ if (FOnCloseButtonClick != NULL)
+ {
+ FOnCloseButtonClick(this, Index);
+ }
+ }
+ else
+ {
+ TPageControl::Dispatch(&Message);
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TThemePageControl::Dispatch(void * Message)
+{
+ TMessage * M = reinterpret_cast(Message);
+ if (M->Msg == CM_MOUSELEAVE)
+ {
+ SetHotCloseButton(-1);
+ TPageControl::Dispatch(Message);
+ }
+ else if (M->Msg == WM_LBUTTONDOWN)
+ {
+ WMLButtonDown(*reinterpret_cast(M));
+ }
+ else
+ {
+ TPageControl::Dispatch(Message);
+ }
+}
+//----------------------------------------------------------------------------------------------------------
#ifdef _DEBUG
void __fastcall TThemePageControl::RequestAlign()
{
diff --git a/source/components/ThemePageControl.h b/source/components/ThemePageControl.h
index c43abe800..2e343bd63 100644
--- a/source/components/ThemePageControl.h
+++ b/source/components/ThemePageControl.h
@@ -10,36 +10,64 @@ public:
__fastcall TThemeTabSheet(TComponent * Owner);
__property bool Shadowed = { read = FShadowed, write = SetShadowed };
+ __property bool ShowCloseButton = { read = FShowCloseButton, write = SetShowCloseButton };
private:
void __fastcall SetShadowed(bool Value);
+ void __fastcall SetShowCloseButton(bool Value);
+ void __fastcall Invalidate();
bool FShadowed;
+ bool FShowCloseButton;
};
//---------------------------------------------------------------------------
+typedef void __fastcall (__closure *TPageControlCloseButtonClick)(TPageControl * Sender, int Index);
+//---------------------------------------------------------------------------
class TThemePageControl : public TPageControl
{
friend class TThemeTabSheet;
+
+__published:
+ __property TPageControlCloseButtonClick OnCloseButtonClick = { read = FOnCloseButtonClick, write = FOnCloseButtonClick };
+
public:
__fastcall TThemePageControl(TComponent * Owner);
int __fastcall GetTabsHeight();
+ UnicodeString __fastcall FormatCaptionWithCloseButton(const UnicodeString & Caption);
protected:
virtual void __fastcall PaintWindow(HDC DC);
DYNAMIC bool __fastcall CanChange();
DYNAMIC void __fastcall Change();
+ DYNAMIC void __fastcall MouseMove(TShiftState Shift, int X, int Y);
+ virtual void __fastcall Dispatch(void * Message);
#ifdef _DEBUG
virtual void __fastcall RequestAlign();
#endif
private:
+ void __fastcall DrawThemesXpTab(HDC DC, int Tab);
void __fastcall DrawThemesXpTabItem(HDC DC, int Item, const TRect & Rect, bool Body, int State);
- void __fastcall DrawTabItem(HDC DC, int Item, TRect Rect, bool Selected, bool Shadowed);
+ void __fastcall DrawTabItem(HDC DC, int Item, TRect TabRect, TRect Rect, bool Selected, bool Shadowed);
void __fastcall DrawThemesPart(HDC DC, int PartId, int StateId, LPCWSTR PartNameID, LPRECT Rect);
void __fastcall InvalidateTab(int Index);
+ int __fastcall CloseButtonSize();
+ int __fastcall GetCrossPadding();
+ TRect __fastcall CloseButtonRect(int Index);
+ int __fastcall IndexOfCloseButtonAt(int X, int Y);
+ void __fastcall ItemContentsRect(int Item, TRect & Rect);
+ bool __fastcall HasItemImage(int Item);
+ void __fastcall ItemTextRect(int Item, TRect & Rect);
+ void __fastcall ItemTabRect(int Item, TRect & Rect);
+ bool __fastcall HasTabCloseButton(int Index);
+ void __fastcall SetHotCloseButton(int Index);
+ void __fastcall DrawCross(HDC DC, int Width, COLORREF Color, const TRect & Rect);
+ void __fastcall WMLButtonDown(TWMLButtonDown & Message);
int FOldTabIndex;
+ int FHotCloseButton;
+ TPageControlCloseButtonClick FOnCloseButtonClick;
};
//---------------------------------------------------------------------------
#endif
diff --git a/source/forms/CustomScpExplorer.cpp b/source/forms/CustomScpExplorer.cpp
index 0c44d1049..f3d438392 100644
--- a/source/forms/CustomScpExplorer.cpp
+++ b/source/forms/CustomScpExplorer.cpp
@@ -4672,10 +4672,10 @@ void __fastcall TCustomScpExplorerForm::DuplicateSession()
}
}
//---------------------------------------------------------------------------
-bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
+bool __fastcall TCustomScpExplorerForm::CanCloseQueue(TTerminalQueue * Queue)
{
- DebugAssert(FQueue != NULL);
- bool Result = FQueue->IsEmpty;
+ DebugAssert(Queue != NULL);
+ bool Result = Queue->IsEmpty;
if (!Result)
{
SetFocus();
@@ -4684,6 +4684,11 @@ bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
return Result;
}
//---------------------------------------------------------------------------
+bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
+{
+ return CanCloseQueue(FQueue);
+}
+//---------------------------------------------------------------------------
void __fastcall TCustomScpExplorerForm::CloseSession()
{
if (CanCloseQueue())
@@ -6256,7 +6261,7 @@ void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
for (int Index = 0; Index <= TerminalList->Count; Index++)
{
- TTabSheet * TabSheet;
+ TThemeTabSheet * TabSheet;
if (Index >= SessionsPageControl->PageCount)
{
TabSheet = new TThemeTabSheet(SessionsPageControl);
@@ -6264,10 +6269,11 @@ void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
}
else
{
- TabSheet = SessionsPageControl->Pages[Index];
+ TabSheet = DebugNotNull(dynamic_cast(SessionsPageControl->Pages[Index]));
}
- if (Index < TerminalList->Count)
+ bool IsSessionTab = (Index < TerminalList->Count);
+ if (IsSessionTab)
{
TTerminal * Terminal = dynamic_cast(TerminalList->Objects[Index]);
TabSheet->Tag = reinterpret_cast(Terminal);
@@ -6281,6 +6287,8 @@ void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
// We know that we are at the last page, sotherwise we could not call this (it assumes that new session tab is the last one)
UpdateNewSessionTab();
}
+
+ TabSheet->ShowCloseButton = IsSessionTab;
}
}
__finally
@@ -6325,7 +6333,7 @@ void __fastcall TCustomScpExplorerForm::UpdateSessionTab(TTabSheet * TabSheet)
TabSheet->ImageIndex = AddSessionColor(Color);
UnicodeString TabCaption = TTerminalManager::Instance()->GetTerminalTitle(ManagedTerminal, true);
- TabSheet->Caption = TabCaption;
+ TabSheet->Caption = SessionsPageControl->FormatCaptionWithCloseButton(TabCaption);
TThemeTabSheet * ThemeTabSheet = dynamic_cast(TabSheet);
if (DebugAlwaysTrue(ThemeTabSheet != NULL))
@@ -9843,3 +9851,29 @@ void __fastcall TCustomScpExplorerForm::ReloadDirectory(TOperationSide Side)
DirView(Side)->ReloadDirectory();
}
//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::SessionsPageControlCloseButtonClick(TPageControl * /*Sender*/, int Index)
+{
+ if (Index == SessionsPageControl->TabIndex)
+ {
+ CloseSession();
+ }
+ else
+ {
+ TTabSheet * TabSheet = SessionsPageControl->Pages[Index];
+ TTerminal * Terminal = GetSessionTabTerminal(TabSheet);
+ TTerminalManager * Manager = TTerminalManager::Instance();
+ if (!Terminal->Active)
+ {
+ Manager->FreeTerminal(Terminal);
+ }
+ else
+ {
+ TTerminalQueue * Queue = Manager->FindQueueForTerminal(Terminal);
+ if (CanCloseQueue(Queue))
+ {
+ Manager->FreeTerminal(Terminal);
+ }
+ }
+ }
+}
+//---------------------------------------------------------------------------
diff --git a/source/forms/CustomScpExplorer.dfm b/source/forms/CustomScpExplorer.dfm
index ffaaf9cc5..c7eaf2719 100644
--- a/source/forms/CustomScpExplorer.dfm
+++ b/source/forms/CustomScpExplorer.dfm
@@ -313,6 +313,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
OnDragDrop = SessionsPageControlDragDrop
OnDragOver = SessionsPageControlDragOver
OnMouseDown = SessionsPageControlMouseDown
+ OnCloseButtonClick = SessionsPageControlCloseButtonClick
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
end
diff --git a/source/forms/CustomScpExplorer.h b/source/forms/CustomScpExplorer.h
index 4618e2b6c..258f936a9 100644
--- a/source/forms/CustomScpExplorer.h
+++ b/source/forms/CustomScpExplorer.h
@@ -189,6 +189,7 @@ __published:
void __fastcall DirViewBusy(TObject *Sender, int Busy, bool & Allow);
void __fastcall SessionsPageControlContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled);
void __fastcall DockContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled);
+ void __fastcall SessionsPageControlCloseButtonClick(TPageControl *Sender, int Index);
private:
TTerminal * FTerminal;
@@ -450,6 +451,7 @@ protected:
void __fastcall QueueViewDeleteItem(int Index);
void __fastcall UserActionTimer(TObject * Sender);
void __fastcall UpdateQueueView();
+ bool __fastcall CanCloseQueue(TTerminalQueue * Queue);
bool __fastcall CanCloseQueue();
virtual bool __fastcall IsFileControl(TObject * Control, TOperationSide Side);
virtual void __fastcall ReloadLocalDirectory(const UnicodeString Directory = L"");
diff --git a/source/packages/tbx/TBXOfficeXPTheme.pas b/source/packages/tbx/TBXOfficeXPTheme.pas
index 8cab200bf..fe63b7873 100644
--- a/source/packages/tbx/TBXOfficeXPTheme.pas
+++ b/source/packages/tbx/TBXOfficeXPTheme.pas
@@ -86,6 +86,8 @@ type
procedure PaintStatusBar(Control: TWinControl; Canvas: TCanvas; R: TRect; Part: Integer); override;
end;
+function GetSelectedBodyColor: TColor;
+
implementation
uses
@@ -1227,7 +1229,7 @@ begin
BtnItemColors[bisDisabled, ipText] := DisabledText;
SetContrast(BtnItemColors[bisDisabled, ipText], ToolbarColor, 80);
BtnItemColors[bisDisabled, ipFrame] := clNone;
- BtnItemColors[bisSelected, ipBody] := Blend(clHighlight, Blend(clBtnFace, clWindow, 50), 10);
+ BtnItemColors[bisSelected, ipBody] := GetSelectedBodyColor;
SetContrast(BtnItemColors[bisSelected, ipBody], ToolbarColor, 5);
BtnItemColors[bisSelected, ipText] := BtnItemColors[bisNormal, ipText];
BtnItemColors[bisSelected, ipFrame] := clHighlight;
@@ -1409,4 +1411,9 @@ begin
if Message.WParam = TSC_VIEWCHANGE then SetupColorCache;
end;
+function GetSelectedBodyColor: TColor;
+begin
+ Result := Blend(clHighlight, Blend(clBtnFace, clWindow, 50), 10);
+end;
+
end.