1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

Bug 1393: Close button on session tab + Non-active session can be closed, as well as disconnected sessions without a need to reconnect them

https://winscp.net/tracker/1393

Source commit: b63ce2363155fa969d91e07f294cca9f1c5c2a98
This commit is contained in:
Martin Prikryl
2018-09-12 14:02:51 +00:00
parent eb1c89d9aa
commit c48fb16840
8 changed files with 362 additions and 59 deletions

View File

@@ -49,8 +49,8 @@
<ILINK_Description>WinSCP components</ILINK_Description>
<ILINK_GenerateImportLibrary>true</ILINK_GenerateImportLibrary>
<ILINK_GenerateLibFile>true</ILINK_GenerateLibFile>
<ILINK_LibraryPath>components\;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<IncludePath>components\;core;packages\filemng;packages\dragndrop;packages\my;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
<ILINK_LibraryPath>components\;$(INTERM_PATH)\Win32\Debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<IncludePath>components\;core;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
<IntermediateOutputDir>$(INTERM_PATH)\$(Platform)\$(Config)</IntermediateOutputDir>
<LinkPackageStatics>rtl.lib;vcl.lib;vclx.lib</LinkPackageStatics>
<Multithreaded>true</Multithreaded>
@@ -116,6 +116,9 @@
<BuildOrder>20</BuildOrder>
<BuildOrder>1</BuildOrder>
</PackageImport>
<PackageImport Include="tbxp.bpi">
<BuildOrder>8</BuildOrder>
</PackageImport>
<PackageImport Include="vcl.bpi">
<BuildOrder>23</BuildOrder>
<BuildOrder>0</BuildOrder>

View File

@@ -38,7 +38,7 @@
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;$(DCC_Namespace)</DCC_Namespace>
<FinalOutputDir>$(INTERM_PATH)\$(Platform)\$(Config)</FinalOutputDir>
<ILINK_LibraryPath>$(BDS)\lib;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<IncludePath>components\;core;windows;packages\filemng;packages\dragndrop;packages\my;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
<IncludePath>components\;core;windows;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
<IntermediateOutputDir>$(INTERM_PATH)\$(Platform)\$(Config)</IntermediateOutputDir>
<Manifest_File>None</Manifest_File>
<Multithreaded>true</Multithreaded>

View File

@@ -5,6 +5,8 @@
#include <Common.h>
#include <vsstyle.h>
#include <memory>
#include <PasTools.hpp>
#include <TBXOfficeXPTheme.hpp>
#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<TThemePageControl *>(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<TThemePageControl *>(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<TThemeTabSheet *>(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<TThemeTabSheet *>(Pages[Index]);
return (ThemeTabSheet != NULL) ? ThemeTabSheet->ShowCloseButton : false;
}
//----------------------------------------------------------------------------------------------------------
void __fastcall TThemePageControl::DrawThemesXpTab(HDC DC, int Tab)
{
TThemeTabSheet * ThemeTabSheet = dynamic_cast<TThemeTabSheet *>(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<HPEN>(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<TCanvas> 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<HPEN>(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<int>(FN(BackColor))) + static_cast<int>(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<TMessage*>(Message);
if (M->Msg == CM_MOUSELEAVE)
{
SetHotCloseButton(-1);
TPageControl::Dispatch(Message);
}
else if (M->Msg == WM_LBUTTONDOWN)
{
WMLButtonDown(*reinterpret_cast<TWMLButtonDown *>(M));
}
else
{
TPageControl::Dispatch(Message);
}
}
//----------------------------------------------------------------------------------------------------------
#ifdef _DEBUG
void __fastcall TThemePageControl::RequestAlign()
{

View File

@@ -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

View File

@@ -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<TThemeTabSheet *>(SessionsPageControl->Pages[Index]));
}
if (Index < TerminalList->Count)
bool IsSessionTab = (Index < TerminalList->Count);
if (IsSessionTab)
{
TTerminal * Terminal = dynamic_cast<TTerminal *>(TerminalList->Objects[Index]);
TabSheet->Tag = reinterpret_cast<int>(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<TThemeTabSheet *>(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);
}
}
}
}
//---------------------------------------------------------------------------

View File

@@ -313,6 +313,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
OnDragDrop = SessionsPageControlDragDrop
OnDragOver = SessionsPageControlDragOver
OnMouseDown = SessionsPageControlMouseDown
OnCloseButtonClick = SessionsPageControlCloseButtonClick
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
end

View File

@@ -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"");

View File

@@ -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.