SynchronizeController.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include <RemoteFiles.h>
  6. #include <Terminal.h>
  7. #include <DiscMon.hpp>
  8. #include <Exceptions.h>
  9. #include "GUIConfiguration.h"
  10. #include "CoreMain.h"
  11. #include "TextsCore.h"
  12. #include "SynchronizeController.h"
  13. //---------------------------------------------------------------------------
  14. #pragma package(smart_init)
  15. //---------------------------------------------------------------------------
  16. __fastcall TSynchronizeController::TSynchronizeController(
  17. TSynchronizeEvent AOnSynchronize, TSynchronizeInvalidEvent AOnSynchronizeInvalid,
  18. TSynchronizeTooManyDirectories AOnTooManyDirectories)
  19. {
  20. FOnSynchronize = AOnSynchronize;
  21. FOnSynchronizeInvalid = AOnSynchronizeInvalid;
  22. FOnTooManyDirectories = AOnTooManyDirectories;
  23. FSynchronizeMonitor = NULL;
  24. FSynchronizeAbort = NULL;
  25. FSynchronizeLog = NULL;
  26. FOptions = NULL;
  27. }
  28. //---------------------------------------------------------------------------
  29. __fastcall TSynchronizeController::~TSynchronizeController()
  30. {
  31. assert(FSynchronizeMonitor == NULL);
  32. }
  33. //---------------------------------------------------------------------------
  34. void __fastcall TSynchronizeController::StartStop(TObject * Sender,
  35. bool Start, const TSynchronizeParamType & Params, const TCopyParamType & CopyParam,
  36. TSynchronizeOptions * Options,
  37. TSynchronizeAbortEvent OnAbort, TSynchronizeThreadsEvent OnSynchronizeThreads,
  38. TSynchronizeLog OnSynchronizeLog)
  39. {
  40. if (Start)
  41. {
  42. try
  43. {
  44. assert(OnSynchronizeLog != NULL);
  45. FSynchronizeLog = OnSynchronizeLog;
  46. FOptions = Options;
  47. if (FLAGSET(Params.Options, soSynchronize) &&
  48. (FOnSynchronize != NULL))
  49. {
  50. FOnSynchronize(this, Params.LocalDirectory,
  51. Params.RemoteDirectory, CopyParam,
  52. Params, NULL, FOptions, true);
  53. }
  54. FCopyParam = CopyParam;
  55. FSynchronizeParams = Params;
  56. assert(OnAbort);
  57. FSynchronizeAbort = OnAbort;
  58. if (FLAGSET(FSynchronizeParams.Options, soRecurse))
  59. {
  60. SynchronizeLog(slScan,
  61. FMTLOAD(SYNCHRONIZE_SCAN, (FSynchronizeParams.LocalDirectory)));
  62. }
  63. FSynchronizeMonitor = new TDiscMonitor(dynamic_cast<TComponent*>(Sender));
  64. FSynchronizeMonitor->SubTree = false;
  65. TMonitorFilters Filters;
  66. Filters << moFilename << moLastWrite;
  67. if (FLAGSET(FSynchronizeParams.Options, soRecurse))
  68. {
  69. Filters << moDirName;
  70. }
  71. FSynchronizeMonitor->Filters = Filters;
  72. FSynchronizeMonitor->MaxDirectories = 0;
  73. FSynchronizeMonitor->ChangeDelay = GUIConfiguration->KeepUpToDateChangeDelay;
  74. FSynchronizeMonitor->OnTooManyDirectories = SynchronizeTooManyDirectories;
  75. FSynchronizeMonitor->OnDirectoriesChange = SynchronizeDirectoriesChange;
  76. FSynchronizeMonitor->OnFilter = SynchronizeFilter;
  77. FSynchronizeMonitor->AddDirectory(FSynchronizeParams.LocalDirectory,
  78. FLAGSET(FSynchronizeParams.Options, soRecurse));
  79. FSynchronizeMonitor->OnChange = SynchronizeChange;
  80. FSynchronizeMonitor->OnInvalid = SynchronizeInvalid;
  81. FSynchronizeMonitor->OnSynchronize = OnSynchronizeThreads;
  82. // get count before open to avoid thread issues
  83. int Directories = FSynchronizeMonitor->Directories->Count;
  84. FSynchronizeMonitor->Open();
  85. SynchronizeLog(slStart, FMTLOAD(SYNCHRONIZE_START, (Directories)));
  86. }
  87. catch(...)
  88. {
  89. SAFE_DESTROY(FSynchronizeMonitor);
  90. throw;
  91. }
  92. }
  93. else
  94. {
  95. FOptions = NULL;
  96. SAFE_DESTROY(FSynchronizeMonitor);
  97. }
  98. }
  99. //---------------------------------------------------------------------------
  100. void __fastcall TSynchronizeController::SynchronizeChange(
  101. TObject * /*Sender*/, const AnsiString Directory, bool & SubdirsChanged)
  102. {
  103. try
  104. {
  105. AnsiString RemoteDirectory;
  106. AnsiString RootLocalDirectory;
  107. RootLocalDirectory = IncludeTrailingBackslash(FSynchronizeParams.LocalDirectory);
  108. RemoteDirectory = UnixIncludeTrailingBackslash(FSynchronizeParams.RemoteDirectory);
  109. AnsiString LocalDirectory = IncludeTrailingBackslash(Directory);
  110. assert(LocalDirectory.SubString(1, RootLocalDirectory.Length()) ==
  111. RootLocalDirectory);
  112. RemoteDirectory = RemoteDirectory +
  113. ToUnixPath(LocalDirectory.SubString(RootLocalDirectory.Length() + 1,
  114. LocalDirectory.Length() - RootLocalDirectory.Length()));
  115. SynchronizeLog(slChange, FMTLOAD(SYNCHRONIZE_CHANGE,
  116. (ExcludeTrailingBackslash(LocalDirectory))));
  117. if (FOnSynchronize != NULL)
  118. {
  119. // this is completelly wrong as the options structure
  120. // can contain non-root specific options in future
  121. TSynchronizeOptions * Options =
  122. ((LocalDirectory == RootLocalDirectory) ? FOptions : NULL);
  123. TSynchronizeChecklist * Checklist = NULL;
  124. FOnSynchronize(this, LocalDirectory, RemoteDirectory, FCopyParam,
  125. FSynchronizeParams, &Checklist, Options, false);
  126. try
  127. {
  128. if (FLAGSET(FSynchronizeParams.Options, soRecurse))
  129. {
  130. SubdirsChanged = false;
  131. assert(Checklist != NULL);
  132. for (int Index = 0; Index < Checklist->Count; Index++)
  133. {
  134. const TSynchronizeChecklist::TItem * Item = Checklist->Item[Index];
  135. // note that there may be action saDeleteRemote even if nothing has changed
  136. // so this is sub-optimal
  137. if (Item->IsDirectory)
  138. {
  139. if ((Item->Action == TSynchronizeChecklist::saUploadNew) ||
  140. (Item->Action == TSynchronizeChecklist::saDeleteRemote))
  141. {
  142. SubdirsChanged = true;
  143. break;
  144. }
  145. else
  146. {
  147. assert(false);
  148. }
  149. }
  150. }
  151. }
  152. else
  153. {
  154. SubdirsChanged = false;
  155. }
  156. }
  157. __finally
  158. {
  159. delete Checklist;
  160. }
  161. }
  162. }
  163. catch(Exception & E)
  164. {
  165. SynchronizeAbort(dynamic_cast<EFatal*>(&E) != NULL);
  166. }
  167. }
  168. //---------------------------------------------------------------------------
  169. void __fastcall TSynchronizeController::SynchronizeAbort(bool Close)
  170. {
  171. if (FSynchronizeMonitor != NULL)
  172. {
  173. FSynchronizeMonitor->Close();
  174. }
  175. assert(FSynchronizeAbort);
  176. FSynchronizeAbort(NULL, Close);
  177. }
  178. //---------------------------------------------------------------------------
  179. void __fastcall TSynchronizeController::LogOperation(TSynchronizeOperation Operation,
  180. const AnsiString FileName)
  181. {
  182. TSynchronizeLogEntry Entry;
  183. AnsiString Message;
  184. switch (Operation)
  185. {
  186. case soDelete:
  187. Entry = slDelete;
  188. Message = FMTLOAD(SYNCHRONIZE_DELETED, (FileName));
  189. break;
  190. default:
  191. assert(false);
  192. // fallthru
  193. case soUpload:
  194. Entry = slUpload;
  195. Message = FMTLOAD(SYNCHRONIZE_UPLOADED, (FileName));
  196. break;
  197. }
  198. SynchronizeLog(Entry, Message);
  199. }
  200. //---------------------------------------------------------------------------
  201. void __fastcall TSynchronizeController::SynchronizeLog(TSynchronizeLogEntry Entry,
  202. const AnsiString Message)
  203. {
  204. if (FSynchronizeLog != NULL)
  205. {
  206. FSynchronizeLog(this, Entry, Message);
  207. }
  208. }
  209. //---------------------------------------------------------------------------
  210. void __fastcall TSynchronizeController::SynchronizeFilter(TObject * /*Sender*/,
  211. const AnsiString DirectoryName, bool & Add)
  212. {
  213. if ((FOptions != NULL) && (FOptions->Filter != NULL))
  214. {
  215. if (IncludeTrailingBackslash(ExtractFilePath(DirectoryName)) ==
  216. IncludeTrailingBackslash(FSynchronizeParams.LocalDirectory))
  217. {
  218. int FoundIndex;
  219. Add = FOptions->Filter->Find(ExtractFileName(DirectoryName), FoundIndex);
  220. }
  221. }
  222. TFileMasks::TParams MaskParams; // size does not matter for directories
  223. Add = Add && FCopyParam.AllowTransfer(DirectoryName, osLocal, true, MaskParams);
  224. }
  225. //---------------------------------------------------------------------------
  226. void __fastcall TSynchronizeController::SynchronizeInvalid(
  227. TObject * /*Sender*/, const AnsiString Directory, const AnsiString ErrorStr)
  228. {
  229. if (FOnSynchronizeInvalid != NULL)
  230. {
  231. FOnSynchronizeInvalid(this, Directory, ErrorStr);
  232. }
  233. SynchronizeAbort(false);
  234. }
  235. //---------------------------------------------------------------------------
  236. void __fastcall TSynchronizeController::SynchronizeTooManyDirectories(
  237. TObject * /*Sender*/, int & MaxDirectories)
  238. {
  239. if (FOnTooManyDirectories != NULL)
  240. {
  241. FOnTooManyDirectories(this, MaxDirectories);
  242. }
  243. }
  244. //---------------------------------------------------------------------------
  245. void __fastcall TSynchronizeController::SynchronizeDirectoriesChange(
  246. TObject * /*Sender*/, int Directories)
  247. {
  248. SynchronizeLog(slDirChange, FMTLOAD(SYNCHRONIZE_START, (Directories)));
  249. }