ソースを参照

Extension option aliases "sessionlogpath" and "pausecheckbox" + Fixing extension option vs. control index mismatches + Removing dot from the "Select file for session log" dialog title

Source commit: 069a8a55bdad3365baeab2f0cb629031b61c0ec9
Martin Prikryl 9 年 前
コミット
a16cbe4ab2

+ 55 - 12
source/forms/Custom.cpp

@@ -861,6 +861,8 @@ private:
     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(
@@ -891,6 +893,7 @@ __fastcall TCustomCommandOptionsDialog::TCustomCommandOptionsDialog(
         Value = Option.Default;
       }
 
+      int Tag = (OptionIndex << 16) + ControlIndex;
       TControl * Control = NULL;
       std::vector<UnicodeString> Values;
       if (Option.Kind == TCustomCommandType::okUnknown)
@@ -947,7 +950,7 @@ __fastcall TCustomCommandOptionsDialog::TCustomCommandOptionsDialog(
         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 = ControlIndex;
+        Button->Tag = Tag;
         Button->Caption = LoadStr(EXTENSION_OPTIONS_BROWSE);
         Button->OnClick = BrowseButtonClick;
         ScaleButtonControl(Button);
@@ -993,7 +996,7 @@ __fastcall TCustomCommandOptionsDialog::TCustomCommandOptionsDialog(
 
       if (Control != NULL)
       {
-        Control->Tag = ControlIndex;
+        Control->Tag = Tag;
       }
       FControls.push_back(Control);
       FValues.push_back(Values);
@@ -1038,34 +1041,68 @@ void __fastcall TCustomCommandOptionsDialog::AddOptionComboBox(
   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(Label->Tag);
+  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 Index = Button->Tag;
-  THistoryComboBox * ComboBox = dynamic_cast<THistoryComboBox *>(FControls[Index]);
+  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 Caption = FCommand->GetOption(Index).Caption;
-  Caption = StripHotkey(Caption);
-  if (!Caption.IsEmpty() && (Caption[Caption.Length()] == L':'))
+
+  UnicodeString Title;
+  if (!Option.FileCaption.IsEmpty())
+  {
+    Title = Option.FileCaption;
+  }
+  else
   {
-    Caption.SetLength(Caption.Length() - 1);
+    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;
   }
-  OpenDialog->Title = FMTLOAD(EXTENSION_OPTIONS_BROWSE_TITLE, (Caption));
-  UnicodeString ExpandedValue = ExpandEnvironmentVariables(ComboBox->Text);
+  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())
   {
@@ -1073,6 +1110,12 @@ void __fastcall TCustomCommandOptionsDialog::BrowseButtonClick(TObject * Sender)
     {
       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;
+    }
   }
 }
 //---------------------------------------------------------------------------
@@ -1179,7 +1222,7 @@ UnicodeString __fastcall TCustomCommandOptionsDialog::GetComboBoxValue(
   }
   else
   {
-    Result = FValues[Control->Tag][ComboBox->ItemIndex];
+    Result = FValues[GetControlIndex(Control)][ComboBox->ItemIndex];
   }
   return Result;
 }

+ 1 - 1
source/forms/Preferences.cpp

@@ -2471,7 +2471,7 @@ void __fastcall TPreferencesDialog::AddExtension()
 
       // validate syntax
       CustomCommand.reset(new TCustomCommandType());
-      CustomCommand->LoadExtension(Lines.get());
+      CustomCommand->LoadExtension(Lines.get(), FileName);
     }
     catch (Exception & E)
     {

+ 1 - 1
source/forms/Preferences.dfm

@@ -293,7 +293,7 @@ object PreferencesDialog: TPreferencesDialog
             DefaultExt = 'log'
             Filter = 'Session log files (*.log)|*.log|All files (*.*)|*.*'
             DialogOptions = [ofHideReadOnly, ofPathMustExist]
-            DialogTitle = 'Select file for session log.'
+            DialogTitle = 'Select file for session log'
             ClickKey = 16397
             Anchors = [akLeft, akTop, akRight]
             TabOrder = 3

+ 4 - 0
source/resource/TextsWin.h

@@ -584,6 +584,10 @@
 #define EXTENSION_OPTIONS_CAPTION 1976
 #define EXTENSION_OPTIONS_BROWSE 1977
 #define EXTENSION_OPTIONS_BROWSE_TITLE 1978
+#define EXTENSION_PAUSE_CHECKBOX 1979
+#define EXTENSION_SESSIONLOG_FILE 1980
+#define EXTENSION_SESSIONLOG_CAPTION 1981
+#define EXTENSION_SESSIONLOG_FILTER 1982
 
 // 2xxx is reserved for TextsFileZilla.h
 

+ 4 - 0
source/resource/TextsWin1.rc

@@ -587,6 +587,10 @@ BEGIN
         EXTENSION_OPTIONS_CAPTION, "Options for extension '%s'"
         EXTENSION_OPTIONS_BROWSE, "Browse..."
         EXTENSION_OPTIONS_BROWSE_TITLE, "Select '%s'"
+        EXTENSION_PAUSE_CHECKBOX, "&Pause at the end"
+        EXTENSION_SESSIONLOG_FILE, "&Session log file:"
+        EXTENSION_SESSIONLOG_CAPTION, "Select file for session log"
+        EXTENSION_SESSIONLOG_FILTER, "Session log files (*.log)|*.log|All files (*.*)|*.*"
 
         WIN_VARIABLE_STRINGS, "WIN_VARIABLE"
         WINSCP_COPYRIGHT, "Copyright © 2000-2016 Martin Prikryl"

+ 54 - 6
source/windows/WinConfiguration.cpp

@@ -2727,16 +2727,20 @@ void __fastcall TCustomCommandType::LoadExtension(const UnicodeString & Path)
   std::unique_ptr<TStringList> Lines(new TStringList());
   FileName = Path;
   LoadScriptFromFile(Path, Lines.get());
-  LoadExtension(Lines.get());
+  LoadExtension(Lines.get(), Path);
   Command = ReplaceStr(Command, L"%EXTENSION_PATH%", Path);
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomCommandType::LoadExtension(TStrings * Lines)
+void __fastcall TCustomCommandType::LoadExtension(TStrings * Lines, const UnicodeString & PathForBaseName)
 {
   Params = ccLocal;
   bool AnythingFound = false;
   std::set<UnicodeString> OptionIds;
 
+  UnicodeString ExtensionBaseName = ExtractFileName(PathForBaseName);
+  // ExtractFileNameOnly trims the last extension only, we want to trim all extensions
+  ExtensionBaseName = CutToChar(ExtensionBaseName, L'.', true);
+
   for (int Index = 0; Index < Lines->Count; Index++)
   {
     UnicodeString Line = Lines->Strings[Index].Trim();
@@ -2875,7 +2879,7 @@ void __fastcall TCustomCommandType::LoadExtension(TStrings * Lines)
           else if (Key == L"option")
           {
             TOption Option;
-            if (!ParseOption(Value, Option) ||
+            if (!ParseOption(Value, Option, ExtensionBaseName) ||
                 (Option.IsControl && (OptionIds.find(Option.Id.LowerCase()) != OptionIds.end())))
             {
               throw Exception(MainInstructions(FMTLOAD(EXTENSION_DIRECTIVE_ERROR, (Value, Directive))));
@@ -2943,7 +2947,7 @@ void __fastcall TCustomCommandType::LoadExtension(TStrings * Lines)
   }
 }
 //---------------------------------------------------------------------------
-bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOption & Option)
+bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOption & Option, const UnicodeString & ExtensionBaseName)
 {
   UnicodeString Buf = Value;
   UnicodeString KindName;
@@ -2980,6 +2984,10 @@ bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOp
 
     if (Result)
     {
+      UnicodeString DefaultCaption;
+      UnicodeString DefaultDefault;
+      TOption::TParams DefaultParams;
+
       KindName = KindName.LowerCase();
       if (KindName == L"label")
       {
@@ -3011,6 +3019,17 @@ bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOp
         Option.Kind = okFile;
         Result = Option.IsControl;
       }
+      else if (KindName == L"sessionlogfile")
+      {
+        Option.Kind = okFile;
+        Result = Option.IsControl;
+        DefaultCaption = LoadStr(EXTENSION_SESSIONLOG_FILE);
+        Option.FileCaption = LoadStr(EXTENSION_SESSIONLOG_CAPTION);
+        Option.FileFilter = LoadStr(EXTENSION_SESSIONLOG_FILTER);
+        // Similar to TConfiguration::GetDefaultLogFileName
+        Option.FileInitial = L"%TEMP%\\" + ExtensionBaseName + L".log";
+        Option.FileExt = L"log";
+      }
       else if (KindName == L"dropdownlist")
       {
         Option.Kind = okDropDownList;
@@ -3026,6 +3045,14 @@ bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOp
         Option.Kind = okCheckBox;
         Result = Option.IsControl;
       }
+      else if (KindName == L"pausecheckbox")
+      {
+        Option.Kind = okCheckBox;
+        Result = Option.IsControl;
+        DefaultCaption = LoadStr(EXTENSION_PAUSE_CHECKBOX);
+        DefaultDefault = L"-pause";
+        DefaultParams.push_back(L"-pause");
+      }
       else
       {
         Option.Kind = okUnknown;
@@ -3034,7 +3061,14 @@ bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOp
       if ((Option.Kind != okUnknown) &&
           (Option.Kind != okSeparator))
       {
-        Result = CutTokenEx(Buf, Option.Caption);
+        Result =
+          CutTokenEx(Buf, Option.Caption);
+
+        if (!Result && !DefaultCaption.IsEmpty())
+        {
+          Option.Caption = DefaultCaption;
+          Result = true;
+        }
 
         if (Result && Option.IsControl)
         {
@@ -3046,6 +3080,15 @@ bool __fastcall TCustomCommandType::ParseOption(const UnicodeString & Value, TOp
               Option.Params.push_back(Param);
             }
           }
+          else
+          {
+            Option.Default = DefaultDefault;
+          }
+
+          if (Option.Params.size() == 0)
+          {
+            Option.Params = DefaultParams;
+          }
         }
       }
     }
@@ -3142,13 +3185,18 @@ bool __fastcall TCustomCommandType::TOption::GetIsControl() const
 //---------------------------------------------------------------------------
 bool TCustomCommandType::TOption::operator==(const TCustomCommandType::TOption & Other) const
 {
+  // needed by vector<> but probably never used
   return
     (Id == Other.Id) &&
     (Flags == Other.Flags) &&
     (Kind == Other.Kind) &&
     (Caption == Other.Caption) &&
     (Default == Other.Default) &&
-    (Params == Other.Params);
+    (Params == Other.Params) &&
+    (FileCaption == Other.FileCaption) &&
+    (FileFilter == Other.FileFilter) &&
+    (FileInitial == Other.FileInitial) &&
+    (FileExt == Other.FileExt);
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------

+ 6 - 2
source/windows/WinConfiguration.h

@@ -727,6 +727,10 @@ public:
     UnicodeString Default;
     typedef std::vector<UnicodeString> TParams;
     TParams Params;
+    UnicodeString FileCaption;
+    UnicodeString FileFilter;
+    UnicodeString FileInitial;
+    UnicodeString FileExt;
 
     bool operator==(const TOption & Other) const;
     __property bool IsControl = { read = GetIsControl };
@@ -739,7 +743,7 @@ public:
   bool __fastcall Equals(const TCustomCommandType * Other) const;
 
   void __fastcall LoadExtension(const UnicodeString & Path);
-  void __fastcall LoadExtension(TStrings * Lines);
+  void __fastcall LoadExtension(TStrings * Lines, const UnicodeString & PathForBaseName);
   static UnicodeString __fastcall GetExtensionId(const UnicodeString & Name);
 
   __property UnicodeString Name = { read = FName, write = FName };
@@ -759,7 +763,7 @@ public:
   UnicodeString __fastcall GetCommandWithExpandedOptions(TStrings * CustomCommandOptions) const;
 
 protected:
-  bool __fastcall ParseOption(const UnicodeString & Value, TOption & Option);
+  bool __fastcall ParseOption(const UnicodeString & Value, TOption & Option, const UnicodeString & ExtensionBaseName);
   int __fastcall GetOptionsCount() const;
   UnicodeString __fastcall GetOptionCommand(const TOption & Option, const UnicodeString & Value) const;