Preferences.cpp 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <StrUtils.hpp>
  5. #include <Common.h>
  6. #include <math.h>
  7. #include "Preferences.h"
  8. #include "Custom.h"
  9. #include <CoreMain.h>
  10. #include <Terminal.h>
  11. #include <Bookmarks.h>
  12. #include "VCLCommon.h"
  13. #include "GUITools.h"
  14. #include "Tools.h"
  15. #include "TextsCore.h"
  16. #include "TextsWin.h"
  17. #include "HelpWin.h"
  18. #include "WinInterface.h"
  19. #include "WinConfiguration.h"
  20. #include "Setup.h"
  21. #include "ProgParams.h"
  22. #include "Http.h"
  23. //---------------------------------------------------------------------
  24. #pragma link "CopyParams"
  25. #pragma link "UpDownEdit"
  26. #pragma link "ComboEdit"
  27. #ifndef NO_RESOURCES
  28. #pragma link "HistoryComboBox"
  29. #pragma resource "*.dfm"
  30. #endif
  31. //---------------------------------------------------------------------
  32. bool __fastcall DoPreferencesDialog(TPreferencesMode APreferencesMode,
  33. TPreferencesDialogData * DialogData)
  34. {
  35. bool Result;
  36. TPreferencesDialog * PreferencesDialog =
  37. new TPreferencesDialog(GetFormOwner(), APreferencesMode);
  38. try
  39. {
  40. Result = PreferencesDialog->Execute(DialogData);
  41. if (Result)
  42. {
  43. Configuration->SaveExplicit();
  44. }
  45. }
  46. __finally
  47. {
  48. delete PreferencesDialog;
  49. }
  50. return Result;
  51. }
  52. //---------------------------------------------------------------------
  53. __fastcall TPreferencesDialog::TPreferencesDialog(
  54. TComponent* AOwner, TPreferencesMode PreferencesMode)
  55. : TForm(AOwner)
  56. {
  57. SetCorrectFormParent(this);
  58. FNoUpdate = 0;
  59. FPreferencesMode = PreferencesMode;
  60. FEditorFont.reset(new TFont());
  61. FEditorFont->Color = clWindowText;
  62. FPanelFont.reset(new TFont());
  63. FPanelFont->Color = clWindowText;
  64. // currently useless
  65. FAfterFilenameEditDialog = false;
  66. FCustomCommandList = new TCustomCommandList();
  67. FCustomCommandChanging = false;
  68. FExtensionList = new TCustomCommandList();
  69. FListViewDragDest = -1;
  70. FCopyParamList = new TCopyParamList();
  71. FEditorList = new TEditorList();
  72. FAutomaticUpdatesPossible = IsInstalled();
  73. FCustomCommandsHintItem = NULL;
  74. FAddedExtensions.reset(CreateSortedStringList());
  75. FCustomCommandOptions.reset(new TStringList());
  76. UseSystemSettings(this);
  77. FCustomCommandsScrollOnDragOver = new TListViewScrollOnDragOver(CustomCommandsView, true);
  78. FixListColumnWidth(CustomCommandsView, -1);
  79. FCopyParamScrollOnDragOver = new TListViewScrollOnDragOver(CopyParamListView, true);
  80. FixListColumnWidth(CopyParamListView, -1);
  81. FEditorScrollOnDragOver = new TListViewScrollOnDragOver(EditorListView3, true);
  82. FixListColumnWidth(EditorListView3, -1);
  83. FOrigCustomCommandsViewWindowProc = CustomCommandsView->WindowProc;
  84. CustomCommandsView->WindowProc = CustomCommandsViewWindowProc;
  85. ComboAutoSwitchInitialize(UpdatesBetaVersionsCombo);
  86. EnableControl(UpdatesBetaVersionsCombo, !WinConfiguration->IsBeta);
  87. EnableControl(UpdatesBetaVersionsLabel, UpdatesBetaVersionsCombo->Enabled);
  88. HintLabel(LogFileNameHintText, LoadStr(LOG_FILE_HINT3));
  89. HintLabel(ActionsLogFileNameHintText, LoadStr(LOG_FILE_HINT3));
  90. HintLabel(ShellIconsText2);
  91. HotTrackLabel(CopyParamLabel);
  92. HintLabel(PuttyPathHintText, LoadStr(PUTTY_PATTERNS_HINT2));
  93. EditorEncodingCombo->Items->Add(DefaultEncodingName());
  94. EditorEncodingCombo->Items->Add(LoadStr(UTF8_NAME));
  95. std::unique_ptr<TStrings> Workspaces(StoredSessions->GetWorkspaces());
  96. AutoWorkspaceCombo->Items->AddStrings(Workspaces.get());
  97. AutoSaveWorkspacePasswordsCheck->Caption = LoadStr(SAVE_WORKSPACE_PASSWORDS);
  98. PuttyRegistryStorageKeyEdit->Items->Add(OriginalPuttyRegistryStorageKey);
  99. PuttyRegistryStorageKeyEdit->Items->Add(KittyRegistryStorageKey);
  100. MenuButton(RegisterAsUrlHandlersButton);
  101. MenuButton(EditorFontColorButton);
  102. MenuButton(EditorBackgroundColorButton);
  103. LoadDialogImage(CommanderInterfacePicture, L"Commander");
  104. LoadDialogImage(ExplorerInterfacePicture, L"Explorer");
  105. LinkLabel(UpdatesLink);
  106. LinkAppLabel(BackgroundConfirmationsLink);
  107. HideComponentsPanel(this);
  108. }
  109. //---------------------------------------------------------------------------
  110. __fastcall TPreferencesDialog::~TPreferencesDialog()
  111. {
  112. SAFE_DESTROY(FEditorScrollOnDragOver);
  113. SAFE_DESTROY(FCopyParamScrollOnDragOver);
  114. SAFE_DESTROY(FCustomCommandsScrollOnDragOver);
  115. delete FCustomCommandList;
  116. FCustomCommandList = NULL;
  117. delete FExtensionList;
  118. FExtensionList = NULL;
  119. delete FCopyParamList;
  120. FCopyParamList = NULL;
  121. delete FEditorList;
  122. FEditorList = NULL;
  123. }
  124. //---------------------------------------------------------------------
  125. bool __fastcall TPreferencesDialog::Execute(TPreferencesDialogData * DialogData)
  126. {
  127. PuttyPathEdit->Items = CustomWinConfiguration->History[L"PuttyPath"];
  128. FDialogData = DialogData;
  129. bool Result = (ShowModal() == DefaultResult(this));
  130. if (Result)
  131. {
  132. SaveConfiguration();
  133. CustomWinConfiguration->History[L"PuttyPath"] = PuttyPathEdit->Items;
  134. }
  135. else
  136. {
  137. for (int Index = 0; Index < FAddedExtensions->Count; Index++)
  138. {
  139. DeleteFile(ApiPath(FAddedExtensions->Strings[Index]));
  140. }
  141. }
  142. return Result;
  143. }
  144. //---------------------------------------------------------------------------
  145. void __fastcall TPreferencesDialog::LoadLanguages()
  146. {
  147. if (!FLanguagesLoaded)
  148. {
  149. LanguagesView->Items->Clear();
  150. LCID Locale = GUIConfiguration->Locale;
  151. if (Locale == NULL)
  152. {
  153. DebugAssert(GUIConfiguration->AppliedLocale == WinConfiguration->DefaultLocale);
  154. Locale = WinConfiguration->DefaultLocale;
  155. }
  156. TObjectList * Locales = GUIConfiguration->Locales;
  157. for (int Index = 0; Index < Locales->Count; Index++)
  158. {
  159. TListItem * Item = LanguagesView->Items->Add();
  160. TLocaleInfo * LocaleInfo = DebugNotNull(dynamic_cast<TLocaleInfo *>(Locales->Items[Index]));
  161. Item->Caption = LocaleInfo->Name;
  162. Item->Data = LocaleInfo;
  163. Item->Focused = (LocaleInfo->Locale == Locale);
  164. Item->Selected = Item->Focused;
  165. }
  166. FLanguagesLoaded = false;
  167. }
  168. }
  169. //---------------------------------------------------------------------------
  170. TTabSheet * __fastcall TPreferencesDialog::FindPageForTreeNode(TTreeNode * Node)
  171. {
  172. for (int pi = 0; pi < PageControl->PageCount; pi++)
  173. {
  174. TTabSheet * Sheet = PageControl->Pages[pi];
  175. if (Sheet->Tag == Node->SelectedIndex)
  176. {
  177. return Sheet;
  178. }
  179. }
  180. DebugFail();
  181. return NULL;
  182. }
  183. //---------------------------------------------------------------------------
  184. void __fastcall TPreferencesDialog::PrepareNavigationTree(TTreeView * Tree)
  185. {
  186. Tree->FullExpand();
  187. int i = 0;
  188. while (i < Tree->Items->Count)
  189. {
  190. TTreeNode * Node = Tree->Items->Item[i];
  191. TTabSheet * Sheet = FindPageForTreeNode(Node);
  192. if (DebugNotNull(Sheet))
  193. {
  194. if (Sheet->Enabled)
  195. {
  196. // gets called multiple times occasionally
  197. // (e.g. when called from upload dialog invoked by /upload)
  198. if (!Sheet->Caption.IsEmpty())
  199. {
  200. Node->Text = Sheet->Caption;
  201. Sheet->Caption = L"";
  202. }
  203. }
  204. else
  205. {
  206. Tree->Items->Delete(Node);
  207. i--;
  208. }
  209. }
  210. i++;
  211. }
  212. }
  213. //---------------------------------------------------------------------------
  214. void __fastcall TPreferencesDialog::LoadConfiguration()
  215. {
  216. FNoUpdate++;
  217. try
  218. {
  219. #define BOOLPROP(PROP) PROP ## Check->Checked = WinConfiguration->PROP;
  220. BOOLPROP(DefaultDirIsHome);
  221. BOOLPROP(PreservePanelState);
  222. BOOLPROP(DeleteToRecycleBin);
  223. BOOLPROP(DDTransferConfirmation);
  224. BOOLPROP(DDWarnLackOfTempSpace);
  225. BOOLPROP(ShowHiddenFiles);
  226. BOOLPROP(RenameWholeName);
  227. BOOLPROP(ShowInaccesibleDirectories);
  228. BOOLPROP(CopyOnDoubleClickConfirmation);
  229. BOOLPROP(ConfirmTransferring);
  230. BOOLPROP(ConfirmOverwriting);
  231. BOOLPROP(ConfirmResume);
  232. BOOLPROP(ConfirmDeleting);
  233. BOOLPROP(ConfirmRecycling);
  234. BOOLPROP(ConfirmExitOnCompletion);
  235. BOOLPROP(ConfirmCommandSession);
  236. BOOLPROP(ContinueOnError);
  237. BOOLPROP(DDAllowMoveInit);
  238. BOOLPROP(BeepOnFinish);
  239. BOOLPROP(TemporaryDirectoryAppendSession);
  240. BOOLPROP(TemporaryDirectoryAppendPath);
  241. BOOLPROP(TemporaryDirectoryDeterministic);
  242. BOOLPROP(TemporaryDirectoryCleanup);
  243. BOOLPROP(ConfirmTemporaryDirectoryCleanup);
  244. BOOLPROP(FullRowSelect);
  245. ConfirmClosingSessionCheck2->Checked = WinConfiguration->ConfirmClosingSession;
  246. if (WinConfiguration->DDTransferConfirmation == asAuto)
  247. {
  248. // allow grayed state only initially,
  249. // once the off state is confirmed, never allow returning
  250. // to the undefined state
  251. DDTransferConfirmationCheck->AllowGrayed = true;
  252. }
  253. CheckBoxAutoSwitchLoad(DDTransferConfirmationCheck, WinConfiguration->DDTransferConfirmation);
  254. BeepOnFinishAfterEdit->AsInteger =
  255. int(static_cast<double>(GUIConfiguration->BeepOnFinishAfter) * SecsPerDay);
  256. BOOLPROP(BalloonNotifications);
  257. DDExtEnabledButton->Checked = WinConfiguration->DDExtEnabled;
  258. DDExtDisabledButton->Checked = !DDExtEnabledButton->Checked;
  259. DDWarnOnMoveCheck->Checked = !WinConfiguration->DDAllowMove;
  260. if (WinConfiguration->DDTemporaryDirectory.IsEmpty())
  261. {
  262. DDSystemTemporaryDirectoryButton->Checked = true;
  263. DDTemporaryDirectoryEdit->Text = SystemTemporaryDirectory();
  264. }
  265. else
  266. {
  267. DDCustomTemporaryDirectoryButton->Checked = true;
  268. DDTemporaryDirectoryEdit->Text = WinConfiguration->DDTemporaryDirectory;
  269. }
  270. // Commander
  271. if (WinConfiguration->ScpCommander.NortonLikeMode == nlOff)
  272. {
  273. NortonLikeModeCombo->ItemIndex = 2;
  274. }
  275. else if (WinConfiguration->ScpCommander.NortonLikeMode == nlKeyboard)
  276. {
  277. NortonLikeModeCombo->ItemIndex = 1;
  278. }
  279. else
  280. {
  281. NortonLikeModeCombo->ItemIndex = 0;
  282. }
  283. SwappedPanelsCheck->Checked =
  284. WinConfiguration->ScpCommander.SwappedPanels;
  285. TreeOnLeftCheck->Checked = WinConfiguration->ScpCommander.TreeOnLeft;
  286. ExplorerKeyboardShortcutsCombo->ItemIndex =
  287. WinConfiguration->ScpCommander.ExplorerKeyboardShortcuts ? 1 : 0;
  288. BOOLPROP(UseLocationProfiles);
  289. CompareByTimeCheck->Checked = WinConfiguration->ScpCommander.CompareByTime;
  290. CompareBySizeCheck->Checked = WinConfiguration->ScpCommander.CompareBySize;
  291. // Local panel
  292. PreserveLocalDirectoryCheck->Checked =
  293. WinConfiguration->ScpCommander.PreserveLocalDirectory;
  294. SystemContextMenuCheck->Checked =
  295. WinConfiguration->ScpCommander.SystemContextMenu;
  296. // Explorer
  297. ShowFullAddressCheck->Checked =
  298. WinConfiguration->ScpExplorer.ShowFullAddress;
  299. // select none when stNul
  300. RegistryStorageButton->Checked = (Configuration->Storage == stRegistry);
  301. IniFileStorageButton2->Checked = (Configuration->Storage == stIniFile);
  302. RandomSeedFileEdit->Text = Configuration->RandomSeedFile;
  303. // editor
  304. EditorWordWrapCheck->Checked = WinConfiguration->Editor.WordWrap;
  305. EditorTabSizeEdit->AsInteger = WinConfiguration->Editor.TabSize;
  306. if (WinConfiguration->Editor.Encoding == CP_UTF8)
  307. {
  308. EditorEncodingCombo->ItemIndex = 1;
  309. }
  310. else
  311. {
  312. EditorEncodingCombo->ItemIndex = 0;
  313. }
  314. TWinConfiguration::RestoreFont(WinConfiguration->Editor.Font, FEditorFont.get());
  315. FEditorFont->Color = WinConfiguration->Editor.FontColor;
  316. FEditorBackgroundColor = WinConfiguration->Editor.BackgroundColor;
  317. (*FEditorList) = *WinConfiguration->EditorList;
  318. UpdateEditorListView();
  319. FCopyParams = GUIConfiguration->DefaultCopyParam;
  320. ResumeOnButton->Checked = GUIConfiguration->DefaultCopyParam.ResumeSupport == rsOn;
  321. ResumeSmartButton->Checked = GUIConfiguration->DefaultCopyParam.ResumeSupport == rsSmart;
  322. ResumeOffButton->Checked = GUIConfiguration->DefaultCopyParam.ResumeSupport == rsOff;
  323. ResumeThresholdEdit->Value = GUIConfiguration->DefaultCopyParam.ResumeThreshold / 1024;
  324. SessionReopenAutoCheck->Checked = (Configuration->SessionReopenAuto > 0);
  325. SessionReopenAutoEdit->Value = (Configuration->SessionReopenAuto > 0 ?
  326. (Configuration->SessionReopenAuto / MSecsPerSec) : 5);
  327. SessionReopenAutoIdleCheck->Checked = (GUIConfiguration->SessionReopenAutoIdle > 0);
  328. SessionReopenAutoIdleEdit->Value = (GUIConfiguration->SessionReopenAutoIdle > 0 ?
  329. (GUIConfiguration->SessionReopenAutoIdle / MSecsPerSec) : 5);
  330. SessionReopenAutoStallCheck->Checked = (Configuration->SessionReopenAutoStall > 0);
  331. SessionReopenAutoStallEdit->Value = (Configuration->SessionReopenAutoStall > 0 ?
  332. (Configuration->SessionReopenAutoStall / MSecsPerSec) : SecsPerMin);
  333. SessionReopenTimeoutEdit->Value = (Configuration->SessionReopenTimeout / MSecsPerSec);
  334. GeneralSheet->Enabled = WinConfiguration->ExpertMode;
  335. ExplorerSheet->Enabled = WinConfiguration->ExpertMode;
  336. CommanderSheet->Enabled = WinConfiguration->ExpertMode;
  337. EditorSheet->Enabled = WinConfiguration->ExpertMode && !WinConfiguration->DisableOpenEdit;
  338. StorageGroup->Visible = WinConfiguration->ExpertMode;
  339. RandomSeedFileLabel->Visible = WinConfiguration->ExpertMode;
  340. RandomSeedFileEdit->Visible = WinConfiguration->ExpertMode;
  341. FCustomCommandList->Assign(WinConfiguration->CustomCommandList);
  342. FExtensionList->Assign(WinConfiguration->ExtensionList);
  343. UpdateCustomCommandsView();
  344. FCustomCommandOptions->Assign(WinConfiguration->CustomCommandOptions);
  345. PuttyPathEdit->Text = GUIConfiguration->PuttyPath;
  346. PuttyPasswordCheck2->Checked = GUIConfiguration->PuttyPassword;
  347. AutoOpenInPuttyCheck->Checked = WinConfiguration->AutoOpenInPutty;
  348. TelnetForFtpInPuttyCheck->Checked = WinConfiguration->TelnetForFtpInPutty;
  349. SelectPuttyRegistryStorageKey(GUIConfiguration->PuttyRegistryStorageKey);
  350. // Queue
  351. QueueTransferLimitEdit->AsInteger = GUIConfiguration->QueueTransfersLimit;
  352. EnableQueueByDefaultCheck->Checked = WinConfiguration->EnableQueueByDefault;
  353. QueueAutoPopupCheck->Checked = GUIConfiguration->QueueAutoPopup;
  354. QueueCheck->Checked = GUIConfiguration->DefaultCopyParam.Queue;
  355. QueueIndividuallyCheck->Checked = GUIConfiguration->DefaultCopyParam.QueueIndividually;
  356. QueueNoConfirmationCheck->Checked = GUIConfiguration->DefaultCopyParam.QueueNoConfirmation;
  357. if (!GUIConfiguration->QueueKeepDoneItems)
  358. {
  359. QueueKeepDoneItemsForCombo->ItemIndex = 0;
  360. }
  361. else if (GUIConfiguration->QueueKeepDoneItemsFor < 0)
  362. {
  363. QueueKeepDoneItemsForCombo->ItemIndex = 5;
  364. }
  365. else if (GUIConfiguration->QueueKeepDoneItemsFor <= 15)
  366. {
  367. QueueKeepDoneItemsForCombo->ItemIndex = 1;
  368. }
  369. else if (GUIConfiguration->QueueKeepDoneItemsFor <= 60)
  370. {
  371. QueueKeepDoneItemsForCombo->ItemIndex = 2;
  372. }
  373. else if (GUIConfiguration->QueueKeepDoneItemsFor <= 15 * 60)
  374. {
  375. QueueKeepDoneItemsForCombo->ItemIndex = 3;
  376. }
  377. else if (GUIConfiguration->QueueKeepDoneItemsFor <= 60 * 60)
  378. {
  379. QueueKeepDoneItemsForCombo->ItemIndex = 4;
  380. }
  381. if (WinConfiguration->QueueView.Show == qvShow)
  382. {
  383. QueueViewShowButton->Checked = true;
  384. }
  385. else if (WinConfiguration->QueueView.Show == qvHideWhenEmpty)
  386. {
  387. QueueViewHideWhenEmptyButton->Checked = true;
  388. }
  389. else
  390. {
  391. QueueViewHideButton->Checked = true;
  392. }
  393. // window
  394. AutoSaveWorkspaceCheck->Checked = WinConfiguration->AutoSaveWorkspace;
  395. AutoWorkspaceCombo->Text =
  396. DefaultStr(WinConfiguration->AutoWorkspace,
  397. // It will rarely happen that LastWorkspace is set, while AutoWorkspace not.
  398. // It can happen only when user saved workspace before opening the Preferences
  399. // dialog for the first time
  400. DefaultStr(WinConfiguration->LastWorkspace, LoadStr(NEW_WORKSPACE)));
  401. AutoSaveWorkspacePasswordsCheck->Checked = WinConfiguration->AutoSaveWorkspacePasswords;
  402. if (WinConfiguration->PathInCaption == picFull)
  403. {
  404. PathInCaptionFullButton->Checked = true;
  405. }
  406. else if (WinConfiguration->PathInCaption == picShort)
  407. {
  408. PathInCaptionShortButton->Checked = true;
  409. }
  410. else
  411. {
  412. PathInCaptionNoneButton->Checked = true;
  413. }
  414. BOOLPROP(MinimizeToTray);
  415. BOOLPROP(ExternalSessionInExistingInstance);
  416. BOOLPROP(KeepOpenWhenNoSession);
  417. BOOLPROP(ShowTips);
  418. // panels
  419. DoubleClickActionCombo->ItemIndex = WinConfiguration->DoubleClickAction;
  420. BOOLPROP(AutoReadDirectoryAfterOp);
  421. BOOLPROP(RefreshRemotePanel);
  422. RefreshRemotePanelIntervalEdit->Value =
  423. int(static_cast<double>(WinConfiguration->RefreshRemotePanelInterval) * SecsPerDay);
  424. switch (WinConfiguration->FormatSizeBytes)
  425. {
  426. case fbNone:
  427. FormatSizeBytesCombo->ItemIndex = 0;
  428. break;
  429. case fbKilobytes:
  430. FormatSizeBytesCombo->ItemIndex = 1;
  431. break;
  432. case fbShort:
  433. FormatSizeBytesCombo->ItemIndex = 2;
  434. break;
  435. default:
  436. DebugFail();
  437. }
  438. bool CustomPanelFont = !WinConfiguration->PanelFont.FontName.IsEmpty();
  439. PanelFontCheck->Checked = CustomPanelFont;
  440. if (CustomPanelFont)
  441. {
  442. TWinConfiguration::RestoreFont(WinConfiguration->PanelFont, FPanelFont.get());
  443. }
  444. else
  445. {
  446. FPanelFont->Assign(WinConfiguration->SystemIconFont);
  447. }
  448. // updates
  449. TUpdatesConfiguration Updates = WinConfiguration->Updates;
  450. if (int(Updates.Period) <= 0)
  451. {
  452. UpdatesPeriodCombo->ItemIndex = 0;
  453. }
  454. else if (int(Updates.Period) <= 1)
  455. {
  456. UpdatesPeriodCombo->ItemIndex = 1;
  457. }
  458. else if (int(Updates.Period) <= 7)
  459. {
  460. UpdatesPeriodCombo->ItemIndex = 2;
  461. }
  462. else
  463. {
  464. UpdatesPeriodCombo->ItemIndex = 3;
  465. }
  466. UpdatesShowOnStartup->Checked = Updates.ShowOnStartup;
  467. UpdatesAuthenticationEmailEdit->Text = Updates.AuthenticationEmail;
  468. FVerifiedUpdatesAuthenticationEmail = UpdatesAuthenticationEmailEdit->Text;
  469. CollectUsageCheck->Checked = Configuration->CollectUsage;
  470. ComboAutoSwitchLoad(UpdatesBetaVersionsCombo, Updates.BetaVersions);
  471. switch (Updates.ConnectionType)
  472. {
  473. case ctDirect:
  474. default:
  475. UpdatesDirectCheck->Checked = true;
  476. break;
  477. case ctAuto:
  478. UpdatesAutoCheck->Checked = true;
  479. break;
  480. case ctProxy:
  481. UpdatesProxyCheck->Checked = true;
  482. break;
  483. }
  484. UpdatesProxyHostEdit->Text = Updates.ProxyHost;
  485. UpdatesProxyPortEdit->AsInteger = Updates.ProxyPort;
  486. // presets
  487. (*FCopyParamList) = *WinConfiguration->CopyParamList;
  488. UpdateCopyParamListView();
  489. CopyParamListView->ItemIndex = 0;
  490. BOOLPROP(CopyParamAutoSelectNotice);
  491. // interface
  492. switch (CustomWinConfiguration->Interface)
  493. {
  494. case ifCommander:
  495. CommanderInterfaceButton2->Checked = true;
  496. break;
  497. case ifExplorer:
  498. ExplorerInterfaceButton2->Checked = true;
  499. break;
  500. default:
  501. DebugFail();
  502. break;
  503. }
  504. // security
  505. UseMasterPasswordCheck->Checked = WinConfiguration->UseMasterPassword;
  506. SessionRememberPasswordCheck->Checked = GUIConfiguration->SessionRememberPassword;
  507. // network
  508. RetrieveExternalIpAddressButton->Checked = Configuration->ExternalIpAddress.IsEmpty();
  509. CustomExternalIpAddressButton->Checked = !RetrieveExternalIpAddressButton->Checked;
  510. CustomExternalIpAddressEdit->Text = Configuration->ExternalIpAddress;
  511. TryFtpWhenSshFailsCheck->Checked = Configuration->TryFtpWhenSshFails;
  512. // logging
  513. EnableLoggingCheck->Checked = Configuration->Logging;
  514. LogProtocolCombo->ItemIndex = Configuration->LogProtocol;
  515. LogToFileCheck->Checked = Configuration->LogToFile;
  516. LogFileNameEdit3->Text =
  517. !Configuration->LogFileName.IsEmpty() ? Configuration->LogFileName : Configuration->DefaultLogFileName;
  518. if (Configuration->LogFileAppend)
  519. {
  520. LogFileAppendButton->Checked = true;
  521. }
  522. else
  523. {
  524. LogFileOverwriteButton->Checked = true;
  525. }
  526. BOOLPROP(LogSensitive);
  527. EnableActionsLoggingCheck->Checked = Configuration->LogActions;
  528. ActionsLogFileNameEdit->Text = Configuration->ActionsLogFileName;
  529. #undef BOOLPROP
  530. }
  531. __finally
  532. {
  533. FNoUpdate--;
  534. }
  535. UpdateControls();
  536. }
  537. //---------------------------------------------------------------------------
  538. void __fastcall TPreferencesDialog::SaveConfiguration()
  539. {
  540. Configuration->BeginUpdate();
  541. try
  542. {
  543. TGUICopyParamType CopyParam = GUIConfiguration->DefaultCopyParam;
  544. #define BOOLPROP(PROP) WinConfiguration->PROP = PROP ## Check->Checked
  545. BOOLPROP(DefaultDirIsHome);
  546. BOOLPROP(PreservePanelState);
  547. BOOLPROP(DeleteToRecycleBin);
  548. BOOLPROP(DDWarnLackOfTempSpace);
  549. BOOLPROP(ShowHiddenFiles);
  550. BOOLPROP(RenameWholeName);
  551. BOOLPROP(ShowInaccesibleDirectories);
  552. BOOLPROP(CopyOnDoubleClickConfirmation);
  553. BOOLPROP(ConfirmTransferring);
  554. BOOLPROP(ConfirmOverwriting);
  555. BOOLPROP(ConfirmResume);
  556. BOOLPROP(ConfirmDeleting);
  557. BOOLPROP(ConfirmRecycling);
  558. BOOLPROP(ConfirmExitOnCompletion);
  559. BOOLPROP(ConfirmCommandSession);
  560. BOOLPROP(ContinueOnError);
  561. BOOLPROP(DDAllowMoveInit);
  562. BOOLPROP(BeepOnFinish);
  563. BOOLPROP(TemporaryDirectoryAppendSession);
  564. BOOLPROP(TemporaryDirectoryAppendPath);
  565. BOOLPROP(TemporaryDirectoryDeterministic);
  566. BOOLPROP(TemporaryDirectoryCleanup);
  567. BOOLPROP(ConfirmTemporaryDirectoryCleanup);
  568. BOOLPROP(FullRowSelect);
  569. WinConfiguration->ConfirmClosingSession = ConfirmClosingSessionCheck2->Checked;
  570. WinConfiguration->DDTransferConfirmation =
  571. CheckBoxAutoSwitchSave(DDTransferConfirmationCheck);
  572. GUIConfiguration->BeepOnFinishAfter =
  573. static_cast<double>(BeepOnFinishAfterEdit->Value / SecsPerDay);
  574. BOOLPROP(BalloonNotifications);
  575. WinConfiguration->DDAllowMove = !DDWarnOnMoveCheck->Checked;
  576. WinConfiguration->DDExtEnabled = DDExtEnabledButton->Checked;
  577. if (DDSystemTemporaryDirectoryButton->Checked)
  578. {
  579. WinConfiguration->DDTemporaryDirectory = L"";
  580. }
  581. else
  582. {
  583. WinConfiguration->DDTemporaryDirectory = DDTemporaryDirectoryEdit->Text;
  584. }
  585. // Commander
  586. TScpCommanderConfiguration ScpCommander = WinConfiguration->ScpCommander;
  587. if (NortonLikeModeCombo->ItemIndex == 2)
  588. {
  589. ScpCommander.NortonLikeMode = nlOff;
  590. }
  591. else if (NortonLikeModeCombo->ItemIndex == 1)
  592. {
  593. ScpCommander.NortonLikeMode = nlKeyboard;
  594. }
  595. else
  596. {
  597. ScpCommander.NortonLikeMode = nlOn;
  598. }
  599. ScpCommander.SwappedPanels = SwappedPanelsCheck->Checked;
  600. ScpCommander.TreeOnLeft = TreeOnLeftCheck->Checked;
  601. ScpCommander.ExplorerKeyboardShortcuts =
  602. (ExplorerKeyboardShortcutsCombo->ItemIndex != 0);
  603. BOOLPROP(UseLocationProfiles);
  604. ScpCommander.CompareByTime = CompareByTimeCheck->Checked;
  605. ScpCommander.CompareBySize = CompareBySizeCheck->Checked;
  606. // Local panel
  607. ScpCommander.PreserveLocalDirectory = PreserveLocalDirectoryCheck->Checked;
  608. ScpCommander.SystemContextMenu = SystemContextMenuCheck->Checked;
  609. WinConfiguration->ScpCommander = ScpCommander;
  610. // Explorer
  611. TScpExplorerConfiguration ScpExplorer = WinConfiguration->ScpExplorer;
  612. ScpExplorer.ShowFullAddress = ShowFullAddressCheck->Checked;
  613. WinConfiguration->ScpExplorer = ScpExplorer;
  614. Configuration->RandomSeedFile = RandomSeedFileEdit->Text;
  615. // editor
  616. WinConfiguration->Editor.WordWrap = EditorWordWrapCheck->Checked;
  617. WinConfiguration->Editor.TabSize = EditorTabSizeEdit->AsInteger;
  618. switch (EditorEncodingCombo->ItemIndex)
  619. {
  620. case 1:
  621. WinConfiguration->Editor.Encoding = CP_UTF8;
  622. break;
  623. default:
  624. WinConfiguration->Editor.Encoding = CP_ACP;
  625. break;
  626. }
  627. TWinConfiguration::StoreFont(FEditorFont.get(), WinConfiguration->Editor.Font);
  628. WinConfiguration->Editor.FontColor = FEditorFont->Color;
  629. WinConfiguration->Editor.BackgroundColor = FEditorBackgroundColor;
  630. WinConfiguration->EditorList = FEditorList;
  631. // overwrites only TCopyParamType fields
  632. CopyParam = FCopyParams;
  633. if (ResumeOnButton->Checked) CopyParam.ResumeSupport = rsOn;
  634. if (ResumeSmartButton->Checked) CopyParam.ResumeSupport = rsSmart;
  635. if (ResumeOffButton->Checked) CopyParam.ResumeSupport = rsOff;
  636. CopyParam.ResumeThreshold = ResumeThresholdEdit->AsInteger * 1024;
  637. Configuration->SessionReopenAuto =
  638. (SessionReopenAutoCheck->Checked ? (SessionReopenAutoEdit->AsInteger * MSecsPerSec) : 0);
  639. GUIConfiguration->SessionReopenAutoIdle =
  640. (SessionReopenAutoIdleCheck->Checked ? (SessionReopenAutoIdleEdit->AsInteger * MSecsPerSec) : 0);
  641. Configuration->SessionReopenAutoStall =
  642. (SessionReopenAutoStallCheck->Checked ? (SessionReopenAutoStallEdit->AsInteger * MSecsPerSec) : 0);
  643. Configuration->SessionReopenTimeout = (SessionReopenTimeoutEdit->AsInteger * MSecsPerSec);
  644. WinConfiguration->CustomCommandList = FCustomCommandList;
  645. WinConfiguration->ExtensionList = FExtensionList;
  646. WinConfiguration->CustomCommandOptions = FCustomCommandOptions.get();
  647. GUIConfiguration->PuttyPath = PuttyPathEdit->Text;
  648. GUIConfiguration->PuttyPassword = PuttyPasswordCheck2->Checked;
  649. WinConfiguration->AutoOpenInPutty = AutoOpenInPuttyCheck->Checked;
  650. WinConfiguration->TelnetForFtpInPutty = TelnetForFtpInPuttyCheck->Checked;
  651. // do not overwrite custom keys
  652. if (PuttyRegistryStorageKeyEdit->ItemIndex >= 0)
  653. {
  654. GUIConfiguration->PuttyRegistryStorageKey = PuttyRegistryStorageKeyEdit->Text;
  655. }
  656. // Queue
  657. GUIConfiguration->QueueTransfersLimit = QueueTransferLimitEdit->AsInteger;
  658. WinConfiguration->EnableQueueByDefault = EnableQueueByDefaultCheck->Checked;
  659. GUIConfiguration->QueueAutoPopup = QueueAutoPopupCheck->Checked;
  660. CopyParam.Queue = QueueCheck->Checked;
  661. CopyParam.QueueIndividually = QueueIndividuallyCheck->Checked;
  662. CopyParam.QueueNoConfirmation = QueueNoConfirmationCheck->Checked;
  663. GUIConfiguration->QueueKeepDoneItems = (QueueKeepDoneItemsForCombo->ItemIndex != 0);
  664. switch (QueueKeepDoneItemsForCombo->ItemIndex)
  665. {
  666. case 0:
  667. GUIConfiguration->QueueKeepDoneItemsFor = 0;
  668. break;
  669. case 1:
  670. GUIConfiguration->QueueKeepDoneItemsFor = 15;
  671. break;
  672. case 2:
  673. GUIConfiguration->QueueKeepDoneItemsFor = 60;
  674. break;
  675. case 3:
  676. GUIConfiguration->QueueKeepDoneItemsFor = 15 * 60;
  677. break;
  678. case 4:
  679. GUIConfiguration->QueueKeepDoneItemsFor = 60 * 60;
  680. break;
  681. default:
  682. GUIConfiguration->QueueKeepDoneItemsFor = -1;
  683. break;
  684. }
  685. if (QueueViewShowButton->Checked)
  686. {
  687. WinConfiguration->QueueView.Show = qvShow;
  688. }
  689. else if (QueueViewHideWhenEmptyButton->Checked)
  690. {
  691. WinConfiguration->QueueView.Show = qvHideWhenEmpty;
  692. }
  693. else
  694. {
  695. WinConfiguration->QueueView.Show = qvHide;
  696. }
  697. GUIConfiguration->DefaultCopyParam = CopyParam;
  698. // window
  699. WinConfiguration->AutoSaveWorkspace =
  700. !AutoWorkspaceCombo->Text.IsEmpty() &&
  701. AutoSaveWorkspaceCheck->Checked;
  702. if (!AutoWorkspaceCombo->Text.IsEmpty())
  703. {
  704. WinConfiguration->AutoWorkspace = AutoWorkspaceCombo->Text;
  705. }
  706. WinConfiguration->AutoSaveWorkspacePasswords = AutoSaveWorkspacePasswordsCheck->Checked;
  707. if (PathInCaptionFullButton->Checked)
  708. {
  709. WinConfiguration->PathInCaption = picFull;
  710. }
  711. else if (PathInCaptionShortButton->Checked)
  712. {
  713. WinConfiguration->PathInCaption = picShort;
  714. }
  715. else
  716. {
  717. WinConfiguration->PathInCaption = picNone;
  718. }
  719. BOOLPROP(MinimizeToTray);
  720. BOOLPROP(ExternalSessionInExistingInstance);
  721. BOOLPROP(KeepOpenWhenNoSession);
  722. BOOLPROP(ShowTips);
  723. // panels
  724. WinConfiguration->DoubleClickAction = (TDoubleClickAction)DoubleClickActionCombo->ItemIndex;
  725. BOOLPROP(AutoReadDirectoryAfterOp);
  726. BOOLPROP(RefreshRemotePanel);
  727. WinConfiguration->RefreshRemotePanelInterval =
  728. static_cast<double>(RefreshRemotePanelIntervalEdit->Value / SecsPerDay);
  729. switch (FormatSizeBytesCombo->ItemIndex)
  730. {
  731. case 0:
  732. WinConfiguration->FormatSizeBytes = fbNone;
  733. break;
  734. case 1:
  735. WinConfiguration->FormatSizeBytes = fbKilobytes;
  736. break;
  737. case 2:
  738. WinConfiguration->FormatSizeBytes = fbShort;
  739. break;
  740. default:
  741. DebugFail();
  742. }
  743. TFontConfiguration PanelFontConfiguration;
  744. if (PanelFontCheck->Checked)
  745. {
  746. TWinConfiguration::StoreFont(FPanelFont.get(), PanelFontConfiguration);
  747. }
  748. WinConfiguration->PanelFont = PanelFontConfiguration;
  749. // updates
  750. WinConfiguration->Updates = SaveUpdates();
  751. Configuration->CollectUsage = CollectUsageCheck->Checked;
  752. // presets
  753. WinConfiguration->CopyParamList = FCopyParamList;
  754. BOOLPROP(CopyParamAutoSelectNotice);
  755. // interface
  756. if (GetInterface() != CustomWinConfiguration->Interface)
  757. {
  758. Configuration->Usage->Inc(L"InterfaceChanges");
  759. }
  760. CustomWinConfiguration->Interface = GetInterface();
  761. // network
  762. Configuration->ExternalIpAddress =
  763. (CustomExternalIpAddressButton->Checked ? CustomExternalIpAddressEdit->Text : UnicodeString());
  764. Configuration->TryFtpWhenSshFails = TryFtpWhenSshFailsCheck->Checked;
  765. // security
  766. GUIConfiguration->SessionRememberPassword = SessionRememberPasswordCheck->Checked;
  767. // logging
  768. Configuration->Logging = EnableLoggingCheck->Checked;
  769. Configuration->LogProtocol = LogProtocolCombo->ItemIndex;
  770. Configuration->LogFileName = LogToFileCheck->Checked ? LogFileNameEdit3->Text : UnicodeString();
  771. Configuration->LogFileAppend = LogFileAppendButton->Checked;
  772. BOOLPROP(LogSensitive);
  773. Configuration->LogActions = EnableActionsLoggingCheck->Checked;
  774. Configuration->ActionsLogFileName = ActionsLogFileNameEdit->Text;
  775. // languages
  776. if (LanguagesView->ItemFocused != NULL)
  777. {
  778. TLocaleInfo * LocaleInfo = static_cast<TLocaleInfo *>(LanguagesView->ItemFocused->Data);
  779. LCID Locale;
  780. // Do not change the locale settings, unless changed explicitly by user
  781. // to allow an automatic upgrade to new translation once the UI language translation
  782. // becomes available
  783. if (LocaleInfo->Locale == WinConfiguration->DefaultLocale)
  784. {
  785. Locale = NULL;
  786. }
  787. else
  788. {
  789. Locale = LocaleInfo->Locale;
  790. }
  791. GUIConfiguration->Locale = Locale;
  792. }
  793. // This possibly fails, make it last, so that the other settings are preserved.
  794. // Do nothing when no option is selected (i.e. storage is stNul).
  795. if (RegistryStorageButton->Checked)
  796. {
  797. Configuration->Storage = stRegistry;
  798. }
  799. else if (IniFileStorageButton2->Checked)
  800. {
  801. Configuration->Storage = stIniFile;
  802. }
  803. #undef BOOLPROP
  804. }
  805. __finally
  806. {
  807. Configuration->EndUpdate();
  808. }
  809. }
  810. //---------------------------------------------------------------------------
  811. TUpdatesConfiguration __fastcall TPreferencesDialog::SaveUpdates()
  812. {
  813. TUpdatesConfiguration Updates = WinConfiguration->Updates;
  814. if (UpdatesPeriodCombo->ItemIndex == 0)
  815. {
  816. Updates.Period = 0;
  817. }
  818. else if (UpdatesPeriodCombo->ItemIndex == 1)
  819. {
  820. Updates.Period = 1;
  821. }
  822. else if (UpdatesPeriodCombo->ItemIndex == 2)
  823. {
  824. Updates.Period = 7;
  825. }
  826. else
  827. {
  828. Updates.Period = 30;
  829. }
  830. Updates.ShowOnStartup = UpdatesShowOnStartup->Checked;
  831. Updates.AuthenticationEmail = UpdatesAuthenticationEmailEdit->Text;
  832. Updates.BetaVersions = ComboAutoSwitchSave(UpdatesBetaVersionsCombo);
  833. if (UpdatesDirectCheck->Checked)
  834. {
  835. Updates.ConnectionType = ctDirect;
  836. }
  837. else if (UpdatesAutoCheck->Checked)
  838. {
  839. Updates.ConnectionType = ctAuto;
  840. }
  841. else if (UpdatesProxyCheck->Checked)
  842. {
  843. if (!UpdatesProxyHostEdit->Text.IsEmpty())
  844. {
  845. Updates.ConnectionType = ctProxy;
  846. }
  847. else
  848. {
  849. Updates.ConnectionType = ctDirect;
  850. }
  851. }
  852. Updates.ProxyHost = UpdatesProxyHostEdit->Text;
  853. Updates.ProxyPort = UpdatesProxyPortEdit->AsInteger;
  854. return Updates;
  855. }
  856. //---------------------------------------------------------------------------
  857. TInterface __fastcall TPreferencesDialog::GetInterface()
  858. {
  859. return CommanderInterfaceButton2->Checked ? ifCommander : ifExplorer;
  860. }
  861. //---------------------------------------------------------------------------
  862. void __fastcall TPreferencesDialog::FormShow(TObject * /*Sender*/)
  863. {
  864. // Load only now, particularly so that we have handles allocated already.
  865. // If called before ShowModal, we end up recreating the handles,
  866. // what causes flicker of the currently focused window
  867. LoadConfiguration();
  868. InstallPathWordBreakProc(RandomSeedFileEdit);
  869. InstallPathWordBreakProc(DDTemporaryDirectoryEdit);
  870. InstallPathWordBreakProc(PuttyPathEdit);
  871. InstallPathWordBreakProc(LogFileNameEdit3);
  872. InstallPathWordBreakProc(ActionsLogFileNameEdit);
  873. ListView_SetExtendedListViewStyle(CustomCommandsView->Handle, (ListView_GetExtendedListViewStyle(CustomCommandsView->Handle) & ~LVS_EX_INFOTIP));
  874. PrepareNavigationTree(NavigationTree);
  875. switch (FPreferencesMode) {
  876. case pmEditor: PageControl->ActivePage = EditorSheet; break;
  877. case pmCustomCommands: PageControl->ActivePage = CustomCommandsSheet; break;
  878. case pmQueue: PageControl->ActivePage = QueueSheet; break;
  879. case pmLogging: PageControl->ActivePage = LogSheet; break;
  880. case pmUpdates: PageControl->ActivePage = UpdatesSheet; break;
  881. case pmPresets: PageControl->ActivePage = CopyParamListSheet; break;
  882. case pmEditors: PageControl->ActivePage = EditorSheet; break;
  883. case pmCommander: PageControl->ActivePage = CommanderSheet; break;
  884. case pmEditorInternal: PageControl->ActivePage = EditorInternalSheet; break;
  885. default: PageControl->ActivePage = PreferencesSheet; break;
  886. }
  887. PageControlChange(NULL);
  888. ActiveControl = NavigationTree;
  889. }
  890. //---------------------------------------------------------------------------
  891. void __fastcall TPreferencesDialog::ControlChange(TObject * /*Sender*/)
  892. {
  893. UpdateControls();
  894. }
  895. //---------------------------------------------------------------------------
  896. UnicodeString __fastcall TPreferencesDialog::TabSample(UnicodeString Values)
  897. {
  898. UnicodeString Result;
  899. for (int Index = 1; Index <= Values.Length(); Index++)
  900. {
  901. if (Index > 1)
  902. {
  903. Result += L' ';
  904. if (EditorTabSizeEdit->AsInteger > 2)
  905. {
  906. Result += UnicodeString::StringOfChar(L' ', EditorTabSizeEdit->AsInteger - 2);
  907. }
  908. }
  909. Result += Values[Index];
  910. }
  911. return Result;
  912. }
  913. //---------------------------------------------------------------------------
  914. TCustomCommandList * __fastcall TPreferencesDialog::GetCommandList(int Index)
  915. {
  916. if (Index < FCustomCommandList->Count)
  917. {
  918. return FCustomCommandList;
  919. }
  920. else
  921. {
  922. return FExtensionList;
  923. }
  924. }
  925. //---------------------------------------------------------------------------
  926. int __fastcall TPreferencesDialog::GetCommandIndex(int Index)
  927. {
  928. if (Index >= FCustomCommandList->Count)
  929. {
  930. Index -= FCustomCommandList->Count;
  931. }
  932. return Index;
  933. }
  934. //---------------------------------------------------------------------------
  935. int __fastcall TPreferencesDialog::GetListCommandIndex(TCustomCommandList * List)
  936. {
  937. int Index;
  938. if (GetCommandList(CustomCommandsView->ItemIndex) == List)
  939. {
  940. Index = GetCommandIndex(CustomCommandsView->ItemIndex);
  941. }
  942. else
  943. {
  944. Index = -1;
  945. }
  946. return Index;
  947. }
  948. //---------------------------------------------------------------------------
  949. int __fastcall TPreferencesDialog::GetCommandListIndex(TCustomCommandList * List, int Index)
  950. {
  951. if (List == FExtensionList)
  952. {
  953. Index += FCustomCommandList->Count;
  954. }
  955. return Index;
  956. }
  957. //---------------------------------------------------------------------------
  958. void __fastcall TPreferencesDialog::UpdateControls()
  959. {
  960. if (FNoUpdate == 0)
  961. {
  962. EnableControl(BeepOnFinishAfterEdit, BeepOnFinishCheck->Checked);
  963. EnableControl(BeepOnFinishAfterText, BeepOnFinishCheck->Checked);
  964. EnableControl(ResumeThresholdEdit, ResumeSmartButton->Checked);
  965. EnableControl(ResumeThresholdUnitLabel2, ResumeThresholdEdit->Enabled);
  966. EnableControl(SessionReopenAutoEdit, SessionReopenAutoCheck->Checked);
  967. EnableControl(SessionReopenAutoLabel, SessionReopenAutoEdit->Enabled);
  968. EnableControl(SessionReopenAutoSecLabel, SessionReopenAutoEdit->Enabled);
  969. EnableControl(SessionReopenAutoIdleEdit, SessionReopenAutoIdleCheck->Checked);
  970. EnableControl(SessionReopenAutoIdleLabel, SessionReopenAutoIdleEdit->Enabled);
  971. EnableControl(SessionReopenAutoIdleSecLabel, SessionReopenAutoIdleEdit->Enabled);
  972. EnableControl(SessionReopenAutoStallEdit, SessionReopenAutoStallCheck->Checked);
  973. EnableControl(SessionReopenAutoStallLabel, SessionReopenAutoStallEdit->Enabled);
  974. EnableControl(SessionReopenAutoStallSecLabel, SessionReopenAutoStallEdit->Enabled);
  975. EnableControl(SessionReopenTimeoutEdit,
  976. SessionReopenAutoEdit->Enabled || SessionReopenAutoStallCheck->Checked);
  977. EnableControl(SessionReopenTimeoutLabel, SessionReopenTimeoutEdit->Enabled);
  978. EnableControl(SessionReopenTimeoutSecLabel,SessionReopenTimeoutEdit->Enabled);
  979. EnableControl(CopyOnDoubleClickConfirmationCheck,
  980. (DoubleClickActionCombo->ItemIndex == 1) && ConfirmTransferringCheck->Checked);
  981. TFont * ActualPanelFont = PanelFontCheck->Checked ? FPanelFont.get() : WinConfiguration->SystemIconFont;
  982. UnicodeString PanelFontLabelText;
  983. PanelFontLabelText = FMTLOAD(EDITOR_FONT_FMT,
  984. (ActualPanelFont->Name, ActualPanelFont->Size));
  985. PanelFontLabel->Caption = PanelFontLabelText;
  986. if (!SameFont(PanelFontLabel->Font, ActualPanelFont))
  987. {
  988. PanelFontLabel->Font = ActualPanelFont;
  989. }
  990. EnableControl(RefreshRemotePanelIntervalEdit, RefreshRemotePanelCheck->Checked);
  991. EnableControl(RefreshRemoteDirectoryUnitLabel, RefreshRemotePanelCheck->Checked);
  992. UnicodeString EditorFontLabelText;
  993. EditorFontLabelText = FMTLOAD(EDITOR_FONT_FMT,
  994. (FEditorFont->Name, FEditorFont->Size)) + L"\n\n";
  995. EditorFontLabelText += TabSample(L"ABCD") + L"\n";
  996. EditorFontLabelText += TabSample(L"1234");
  997. EditorFontLabel->Caption = EditorFontLabelText;
  998. TColor EditorFontColor = GetWindowTextColor(FEditorFont->Color);
  999. if (!SameFont(EditorFontLabel->Font, FEditorFont.get()) ||
  1000. (EditorFontLabel->Font->Color != EditorFontColor))
  1001. {
  1002. std::unique_ptr<TFont> Font(new TFont);
  1003. Font->Assign(FEditorFont.get());
  1004. Font->Color = EditorFontColor;
  1005. EditorFontLabel->Font = Font.get();
  1006. }
  1007. EditorFontLabel->Color = GetWindowColor(FEditorBackgroundColor);
  1008. TCustomCommandList * CommandList = GetCommandList(CustomCommandsView->ItemIndex);
  1009. int CommandIndex = GetCommandIndex(CustomCommandsView->ItemIndex);
  1010. bool CommandSelected = (CustomCommandsView->Selected != NULL);
  1011. bool CustomCommandSelected = CommandSelected && (CommandList == FCustomCommandList);
  1012. bool ExtensionSelected = CommandSelected && (CommandList == FExtensionList);
  1013. EnableControl(EditCommandButton, CustomCommandSelected);
  1014. EditCommandButton->Visible = !ExtensionSelected;
  1015. EnableControl(ConfigureCommandButton, ExtensionSelected && CommandList->Commands[CommandIndex]->AnyOptionWithFlag(TCustomCommandType::ofConfig));
  1016. ConfigureCommandButton->Visible = ExtensionSelected;
  1017. EnableControl(RemoveCommandButton, CommandSelected);
  1018. EnableControl(UpCommandButton, CommandSelected && (CommandIndex > 0));
  1019. EnableControl(DownCommandButton, CommandSelected && (CommandIndex < CommandList->Count - 1));
  1020. bool CopyParamSelected = (CopyParamListView->Selected != NULL);
  1021. EnableControl(EditCopyParamButton, CopyParamSelected);
  1022. EnableControl(DuplicateCopyParamButton, CopyParamSelected);
  1023. EnableControl(RemoveCopyParamButton,
  1024. CopyParamSelected && (CopyParamListView->ItemIndex >= 1));
  1025. EnableControl(UpCopyParamButton,
  1026. CopyParamSelected && (CopyParamListView->ItemIndex > 1));
  1027. EnableControl(DownCopyParamButton,
  1028. CopyParamSelected &&
  1029. (CopyParamListView->ItemIndex >= 1) &&
  1030. (CopyParamListView->ItemIndex < CopyParamListView->Items->Count - 1));
  1031. EnableControl(CopyParamAutoSelectNoticeCheck, FCopyParamList->AnyRule);
  1032. UnicodeString InfoStr;
  1033. if (CopyParamSelected)
  1034. {
  1035. const TCopyParamType * SelectedCopyParam = GetCopyParam(CopyParamListView->ItemIndex);
  1036. InfoStr = SelectedCopyParam->GetInfoStr(L"; ", 0);
  1037. if (CopyParamListView->ItemIndex >= 1)
  1038. {
  1039. const TCopyParamRule * Rule = FCopyParamList->Rules[CopyParamListView->ItemIndex - 1];
  1040. if (Rule != NULL)
  1041. {
  1042. InfoStr += L"\n" + FORMAT(ReplaceStr(LoadStr(COPY_PARAM_RULE), L"\n", L" "), (Rule->GetInfoStr(L"; ")));
  1043. }
  1044. }
  1045. }
  1046. SetLabelHintPopup(CopyParamLabel, InfoStr);
  1047. EnableControl(DDExtEnabledButton, WinConfiguration->DDExtInstalled);
  1048. EnableControl(DDExtEnabledLabel, WinConfiguration->DDExtInstalled);
  1049. EnableControl(DDExtDisabledPanel, DDExtDisabledButton->Checked);
  1050. EnableControl(DDTemporaryDirectoryEdit, DDCustomTemporaryDirectoryButton->Enabled &&
  1051. DDCustomTemporaryDirectoryButton->Checked);
  1052. EnableControl(DDWarnOnMoveCheck, DDExtDisabledButton->Checked &&
  1053. DDAllowMoveInitCheck->Checked);
  1054. EnableControl(ConfirmTemporaryDirectoryCleanupCheck,
  1055. TemporaryDirectoryCleanupCheck->Checked);
  1056. // allow only when some of the known storages is selected,
  1057. // and particularly do not allow switching storage, when we start with stNul,
  1058. // as that would destroy the stored configuration
  1059. EnableControl(StorageGroup, RegistryStorageButton->Checked || IniFileStorageButton2->Checked);
  1060. IniFileStorageButton2->Caption =
  1061. AnsiReplaceStr(IniFileStorageButton2->Caption, L"(winscp.ini)",
  1062. FORMAT(L"(%s)", (ExpandEnvironmentVariables(Configuration->IniFileStorageName))));
  1063. EditorFontLabel->WordWrap = EditorWordWrapCheck->Checked;
  1064. bool EditorSelected = (EditorListView3->Selected != NULL);
  1065. EnableControl(EditEditorButton, EditorSelected);
  1066. EnableControl(RemoveEditorButton, EditorSelected);
  1067. EnableControl(UpEditorButton, EditorSelected &&
  1068. (EditorListView3->ItemIndex > 0));
  1069. EnableControl(DownEditorButton, EditorSelected &&
  1070. (EditorListView3->ItemIndex < EditorListView3->Items->Count - 1));
  1071. // updates
  1072. EnableControl(UpdatesAuthenticationEmailEdit, FAutomaticUpdatesPossible);
  1073. EnableControl(UpdatesAuthenticationEmailLabel, UpdatesAuthenticationEmailEdit->Enabled);
  1074. EnableControl(UsageViewButton, CollectUsageCheck->Checked);
  1075. EnableControl(UpdatesProxyHostEdit, UpdatesProxyCheck->Checked);
  1076. EnableControl(UpdatesProxyHostLabel, UpdatesProxyHostEdit->Enabled);
  1077. EnableControl(UpdatesProxyPortEdit, UpdatesProxyCheck->Checked);
  1078. EnableControl(UpdatesProxyPortLabel, UpdatesProxyPortEdit->Enabled);
  1079. bool IsSiteCommand = false;
  1080. bool IsPasswordCommand = false;
  1081. try
  1082. {
  1083. TRemoteCustomCommand RemoteCustomCommand;
  1084. TInteractiveCustomCommand InteractiveCustomCommand(&RemoteCustomCommand);
  1085. UnicodeString PuttyPath = PuttyPathEdit->Text;
  1086. PuttyPath = InteractiveCustomCommand.Complete(PuttyPath, false);
  1087. IsSiteCommand = RemoteCustomCommand.IsSiteCommand(PuttyPath);
  1088. IsPasswordCommand = RemoteCustomCommand.IsPasswordCommand(PuttyPath);
  1089. }
  1090. catch (...)
  1091. {
  1092. // noop
  1093. }
  1094. bool AnyPuttyPath = !PuttyPathEdit->Text.IsEmpty();
  1095. EnableControl(PuttyPasswordCheck2, AnyPuttyPath && !IsPasswordCommand);
  1096. EnableControl(AutoOpenInPuttyCheck, AnyPuttyPath);
  1097. EnableControl(TelnetForFtpInPuttyCheck,
  1098. AnyPuttyPath && !IsSiteCommand);
  1099. EnableControl(PuttyRegistryStorageKeyEdit,
  1100. AnyPuttyPath && !IsSiteCommand);
  1101. EnableControl(PuttyRegistryStorageKeyLabel, PuttyRegistryStorageKeyEdit->Enabled);
  1102. EnableControl(SetMasterPasswordButton, WinConfiguration->UseMasterPassword);
  1103. // network
  1104. EnableControl(CustomExternalIpAddressEdit, CustomExternalIpAddressButton->Checked);
  1105. // window
  1106. EnableControl(AutoWorkspaceCombo, AutoSaveWorkspaceCheck->Checked);
  1107. EnableControl(AutoWorkspaceLabel, AutoWorkspaceCombo->Enabled);
  1108. EnableControl(AutoSaveWorkspacePasswordsCheck,
  1109. !Configuration->DisablePasswordStoring &&
  1110. AutoWorkspaceCombo->Enabled);
  1111. // integration
  1112. // There's no quick launch in Windows 7
  1113. EnableControl(QuickLaunchIconButton, !IsWin7());
  1114. MakeDefaultHandlerItem->Visible = IsWinVista();
  1115. // languages
  1116. LanguageChangeLabel->Visible =
  1117. DebugAlwaysTrue(!GUIConfiguration->CanApplyLocaleImmediately) &&
  1118. (LanguagesView->ItemFocused != NULL) &&
  1119. (static_cast<TLocaleInfo *>(LanguagesView->ItemFocused->Data)->Locale != GUIConfiguration->AppliedLocale);
  1120. // logging
  1121. EnableControl(LogProtocolCombo, EnableLoggingCheck->Checked);
  1122. EnableControl(LogToFileCheck, LogProtocolCombo->Enabled);
  1123. EnableControl(LogFileNameEdit3, LogToFileCheck->Enabled && LogToFileCheck->Checked);
  1124. EnableControl(LogFileNameHintText, LogFileNameEdit3->Enabled);
  1125. EnableControl(LogFileAppendButton, LogFileNameEdit3->Enabled);
  1126. EnableControl(LogFileOverwriteButton, LogFileNameEdit3->Enabled);
  1127. EnableControl(LogSensitiveCheck, LogProtocolCombo->Enabled);
  1128. EnableControl(ActionsLogFileNameEdit, EnableActionsLoggingCheck->Checked);
  1129. EnableControl(ActionsLogFileNameHintText, ActionsLogFileNameEdit->Enabled);
  1130. // interface
  1131. InterfaceChangeLabel->Visible =
  1132. !CustomWinConfiguration->CanApplyInterfaceImmediately &&
  1133. (GetInterface() != CustomWinConfiguration->AppliedInterface);
  1134. }
  1135. }
  1136. //---------------------------------------------------------------------------
  1137. void __fastcall TPreferencesDialog::EditorFontButtonClick(TObject * /*Sender*/)
  1138. {
  1139. if (FontDialog(FEditorFont.get()))
  1140. {
  1141. UpdateControls();
  1142. }
  1143. }
  1144. //---------------------------------------------------------------------------
  1145. void __fastcall TPreferencesDialog::EditorFontColorChange(TColor Color)
  1146. {
  1147. FEditorFont->Color = Color;
  1148. UpdateControls();
  1149. }
  1150. //---------------------------------------------------------------------------
  1151. void __fastcall TPreferencesDialog::EditorFontColorButtonClick(TObject * /*Sender*/)
  1152. {
  1153. // WORKAROUND: Compiler keeps crashing randomly (but frequently) with
  1154. // "internal error" when passing menu directly to unique_ptr.
  1155. // Splitting it to two statements seems to help.
  1156. // The same hack exists in TSiteAdvancedDialog::ColorButtonClick
  1157. TPopupMenu * Menu = CreateColorPopupMenu(FEditorFont->Color, EditorFontColorChange);
  1158. // Popup menu has to survive the popup as TBX calls click handler asynchronously (post).
  1159. FColorPopupMenu.reset(Menu);
  1160. MenuPopup(Menu, EditorFontColorButton);
  1161. }
  1162. //---------------------------------------------------------------------------
  1163. void __fastcall TPreferencesDialog::EditorBackgroundColorChange(TColor Color)
  1164. {
  1165. FEditorBackgroundColor = Color;
  1166. UpdateControls();
  1167. }
  1168. //---------------------------------------------------------------------------
  1169. void __fastcall TPreferencesDialog::EditorBackgroundColorButtonClick(TObject * /*Sender*/)
  1170. {
  1171. // See comment in EditorFontColorButtonClick.
  1172. // We are using session color (contrary to editor text color) for background
  1173. // for a consistency with color selection menu on editor toolbar.
  1174. TTBXPopupMenu * PopupMenu = new TTBXPopupMenu(Application);
  1175. FColorPopupMenu.reset(PopupMenu);
  1176. CreateEditorBackgroundColorMenu(PopupMenu->Items, FEditorBackgroundColor, EditorBackgroundColorChange);
  1177. MenuPopup(FColorPopupMenu.get(), EditorBackgroundColorButton);
  1178. }
  1179. //---------------------------------------------------------------------------
  1180. void __fastcall TPreferencesDialog::PanelFontButtonClick(TObject * /*Sender*/)
  1181. {
  1182. if (FontDialog(FPanelFont.get()))
  1183. {
  1184. PanelFontCheck->Checked = true;
  1185. UpdateControls();
  1186. }
  1187. }
  1188. //---------------------------------------------------------------------------
  1189. void __fastcall TPreferencesDialog::FormCloseQuery(TObject * /*Sender*/,
  1190. bool & /*CanClose*/)
  1191. {
  1192. if (ModalResult == DefaultResult(this))
  1193. {
  1194. ExitActiveControl(this);
  1195. }
  1196. }
  1197. //---------------------------------------------------------------------------
  1198. void __fastcall TPreferencesDialog::IconButtonClick(TObject *Sender)
  1199. {
  1200. UnicodeString IconName, Params;
  1201. int SpecialFolder;
  1202. if (Sender == DesktopIconButton)
  1203. {
  1204. IconName = AppName;
  1205. int Result =
  1206. MessageDialog(LoadStr(CREATE_DESKTOP_ICON2), qtConfirmation,
  1207. qaYes | qaNo | qaCancel, HELP_CREATE_ICON);
  1208. switch (Result)
  1209. {
  1210. case qaYes:
  1211. SpecialFolder = CSIDL_COMMON_DESKTOPDIRECTORY;
  1212. break;
  1213. case qaNo:
  1214. SpecialFolder = CSIDL_DESKTOPDIRECTORY;
  1215. break;
  1216. default:
  1217. Abort();
  1218. break;
  1219. }
  1220. }
  1221. else
  1222. {
  1223. if (MessageDialog(MainInstructions(LoadStr(CONFIRM_CREATE_ICON)),
  1224. qtConfirmation, qaYes | qaNo, HELP_CREATE_ICON) == qaYes)
  1225. {
  1226. if (Sender == SendToHookButton)
  1227. {
  1228. IconName = FMTLOAD(SENDTO_HOOK_NAME2, (AppName));
  1229. SpecialFolder = CSIDL_SENDTO;
  1230. Params = TProgramParams::FormatSwitch(UPLOAD_SWITCH);
  1231. }
  1232. else if (Sender == QuickLaunchIconButton)
  1233. {
  1234. IconName = L"Microsoft\\Internet Explorer\\Quick Launch\\" +
  1235. AppName;
  1236. SpecialFolder = CSIDL_APPDATA;
  1237. }
  1238. }
  1239. else
  1240. {
  1241. Abort();
  1242. }
  1243. }
  1244. TInstantOperationVisualizer Visualizer;
  1245. CreateDesktopShortCut(IconName,
  1246. Application->ExeName, Params, L"", SpecialFolder);
  1247. }
  1248. //---------------------------------------------------------------------------
  1249. void __fastcall TPreferencesDialog::CustomCommandsViewData(TObject * /*Sender*/,
  1250. TListItem * Item)
  1251. {
  1252. // WORKAROUND We get here on Wine after destructor is called
  1253. if ((FCustomCommandList != NULL) && (FExtensionList != NULL))
  1254. {
  1255. int Index = Item->Index;
  1256. const TCustomCommandType * Command = GetCommandList(Index)->Commands[GetCommandIndex(Index)];
  1257. UnicodeString Caption = StripHotkey(Command->Name);
  1258. Item->Caption = Caption;
  1259. DebugAssert(!Item->SubItems->Count);
  1260. Item->SubItems->Add(Command->Command);
  1261. Item->SubItems->Add(LoadStr(
  1262. FLAGSET(Command->Params, ccLocal) ? CUSTOM_COMMAND_LOCAL : CUSTOM_COMMAND_REMOTE));
  1263. }
  1264. }
  1265. //---------------------------------------------------------------------------
  1266. void __fastcall TPreferencesDialog::ListViewSelectItem(
  1267. TObject * /*Sender*/, TListItem * /*Item*/, bool /*Selected*/)
  1268. {
  1269. UpdateControls();
  1270. }
  1271. //---------------------------------------------------------------------------
  1272. void __fastcall TPreferencesDialog::UpdateCustomCommandsView()
  1273. {
  1274. CustomCommandsView->Items->Count = FCustomCommandList->Count + FExtensionList->Count;
  1275. AutoSizeListColumnsWidth(CustomCommandsView, 1);
  1276. CustomCommandsView->Invalidate();
  1277. // particularly after command is edited/configured, make sure the hint is updated,
  1278. // even if we manage to display a hint for the same command as before the change
  1279. FCustomCommandsHintItem = NULL;
  1280. }
  1281. //---------------------------------------------------------------------------
  1282. void __fastcall TPreferencesDialog::CustomCommandsViewKeyDown(
  1283. TObject * /*Sender*/, WORD & Key, TShiftState /*Shift*/)
  1284. {
  1285. if (RemoveCommandButton->Enabled && (Key == VK_DELETE))
  1286. {
  1287. RemoveCommandButtonClick(NULL);
  1288. }
  1289. if (AddCommandButton->Enabled && (Key == VK_INSERT))
  1290. {
  1291. AddEditCommand(false);
  1292. }
  1293. }
  1294. //---------------------------------------------------------------------------
  1295. void __fastcall TPreferencesDialog::CustomCommandsViewDblClick(
  1296. TObject * /*Sender*/)
  1297. {
  1298. if (EditCommandButton->Enabled)
  1299. {
  1300. AddEditCommand(true);
  1301. }
  1302. else if (ConfigureCommandButton->Enabled)
  1303. {
  1304. ConfigureCommand();
  1305. }
  1306. }
  1307. //---------------------------------------------------------------------------
  1308. static int __fastcall AddCommandToList(TCustomCommandList * List, int Index, TCustomCommandType * Command)
  1309. {
  1310. if (Index >= 0)
  1311. {
  1312. List->Insert(Index, Command);
  1313. }
  1314. else
  1315. {
  1316. List->Add(Command);
  1317. Index = List->Count - 1;
  1318. }
  1319. return Index;
  1320. }
  1321. //---------------------------------------------------------------------------
  1322. void __fastcall TPreferencesDialog::AddEditCommand(bool Edit)
  1323. {
  1324. TCustomCommandType Command;
  1325. if (Edit)
  1326. {
  1327. int Index = CustomCommandsView->ItemIndex;
  1328. DebugAssert(GetCommandList(Index) == FCustomCommandList);
  1329. Command = *FCustomCommandList->Commands[GetCommandIndex(Index)];
  1330. }
  1331. TShortCuts ShortCuts;
  1332. if (WinConfiguration->SharedBookmarks != NULL)
  1333. {
  1334. WinConfiguration->SharedBookmarks->ShortCuts(ShortCuts);
  1335. }
  1336. FCustomCommandList->ShortCuts(ShortCuts);
  1337. FExtensionList->ShortCuts(ShortCuts);
  1338. if (DoCustomCommandDialog(Command, FCustomCommandList,
  1339. (Edit ? ccmEdit : ccmAdd), 0, NULL, &ShortCuts))
  1340. {
  1341. int Index = GetListCommandIndex(FCustomCommandList);
  1342. TCustomCommandType * ACommand = new TCustomCommandType(Command);
  1343. if (Edit)
  1344. {
  1345. DebugAssert(Index < FCustomCommandList->Count);
  1346. FCustomCommandList->Change(Index, ACommand);
  1347. }
  1348. else
  1349. {
  1350. Index = AddCommandToList(FCustomCommandList, Index, ACommand);
  1351. }
  1352. UpdateCustomCommandsView();
  1353. CustomCommandsView->ItemIndex = GetCommandListIndex(FCustomCommandList, Index);
  1354. CustomCommandsView->ItemFocused->MakeVisible(false);
  1355. UpdateControls();
  1356. }
  1357. }
  1358. //---------------------------------------------------------------------------
  1359. void __fastcall TPreferencesDialog::RemoveCommandButtonClick(
  1360. TObject * /*Sender*/)
  1361. {
  1362. TCustomCommandList * List = GetCommandList(CustomCommandsView->ItemIndex);
  1363. int Index = GetCommandIndex(CustomCommandsView->ItemIndex);
  1364. if (List == FExtensionList)
  1365. {
  1366. const TCustomCommandType * CustomComand = List->Commands[Index];
  1367. // If the extension was added in this "preferences session", remove the file
  1368. int PathIndex = FAddedExtensions->IndexOf(CustomComand->FileName);
  1369. if (PathIndex >= 0)
  1370. {
  1371. FAddedExtensions->Delete(PathIndex);
  1372. DeleteFile(ApiPath(CustomComand->FileName));
  1373. }
  1374. }
  1375. List->Delete(Index);
  1376. UpdateCustomCommandsView();
  1377. UpdateControls();
  1378. }
  1379. //---------------------------------------------------------------------------
  1380. void __fastcall TPreferencesDialog::CustomCommandMove(int Source, int Dest)
  1381. {
  1382. TCustomCommandList * List = GetCommandList(CustomCommandsView->ItemIndex);
  1383. int SourceIndex = GetCommandIndex(Source);
  1384. int DestIndex = GetCommandIndex(Dest);
  1385. List->Move(SourceIndex, DestIndex);
  1386. // workaround for bug in VCL
  1387. CustomCommandsView->ItemIndex = -1;
  1388. CustomCommandsView->ItemFocused = CustomCommandsView->Selected;
  1389. CustomCommandsView->ItemIndex = Dest;
  1390. UpdateCustomCommandsView();
  1391. UpdateControls();
  1392. }
  1393. //---------------------------------------------------------------------------
  1394. void __fastcall TPreferencesDialog::UpDownCommandButtonClick(TObject * Sender)
  1395. {
  1396. CustomCommandMove(CustomCommandsView->ItemIndex,
  1397. CustomCommandsView->ItemIndex + (Sender == UpCommandButton ? -1 : 1));
  1398. }
  1399. //---------------------------------------------------------------------------
  1400. TListViewScrollOnDragOver * __fastcall TPreferencesDialog::ScrollOnDragOver(TObject * ListView)
  1401. {
  1402. if (ListView == CopyParamListView)
  1403. {
  1404. return FCopyParamScrollOnDragOver;
  1405. }
  1406. else if (ListView == CustomCommandsView)
  1407. {
  1408. return FCustomCommandsScrollOnDragOver;
  1409. }
  1410. else if (ListView == EditorListView3)
  1411. {
  1412. return FEditorScrollOnDragOver;
  1413. }
  1414. else
  1415. {
  1416. DebugFail();
  1417. return NULL;
  1418. }
  1419. }
  1420. //---------------------------------------------------------------------------
  1421. void __fastcall TPreferencesDialog::ListViewStartDrag(
  1422. TObject * Sender, TDragObject *& /*DragObject*/)
  1423. {
  1424. FListViewDragSource = dynamic_cast<TListView*>(Sender)->ItemIndex;
  1425. FListViewDragDest = -1;
  1426. ScrollOnDragOver(Sender)->StartDrag();
  1427. }
  1428. //---------------------------------------------------------------------------
  1429. static int __fastcall PointToListViewIndex(TObject * Sender, int X, int Y)
  1430. {
  1431. TListItem * Item = dynamic_cast<TListView*>(Sender)->GetItemAt(X, Y);
  1432. return Item ? Item->Index : -1;
  1433. }
  1434. //---------------------------------------------------------------------------
  1435. bool __fastcall TPreferencesDialog::AllowListViewDrag(TObject * Sender, int X, int Y)
  1436. {
  1437. FListViewDragDest = PointToListViewIndex(Sender, X, Y);
  1438. return (FListViewDragDest >= 0) && (FListViewDragDest != FListViewDragSource);
  1439. }
  1440. //---------------------------------------------------------------------------
  1441. void __fastcall TPreferencesDialog::CustomCommandsViewDragDrop(
  1442. TObject * Sender, TObject * Source, int X, int Y)
  1443. {
  1444. if (Source == CustomCommandsView)
  1445. {
  1446. if (AllowListViewDrag(Sender, X, Y) &&
  1447. (GetCommandList(FListViewDragSource) == GetCommandList(FListViewDragDest)))
  1448. {
  1449. CustomCommandMove(FListViewDragSource, FListViewDragDest);
  1450. }
  1451. }
  1452. }
  1453. //---------------------------------------------------------------------------
  1454. void __fastcall TPreferencesDialog::CustomCommandsViewDragOver(
  1455. TObject *Sender, TObject *Source, int X, int Y, TDragState State, bool & Accept)
  1456. {
  1457. ListViewDragOver(Sender, Source, X, Y, State, Accept);
  1458. if (Source == Sender)
  1459. {
  1460. int Dest = PointToListViewIndex(Sender, X, Y);
  1461. if (GetCommandList(FListViewDragSource) != GetCommandList(Dest))
  1462. {
  1463. Accept = false;
  1464. }
  1465. }
  1466. }
  1467. //---------------------------------------------------------------------------
  1468. void __fastcall TPreferencesDialog::ListViewDragOver(
  1469. TObject * Sender, TObject * Source, int X, int Y,
  1470. TDragState /*State*/, bool & Accept)
  1471. {
  1472. if (Source == Sender)
  1473. {
  1474. // cannot use AllowListViewDrag(X, Y) because of bug in VCL
  1475. // (when dropped on item itself, when it was dragged over another item before,
  1476. // that another item remains highlighted forever)
  1477. Accept = true;
  1478. ScrollOnDragOver(Source)->DragOver(TPoint(X, Y));
  1479. }
  1480. }
  1481. //---------------------------------------------------------------------------
  1482. const TCopyParamType * TPreferencesDialog::GetCopyParam(int Index)
  1483. {
  1484. if (Index == 0)
  1485. {
  1486. return &FCopyParams;
  1487. }
  1488. else
  1489. {
  1490. return FCopyParamList->CopyParams[Index - 1];
  1491. }
  1492. }
  1493. //---------------------------------------------------------------------------
  1494. void __fastcall TPreferencesDialog::CopyParamMove(int Source, int Dest)
  1495. {
  1496. if (Source >= 1 && Source < (1 + FCopyParamList->Count) &&
  1497. Dest >= 0 && Dest < (1 + FCopyParamList->Count))
  1498. {
  1499. if (Dest == 0)
  1500. {
  1501. Dest = 1;
  1502. }
  1503. FCopyParamList->Move(Source - 1, Dest - 1);
  1504. // workaround for bug in VCL
  1505. CopyParamListView->ItemIndex = -1;
  1506. CopyParamListView->ItemFocused = CopyParamListView->Selected;
  1507. CopyParamListView->ItemIndex = Dest;
  1508. UpdateCopyParamListView();
  1509. UpdateControls();
  1510. }
  1511. }
  1512. //---------------------------------------------------------------------------
  1513. void __fastcall TPreferencesDialog::CopyParamListViewDragDrop(
  1514. TObject * Sender, TObject * Source, int X, int Y)
  1515. {
  1516. if (Source == CopyParamListView)
  1517. {
  1518. if (AllowListViewDrag(Sender, X, Y))
  1519. {
  1520. CopyParamMove(FListViewDragSource, FListViewDragDest);
  1521. }
  1522. }
  1523. }
  1524. //---------------------------------------------------------------------------
  1525. void __fastcall TPreferencesDialog::UpDownCopyParamButtonClick(TObject * Sender)
  1526. {
  1527. CopyParamMove(CopyParamListView->ItemIndex,
  1528. CopyParamListView->ItemIndex + (Sender == UpCopyParamButton ? -1 : 1));
  1529. }
  1530. //---------------------------------------------------------------------------
  1531. void __fastcall TPreferencesDialog::RemoveCopyParamButtonClick(
  1532. TObject * /*Sender*/)
  1533. {
  1534. DebugAssert(CopyParamListView->ItemIndex >= 1 &&
  1535. CopyParamListView->ItemIndex < (1 + FCopyParamList->Count));
  1536. FCopyParamList->Delete(CopyParamListView->ItemIndex - 1);
  1537. UpdateCopyParamListView();
  1538. UpdateControls();
  1539. }
  1540. //---------------------------------------------------------------------------
  1541. void __fastcall TPreferencesDialog::AddEditCopyParam(TCopyParamPresetMode Mode)
  1542. {
  1543. int Index = CopyParamListView->ItemIndex;
  1544. bool Result;
  1545. if ((Index == 0) && (Mode == cpmEdit))
  1546. {
  1547. Result = DoCopyParamCustomDialog(FCopyParams, 0);
  1548. }
  1549. else
  1550. {
  1551. TCopyParamRuleData * CopyParamRuleData =
  1552. (FDialogData != NULL ? FDialogData->CopyParamRuleData : NULL);
  1553. // negative (when default is selected) means add to the end
  1554. Index--;
  1555. Result = DoCopyParamPresetDialog(FCopyParamList, Index, Mode, CopyParamRuleData, FCopyParams);
  1556. if (Result)
  1557. {
  1558. UpdateCopyParamListView();
  1559. CopyParamListView->ItemIndex = Index + 1;
  1560. // when using duplicate button, focus remains on original item
  1561. CopyParamListView->ItemFocused = CopyParamListView->Selected;
  1562. }
  1563. }
  1564. if (Result)
  1565. {
  1566. UpdateControls();
  1567. }
  1568. }
  1569. //---------------------------------------------------------------------------
  1570. void __fastcall TPreferencesDialog::AddCopyParamButtonClick(TObject * /*Sender*/)
  1571. {
  1572. AddEditCopyParam(cpmAdd);
  1573. }
  1574. //---------------------------------------------------------------------------
  1575. void __fastcall TPreferencesDialog::EditCopyParamButtonClick(TObject * /*Sender*/)
  1576. {
  1577. AddEditCopyParam(cpmEdit);
  1578. }
  1579. //---------------------------------------------------------------------------
  1580. void __fastcall TPreferencesDialog::DuplicateCopyParamButtonClick(TObject * /*Sender*/)
  1581. {
  1582. AddEditCopyParam(cpmDuplicate);
  1583. }
  1584. //---------------------------------------------------------------------------
  1585. void __fastcall TPreferencesDialog::CopyParamListViewDblClick(
  1586. TObject * /*Sender*/)
  1587. {
  1588. if (EditCopyParamButton->Enabled)
  1589. {
  1590. AddEditCopyParam(cpmEdit);
  1591. }
  1592. }
  1593. //---------------------------------------------------------------------------
  1594. void __fastcall TPreferencesDialog::CopyParamListViewKeyDown(
  1595. TObject * /*Sender*/, WORD & Key, TShiftState /*Shift*/)
  1596. {
  1597. if (RemoveCopyParamButton->Enabled && (Key == VK_DELETE))
  1598. {
  1599. RemoveCopyParamButtonClick(NULL);
  1600. }
  1601. if (AddCopyParamButton->Enabled && (Key == VK_INSERT))
  1602. {
  1603. AddEditCopyParam(cpmAdd);
  1604. }
  1605. }
  1606. //---------------------------------------------------------------------------
  1607. void __fastcall TPreferencesDialog::EditorMove(int Source, int Dest)
  1608. {
  1609. if (Source >= 0 && Source < FEditorList->Count &&
  1610. Dest >= 0 && Dest < FEditorList->Count)
  1611. {
  1612. FEditorList->Move(Source, Dest);
  1613. // workaround for bug in VCL
  1614. EditorListView3->ItemIndex = -1;
  1615. EditorListView3->ItemFocused = EditorListView3->Selected;
  1616. EditorListView3->ItemIndex = Dest;
  1617. UpdateEditorListView();
  1618. UpdateControls();
  1619. }
  1620. }
  1621. //---------------------------------------------------------------------------
  1622. void __fastcall TPreferencesDialog::EditorListView3DragDrop(TObject * Sender,
  1623. TObject * Source, int X, int Y)
  1624. {
  1625. if (Source == EditorListView3)
  1626. {
  1627. if (AllowListViewDrag(Sender, X, Y))
  1628. {
  1629. EditorMove(FListViewDragSource, FListViewDragDest);
  1630. }
  1631. }
  1632. }
  1633. //---------------------------------------------------------------------------
  1634. void __fastcall TPreferencesDialog::UpDownEditorButtonClick(TObject *Sender)
  1635. {
  1636. EditorMove(EditorListView3->ItemIndex,
  1637. EditorListView3->ItemIndex + (Sender == UpEditorButton ? -1 : 1));
  1638. }
  1639. //---------------------------------------------------------------------------
  1640. void __fastcall TPreferencesDialog::RemoveEditorButtonClick(
  1641. TObject * /*Sender*/)
  1642. {
  1643. DebugAssert(EditorListView3->ItemIndex >= 0 &&
  1644. EditorListView3->ItemIndex < FEditorList->Count);
  1645. FEditorList->Delete(EditorListView3->ItemIndex);
  1646. UpdateEditorListView();
  1647. UpdateControls();
  1648. }
  1649. //---------------------------------------------------------------------------
  1650. void __fastcall TPreferencesDialog::AddEditEditorButtonClick(TObject * Sender)
  1651. {
  1652. TEditorPreferencesMode Mode = (Sender == EditEditorButton ? epmEdit : epmAdd);
  1653. int Index = EditorListView3->ItemIndex;
  1654. TEditorPreferences * Editor;
  1655. if (Mode == epmEdit)
  1656. {
  1657. Editor = new TEditorPreferences(*FEditorList->Editors[Index]);
  1658. }
  1659. else
  1660. {
  1661. Editor = new TEditorPreferences();
  1662. }
  1663. try
  1664. {
  1665. bool DummyRemember = false;
  1666. if (DoEditorPreferencesDialog(Editor->GetData(), DummyRemember, Mode, true))
  1667. {
  1668. if (Mode == epmEdit)
  1669. {
  1670. FEditorList->Change(Index, Editor);
  1671. }
  1672. else
  1673. {
  1674. if (Index < 0)
  1675. {
  1676. Index = FEditorList->Count;
  1677. FEditorList->Add(Editor);
  1678. }
  1679. else
  1680. {
  1681. FEditorList->Insert(Index, Editor);
  1682. }
  1683. }
  1684. // ownership of the object lost
  1685. Editor = NULL;
  1686. UpdateEditorListView();
  1687. EditorListView3->ItemIndex = Index;
  1688. UpdateControls();
  1689. }
  1690. }
  1691. __finally
  1692. {
  1693. delete Editor;
  1694. }
  1695. }
  1696. //---------------------------------------------------------------------------
  1697. void __fastcall TPreferencesDialog::EditorListView3DblClick(TObject * /*Sender*/)
  1698. {
  1699. if (EditEditorButton->Enabled)
  1700. {
  1701. AddEditEditorButtonClick(EditEditorButton);
  1702. }
  1703. }
  1704. //---------------------------------------------------------------------------
  1705. void __fastcall TPreferencesDialog::EditorListView3KeyDown(TObject * /*Sender*/,
  1706. WORD & Key, TShiftState /*Shift*/)
  1707. {
  1708. if (RemoveEditorButton->Enabled && (Key == VK_DELETE))
  1709. {
  1710. RemoveEditorButtonClick(NULL);
  1711. }
  1712. if (AddEditorButton->Enabled && (Key == VK_INSERT))
  1713. {
  1714. AddEditEditorButtonClick(AddEditorButton);
  1715. }
  1716. }
  1717. //---------------------------------------------------------------------------
  1718. void __fastcall TPreferencesDialog::UpdateEditorListView()
  1719. {
  1720. EditorListView3->Items->Count = FEditorList->Count;
  1721. AutoSizeListColumnsWidth(EditorListView3);
  1722. EditorListView3->Invalidate();
  1723. }
  1724. //---------------------------------------------------------------------------
  1725. void __fastcall TPreferencesDialog::EditorListView3Data(TObject * /*Sender*/,
  1726. TListItem * Item)
  1727. {
  1728. // WORKAROUND We get here on Wine after destructor is called
  1729. if (FEditorList != NULL)
  1730. {
  1731. int Index = Item->Index;
  1732. DebugAssert(Index >= 0 && Index <= FEditorList->Count);
  1733. const TEditorPreferences * Editor = FEditorList->Editors[Index];
  1734. Item->Caption = Editor->Name;
  1735. Item->SubItems->Add(Editor->Data->FileMask.Masks);
  1736. if (Editor->Data->Editor == edExternal)
  1737. {
  1738. Item->SubItems->Add(BooleanToStr(Editor->Data->ExternalEditorText));
  1739. }
  1740. }
  1741. }
  1742. //---------------------------------------------------------------------------
  1743. void __fastcall TPreferencesDialog::NavigationTreeChange(TObject * /*Sender*/,
  1744. TTreeNode * Node)
  1745. {
  1746. if (DebugAlwaysTrue(Node->SelectedIndex > 0))
  1747. {
  1748. PageControl->ActivePage = DebugNotNull(FindPageForTreeNode(Node));
  1749. // reshow the accelerators, etc
  1750. ResetSystemSettings(this);
  1751. // This is particularly here to enable EditCopyParamButton,
  1752. // as for some reason CopyParamListView->Selected is NULL until
  1753. // its page is shown for the first time
  1754. UpdateControls();
  1755. }
  1756. }
  1757. //---------------------------------------------------------------------------
  1758. void __fastcall TPreferencesDialog::PageControlChange(TObject * /*Sender*/)
  1759. {
  1760. // this is probably only ever called from FormShow (explicitly)
  1761. bool Found = false;
  1762. if (DebugAlwaysTrue(PageControl->ActivePage->Tag > 0))
  1763. {
  1764. for (int Index = 0; Index < NavigationTree->Items->Count; Index++)
  1765. {
  1766. if (NavigationTree->Items->Item[Index]->SelectedIndex ==
  1767. PageControl->ActivePage->Tag)
  1768. {
  1769. NavigationTree->Items->Item[Index]->Selected = true;
  1770. Found = true;
  1771. }
  1772. }
  1773. }
  1774. if (DebugAlwaysTrue(Found))
  1775. {
  1776. UpdateControls();
  1777. }
  1778. }
  1779. //---------------------------------------------------------------------------
  1780. void __fastcall TPreferencesDialog::CMDialogKey(TWMKeyDown & Message)
  1781. {
  1782. if (Message.CharCode == VK_TAB)
  1783. {
  1784. TShiftState Shift = KeyDataToShiftState(Message.KeyData);
  1785. if (Shift.Contains(ssCtrl))
  1786. {
  1787. TTreeNode * Node = NavigationTree->Selected;
  1788. if (!Shift.Contains(ssShift))
  1789. {
  1790. Node = Node->GetNext();
  1791. if (!Node) Node = NavigationTree->Items->GetFirstNode();
  1792. }
  1793. else
  1794. {
  1795. if (Node->GetPrev()) Node = Node->GetPrev();
  1796. else
  1797. while (Node->GetNext()) Node = Node->GetNext();
  1798. }
  1799. Node->Selected = True;
  1800. Message.Result = 1;
  1801. return;
  1802. }
  1803. }
  1804. TForm::Dispatch(&Message);
  1805. }
  1806. //---------------------------------------------------------------------------
  1807. void __fastcall TPreferencesDialog::WMHelp(TWMHelp & Message)
  1808. {
  1809. DebugAssert(Message.HelpInfo != NULL);
  1810. if (Message.HelpInfo->iContextType == HELPINFO_WINDOW)
  1811. {
  1812. // invoke help for active page (not for whole form), regardless of focus
  1813. // (e.g. even if focus is on control outside pagecontrol)
  1814. Message.HelpInfo->hItemHandle = PageControl->ActivePage->Handle;
  1815. }
  1816. TForm::Dispatch(&Message);
  1817. }
  1818. //---------------------------------------------------------------------------
  1819. void __fastcall TPreferencesDialog::Dispatch(void *Message)
  1820. {
  1821. TMessage * M = reinterpret_cast<TMessage*>(Message);
  1822. DebugAssert(M);
  1823. if (M->Msg == CM_DIALOGKEY)
  1824. {
  1825. CMDialogKey(*((TWMKeyDown *)Message));
  1826. }
  1827. else if (M->Msg == WM_HELP)
  1828. {
  1829. WMHelp(*((TWMHelp *)Message));
  1830. }
  1831. else
  1832. {
  1833. TForm::Dispatch(Message);
  1834. }
  1835. }
  1836. //---------------------------------------------------------------------------
  1837. void __fastcall TPreferencesDialog::RegisterAsUrlHandlersButtonClick(
  1838. TObject * /*Sender*/)
  1839. {
  1840. MenuPopup(RegisterAsUrlHandlerMenu, RegisterAsUrlHandlersButton);
  1841. }
  1842. //---------------------------------------------------------------------------
  1843. void __fastcall TPreferencesDialog::RegisterAsUrlHandlerItemClick(TObject * /*Sender*/)
  1844. {
  1845. unsigned int Result =
  1846. MessageDialog(MainInstructions(LoadStr(CONFIRM_REGISTER_URL2)),
  1847. qtConfirmation, qaYes | qaNo, HELP_REGISTER_URL);
  1848. if (Result == qaYes)
  1849. {
  1850. TInstantOperationVisualizer Visualizer;
  1851. RegisterForDefaultProtocols();
  1852. }
  1853. }
  1854. //---------------------------------------------------------------------------
  1855. void __fastcall TPreferencesDialog::UnregisterForDefaultProtocolsItemClick(TObject * /*Sender*/)
  1856. {
  1857. unsigned int Result =
  1858. MessageDialog(MainInstructions(LoadStr(CONFIRM_UNREGISTER_URL)),
  1859. qtConfirmation, qaYes | qaNo, HELP_REGISTER_URL);
  1860. if (Result == qaYes)
  1861. {
  1862. TInstantOperationVisualizer Visualizer;
  1863. UnregisterForProtocols();
  1864. }
  1865. }
  1866. //---------------------------------------------------------------------------
  1867. void __fastcall TPreferencesDialog::MakeDefaultHandlerItemClick(TObject * /*Sender*/)
  1868. {
  1869. TOperationVisualizer Visualizer;
  1870. LaunchAdvancedAssociationUI();
  1871. }
  1872. //---------------------------------------------------------------------------
  1873. void __fastcall TPreferencesDialog::DDExtLabelClick(TObject * Sender)
  1874. {
  1875. ((Sender == DDExtEnabledLabel) ? DDExtEnabledButton : DDExtDisabledButton)->
  1876. SetFocus();
  1877. }
  1878. //---------------------------------------------------------------------------
  1879. void __fastcall TPreferencesDialog::AddSearchPathButtonClick(
  1880. TObject * /*Sender*/)
  1881. {
  1882. UnicodeString AppPath = ExtractFilePath(Application->ExeName);
  1883. if (MessageDialog(MainInstructions(FMTLOAD(CONFIRM_ADD_SEARCH_PATH, (AppPath))),
  1884. qtConfirmation, qaYes | qaNo, HELP_ADD_SEARCH_PATH) == qaYes)
  1885. {
  1886. TInstantOperationVisualizer Visualizer;
  1887. AddSearchPath(AppPath);
  1888. }
  1889. }
  1890. //---------------------------------------------------------------------------
  1891. void __fastcall TPreferencesDialog::EditorFontLabelDblClick(
  1892. TObject * Sender)
  1893. {
  1894. EditorFontButtonClick(Sender);
  1895. }
  1896. //---------------------------------------------------------------------------
  1897. void __fastcall TPreferencesDialog::UpdateCopyParamListView()
  1898. {
  1899. CopyParamListView->Items->Count = 1 + FCopyParamList->Count;
  1900. AutoSizeListColumnsWidth(CopyParamListView);
  1901. CopyParamListView->Invalidate();
  1902. }
  1903. //---------------------------------------------------------------------------
  1904. void __fastcall TPreferencesDialog::CopyParamListViewData(TObject * /*Sender*/,
  1905. TListItem * Item)
  1906. {
  1907. // WORKAROUND We get here on Wine after destructor is called
  1908. if (FCopyParamList != NULL)
  1909. {
  1910. UnicodeString Name;
  1911. UnicodeString Rule;
  1912. int Index = Item->Index;
  1913. if (Index == 0)
  1914. {
  1915. Name = StripHotkey(LoadStr(COPY_PARAM_DEFAULT));
  1916. }
  1917. else
  1918. {
  1919. DebugAssert(Index >= 1 && Index <= 1 + FCopyParamList->Count);
  1920. Name = StripHotkey(FCopyParamList->Names[Index - 1]);
  1921. Rule = BooleanToStr(FCopyParamList->Rules[Index - 1] != NULL);
  1922. }
  1923. Item->Caption = Name;
  1924. Item->SubItems->Add(Rule);
  1925. }
  1926. }
  1927. //---------------------------------------------------------------------------
  1928. void __fastcall TPreferencesDialog::HelpButtonClick(TObject * /*Sender*/)
  1929. {
  1930. FormHelp(this);
  1931. }
  1932. //---------------------------------------------------------------------------
  1933. void __fastcall TPreferencesDialog::PuttyPathBrowseButtonClick(
  1934. TObject * /*Sender*/)
  1935. {
  1936. UnicodeString Executables = FORMAT("%s;%s", (OriginalPuttyExecutable, KittyExecutable));
  1937. BrowseForExecutable(PuttyPathEdit, LoadStr(PREFERENCES_SELECT_PUTTY2),
  1938. FMTLOAD(PREFERENCES_PUTTY_FILTER2, (Executables)), false, false);
  1939. }
  1940. //---------------------------------------------------------------------------
  1941. void __fastcall TPreferencesDialog::PathEditBeforeDialog(
  1942. TObject * /*Sender*/, UnicodeString & Name, bool & /*Action*/)
  1943. {
  1944. FBeforeDialogPath = Name;
  1945. Name = ExpandEnvironmentVariables(Name);
  1946. }
  1947. //---------------------------------------------------------------------------
  1948. void __fastcall TPreferencesDialog::PathEditAfterDialog(
  1949. TObject * /*Sender*/, UnicodeString & Name, bool & /*Action*/)
  1950. {
  1951. if (CompareFileName(Name, ExpandEnvironmentVariables(FBeforeDialogPath)))
  1952. {
  1953. Name = FBeforeDialogPath;
  1954. }
  1955. }
  1956. //---------------------------------------------------------------------------
  1957. void __fastcall TPreferencesDialog::NavigationTreeCollapsing(
  1958. TObject * /*Sender*/, TTreeNode * /*Node*/, bool & AllowCollapse)
  1959. {
  1960. AllowCollapse = false;
  1961. }
  1962. //---------------------------------------------------------------------------
  1963. void __fastcall TPreferencesDialog::ListViewEndDrag(
  1964. TObject * Sender, TObject * /*Target*/, int /*X*/, int /*Y*/)
  1965. {
  1966. ScrollOnDragOver(Sender)->EndDrag();
  1967. }
  1968. //---------------------------------------------------------------------------
  1969. void __fastcall TPreferencesDialog::SessionReopenTimeoutEditSetValue(
  1970. TObject * /*Sender*/, Extended Value, UnicodeString & Text, bool & Handled)
  1971. {
  1972. if (Value == 0)
  1973. {
  1974. Text = LoadStr(PREFERENCES_RECONNECT_TIMEOUT_UNLIMITED);
  1975. Handled = true;
  1976. }
  1977. }
  1978. //---------------------------------------------------------------------------
  1979. void __fastcall TPreferencesDialog::SessionReopenTimeoutEditGetValue(
  1980. TObject * /*Sender*/, UnicodeString Text, Extended & Value, bool & Handled)
  1981. {
  1982. if (AnsiSameText(Text, LoadStr(PREFERENCES_RECONNECT_TIMEOUT_UNLIMITED)))
  1983. {
  1984. Value = 0;
  1985. Handled = true;
  1986. }
  1987. }
  1988. //---------------------------------------------------------------------------
  1989. bool __fastcall TPreferencesDialog::CanSetMasterPassword()
  1990. {
  1991. bool Result;
  1992. bool Retry;
  1993. do
  1994. {
  1995. Retry = false;
  1996. Result = !AnyOtherInstanceOfSelf();
  1997. if (!Result)
  1998. {
  1999. unsigned int Answer =
  2000. MessageDialog(
  2001. LoadStr(MASTER_PASSWORD_OTHER_INSTANCE),
  2002. qtConfirmation, qaRetry | qaIgnore | qaCancel,
  2003. HELP_MASTER_PASSWORD);
  2004. switch (Answer)
  2005. {
  2006. case qaRetry:
  2007. Retry = true;
  2008. break;
  2009. case qaIgnore:
  2010. Result = true;
  2011. break;
  2012. case qaCancel:
  2013. default:
  2014. // noop
  2015. break;
  2016. }
  2017. }
  2018. }
  2019. while (Retry && !Result);
  2020. return Result;
  2021. }
  2022. //---------------------------------------------------------------------------
  2023. void __fastcall TPreferencesDialog::MasterPasswordChanged(
  2024. UnicodeString Message, TStrings * RecryptPasswordErrors)
  2025. {
  2026. // Save master password.
  2027. // This is unlikely to fail, as storage is written explicitly already
  2028. // when writing the recrypted passwords
  2029. Configuration->SaveExplicit();
  2030. TQueryType QueryType = qtInformation;
  2031. if (RecryptPasswordErrors->Count > 0)
  2032. {
  2033. Message = FMTLOAD(MASTER_PASSWORD_RECRYPT_ERRORS, (Message));
  2034. QueryType = qtWarning;
  2035. }
  2036. MoreMessageDialog(
  2037. Message, RecryptPasswordErrors, QueryType, qaOK, HELP_MASTER_PASSWORD);
  2038. }
  2039. //---------------------------------------------------------------------------
  2040. void __fastcall TPreferencesDialog::ChangeMasterPassword(UnicodeString Message)
  2041. {
  2042. UnicodeString NewPassword;
  2043. if (DoChangeMasterPasswordDialog(NewPassword))
  2044. {
  2045. std::unique_ptr<TStrings> RecryptPasswordErrors(new TStringList());
  2046. WinConfiguration->ChangeMasterPassword(NewPassword, RecryptPasswordErrors.get());
  2047. MasterPasswordChanged(Message, RecryptPasswordErrors.get());
  2048. }
  2049. }
  2050. //---------------------------------------------------------------------------
  2051. void __fastcall TPreferencesDialog::UseMasterPasswordCheckClick(
  2052. TObject * /*Sender*/)
  2053. {
  2054. if (UseMasterPasswordCheck->Checked != WinConfiguration->UseMasterPassword)
  2055. {
  2056. try
  2057. {
  2058. if (CanSetMasterPassword())
  2059. {
  2060. if (UseMasterPasswordCheck->Checked)
  2061. {
  2062. ChangeMasterPassword(LoadStr(MASTER_PASSWORD_SET2));
  2063. }
  2064. else
  2065. {
  2066. if (DoMasterPasswordDialog())
  2067. {
  2068. std::unique_ptr<TStrings> RecryptPasswordErrors(new TStringList());
  2069. WinConfiguration->ClearMasterPassword(RecryptPasswordErrors.get());
  2070. MasterPasswordChanged(LoadStr(MASTER_PASSWORD_CLEARED2), RecryptPasswordErrors.get());
  2071. }
  2072. }
  2073. }
  2074. }
  2075. __finally
  2076. {
  2077. UseMasterPasswordCheck->Checked = WinConfiguration->UseMasterPassword;
  2078. UpdateControls();
  2079. }
  2080. }
  2081. }
  2082. //---------------------------------------------------------------------------
  2083. void __fastcall TPreferencesDialog::SetMasterPasswordButtonClick(
  2084. TObject * /*Sender*/)
  2085. {
  2086. if (CanSetMasterPassword())
  2087. {
  2088. ChangeMasterPassword(MainInstructions(LoadStr(MASTER_PASSWORD_CHANGED)));
  2089. }
  2090. }
  2091. //---------------------------------------------------------------------------
  2092. void __fastcall TPreferencesDialog::UsageViewButtonClick(TObject * /*Sender*/)
  2093. {
  2094. std::unique_ptr<TStrings> Data(TextToStringList(GetUsageData()));
  2095. UnicodeString Message =
  2096. Data->Text.IsEmpty() ? MainInstructions(LoadStr(USAGE_DATA_NONE)) : LoadStr(USAGE_DATA2);
  2097. MoreMessageDialog(Message, Data.get(), qtInformation, qaOK, HELP_USAGE);
  2098. }
  2099. //---------------------------------------------------------------------------
  2100. void __fastcall TPreferencesDialog::CopyParamLabelClick(TObject * /*Sender*/)
  2101. {
  2102. if (EditCopyParamButton->Enabled)
  2103. {
  2104. AddEditCopyParam(cpmEdit);
  2105. }
  2106. }
  2107. //---------------------------------------------------------------------------
  2108. void __fastcall TPreferencesDialog::CopyParamListViewCustomDrawItem(
  2109. TCustomListView * Sender, TListItem * Item,
  2110. TCustomDrawState /*State*/, bool & /*DefaultDraw*/)
  2111. {
  2112. if (Item->Index == 0)
  2113. {
  2114. Sender->Canvas->Font->Style = Sender->Canvas->Font->Style << fsBold;
  2115. }
  2116. }
  2117. //---------------------------------------------------------------------------
  2118. void __fastcall TPreferencesDialog::SelectPuttyRegistryStorageKey(const UnicodeString & Key)
  2119. {
  2120. PuttyRegistryStorageKeyEdit->ItemIndex =
  2121. PuttyRegistryStorageKeyEdit->Items->IndexOf(Key);
  2122. }
  2123. //---------------------------------------------------------------------------
  2124. void __fastcall TPreferencesDialog::PuttyPathEditChange(TObject * /*Sender*/)
  2125. {
  2126. UnicodeString PuttyPath = PuttyPathEdit->Text;
  2127. if (ContainsText(PuttyPath, OriginalPuttyExecutable))
  2128. {
  2129. SelectPuttyRegistryStorageKey(OriginalPuttyRegistryStorageKey);
  2130. }
  2131. else if (ContainsText(PuttyPath, KittyExecutable))
  2132. {
  2133. SelectPuttyRegistryStorageKey(KittyRegistryStorageKey);
  2134. }
  2135. UpdateControls();
  2136. }
  2137. //---------------------------------------------------------------------------
  2138. void __fastcall TPreferencesDialog::NavigationTreeChanging(TObject * /*Sender*/,
  2139. TTreeNode * Node, bool & /*AllowChange*/)
  2140. {
  2141. TTabSheet * Sheet = FindPageForTreeNode(Node);
  2142. // delay load as this can be time consuming
  2143. if (Sheet == LanguagesSheet)
  2144. {
  2145. LoadLanguages();
  2146. }
  2147. }
  2148. //---------------------------------------------------------------------------
  2149. void __fastcall TPreferencesDialog::LanguagesGetMoreButtonClick(TObject * /*Sender*/)
  2150. {
  2151. OpenBrowser(ProgramUrl(LoadStr(LOCALES_URL)));
  2152. }
  2153. //---------------------------------------------------------------------------
  2154. void __fastcall TPreferencesDialog::CommanderClick(TObject * /*Sender*/)
  2155. {
  2156. CommanderInterfaceButton2->SetFocus();
  2157. }
  2158. //---------------------------------------------------------------------------
  2159. void __fastcall TPreferencesDialog::ExplorerClick(TObject * /*Sender*/)
  2160. {
  2161. ExplorerInterfaceButton2->SetFocus();
  2162. }
  2163. //---------------------------------------------------------------------------
  2164. void __fastcall TPreferencesDialog::PanelFontLabelDblClick(TObject * Sender)
  2165. {
  2166. PanelFontButtonClick(Sender);
  2167. }
  2168. //---------------------------------------------------------------------------
  2169. void __fastcall TPreferencesDialog::UpdatesAuthenticationEmailEditExit(TObject * /*Sender*/)
  2170. {
  2171. if (FVerifiedUpdatesAuthenticationEmail != UpdatesAuthenticationEmailEdit->Text)
  2172. {
  2173. FVerifiedUpdatesAuthenticationEmail = UpdatesAuthenticationEmailEdit->Text;
  2174. if (!FVerifiedUpdatesAuthenticationEmail.IsEmpty())
  2175. {
  2176. TUpdatesConfiguration Updates = SaveUpdates();
  2177. {
  2178. TInstantOperationVisualizer Visualizer;
  2179. QueryUpdates(Updates);
  2180. }
  2181. UnicodeString AuthenticationError = Updates.Results.AuthenticationError;
  2182. if (!AuthenticationError.IsEmpty())
  2183. {
  2184. AuthenticationError = FormatUpdatesMessage(AuthenticationError);
  2185. if (HasParagraphs(AuthenticationError))
  2186. {
  2187. AuthenticationError = MainInstructionsFirstParagraph(AuthenticationError);
  2188. }
  2189. else
  2190. {
  2191. AuthenticationError = MainInstructions(AuthenticationError);
  2192. }
  2193. UnicodeString HelpUrl = GetEnableAutomaticUpdatesUrl();
  2194. unsigned int Result =
  2195. MoreMessageDialog(AuthenticationError, NULL, qtError, qaIgnore | qaAbort, HelpUrl);
  2196. if (Result == qaAbort)
  2197. {
  2198. Abort();
  2199. }
  2200. }
  2201. }
  2202. }
  2203. }
  2204. //---------------------------------------------------------------------------
  2205. void __fastcall TPreferencesDialog::UpdatesLinkClick(TObject * /*Sender*/)
  2206. {
  2207. EnableAutomaticUpdates();
  2208. }
  2209. //---------------------------------------------------------------------------
  2210. void __fastcall TPreferencesDialog::CustomCommandsViewWindowProc(TMessage & Message)
  2211. {
  2212. FOrigCustomCommandsViewWindowProc(Message);
  2213. if (Message.Msg == CN_NOTIFY)
  2214. {
  2215. TWMNotify & NotifyMessage = reinterpret_cast<TWMNotify &>(Message);
  2216. if (NotifyMessage.NMHdr->code == NM_CUSTOMDRAW)
  2217. {
  2218. // request CDDS_ITEMPOSTPAINT notification
  2219. Message.Result |= CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYSUBITEMDRAW;
  2220. TNMLVCustomDraw * CustomDraw = reinterpret_cast<TNMLVCustomDraw *>(NotifyMessage.NMHdr);
  2221. int Index = CustomDraw->nmcd.dwItemSpec;
  2222. int CommandIndex = GetCommandIndex(Index);
  2223. TCustomCommandList * List = GetCommandList(Index);
  2224. // after end of every list, except for the last last list
  2225. if ((CommandIndex == List->Count - 1) && (Index < CustomCommandsView->Items->Count - 1) &&
  2226. FLAGSET(CustomDraw->nmcd.dwDrawStage, CDDS_ITEMPOSTPAINT))
  2227. {
  2228. TRect Rect;
  2229. Rect.Top = CustomDraw->iSubItem;
  2230. Rect.Left = LVIR_BOUNDS;
  2231. CustomCommandsView->Perform(LVM_GETSUBITEMRECT, CustomDraw->nmcd.dwItemSpec, reinterpret_cast<LPARAM>(&Rect));
  2232. HDC DC = CustomDraw->nmcd.hdc;
  2233. SelectObject(DC, GetStockObject(DC_PEN));
  2234. SetDCPenColor(DC, ColorToRGB(clWindowFrame));
  2235. MoveToEx(DC, Rect.Left, Rect.Bottom - 1, NULL);
  2236. LineTo(DC, Rect.Right, Rect.Bottom - 1);
  2237. }
  2238. }
  2239. }
  2240. }
  2241. //---------------------------------------------------------------------------
  2242. void __fastcall TPreferencesDialog::AddExtension()
  2243. {
  2244. const UnicodeString HistoryKey(L"ExtensionPath");
  2245. std::unique_ptr<TStrings> History(CloneStrings(CustomWinConfiguration->History[HistoryKey]));
  2246. UnicodeString Path;
  2247. if (InputDialog(LoadStr(ADD_EXTENSION_CAPTION), LoadStr(ADD_EXTENSION_PROMPT), Path,
  2248. HELP_NONE, History.get(), true) &&
  2249. !Path.IsEmpty())
  2250. {
  2251. CustomWinConfiguration->History[HistoryKey] = History.get();
  2252. bool Trusted;
  2253. bool Latest;
  2254. UnicodeString FileName;
  2255. UnicodeString ExtensionPath;
  2256. std::unique_ptr<TStringList> Lines(new TStringList());
  2257. std::unique_ptr<TCustomCommandType> CustomCommand;
  2258. bool IsUrl = IsHttpOrHttpsUrl(Path);
  2259. try
  2260. {
  2261. if (IsUrl)
  2262. {
  2263. UnicodeString Url = Path;
  2264. Url = SecureUrl(Url);
  2265. bool WinSCPURL = IsWinSCPUrl(Url);
  2266. if (WinSCPURL)
  2267. {
  2268. Url = ProgramUrl(Url);
  2269. // The EncodeUrlString should not be necessary, but as we get the value from regitry, let's be safe
  2270. Url = AppendUrlParams(Url, FORMAT(L"netframework=%s", (EncodeUrlString(GetNetVersionStr()))));
  2271. Url = AppendUrlParams(Url, FORMAT(L"powershell=%s", (EncodeUrlString(GetPowerShellVersionStr()))));
  2272. Url = AppendUrlParams(Url, FORMAT(L"windows=%s", (EncodeUrlString(WindowsVersion()))));
  2273. Url = CampaignUrl(Url);
  2274. }
  2275. TOperationVisualizer Visualizer;
  2276. std::unique_ptr<THttp> Http(CreateHttp());
  2277. Http->URL = Url;
  2278. std::unique_ptr<TStrings> Headers(new TStringList());
  2279. Headers->Values[L"Accept"] = L"text/winscpextension,text/plain";
  2280. Http->RequestHeaders = Headers.get();
  2281. Http->Get();
  2282. UnicodeString TrustedStr = Http->ResponseHeaders->Values["WinSCP-Extension-Trusted"];
  2283. Trusted = WinSCPURL && (StrToIntDef(TrustedStr, 0) != 0);
  2284. FileName = MakeValidFileName(Http->ResponseHeaders->Values["WinSCP-Extension-Id"]);
  2285. if (FileName.IsEmpty())
  2286. {
  2287. FileName = MakeValidFileName(ExtractFileNameFromUrl(Path));
  2288. }
  2289. Lines->Text = Http->Response;
  2290. Latest = Http->ResponseHeaders->Values["WinSCP-Extension-Skipped"].Trim().IsEmpty();
  2291. }
  2292. else
  2293. {
  2294. if (!FileExists(ApiPath(Path)))
  2295. {
  2296. throw Exception(MainInstructions(FMTLOAD(FILE_NOT_EXISTS, (Path))));
  2297. }
  2298. Trusted = true;
  2299. Latest = true;
  2300. UnicodeString Id = WinConfiguration->GetExtensionId(Path);
  2301. FileName = ExtractFileName(Path);
  2302. if (!Id.IsEmpty())
  2303. {
  2304. ExtensionPath = Path;
  2305. }
  2306. LoadScriptFromFile(Path, Lines.get());
  2307. }
  2308. // validate syntax
  2309. CustomCommand.reset(new TCustomCommandType());
  2310. CustomCommand->LoadExtension(Lines.get(), FileName);
  2311. }
  2312. catch (Exception & E)
  2313. {
  2314. throw ExtException(&E, MainInstructions(FMTLOAD(EXTENSION_LOAD_ERROR, (Path))));
  2315. }
  2316. if (!ExtensionPath.IsEmpty())
  2317. {
  2318. int Index = FExtensionList->FindIndexByFileName(Path);
  2319. if (Index > 0)
  2320. {
  2321. CustomCommandsView->ItemIndex = GetCommandListIndex(FExtensionList, Index);
  2322. CustomCommandsView->ItemFocused->MakeVisible(false);
  2323. CustomCommandsView->SetFocus();
  2324. throw Exception(MainInstructions(LoadStr(EXTENSION_INSTALLED_ALREADY)));
  2325. }
  2326. }
  2327. if (FExtensionList->Find(CustomCommand->Name) != NULL)
  2328. {
  2329. throw Exception(MainInstructions(FMTLOAD(EXTENSION_DUPLICATE, (StripHotkey(CustomCommand->Name)))));
  2330. }
  2331. if (ExtensionPath.IsEmpty())
  2332. {
  2333. if (TCustomCommandType::GetExtensionId(FileName).IsEmpty())
  2334. {
  2335. UnicodeString FileNameOnly = ExtractFileNameOnly(FileName);
  2336. if (FileNameOnly.IsEmpty())
  2337. {
  2338. FileName = MakeValidFileName(StripHotkey(CustomCommand->Name)) + WinSCPExtensionExt;
  2339. }
  2340. else
  2341. {
  2342. FileName = ExtractFileNameOnly(FileName) + WinSCPExtensionExt + ExtractFileExt(FileName);
  2343. }
  2344. }
  2345. }
  2346. if (Trusted ||
  2347. (MessageDialog(MainInstructions(LoadStr(EXTENSION_UNTRUSTED)), qtWarning, qaOK | qaCancel) == qaOK))
  2348. {
  2349. if (ExtensionPath.IsEmpty())
  2350. {
  2351. UnicodeString UserExtensionsPath = WinConfiguration->GetUserExtensionsPath();
  2352. if (!DirectoryExists(UserExtensionsPath) &&
  2353. !ForceDirectories(UserExtensionsPath))
  2354. {
  2355. throw EOSExtException(MainInstructions(FMTLOAD(CREATE_LOCAL_DIR_ERROR, (UserExtensionsPath))));
  2356. }
  2357. ExtensionPath = IncludeTrailingBackslash(UserExtensionsPath) + FileName;
  2358. int Counter = 1;
  2359. UnicodeString OriginalExtensionPath = ExtensionPath;
  2360. int P = Pos(UpperCase(WinSCPExtensionExt), UpperCase(OriginalExtensionPath));
  2361. while (FileExists(ApiPath(ExtensionPath)))
  2362. {
  2363. Counter++;
  2364. ExtensionPath = LeftStr(OriginalExtensionPath, P - 1) + IntToStr(Counter) + RightStr(OriginalExtensionPath, OriginalExtensionPath.Length() - P + 1);
  2365. }
  2366. Lines->SaveToFile(ApiPath(ExtensionPath));
  2367. FAddedExtensions->Add(ExtensionPath);
  2368. }
  2369. int Index = GetListCommandIndex(FExtensionList);
  2370. std::unique_ptr<TCustomCommandType> CustomCommand(new TCustomCommandType());
  2371. CustomCommand->Id = WinConfiguration->GetExtensionId(ExtensionPath);
  2372. CustomCommand->LoadExtension(ExtensionPath);
  2373. Index = AddCommandToList(FExtensionList, Index, CustomCommand.release());
  2374. UpdateCustomCommandsView();
  2375. CustomCommandsView->ItemIndex = GetCommandListIndex(FExtensionList, Index);
  2376. CustomCommandsView->ItemFocused->MakeVisible(false);
  2377. UpdateControls();
  2378. if (!Latest)
  2379. {
  2380. MessageDialog(LoadStr(EXTENSION_NOT_LATEST), qtInformation, qaOK);
  2381. }
  2382. if (IsUrl)
  2383. {
  2384. Configuration->Usage->Inc(L"ExtensionAddsFromUrl");
  2385. }
  2386. else
  2387. {
  2388. Configuration->Usage->Inc(L"ExtensionAddsFromFile");
  2389. }
  2390. }
  2391. }
  2392. }
  2393. //---------------------------------------------------------------------------
  2394. void __fastcall TPreferencesDialog::AddCommandButtonClick(TObject * /*Sender*/)
  2395. {
  2396. if (GetCommandList(CustomCommandsView->ItemIndex) == FCustomCommandList)
  2397. {
  2398. AddEditCommand(false);
  2399. }
  2400. else
  2401. {
  2402. AddExtension();
  2403. }
  2404. }
  2405. //---------------------------------------------------------------------------
  2406. void __fastcall TPreferencesDialog::AddCustomCommandMenuItemClick(TObject * /*Sender*/)
  2407. {
  2408. AddEditCommand(false);
  2409. }
  2410. //---------------------------------------------------------------------------
  2411. void __fastcall TPreferencesDialog::AddExtensionMenuItemClick(TObject * /*Sender*/)
  2412. {
  2413. AddExtension();
  2414. }
  2415. //---------------------------------------------------------------------------
  2416. void __fastcall TPreferencesDialog::EditCommandButtonClick(TObject * /*Sender*/)
  2417. {
  2418. AddEditCommand(true);
  2419. }
  2420. //---------------------------------------------------------------------------
  2421. void __fastcall TPreferencesDialog::AddCommandButtonDropDownClick(TObject * /*Sender*/)
  2422. {
  2423. AddCustomCommandMenuItem->Default = (GetCommandList(CustomCommandsView->ItemIndex) == FCustomCommandList);
  2424. AddExtensionMenuItem->Default = (GetCommandList(CustomCommandsView->ItemIndex) == FExtensionList);
  2425. MenuPopup(AddCommandMenu, AddCommandButton);
  2426. }
  2427. //---------------------------------------------------------------------------
  2428. void __fastcall TPreferencesDialog::CustomCommandsViewMouseMove(TObject * /*Sender*/, TShiftState /*Shift*/, int X, int Y)
  2429. {
  2430. TListItem * Item = CustomCommandsView->GetItemAt(X, Y);
  2431. int Index = (Item != NULL) ? Item->Index : -1;
  2432. if (Index != FCustomCommandsHintItem)
  2433. {
  2434. Application->CancelHint();
  2435. UnicodeString Hint;
  2436. if (Index >= 0)
  2437. {
  2438. TCustomCommandList * List = GetCommandList(Index);
  2439. const TCustomCommandType * Command = List->Commands[GetCommandIndex(Index)];
  2440. Hint = StripHotkey(Command->Name);
  2441. if (Command->ShortCut != 0)
  2442. {
  2443. Hint = FORMAT(L"%s (%s)", (Hint, ShortCutToText(Command->ShortCut)));
  2444. }
  2445. if (!Command->Description.IsEmpty())
  2446. {
  2447. Hint += L"\n" + Command->Description;
  2448. }
  2449. Hint += L"\n" + Command->GetCommandWithExpandedOptions(FCustomCommandOptions.get());
  2450. if (List == FExtensionList)
  2451. {
  2452. Hint += L"\n" + Command->FileName;
  2453. }
  2454. }
  2455. CustomCommandsView->Hint = Hint;
  2456. FCustomCommandsHintItem = Index;
  2457. }
  2458. }
  2459. //---------------------------------------------------------------------------
  2460. void __fastcall TPreferencesDialog::BackgroundConfirmationsLinkClick(TObject * /*Sender*/)
  2461. {
  2462. PageControl->ActivePage = QueueSheet;
  2463. PageControlChange(NULL);
  2464. QueueNoConfirmationCheck->SetFocus();
  2465. QueueNoConfirmationCheck->Perform(WM_CHANGEUISTATE, MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
  2466. }
  2467. //---------------------------------------------------------------------------
  2468. void __fastcall TPreferencesDialog::ConfigureCommandButtonClick(TObject * /*Sender*/)
  2469. {
  2470. ConfigureCommand();
  2471. }
  2472. //---------------------------------------------------------------------------
  2473. void __fastcall TPreferencesDialog::ConfigureCommand()
  2474. {
  2475. int Index = CustomCommandsView->ItemIndex;
  2476. const TCustomCommandType * Command = GetCommandList(Index)->Commands[GetCommandIndex(Index)];
  2477. DoCustomCommandOptionsDialog(Command, FCustomCommandOptions.get(), TCustomCommandType::ofConfig, NULL);
  2478. UpdateCustomCommandsView();
  2479. }
  2480. //---------------------------------------------------------------------------
  2481. void __fastcall TPreferencesDialog::LanguagesViewCustomDrawItem(
  2482. TCustomListView * Sender, TListItem * Item, TCustomDrawState /*State*/, bool & /*DefaultDraw*/)
  2483. {
  2484. TLocaleInfo * LocaleInfo = static_cast<TLocaleInfo *>(Item->Data);
  2485. if (LocaleInfo->Locale == WinConfiguration->DefaultLocale)
  2486. {
  2487. Sender->Canvas->Font->Style = Sender->Canvas->Font->Style << fsBold;
  2488. }
  2489. if (LocaleInfo->Completeness < 0)
  2490. {
  2491. Sender->Canvas->Font->Color = clRed;
  2492. }
  2493. else if (LocaleInfo->Completeness < 100)
  2494. {
  2495. Sender->Canvas->Font->Color = clGrayText;
  2496. }
  2497. }
  2498. //---------------------------------------------------------------------------