| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590 | //---------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include <Dialogs.hpp>//---------------------------------------------------------------------#include <Common.h>#include <CustomWinConfiguration.h>#include <WinInterface.h>#include <VCLCommon.h>#include <TextsWin.h>#include <HelpWin.h>#include <CoreMain.h>#include <PasTools.hpp>#include <ProgParams.h>#include <Tools.h>#include <GUITools.h>#include <HistoryComboBox.hpp>#include <Math.hpp>#include "Custom.h"//---------------------------------------------------------------------#pragma link "PasswordEdit"#ifndef NO_RESOURCES#pragma resource "*.dfm"#endif//---------------------------------------------------------------------__fastcall TCustomDialog::TCustomDialog(UnicodeString AHelpKeyword)  : TForm(GetFormOwner()){  UseSystemSettings(this);  FControlPadding = ScaleByTextHeight(this, 8);  FPos = ScaleByTextHeight(this, 8);  FPrePos = FPos;  FHorizontalMargin = ScaleByTextHeight(this, 8);  FIndent = FHorizontalMargin;  FGroupBox = NULL;  HelpKeyword = AHelpKeyword;  TBorderIcons BI = BorderIcons;  if (HelpKeyword.IsEmpty())  {    BI >> biHelp;    OKButton->Left = CancelButton->Left;    CancelButton->Left = HelpButton->Left;    HelpButton->Visible = false;  }  else  {    BI << biHelp;  }  BorderIcons = BI;}//---------------------------------------------------------------------bool __fastcall TCustomDialog::Execute(){  Changed();  return (ShowModal() == DefaultResult(this));}//---------------------------------------------------------------------void __fastcall TCustomDialog::DoChange(bool & /*CanSubmit*/){  // noop}//---------------------------------------------------------------------void __fastcall TCustomDialog::Changed(){  bool CanSubmit = true;  DoChange(CanSubmit);  EnableControl(OKButton, CanSubmit);}//---------------------------------------------------------------------void __fastcall TCustomDialog::Change(TObject * /*Sender*/){  Changed();}//---------------------------------------------------------------------------void __fastcall TCustomDialog::DoHelp(){  FormHelp(this);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::HelpButtonClick(TObject * /*Sender*/){  DoHelp();}//---------------------------------------------------------------------------void __fastcall TCustomDialog::DoShow(){  OKButton->TabOrder = FCount;  CancelButton->TabOrder = static_cast<short>(FCount + 1);  HelpButton->TabOrder = static_cast<short>(FCount + 2);  Changed();  TForm::DoShow();}//---------------------------------------------------------------------------void __fastcall TCustomDialog::DoValidate(){  // noop}//---------------------------------------------------------------------------bool __fastcall TCustomDialog::CloseQuery(){  if (ModalResult == DefaultResult(this))  {    DoValidate();  }  return TForm::CloseQuery();}//---------------------------------------------------------------------------void __fastcall TCustomDialog::RemoveCancelButton(){  CancelButton->Visible = false;  OKButton->Left = CancelButton->Left;  OKButton->Cancel = true;  DebugAssert(OKButton->Width == CancelButton->Width);  DebugAssert(OKButton->Top == CancelButton->Top);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddDialogButton(TButton * Button){  Button->Parent = this;  Button->Top = OKButton->Top;  Button->Left = FHorizontalMargin;  Button->Height = OKButton->Height;  AddWinControl(Button);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddImage(const UnicodeString & ImageName){  TImage * Image = new TImage(this);  Image->Name = L"Image";  Image->Parent = GetDefaultParent();  LoadDialogImage(Image, ImageName);  Image->SetBounds(FIndent, FPos + ScaleByTextHeight(this, 3), Image->Picture->Width, Image->Picture->Height);  FIndent += Image->Width + ScaleByTextHeight(this, 12);}//---------------------------------------------------------------------------int __fastcall TCustomDialog::GetMaxControlWidth(TControl * Control){  return GetDefaultParent()->ClientWidth - Control->Left - FHorizontalMargin;}//---------------------------------------------------------------------------TWinControl * __fastcall TCustomDialog::GetDefaultParent(){  return (FGroupBox != NULL) ? FGroupBox : static_cast<TWinControl *>(this);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AdjustHeight(TControl * Control){  FPos = Control->Top + Control->Height + FControlPadding;  int Delta = (FPos - FPrePos);  ClientHeight = ClientHeight + Delta;  if (FGroupBox != NULL)  {    FGroupBox->Height = FGroupBox->Height + Delta;  }  FPrePos = FPos;}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddWinControl(TWinControl * Control){  Control->TabOrder = FCount;  FCount++;}//---------------------------------------------------------------------------TCheckBox * __fastcall TCustomDialog::CreateAndAddCheckBox(const UnicodeString & Caption){  TCheckBox * CheckBox = new TCheckBox(this);  CheckBox->Caption = Caption;  AddButtonControl(CheckBox);  return CheckBox;}//---------------------------------------------------------------------------TLabel * __fastcall TCustomDialog::CreateLabel(UnicodeString Label){  TLabel * Result = new TLabel(this);  Result->Caption = Label;  return Result;}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddEditLikeControl(TWinControl * Edit, TLabel * Label, bool OneLine){  Edit->Parent = GetDefaultParent();  // this updates Height property to real value  Edit->HandleNeeded();  if (Label != NULL)  {    Label->Parent = GetDefaultParent();    Label->Left = FIndent;    if (OneLine)    {      DebugAssert(Edit->Height > Label->Height);      Label->Top = FPos + ((Edit->Height - Label->Height) / 2);    }    else    {      Label->Top = FPos;      FPos += Label->Height + ScaleByTextHeight(this, 4);    }  }  Edit->Top = FPos;  if (OneLine)  {    Edit->Left = GetDefaultParent()->ClientWidth - FHorizontalMargin - Edit->Width;  }  else  {    Edit->Left = FIndent;    Edit->Width = GetMaxControlWidth(Edit);  }  AdjustHeight(Edit);  if (Label != NULL)  {    if (Label->FocusControl == NULL)    {      Label->FocusControl = Edit;    }    else    {      DebugAssert(Label->FocusControl == Edit);    }  }  AddWinControl(Edit);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddEdit(TCustomEdit * Edit, TLabel * Label, bool OneLine){  AddEditLikeControl(Edit, Label, OneLine);  TEdit * PublicEdit = reinterpret_cast<TEdit *>(Edit);  if (PublicEdit->OnChange == NULL)  {    PublicEdit->OnChange = Change;  }}//---------------------------------------------------------------------------void __fastcall TCustomDialog::SetUpComboBox(TCustomCombo * Combo, TStrings * Items, bool OneLine){  if (Items != NULL)  {    Combo->Items = Items;  }  if (OneLine)  {    int Width = 0;    for (int Index = 0; Index < Combo->Items->Count; Index++)    {      Width = Max(Width, Combo->Canvas->TextWidth(Combo->Items->Strings[Index]));    }    Width += ScaleByTextHeight(Combo, 4 + 16 + 14);    Width = Max(Width, HelpButton->Width);    Combo->Width = Width;    Combo->Left = GetDefaultParent()->ClientWidth - FHorizontalMargin - Width;  }  TComboBox * PublicCombo = reinterpret_cast<TComboBox *>(Combo);  if (PublicCombo->OnChange == NULL)  {    PublicCombo->OnChange = Change;  }}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddComboBox(TCustomCombo * Combo, TLabel * Label, TStrings * Items, bool OneLine){  AddEditLikeControl(Combo, Label, OneLine);  SetUpComboBox(Combo, Items, OneLine);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddShortCutComboBox(TComboBox * Combo, TLabel * Label, const TShortCuts & ShortCuts){  AddEditLikeControl(Combo, Label, true);  InitializeShortCutCombo(Combo, ShortCuts);  SetUpComboBox(Combo, NULL, true);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::ScaleButtonControl(TButtonControl * Control){  // this updates Height property to real value  Control->HandleNeeded();  // buttons do not scale with text on their own  Control->Height = ScaleByTextHeight(Control, Control->Height);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddButtonControl(TButtonControl * Control){  Control->Parent = GetDefaultParent();  Control->Left = FIndent + ScaleByTextHeight(this, 6);  Control->Top = FPos;  Control->Width = GetMaxControlWidth(Control);  ScaleButtonControl(Control);  AdjustHeight(Control);  AddWinControl(Control);  TCheckBox * PublicControl = reinterpret_cast<TCheckBox *>(Control);  if (PublicControl->OnClick == NULL)  {    PublicControl->OnClick = Change;  }}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddText(TLabel * Label){  Label->Parent = GetDefaultParent();  Label->WordWrap = true;  Label->Left = FIndent;  Label->Width = GetMaxControlWidth(Label);  Label->Top = FPos;  Label->ShowAccelChar = false;  TRect TextRect;  SetRect(&TextRect, 0, 0, Label->Width, 0);  DrawText(Label->Canvas->Handle, Label->Caption.c_str(), Label->Caption.Length() + 1, &TextRect,    DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK | DT_NOPREFIX |    Label->DrawTextBiDiModeFlagsReadingOnly());  Label->Height = TextRect.Height();  AdjustHeight(Label);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddText(TStaticText * Label){  Label->Parent = GetDefaultParent();  Label->Left = FIndent;  Label->Width = GetMaxControlWidth(Label);  Label->Top = FPos;  Label->ShowAccelChar = false;  AdjustHeight(Label);  AddWinControl(Label);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::AddSeparator(){  TBevel * Bevel = new TBevel(this);  Bevel->Parent = GetDefaultParent();  Bevel->Left = FIndent;  Bevel->Top = FPos;  Bevel->Height = 2;  Bevel->Width = GetMaxControlWidth(Bevel);  AdjustHeight(Bevel);}//---------------------------------------------------------------------------void __fastcall TCustomDialog::StartGroup(const UnicodeString & Caption){  if (FGroupBox != NULL)  {    FIndent = FGroupBox->Left;    FPos = FGroupBox->Top + FGroupBox->Height + FControlPadding;    FPrePos = FPos;    FGroupBox = NULL;  }  TGroupBox * GroupBox = new TGroupBox(this);  GroupBox->Parent = this;  GroupBox->Caption = Caption;  GroupBox->Left = FIndent;  GroupBox->Top = FPos;  GroupBox->Height = ScaleByTextHeight(GroupBox, 20);  GroupBox->Width = GetMaxControlWidth(GroupBox);  AdjustHeight(GroupBox);  AddWinControl(GroupBox);  FPos = ScaleByTextHeight(this, 16);  FPrePos = FPos;  FIndent = FHorizontalMargin;  FGroupBox = GroupBox;}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TSaveSessionDialog : public TCustomDialog{public:  __fastcall TSaveSessionDialog(TComponent* AOwner);  void __fastcall Init(bool CanSavePassword, bool NotRecommendedSavingPassword,    TStrings * AdditionalFolders);  bool __fastcall Execute(UnicodeString & SessionName, bool & SavePassword,    bool & CreateShortcut, const UnicodeString & OriginalSessionName);protected:  virtual void __fastcall DoValidate();  virtual void __fastcall DoChange(bool & CanSubmit);private:  UnicodeString FOriginalSessionName;  TEdit * SessionNameEdit;  TComboBox * FolderCombo;  TCheckBox * SavePasswordCheck;  TCheckBox * CreateShortcutCheck;  UnicodeString FRootFolder;  UnicodeString __fastcall GetSessionName();};//---------------------------------------------------------------------------// Need to have an Owner argument for SafeFormCreate__fastcall TSaveSessionDialog::TSaveSessionDialog(TComponent* /*AOwner*/) :  TCustomDialog(HELP_SESSION_SAVE){}//---------------------------------------------------------------------------void __fastcall TSaveSessionDialog::Init(bool CanSavePassword,  bool NotRecommendedSavingPassword, TStrings * AdditionalFolders){  Caption = LoadStr(SAVE_SESSION_CAPTION);  SessionNameEdit = new TEdit(this);  AddEdit(SessionNameEdit, CreateLabel(LoadStr(SAVE_SESSION_PROMPT)));  FRootFolder = LoadStr(SAVE_SESSION_ROOT_FOLDER2);  std::unique_ptr<TStringList> Folders(new TStringList());  if (AdditionalFolders != NULL)  {    Folders->AddStrings(AdditionalFolders);  }  for (int Index = 0; Index < StoredSessions->Count; Index++)  {    TSessionData * Data = StoredSessions->Sessions[Index];    if (!Data->Special && !Data->IsWorkspace)    {      UnicodeString Folder = Data->FolderName;      if (!Folder.IsEmpty() && Folders->IndexOf(Folder) < 0)      {        Folders->Add(Folder);      }    }  }  DebugAssert(!Folders->CaseSensitive);  Folders->Sort();  FolderCombo = new TComboBox(this);  AddComboBox(FolderCombo, CreateLabel(LoadStr(SAVE_SESSION_FOLDER)));  FolderCombo->DropDownCount = Max(FolderCombo->DropDownCount, 16);  FolderCombo->Items->Add(FRootFolder);  FolderCombo->Items->AddStrings(Folders.get());  SavePasswordCheck = CreateAndAddCheckBox(    LoadStr(NotRecommendedSavingPassword ? SAVE_SESSION_PASSWORD :      (CustomWinConfiguration->UseMasterPassword ? SAVE_SESSION_PASSWORD_MASTER : SAVE_SESSION_PASSWORD_RECOMMENDED)));  CreateShortcutCheck = CreateAndAddCheckBox(LoadStr(SAVE_SITE_WORKSPACE_SHORTCUT));  EnableControl(SavePasswordCheck, CanSavePassword);}//---------------------------------------------------------------------------bool __fastcall TSaveSessionDialog::Execute(  UnicodeString & SessionName, bool & SavePassword, bool & CreateShortcut,  const UnicodeString & OriginalSessionName){  FOriginalSessionName = OriginalSessionName;  SessionNameEdit->Text = TSessionData::ExtractLocalName(SessionName);  UnicodeString Folder = TSessionData::ExtractFolderName(SessionName);  if (Folder.IsEmpty())  {    FolderCombo->Text = FRootFolder;  }  else  {    FolderCombo->Text = Folder;  }  SavePasswordCheck->Checked = SavePassword;  CreateShortcutCheck->Checked = CreateShortcut;  bool Result = TCustomDialog::Execute();  if (Result)  {    SessionName = GetSessionName();    SavePassword = SavePasswordCheck->Checked;    CreateShortcut = CreateShortcutCheck->Checked;  }  return Result;}//---------------------------------------------------------------------------UnicodeString __fastcall TSaveSessionDialog::GetSessionName(){  UnicodeString Folder;  if (FolderCombo->Text != FRootFolder)  {    Folder = FolderCombo->Text;  }  return TSessionData::ComposePath(Folder, SessionNameEdit->Text);}//---------------------------------------------------------------------------void __fastcall TSaveSessionDialog::DoValidate(){  TSessionData::ValidateName(SessionNameEdit->Text);  SessionNameValidate(GetSessionName(), FOriginalSessionName);  UnicodeString Folder = TSessionData::ExtractFolderName(GetSessionName());  if (!Folder.IsEmpty() && StoredSessions->IsWorkspace(Folder))  {    throw Exception(FMTLOAD(WORKSPACE_NOT_FOLDER, (Folder)));  }  if (SavePasswordCheck->Enabled && SavePasswordCheck->Checked &&      CustomWinConfiguration->UseMasterPassword)  {    CustomWinConfiguration->AskForMasterPasswordIfNotSet();  }  TCustomDialog::DoValidate();}//---------------------------------------------------------------------------void __fastcall TSaveSessionDialog::DoChange(bool & CanSubmit){  CanSubmit = !SessionNameEdit->Text.IsEmpty();  TCustomDialog::DoChange(CanSubmit);}//---------------------------------------------------------------------------TSessionData * __fastcall DoSaveSession(TSessionData * SessionData,  TSessionData * OriginalSession, bool ForceDialog,  TStrings * AdditionalFolders){  bool SavePassword = false;  bool * PSavePassword;  bool NotRecommendedSavingPassword =    !CustomWinConfiguration->UseMasterPassword &&    !SameText(SessionData->UserName, AnonymousUserName);  if (Configuration->DisablePasswordStoring ||      !SessionData->HasAnySessionPassword())  {    PSavePassword = NULL;  }  else  {    PSavePassword = &SavePassword;    SavePassword =      ((OriginalSession != NULL) && OriginalSession->HasAnySessionPassword()) ||      !NotRecommendedSavingPassword;  }  UnicodeString SessionName = SessionData->SessionName;  bool Result;  bool CreateShortcut = false;  if (!ForceDialog && ((PSavePassword == NULL) || SavePassword))  {    // This is probably here to ask before session is started saving.    // Otherwise we would ask implicitly, when saving passwords, but at that moment,    // part of the site is already saved and when the user cancel the prompt it's too late.    CustomWinConfiguration->AskForMasterPasswordIfNotSetAndNeededToPersistSessionData(SessionData);    Result = true;  }  else  {    // This can be a standalone dialog when used with save URL (from GetLoginData)    TSaveSessionDialog * Dialog = SafeFormCreate<TSaveSessionDialog>();    try    {      Dialog->Init((PSavePassword != NULL), NotRecommendedSavingPassword, AdditionalFolders);      Result = Dialog->Execute(SessionName, SavePassword, CreateShortcut, SessionData->Name);    }    __finally    {      delete Dialog;    }  }  TSessionData * NewSession = NULL;  if (Result)  {    if ((PSavePassword != NULL) && !SavePassword)    {      SessionData->ClearSessionPasswords();    }    NewSession =      StoredSessions->NewSession(SessionName, SessionData);    // modified only, explicit    StoredSessions->Save(false, true);    if (!SessionData->HostKey.IsEmpty())    {      SessionData->CacheHostKeyIfNotCached();    }    if (CreateShortcut)    {      TOperationVisualizer Visualizer;      UnicodeString AdditionalParams =        TProgramParams::FormatSwitch(DESKTOP_SWITCH) + L" " +        TProgramParams::FormatSwitch(UPLOAD_IF_ANY_SWITCH);      CreateDesktopSessionShortCut(SessionName, L"", AdditionalParams, -1, SITE_ICON);    }  }  return NewSession;}//---------------------------------------------------------------------------void __fastcall SessionNameValidate(const UnicodeString & Text,  const UnicodeString & OriginalName){  TSessionData::ValidatePath(Text);  DebugAssert(StoredSessions);  TSessionData * Data = (TSessionData *)StoredSessions->FindByName(Text);  if (Data && Data->Special)  {    MessageDialog(FMTLOAD(CANNOT_OVERWRITE_SPECIAL_SESSION, (Text)),      qtError, qaOK, HELP_NONE);    Abort();  }  else if ((Data != NULL) && !Data->IsSameName(OriginalName) &&    MessageDialog(MainInstructions(FMTLOAD(CONFIRM_OVERWRITE_SESSION, (Text))),      qtConfirmation, qaYes | qaNo, HELP_SESSION_SAVE_OVERWRITE) != qaYes)  {    Abort();  }}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TSaveWorkspaceDialog : public TCustomDialog{public:  __fastcall TSaveWorkspaceDialog(bool CanSavePasswords,    bool NotRecommendedSavingPasswords);  bool __fastcall Execute(    UnicodeString & WorkspaceName, bool & SavePasswords, bool & CreateShortcut,    bool & EnableAutoSave);protected:  virtual void __fastcall DoValidate();  virtual void __fastcall DoChange(bool & CanSubmit);private:  TComboBox * WorkspaceNameCombo;  TCheckBox * SavePasswordsCheck;  TCheckBox * CreateShortcutCheck;  TCheckBox * EnableAutoSaveCheck;};//---------------------------------------------------------------------------__fastcall TSaveWorkspaceDialog::TSaveWorkspaceDialog(    bool CanSavePasswords, bool NotRecommendedSavingPasswords) :  TCustomDialog(HELP_WORKSPACE_SAVE){  Caption = LoadStr(SAVE_WORKSPACE_CAPTION);  WorkspaceNameCombo = new TComboBox(this);  WorkspaceNameCombo->AutoComplete = false;  AddComboBox(WorkspaceNameCombo, CreateLabel(LoadStr(SAVE_WORKSPACE_PROMPT)));  WorkspaceNameCombo->DropDownCount = Max(WorkspaceNameCombo->DropDownCount, 16);  std::unique_ptr<TStrings> Workspaces(StoredSessions->GetWorkspaces());  WorkspaceNameCombo->Items->AddStrings(Workspaces.get());  SavePasswordsCheck = CreateAndAddCheckBox(    LoadStr(NotRecommendedSavingPasswords ? SAVE_WORKSPACE_PASSWORDS :      (CustomWinConfiguration->UseMasterPassword ?        SAVE_WORKSPACE_PASSWORDS_MASTER : SAVE_WORKSPACE_PASSWORDS_RECOMMENDED)));  EnableControl(SavePasswordsCheck, CanSavePasswords);  CreateShortcutCheck = CreateAndAddCheckBox(LoadStr(SAVE_SITE_WORKSPACE_SHORTCUT));  EnableAutoSaveCheck = CreateAndAddCheckBox(LoadStr(SAVE_WORKSPACE_AUTO));}//---------------------------------------------------------------------------bool __fastcall TSaveWorkspaceDialog::Execute(  UnicodeString & WorkspaceName, bool & SavePasswords, bool & CreateShortcut,  bool & EnableAutoSave){  WorkspaceNameCombo->Text = WorkspaceName;  SavePasswordsCheck->Checked = SavePasswords;  CreateShortcutCheck->Checked = CreateShortcut;  EnableAutoSaveCheck->Checked = EnableAutoSave;  bool Result = TCustomDialog::Execute();  if (Result)  {    WorkspaceName = WorkspaceNameCombo->Text;    SavePasswords = SavePasswordsCheck->Checked;    CreateShortcut = CreateShortcutCheck->Checked;    EnableAutoSave = EnableAutoSaveCheck->Checked;  }  return Result;}//---------------------------------------------------------------------------void __fastcall TSaveWorkspaceDialog::DoValidate(){  TSessionData::ValidateName(WorkspaceNameCombo->Text);  if (StoredSessions->IsFolder(WorkspaceNameCombo->Text))  {    throw Exception(FMTLOAD(FOLDER_NOT_WORKSPACE, (WorkspaceNameCombo->Text)));  }  if (SavePasswordsCheck->Enabled && SavePasswordsCheck->Checked &&      CustomWinConfiguration->UseMasterPassword)  {    CustomWinConfiguration->AskForMasterPasswordIfNotSet();  }  TCustomDialog::DoValidate();}//---------------------------------------------------------------------------void __fastcall TSaveWorkspaceDialog::DoChange(bool & CanSubmit){  CanSubmit = !WorkspaceNameCombo->Text.IsEmpty();  TCustomDialog::DoChange(CanSubmit);}//---------------------------------------------------------------------------bool __fastcall DoSaveWorkspaceDialog(UnicodeString & WorkspaceName,  bool * SavePasswords, bool NotRecommendedSavingPasswords,  bool & CreateShortcut, bool & EnableAutoSave){  std::unique_ptr<TSaveWorkspaceDialog> Dialog(    new TSaveWorkspaceDialog((SavePasswords != NULL), NotRecommendedSavingPasswords));  bool Dummy = false;  if (SavePasswords == NULL)  {    SavePasswords = &Dummy;  }  return    Dialog->Execute(      WorkspaceName, *SavePasswords, CreateShortcut, EnableAutoSave);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TShortCutDialog : public TCustomDialog{public:  __fastcall TShortCutDialog(const TShortCuts & ShortCuts, UnicodeString HelpKeyword);  bool __fastcall Execute(TShortCut & ShortCut);private:  TComboBox * ShortCutCombo;};//---------------------------------------------------------------------------__fastcall TShortCutDialog::TShortCutDialog(const TShortCuts & ShortCuts, UnicodeString HelpKeyword) :  TCustomDialog(HelpKeyword){  Caption = LoadStr(SHORTCUT_CAPTION);  ShortCutCombo = new TComboBox(this);  AddShortCutComboBox(ShortCutCombo, CreateLabel(LoadStr(SHORTCUT_LABEL)), ShortCuts);}//---------------------------------------------------------------------------bool __fastcall TShortCutDialog::Execute(TShortCut & ShortCut){  SetShortCutCombo(ShortCutCombo, ShortCut);  bool Result = TCustomDialog::Execute();  if (Result)  {    ShortCut = GetShortCutCombo(ShortCutCombo);  }  return Result;}//---------------------------------------------------------------------------bool __fastcall DoShortCutDialog(TShortCut & ShortCut,  const TShortCuts & ShortCuts, UnicodeString HelpKeyword){  bool Result;  TShortCutDialog * Dialog = new TShortCutDialog(ShortCuts, HelpKeyword);  try  {    Result = Dialog->Execute(ShortCut);  }  __finally  {    delete Dialog;  }  return Result;}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TRemoteMoveDialog : public TCustomDialog{public:  __fastcall TRemoteMoveDialog(bool Multi);  bool __fastcall Execute(UnicodeString & Target, UnicodeString & FileMask);protected:  DYNAMIC void __fastcall DoShow();  virtual void __fastcall DoValidate();  UnicodeString __fastcall GetFileMask();private:  THistoryComboBox * Combo;  bool FMulti;};//---------------------------------------------------------------------------__fastcall TRemoteMoveDialog::TRemoteMoveDialog(bool Multi) :  TCustomDialog(HELP_REMOTE_MOVE){  Caption = LoadStr(REMOTE_MOVE_TITLE);  // The same as TRemoteTransferDialog  ClientWidth = ScaleByTextHeight(this, 420);  FMulti = Multi;  AddImage(L"Move To");  Combo = new THistoryComboBox(this);  Combo->AutoComplete = false;  AddComboBox(Combo, CreateLabel(LoadStr(REMOTE_TRANSFER_PROMPT2)));}//---------------------------------------------------------------------------bool __fastcall TRemoteMoveDialog::Execute(UnicodeString & Target, UnicodeString & FileMask){  Combo->Items = CustomWinConfiguration->History[L"RemoteTarget"];  Combo->Text = UnixIncludeTrailingBackslash(Target) + FileMask;  bool Result = TCustomDialog::Execute();  if (Result)  {    Target = UnixExtractFilePath(Combo->Text);    FileMask = GetFileMask();    Combo->SaveToHistory();    CustomWinConfiguration->History[L"RemoteTarget"] = Combo->Items;  }  return Result;}//---------------------------------------------------------------------------UnicodeString __fastcall TRemoteMoveDialog::GetFileMask(){  return UnixExtractFileName(Combo->Text);}//---------------------------------------------------------------------------void __fastcall TRemoteMoveDialog::DoShow(){  TCustomDialog::DoShow();  InstallPathWordBreakProc(Combo);}//---------------------------------------------------------------------------void __fastcall TRemoteMoveDialog::DoValidate(){  if (!IsFileNameMask(GetFileMask()) && FMulti)  {    UnicodeString Message =      FormatMultiFilesToOneConfirmation(Combo->Text, true);    if (MessageDialog(Message, qtConfirmation, qaOK | qaCancel, HELP_NONE) == qaCancel)    {      Abort();    }  }  TCustomDialog::DoValidate();}//---------------------------------------------------------------------------bool __fastcall DoRemoteMoveDialog(bool Multi, UnicodeString & Target, UnicodeString & FileMask){  std::unique_ptr<TRemoteMoveDialog> Dialog(new TRemoteMoveDialog(Multi));  return Dialog->Execute(Target, FileMask);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TCustomCommandOptionsDialog : public TCustomDialog{public:  __fastcall TCustomCommandOptionsDialog(    const TCustomCommandType * Command, TStrings * CustomCommandOptions, unsigned int Flags,    TCustomCommand * CustomCommandForOptions, const UnicodeString & Site, const TShortCuts * ShortCuts);  bool __fastcall Execute(TShortCut * ShortCut);protected:  virtual void __fastcall DoHelp();  DYNAMIC void __fastcall DoShow();private:  const TCustomCommandType * FCommand;  TStrings * FCustomCommandOptions;  std::vector<TControl *> FControls;  std::vector<std::vector<UnicodeString> > FValues;  unsigned int FFlags;  UnicodeString FSite;  TComboBox * FShortCutCombo;  UnicodeString __fastcall HistoryKey(const TCustomCommandType::TOption & Option);  THistoryComboBox * __fastcall CreateHistoryComboBox(const TCustomCommandType::TOption & Option, const UnicodeString & Value);  void __fastcall BrowseButtonClick(TObject * Sender);  void __fastcall LinkLabelClick(TObject * Sender);  UnicodeString __fastcall SaveHistoryComboBoxValue(TControl * Control, const TCustomCommandType::TOption & Option);  void __fastcall AddOptionComboBox(    TComboBox * ComboBox, const UnicodeString & Value, const TCustomCommandType::TOption & Option,    std::vector<UnicodeString> & Values);  UnicodeString __fastcall GetComboBoxValue(TControl * Control, const UnicodeString & Default);  int __fastcall GetOptionIndex(TControl * Control);  int __fastcall GetControlIndex(TControl * Control);};//---------------------------------------------------------------------------__fastcall TCustomCommandOptionsDialog::TCustomCommandOptionsDialog(    const TCustomCommandType * Command, TStrings * CustomCommandOptions,    unsigned int Flags, TCustomCommand * CustomCommandForOptions,    const UnicodeString & Site, const TShortCuts * ShortCuts) :  TCustomDialog(HELP_EXTENSION_OPTIONS){  FCommand = Command;  FFlags = Flags;  FCustomCommandOptions = CustomCommandOptions;  FSite = Site;  Caption = StripEllipsis(StripHotkey(FCommand->Name));  Width = ScaleByTextHeight(this, 400);  bool HasGroups = false;  int ControlIndex = 0;  for (int OptionIndex = 0; OptionIndex < FCommand->OptionsCount; OptionIndex++)  {    const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);    if ((Option.Flags & FFlags) != 0)    {      UnicodeString OptionKey = FCommand->GetOptionKey(Option, FSite);      UnicodeString Value;      if ((CustomCommandForOptions != NULL) &&          Option.HasPatterns(CustomCommandForOptions))      {        Value = CustomCommandForOptions->Complete(Option.Default, true);      }      else      {        if (FCustomCommandOptions->IndexOfName(OptionKey) >= 0)        {          Value = FCustomCommandOptions->Values[OptionKey];        }        else        {          Value = Option.Default;        }      }      int Tag = (OptionIndex << 16) + ControlIndex;      TControl * Control = NULL;      std::vector<UnicodeString> Values;      if (Option.Kind == TCustomCommandType::okUnknown)      {        Control = NULL;      }      else if (Option.Kind == TCustomCommandType::okLabel)      {        TLabel * Label = CreateLabel(Option.Caption);        AddText(Label);        Control = Label;      }      else if (Option.Kind == TCustomCommandType::okLink)      {        TStaticText * Label = new TStaticText(this);        Label->Caption = Option.Caption;        if (IsHttpOrHttpsUrl(Label->Caption))        {          Label->Caption = SecureUrl(Label->Caption);          LinkLabel(Label);          Label->TabStop = true;        }        else if (!Option.Default.IsEmpty() && IsHttpOrHttpsUrl(Option.Default))        {          Label->OnClick = LinkLabelClick;          LinkLabel(Label);          Label->TabStop = true;        }        else        {          // keep it plain text, as we have no URL        }        AddText(Label);        Control = Label;      }      else if (Option.Kind == TCustomCommandType::okGroup)      {        StartGroup(Option.Caption);        HasGroups = true;      }      else if (Option.Kind == TCustomCommandType::okSeparator)      {        AddSeparator();      }      else if (Option.Kind == TCustomCommandType::okTextBox)      {        Control = CreateHistoryComboBox(Option, Value);      }      else if (Option.Kind == TCustomCommandType::okFile)      {        THistoryComboBox * ComboBox = CreateHistoryComboBox(Option, Value);        TButton * Button = new TButton(this);        Button->Parent = GetDefaultParent();        Button->Width = HelpButton->Width;        Button->Left = GetDefaultParent()->ClientWidth - Button->Width - HorizontalMargin;        ComboBox->Width = Button->Left - ComboBox->Left - ScaleByTextHeight(this, 6);        Button->Top = ComboBox->Top - ScaleByTextHeight(this, 2);        Button->Tag = Tag;        Button->Caption = LoadStr(EXTENSION_OPTIONS_BROWSE);        Button->OnClick = BrowseButtonClick;        ScaleButtonControl(Button);        AddWinControl(Button);        Control = ComboBox;      }      else if (Option.Kind == TCustomCommandType::okDropDownList)      {        TComboBox * ComboBox = new TComboBox(this);        ComboBox->Style = csDropDownList;        AddOptionComboBox(ComboBox, Value, Option, Values);        Control = ComboBox;      }      else if (Option.Kind == TCustomCommandType::okComboBox)      {        TComboBox * ComboBox = new TComboBox(this);        ComboBox->Style = csDropDown;        AddOptionComboBox(ComboBox, Value, Option, Values);        if (ComboBox->ItemIndex < 0)        {          ComboBox->Text = Value;        }        Control = ComboBox;      }      else if (Option.Kind == TCustomCommandType::okCheckBox)      {        TCheckBox * CheckBox = CreateAndAddCheckBox(Option.Caption);        CheckBox->Checked =          (Option.Params.size() >= 1) &&          (Value == Option.Params[0]);        Control = CheckBox;      }      else      {        DebugFail();      }      if (Control != NULL)      {        Control->Tag = Tag;      }      FControls.push_back(Control);      FValues.push_back(Values);      ControlIndex++;      DebugAssert(static_cast<int>(FControls.size()) == ControlIndex);    }  }  if (ShortCuts != NULL)  {    if (HasGroups)    {      StartGroup(LoadStr(EXTENSION_GENERAL_GROUP));    }    else if (ControlIndex > 0)    {      AddSeparator();    }    FShortCutCombo = new TComboBox(this);    AddShortCutComboBox(FShortCutCombo, CreateLabel(LoadStr(EXTENSION_SHORTCUT)), *ShortCuts);  }}//---------------------------------------------------------------------------void __fastcall TCustomCommandOptionsDialog::AddOptionComboBox(  TComboBox * ComboBox, const UnicodeString & Value, const TCustomCommandType::TOption & Option, std::vector<UnicodeString> & Values){  std::unique_ptr<TStringList> Items(new TStringList());  int ItemIndex = -1;  TCustomCommandType::TOption::TParams::const_iterator ParamI = Option.Params.begin();  while (ParamI != Option.Params.end())  {    UnicodeString Item = (*ParamI);    int P = Item.Pos(L"=");    UnicodeString ParamValue;    if (P > 0)    {      ParamValue = Item.SubString(1, P - 1);      Item.Delete(1, P);    }    else    {      ParamValue = Item;    }    Item = WinConfiguration->ExtensionStringTranslation(FCommand->Id, Item);    Items->Add(Item);    if (Value == ParamValue)    {      ItemIndex = Items->Count - 1;    }    Values.push_back(ParamValue);    ParamI++;  }  AddComboBox(ComboBox, CreateLabel(Option.Caption), Items.get(), true);  ComboBox->ItemIndex = ItemIndex;}//---------------------------------------------------------------------------int __fastcall TCustomCommandOptionsDialog::GetOptionIndex(TControl * Control){  return (Control->Tag >> 16);}//---------------------------------------------------------------------------int __fastcall TCustomCommandOptionsDialog::GetControlIndex(TControl * Control){  return (Control->Tag & 0xFFFF);}//---------------------------------------------------------------------------void __fastcall TCustomCommandOptionsDialog::LinkLabelClick(TObject * Sender){  TStaticText * Label = DebugNotNull(dynamic_cast<TStaticText *>(Sender));  const TCustomCommandType::TOption & Option = FCommand->GetOption(GetOptionIndex(Label));  OpenBrowser(SecureUrl(Option.Default));}//---------------------------------------------------------------------------void __fastcall TCustomCommandOptionsDialog::BrowseButtonClick(TObject * Sender){  TButton * Button = DebugNotNull(dynamic_cast<TButton *>(Sender));  int OptionIndex = GetOptionIndex(Button);  const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);  int ControlIndex = GetControlIndex(Button);  THistoryComboBox * ComboBox = dynamic_cast<THistoryComboBox *>(FControls[ControlIndex]);  std::unique_ptr<TOpenDialog> OpenDialog(new TOpenDialog(Application));  UnicodeString Title;  if (!Option.FileCaption.IsEmpty())  {    Title = Option.FileCaption;  }  else  {    UnicodeString Caption = Option.Caption;    Caption = StripHotkey(Caption);    if (!Caption.IsEmpty() && (Caption[Caption.Length()] == L':'))    {      Caption.SetLength(Caption.Length() - 1);    }    Title = FMTLOAD(EXTENSION_OPTIONS_BROWSE_TITLE, (Caption));  }  OpenDialog->Title = Title;  UnicodeString Value;  if (ComboBox->Text.IsEmpty())  {    Value = Option.FileInitial;  }  else  {    Value = ComboBox->Text;  }  UnicodeString ExpandedValue = ExpandEnvironmentVariables(Value);  OpenDialog->FileName = ExpandedValue;  UnicodeString InitialDir = ExtractFilePath(ExpandedValue);  if (!InitialDir.IsEmpty())  {    OpenDialog->InitialDir = InitialDir;  }  OpenDialog->Filter = Option.FileFilter;  OpenDialog->DefaultExt = Option.FileExt;  if (OpenDialog->Execute())  {    if (OpenDialog->FileName != ExpandedValue)    {      ComboBox->Text = OpenDialog->FileName;    }    // If user just confirms the initial value, persist it    else if (ComboBox->Text.IsEmpty())    {      DebugAssert(Option.FileInitial == Value);      ComboBox->Text = Value;    }  }}//---------------------------------------------------------------------------THistoryComboBox * __fastcall TCustomCommandOptionsDialog::CreateHistoryComboBox(  const TCustomCommandType::TOption & Option, const UnicodeString & Value){  THistoryComboBox * ComboBox = new THistoryComboBox(this);  ComboBox->AutoComplete = false;  AddComboBox(ComboBox, CreateLabel(Option.Caption));  ComboBox->Items = CustomWinConfiguration->History[HistoryKey(Option)];  ComboBox->Text = Value;  return ComboBox;}//---------------------------------------------------------------------------UnicodeString __fastcall TCustomCommandOptionsDialog::HistoryKey(const TCustomCommandType::TOption & Option){  UnicodeString Result = FCommand->GetOptionKey(Option, FSite);  Result = CustomWinConfiguration->GetValidHistoryKey(Result);  return L"CustomCommandOption_" + Result;}//---------------------------------------------------------------------------bool __fastcall TCustomCommandOptionsDialog::Execute(TShortCut * ShortCut){  if (ShortCut != NULL)  {    SetShortCutCombo(FShortCutCombo, *ShortCut);  }  bool Result = TCustomDialog::Execute();  if (Result)  {    int ControlIndex = 0;    for (int OptionIndex = 0; OptionIndex < FCommand->OptionsCount; OptionIndex++)    {      const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);      if ((Option.Flags & FFlags) != 0)      {        if ((Option.Kind != TCustomCommandType::okUnknown) &&            Option.IsControl)        {          UnicodeString OptionKey = FCommand->GetOptionKey(Option, FSite);          TControl * Control = FControls[ControlIndex];          UnicodeString Value;          if (Option.Kind == TCustomCommandType::okTextBox)          {            Value = SaveHistoryComboBoxValue(Control, Option);          }          else if (Option.Kind == TCustomCommandType::okFile)          {            Value = SaveHistoryComboBoxValue(Control, Option);          }          else if (Option.Kind == TCustomCommandType::okDropDownList)          {            Value = GetComboBoxValue(Control, Option.Default);          }          else if (Option.Kind == TCustomCommandType::okComboBox)          {            TComboBox * ComboBox = DebugNotNull(dynamic_cast<TComboBox *>(Control));            Value = GetComboBoxValue(Control, ComboBox->Text);          }          else if (Option.Kind == TCustomCommandType::okCheckBox)          {            TCheckBox * CheckBox = DebugNotNull(dynamic_cast<TCheckBox *>(Control));            int Index = (CheckBox->Checked ? 0 : 1);            Value = (Index < static_cast<int>(Option.Params.size())) ? Option.Params[Index] : UnicodeString();          }          else          {            DebugFail();          }          // The default value setter deletes the "name" when the value is empty.          // It would cause us to fall back to the default value, but we want to remember the empty value.          if (Value.IsEmpty())          {            int Index = FCustomCommandOptions->IndexOfName(OptionKey);            if (Index < 0)            {              Index = FCustomCommandOptions->Add(L"");            }            UnicodeString Line = OptionKey + FCustomCommandOptions->NameValueSeparator;            FCustomCommandOptions->Strings[Index] = Line;          }          else          {            FCustomCommandOptions->Values[OptionKey] = Value;          }        }        ControlIndex++;      }    }    if (ShortCut != NULL)    {      *ShortCut = GetShortCutCombo(FShortCutCombo);    }  }  return Result;}//---------------------------------------------------------------------------UnicodeString __fastcall TCustomCommandOptionsDialog::GetComboBoxValue(  TControl * Control, const UnicodeString & Default){  TComboBox * ComboBox = DebugNotNull(dynamic_cast<TComboBox *>(Control));  UnicodeString Result;  if (ComboBox->ItemIndex < 0)  {    Result = Default;  }  else  {    Result = FValues[GetControlIndex(Control)][ComboBox->ItemIndex];  }  return Result;}//---------------------------------------------------------------------------UnicodeString __fastcall TCustomCommandOptionsDialog::SaveHistoryComboBoxValue(  TControl * Control, const TCustomCommandType::TOption & Option){  THistoryComboBox * ComboBox = DebugNotNull(dynamic_cast<THistoryComboBox *>(Control));  ComboBox->SaveToHistory();  CustomWinConfiguration->History[HistoryKey(Option)] = ComboBox->Items;  return ComboBox->Text;}//---------------------------------------------------------------------------void __fastcall TCustomCommandOptionsDialog::DoHelp(){  UnicodeString HelpPage;  if (!FCommand->OptionsPage.IsEmpty())  {    HelpPage = FCommand->OptionsPage;  }  else  {    HelpPage = FCommand->HomePage;  }  if (!HelpPage.IsEmpty())  {    OpenBrowser(HelpPage);  }  else  {    TCustomDialog::DoHelp();  }}//---------------------------------------------------------------------------void __fastcall TCustomCommandOptionsDialog::DoShow(){  TCustomDialog::DoShow();  int ControlIndex = 0;  for (int OptionIndex = 0; OptionIndex < FCommand->OptionsCount; OptionIndex++)  {    const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);    if ((Option.Flags & FFlags) != 0)    {      if (Option.Kind == TCustomCommandType::okFile)      {        TControl * Control = FControls[ControlIndex];        InstallPathWordBreakProc(DebugNotNull(dynamic_cast<TWinControl *>(Control)));      }      ControlIndex++;    }  }}//---------------------------------------------------------------------------bool __fastcall DoCustomCommandOptionsDialog(  const TCustomCommandType * Command, TStrings * CustomCommandOptions, TShortCut * ShortCut,  unsigned int Flags, TCustomCommand * CustomCommandForOptions,  const UnicodeString & Site, const TShortCuts * ShortCuts){  std::unique_ptr<TCustomCommandOptionsDialog> Dialog(    new TCustomCommandOptionsDialog(Command, CustomCommandOptions, Flags, CustomCommandForOptions, Site, ShortCuts));  return Dialog->Execute(ShortCut);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TUsageStatisticsDialog : public TCustomDialog{public:  __fastcall TUsageStatisticsDialog();protected:  virtual void __fastcall DoChange(bool & CanSubmit);private:  TEdit * FilterEdit;  TMemo * UsageMemo;  TButton * ClipboardButton;  void __fastcall ClipboardButtonClick(TObject * Sender);};//---------------------------------------------------------------------------__fastcall TUsageStatisticsDialog::TUsageStatisticsDialog() :  TCustomDialog(HELP_USAGE){  Caption = LoadStr(USAGE_CAPTION);  Width = ScaleByTextHeight(this, 400);  TLabel * Label = new TLabel(this);  // UnformatMessage is called, because previously, ** markup was used and translations may still contain that  Label->Caption = UnformatMessage(LoadStr(USAGE_DATA2));  AddText(Label);  FilterEdit = new TEdit(this);  FilterEdit->Width = ScaleByTextHeight(this, 250);  TLabel * FilterLabel = new TLabel(this);  FilterLabel->Caption = LoadStr(USAGE_FILTER);  AddEdit(FilterEdit, FilterLabel, true);  UsageMemo = new TMemo(this);  UsageMemo->Height = ScaleByTextHeight(this, 300);  UsageMemo->ScrollBars = ssVertical;  AddEdit(UsageMemo, NULL);  ReadOnlyControl(UsageMemo);  ClipboardButton = new TButton(this);  ClipboardButton->Caption = LoadStr(USAGE_COPY);  ClipboardButton->Width = ScaleByTextHeight(this, 121);  ClipboardButton->OnClick = ClipboardButtonClick;  AddDialogButton(ClipboardButton);  RemoveCancelButton();}//---------------------------------------------------------------------------void __fastcall TUsageStatisticsDialog::ClipboardButtonClick(TObject * /*Sender*/){  TInstantOperationVisualizer Visualizer;  CopyToClipboard(UsageMemo->Lines);}//---------------------------------------------------------------------------void __fastcall TUsageStatisticsDialog::DoChange(bool & CanSubmit){  TCustomDialog::DoChange(CanSubmit);  UnicodeString Text = Configuration->Usage->Serialize(L"\n", FilterEdit->Text);  bool NoUsage = Text.IsEmpty();  ClipboardButton->Enabled = !NoUsage;  if (NoUsage)  {    Text = LoadStr(USAGE_DATA_NONE2);  }  UsageMemo->Lines->Text = Text;}//---------------------------------------------------------------------------void __fastcall DoUsageStatisticsDialog(){  std::unique_ptr<TUsageStatisticsDialog> Dialog(new TUsageStatisticsDialog());  Dialog->Execute();}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TSiteRawDialog : public TCustomDialog{public:  __fastcall TSiteRawDialog();  bool __fastcall Execute(TSessionData * Data);private:  TMemo * SettingsMemo;  void __fastcall AddButtonClick(TObject * Sender);  void __fastcall SettingsMemoKeyDown(TObject * Sender, WORD & Key, TShiftState Shift);  void DeleteNames(TStrings * Names, TStrings * Options);};//---------------------------------------------------------------------------__fastcall TSiteRawDialog::TSiteRawDialog() :  TCustomDialog(HELP_SITE_RAW){  Caption = LoadStr(SITE_RAW_CAPTION);  Width = ScaleByTextHeight(this, 400);  SettingsMemo = new TMemo(this);  SettingsMemo->Height = ScaleByTextHeight(this, 300);  SettingsMemo->OnKeyDown = SettingsMemoKeyDown;  AddEdit(SettingsMemo, NULL);  TButton * AddButton = new TButton(this);  AddButton->Caption = LoadStr(SITE_RAW_ADD);  AddButton->Width = OKButton->Width;  AddButton->OnClick = AddButtonClick;  AddDialogButton(AddButton);}//---------------------------------------------------------------------------bool __fastcall TSiteRawDialog::Execute(TSessionData * Data){  std::unique_ptr<TSessionData> FactoryDefaults(new TSessionData(L""));  std::unique_ptr<TSessionData> RawData(new TSessionData(L""));  RawData->Assign(Data);  // SFTP-only is not reflected by the protocol prefix, we have to use rawsettings for that  if (RawData->FSProtocol != fsSFTPonly)  {    RawData->FSProtocol = FactoryDefaults->FSProtocol;  }  RawData->HostName = FactoryDefaults->HostName;  RawData->PortNumber = FactoryDefaults->PortNumber;  RawData->UserName = FactoryDefaults->UserName;  RawData->Password = FactoryDefaults->Password;  RawData->Ftps = FactoryDefaults->Ftps;  std::unique_ptr<TStrings> Options(RawData->SaveToOptions(FactoryDefaults.get(), false));  SettingsMemo->Lines = Options.get();  bool Result = TCustomDialog::Execute();  if (Result)  {    std::unique_ptr<TSessionData> BackupData(new TSessionData(L""));    BackupData->Assign(Data);    Data->DefaultSettings();    Data->FSProtocol = BackupData->FSProtocol;    Data->HostName = BackupData->HostName;    Data->PortNumber = BackupData->PortNumber;    Data->UserName = BackupData->UserName;    Data->Password = BackupData->Password;    Data->Ftps = BackupData->Ftps;    Data->ApplyRawSettings(SettingsMemo->Lines);  }  return Result;}//---------------------------------------------------------------------------void __fastcall TSiteRawDialog::SettingsMemoKeyDown(TObject * Sender, WORD & Key, TShiftState Shift){  MemoKeyDown(Sender, Key, Shift);}//---------------------------------------------------------------------------void __fastcall TSiteRawDialog::AddButtonClick(TObject *){  std::unique_ptr<TSessionData> FactoryDefaults(new TSessionData(L""));  std::unique_ptr<TSessionData> BasicData(new TSessionData(L""));  BasicData->FSProtocol = TFSProtocol(FactoryDefaults->FSProtocol + 1);  UnicodeString RandomAppendix(L"_");  BasicData->HostName = FactoryDefaults->HostName + RandomAppendix;  BasicData->Ftps = TFtps(FactoryDefaults->Ftps + 1);  BasicData->PortNumber = DefaultPort(BasicData->FSProtocol, BasicData->Ftps) + 1;  BasicData->UserName = FactoryDefaults->UserName + RandomAppendix;  BasicData->Password = FactoryDefaults->Password + RandomAppendix;  std::unique_ptr<TStrings> BasicOptions(BasicData->SaveToOptions(FactoryDefaults.get(), false));  std::unique_ptr<TStrings> AllOptions(FactoryDefaults->SaveToOptions(NULL, false));  std::unique_ptr<TStrings> Names(CreateSortedStringList());  for (int Index = 0; Index < AllOptions->Count; Index++)  {    Names->Add(AllOptions->Names[Index]);  }  DeleteNames(Names.get(), BasicOptions.get());  DeleteNames(Names.get(), SettingsMemo->Lines);  std::unique_ptr<TCustomDialog> AddDialog(new TCustomDialog(HelpKeyword));  AddDialog->Caption = LoadStr(SITE_RAW_ADD_CAPTION);  TComboBox * AddComboBox = new TComboBox(AddDialog.get());  AddComboBox->Style = csDropDownList;  AddComboBox->DropDownCount = Max(AddComboBox->DropDownCount, 16);  AddDialog->AddComboBox(AddComboBox, CreateLabel(LoadStr(SITE_RAW_ADD_LABEL)), Names.get(), true);  AddComboBox->ItemIndex = 0;  if (AddDialog->Execute())  {    UnicodeString Name = AddComboBox->Items->Strings[AddComboBox->ItemIndex];    UnicodeString Value = AllOptions->Values[Name];    UnicodeString NameAndSeparator = Name + SettingsMemo->Lines->NameValueSeparator;    int Start = (SettingsMemo->Lines->Text + NameAndSeparator).Length();    SettingsMemo->Lines->Add(NameAndSeparator + Value);    SettingsMemo->SetFocus();    SettingsMemo->SelStart = Start;    SettingsMemo->SelLength = Value.Length();  }}//---------------------------------------------------------------------------void TSiteRawDialog::DeleteNames(TStrings * Names, TStrings * Options){  for (int Index = 0; Index < Options->Count; Index++)  {    UnicodeString Name = Options->Names[Index];    if (!Name.IsEmpty())    {      int I = Names->IndexOf(Name);      if (I >= 0)      {        Names->Delete(I);      }    }  }}//---------------------------------------------------------------------------void __fastcall DoSiteRawDialog(TSessionData * Data){  std::unique_ptr<TSiteRawDialog> Dialog(new TSiteRawDialog());  Dialog->Execute(Data);}
 |