FileOperationProgress.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Common.h"
  5. #include "FileOperationProgress.h"
  6. //---------------------------------------------------------------------------
  7. #define TRANSFER_BUF_SIZE 4096
  8. //---------------------------------------------------------------------------
  9. __fastcall TFileOperationProgressType::TFileOperationProgressType()
  10. {
  11. FOnProgress = NULL;
  12. FOnFinished = NULL;
  13. Clear();
  14. }
  15. //---------------------------------------------------------------------------
  16. __fastcall TFileOperationProgressType::TFileOperationProgressType(
  17. TFileOperationProgressEvent AOnProgress, TFileOperationFinished AOnFinished)
  18. {
  19. FOnProgress = AOnProgress;
  20. FOnFinished = AOnFinished;
  21. Clear();
  22. }
  23. //---------------------------------------------------------------------------
  24. __fastcall TFileOperationProgressType::~TFileOperationProgressType()
  25. {
  26. assert(!InProgress && !Suspended);
  27. }
  28. //---------------------------------------------------------------------------
  29. void __fastcall TFileOperationProgressType::Clear()
  30. {
  31. FileName = "";
  32. AsciiTransfer = false;
  33. ResumeStatus = rsNotAvailable;
  34. Count = 0;
  35. FFilesFinished = 0;
  36. StartTime = Now();
  37. FStopped = 0;
  38. Suspended = false;
  39. FSuspendTime = 0;
  40. InProgress = false;
  41. TotalTransfered = 0;
  42. TotalSkipped = 0;
  43. TotalSize = 0;
  44. TotalSizeSet = false;
  45. Operation = foNone;
  46. DragDrop = false;
  47. YesToAll = false;
  48. YesToNewer = false;
  49. NoToAll = false;
  50. // to bypass check in ClearTransfer()
  51. TransferSize = 0;
  52. ClearTransfer();
  53. }
  54. //---------------------------------------------------------------------------
  55. void __fastcall TFileOperationProgressType::ClearTransfer()
  56. {
  57. if ((TransferSize > 0) && (TransferedSize < TransferSize))
  58. {
  59. __int64 RemainingSide = (TransferSize - TransferedSize);
  60. TotalSkipped += RemainingSide;
  61. }
  62. LocalSize = 0;
  63. TransferSize = 0;
  64. LocalyUsed = 0;
  65. TransferedSize = 0;
  66. TransferingFile = false;
  67. FFileStopped = 0;
  68. }
  69. //---------------------------------------------------------------------------
  70. void __fastcall TFileOperationProgressType::Start(TFileOperation AOperation,
  71. TOperationSide ASide, int ACount, bool ADragDrop,
  72. const AnsiString ADirectory)
  73. {
  74. Clear();
  75. Operation = AOperation;
  76. Side = ASide;
  77. Count = ACount;
  78. InProgress = true;
  79. Cancel = csContinue;
  80. Directory = ADirectory;
  81. DragDrop = ADragDrop;
  82. DoProgress();
  83. }
  84. //---------------------------------------------------------------------------
  85. void __fastcall TFileOperationProgressType::Reset()
  86. {
  87. InProgress = false;
  88. Suspended = false;
  89. }
  90. //---------------------------------------------------------------------------
  91. void __fastcall TFileOperationProgressType::Stop()
  92. {
  93. // added to include remaining bytes to TotalSkipped, in case
  94. // the progress happes to update before closing
  95. ClearTransfer();
  96. InProgress = false;
  97. DoProgress();
  98. }
  99. //---------------------------------------------------------------------------
  100. void __fastcall TFileOperationProgressType::Suspend()
  101. {
  102. assert(!Suspended);
  103. Suspended = true;
  104. FSuspendTime = Now();
  105. DoProgress();
  106. }
  107. //---------------------------------------------------------------------------
  108. void __fastcall TFileOperationProgressType::Resume()
  109. {
  110. assert(Suspended);
  111. Suspended = false;
  112. TDateTime TimeSuspended = (Now() - FSuspendTime);
  113. // see CPS()
  114. FStopped += TimeSuspended;
  115. FFileStopped += TimeSuspended;
  116. DoProgress();
  117. }
  118. //---------------------------------------------------------------------------
  119. int __fastcall TFileOperationProgressType::OperationProgress()
  120. {
  121. assert(Count);
  122. return (FFilesFinished * 100)/Count;
  123. }
  124. //---------------------------------------------------------------------------
  125. int __fastcall TFileOperationProgressType::TransferProgress()
  126. {
  127. if (TransferSize) return (int)((TransferedSize * 100)/TransferSize);
  128. else return 0;
  129. }
  130. //---------------------------------------------------------------------------
  131. int __fastcall TFileOperationProgressType::TotalTransferProgress()
  132. {
  133. assert(TotalSizeSet);
  134. int Result = TotalSize > 0 ? (int)(((TotalTransfered + TotalSkipped) * 100)/TotalSize) : 0;
  135. return Result < 100 ? Result : Result;
  136. }
  137. //---------------------------------------------------------------------------
  138. int __fastcall TFileOperationProgressType::OverallProgress()
  139. {
  140. if (TotalSizeSet)
  141. {
  142. assert((Operation == foCopy) || (Operation == foMove));
  143. return TotalTransferProgress();
  144. }
  145. else
  146. {
  147. return OperationProgress();
  148. }
  149. }
  150. //---------------------------------------------------------------------------
  151. void __fastcall TFileOperationProgressType::DoProgress()
  152. {
  153. if (FOnProgress) FOnProgress(*this, Cancel);
  154. }
  155. //---------------------------------------------------------------------------
  156. void __fastcall TFileOperationProgressType::Finish(AnsiString FileName,
  157. bool Success, bool & DisconnectWhenComplete)
  158. {
  159. assert(InProgress);
  160. if (FOnFinished)
  161. {
  162. FOnFinished(Operation, Side, DragDrop, FileName,
  163. /* TODO : There wasn't 'Success' condition, was it by mistake or by purpose? */
  164. Success && (Cancel == csContinue), DisconnectWhenComplete);
  165. }
  166. FFilesFinished++;
  167. DoProgress();
  168. }
  169. //---------------------------------------------------------------------------
  170. void __fastcall TFileOperationProgressType::SetFile(AnsiString AFileName)
  171. {
  172. FileName = AFileName;
  173. ClearTransfer();
  174. FFileStartTime = Now();
  175. DoProgress();
  176. }
  177. //---------------------------------------------------------------------------
  178. void __fastcall TFileOperationProgressType::SetLocalSize(__int64 ASize)
  179. {
  180. LocalSize = ASize;
  181. DoProgress();
  182. }
  183. //---------------------------------------------------------------------------
  184. void __fastcall TFileOperationProgressType::AddLocalyUsed(__int64 ASize)
  185. {
  186. LocalyUsed += ASize;
  187. if (LocalyUsed > LocalSize)
  188. {
  189. LocalSize = LocalyUsed;
  190. }
  191. DoProgress();
  192. }
  193. //---------------------------------------------------------------------------
  194. bool __fastcall TFileOperationProgressType::IsLocalyDone()
  195. {
  196. assert(LocalyUsed <= LocalSize);
  197. return (LocalyUsed == LocalSize);
  198. }
  199. //---------------------------------------------------------------------------
  200. unsigned long __fastcall TFileOperationProgressType::LocalBlockSize()
  201. {
  202. unsigned long Result = TRANSFER_BUF_SIZE;
  203. if (LocalyUsed + Result > LocalSize) Result = (unsigned long)(LocalSize - LocalyUsed);
  204. return Result;
  205. }
  206. //---------------------------------------------------------------------------
  207. void __fastcall TFileOperationProgressType::SetTotalSize(__int64 ASize)
  208. {
  209. TotalSize = ASize;
  210. TotalSizeSet = true;
  211. DoProgress();
  212. }
  213. //---------------------------------------------------------------------------
  214. void __fastcall TFileOperationProgressType::SetTransferSize(__int64 ASize)
  215. {
  216. TransferSize = ASize;
  217. DoProgress();
  218. }
  219. //---------------------------------------------------------------------------
  220. void __fastcall TFileOperationProgressType::ChangeTransferSize(__int64 ASize)
  221. {
  222. // reflect change on file size (due to text transfer mode conversion particulary)
  223. // on total transfer size
  224. if (TotalSizeSet)
  225. {
  226. TotalSize += (ASize - TransferSize);
  227. }
  228. TransferSize = ASize;
  229. DoProgress();
  230. }
  231. //---------------------------------------------------------------------------
  232. void __fastcall TFileOperationProgressType::AddTransfered(__int64 ASize,
  233. bool AddToTotals)
  234. {
  235. TransferedSize += ASize;
  236. if (TransferedSize > TransferSize)
  237. {
  238. // this can happen with SFTP when downloading file that
  239. // grows while being downloaded
  240. if (TotalSizeSet)
  241. {
  242. TotalSize += (TransferedSize - TransferSize);
  243. }
  244. TransferSize = TransferedSize;
  245. }
  246. if (AddToTotals)
  247. {
  248. TotalTransfered += ASize;
  249. }
  250. DoProgress();
  251. }
  252. //---------------------------------------------------------------------------
  253. void __fastcall TFileOperationProgressType::AddResumed(__int64 ASize)
  254. {
  255. TotalSkipped += ASize;
  256. AddTransfered(ASize, false);
  257. AddLocalyUsed(ASize);
  258. }
  259. //---------------------------------------------------------------------------
  260. unsigned long __fastcall TFileOperationProgressType::TransferBlockSize()
  261. {
  262. unsigned long Result = TRANSFER_BUF_SIZE;
  263. if (TransferedSize + Result > TransferSize) Result = (unsigned long)(TransferSize - TransferedSize);
  264. return Result;
  265. }
  266. //---------------------------------------------------------------------------
  267. unsigned long __fastcall TFileOperationProgressType::StaticBlockSize()
  268. {
  269. return TRANSFER_BUF_SIZE;
  270. }
  271. //---------------------------------------------------------------------------
  272. bool __fastcall TFileOperationProgressType::IsTransferDone()
  273. {
  274. assert(TransferedSize <= TransferSize);
  275. return (TransferedSize == TransferSize);
  276. }
  277. //---------------------------------------------------------------------------
  278. void __fastcall TFileOperationProgressType::SetAsciiTransfer(bool AAsciiTransfer)
  279. {
  280. AsciiTransfer = AAsciiTransfer;
  281. DoProgress();
  282. }
  283. //---------------------------------------------------------------------------
  284. void __fastcall TFileOperationProgressType::SetResumeStatus(TResumeStatus AResumeStatus)
  285. {
  286. ResumeStatus = AResumeStatus;
  287. DoProgress();
  288. }
  289. //---------------------------------------------------------------------------
  290. TDateTime __fastcall TFileOperationProgressType::TimeElapsed()
  291. {
  292. return Now() - StartTime;
  293. }
  294. //---------------------------------------------------------------------------
  295. unsigned int __fastcall TFileOperationProgressType::CPS()
  296. {
  297. TDateTime CurTime = Suspended ? FSuspendTime : Now();
  298. TDateTime RealTime = (CurTime - StartTime) - FStopped;
  299. if ((double)RealTime > 0)
  300. {
  301. return TotalTransfered / ((double)RealTime * (24 * 60 * 60));
  302. }
  303. else
  304. {
  305. return 0;
  306. }
  307. }
  308. //---------------------------------------------------------------------------
  309. TDateTime __fastcall TFileOperationProgressType::TimeExpected()
  310. {
  311. unsigned int CurCps = CPS();
  312. if (CurCps) return TDateTime((double)(((double)(TransferSize - TransferedSize)) / CurCps) / (24 * 60 * 60));
  313. else return 0;
  314. }
  315. //---------------------------------------------------------------------------
  316. TDateTime __fastcall TFileOperationProgressType::TotalTimeExpected()
  317. {
  318. assert(TotalSizeSet);
  319. unsigned int CurCps = CPS();
  320. if (CurCps > 0)
  321. {
  322. return TDateTime((double)((double)TotalSize / CurCps) /
  323. (24 * 60 * 60));
  324. }
  325. else
  326. {
  327. return 0;
  328. }
  329. }