SynchronizeController.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. if (Checklist != NULL)
  127. {
  128. try
  129. {
  130. if (FLAGSET(FSynchronizeParams.Options, soRecurse))
  131. {
  132. SubdirsChanged = false;
  133. assert(Checklist != NULL);
  134. for (int Index = 0; Index < Checklist->Count; Index++)
  135. {
  136. const TSynchronizeChecklist::TItem * Item = Checklist->Item[Index];
  137. // note that there may be action saDeleteRemote even if nothing has changed
  138. // so this is sub-optimal
  139. if (Item->IsDirectory)
  140. {
  141. if ((Item->Action == TSynchronizeChecklist::saUploadNew) ||
  142. (Item->Action == TSynchronizeChecklist::saDeleteRemote))
  143. {
  144. SubdirsChanged = true;
  145. break;
  146. }
  147. else
  148. {
  149. assert(false);
  150. }
  151. }
  152. }
  153. }
  154. else
  155. {
  156. SubdirsChanged = false;
  157. }
  158. }
  159. __finally
  160. {
  161. delete Checklist;
  162. }
  163. }
  164. }
  165. }
  166. catch(Exception & E)
  167. {
  168. SynchronizeAbort(dynamic_cast<EFatal*>(&E) != NULL);
  169. }
  170. }
  171. //---------------------------------------------------------------------------
  172. void __fastcall TSynchronizeController::SynchronizeAbort(bool Close)
  173. {
  174. if (FSynchronizeMonitor != NULL)
  175. {
  176. FSynchronizeMonitor->Close();
  177. }
  178. assert(FSynchronizeAbort);
  179. FSynchronizeAbort(NULL, Close);
  180. }
  181. //---------------------------------------------------------------------------
  182. void __fastcall TSynchronizeController::LogOperation(TSynchronizeOperation Operation,
  183. const AnsiString FileName)
  184. {
  185. TSynchronizeLogEntry Entry;
  186. AnsiString Message;
  187. switch (Operation)
  188. {
  189. case soDelete:
  190. Entry = slDelete;
  191. Message = FMTLOAD(SYNCHRONIZE_DELETED, (FileName));
  192. break;
  193. default:
  194. assert(false);
  195. // fallthru
  196. case soUpload:
  197. Entry = slUpload;
  198. Message = FMTLOAD(SYNCHRONIZE_UPLOADED, (FileName));
  199. break;
  200. }
  201. SynchronizeLog(Entry, Message);
  202. }
  203. //---------------------------------------------------------------------------
  204. void __fastcall TSynchronizeController::SynchronizeLog(TSynchronizeLogEntry Entry,
  205. const AnsiString Message)
  206. {
  207. if (FSynchronizeLog != NULL)
  208. {
  209. FSynchronizeLog(this, Entry, Message);
  210. }
  211. }
  212. //---------------------------------------------------------------------------
  213. void __fastcall TSynchronizeController::SynchronizeFilter(TObject * /*Sender*/,
  214. const AnsiString DirectoryName, bool & Add)
  215. {
  216. if ((FOptions != NULL) && (FOptions->Filter != NULL))
  217. {
  218. if (IncludeTrailingBackslash(ExtractFilePath(DirectoryName)) ==
  219. IncludeTrailingBackslash(FSynchronizeParams.LocalDirectory))
  220. {
  221. int FoundIndex;
  222. Add = FOptions->Filter->Find(ExtractFileName(DirectoryName), FoundIndex);
  223. }
  224. }
  225. TFileMasks::TParams MaskParams; // size does not matter for directories
  226. Add = Add && FCopyParam.AllowTransfer(DirectoryName, osLocal, true, MaskParams);
  227. }
  228. //---------------------------------------------------------------------------
  229. void __fastcall TSynchronizeController::SynchronizeInvalid(
  230. TObject * /*Sender*/, const AnsiString Directory, const AnsiString ErrorStr)
  231. {
  232. if (FOnSynchronizeInvalid != NULL)
  233. {
  234. FOnSynchronizeInvalid(this, Directory, ErrorStr);
  235. }
  236. SynchronizeAbort(false);
  237. }
  238. //---------------------------------------------------------------------------
  239. void __fastcall TSynchronizeController::SynchronizeTooManyDirectories(
  240. TObject * /*Sender*/, int & MaxDirectories)
  241. {
  242. if (FOnTooManyDirectories != NULL)
  243. {
  244. FOnTooManyDirectories(this, MaxDirectories);
  245. }
  246. }
  247. //---------------------------------------------------------------------------
  248. void __fastcall TSynchronizeController::SynchronizeDirectoriesChange(
  249. TObject * /*Sender*/, int Directories)
  250. {
  251. SynchronizeLog(slDirChange, FMTLOAD(SYNCHRONIZE_START, (Directories)));
  252. }