| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742 | //---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include <Common.h>#include "WinInterface.h"#include "Synchronize.h"#include "VCLCommon.h"#include "CopyParams.h"#include "Terminal.h"#include "GUITools.h"#include <CoreMain.h>#include <Configuration.h>#include <TextsWin.h>#include <HelpWin.h>#include <WinConfiguration.h>#include <StrUtils.hpp>#include <Tools.h>//---------------------------------------------------------------------------#pragma package(smart_init)#pragma link "HistoryComboBox"#pragma link "GrayedCheckBox"#ifndef NO_RESOURCES#pragma resource "*.dfm"#endif//---------------------------------------------------------------------------const int WM_USER_STOP = WM_WINSCP_USER + 2;//---------------------------------------------------------------------------bool __fastcall DoSynchronizeDialog(TSynchronizeParamType & Params,  const TCopyParamType * CopyParams, TSynchronizeStartStopEvent OnStartStop,  bool & SaveSettings, int Options, int CopyParamAttrs,  TGetSynchronizeOptionsEvent OnGetOptions,  TSynchronizeSessionLog OnSynchronizeSessionLog,  TFeedSynchronizeError & OnFeedSynchronizeError,  TSynchronizeInNewWindow OnSynchronizeInNewWindow,  bool Start){  bool Result;  TSynchronizeDialog * Dialog = SafeFormCreate<TSynchronizeDialog>(Application);  Dialog->Init(OnStartStop, OnGetOptions, OnSynchronizeSessionLog, OnFeedSynchronizeError, OnSynchronizeInNewWindow, Start);  try  {    Dialog->Options = Options;    Dialog->CopyParamAttrs = CopyParamAttrs;    Dialog->Params = Params;    Dialog->CopyParams = *CopyParams;    Dialog->SaveSettings = SaveSettings;    Result = Dialog->Execute();    if (Result)    {      SaveSettings = Dialog->SaveSettings;      Params = Dialog->Params;    }  }  __finally  {    delete Dialog;  }  return Result;}//---------------------------------------------------------------------------const TSynchronizeDialog::MaxLogItems = 1000;//---------------------------------------------------------------------------struct TLogItemData{  TSynchronizeLogEntry Entry;  UnicodeString Message;  std::unique_ptr<TStrings> MoreMessages;  TQueryType Type;  UnicodeString HelpKeyword;};//---------------------------------------------------------------------------__fastcall TSynchronizeDialog::TSynchronizeDialog(TComponent * Owner)  : TForm(Owner){  UseSystemSettings(this);  FOptions = 0;  FSynchronizing = false;  FMinimizedByMe = false;  FPresetsMenu = new TPopupMenu(this);  FSynchronizeOptions = NULL;  HotTrackLabel(CopyParamLabel);  CopyParamListButton(TransferSettingsButton);  LoadDialogImage(Image, L"Keep remote directory up to date");  SetGlobalMinimizeHandler(this, GlobalMinimize);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::Init(TSynchronizeStartStopEvent OnStartStop,  TGetSynchronizeOptionsEvent OnGetOptions,  TSynchronizeSessionLog OnSynchronizeSessionLog,  TFeedSynchronizeError & OnFeedSynchronizeError,  TSynchronizeInNewWindow OnSynchronizeInNewWindow,  bool StartImmediately){  FOnStartStop = OnStartStop;  FOnGetOptions = OnGetOptions;  FOnSynchronizeSessionLog = OnSynchronizeSessionLog;  FOnFeedSynchronizeError = &OnFeedSynchronizeError;  DebugAssert(OnSynchronizeInNewWindow != NULL);  FOnSynchronizeInNewWindow = OnSynchronizeInNewWindow;  FStartImmediately = StartImmediately;}//---------------------------------------------------------------------------__fastcall TSynchronizeDialog::~TSynchronizeDialog(){  // if application is closing OnCloseQuery might not get called  // (this particularly happens if last terminal is disconnected while dialog is  // open)  if (FSynchronizing)  {    OnlyStop();  }  ClearGlobalMinimizeHandler(GlobalMinimize);  delete FSynchronizeOptions;  delete FPresetsMenu;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::FeedSynchronizeError(  const UnicodeString & Message, TStrings * MoreMessages, TQueryType Type,  const UnicodeString & HelpKeyword){  DoLogInternal(slContinuedError, Message, MoreMessages, Type, HelpKeyword);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::UpdateControls(){  EnableControl(StartButton, !LocalDirectoryEdit->Text.IsEmpty() &&    !RemoteDirectoryEdit->Text.IsEmpty());  TButton * OldButton = FSynchronizing ? StartButton : StopButton;  TButton * NewButton = FSynchronizing ? StopButton : StartButton;  if (!NewButton->Visible || OldButton->Visible)  {    NewButton->Visible = true;    if (OldButton->Focused())    {      NewButton->SetFocus();    }    OldButton->Default = false;    NewButton->Default = true;    OldButton->Visible = false;    // some of the above steps hides accelerators when start button is pressed with mouse    ResetSystemSettings(this);  }  Caption = FormatFormCaption(this, LoadStr(FSynchronizing ? SYNCHRONIZE_SYCHRONIZING : SYNCHRONIZE_TITLE));  EnableControl(TransferSettingsButton, !FSynchronizing);  CancelButton->Visible = !FSynchronizing || FLAGSET(FOptions, soNoMinimize);  EnableControl(CancelButton, !FSynchronizing);  EnableControl(DirectoriesGroup, !FSynchronizing);  EnableControl(OptionsGroup, !FSynchronizing);  EnableControl(CopyParamGroup, !FSynchronizing);  MinimizeButton->Visible = FSynchronizing && FLAGCLEAR(FOptions, soNoMinimize);  EnableControl(SynchronizeSelectedOnlyCheck,    OptionsGroup->Enabled && FLAGSET(FOptions, soAllowSelectedOnly));  UnicodeString InfoStr = CopyParams.GetInfoStr(L"; ", ActualCopyParamAttrs());  SetLabelHintPopup(CopyParamLabel, InfoStr);  TransferSettingsButton->Style =    FLAGCLEAR(Options, soDoNotUsePresets) ?      TCustomButton::bsSplitButton : TCustomButton::bsPushButton;  if (LogPanel->Visible != FSynchronizing)  {    if (FSynchronizing)    {      LogPanel->Visible = true;      ClientHeight = ClientHeight + LogPanel->Height;    }    else    {      ClientHeight = ClientHeight - LogPanel->Height;      LogPanel->Visible = false;    }  }  // When minimizing to tray globally, no point showing special "minimize to tray" command  MinimizeButton->Style =    !WinConfiguration->MinimizeToTray ? TCustomButton::bsSplitButton : TCustomButton::bsPushButton;  StartButton->Style = AllowStartInNewWindow() ? TCustomButton::bsSplitButton : TCustomButton::bsPushButton;}//---------------------------------------------------------------------------bool __fastcall TSynchronizeDialog::AllowStartInNewWindow(){  return !IsMainFormLike(this);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::ControlChange(TObject * /*Sender*/){  UpdateControls();}//---------------------------------------------------------------------------bool __fastcall TSynchronizeDialog::Execute(){  // at start assume that copy param is current preset  FPreset = GUIConfiguration->CopyParamCurrent;  LocalDirectoryEdit->Items = CustomWinConfiguration->History[L"LocalDirectory"];  RemoteDirectoryEdit->Items = CustomWinConfiguration->History[L"RemoteDirectory"];  ShowModal();  return true;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::SetParams(const TSynchronizeParamType& value){  FParams = value;  RemoteDirectoryEdit->Text = value.RemoteDirectory;  LocalDirectoryEdit->Text = value.LocalDirectory;  SynchronizeDeleteCheck->Checked = FLAGSET(value.Params, TTerminal::spDelete);  SynchronizeExistingOnlyCheck->Checked = FLAGSET(value.Params, TTerminal::spExistingOnly);  SynchronizeSelectedOnlyCheck->Checked = FLAGSET(value.Params, TTerminal::spSelectedOnly);  SynchronizeRecursiveCheck->Checked = FLAGSET(value.Options, soRecurse);  SynchronizeSynchronizeCheck->State =    FLAGSET(value.Options, soSynchronizeAsk) ? cbGrayed :      (FLAGSET(value.Options, soSynchronize) ? cbChecked : cbUnchecked);  ContinueOnErrorCheck->Checked = FLAGSET(value.Options, soContinueOnError);}//---------------------------------------------------------------------------TSynchronizeParamType __fastcall TSynchronizeDialog::GetParams(){  TSynchronizeParamType Result = FParams;  Result.RemoteDirectory = RemoteDirectoryEdit->Text;  Result.LocalDirectory = LocalDirectoryEdit->Text;  Result.Params =    (Result.Params & ~(TTerminal::spDelete | TTerminal::spExistingOnly | TTerminal::spSelectedOnly | TTerminal::spTimestamp)) |    FLAGMASK(SynchronizeDeleteCheck->Checked, TTerminal::spDelete) |    FLAGMASK(SynchronizeExistingOnlyCheck->Checked, TTerminal::spExistingOnly) |    FLAGMASK(SynchronizeSelectedOnlyCheck->Checked, TTerminal::spSelectedOnly);  Result.Options =    (Result.Options & ~(soRecurse | soSynchronize | soSynchronizeAsk | soContinueOnError)) |    FLAGMASK(SynchronizeRecursiveCheck->Checked, soRecurse) |    FLAGMASK(SynchronizeSynchronizeCheck->State == cbChecked, soSynchronize) |    FLAGMASK(SynchronizeSynchronizeCheck->State == cbGrayed, soSynchronizeAsk) |    FLAGMASK(ContinueOnErrorCheck->Checked, soContinueOnError);  return Result;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::LocalDirectoryBrowseButtonClick(      TObject * /*Sender*/){  UnicodeString Directory = LocalDirectoryEdit->Text;  if (SelectDirectory(Directory, LoadStr(SELECT_LOCAL_DIRECTORY), false))  {    LocalDirectoryEdit->Text = Directory;  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::SetOptions(int value){  if (Options != value)  {    FOptions = value;    UpdateControls();  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::CopyParamListPopup(TRect R, int AdditionalOptions){  // We pass in FCopyParams, although it may not be the exact copy param  // that will be used (because of PreserveTime). The reason is to  // display checkbox next to user-selected preset  ::CopyParamListPopup(    R, FPresetsMenu, FCopyParams, FPreset, CopyParamClick,    AdditionalOptions, ActualCopyParamAttrs());}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::TransferSettingsButtonClick(  TObject * /*Sender*/){  if (FLAGCLEAR(FOptions, soDoNotUsePresets) && !SupportsSplitButton())  {    CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);  }  else  {    CopyParamGroupClick(NULL);  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::DoStartStop(bool Start, bool Synchronize){  if (FOnStartStop)  {    TSynchronizeParamType SParams = GetParams();    SParams.Options =      (SParams.Options & ~(soSynchronize | soSynchronizeAsk)) |      FLAGMASK(Synchronize, soSynchronize);    if (Start)    {      DebugAssert(*FOnFeedSynchronizeError == NULL);      *FOnFeedSynchronizeError =        (FLAGSET(SParams.Options, soContinueOnError) ? &FeedSynchronizeError : TFeedSynchronizeError(NULL));      delete FSynchronizeOptions;      FSynchronizeOptions = new TSynchronizeOptions;      FOnGetOptions(SParams.Params, *FSynchronizeOptions);    }    else    {      *FOnFeedSynchronizeError = NULL;    }    FOnStartStop(this, Start, SParams, CopyParams, FSynchronizeOptions, DoAbort,      NULL, DoLog);  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::Dispatch(void * AMessage){  DebugAssert(AMessage != NULL);  TMessage & Message = *reinterpret_cast<TMessage *>(AMessage);  if ((Message.Msg == WM_USER_STOP) && FAbort)  {    if (FSynchronizing)    {      Stop();    }    if (FClose)    {      FClose = false;      ModalResult = mrCancel;    }  }  else if (Message.Msg == WM_MANAGES_CAPTION)  {    // caption managed in UpdateControls()    Message.Result = 1;  }  else  {    TForm::Dispatch(AMessage);  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::DoAbort(TObject * /*Sender*/, bool Close){  FAbort = true;  FClose = Close;  PostMessage(Handle, WM_USER_STOP, 0, 0);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::DoLogInternal(  TSynchronizeLogEntry Entry, const UnicodeString & Message,  TStrings * MoreMessages, TQueryType Type, const UnicodeString & HelpKeyword){  LogView->Items->BeginUpdate();  try  {    TListItem * Item = LogView->Items->Add();    TLogItemData * LogItemData = new TLogItemData();    Item->Data = LogItemData;    LogItemData->Entry = Entry;    LogItemData->Message = Message;    if (MoreMessages != NULL)    {      LogItemData->MoreMessages.reset(new TStringList());      LogItemData->MoreMessages->Assign(MoreMessages);    }    LogItemData->Type = Type;    LogItemData->HelpKeyword = HelpKeyword;    Item->Caption = Now().TimeString();    UnicodeString UnformattedMessage = UnformatMessage(Message);    UnformattedMessage = ReplaceStr(UnformattedMessage, L"\r", L"");    UnformattedMessage = ReplaceStr(UnformattedMessage, L"\n", L" ");    Item->SubItems->Add(UnformattedMessage);    Item->MakeVisible(false);    while (LogView->Items->Count > MaxLogItems)    {      LogView->Items->Delete(0);    }  }  __finally  {    LogView->Items->EndUpdate();    if (Entry == slScan)    {      // redraw log before the scanning block update      LogView->Repaint();    }  }  FOnSynchronizeSessionLog(Message);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::DoLog(TSynchronizeController * /*Controller*/,  TSynchronizeLogEntry Entry, const UnicodeString Message){  DoLogInternal(Entry, Message,    // these are unused (as Entry is not slContinuedError here)    NULL, qtInformation, UnicodeString());}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::StartButtonClick(TObject * /*Sender*/){  if (AllowStartInNewWindow() && OpenInNewWindow())  {    StartInNewWindow();  }  else  {    Start();  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::Start(){  bool Synchronize;  bool Continue = true;  if (SynchronizeSynchronizeCheck->State == cbGrayed)  {    TMessageParams Params(mpNeverAskAgainCheck);    switch (MoreMessageDialog(LoadStr(SYNCHRONISE_BEFORE_KEEPUPTODATE2),        NULL, qtConfirmation, qaYes | qaNo | qaCancel, HELP_KEEPUPTODATE_SYNCHRONIZE,        &Params))    {      case qaNeverAskAgain:        SynchronizeSynchronizeCheck->State = cbChecked;        // fall thru      case qaYes:        Synchronize = true;        break;      case qaNo:        Synchronize = false;        break;      default:      case qaCancel:        Continue = false;        break;    };  }  else  {    Synchronize = SynchronizeSynchronizeCheck->Checked;  }  if (Continue)  {    DebugAssert(!FSynchronizing);    SaveHistory();    FSynchronizing = true;    try    {      UpdateControls();      Repaint();      FAbort = false;      DoStartStop(true, Synchronize);    }    catch(...)    {      FSynchronizing = false;      UpdateControls();      throw;    }  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::SaveHistory(){  LocalDirectoryEdit->SaveToHistory();  CustomWinConfiguration->History[L"LocalDirectory"] = LocalDirectoryEdit->Items;  RemoteDirectoryEdit->SaveToHistory();  CustomWinConfiguration->History[L"RemoteDirectory"] = RemoteDirectoryEdit->Items;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::StopButtonClick(TObject * /*Sender*/){  Stop();}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::OnlyStop(){  FSynchronizing = false;  DoStartStop(false, false);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::Stop(){  OnlyStop();  UpdateControls();  Repaint();  if (IsApplicationMinimized() && FMinimizedByMe)  {    FMinimizedByMe = false;    ApplicationRestore();    Application->BringToFront();  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::Minimize(TObject * Sender){  CallGlobalMinimizeHandler(Sender);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::MinimizeButtonClick(TObject * Sender){  Minimize(Sender);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::GlobalMinimize(TObject * /*Sender*/){  ApplicationMinimize();  FMinimizedByMe = true;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::SetSaveSettings(bool value){  SaveSettingsCheck->Checked = value;}//---------------------------------------------------------------------------bool __fastcall TSynchronizeDialog::GetSaveSettings(){  return SaveSettingsCheck->Checked;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::FormShow(TObject * /*Sender*/){  InstallPathWordBreakProc(LocalDirectoryEdit);  InstallPathWordBreakProc(RemoteDirectoryEdit);  // OnShow gets called more than once sometimes  if (!FSynchronizing)  {    ClearLog();    UpdateControls();    if (FStartImmediately)    {      // if starting get cancelled (from SYNCHRONISE_BEFORE_KEEPUPTODATE2 prompt),      // and OnShow gets called again (FSynchronizing is false),      // we do not want to try to start again      FStartImmediately = false;      StartButtonClick(NULL);    }  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::FormCloseQuery(TObject * /*Sender*/,  bool & /*CanClose*/){  if (FSynchronizing)  {    Stop();  }}//---------------------------------------------------------------------------TCopyParamType __fastcall TSynchronizeDialog::GetCopyParams(){  TCopyParamType Result = FCopyParams;  Result.PreserveTime = true;  Result.NewerOnly = false;  return Result;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::SetCopyParams(const TCopyParamType & value){  FCopyParams = value;  UpdateControls();}//---------------------------------------------------------------------------int __fastcall TSynchronizeDialog::ActualCopyParamAttrs(){  return FCopyParamAttrs | cpaNoPreserveTime | cpaNoNewerOnly;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::CopyParamClick(TObject * Sender){  DebugAssert(FLAGCLEAR(FOptions, soDoNotUsePresets));  // PreserveTime is forced for some settings, but avoid hard-setting it until  // user really confirms it on custom dialog  TCopyParamType ACopyParams = CopyParams;  if (CopyParamListPopupClick(Sender, ACopyParams, FPreset,        ActualCopyParamAttrs()) > 0)  {    FCopyParams = ACopyParams;    UpdateControls();  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::CopyParamGroupContextPopup(  TObject * /*Sender*/, TPoint & MousePos, bool & Handled){  if (FLAGCLEAR(FOptions, soDoNotUsePresets))  {    CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos),      cplCustomizeDefault);    Handled = true;  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::CopyParamGroupClick(TObject * /*Sender*/){  // PreserveTime is forced for some settings, but avoid hard-setting it until  // user really confirms it on cutom dialog  TCopyParamType ACopyParams = CopyParams;  if (DoCopyParamCustomDialog(ACopyParams, ActualCopyParamAttrs()))  {    FCopyParams = ACopyParams;    UpdateControls();  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::HelpButtonClick(TObject * /*Sender*/){  FormHelp(this);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::ClearLog(){  // TListItems::Clear() does nothing without allocated handle  LogView->HandleNeeded();  LogView->Items->Clear();}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::CopyLog(){  TInstantOperationVisualizer Visualizer;  UnicodeString Content;  for (int i = 0; i < LogView->Items->Count; i++)  {    TListItem * Item = LogView->Items->Item[i];    Content += Item->Caption + L"\t" + Item->SubItems->Strings[0] + L"\r\n";  }  CopyToClipboard(Content);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::LogViewKeyDown(TObject * /*Sender*/,  WORD & Key, TShiftState Shift){  if (Key == VK_DELETE)  {    ClearLog();    Key = 0;  }  else if ((Key == L'C') && Shift.Contains(ssCtrl) && (LogView->Items->Count > 0))  {    CopyLog();    Key = 0;  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::FormKeyDown(TObject * /*Sender*/, WORD & Key,  TShiftState /*Shift*/){  if ((Key == VK_ESCAPE) && FSynchronizing)  {    Stop();    Key = 0;  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/){  CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::LogViewCustomDrawItem(TCustomListView * Sender,  TListItem * Item, TCustomDrawState /*State*/, bool & /*DefaultDraw*/){  TLogItemData * LogItemData = GetLogItemData(Item);  if (LogItemData->Entry == slContinuedError)  {    Sender->Canvas->Font->Color = clRed;  }}//---------------------------------------------------------------------------TLogItemData * __fastcall TSynchronizeDialog::GetLogItemData(TListItem * Item){  return reinterpret_cast<TLogItemData *>(Item->Data);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::LogViewDeletion(TObject * /*Sender*/, TListItem * Item){  delete GetLogItemData(Item);  Item->Data = NULL;}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::LogViewDblClick(TObject * /*Sender*/){  if (LogView->ItemFocused != NULL)  {    TLogItemData * LogItemData = GetLogItemData(LogView->ItemFocused);    if (LogItemData->Entry == slContinuedError)    {      MoreMessageDialog(        LogItemData->Message, LogItemData->MoreMessages.get(), LogItemData->Type,        qaOK, LogItemData->HelpKeyword);    }  }}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::Minimize1Click(TObject * Sender){  Minimize(Sender);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::MinimizetoTray1Click(TObject * Sender){  WinConfiguration->MinimizeToTrayOnce();  Minimize(Sender);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::MinimizeButtonDropDownClick(TObject * /*Sender*/){  MenuPopup(MinimizeMenu, MinimizeButton);}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::StartInNewWindow1Click(TObject * /*Sender*/){  StartInNewWindow();}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::StartInNewWindow(){  SaveHistory();  TSynchronizeParamType AParams = Params;  TCopyParamType ACopyParams = CopyParams;  FOnSynchronizeInNewWindow(AParams, &ACopyParams);  Close();}//---------------------------------------------------------------------------void __fastcall TSynchronizeDialog::StartButtonDropDownClick(TObject * /*Sender*/){  MenuPopup(StartMenu, StartButton);}//---------------------------------------------------------------------------
 |