UserInterface.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "ScpCommander.h"
  5. #include "ScpExplorer.h"
  6. #include <CoreMain.h>
  7. #include <Common.h>
  8. #include <Exceptions.h>
  9. #include <Cryptography.h>
  10. #include "ProgParams.h"
  11. #include "VCLCommon.h"
  12. #include "WinConfiguration.h"
  13. #include "TerminalManager.h"
  14. #include "TextsWin.h"
  15. #include "TBXThemes.hpp"
  16. #include "TBXOfficeXPTheme.hpp"
  17. #include "TBXOffice2003Theme.hpp"
  18. #include "PasswordEdit.hpp"
  19. #include "ProgParams.h"
  20. #include "Tools.h"
  21. #include "Custom.h"
  22. #include "HelpWin.h"
  23. #include <Math.hpp>
  24. #include <GUITools.h>
  25. //---------------------------------------------------------------------------
  26. #pragma package(smart_init)
  27. //---------------------------------------------------------------------------
  28. const UnicodeString AppName = L"WinSCP";
  29. //---------------------------------------------------------------------------
  30. TConfiguration * __fastcall CreateConfiguration()
  31. {
  32. TConfiguration * Configuration = new TWinConfiguration();
  33. TProgramParams * Params = TProgramParams::Instance();
  34. UnicodeString IniFileName = Params->SwitchValue(L"ini");
  35. if (!IniFileName.IsEmpty())
  36. {
  37. if (AnsiSameText(IniFileName, L"nul"))
  38. {
  39. Configuration->SetNulStorage();
  40. }
  41. else
  42. {
  43. IniFileName = ExpandFileName(ExpandEnvironmentVariables(IniFileName));
  44. Configuration->IniFileStorageName = IniFileName;
  45. }
  46. }
  47. return Configuration;
  48. }
  49. //---------------------------------------------------------------------------
  50. TCustomScpExplorerForm * __fastcall CreateScpExplorer()
  51. {
  52. TCustomScpExplorerForm * ScpExplorer;
  53. if (WinConfiguration->Interface == ifExplorer)
  54. {
  55. ScpExplorer = SafeFormCreate<TScpExplorerForm>();
  56. }
  57. else
  58. {
  59. ScpExplorer = SafeFormCreate<TScpCommanderForm>();
  60. }
  61. return ScpExplorer;
  62. }
  63. //---------------------------------------------------------------------------
  64. UnicodeString __fastcall SshVersionString()
  65. {
  66. return FORMAT(L"WinSCP-release-%s", (Configuration->Version));
  67. }
  68. //---------------------------------------------------------------------------
  69. UnicodeString __fastcall AppNameString()
  70. {
  71. return L"WinSCP";
  72. }
  73. //---------------------------------------------------------------------------
  74. UnicodeString __fastcall GetCompanyRegistryKey()
  75. {
  76. return L"Software\\Martin Prikryl";
  77. }
  78. //---------------------------------------------------------------------------
  79. UnicodeString __fastcall GetRegistryKey()
  80. {
  81. return GetCompanyRegistryKey() + L"\\WinSCP 2";
  82. }
  83. //---------------------------------------------------------------------------
  84. static bool ForcedOnForeground = false;
  85. void __fastcall SetOnForeground(bool OnForeground)
  86. {
  87. ForcedOnForeground = OnForeground;
  88. }
  89. //---------------------------------------------------------------------------
  90. void __fastcall FlashOnBackground()
  91. {
  92. assert(Application);
  93. if (!ForcedOnForeground && !ForegroundTask())
  94. {
  95. FlashWindow(Application->MainFormHandle, true);
  96. }
  97. }
  98. //---------------------------------------------------------------------------
  99. void __fastcall LocalSystemSettings(TCustomForm * /*Control*/)
  100. {
  101. // noop
  102. }
  103. //---------------------------------------------------------------------------
  104. void __fastcall ShowExtendedException(Exception * E)
  105. {
  106. ShowExtendedExceptionEx(NULL, E);
  107. }
  108. //---------------------------------------------------------------------------
  109. void __fastcall ShowExtendedExceptionEx(TTerminal * Terminal,
  110. Exception * E)
  111. {
  112. bool Show = ShouldDisplayException(E);
  113. TTerminalManager * Manager = TTerminalManager::Instance(false);
  114. TQueryType Type;
  115. ESshTerminate * Terminate = dynamic_cast<ESshTerminate*>(E);
  116. bool CloseOnCompletion = (Terminate != NULL);
  117. Type = CloseOnCompletion ? qtInformation : qtError;
  118. bool ConfirmExitOnCompletion =
  119. CloseOnCompletion &&
  120. (Terminate->Operation == odoDisconnect) &&
  121. WinConfiguration->ConfirmExitOnCompletion;
  122. if (E->InheritsFrom(__classid(EFatal)) && (Terminal != NULL) &&
  123. (Manager != NULL) && (Manager->ActiveTerminal == Terminal))
  124. {
  125. if (CloseOnCompletion)
  126. {
  127. Manager->DisconnectActiveTerminal();
  128. }
  129. int SessionReopenTimeout = 0;
  130. TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
  131. if ((ManagedTerminal != NULL) &&
  132. ((Configuration->SessionReopenTimeout == 0) ||
  133. ((double)ManagedTerminal->ReopenStart == 0) ||
  134. (int(double(Now() - ManagedTerminal->ReopenStart) * MSecsPerDay) < Configuration->SessionReopenTimeout)))
  135. {
  136. SessionReopenTimeout = GUIConfiguration->SessionReopenAutoIdle;
  137. }
  138. unsigned int Result;
  139. if (CloseOnCompletion)
  140. {
  141. assert(Show);
  142. if (ConfirmExitOnCompletion)
  143. {
  144. TMessageParams Params(mpNeverAskAgainCheck);
  145. UnicodeString MessageFormat =
  146. MainInstructions((Manager->Count > 1) ?
  147. FMTLOAD(DISCONNECT_ON_COMPLETION, (Manager->Count - 1)) :
  148. LoadStr(EXIT_ON_COMPLETION));
  149. Result = FatalExceptionMessageDialog(E, Type, 0,
  150. MessageFormat,
  151. qaYes | qaNo, HELP_NONE, &Params);
  152. if (Result == qaNeverAskAgain)
  153. {
  154. Result = qaYes;
  155. WinConfiguration->ConfirmExitOnCompletion = false;
  156. }
  157. }
  158. else
  159. {
  160. Result = qaYes;
  161. }
  162. }
  163. else
  164. {
  165. if (Show)
  166. {
  167. Result = FatalExceptionMessageDialog(E, Type, SessionReopenTimeout);
  168. }
  169. else
  170. {
  171. Result = qaOK;
  172. }
  173. }
  174. if (Result == qaYes)
  175. {
  176. assert(Terminate != NULL);
  177. assert(Terminate->Operation != odoIdle);
  178. Application->Terminate();
  179. switch (Terminate->Operation)
  180. {
  181. case odoDisconnect:
  182. break;
  183. case odoShutDown:
  184. ShutDownWindows();
  185. break;
  186. default:
  187. assert(false);
  188. }
  189. }
  190. else if (Result == qaRetry)
  191. {
  192. Manager->ReconnectActiveTerminal();
  193. }
  194. else
  195. {
  196. Manager->FreeActiveTerminal();
  197. }
  198. }
  199. else
  200. {
  201. // this should not happen as we never use Terminal->CloseOnCompletion
  202. // on inactive terminal
  203. if (CloseOnCompletion)
  204. {
  205. assert(Show);
  206. if (ConfirmExitOnCompletion)
  207. {
  208. TMessageParams Params(mpNeverAskAgainCheck);
  209. if (ExceptionMessageDialog(E, Type, L"", qaOK, HELP_NONE, &Params) ==
  210. qaNeverAskAgain)
  211. {
  212. WinConfiguration->ConfirmExitOnCompletion = false;
  213. }
  214. }
  215. }
  216. else
  217. {
  218. if (Show)
  219. {
  220. ExceptionMessageDialog(E, Type);
  221. }
  222. }
  223. }
  224. }
  225. //---------------------------------------------------------------------------
  226. void __fastcall ShowNotification(TTerminal * Terminal, const UnicodeString & Str,
  227. TQueryType Type)
  228. {
  229. TTerminalManager * Manager = TTerminalManager::Instance(false);
  230. assert(Manager != NULL);
  231. Manager->ScpExplorer->PopupTrayBalloon(Terminal, Str, Type);
  232. }
  233. //---------------------------------------------------------------------------
  234. void __fastcall ConfigureInterface()
  235. {
  236. UnicodeString S;
  237. S = LoadStr(MIDDLE_EAST);
  238. if (!S.IsEmpty())
  239. {
  240. SysLocale.MiddleEast = static_cast<bool>(StrToInt(S));
  241. }
  242. else
  243. {
  244. SysLocale.MiddleEast = false;
  245. }
  246. S = LoadStr(BIDI_MODE);
  247. if (!S.IsEmpty())
  248. {
  249. Application->BiDiMode = static_cast<TBiDiMode>(StrToInt(bdRightToLeft));
  250. }
  251. else
  252. {
  253. Application->BiDiMode = bdLeftToRight;
  254. }
  255. SetTBXSysParam(TSP_XPVISUALSTYLE, XPVS_AUTOMATIC);
  256. // Can be called during configuration creation.
  257. // Skip now, will be called again later.
  258. if (Configuration != NULL)
  259. {
  260. TBXSetTheme(WinConfiguration->Theme);
  261. }
  262. // Has any effect on Wine only
  263. // (otherwise initial UserDocumentDirectory is equivalent to GetPersonalFolder())
  264. UserDocumentDirectory = GetPersonalFolder();
  265. }
  266. //---------------------------------------------------------------------------
  267. // dummy function to force linking of TBXOfficeXPTheme.pas
  268. void __fastcall CreateThemes()
  269. {
  270. new TTBXOfficeXPTheme(L"OfficeXP");
  271. new TTBXOffice2003Theme(L"Office2003");
  272. }
  273. //---------------------------------------------------------------------------
  274. void __fastcall DoAboutDialog(TConfiguration *Configuration)
  275. {
  276. DoAboutDialog(Configuration, true, NULL);
  277. }
  278. //---------------------------------------------------------------------
  279. void __fastcall DoProductLicense()
  280. {
  281. DoLicenseDialog(lcWinScp);
  282. }
  283. //---------------------------------------------------------------------------
  284. const UnicodeString PixelsPerInchKey = L"PixelsPerInch";
  285. //---------------------------------------------------------------------
  286. int __fastcall GetToolbarLayoutPixelsPerInch(TStrings * Storage)
  287. {
  288. int Result;
  289. if (Storage->IndexOfName(PixelsPerInchKey))
  290. {
  291. Result = LoadPixelsPerInch(Storage->Values[PixelsPerInchKey]);
  292. }
  293. else
  294. {
  295. Result = -1;
  296. }
  297. return Result;
  298. }
  299. //---------------------------------------------------------------------
  300. static inline void __fastcall GetToolbarKey(const UnicodeString & ToolbarName,
  301. const UnicodeString & Value, UnicodeString & ToolbarKey)
  302. {
  303. int ToolbarNameLen;
  304. if ((ToolbarName.Length() > 7) &&
  305. (ToolbarName.SubString(ToolbarName.Length() - 7 + 1, 7) == L"Toolbar"))
  306. {
  307. ToolbarNameLen = ToolbarName.Length() - 7;
  308. }
  309. else
  310. {
  311. ToolbarNameLen = ToolbarName.Length();
  312. }
  313. ToolbarKey = ToolbarName.SubString(1, ToolbarNameLen) + L"_" + Value;
  314. }
  315. //---------------------------------------------------------------------------
  316. static int __fastcall ToolbarReadInt(const UnicodeString ToolbarName,
  317. const UnicodeString Value, const int Default, const void * ExtraData)
  318. {
  319. int Result;
  320. if (Value == L"Rev")
  321. {
  322. Result = 2000;
  323. }
  324. else
  325. {
  326. TStrings * Storage = static_cast<TStrings *>(const_cast<void*>(ExtraData));
  327. UnicodeString ToolbarKey;
  328. GetToolbarKey(ToolbarName, Value, ToolbarKey);
  329. if (Storage->IndexOfName(ToolbarKey) >= 0)
  330. {
  331. Result = StrToIntDef(Storage->Values[ToolbarKey], Default);
  332. #if 0
  333. // this does not work well, as it scales down the stretched
  334. // toolbars (path toolbars) too much, it has to be reimplemented smarter
  335. if (Value == L"DockPos")
  336. {
  337. int PixelsPerInch = GetToolbarLayoutPixelsPerInch(Storage);
  338. // When DPI has decreased since the last time, scale down
  339. // toolbar position to get rid of gaps caused by smaller labels.
  340. // Do not do this when DPI has increased as it would introduce gaps,
  341. // as toolbars consists mostly of icons only, that do not scale.
  342. // The toolbars shift themselves anyway, when other toolbars to the left
  343. // get wider. We also risk a bit that toolbar order changes,
  344. // as with very small toolbars (History) we can get scaled down position
  345. // of the following toolbar to the left of it.
  346. // There's special handling (also for scaling-up) stretched toolbars
  347. // in LoadToolbarsLayoutStr
  348. if ((PixelsPerInch > 0) && (Screen->PixelsPerInch < PixelsPerInch))
  349. {
  350. Result = LoadDimension(Result, PixelsPerInch);
  351. }
  352. }
  353. #endif
  354. }
  355. else
  356. {
  357. Result = Default;
  358. }
  359. }
  360. return Result;
  361. }
  362. //---------------------------------------------------------------------------
  363. static UnicodeString __fastcall ToolbarReadString(const UnicodeString ToolbarName,
  364. const UnicodeString Value, const UnicodeString Default, const void * ExtraData)
  365. {
  366. UnicodeString Result;
  367. TStrings * Storage = static_cast<TStrings *>(const_cast<void*>(ExtraData));
  368. UnicodeString ToolbarKey;
  369. GetToolbarKey(ToolbarName, Value, ToolbarKey);
  370. if (Storage->IndexOfName(ToolbarKey) >= 0)
  371. {
  372. Result = Storage->Values[ToolbarKey];
  373. }
  374. else
  375. {
  376. Result = Default;
  377. }
  378. return Result;
  379. }
  380. //---------------------------------------------------------------------------
  381. static void __fastcall ToolbarWriteInt(const UnicodeString ToolbarName,
  382. const UnicodeString Value, const int Data, const void * ExtraData)
  383. {
  384. if (Value != L"Rev")
  385. {
  386. TStrings * Storage = static_cast<TStrings *>(const_cast<void*>(ExtraData));
  387. UnicodeString ToolbarKey;
  388. GetToolbarKey(ToolbarName, Value, ToolbarKey);
  389. assert(Storage->IndexOfName(ToolbarKey) < 0);
  390. Storage->Values[ToolbarKey] = IntToStr(Data);
  391. }
  392. }
  393. //---------------------------------------------------------------------------
  394. static void __fastcall ToolbarWriteString(const UnicodeString ToolbarName,
  395. const UnicodeString Value, const UnicodeString Data, const void * ExtraData)
  396. {
  397. TStrings * Storage = static_cast<TStrings *>(const_cast<void*>(ExtraData));
  398. UnicodeString ToolbarKey;
  399. GetToolbarKey(ToolbarName, Value, ToolbarKey);
  400. assert(Storage->IndexOfName(ToolbarKey) < 0);
  401. Storage->Values[ToolbarKey] = Data;
  402. }
  403. //---------------------------------------------------------------------------
  404. UnicodeString __fastcall GetToolbarsLayoutStr(const TComponent * OwnerComponent)
  405. {
  406. UnicodeString Result;
  407. TStrings * Storage = new TStringList();
  408. try
  409. {
  410. TBCustomSavePositions(OwnerComponent, ToolbarWriteInt, ToolbarWriteString,
  411. Storage);
  412. Storage->Values[PixelsPerInchKey] = SavePixelsPerInch();
  413. Result = Storage->CommaText;
  414. }
  415. __finally
  416. {
  417. delete Storage;
  418. }
  419. return Result;
  420. }
  421. //---------------------------------------------------------------------------
  422. void __fastcall LoadToolbarsLayoutStr(TComponent * OwnerComponent, UnicodeString LayoutStr)
  423. {
  424. TStrings * Storage = new TStringList();
  425. try
  426. {
  427. Storage->CommaText = LayoutStr;
  428. TBCustomLoadPositions(OwnerComponent, ToolbarReadInt, ToolbarReadString,
  429. Storage);
  430. int PixelsPerInch = GetToolbarLayoutPixelsPerInch(Storage);
  431. // Scale toolbars stretched to the first other toolbar to the right
  432. if ((PixelsPerInch > 0) && (PixelsPerInch != Screen->PixelsPerInch)) // optimization
  433. {
  434. for (int Index = 0; Index < OwnerComponent->ComponentCount; Index++)
  435. {
  436. TTBXToolbar * Toolbar =
  437. dynamic_cast<TTBXToolbar *>(OwnerComponent->Components[Index]);
  438. if ((Toolbar != NULL) && Toolbar->Stretch &&
  439. (Toolbar->OnGetBaseSize != NULL) &&
  440. // we do not support floating of stretched toolbars
  441. ALWAYS_TRUE(!Toolbar->Floating))
  442. {
  443. TTBXToolbar * FollowingToolbar = NULL;
  444. for (int Index2 = 0; Index2 < OwnerComponent->ComponentCount; Index2++)
  445. {
  446. TTBXToolbar * Toolbar2 =
  447. dynamic_cast<TTBXToolbar *>(OwnerComponent->Components[Index2]);
  448. if ((Toolbar2 != NULL) && !Toolbar2->Floating &&
  449. (Toolbar2->Parent == Toolbar->Parent) &&
  450. (Toolbar2->DockRow == Toolbar->DockRow) &&
  451. (Toolbar2->DockPos > Toolbar->DockPos) &&
  452. ((FollowingToolbar == NULL) || (FollowingToolbar->DockPos > Toolbar2->DockPos)))
  453. {
  454. FollowingToolbar = Toolbar2;
  455. }
  456. }
  457. if (FollowingToolbar != NULL)
  458. {
  459. int NewWidth = LoadDimension(Toolbar->Width, PixelsPerInch);
  460. FollowingToolbar->DockPos += NewWidth - Toolbar->Width;
  461. }
  462. }
  463. }
  464. }
  465. }
  466. __finally
  467. {
  468. delete Storage;
  469. }
  470. }
  471. //---------------------------------------------------------------------------
  472. void __fastcall AddMenuSeparator(TTBCustomItem * Menu)
  473. {
  474. TTBXSeparatorItem * Item = new TTBXSeparatorItem(Menu);
  475. Menu->Add(Item);
  476. }
  477. //---------------------------------------------------------------------------
  478. static TComponent * LastPopupComponent = NULL;
  479. static TRect LastPopupRect(-1, -1, -1, -1);
  480. static TDateTime LastCloseUp;
  481. //---------------------------------------------------------------------------
  482. void __fastcall MenuPopup(TPopupMenu * AMenu, TRect Rect,
  483. TComponent * PopupComponent)
  484. {
  485. // Pressing the same button within 200ms after closing its popup menu
  486. // does nothing.
  487. // It is to immitate close-by-click behaviour. Note that menu closes itself
  488. // before onclick handler of button occurs.
  489. // To support content menu popups, we have to check for the popup location too,
  490. // to allow poping menu on different location (such as different node of TTreeView),
  491. // even if there's another popup opened already (so that the time interval
  492. // below does not elapse).
  493. TDateTime N = Now();
  494. TDateTime Diff = N - LastCloseUp;
  495. if ((PopupComponent == LastPopupComponent) &&
  496. (Rect == LastPopupRect) &&
  497. (Diff < TDateTime(0, 0, 0, 200)))
  498. {
  499. LastPopupComponent = NULL;
  500. }
  501. else
  502. {
  503. TTBXPopupMenu * Menu = dynamic_cast<TTBXPopupMenu *>(AMenu);
  504. if (Menu == NULL)
  505. {
  506. Menu = CreateTBXPopupMenu(AMenu->Owner);
  507. Menu->OnPopup = AMenu->OnPopup;
  508. Menu->Items->SubMenuImages = AMenu->Images;
  509. for (int Index = 0; Index < AMenu->Items->Count; Index++)
  510. {
  511. TMenuItem * AItem = AMenu->Items->Items[Index];
  512. TTBCustomItem * Item;
  513. // recurse not implemented yet
  514. assert(AItem->Count == 0);
  515. if (!AItem->Enabled && !AItem->Visible && (AItem->Action == NULL) && (AItem->OnClick == NULL))
  516. {
  517. TTBXLabelItem * LabelItem = new TTBXLabelItem(Menu);
  518. // TTBXLabelItem has it's own Caption
  519. LabelItem->Caption = AItem->Caption;
  520. LabelItem->SectionHeader = true;
  521. Item = LabelItem;
  522. }
  523. else
  524. {
  525. // see TB2DsgnConverter.pas DoConvert
  526. if (AItem->Caption == L"-")
  527. {
  528. Item = new TTBXSeparatorItem(Menu);
  529. }
  530. else
  531. {
  532. Item = new TTBXItem(Menu);
  533. Item->Action = AItem->Action;
  534. Item->AutoCheck = AItem->AutoCheck;
  535. Item->Caption = AItem->Caption;
  536. Item->Checked = AItem->Checked;
  537. if (AItem->Default)
  538. {
  539. Item->Options = Item->Options << tboDefault;
  540. }
  541. Item->Enabled = AItem->Enabled;
  542. Item->GroupIndex = AItem->GroupIndex;
  543. Item->HelpContext = AItem->HelpContext;
  544. Item->ImageIndex = AItem->ImageIndex;
  545. Item->RadioItem = AItem->RadioItem;
  546. Item->ShortCut = AItem->ShortCut;
  547. Item->SubMenuImages = AItem->SubMenuImages;
  548. Item->OnClick = AItem->OnClick;
  549. }
  550. Item->Hint = AItem->Hint;
  551. Item->Tag = AItem->Tag;
  552. Item->Visible = AItem->Visible;
  553. }
  554. Menu->Items->Add(Item);
  555. }
  556. }
  557. Menu->PopupComponent = PopupComponent;
  558. Menu->PopupEx(Rect);
  559. LastPopupComponent = PopupComponent;
  560. LastPopupRect = Rect;
  561. LastCloseUp = Now();
  562. }
  563. }
  564. //---------------------------------------------------------------------------
  565. const int ColorCols = 8;
  566. const int StandardColorRows = 2;
  567. const int StandardColorCount = ColorCols * StandardColorRows;
  568. const int UserColorRows = 1;
  569. const int UserColorCount = UserColorRows * ColorCols;
  570. const wchar_t ColorSeparator = L',';
  571. //---------------------------------------------------------------------------
  572. static void __fastcall GetStandardSessionColorInfo(
  573. int Col, int Row, TColor & Color, UnicodeString & Name)
  574. {
  575. #define COLOR_INFO(COL, ROW, NAME, COLOR) \
  576. if ((Col == COL) && (Row == ROW)) { Name = NAME; Color = TColor(COLOR); } else
  577. // bottom row of default TBX color set
  578. COLOR_INFO(0, 0, L"Rose", 0xCC99FF)
  579. COLOR_INFO(1, 0, L"Tan", 0x99CCFF)
  580. COLOR_INFO(2, 0, L"Light Yellow", 0x99FFFF)
  581. COLOR_INFO(3, 0, L"Light Green", 0xCCFFCC)
  582. COLOR_INFO(4, 0, L"Light Turquoise", 0xFFFFCC)
  583. COLOR_INFO(5, 0, L"Pale Blue", 0xFFCC99)
  584. COLOR_INFO(6, 0, L"Lavender", 0xFF99CC)
  585. // second row of Excel 2010 palette with second color (Lighter Black) skipped
  586. COLOR_INFO(7, 0, L"Light Orange", 0xB5D5FB)
  587. COLOR_INFO(0, 1, L"Darker White", 0xD8D8D8)
  588. COLOR_INFO(1, 1, L"Darker Tan", 0x97BDC4)
  589. COLOR_INFO(2, 1, L"Lighter Blue", 0xE2B38D)
  590. COLOR_INFO(3, 1, L"Light Blue", 0xE4CCB8)
  591. COLOR_INFO(4, 1, L"Lighter Red", 0xB7B9E5)
  592. COLOR_INFO(5, 1, L"Light Olive Green", 0xBCE3D7)
  593. COLOR_INFO(6, 1, L"Light Purple", 0xD9C1CC)
  594. COLOR_INFO(7, 1, L"Light Aqua", 0xE8DDB7)
  595. FAIL;
  596. #undef COLOR_INFO
  597. }
  598. //---------------------------------------------------------------------------
  599. static void __fastcall SessionColorSetGetColorInfo(
  600. void * /*Data*/, TTBXCustomColorSet * /*Sender*/, int Col, int Row, TColor & Color, UnicodeString & Name)
  601. {
  602. GetStandardSessionColorInfo(Col, Row, Color, Name);
  603. }
  604. //---------------------------------------------------------------------------
  605. static TColor __fastcall RestoreColor(UnicodeString CStr)
  606. {
  607. return TColor(StrToInt(UnicodeString(L"$") + CStr));
  608. }
  609. //---------------------------------------------------------------------------
  610. static UnicodeString __fastcall StoreColor(TColor Color)
  611. {
  612. return IntToHex(Color, 6);
  613. }
  614. //---------------------------------------------------------------------------
  615. static UnicodeString __fastcall ExtractColorStr(UnicodeString & Colors)
  616. {
  617. return ::CutToChar(Colors, ColorSeparator, true);
  618. }
  619. //---------------------------------------------------------------------------
  620. static bool __fastcall IsStandardColor(TColor Color)
  621. {
  622. for (int Row = 0; Row < StandardColorRows; Row++)
  623. {
  624. for (int Col = 0; Col < ColorCols; Col++)
  625. {
  626. TColor StandardColor;
  627. UnicodeString Name; // unused
  628. GetStandardSessionColorInfo(Col, Row, StandardColor, Name);
  629. if (StandardColor == Color)
  630. {
  631. return true;
  632. }
  633. }
  634. }
  635. return false;
  636. }
  637. //---------------------------------------------------------------------------
  638. class TColorChangeData : public TComponent
  639. {
  640. public:
  641. __fastcall TColorChangeData(TColorChangeEvent OnColorChange, TColor Color);
  642. static TColorChangeData * __fastcall Retrieve(TObject * Object);
  643. void __fastcall ColorChange(TColor Color);
  644. __property TColor Color = { read = FColor };
  645. private:
  646. TColorChangeEvent FOnColorChange;
  647. TColor FColor;
  648. };
  649. //---------------------------------------------------------------------------
  650. __fastcall TColorChangeData::TColorChangeData(TColorChangeEvent OnColorChange, TColor Color) :
  651. TComponent(NULL)
  652. {
  653. Name = QualifiedClassName();
  654. FOnColorChange = OnColorChange;
  655. FColor = Color;
  656. }
  657. //---------------------------------------------------------------------------
  658. TColorChangeData * __fastcall TColorChangeData::Retrieve(TObject * Object)
  659. {
  660. TComponent * Component = NOT_NULL(dynamic_cast<TComponent *>(Object));
  661. TComponent * ColorChangeDataComponent = Component->FindComponent(QualifiedClassName());
  662. return NOT_NULL(dynamic_cast<TColorChangeData *>(ColorChangeDataComponent));
  663. }
  664. //---------------------------------------------------------------------------
  665. void __fastcall TColorChangeData::ColorChange(TColor Color)
  666. {
  667. if ((Color != TColor(0)) &&
  668. !IsStandardColor(Color))
  669. {
  670. UnicodeString SessionColors = StoreColor(Color);
  671. UnicodeString Temp = CustomWinConfiguration->SessionColors;
  672. while (!Temp.IsEmpty())
  673. {
  674. UnicodeString CStr = ExtractColorStr(Temp);
  675. if (RestoreColor(CStr) != Color)
  676. {
  677. SessionColors += UnicodeString(ColorSeparator) + CStr;
  678. }
  679. }
  680. CustomWinConfiguration->SessionColors = SessionColors;
  681. }
  682. FOnColorChange(Color);
  683. }
  684. //---------------------------------------------------------------------------
  685. static void __fastcall ColorDefaultClick(void * /*Data*/, TObject * Sender)
  686. {
  687. TColorChangeData::Retrieve(Sender)->ColorChange(TColor(0));
  688. }
  689. //---------------------------------------------------------------------------
  690. static void __fastcall ColorPaletteChange(void * /*Data*/, TObject * Sender)
  691. {
  692. TTBXColorPalette * ColorPalette = NOT_NULL(dynamic_cast<TTBXColorPalette *>(Sender));
  693. TColor Color = (ColorPalette->Color != Vcl::Graphics::clNone ? ColorPalette->Color : (TColor)0);
  694. TColorChangeData::Retrieve(Sender)->ColorChange(Color);
  695. }
  696. //---------------------------------------------------------------------------
  697. static UnicodeString __fastcall CustomColorName(int Index)
  698. {
  699. return UnicodeString(L"Color") + wchar_t(L'A' + Index);
  700. }
  701. //---------------------------------------------------------------------------
  702. static void __fastcall ColorPickClick(void * /*Data*/, TObject * Sender)
  703. {
  704. TColorChangeData * ColorChangeData = TColorChangeData::Retrieve(Sender);
  705. std::unique_ptr<TColorDialog> Dialog(new TColorDialog(Application));
  706. Dialog->Options = Dialog->Options << cdFullOpen << cdAnyColor;
  707. Dialog->Color = (ColorChangeData->Color != 0 ? ColorChangeData->Color : clSkyBlue);
  708. UnicodeString Temp = CustomWinConfiguration->SessionColors;
  709. int StandardColorIndex = 0;
  710. int CustomColors = Min(MaxCustomColors, StandardColorCount);
  711. for (int Index = 0; Index < CustomColors; Index++)
  712. {
  713. TColor CustomColor;
  714. if (!Temp.IsEmpty())
  715. {
  716. CustomColor = RestoreColor(ExtractColorStr(Temp));
  717. }
  718. else
  719. {
  720. UnicodeString Name; // not used
  721. assert(StandardColorIndex < StandardColorCount);
  722. GetStandardSessionColorInfo(
  723. StandardColorIndex % ColorCols, StandardColorIndex / ColorCols,
  724. CustomColor, Name);
  725. StandardColorIndex++;
  726. }
  727. Dialog->CustomColors->Values[CustomColorName(Index)] = StoreColor(CustomColor);
  728. }
  729. if (Dialog->Execute())
  730. {
  731. // so that we do not have to try to preserve the excess colors
  732. assert(UserColorCount <= MaxCustomColors);
  733. UnicodeString SessionColors;
  734. for (int Index = 0; Index < MaxCustomColors; Index++)
  735. {
  736. UnicodeString CStr = Dialog->CustomColors->Values[CustomColorName(Index)];
  737. if (!CStr.IsEmpty())
  738. {
  739. TColor CustomColor = RestoreColor(CStr);
  740. if (!IsStandardColor(CustomColor))
  741. {
  742. AddToList(SessionColors, StoreColor(CustomColor), ColorSeparator);
  743. }
  744. }
  745. }
  746. CustomWinConfiguration->SessionColors = SessionColors;
  747. // call color change only after copying custom colors back,
  748. // so that it can add selected color to the user list
  749. ColorChangeData->ColorChange(Dialog->Color);
  750. }
  751. }
  752. //---------------------------------------------------------------------------
  753. TPopupMenu * __fastcall CreateSessionColorPopupMenu(TColor Color,
  754. TColorChangeEvent OnColorChange)
  755. {
  756. std::unique_ptr<TTBXPopupMenu> PopupMenu(new TTBXPopupMenu(Application));
  757. CreateSessionColorMenu(PopupMenu->Items, Color, OnColorChange);
  758. return PopupMenu.release();
  759. }
  760. //---------------------------------------------------------------------------
  761. static void __fastcall UserSessionColorSetGetColorInfo(
  762. void * /*Data*/, TTBXCustomColorSet * Sender, int Col, int Row, TColor & Color, UnicodeString & /*Name*/)
  763. {
  764. int Index = (Row * Sender->ColCount) + Col;
  765. UnicodeString Temp = CustomWinConfiguration->SessionColors;
  766. while ((Index > 0) && !Temp.IsEmpty())
  767. {
  768. ExtractColorStr(Temp);
  769. Index--;
  770. }
  771. if (!Temp.IsEmpty())
  772. {
  773. Color = RestoreColor(ExtractColorStr(Temp));
  774. }
  775. else
  776. {
  777. // hide the trailing cells
  778. Color = Vcl::Graphics::clNone;
  779. }
  780. }
  781. //---------------------------------------------------------------------------
  782. void __fastcall CreateColorPalette(TTBCustomItem * Owner, TColor Color, int Rows,
  783. TCSGetColorInfo OnGetColorInfo, TColorChangeEvent OnColorChange)
  784. {
  785. TTBXCustomColorSet * ColorSet = new TTBXCustomColorSet(Owner);
  786. TTBXColorPalette * ColorPalette = new TTBXColorPalette(Owner);
  787. ColorPalette->InsertComponent(ColorSet);
  788. ColorPalette->ColorSet = ColorSet;
  789. // has to be set only after it's assigned to color palette
  790. ColorSet->ColCount = ColorCols;
  791. ColorSet->RowCount = Rows;
  792. ColorSet->OnGetColorInfo = OnGetColorInfo;
  793. ColorPalette->Color = (Color != 0) ? Color : Vcl::Graphics::clNone;
  794. ColorPalette->OnChange = MakeMethod<TNotifyEvent>(NULL, ColorPaletteChange);
  795. ColorPalette->InsertComponent(new TColorChangeData(OnColorChange, Color));
  796. Owner->Add(ColorPalette);
  797. Owner->Add(new TTBXSeparatorItem(Owner));
  798. }
  799. //---------------------------------------------------------------------------
  800. void __fastcall CreateSessionColorMenu(TComponent * AOwner, TColor Color,
  801. TColorChangeEvent OnColorChange)
  802. {
  803. TTBCustomItem * Owner = dynamic_cast<TTBCustomItem *>(AOwner);
  804. if (ALWAYS_TRUE(Owner != NULL))
  805. {
  806. Owner->Clear();
  807. TTBCustomItem * Item;
  808. Item = new TTBXItem(Owner);
  809. Item->Caption = LoadStr(COLOR_DEFAULT_CAPTION);
  810. Item->Hint = LoadStr(COLOR_DEFAULT_HINT);
  811. Item->HelpKeyword = HELP_COLOR;
  812. Item->OnClick = MakeMethod<TNotifyEvent>(NULL, ColorDefaultClick);
  813. Item->Checked = (Color == TColor(0));
  814. Item->InsertComponent(new TColorChangeData(OnColorChange, Color));
  815. Owner->Add(Item);
  816. Owner->Add(new TTBXSeparatorItem(Owner));
  817. int SessionColorCount = 0;
  818. UnicodeString Temp = CustomWinConfiguration->SessionColors;
  819. while (!Temp.IsEmpty())
  820. {
  821. SessionColorCount++;
  822. ExtractColorStr(Temp);
  823. }
  824. if (SessionColorCount > 0)
  825. {
  826. SessionColorCount = Min(SessionColorCount, UserColorCount);
  827. int RowCount = ((SessionColorCount + ColorCols - 1) / ColorCols);
  828. assert(RowCount <= UserColorRows);
  829. CreateColorPalette(Owner, Color, RowCount,
  830. MakeMethod<TCSGetColorInfo>(NULL, UserSessionColorSetGetColorInfo),
  831. OnColorChange);
  832. }
  833. CreateColorPalette(Owner, Color, StandardColorRows,
  834. MakeMethod<TCSGetColorInfo>(NULL, SessionColorSetGetColorInfo),
  835. OnColorChange);
  836. Owner->Add(new TTBXSeparatorItem(Owner));
  837. Item = new TTBXItem(Owner);
  838. Item->Caption = LoadStr(COLOR_PICK_CAPTION);
  839. Item->Hint = LoadStr(COLOR_PICK_HINT);
  840. Item->HelpKeyword = HELP_COLOR;
  841. Item->OnClick = MakeMethod<TNotifyEvent>(NULL, ColorPickClick);
  842. Item->InsertComponent(new TColorChangeData(OnColorChange, Color));
  843. Owner->Add(Item);
  844. }
  845. }
  846. //---------------------------------------------------------------------------
  847. void __fastcall UpgradeSpeedButton(TSpeedButton * /*Button*/)
  848. {
  849. // no-op yet
  850. }
  851. //---------------------------------------------------------------------------
  852. struct TThreadParam
  853. {
  854. TThreadFunc ThreadFunc;
  855. void * Parameter;
  856. };
  857. //---------------------------------------------------------------------------
  858. static int __fastcall ThreadProc(void * AParam)
  859. {
  860. TThreadParam * Param = reinterpret_cast<TThreadParam *>(AParam);
  861. unsigned int Result = Param->ThreadFunc(Param->Parameter);
  862. delete Param;
  863. EndThread(Result);
  864. return Result;
  865. }
  866. //---------------------------------------------------------------------------
  867. int __fastcall StartThread(void * SecurityAttributes, unsigned StackSize,
  868. TThreadFunc ThreadFunc, void * Parameter, unsigned CreationFlags,
  869. TThreadID & ThreadId)
  870. {
  871. TThreadParam * Param = new TThreadParam;
  872. Param->ThreadFunc = ThreadFunc;
  873. Param->Parameter = Parameter;
  874. return BeginThread(SecurityAttributes, StackSize, ThreadProc, Param,
  875. CreationFlags, ThreadId);
  876. }
  877. //---------------------------------------------------------------------------
  878. static TShortCut FirstCtrlNumberShortCut = ShortCut(L'0', TShiftState() << ssCtrl);
  879. static TShortCut LastCtrlNumberShortCut = ShortCut(L'9', TShiftState() << ssCtrl);
  880. static TShortCut FirstShiftCtrlAltLetterShortCut = ShortCut(L'A', TShiftState() << ssShift << ssCtrl << ssAlt);
  881. static TShortCut LastShiftCtrlAltLetterShortCut = ShortCut(L'Z', TShiftState() << ssShift << ssCtrl << ssAlt);
  882. //---------------------------------------------------------------------------
  883. void __fastcall InitializeShortCutCombo(TComboBox * ComboBox,
  884. const TShortCuts & ShortCuts)
  885. {
  886. ComboBox->Items->BeginUpdate();
  887. try
  888. {
  889. ComboBox->Items->Clear();
  890. ComboBox->Items->AddObject(LoadStr(SHORTCUT_NONE), reinterpret_cast<TObject* >(0));
  891. for (TShortCut AShortCut = FirstCtrlNumberShortCut; AShortCut <= LastCtrlNumberShortCut; AShortCut++)
  892. {
  893. if (!ShortCuts.Has(AShortCut))
  894. {
  895. ComboBox->Items->AddObject(ShortCutToText(AShortCut), reinterpret_cast<TObject* >(AShortCut));
  896. }
  897. }
  898. for (TShortCut AShortCut = FirstShiftCtrlAltLetterShortCut; AShortCut <= LastShiftCtrlAltLetterShortCut; AShortCut++)
  899. {
  900. if (!ShortCuts.Has(AShortCut))
  901. {
  902. ComboBox->Items->AddObject(ShortCutToText(AShortCut), reinterpret_cast<TObject* >(AShortCut));
  903. }
  904. }
  905. }
  906. __finally
  907. {
  908. ComboBox->Items->EndUpdate();
  909. }
  910. ComboBox->Style = csDropDownList;
  911. ComboBox->DropDownCount = Max(ComboBox->DropDownCount, 16);
  912. }
  913. //---------------------------------------------------------------------------
  914. void __fastcall SetShortCutCombo(TComboBox * ComboBox, TShortCut Value)
  915. {
  916. for (int Index = ComboBox->Items->Count - 1; Index >= 0; Index--)
  917. {
  918. TShortCut AShortCut = TShortCut(ComboBox->Items->Objects[Index]);
  919. if (AShortCut == Value)
  920. {
  921. ComboBox->ItemIndex = Index;
  922. break;
  923. }
  924. else if (AShortCut < Value)
  925. {
  926. assert(Value != 0);
  927. ComboBox->Items->InsertObject(Index + 1, ShortCutToText(Value),
  928. reinterpret_cast<TObject* >(Value));
  929. ComboBox->ItemIndex = Index + 1;
  930. break;
  931. }
  932. assert(Index > 0);
  933. }
  934. }
  935. //---------------------------------------------------------------------------
  936. TShortCut __fastcall GetShortCutCombo(TComboBox * ComboBox)
  937. {
  938. return TShortCut(ComboBox->Items->Objects[ComboBox->ItemIndex]);
  939. }
  940. //---------------------------------------------------------------------------
  941. bool __fastcall IsCustomShortCut(TShortCut ShortCut)
  942. {
  943. return
  944. ((FirstCtrlNumberShortCut <= ShortCut) && (ShortCut <= LastCtrlNumberShortCut)) ||
  945. ((FirstShiftCtrlAltLetterShortCut <= ShortCut) && (ShortCut <= LastShiftCtrlAltLetterShortCut));
  946. }
  947. //---------------------------------------------------------------------------
  948. //---------------------------------------------------------------------------
  949. class TMasterPasswordDialog : public TCustomDialog
  950. {
  951. public:
  952. __fastcall TMasterPasswordDialog(bool Current);
  953. bool __fastcall Execute(UnicodeString & CurrentPassword, UnicodeString & NewPassword);
  954. protected:
  955. virtual void __fastcall DoValidate();
  956. virtual void __fastcall DoChange(bool & CanSubmit);
  957. private:
  958. TPasswordEdit * CurrentEdit;
  959. TPasswordEdit * NewEdit;
  960. TPasswordEdit * ConfirmEdit;
  961. };
  962. //---------------------------------------------------------------------------
  963. __fastcall TMasterPasswordDialog::TMasterPasswordDialog(bool Current) :
  964. TCustomDialog(Current ? HELP_MASTER_PASSWORD_CURRENT : HELP_MASTER_PASSWORD_CHANGE)
  965. {
  966. Caption = LoadStr(MASTER_PASSWORD_CAPTION);
  967. CurrentEdit = new TPasswordEdit(this);
  968. AddEdit(CurrentEdit, CreateLabel(LoadStr(MASTER_PASSWORD_CURRENT)));
  969. EnableControl(CurrentEdit, Current || WinConfiguration->UseMasterPassword);
  970. CurrentEdit->MaxLength = PasswordMaxLength();
  971. if (!Current)
  972. {
  973. NewEdit = new TPasswordEdit(this);
  974. AddEdit(NewEdit, CreateLabel(LoadStr(MASTER_PASSWORD_NEW)));
  975. NewEdit->MaxLength = CurrentEdit->MaxLength;
  976. if (!WinConfiguration->UseMasterPassword)
  977. {
  978. ActiveControl = NewEdit;
  979. }
  980. ConfirmEdit = new TPasswordEdit(this);
  981. AddEdit(ConfirmEdit, CreateLabel(LoadStr(MASTER_PASSWORD_CONFIRM)));
  982. ConfirmEdit->MaxLength = CurrentEdit->MaxLength;
  983. }
  984. else
  985. {
  986. NewEdit = NULL;
  987. ConfirmEdit = NULL;
  988. }
  989. }
  990. //---------------------------------------------------------------------------
  991. bool __fastcall TMasterPasswordDialog::Execute(
  992. UnicodeString & CurrentPassword, UnicodeString & NewPassword)
  993. {
  994. bool Result = TCustomDialog::Execute();
  995. if (Result)
  996. {
  997. if (CurrentEdit->Enabled)
  998. {
  999. CurrentPassword = CurrentEdit->Text;
  1000. }
  1001. if (NewEdit != NULL)
  1002. {
  1003. NewPassword = NewEdit->Text;
  1004. }
  1005. }
  1006. return Result;
  1007. }
  1008. //---------------------------------------------------------------------------
  1009. void __fastcall TMasterPasswordDialog::DoChange(bool & CanSubmit)
  1010. {
  1011. CanSubmit =
  1012. (!WinConfiguration->UseMasterPassword || (IsValidPassword(CurrentEdit->Text) >= 0)) &&
  1013. ((NewEdit == NULL) || (IsValidPassword(NewEdit->Text) >= 0)) &&
  1014. ((ConfirmEdit == NULL) || (IsValidPassword(ConfirmEdit->Text) >= 0));
  1015. TCustomDialog::DoChange(CanSubmit);
  1016. }
  1017. //---------------------------------------------------------------------------
  1018. void __fastcall TMasterPasswordDialog::DoValidate()
  1019. {
  1020. TCustomDialog::DoValidate();
  1021. if (WinConfiguration->UseMasterPassword &&
  1022. !WinConfiguration->ValidateMasterPassword(CurrentEdit->Text))
  1023. {
  1024. CurrentEdit->SetFocus();
  1025. CurrentEdit->SelectAll();
  1026. throw Exception(MainInstructions(LoadStr(MASTER_PASSWORD_INCORRECT)));
  1027. }
  1028. if (NewEdit != NULL)
  1029. {
  1030. if (NewEdit->Text != ConfirmEdit->Text)
  1031. {
  1032. ConfirmEdit->SetFocus();
  1033. ConfirmEdit->SelectAll();
  1034. throw Exception(MainInstructions(LoadStr(MASTER_PASSWORD_DIFFERENT)));
  1035. }
  1036. int Valid = IsValidPassword(NewEdit->Text);
  1037. if (Valid <= 0)
  1038. {
  1039. assert(Valid == 0);
  1040. if (MessageDialog(LoadStr(MASTER_PASSWORD_SIMPLE2), qtWarning,
  1041. qaOK | qaCancel, HELP_MASTER_PASSWORD_SIMPLE) == qaCancel)
  1042. {
  1043. NewEdit->SetFocus();
  1044. NewEdit->SelectAll();
  1045. Abort();
  1046. }
  1047. }
  1048. }
  1049. }
  1050. //---------------------------------------------------------------------------
  1051. static bool __fastcall DoMasterPasswordDialog(bool Current,
  1052. UnicodeString & NewPassword)
  1053. {
  1054. bool Result;
  1055. TMasterPasswordDialog * Dialog = new TMasterPasswordDialog(Current);
  1056. try
  1057. {
  1058. UnicodeString CurrentPassword;
  1059. Result = Dialog->Execute(CurrentPassword, NewPassword);
  1060. if (Result)
  1061. {
  1062. if ((Current || WinConfiguration->UseMasterPassword) &&
  1063. ALWAYS_TRUE(!CurrentPassword.IsEmpty()))
  1064. {
  1065. WinConfiguration->SetMasterPassword(CurrentPassword);
  1066. }
  1067. }
  1068. }
  1069. __finally
  1070. {
  1071. delete Dialog;
  1072. }
  1073. return Result;
  1074. }
  1075. //---------------------------------------------------------------------------
  1076. bool __fastcall DoMasterPasswordDialog()
  1077. {
  1078. UnicodeString NewPassword;
  1079. bool Result = DoMasterPasswordDialog(true, NewPassword);
  1080. assert(NewPassword.IsEmpty());
  1081. return Result;
  1082. }
  1083. //---------------------------------------------------------------------------
  1084. bool __fastcall DoChangeMasterPasswordDialog(UnicodeString & NewPassword)
  1085. {
  1086. bool Result = DoMasterPasswordDialog(false, NewPassword);
  1087. return Result;
  1088. }
  1089. //---------------------------------------------------------------------------
  1090. void __fastcall MessageWithNoHelp(const UnicodeString & Message)
  1091. {
  1092. TMessageParams Params;
  1093. Params.AllowHelp = false; // to avoid recursion
  1094. if (MessageDialog(LoadStr(HELP_SEND_MESSAGE2), qtConfirmation,
  1095. qaOK | qaCancel, HELP_NONE, &Params) == qaOK)
  1096. {
  1097. SearchHelp(Message);
  1098. }
  1099. }