Merge lp:~carlos-mazieri/ubuntu-filemanager-app/model into lp:ubuntu-filemanager-app/plugin
- model
- Merge into plugin
Status: | Merged |
---|---|
Approved by: | Carlos Jose Mazieri |
Approved revision: | 46 |
Merged at revision: | 39 |
Proposed branch: | lp:~carlos-mazieri/ubuntu-filemanager-app/model |
Merge into: | lp:ubuntu-filemanager-app/plugin |
Diff against target: |
2020 lines (+637/-412) 13 files modified
folderlistmodel/dirmodel.cpp (+100/-117) folderlistmodel/dirmodel.h (+14/-15) folderlistmodel/externalfswatcher.cpp (+114/-0) folderlistmodel/externalfswatcher.h (+68/-0) folderlistmodel/filesystemaction.cpp (+64/-93) folderlistmodel/filesystemaction.h (+3/-4) folderlistmodel/folderlistmodel.pri (+2/-0) folderlistmodel/iorequest.cpp (+39/-30) folderlistmodel/iorequest.h (+1/-2) folderlistmodel/iorequestworker.cpp (+4/-44) folderlistmodel/iorequestworker.h (+0/-3) test_folderlistmodel/regression/regression_folderlilstmodel.pro (+2/-0) test_folderlistmodel/regression/tst_folderlistmodel.cpp (+226/-104) |
To merge this branch: | bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/model |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Carlos Jose Mazieri | Approve | ||
Victor Thompson (community) | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+195968@code.launchpad.net |
Commit message
The auto-refresh feature which watches for external modifications in the file system is now using QFileSystemWatcher which was extended by ExternalFSWatcher class in externalfswatcher.h
Description of the change
The auto-refresh feature which watches for external modifications in the file system is now using QFileSystemWatcher which was extended by ExternalFSWatcher class in externalfswatch
The refresh time interval is 900 milliseconds.
The old mechanism used: comparing current path modification times, might fail when there are files modified in the same time stamp.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Victor Thompson (vthompson) wrote : | # |
I tested the external modification functionality and ran the regression suite and everything looks good. If the modification time issue was a consistent failure, consider adding a unit test for this situation.
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
Victor, Thanks for testing this.
I notice "the modification time issue" sometimes running the test case watchExternalCh
The old logic used to check current directory modification time, the problem could happen if next modification time happened in the same time stamp as the last notification, in this case there were no differecence between time stamps used to compare in order to indentify changes in the file system.
I think that QFileSystemWatcher watches directory file descriptor updates based on "select" or similar system call which must avoid this kind of problem.
Right now, related tests cases are:
void watchExternalCh
void extFsWatcherCha
void extFsWatcherMod
void extFsWatcherSet
void extFsWatcherCha
I can add that test case, thanks for this suggestion.
Carlos Jose Mazieri (carlos-mazieri) : | # |
Preview Diff
1 | === modified file 'folderlistmodel/dirmodel.cpp' |
2 | --- folderlistmodel/dirmodel.cpp 2013-10-06 14:49:04 +0000 |
3 | +++ folderlistmodel/dirmodel.cpp 2013-11-20 14:23:19 +0000 |
4 | @@ -33,6 +33,7 @@ |
5 | #include "iorequest.h" |
6 | #include "ioworkerthread.h" |
7 | #include "filesystemaction.h" |
8 | +#include "externalfswatcher.h" |
9 | |
10 | #ifndef DO_NOT_USE_TAG_LIB |
11 | #include <taglib/attachedpictureframe.h> |
12 | @@ -58,10 +59,8 @@ |
13 | #endif |
14 | |
15 | #define IS_VALID_ROW(row) (row >=0 && row < mDirectoryContents.count()) |
16 | -#define WARN_ROW_OUT_OF_RANGE(row) qWarning() << Q_FUNC_INFO << "row" << row << "Out of bounds access" |
17 | +#define WARN_ROW_OUT_OF_RANGE(row) qWarning() << Q_FUNC_INFO << this << "row:" << row << "Out of bounds access" |
18 | |
19 | -#define NO_EXT_FS_WATCHER_TIMER -1 |
20 | -#define IS_EXT_FS_WATCHER_TIMER_ACTIVE() (mExternalFSWatcherTimer != NO_EXT_FS_WATCHER_TIMER) |
21 | #define IS_FILE_MANAGER_IDLE() (!mAwaitingResults) |
22 | |
23 | |
24 | @@ -97,10 +96,8 @@ |
25 | , mShowHiddenFiles(false) |
26 | , mSortBy(SortByName) |
27 | , mSortOrder(SortAscending) |
28 | - , mCompareFunction(0) |
29 | - , mExternalFSWatcherTimer(NO_EXT_FS_WATCHER_TIMER) |
30 | - , mEnableExternalFSWatcher(false) |
31 | - , mLastModifiedCurrentPath(QDateTime::currentDateTime()) |
32 | + , mCompareFunction(0) |
33 | + , mExtFSWatcher(0) |
34 | , m_fsAction(new FileSystemAction(this) ) |
35 | { |
36 | mNameFilters = QStringList() << "*"; |
37 | @@ -127,6 +124,9 @@ |
38 | connect(m_fsAction, SIGNAL(removed(QString)), |
39 | this, SLOT(onItemRemoved(QString))); |
40 | |
41 | + connect(m_fsAction, SIGNAL(removedThenAdded(QFileInfo)), |
42 | + this, SLOT(onItemChangedOutSideFm(QFileInfo))); |
43 | + |
44 | connect(m_fsAction, SIGNAL(error(QString,QString)), |
45 | this, SIGNAL(error(QString,QString))); |
46 | |
47 | @@ -229,7 +229,7 @@ |
48 | role = FileNameRole + index.column(); |
49 | #else |
50 | if (role < FileNameRole || role > TrackCoverRole) { |
51 | - qWarning() << Q_FUNC_INFO << "Got an out of range role: " << role; |
52 | + qWarning() << Q_FUNC_INFO << this << "Got an out of range role: " << role; |
53 | return QVariant(); |
54 | } |
55 | |
56 | @@ -304,7 +304,7 @@ |
57 | #if !defined(REGRESSION_TEST_FOLDERLISTMODEL) |
58 | // this should not happen, ever |
59 | Q_ASSERT(false); |
60 | - qWarning() << Q_FUNC_INFO << "Got an unknown role: " << role; |
61 | + qWarning() << Q_FUNC_INFO << this << "Got an unknown role: " << role; |
62 | #endif |
63 | break; |
64 | } |
65 | @@ -326,29 +326,17 @@ |
66 | if (mAwaitingResults) { |
67 | // TODO: handle the case where pathName != our current path, cancel old |
68 | // request, start a new one |
69 | - qDebug() << Q_FUNC_INFO << "Ignoring path change request, request already running"; |
70 | + qDebug() << Q_FUNC_INFO << this << "Ignoring path change request, request already running"; |
71 | return; |
72 | } |
73 | |
74 | -#if DEBUG_EXT_FS_WATCHER |
75 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
76 | - << Q_FUNC_INFO |
77 | - << "changing current path to:" << pathName; |
78 | -#endif |
79 | - |
80 | - /* |
81 | - * if active the External File System Watcher is stopped |
82 | - */ |
83 | - stoptExternalFsWatcher(); |
84 | - |
85 | mAwaitingResults = true; |
86 | emit awaitingResultsChanged(); |
87 | #if DEBUG_MESSAGES |
88 | - qDebug() << Q_FUNC_INFO << "Changing to " << pathName << " on " << QThread::currentThreadId(); |
89 | + qDebug() << Q_FUNC_INFO << this << "Changing to " << pathName << " on " << QThread::currentThreadId(); |
90 | #endif |
91 | - beginResetModel(); |
92 | - mDirectoryContents.clear(); |
93 | - endResetModel(); |
94 | + |
95 | + clear(); |
96 | |
97 | DirListWorker *dlw = createWorkerRequest(IORequest::DirList, pathName); |
98 | connect(dlw, SIGNAL(itemsAdded(QVector<QFileInfo>)), SLOT(onItemsAdded(QVector<QFileInfo>))); |
99 | @@ -356,14 +344,14 @@ |
100 | ioWorkerThread()->addRequest(dlw); |
101 | |
102 | mCurrentDir = pathName; |
103 | - emit pathChanged(pathName); |
104 | + emit pathChanged(pathName); |
105 | } |
106 | |
107 | |
108 | void DirModel::onResultsFetched() { |
109 | if (mAwaitingResults) { |
110 | #if DEBUG_MESSAGES |
111 | - qDebug() << Q_FUNC_INFO << "No longer awaiting results"; |
112 | + qDebug() << Q_FUNC_INFO << this << "No longer awaiting results"; |
113 | #endif |
114 | mAwaitingResults = false; |
115 | emit awaitingResultsChanged(); |
116 | @@ -373,7 +361,7 @@ |
117 | void DirModel::onItemsAdded(const QVector<QFileInfo> &newFiles) |
118 | { |
119 | #if DEBUG_MESSAGES |
120 | - qDebug() << Q_FUNC_INFO << "Got new files: " << newFiles.count(); |
121 | + qDebug() << Q_FUNC_INFO << this << "Got new files: " << newFiles.count(); |
122 | #endif |
123 | |
124 | foreach (const QFileInfo &fi, newFiles) { |
125 | @@ -403,7 +391,7 @@ |
126 | bool DirModel::rename(int row, const QString &newName) |
127 | { |
128 | #if DEBUG_MESSAGES |
129 | - qDebug() << Q_FUNC_INFO << "Renaming " << row << " to " << newName; |
130 | + qDebug() << Q_FUNC_INFO << this << "Renaming " << row << " to " << newName; |
131 | #endif |
132 | |
133 | if (!IS_VALID_ROW(row)) { |
134 | @@ -419,7 +407,7 @@ |
135 | bool retval = f.rename(newFullFilename); |
136 | if (!retval) |
137 | { |
138 | - qDebug() << Q_FUNC_INFO << "Rename returned error code: " << f.error() << f.errorString(); |
139 | + qDebug() << Q_FUNC_INFO << this << "Rename returned error code: " << f.error() << f.errorString(); |
140 | emit(QObject::tr("Rename error"), f.errorString()); |
141 | } |
142 | else |
143 | @@ -437,7 +425,7 @@ |
144 | bool retval = dir.mkdir(newDir); |
145 | if (!retval) { |
146 | const char *errorStr = strerror(errno); |
147 | - qDebug() << Q_FUNC_INFO << "Error creating new directory: " << errno << " (" << errorStr << ")"; |
148 | + qDebug() << Q_FUNC_INFO << this << "Error creating new directory: " << errno << " (" << errorStr << ")"; |
149 | emit error(QObject::tr("Error creating new folder"), errorStr); |
150 | } else { |
151 | onItemAdded(dir.filePath(newDir)); |
152 | @@ -514,16 +502,16 @@ |
153 | { |
154 | QDir dir(mCurrentDir); |
155 | if (dir.isRoot()) { |
156 | - qDebug() << Q_FUNC_INFO << "already at root"; |
157 | + qDebug() << Q_FUNC_INFO << this << "already at root"; |
158 | return mCurrentDir; |
159 | } |
160 | |
161 | bool success = dir.cdUp(); |
162 | if (!success) { |
163 | - qWarning() << Q_FUNC_INFO << "Failed to to go to parent of " << mCurrentDir; |
164 | + qWarning() << Q_FUNC_INFO << this << "Failed to to go to parent of " << mCurrentDir; |
165 | return mCurrentDir; |
166 | } |
167 | - qDebug() << Q_FUNC_INFO << "returning" << dir.absolutePath(); |
168 | + qDebug() << Q_FUNC_INFO << this << "returning" << dir.absolutePath(); |
169 | return dir.absolutePath(); |
170 | } |
171 | |
172 | @@ -703,8 +691,11 @@ |
173 | void DirModel::onItemRemoved(const QFileInfo &fi) |
174 | { |
175 | int row = rowOfItem(fi); |
176 | -#if DEBUG_MESSAGES |
177 | - qDebug() << Q_FUNC_INFO << "row" << row; |
178 | +#if DEBUG_MESSAGES || DEBUG_EXT_FS_WATCHER |
179 | + qDebug() << Q_FUNC_INFO << this |
180 | + << "row" << row |
181 | + << "name" << fi.absoluteFilePath() |
182 | + << "removed[True|False]:" << (row >= 0); |
183 | #endif |
184 | if (row >= 0) |
185 | { |
186 | @@ -750,7 +741,7 @@ |
187 | int idx = mDirectoryContents.count(); |
188 | |
189 | if (it == mDirectoryContents.end()) { |
190 | - beginInsertRows(QModelIndex(), mDirectoryContents.count(), mDirectoryContents.count()); |
191 | + beginInsertRows(QModelIndex(), idx, idx); |
192 | mDirectoryContents.append(fi); |
193 | endInsertRows(); |
194 | } else { |
195 | @@ -1043,108 +1034,87 @@ |
196 | reqThread = new ExternalFileSystemChangesWorker(mDirectoryContents, |
197 | pathName, |
198 | dirFilter, mIsRecursive); |
199 | - } |
200 | - connect(reqThread, SIGNAL(fetchingContents(QDateTime)), |
201 | - this, SLOT(onFetchingContents(QDateTime))); |
202 | + } |
203 | return reqThread; |
204 | } |
205 | |
206 | |
207 | -/*! |
208 | - * \brief DirModel::onFetchingContents() slot that is called before any fetch directory operation |
209 | - * |
210 | - * It can be called in two situations: |
211 | - * \li 1. When a user change the current directory, then new content needs be fetched |
212 | - * in this case the timer should be inactive |
213 | - * \li 2. When the external File System Watcher is active and was requested to get the contents |
214 | - * in order to compare and then notify changes. In this case the timer should be already active |
215 | - * |
216 | - * \sa startExternalFsWatcher(), stoptExternalFsWatcher() |
217 | - */ |
218 | -void DirModel::onFetchingContents(QDateTime lastModifiedPath) |
219 | -{ |
220 | - mLastModifiedCurrentPath = lastModifiedPath; |
221 | - if (mEnableExternalFSWatcher) |
222 | - { |
223 | - startExternalFsWatcher(); |
224 | -#if DEBUG_EXT_FS_WATCHER |
225 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
226 | - << Q_FUNC_INFO |
227 | - << "setting modified path" << mLastModifiedCurrentPath.toString("hh:mm:ss.zzz"); |
228 | -#endif |
229 | - } |
230 | -} |
231 | - |
232 | |
233 | /*! |
234 | * \brief DirModel::startExternalFsWatcher() starts the External File System Watcher |
235 | */ |
236 | void DirModel::startExternalFsWatcher() |
237 | { |
238 | - if (!IS_EXT_FS_WATCHER_TIMER_ACTIVE() && mEnableExternalFSWatcher) |
239 | - { |
240 | - mExternalFSWatcherTimer = startTimer(EX_FS_WATCHER_TIMER_INTERVAL); |
241 | #if DEBUG_EXT_FS_WATCHER |
242 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
243 | - << Q_FUNC_INFO << "timerID" << mExternalFSWatcherTimer; |
244 | + qDebug() << "[extFsWorker]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
245 | + << Q_FUNC_INFO << this; |
246 | |
247 | #endif |
248 | - |
249 | + if (!mExtFSWatcher) |
250 | + { |
251 | + mExtFSWatcher = new ExternalFSWatcher(this); |
252 | + mExtFSWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL); |
253 | + connect(this, SIGNAL(pathChanged(QString)), |
254 | + mExtFSWatcher, SLOT(setCurrentPath(QString))); |
255 | + |
256 | + connect(mExtFSWatcher, SIGNAL(pathModified()), |
257 | + this, SLOT(onThereAreExternalChanges())); |
258 | + |
259 | + //setCurrentPath() checks for empty paths |
260 | + mExtFSWatcher->setCurrentPath(mCurrentDir); |
261 | } |
262 | } |
263 | |
264 | |
265 | |
266 | /*! |
267 | - * \brief DirModel::stoptExternalFsWatcher() stops the External File System Watcher |
268 | + * \brief DirModel::stoptExternalFsWatcher stops the External File System Watcher |
269 | */ |
270 | void DirModel::stoptExternalFsWatcher() |
271 | { |
272 | #if DEBUG_EXT_FS_WATCHER |
273 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
274 | - << Q_FUNC_INFO; |
275 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
276 | + << Q_FUNC_INFO << this; |
277 | #endif |
278 | - if (IS_EXT_FS_WATCHER_TIMER_ACTIVE()) |
279 | + if (mExtFSWatcher) |
280 | { |
281 | - killTimer(mExternalFSWatcherTimer); |
282 | - mExternalFSWatcherTimer = NO_EXT_FS_WATCHER_TIMER; |
283 | + delete mExtFSWatcher; |
284 | + mExtFSWatcher = 0; |
285 | } |
286 | } |
287 | |
288 | |
289 | -void DirModel::timerEvent(QTimerEvent *) |
290 | +void DirModel::onThereAreExternalChanges() |
291 | { |
292 | - if ( mEnableExternalFSWatcher |
293 | - && IS_FILE_MANAGER_IDLE() |
294 | - && mLastModifiedCurrentPath < curPathModifiedDate() ) |
295 | + if ( IS_FILE_MANAGER_IDLE() ) |
296 | { |
297 | #if DEBUG_EXT_FS_WATCHER |
298 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
299 | - << Q_FUNC_INFO << "File System modified"; |
300 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
301 | + << Q_FUNC_INFO << this << "File System modified"; |
302 | #endif |
303 | DirListWorker *w = |
304 | createWorkerRequest(IORequest::DirListExternalFSChanges, |
305 | mCurrentDir |
306 | ); |
307 | - ExternalFileSystemChangesWorker *fsWatcher = |
308 | + ExternalFileSystemChangesWorker *extFsWorker = |
309 | static_cast<ExternalFileSystemChangesWorker*> (w); |
310 | |
311 | - connect(fsWatcher, SIGNAL(added(QFileInfo)), |
312 | + connect(extFsWorker, SIGNAL(added(QFileInfo)), |
313 | this, SLOT(onItemAddedOutsideFm(QFileInfo))); |
314 | - connect(fsWatcher, SIGNAL(removed(QFileInfo)), |
315 | + connect(extFsWorker, SIGNAL(removed(QFileInfo)), |
316 | this, SLOT(onItemRemovedOutSideFm(QFileInfo))); |
317 | - connect(fsWatcher, SIGNAL(changed(QFileInfo)), |
318 | + connect(extFsWorker, SIGNAL(changed(QFileInfo)), |
319 | this, SLOT(onItemChangedOutSideFm(QFileInfo))); |
320 | - connect(fsWatcher, SIGNAL(finished()), |
321 | - this, SLOT(onExternalFsWatcherFinihed())); |
322 | + connect(extFsWorker, SIGNAL(finished(int)), |
323 | + this, SLOT(onExternalFsWorkerFinished(int))); |
324 | |
325 | - ioWorkerThread()->addRequest(fsWatcher); |
326 | + ioWorkerThread()->addRequest(extFsWorker); |
327 | } |
328 | #if DEBUG_EXT_FS_WATCHER |
329 | else |
330 | { |
331 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
332 | - << Q_FUNC_INFO << "nothing to do"; |
333 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
334 | + << Q_FUNC_INFO << this << "Busy, nothing to do"; |
335 | } |
336 | #endif |
337 | } |
338 | @@ -1155,18 +1125,24 @@ |
339 | */ |
340 | void DirModel::onItemAddedOutsideFm(const QFileInfo &fi) |
341 | { |
342 | - if (mEnableExternalFSWatcher && IS_FILE_MANAGER_IDLE()) |
343 | +#if DEBUG_EXT_FS_WATCHER |
344 | + int before = rowCount(); |
345 | +#endif |
346 | + if (IS_FILE_MANAGER_IDLE()) |
347 | { |
348 | int row = rowOfItem(fi); |
349 | if (row == -1) |
350 | { |
351 | -#if DEBUG_EXT_FS_WATCHER |
352 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
353 | - << Q_FUNC_INFO << "added" << fi.absoluteFilePath(); |
354 | -#endif |
355 | onItemAdded(fi); |
356 | } |
357 | } |
358 | +#if DEBUG_EXT_FS_WATCHER |
359 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
360 | + << Q_FUNC_INFO << this |
361 | + << "counterBefore:" << before |
362 | + << "added" << fi.absoluteFilePath() |
363 | + << "counterAfter:" << rowCount(); |
364 | +#endif |
365 | } |
366 | |
367 | /*! |
368 | @@ -1178,11 +1154,11 @@ |
369 | */ |
370 | void DirModel::onItemRemovedOutSideFm(const QFileInfo &fi) |
371 | { |
372 | - if (mEnableExternalFSWatcher && IS_FILE_MANAGER_IDLE()) |
373 | + if (IS_FILE_MANAGER_IDLE()) |
374 | { |
375 | #if DEBUG_EXT_FS_WATCHER |
376 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
377 | - << Q_FUNC_INFO << "removed" << fi.absoluteFilePath(); |
378 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
379 | + << Q_FUNC_INFO << this << "removed" << fi.absoluteFilePath(); |
380 | #endif |
381 | onItemRemoved(fi); |
382 | } |
383 | @@ -1195,12 +1171,12 @@ |
384 | */ |
385 | void DirModel::onItemChangedOutSideFm(const QFileInfo &fi) |
386 | { |
387 | - if (mEnableExternalFSWatcher && IS_FILE_MANAGER_IDLE()) |
388 | + if (IS_FILE_MANAGER_IDLE()) |
389 | { |
390 | int row = rowOfItem(fi); |
391 | #if DEBUG_EXT_FS_WATCHER |
392 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
393 | - << Q_FUNC_INFO << "changed" << fi.absoluteFilePath() |
394 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
395 | + << Q_FUNC_INFO << this << "changed" << fi.absoluteFilePath() |
396 | << "from row" << row; |
397 | #endif |
398 | if (row >= 0) |
399 | @@ -1222,24 +1198,29 @@ |
400 | /*! |
401 | * \brief DirModel::onExternalFsWatcherFinihed() |
402 | */ |
403 | -void DirModel::onExternalFsWatcherFinihed() |
404 | +void DirModel::onExternalFsWorkerFinished(int currentDirCounter) |
405 | { |
406 | - mLastModifiedCurrentPath = curPathModifiedDate(); |
407 | + |
408 | #if DEBUG_EXT_FS_WATCHER |
409 | - qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
410 | - << Q_FUNC_INFO |
411 | - << "path modfied" << mLastModifiedCurrentPath.toString("hh:mm:ss.zzz"); |
412 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
413 | + << Q_FUNC_INFO << this |
414 | + << "currentDirCounter:" << currentDirCounter; |
415 | + |
416 | #endif |
417 | + if (currentDirCounter == 0 && IS_FILE_MANAGER_IDLE()) |
418 | + { |
419 | + clear(); |
420 | + } |
421 | } |
422 | |
423 | |
424 | /*! |
425 | - * \brief DirModel::getEnabledExternalFSWatcher() |
426 | + * \brief DirModel:getEnabledExternalFSWatcher() |
427 | * \return true if the External File System Watcher is enabled |
428 | */ |
429 | bool DirModel::getEnabledExternalFSWatcher() const |
430 | { |
431 | - return mEnableExternalFSWatcher; |
432 | + return mExtFSWatcher ? true : false; |
433 | } |
434 | |
435 | |
436 | @@ -1249,14 +1230,9 @@ |
437 | */ |
438 | void DirModel::setEnabledExternalFSWatcher(bool enable) |
439 | { |
440 | - mEnableExternalFSWatcher = enable; |
441 | - if (enable) |
442 | + if(enable) |
443 | { |
444 | - //if a directory is already and the timer is not acive, start the timer |
445 | - if (canReadDir(mCurrentDir)) |
446 | - { |
447 | - startExternalFsWatcher(); |
448 | - } |
449 | + startExternalFsWatcher(); |
450 | } |
451 | else |
452 | { |
453 | @@ -1396,6 +1372,13 @@ |
454 | } |
455 | |
456 | |
457 | +void DirModel::clear() |
458 | +{ |
459 | + beginResetModel(); |
460 | + mDirectoryContents.clear(); |
461 | + endResetModel(); |
462 | +} |
463 | + |
464 | |
465 | #ifndef DO_NOT_USE_TAG_LIB |
466 | QVariant DirModel::getAudioMetaData(const QFileInfo& fi, int role) const |
467 | |
468 | === modified file 'folderlistmodel/dirmodel.h' |
469 | --- folderlistmodel/dirmodel.h 2013-10-06 14:49:04 +0000 |
470 | +++ folderlistmodel/dirmodel.h 2013-11-20 14:23:19 +0000 |
471 | @@ -43,6 +43,7 @@ |
472 | #include "filecompare.h" |
473 | |
474 | class FileSystemAction; |
475 | +class ExternalFSWatcher; |
476 | |
477 | /*! |
478 | * When the External File System Wathcer is enabled, |
479 | @@ -50,7 +51,7 @@ |
480 | * |
481 | * \sa setEnabledExternalFSWatcher() |
482 | */ |
483 | -#define EX_FS_WATCHER_TIMER_INTERVAL 3100 |
484 | +#define EX_FS_WATCHER_TIMER_INTERVAL 900 |
485 | |
486 | class DirModel : public QAbstractListModel |
487 | { |
488 | @@ -104,7 +105,7 @@ |
489 | Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) |
490 | inline QString path() const { return mCurrentDir; } |
491 | void setPath(const QString &pathName); |
492 | - |
493 | + |
494 | Q_INVOKABLE QDateTime curPathAccessedDate() const; |
495 | Q_INVOKABLE QDateTime curPathCreatedDate() const; |
496 | Q_INVOKABLE QDateTime curPathModifiedDate() const; |
497 | @@ -112,7 +113,6 @@ |
498 | Q_INVOKABLE QString curPathCreatedDateLocaleShort() const; |
499 | Q_INVOKABLE QString curPathModifiedDateLocaleShort() const; |
500 | Q_INVOKABLE bool curPathIsWritable() const; |
501 | - |
502 | |
503 | Q_PROPERTY(bool awaitingResults READ awaitingResults NOTIFY awaitingResultsChanged) |
504 | bool awaitingResults() const; |
505 | @@ -373,28 +373,27 @@ |
506 | const QString& pathName); |
507 | bool canReadDir(const QFileInfo& d) const; |
508 | bool canReadFile(const QFileInfo& f) const; |
509 | - QFileInfo setParentIfRelative(const QString &fileOrDir) const; |
510 | + QFileInfo setParentIfRelative(const QString &fileOrDir) const; |
511 | |
512 | private: |
513 | void startExternalFsWatcher(); |
514 | void stoptExternalFsWatcher(); |
515 | + void clear(); |
516 | private slots: |
517 | - void onFetchingContents(QDateTime); |
518 | void onItemAddedOutsideFm(const QFileInfo&fi); |
519 | void onItemRemovedOutSideFm(const QFileInfo&); |
520 | void onItemChangedOutSideFm(const QFileInfo&fi); |
521 | - void onExternalFsWatcherFinihed(); |
522 | -protected: |
523 | - virtual void timerEvent(QTimerEvent *); |
524 | + void onThereAreExternalChanges(); |
525 | + void onExternalFsWorkerFinished(int); |
526 | + |
527 | |
528 | private: |
529 | - bool mShowHiddenFiles; |
530 | - SortBy mSortBy; |
531 | - SortOrder mSortOrder; |
532 | - CompareFunction mCompareFunction; |
533 | - int mExternalFSWatcherTimer; |
534 | - bool mEnableExternalFSWatcher; |
535 | - QDateTime mLastModifiedCurrentPath; |
536 | + bool mShowHiddenFiles; |
537 | + SortBy mSortBy; |
538 | + SortOrder mSortOrder; |
539 | + CompareFunction mCompareFunction; |
540 | + ExternalFSWatcher* mExtFSWatcher; |
541 | + |
542 | |
543 | private: |
544 | FileSystemAction * m_fsAction; //!< it does file system recursive remove/copy/move |
545 | |
546 | === added file 'folderlistmodel/externalfswatcher.cpp' |
547 | --- folderlistmodel/externalfswatcher.cpp 1970-01-01 00:00:00 +0000 |
548 | +++ folderlistmodel/externalfswatcher.cpp 2013-11-20 14:23:19 +0000 |
549 | @@ -0,0 +1,114 @@ |
550 | +/************************************************************************** |
551 | + * |
552 | + * Copyright 2013 Canonical Ltd. |
553 | + * Copyright 2013 Carlos J Mazieri <carlos.mazieri@gmail.com> |
554 | + * |
555 | + * This program is free software; you can redistribute it and/or modify |
556 | + * it under the terms of the GNU Lesser General Public License as published by |
557 | + * the Free Software Foundation; version 3. |
558 | + * |
559 | + * This program is distributed in the hope that it will be useful, |
560 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
561 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
562 | + * GNU Lesser General Public License for more details. |
563 | + * |
564 | + * You should have received a copy of the GNU Lesser General Public License |
565 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
566 | + * |
567 | + * File: externalfswatcher.cpp |
568 | + * Date: 9/14/2013 |
569 | + */ |
570 | + |
571 | +#include "externalfswatcher.h" |
572 | + |
573 | +#include <QTimer> |
574 | +#include <QDateTime> |
575 | +#include <QDebug> |
576 | + |
577 | +#if DEBUG_EXT_FS_WATCHER |
578 | +# define DEBUG_FSWATCHER() \ |
579 | + qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") \ |
580 | + << Q_FUNC_INFO << "m_setPath:" << m_setPath \ |
581 | + << "m_changedPath:" << m_changedPath \ |
582 | + << "m_waitingEmit:" << m_waitingEmitCounter |
583 | +#else |
584 | +# define DEBUG_FSWATCHER() /**/ |
585 | +#endif // |
586 | + |
587 | + |
588 | +ExternalFSWatcher::ExternalFSWatcher(QObject *parent) : |
589 | + QFileSystemWatcher(parent) |
590 | + , m_waitingEmitCounter(0) |
591 | + , m_msWaitTime(DEFAULT_NOTICATION_PERIOD) |
592 | +{ |
593 | + connect(this, SIGNAL(directoryChanged(QString)), |
594 | + this, SLOT(slotDirChanged(QString))); |
595 | +} |
596 | + |
597 | + |
598 | +void ExternalFSWatcher::setCurrentPath(const QString &curPath) |
599 | +{ |
600 | + if (!curPath.isEmpty()) |
601 | + { |
602 | + if (m_setPath != curPath) |
603 | + { |
604 | + if (!m_setPath.isEmpty()) |
605 | + { |
606 | + removePath(m_setPath); |
607 | + } |
608 | + m_setPath = curPath; |
609 | + addPath(m_setPath); |
610 | + } |
611 | + } |
612 | + DEBUG_FSWATCHER(); |
613 | +} |
614 | + |
615 | + |
616 | +void ExternalFSWatcher::slotDirChanged(const QString &dir) |
617 | +{ |
618 | + DEBUG_FSWATCHER(); |
619 | + if ( (m_setPath == dir) |
620 | + && ( m_waitingEmitCounter == 0 || m_setPath != m_changedPath ) |
621 | + ) |
622 | + { |
623 | + removePath(m_setPath); |
624 | + ++m_waitingEmitCounter; |
625 | + m_changedPath = m_setPath; |
626 | + QTimer::singleShot(m_msWaitTime, this, SLOT(slotFireChanges())); |
627 | + } |
628 | +} |
629 | + |
630 | + |
631 | +/*! |
632 | + * \brief ExternalFSWatcher::slotFireChanges() emits \ref pathModified() only when it is sure |
633 | + * that the current path was changed. |
634 | + * |
635 | + * A change for the current path (the last current) MUST be notified at least once. |
636 | + */ |
637 | +void ExternalFSWatcher::slotFireChanges() |
638 | +{ |
639 | + if (--m_waitingEmitCounter == 0) |
640 | + { |
641 | + addPath(m_setPath); |
642 | + if (m_setPath == m_changedPath) |
643 | + { |
644 | + emit pathModified(); |
645 | +#if DEBUG_EXT_FS_WATCHER |
646 | + DEBUG_FSWATCHER() << "emit pathModified()"; |
647 | +#endif |
648 | + } |
649 | + } |
650 | +} |
651 | + |
652 | + |
653 | + |
654 | +void ExternalFSWatcher::setIntervalToNotifyChanges(int ms) |
655 | +{ |
656 | + m_msWaitTime = ms; |
657 | +} |
658 | + |
659 | + |
660 | +int ExternalFSWatcher::getIntervalToNotifyChanges() const |
661 | +{ |
662 | + return m_msWaitTime; |
663 | +} |
664 | |
665 | === added file 'folderlistmodel/externalfswatcher.h' |
666 | --- folderlistmodel/externalfswatcher.h 1970-01-01 00:00:00 +0000 |
667 | +++ folderlistmodel/externalfswatcher.h 2013-11-20 14:23:19 +0000 |
668 | @@ -0,0 +1,68 @@ |
669 | +/************************************************************************** |
670 | + * |
671 | + * Copyright 2013 Canonical Ltd. |
672 | + * Copyright 2013 Carlos J Mazieri <carlos.mazieri@gmail.com> |
673 | + * |
674 | + * This program is free software; you can redistribute it and/or modify |
675 | + * it under the terms of the GNU Lesser General Public License as published by |
676 | + * the Free Software Foundation; version 3. |
677 | + * |
678 | + * This program is distributed in the hope that it will be useful, |
679 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
680 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
681 | + * GNU Lesser General Public License for more details. |
682 | + * |
683 | + * You should have received a copy of the GNU Lesser General Public License |
684 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
685 | + * |
686 | + * File: externalfswatcher.h |
687 | + * Date: 9/14/2013 |
688 | + */ |
689 | + |
690 | +#ifndef EXTERNALFSWATCHER_H |
691 | +#define EXTERNALFSWATCHER_H |
692 | + |
693 | +#include <QFileSystemWatcher> |
694 | + |
695 | +#define DEFAULT_NOTICATION_PERIOD 500 |
696 | + |
697 | + |
698 | +/*! |
699 | + * \brief The ExternalFSWatcher class notifies the owner when the File System when the current path \a m_setPath has changed |
700 | + * emitting pathModified() signal. |
701 | + * |
702 | + * The current path \a m_setPath is set by using the slot \ref setCurrentPath() |
703 | + * |
704 | + * The idea of this class is to minimize notifications as the current path can change quickly. |
705 | + * A notification will occur if it was requested for a path and this path is still the current at the moment |
706 | + * of the notification. |
707 | + * |
708 | + * Once it detects a change it will wait \ref getIntervalToNotifyChanges() milliseconds to notify that change. |
709 | + * At this moment it checks if no \ref setCurrentPath() has been called during this time and then notifies that change. |
710 | + */ |
711 | +class ExternalFSWatcher : public QFileSystemWatcher |
712 | +{ |
713 | + Q_OBJECT |
714 | +public: |
715 | + explicit ExternalFSWatcher(QObject *parent = 0); |
716 | + int getIntervalToNotifyChanges() const; |
717 | + |
718 | +signals: |
719 | + void pathModified(); |
720 | + |
721 | + public slots: |
722 | + void setCurrentPath(const QString& curPath); |
723 | + void setIntervalToNotifyChanges(int ms); |
724 | + |
725 | +private slots: |
726 | + void slotDirChanged(const QString&); |
727 | + void slotFireChanges(); |
728 | + |
729 | + private: |
730 | + QString m_setPath; |
731 | + QString m_changedPath; |
732 | + unsigned m_waitingEmitCounter; |
733 | + int m_msWaitTime; |
734 | +}; |
735 | + |
736 | +#endif // EXTERNALFSWATCHER_H |
737 | |
738 | === modified file 'folderlistmodel/filesystemaction.cpp' |
739 | --- folderlistmodel/filesystemaction.cpp 2013-10-31 23:49:07 +0000 |
740 | +++ folderlistmodel/filesystemaction.cpp 2013-11-20 14:23:19 +0000 |
741 | @@ -68,13 +68,11 @@ |
742 | |
743 | #define COMMON_SIZE_ITEM 120 |
744 | |
745 | -RemoveNotifier FileSystemAction::m_removeNotifier; |
746 | |
747 | static QLatin1String GNOME_COPIED_MIME_TYPE ("x-special/gnome-copied-files"); |
748 | static QLatin1String KDE_CUT_MIME_TYPE ("application/x-kde-cutselection"); |
749 | |
750 | |
751 | - |
752 | class DirModelMimeData : public QMimeData |
753 | { |
754 | public: |
755 | @@ -414,41 +412,6 @@ |
756 | return paths; |
757 | } |
758 | |
759 | -/*! |
760 | - * \brief RemoveNotifier::RemoveNotifier |
761 | - * \param parent |
762 | - */ |
763 | -RemoveNotifier::RemoveNotifier(QObject *parent) : |
764 | - QObject(parent) |
765 | -{ |
766 | -} |
767 | - |
768 | -//=============================================================================================== |
769 | -/*! |
770 | - * \brief RemoveNotifier::notifyRemoved |
771 | - * \param fi |
772 | - */ |
773 | -void RemoveNotifier::notifyRemoved(const QFileInfo &fi) |
774 | -{ |
775 | -#if DEBUG_MESSAGES |
776 | - qDebug() << Q_FUNC_INFO << "emit removed(QFileInfo)" << fi.absoluteFilePath(); |
777 | -#endif |
778 | - emit removed(fi); |
779 | -} |
780 | - |
781 | -//=============================================================================================== |
782 | -/*! |
783 | - * \brief RemoveNotifier::notifyRemoved |
784 | - * \param item |
785 | - */ |
786 | -void RemoveNotifier::notifyRemoved(const QString &item) |
787 | -{ |
788 | -#if DEBUG_MESSAGES |
789 | - qDebug() << Q_FUNC_INFO << "emit removed(QString)" << item; |
790 | -#endif |
791 | - emit removed(item); |
792 | -} |
793 | - |
794 | |
795 | //=============================================================================================== |
796 | /*! |
797 | @@ -463,14 +426,6 @@ |
798 | , m_mimeData ( new DirModelMimeData() ) |
799 | , m_clipboardModifiedByOther(false) |
800 | { |
801 | - //as m_removeNotifier is static it will send signals to all instances of |
802 | - //the model |
803 | - connect(&m_removeNotifier, SIGNAL(removed(QFileInfo)), |
804 | - this, SIGNAL(removed(QFileInfo))); |
805 | - |
806 | - connect(&m_removeNotifier, SIGNAL(removed(QString)), |
807 | - this, SIGNAL(removed(QString))); |
808 | - |
809 | QClipboard *clipboard = QApplication::clipboard(); |
810 | |
811 | connect(clipboard, SIGNAL(dataChanged()), this, SIGNAL(clipboardChanged())); |
812 | @@ -543,10 +498,10 @@ |
813 | { |
814 | emit error(QObject::tr("File or Directory does not exist"), |
815 | pathname + QObject::tr(" does not exist") |
816 | - ); |
817 | + ); |
818 | return; |
819 | } |
820 | - ActionEntry * entry = new ActionEntry(); |
821 | + ActionEntry * entry = new ActionEntry(); |
822 | //this is the item being handled |
823 | entry->reversedOrder.append(info); |
824 | // verify if the destination item already exists |
825 | @@ -563,11 +518,11 @@ |
826 | QDirIterator it(info.absoluteFilePath(), |
827 | QDir::AllEntries | QDir::System | |
828 | QDir::NoDotAndDotDot | QDir::Hidden, |
829 | - QDirIterator::Subdirectories); |
830 | + QDirIterator::Subdirectories); |
831 | while (it.hasNext() && !it.next().isEmpty()) |
832 | - { |
833 | - entry->reversedOrder.prepend(it.fileInfo()); |
834 | - } |
835 | + { |
836 | + entry->reversedOrder.prepend(it.fileInfo()); |
837 | + } |
838 | } |
839 | //set steps and total bytes considering all items in the Entry |
840 | int counter = entry->reversedOrder.count(); |
841 | @@ -575,7 +530,7 @@ |
842 | int sizeSteps = 0; |
843 | int bufferSize = (COPY_BUFFER_SIZE * STEP_FILES); |
844 | while (counter--) |
845 | - { |
846 | + { |
847 | const QFileInfo & item = entry->reversedOrder.at(counter); |
848 | size = (item.isFile() && !item.isDir() && !item.isSymLink()) ? |
849 | item.size() : COMMON_SIZE_ITEM; |
850 | @@ -587,11 +542,11 @@ |
851 | if ( !(size % bufferSize) ) |
852 | { |
853 | --sizeSteps; |
854 | - } |
855 | + } |
856 | action->steps += sizeSteps ; |
857 | - } |
858 | } |
859 | } |
860 | + } |
861 | //set final steps for the Entry based on Items number |
862 | int entrySteps = entry->reversedOrder.count() / STEP_FILES; |
863 | if ( entry->reversedOrder.count() % STEP_FILES) entrySteps++; |
864 | @@ -723,17 +678,33 @@ |
865 | if (m_curAction->type == ActionRemove || m_curAction->type == ActionMove || |
866 | m_curAction->type == ActionHardMoveRemove) |
867 | { |
868 | - m_removeNotifier.notifyRemoved(mainItem); // notify all instances |
869 | + emit removed(mainItem); |
870 | } |
871 | if (m_curAction->type == ActionCopy || m_curAction->type == ActionMove || |
872 | - m_curAction->type == ActionHardMoveCopy) |
873 | + m_curAction->type == ActionHardMoveCopy) |
874 | { |
875 | + bool toAdd = true; |
876 | QString addedItem = targetFom(mainItem.absoluteFilePath(), m_curAction); |
877 | if (curEntry->alreadyExists) |
878 | { |
879 | - m_removeNotifier.notifyRemoved(addedItem); |
880 | - } |
881 | - emit added(addedItem); |
882 | + //if an item already exists, even we remove the original item and then add |
883 | + //the same item again (maybe a new content), |
884 | + //BUT: we want to notify it as a change to NOT give a chance to External File System Watcher |
885 | + //to get it during the time it is (removed + added) |
886 | + if (m_curAction->type == ActionHardMoveCopy) |
887 | + { |
888 | + emit removed(addedItem); |
889 | + } |
890 | + else |
891 | + { //ActionCopy ActionMove |
892 | + emit removedThenAdded(QFileInfo(addedItem)); |
893 | + toAdd = false; |
894 | + } |
895 | + } |
896 | + if(toAdd) |
897 | + { |
898 | + emit added(addedItem); |
899 | + } |
900 | } |
901 | m_curAction->currEntryIndex++; |
902 | //check if is doing a hard move and the copy part has finished |
903 | @@ -1051,29 +1022,29 @@ |
904 | void FileSystemAction::paste() |
905 | { |
906 | ClipboardOperation operation; |
907 | - QStringList paths = m_mimeData->localUrls(operation); |
908 | + QStringList paths = m_mimeData->localUrls(operation); |
909 | #if DEBUG_MESSAGES |
910 | qDebug() << Q_FUNC_INFO << paths; |
911 | #endif |
912 | if (paths.count()) |
913 | - { |
914 | + { |
915 | ActionType actionType = ActionCopy; // start with Copy and check for Cut |
916 | if (operation == ClipboardCut) |
917 | { |
918 | //we allow Copy to backup items, but Cut must Fail |
919 | - if (QFileInfo(m_path).absoluteFilePath() == QFileInfo(paths.at(0)).absolutePath()) |
920 | - { |
921 | - emit error(tr("Cannot paste"), |
922 | - tr("origin and destination folder are the same")); |
923 | - return; |
924 | - } |
925 | - //so far it always returns true since on Linux it is possible to rename |
926 | - // between different file systems |
927 | - if ( moveUsingSameFileSystem(paths.at(0)) ) { |
928 | - actionType = ActionMove; |
929 | - } else { |
930 | - actionType = ActionHardMoveCopy; // first step |
931 | - } |
932 | + if (QFileInfo(m_path).absoluteFilePath() == QFileInfo(paths.at(0)).absolutePath()) |
933 | + { |
934 | + emit error(tr("Cannot paste"), |
935 | + tr("origin and destination folder are the same")); |
936 | + return; |
937 | + } |
938 | + //so far it always returns true since on Linux it is possible to rename |
939 | + // between different file systems |
940 | + if ( moveUsingSameFileSystem(paths.at(0)) ) { |
941 | + actionType = ActionMove; |
942 | + } else { |
943 | + actionType = ActionHardMoveCopy; // first step |
944 | + } |
945 | } |
946 | createAndProcessAction(actionType, paths, operation); |
947 | } |
948 | @@ -1096,17 +1067,17 @@ |
949 | myAction = createAction(actionType, origPathLen); |
950 | myAction->operation = operation; |
951 | myAction->origPath = QFileInfo(paths.at(0)).absolutePath(); |
952 | - myAction->baseOrigSize = myAction->origPath.length(); |
953 | + myAction->baseOrigSize = myAction->origPath.length(); |
954 | for (int counter=0; counter < paths.count(); counter++) |
955 | - { |
956 | + { |
957 | addEntry(myAction, paths.at(counter)); |
958 | } |
959 | if (myAction->totalItems > 0) |
960 | { |
961 | - if (actionType == ActionHardMoveCopy) |
962 | - { |
963 | - myAction->totalItems *= 2; //duplicate this |
964 | - } |
965 | + if (actionType == ActionHardMoveCopy) |
966 | + { |
967 | + myAction->totalItems *= 2; //duplicate this |
968 | + } |
969 | /* |
970 | if (actionType == ActionHardMoveCopy || actionType == ActionCopy) |
971 | { |
972 | @@ -1115,17 +1086,17 @@ |
973 | myAction->steps += myAction->totalBytes / (COPY_BUFFER_SIZE * STEP_FILES); |
974 | } |
975 | */ |
976 | - if (operation == ClipboardCut) |
977 | - { |
978 | - //this must still be false when cut finishes to change the clipboard to the target |
979 | - m_clipboardModifiedByOther = false; |
980 | - } |
981 | - m_queuedActions.append(myAction); |
982 | - if (!m_busy) |
983 | - { |
984 | - processAction(); |
985 | - } |
986 | - } |
987 | + if (operation == ClipboardCut) |
988 | + { |
989 | + //this must still be false when cut finishes to change the clipboard to the target |
990 | + m_clipboardModifiedByOther = false; |
991 | + } |
992 | + m_queuedActions.append(myAction); |
993 | + if (!m_busy) |
994 | + { |
995 | + processAction(); |
996 | + } |
997 | +} |
998 | else |
999 | { // no items were added into the Action, maybe items were removed |
1000 | //addEntry() emits error() signal when items do not exist |
1001 | @@ -1144,7 +1115,7 @@ |
1002 | * \return full pathname of target |
1003 | */ |
1004 | QString FileSystemAction::targetFom(const QString& origItem, const Action* const action) |
1005 | -{ |
1006 | +{ |
1007 | QString destinationUnderTarget(origItem.mid(action->baseOrigSize)); |
1008 | if (action->currEntry && action->currEntry->newName) |
1009 | { |
1010 | @@ -1354,7 +1325,7 @@ |
1011 | endActionEntry(); |
1012 | } |
1013 | else |
1014 | - { |
1015 | + { |
1016 | if (copySingleFileDone) |
1017 | { |
1018 | m_curAction->copyFile.clear(); |
1019 | |
1020 | === modified file 'folderlistmodel/filesystemaction.h' |
1021 | --- folderlistmodel/filesystemaction.h 2013-08-18 12:19:36 +0000 |
1022 | +++ folderlistmodel/filesystemaction.h 2013-11-20 14:23:19 +0000 |
1023 | @@ -43,7 +43,6 @@ |
1024 | #include <QVector> |
1025 | |
1026 | class DirModelMimeData; |
1027 | -class RemoveNotifier; |
1028 | class QFile; |
1029 | class QTemporaryFile; |
1030 | |
1031 | @@ -104,7 +103,7 @@ |
1032 | |
1033 | public slots: |
1034 | void cancel(); |
1035 | - void remove(const QStringList& filePaths); |
1036 | + void remove(const QStringList & filePaths); |
1037 | void pathChanged(const QString& path); |
1038 | void paste(); |
1039 | void cut(const QStringList&); |
1040 | @@ -116,6 +115,7 @@ |
1041 | void removed(const QFileInfo&); |
1042 | void added(const QString& ); |
1043 | void added(const QFileInfo& ); |
1044 | + void removedThenAdded(const QFileInfo&); |
1045 | void progress(int curItem, int totalItems, int percent); |
1046 | void clipboardChanged(); |
1047 | |
1048 | @@ -201,8 +201,7 @@ |
1049 | QVector<Action*> m_queuedActions; //!< work always at item 0, after finishing taking item 0 out |
1050 | Action * m_curAction; |
1051 | bool m_cancelCurrentAction; |
1052 | - bool m_busy; |
1053 | - static RemoveNotifier m_removeNotifier; |
1054 | + bool m_busy; |
1055 | QString m_path; |
1056 | DirModelMimeData * m_mimeData; |
1057 | QString m_errorTitle; |
1058 | |
1059 | === modified file 'folderlistmodel/folderlistmodel.pri' |
1060 | --- folderlistmodel/folderlistmodel.pri 2013-10-31 23:49:07 +0000 |
1061 | +++ folderlistmodel/folderlistmodel.pri 2013-11-20 14:23:19 +0000 |
1062 | @@ -4,6 +4,7 @@ |
1063 | $$PWD/ioworkerthread.cpp \ |
1064 | $$PWD/filesystemaction.cpp \ |
1065 | $$PWD/filecompare.cpp \ |
1066 | + $$PWD/externalfswatcher.cpp |
1067 | |
1068 | |
1069 | |
1070 | @@ -14,6 +15,7 @@ |
1071 | $$PWD/ioworkerthread.h \ |
1072 | $$PWD/filesystemaction.h \ |
1073 | $$PWD/filecompare.h \ |
1074 | + $$PWD/externalfswatcher.h |
1075 | |
1076 | |
1077 | |
1078 | |
1079 | === modified file 'folderlistmodel/iorequest.cpp' |
1080 | --- folderlistmodel/iorequest.cpp 2013-10-31 23:49:07 +0000 |
1081 | +++ folderlistmodel/iorequest.cpp 2013-11-20 14:23:19 +0000 |
1082 | @@ -75,10 +75,9 @@ |
1083 | { |
1084 | #if DEBUG_EXT_FS_WATCHER |
1085 | qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
1086 | - << Q_FUNC_INFO; |
1087 | + << Q_FUNC_INFO; |
1088 | #endif |
1089 | - QVector<QFileInfo> directoryContents; |
1090 | - emit fetchingContents(QFileInfo(mPathName).lastModified()); |
1091 | + QVector<QFileInfo> directoryContents; |
1092 | directoryContents = add(mPathName, mFilter, mIsRecursive, directoryContents); |
1093 | return directoryContents; |
1094 | } |
1095 | @@ -132,42 +131,52 @@ |
1096 | void ExternalFileSystemChangesWorker::run() |
1097 | { |
1098 | QVector<QFileInfo> directoryContents = getContents(); |
1099 | + int addedCounter=0; |
1100 | + int removedCounter=0; |
1101 | #if DEBUG_EXT_FS_WATCHER |
1102 | qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
1103 | - << Q_FUNC_INFO << "checking added and changed files"; |
1104 | + << Q_FUNC_INFO |
1105 | + << "m_curContent.count():" << m_curContent.count() |
1106 | + << "directoryContents.count():" << directoryContents.count(); |
1107 | #endif |
1108 | int counter = directoryContents.count(); |
1109 | - while (counter--) |
1110 | + if (counter > 0) |
1111 | { |
1112 | - const QFileInfo& originalItem = directoryContents.at(counter); |
1113 | - const QFileInfo existItem = m_curContent.value(originalItem.absoluteFilePath()); |
1114 | - if ( existItem.exists() ) |
1115 | - { |
1116 | - //it may have changed |
1117 | - if ( originalItem.size() != existItem.size() |
1118 | - || originalItem.lastModified() != existItem.lastModified() |
1119 | - || originalItem.permissions() != existItem.permissions() |
1120 | - ) |
1121 | - { |
1122 | - emit changed(originalItem); |
1123 | - } |
1124 | - //remove this item |
1125 | - m_curContent.remove(originalItem.absoluteFilePath()); |
1126 | + while (counter--) |
1127 | + { |
1128 | + const QFileInfo& originalItem = directoryContents.at(counter); |
1129 | + const QFileInfo existItem = m_curContent.value(originalItem.absoluteFilePath()); |
1130 | + if ( existItem.exists() ) |
1131 | + { |
1132 | + //it may have changed |
1133 | + if ( originalItem.size() != existItem.size() |
1134 | + || originalItem.lastModified() != existItem.lastModified() |
1135 | + || originalItem.permissions() != existItem.permissions() |
1136 | + ) |
1137 | + { |
1138 | + emit changed(originalItem); |
1139 | + } |
1140 | + //remove this item |
1141 | + m_curContent.remove(originalItem.absoluteFilePath()); |
1142 | + } |
1143 | + else // originalItem was added |
1144 | + { |
1145 | + emit added(originalItem); |
1146 | + ++addedCounter; |
1147 | + } |
1148 | } |
1149 | - else // originalItem was added |
1150 | - { |
1151 | - emit added(originalItem); |
1152 | + |
1153 | + QHash<QString, QFileInfo>::iterator i = m_curContent.begin(); |
1154 | + for ( ; i != m_curContent.end(); ++removedCounter, ++i ) |
1155 | + { |
1156 | + emit removed(i.value()); |
1157 | } |
1158 | } |
1159 | #if DEBUG_EXT_FS_WATCHER |
1160 | qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
1161 | - << Q_FUNC_INFO << "checking for removed files"; |
1162 | + << Q_FUNC_INFO |
1163 | + << "addedCounter:" << addedCounter |
1164 | + << "removedCounter:" << removedCounter; |
1165 | #endif |
1166 | - QHash<QString, QFileInfo>::iterator i = m_curContent.begin(); |
1167 | - while ( i != m_curContent.end() ) |
1168 | - { |
1169 | - emit removed(i.value()); |
1170 | - ++i; |
1171 | - } |
1172 | - emit finished(); |
1173 | + emit finished(counter); |
1174 | } |
1175 | |
1176 | === modified file 'folderlistmodel/iorequest.h' |
1177 | --- folderlistmodel/iorequest.h 2013-07-06 15:13:48 +0000 |
1178 | +++ folderlistmodel/iorequest.h 2013-11-20 14:23:19 +0000 |
1179 | @@ -70,7 +70,6 @@ |
1180 | explicit DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive); |
1181 | void run(); |
1182 | signals: |
1183 | - void fetchingContents(QDateTime); |
1184 | void itemsAdded(const QVector<QFileInfo> &files); |
1185 | void workerFinished(); |
1186 | |
1187 | @@ -101,7 +100,7 @@ |
1188 | void removed(const QFileInfo&); |
1189 | void changed(const QFileInfo&); |
1190 | void added(const QFileInfo& ); |
1191 | - void finished(); |
1192 | + void finished(int); |
1193 | private: |
1194 | QHash<QString, QFileInfo> m_curContent; //!< using hash because the vector can be in any order |
1195 | }; |
1196 | |
1197 | === modified file 'folderlistmodel/iorequestworker.cpp' |
1198 | --- folderlistmodel/iorequestworker.cpp 2013-07-06 14:55:25 +0000 |
1199 | +++ folderlistmodel/iorequestworker.cpp 2013-11-20 14:23:19 +0000 |
1200 | @@ -76,35 +76,11 @@ |
1201 | if (mRequests.empty()) |
1202 | mWaitCondition.wait(&mMutex); |
1203 | |
1204 | - int counter = 0; |
1205 | - while (!mRequests.isEmpty()) |
1206 | - { |
1207 | - /* If there are more than one thread in the queue and there is at least one |
1208 | - * of the type Auto Refresh, do: |
1209 | - * 1. if all threads are type Auto Refresh (leave just one) it might not happen but we check it here |
1210 | - * 2. if there is at least one type DirList, remove all type Auto Refresh, the user might have changed |
1211 | - * the current dir when the Auto Refresh was already in the queue |
1212 | - */ |
1213 | - if ( (counter=mRequests.count()) > 1) |
1214 | - { |
1215 | - int autoRefreshCounter = 0; |
1216 | - for(int aux=0; aux < counter; aux++) |
1217 | - { |
1218 | - if (mRequests.at(aux)->type() == IORequest::DirListExternalFSChanges) |
1219 | - { |
1220 | - autoRefreshCounter++; |
1221 | - } |
1222 | - } |
1223 | - if (autoRefreshCounter) |
1224 | - { |
1225 | - removeAutoRefreshThread( (autoRefreshCounter == counter) |
1226 | - ? counter -1 |
1227 | - : autoRefreshCounter |
1228 | - ); |
1229 | - } |
1230 | - } |
1231 | - IORequest *request = mRequests.takeFirst(); |
1232 | + while (!mRequests.isEmpty()) { |
1233 | + IORequest *request = mRequests.takeFirst(); |
1234 | + |
1235 | lock.unlock(); |
1236 | + |
1237 | request->run(); |
1238 | request->deleteLater(); |
1239 | lock.relock(); |
1240 | @@ -122,19 +98,3 @@ |
1241 | mTimeToQuit = true; |
1242 | mWaitCondition.wakeOne(); |
1243 | } |
1244 | - |
1245 | - |
1246 | - |
1247 | -void IORequestWorker::removeAutoRefreshThread(int toRemoveCounter) |
1248 | -{ |
1249 | - int counter = mRequests.count(); |
1250 | - while(counter-- && toRemoveCounter) |
1251 | - { |
1252 | - if (mRequests.at(counter)->type() == IORequest::DirListExternalFSChanges) |
1253 | - { |
1254 | - --toRemoveCounter; |
1255 | - IORequest *request = mRequests.takeAt(counter); |
1256 | - delete request; |
1257 | - } |
1258 | - } |
1259 | -} |
1260 | |
1261 | === modified file 'folderlistmodel/iorequestworker.h' |
1262 | --- folderlistmodel/iorequestworker.h 2013-06-29 20:36:26 +0000 |
1263 | +++ folderlistmodel/iorequestworker.h 2013-11-20 14:23:19 +0000 |
1264 | @@ -52,9 +52,6 @@ |
1265 | void exit(); |
1266 | |
1267 | private: |
1268 | - void removeAutoRefreshThread(int toRemoveCounter); |
1269 | - |
1270 | -private: |
1271 | QMutex mMutex; |
1272 | QWaitCondition mWaitCondition; |
1273 | QList<IORequest *> mRequests; |
1274 | |
1275 | === modified file 'test_folderlistmodel/regression/regression_folderlilstmodel.pro' |
1276 | --- test_folderlistmodel/regression/regression_folderlilstmodel.pro 2013-08-24 18:30:29 +0000 |
1277 | +++ test_folderlistmodel/regression/regression_folderlilstmodel.pro 2013-11-20 14:23:19 +0000 |
1278 | @@ -26,3 +26,5 @@ |
1279 | |
1280 | # DEFINES += DEBUG_REMOVE |
1281 | |
1282 | +#DEFINES += DEBUG_EXT_FS_WATCHER |
1283 | + |
1284 | |
1285 | === modified file 'test_folderlistmodel/regression/tst_folderlistmodel.cpp' |
1286 | --- test_folderlistmodel/regression/tst_folderlistmodel.cpp 2013-11-02 12:21:29 +0000 |
1287 | +++ test_folderlistmodel/regression/tst_folderlistmodel.cpp 2013-11-20 14:23:19 +0000 |
1288 | @@ -1,6 +1,7 @@ |
1289 | #include "filesystemaction.h" |
1290 | #include "dirmodel.h" |
1291 | #include "tempfiles.h" |
1292 | +#include "externalfswatcher.h" |
1293 | #include <stdio.h> |
1294 | |
1295 | #ifndef DO_NOT_USE_TAG_LIB |
1296 | @@ -72,6 +73,7 @@ |
1297 | void cancel(int index, int, int percent); |
1298 | void slotclipboardChanged(); |
1299 | void slotError(QString title, QString message); |
1300 | + void slotExtFsWatcherPathModified() { ++m_extFSWatcherPathModifiedCounter; } |
1301 | |
1302 | private Q_SLOTS: |
1303 | void initTestCase(); //before all tests |
1304 | @@ -117,6 +119,10 @@ |
1305 | void existsFileAndCanReadFile(); |
1306 | void pathProperties(); |
1307 | void watchExternalChanges(); |
1308 | + void extFsWatcherChangePathManyTimesModifyAllPathsLessLast(); // no notification |
1309 | + void extFsWatcherModifySamePathManyTimesWithInInterval(); // just one notification |
1310 | + void extFsWatcherSetPathAndModifyManyTimesWithInInterval();// just one notification |
1311 | + void extFsWatcherChangePathManyTimesModifyManyTimes(); // many notifications |
1312 | |
1313 | //define TEST_OPENFILES to test QDesktopServices::openUrl() for some files |
1314 | #if defined(TEST_OPENFILES) |
1315 | @@ -167,6 +173,7 @@ |
1316 | QFileIconProvider m_provider; |
1317 | QString m_currentPath; |
1318 | QString m_fileToRemoveInProgressSignal; |
1319 | + int m_extFSWatcherPathModifiedCounter; |
1320 | |
1321 | }; |
1322 | |
1323 | @@ -357,6 +364,29 @@ |
1324 | void TestDirModel::initModels() |
1325 | { |
1326 | cleanModels(); |
1327 | + m_dirModel_01 = new DirModel(); |
1328 | + m_dirModel_02 = new DirModel(); |
1329 | + |
1330 | + connect(m_dirModel_01->m_fsAction, SIGNAL(added(QString)), |
1331 | + this, SLOT(slotFileAdded(QString)) ); |
1332 | + connect(m_dirModel_01->m_fsAction, SIGNAL(removed(QString)), |
1333 | + this, SLOT(slotFileRemoved(QString)) ); |
1334 | + connect(m_dirModel_01->m_fsAction, SIGNAL(added(QFileInfo)), |
1335 | + this, SLOT(slotFileAdded(QFileInfo))); |
1336 | + connect(m_dirModel_01->m_fsAction, SIGNAL(removed(QFileInfo)), |
1337 | + this, SLOT(slotFileRemoved(QFileInfo))); |
1338 | + |
1339 | + connect(m_dirModel_02->m_fsAction, SIGNAL(added(QString)), |
1340 | + this, SLOT(slotFileAdded(QString)) ); |
1341 | + connect(m_dirModel_02->m_fsAction, SIGNAL(removed(QString)), |
1342 | + this, SLOT(slotFileRemoved(QString)) ); |
1343 | + connect(m_dirModel_02->m_fsAction, SIGNAL(added(QFileInfo)), |
1344 | + this, SLOT(slotFileAdded(QFileInfo))); |
1345 | + connect(m_dirModel_02->m_fsAction, SIGNAL(removed(QFileInfo)), |
1346 | + this, SLOT(slotFileRemoved(QFileInfo))); |
1347 | + |
1348 | + m_dirModel_01->setEnabledExternalFSWatcher(true); |
1349 | + m_dirModel_02->setEnabledExternalFSWatcher(true); |
1350 | } |
1351 | |
1352 | |
1353 | @@ -396,6 +426,7 @@ |
1354 | m_receivedErrorSignal = false; |
1355 | m_progressNotificationsCounter = 0; |
1356 | m_visibleProgressMessages = false; |
1357 | + m_extFSWatcherPathModifiedCounter = 0; |
1358 | } |
1359 | |
1360 | |
1361 | @@ -415,6 +446,7 @@ |
1362 | m_fileToRemoveInProgressSignal.clear(); |
1363 | m_progressNotificationsCounter = 0; |
1364 | m_visibleProgressMessages = false; |
1365 | + m_extFSWatcherPathModifiedCounter = 0; |
1366 | } |
1367 | |
1368 | |
1369 | @@ -504,7 +536,6 @@ |
1370 | m_deepDir_01 = new DeepDir("modelRemoveRecursiveDirByIndex", level); |
1371 | QCOMPARE( QFileInfo(m_deepDir_01->path()).exists(), true); |
1372 | |
1373 | - m_dirModel_01 = new DirModel(); |
1374 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1375 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1376 | |
1377 | @@ -535,7 +566,6 @@ |
1378 | files.create(1); |
1379 | items.append(files.lastPath()); |
1380 | |
1381 | - m_dirModel_01 = new DirModel(); |
1382 | connect(m_dirModel_01, SIGNAL(progress(int,int,int)), |
1383 | this, SLOT(progress(int,int,int))); |
1384 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1385 | @@ -563,7 +593,6 @@ |
1386 | files.create(4); |
1387 | QCOMPARE(files.howManyExist(), filesToCreate); |
1388 | |
1389 | - m_dirModel_01 = new DirModel(); |
1390 | m_dirModel_01->setPath(files.lastPath()); |
1391 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1392 | |
1393 | @@ -583,8 +612,7 @@ |
1394 | { |
1395 | QString orig("modelCopyDirToAnotherModel_orig"); |
1396 | |
1397 | - m_deepDir_01 = new DeepDir(orig, 1); |
1398 | - m_dirModel_01 = new DirModel(); |
1399 | + m_deepDir_01 = new DeepDir(orig, 1); |
1400 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1401 | connect(m_dirModel_01, SIGNAL(clipboardChanged()), |
1402 | this, SLOT(slotclipboardChanged())); |
1403 | @@ -593,7 +621,6 @@ |
1404 | |
1405 | QString target("modelCopyDirToAnotherModel_target"); |
1406 | m_deepDir_02 = new DeepDir(target, 0); |
1407 | - m_dirModel_02 = new DirModel(); |
1408 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1409 | this, SLOT(progress(int,int,int))); |
1410 | m_dirModel_02->setPath(m_deepDir_02->path()); |
1411 | @@ -621,8 +648,7 @@ |
1412 | { |
1413 | QString orig("modelCopyManyItemstoAnotherModel_orig"); |
1414 | |
1415 | - m_deepDir_01 = new DeepDir(orig, 5); |
1416 | - m_dirModel_01 = new DirModel(); |
1417 | + m_deepDir_01 = new DeepDir(orig, 5); |
1418 | connect(m_dirModel_01, SIGNAL(clipboardChanged()), |
1419 | this, SLOT(slotclipboardChanged())); |
1420 | const int filesCreated = 10; |
1421 | @@ -650,8 +676,7 @@ |
1422 | QCOMPARE(m_dirModel_01->rowCount(), itemsCreated); |
1423 | |
1424 | QString target("modelCopyManyItemstoAnotherModel_target"); |
1425 | - m_deepDir_02 = new DeepDir(target, 0); |
1426 | - m_dirModel_02 = new DirModel(); |
1427 | + m_deepDir_02 = new DeepDir(target, 0); |
1428 | m_dirModel_02->setPath(m_deepDir_02->path()); |
1429 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1430 | this, SLOT(progress(int,int,int))); |
1431 | @@ -690,15 +715,12 @@ |
1432 | empty.addSubDirLevel(orig); |
1433 | empty.touch(itemsCreated); |
1434 | |
1435 | - |
1436 | - m_dirModel_01 = new DirModel(); |
1437 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1438 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1439 | QCOMPARE(m_dirModel_01->rowCount(), itemsCreated); |
1440 | |
1441 | QString target("modelCopyTwoEmptyFiles_target"); |
1442 | m_deepDir_02 = new DeepDir(target, 0); |
1443 | - m_dirModel_02 = new DirModel(); |
1444 | m_dirModel_02->setPath(m_deepDir_02->path()); |
1445 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1446 | this, SLOT(progress(int,int,int))); |
1447 | @@ -730,14 +752,12 @@ |
1448 | tempFile.addSubDirLevel(orig); |
1449 | tempFile.create(); |
1450 | |
1451 | - m_dirModel_01 = new DirModel(); |
1452 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1453 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1454 | QCOMPARE(m_dirModel_01->rowCount(), 1); |
1455 | |
1456 | QString target("modelCopyFileAndRemoveBeforePaste_target"); |
1457 | - m_deepDir_02 = new DeepDir(target, 0); |
1458 | - m_dirModel_02 = new DirModel(); |
1459 | + m_deepDir_02 = new DeepDir(target, 0); |
1460 | m_dirModel_02->setPath(m_deepDir_02->path()); |
1461 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1462 | this, SLOT(progress(int,int,int))); |
1463 | @@ -769,14 +789,12 @@ |
1464 | tempFile.addSubDirLevel(orig); |
1465 | tempFile.create(); |
1466 | |
1467 | - m_dirModel_01 = new DirModel(); |
1468 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1469 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1470 | QCOMPARE(m_dirModel_01->rowCount(), 1); |
1471 | |
1472 | QString target("modelCopyPasteFileAndRemoveWhenFirstProgressSignalArrives_target"); |
1473 | m_deepDir_02 = new DeepDir(target, 0); |
1474 | - m_dirModel_02 = new DirModel(); |
1475 | m_dirModel_02->setPath(m_deepDir_02->path()); |
1476 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1477 | this, SLOT(slotRemoveFileWhenProgressArrive(int,int,int))); |
1478 | @@ -800,8 +818,7 @@ |
1479 | { |
1480 | QString orig("modelCutManyItemsPasteIntoAnotherModel_orig"); |
1481 | |
1482 | - m_deepDir_01 = new DeepDir(orig, 5); |
1483 | - m_dirModel_01 = new DirModel(); |
1484 | + m_deepDir_01 = new DeepDir(orig, 5); |
1485 | connect(m_dirModel_01, SIGNAL(clipboardChanged()), |
1486 | this, SLOT(slotclipboardChanged())); |
1487 | const int filesCreated = 10; |
1488 | @@ -815,8 +832,7 @@ |
1489 | QCOMPARE(m_dirModel_01->rowCount(), itemsCreated); |
1490 | |
1491 | QString target("modelCutManyItemsPasteIntoAnotherModel_target"); |
1492 | - m_deepDir_02 = new DeepDir(target, 0); |
1493 | - m_dirModel_02 = new DirModel(); |
1494 | + m_deepDir_02 = new DeepDir(target, 0); |
1495 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1496 | this, SLOT(progress(int,int,int))); |
1497 | connect(m_dirModel_02, SIGNAL(error(QString,QString)), |
1498 | @@ -832,7 +848,7 @@ |
1499 | |
1500 | m_dirModel_01->cutPaths(allFiles); |
1501 | m_visibleProgressMessages = true; |
1502 | - m_dirModel_02->paste(); |
1503 | + m_dirModel_02->paste(); |
1504 | int steps = m_dirModel_02->getProgressCounter(); |
1505 | QTest::qWait(TIME_TO_PROCESS); |
1506 | |
1507 | @@ -847,7 +863,7 @@ |
1508 | QString orig("fsActionMoveItemsForcingCopyAndThenRemove_orig"); |
1509 | |
1510 | m_deepDir_01 = new DeepDir(orig, 1); |
1511 | - m_dirModel_01 = new DirModel(); |
1512 | + |
1513 | const int filesCreated = 4; |
1514 | const int itemsCreated = filesCreated +1; |
1515 | |
1516 | @@ -860,12 +876,10 @@ |
1517 | |
1518 | QString target("fsActionMoveItemsForcingCopyAndThenRemove_target"); |
1519 | m_deepDir_02 = new DeepDir(target, 0); |
1520 | - m_dirModel_02 = new DirModel(); |
1521 | + |
1522 | m_dirModel_02->setPath(m_deepDir_02->path()); |
1523 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1524 | |
1525 | - connect(m_dirModel_02->m_fsAction, SIGNAL(added(QString)), |
1526 | - this, SLOT(slotFileAdded(QString))); |
1527 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1528 | this, SLOT(progress(int,int,int))); |
1529 | |
1530 | @@ -894,7 +908,6 @@ |
1531 | m_deepDir_01 = new DeepDir("modelCancelRemoveAction", level); |
1532 | QCOMPARE( QFileInfo(m_deepDir_01->path()).exists(), true); |
1533 | |
1534 | - m_dirModel_01 = new DirModel(); |
1535 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1536 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1537 | |
1538 | @@ -915,9 +928,7 @@ |
1539 | } |
1540 | |
1541 | void TestDirModel::modelTestFileSize() |
1542 | -{ |
1543 | - m_dirModel_01 = new DirModel(); |
1544 | - |
1545 | +{ |
1546 | QCOMPARE(m_dirModel_01->fileSize(0), QString("0 Bytes")); |
1547 | QCOMPARE(m_dirModel_01->fileSize(1023), QString("1023 Bytes")); |
1548 | QCOMPARE(m_dirModel_01->fileSize(1024), QString("1.0 kB")); |
1549 | @@ -935,7 +946,6 @@ |
1550 | m_deepDir_01 = new DeepDir("modelRemoveDirWithHiddenFilesAndLinks", level); |
1551 | QCOMPARE( QFileInfo(m_deepDir_01->path()).exists(), true); |
1552 | |
1553 | - m_dirModel_01 = new DirModel(); |
1554 | m_dirModel_01->setShowHiddenFiles(true); |
1555 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1556 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1557 | @@ -995,14 +1005,13 @@ |
1558 | } |
1559 | big.close(); |
1560 | |
1561 | - m_dirModel_01 = new DirModel(); |
1562 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1563 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1564 | QCOMPARE(m_dirModel_01->rowCount(), 1); |
1565 | |
1566 | QString target("modelCancelCopyAction_target"); |
1567 | m_deepDir_02 = new DeepDir(target, 0); |
1568 | - m_dirModel_02 = new DirModel(); |
1569 | + |
1570 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1571 | this, SLOT(progress(int,int,int))); |
1572 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1573 | @@ -1034,7 +1043,6 @@ |
1574 | QVERIFY(files.count() > 0); |
1575 | QCOMPARE(createLink(files.at(0).absoluteFilePath(), QLatin1String("link_to_file")), true); |
1576 | |
1577 | - m_dirModel_01 = new DirModel(); |
1578 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1579 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1580 | QCOMPARE(m_dirModel_01->rowCount(), 2); |
1581 | @@ -1042,7 +1050,6 @@ |
1582 | |
1583 | QString target("modelCopyFileAndDirectoryLinks_target"); |
1584 | m_deepDir_02 = new DeepDir(target, 0); |
1585 | - m_dirModel_02 = new DirModel(); |
1586 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1587 | this, SLOT(progress(int,int,int))); |
1588 | |
1589 | @@ -1085,7 +1092,6 @@ |
1590 | info_before[counter] = QFileInfo(created_files.at(counter)); |
1591 | } |
1592 | |
1593 | - m_dirModel_01 = new DirModel(); |
1594 | m_dirModel_01->setPath(files.lastPath()); |
1595 | connect(m_dirModel_01, SIGNAL(error(QString,QString)), |
1596 | this, SLOT(slotError(QString,QString))); |
1597 | @@ -1125,7 +1131,6 @@ |
1598 | QStringList created_files(files.createdList()); |
1599 | QCOMPARE(created_files.count(), files_to_create); |
1600 | |
1601 | - m_dirModel_01 = new DirModel(); |
1602 | m_dirModel_01->setPath(files.lastPath()); |
1603 | |
1604 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1605 | @@ -1133,7 +1138,6 @@ |
1606 | created_files.append(m_deepDir_01->firstLevel()); |
1607 | |
1608 | m_dirModel_01->copyPaths(created_files); |
1609 | - m_dirModel_02 = new DirModel(); |
1610 | connect(m_dirModel_02, SIGNAL(error(QString,QString)), |
1611 | this, SLOT(slotError(QString,QString))); |
1612 | |
1613 | @@ -1174,7 +1178,6 @@ |
1614 | DeepDir t2(target2,0); |
1615 | DeepDir t3(target3,0); |
1616 | |
1617 | - m_dirModel_01 = new DirModel(); |
1618 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1619 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1620 | QCOMPARE(items.count(), m_dirModel_01->rowCount()); |
1621 | @@ -1229,10 +1232,9 @@ |
1622 | DeepDir t2(target2,0); |
1623 | DeepDir t3(target3,0); |
1624 | |
1625 | - m_dirModel_01 = new DirModel(); |
1626 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1627 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1628 | - QCOMPARE(items.count(), m_dirModel_01->rowCount()); |
1629 | + QCOMPARE(items.count(), m_dirModel_01->rowCount()); |
1630 | m_dirModel_01->cutPaths(items); |
1631 | |
1632 | DirModel model1; |
1633 | @@ -1266,7 +1268,6 @@ |
1634 | { |
1635 | QString orig("modelCopyPasteAndPasteAgain_orig"); |
1636 | m_deepDir_01 = new DeepDir(orig, 1); |
1637 | - m_dirModel_01 = new DirModel(); |
1638 | connect(m_dirModel_01, SIGNAL(error(QString,QString)), |
1639 | this, SLOT(slotError(QString,QString))); |
1640 | |
1641 | @@ -1277,25 +1278,10 @@ |
1642 | |
1643 | QString target("modelCopyPasteAndPasteAgain_target"); |
1644 | m_deepDir_02 = new DeepDir(target, 0); |
1645 | - m_dirModel_02 = new DirModel(); |
1646 | connect(m_dirModel_02, SIGNAL(error(QString,QString)), |
1647 | this, SLOT(slotError(QString,QString))); |
1648 | |
1649 | - m_dirModel_02->setPath(m_deepDir_02->path()); |
1650 | - connect(m_dirModel_02->m_fsAction, SIGNAL(added(QFileInfo)), |
1651 | - this, SLOT(slotFileAdded(QFileInfo))); |
1652 | - connect(m_dirModel_02->m_fsAction, SIGNAL(added(QString)), |
1653 | - this, SLOT(slotFileAdded(QString))); |
1654 | - |
1655 | -#if 0 /* it is not necessary to connect this signal because it is already handled |
1656 | - * by fsAction member, since the RemoveNotifier is static, the signal is emitted to |
1657 | - * fsAction even it is not being used here |
1658 | - */ |
1659 | - connect(m_dirModel_02->m_fsAction, SIGNAL(removed(QFileInfo)), |
1660 | - this, SLOT(slotFileRemoved(QFileInfo))); |
1661 | - connect(m_dirModel_02->m_fsAction, SIGNAL(removed(QString)), |
1662 | - this, SLOT(slotFileRemoved(QString))); |
1663 | -#endif |
1664 | + m_dirModel_02->setPath(m_deepDir_02->path()); |
1665 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1666 | QCOMPARE(m_dirModel_02->rowCount(), 0); |
1667 | |
1668 | @@ -1313,9 +1299,10 @@ |
1669 | |
1670 | QCOMPARE(compareDirectories(m_deepDir_01->path(), m_deepDir_02->path()), true); |
1671 | QCOMPARE(m_receivedErrorSignal, false); |
1672 | - //same item was removed from view and added again |
1673 | - QCOMPARE(m_filesRemoved.count(), 1); |
1674 | - QCOMPARE(m_filesAdded.count(), 2); |
1675 | + |
1676 | + //when items already exist, changed signal is emitted |
1677 | + QCOMPARE(m_filesRemoved.count(), 0); |
1678 | + QCOMPARE(m_filesAdded.count(), 1); |
1679 | } |
1680 | |
1681 | |
1682 | @@ -1327,20 +1314,20 @@ |
1683 | TempFiles tempFiles_01; |
1684 | TempFiles tempDir_01; |
1685 | |
1686 | - const int createCounter = 8; |
1687 | + const int createCounterTopLevel = 8; |
1688 | + const int createCounterSubLevel = 2; |
1689 | |
1690 | tempFiles_01.addSubDirLevel(orig); |
1691 | - tempFiles_01.create(createCounter - 1); |
1692 | + tempFiles_01.create(createCounterTopLevel); |
1693 | tempDir_01.addSubDirLevel(orig); |
1694 | tempDir_01.addSubDirLevel(moreOneLevel); |
1695 | tempDir_01.create(2); |
1696 | |
1697 | - m_dirModel_01 = new DirModel(); |
1698 | connect(m_dirModel_01, SIGNAL(error(QString,QString)), |
1699 | this, SLOT(slotError(QString,QString))); |
1700 | m_dirModel_01->setPath(tempFiles_01.lastPath()); |
1701 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1702 | - QCOMPARE(m_dirModel_01->rowCount(), createCounter); |
1703 | + QCOMPARE(m_dirModel_01->rowCount(), createCounterTopLevel+1); //those created top level plus the subfolder |
1704 | |
1705 | QString target("modelCutPasteIntoExistentItems_target"); |
1706 | m_deepDir_02 = new DeepDir(target, 0); |
1707 | @@ -1348,25 +1335,21 @@ |
1708 | TempFiles tempDir_02; |
1709 | |
1710 | tempFiles_02.addSubDirLevel(target); |
1711 | - tempFiles_02.create(createCounter -1); |
1712 | + tempFiles_02.create(createCounterTopLevel); |
1713 | tempDir_02.addSubDirLevel(target); |
1714 | tempDir_02.addSubDirLevel(moreOneLevel); |
1715 | - tempDir_02.create(2); |
1716 | - m_dirModel_02 = new DirModel(); |
1717 | + tempDir_02.create(createCounterSubLevel); |
1718 | + |
1719 | connect(m_dirModel_02, SIGNAL(error(QString,QString)), |
1720 | this, SLOT(slotError(QString,QString))); |
1721 | connect(m_dirModel_02, SIGNAL(progress(int,int,int)), |
1722 | this, SLOT(progress(int,int,int))); |
1723 | m_dirModel_02->setPath(tempFiles_02.lastPath()); |
1724 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1725 | - QCOMPARE(m_dirModel_02->rowCount(), createCounter); |
1726 | - |
1727 | - connect(m_dirModel_02->m_fsAction, SIGNAL(added(QFileInfo)), |
1728 | - this, SLOT(slotFileAdded(QFileInfo))); |
1729 | - connect(m_dirModel_02->m_fsAction, SIGNAL(added(QString)), |
1730 | - this, SLOT(slotFileAdded(QString))); |
1731 | - |
1732 | - //both directories have the same content |
1733 | + |
1734 | + QCOMPARE(m_dirModel_02->rowCount(), createCounterTopLevel+1); //those created top level plus the subfolder |
1735 | + |
1736 | + //both directories have the same content |
1737 | QCOMPARE(compareDirectories(tempFiles_01.lastPath(), tempFiles_02.lastPath()), true); |
1738 | |
1739 | //cut from first Model |
1740 | @@ -1378,10 +1361,10 @@ |
1741 | QTest::qWait(TIME_TO_PROCESS *2); |
1742 | |
1743 | QCOMPARE(m_receivedErrorSignal, false); |
1744 | - // same item removed from model_01 (cut) and from model_02 because it already exists there |
1745 | - // for temp directory removed() signal is also emitted, so there is one more |
1746 | - QCOMPARE(m_filesRemoved.count(), createCounter *2 + 1); |
1747 | - QCOMPARE(m_filesAdded.count(), createCounter ); |
1748 | + |
1749 | + QCOMPARE(m_filesRemoved.count(), createCounterTopLevel + createCounterSubLevel); |
1750 | + //when items being copied from COPY or renamed from CUT already exist, they are not added |
1751 | + QCOMPARE(m_filesAdded.count(), 0 ); |
1752 | } |
1753 | |
1754 | |
1755 | @@ -1389,7 +1372,7 @@ |
1756 | { |
1757 | QString orig("openPathAbsouluteAndRelative"); |
1758 | m_deepDir_01 = new DeepDir(orig, 1); |
1759 | - m_dirModel_01 = new DirModel(); |
1760 | + |
1761 | connect(m_dirModel_01, SIGNAL(error(QString,QString)), |
1762 | this, SLOT(slotError(QString,QString))); |
1763 | |
1764 | @@ -1425,7 +1408,6 @@ |
1765 | { |
1766 | QString orig("existsDirAnCanReadDir"); |
1767 | m_deepDir_01 = new DeepDir(orig, 1); |
1768 | - m_dirModel_01 = new DirModel(); |
1769 | |
1770 | connect(m_dirModel_01, SIGNAL(error(QString,QString)), |
1771 | this, SLOT(slotError(QString,QString))); |
1772 | @@ -1471,7 +1453,7 @@ |
1773 | { |
1774 | QString orig("existsFileAndCanReadFile"); |
1775 | m_deepDir_01 = new DeepDir(orig, 1); |
1776 | - m_dirModel_01 = new DirModel(); |
1777 | + |
1778 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1779 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1780 | |
1781 | @@ -1528,7 +1510,6 @@ |
1782 | temp.addSubDirLevel(orig); |
1783 | temp.create(1); |
1784 | |
1785 | - m_dirModel_01 = new DirModel(); |
1786 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1787 | QTest::qWait(TIME_TO_REFRESH_DIR); |
1788 | |
1789 | @@ -1575,31 +1556,37 @@ |
1790 | DirModel thirdFM; |
1791 | thirdFM.setPath(tempUnderFirstLevel.lastPath()); |
1792 | |
1793 | - m_dirModel_01 = new DirModel(); |
1794 | + |
1795 | + connect(m_dirModel_01, SIGNAL(error(QString,QString)), |
1796 | + this, SLOT(slotError(QString,QString))); |
1797 | m_dirModel_01->setPath(m_deepDir_01->path()); |
1798 | - m_dirModel_01->setEnabledExternalFSWatcher(true); |
1799 | - |
1800 | - m_dirModel_02 = new DirModel(); |
1801 | + |
1802 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
1803 | + |
1804 | + connect(m_dirModel_02, SIGNAL(error(QString,QString)), |
1805 | + this, SLOT(slotError(QString,QString))); |
1806 | m_dirModel_02->setPath(m_deepDir_01->path()); |
1807 | - m_dirModel_02->setEnabledExternalFSWatcher(true); |
1808 | |
1809 | - QTest::qWait(TIME_TO_REFRESH_DIR+30); |
1810 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
1811 | |
1812 | QCOMPARE(thirdFM.rowCount(), cut_items); |
1813 | QCOMPARE(m_dirModel_01->rowCount(), 1); |
1814 | QCOMPARE(m_dirModel_02->rowCount(), 1); |
1815 | |
1816 | - //modification loop |
1817 | - int pieceTime = EX_FS_WATCHER_TIMER_INTERVAL/cut_items; |
1818 | - int odd = 0; |
1819 | + qDebug() << "dirModelObjs:" << m_dirModel_01 << m_dirModel_02 << &thirdFM; |
1820 | + |
1821 | QString createdOutsideName; |
1822 | TempFiles createdOutsideFiles; |
1823 | createdOutsideFiles.addSubDirLevel(orig); |
1824 | int total_removed = 0; |
1825 | + int odd=0; |
1826 | + |
1827 | + thirdFM.setEnabledExternalFSWatcher(true); |
1828 | + |
1829 | for ( int counter = 0; counter < cut_items; ++counter ) |
1830 | { |
1831 | thirdFM.cutIndex(0); |
1832 | - if ( (odd ^= 1)) |
1833 | + if ( (odd^=1) ) |
1834 | { |
1835 | m_dirModel_01->paste(); |
1836 | } |
1837 | @@ -1609,24 +1596,26 @@ |
1838 | } |
1839 | QTest::qWait(TIME_TO_PROCESS); |
1840 | //at least one file is removed |
1841 | - if (m_dirModel_01->rowCount() > 1 && |
1842 | + if (m_dirModel_02->rowCount() > 1 && |
1843 | (!total_removed || (QDateTime::currentDateTime().time().msec() % 100) == 0)) |
1844 | { |
1845 | //using index 1 because 0 is a directory and the items are being moved up |
1846 | - m_dirModel_01->removeIndex(1); |
1847 | + m_dirModel_02->removeIndex(1); |
1848 | + QTest::qWait(TIME_TO_PROCESS); |
1849 | ++total_removed; |
1850 | - } |
1851 | - QTest::qWait(pieceTime + TIME_TO_PROCESS); |
1852 | + } |
1853 | createdOutsideName.sprintf("created_%d", counter); |
1854 | createdOutsideFiles.create(createdOutsideName); |
1855 | } |
1856 | - |
1857 | int total_created = 1 + cut_items + createdOutsideFiles.created() - total_removed; |
1858 | - QTest::qWait(EX_FS_WATCHER_TIMER_INTERVAL + TIME_TO_PROCESS + TIME_TO_PROCESS); |
1859 | + QTest::qWait(EX_FS_WATCHER_TIMER_INTERVAL * 2); |
1860 | + qWarning("using 2 instances [cut_items]=%d [created outside]=%d, [removed outside]=%d", cut_items, createdOutsideFiles.created(), total_removed); |
1861 | |
1862 | - qWarning("using 2 instances [created outside]=%d, [removed outside]=%d", createdOutsideFiles.created(), total_removed); |
1863 | QCOMPARE(m_dirModel_01->rowCount(), total_created); |
1864 | - QCOMPARE(m_dirModel_02->rowCount(), total_created); |
1865 | + if (m_dirModel_02->getEnabledExternalFSWatcher()) |
1866 | + { |
1867 | + QCOMPARE(m_dirModel_02->rowCount(), total_created); |
1868 | + } |
1869 | } |
1870 | |
1871 | |
1872 | @@ -1752,7 +1741,6 @@ |
1873 | sound_44100_mp3_data_len); |
1874 | QCOMPARE(mp3File.isEmpty(), false); |
1875 | |
1876 | - m_dirModel_01 = new DirModel(); |
1877 | m_dirModel_01->setReadsMediaMetadata(true); |
1878 | QFileInfo fi(mp3File); |
1879 | |
1880 | @@ -1836,6 +1824,140 @@ |
1881 | #endif |
1882 | |
1883 | |
1884 | +/*! |
1885 | + * \brief TestDirModel::extFsWatcherChangePathManyTimesModifyAllPathsLessLast() expects no Notification |
1886 | + * |
1887 | + * As the current path changes in a small interval of the time and the last path set |
1888 | + * is not modified, the signal pathModified() MUST NOT be fired. |
1889 | + */ |
1890 | +void TestDirModel::extFsWatcherChangePathManyTimesModifyAllPathsLessLast() |
1891 | +{ |
1892 | + ExternalFSWatcher watcher; |
1893 | + connect(&watcher, SIGNAL(pathModified()), |
1894 | + this, SLOT(slotExtFsWatcherPathModified())); |
1895 | + |
1896 | + const int items = 150; |
1897 | + QVector<DeepDir *> deepDirs; |
1898 | + deepDirs.reserve(items); |
1899 | + |
1900 | + for (int counter=1; counter <= items ; ++counter) |
1901 | + { |
1902 | + QString dirName(QString("extModifyAllLessLast") + QString::number(counter)); |
1903 | + DeepDir *d = new DeepDir(dirName,0); |
1904 | + QTest::qWait(1); |
1905 | + watcher.setCurrentPath(d->path()); |
1906 | + if (counter < items) // last dir does not receive a file |
1907 | + { |
1908 | + TempFiles file; |
1909 | + file.addSubDirLevel(dirName); |
1910 | + file.create(); |
1911 | + QTest::qWait(1); |
1912 | + } |
1913 | + deepDirs.append(d); |
1914 | + } |
1915 | + QTest::qWait(TIME_TO_PROCESS); |
1916 | + qDeleteAll(deepDirs); |
1917 | + |
1918 | + QCOMPARE(m_extFSWatcherPathModifiedCounter, 0); |
1919 | +} |
1920 | + |
1921 | + |
1922 | +/*! |
1923 | + * \brief TestDirModel::extFsWatcherChangePathManyTimesModifyManyTimes |
1924 | + * |
1925 | + * Change path many times, force one notification at each path |
1926 | + */ |
1927 | +void TestDirModel::extFsWatcherChangePathManyTimesModifyManyTimes() |
1928 | +{ |
1929 | + ExternalFSWatcher watcher; |
1930 | + connect(&watcher, SIGNAL(pathModified()), |
1931 | + this, SLOT(slotExtFsWatcherPathModified())); |
1932 | + |
1933 | + const int items = 50; |
1934 | + QVector<DeepDir *> deepDirs; |
1935 | + deepDirs.reserve(items); |
1936 | + |
1937 | + for (int counter=0; counter < items ; ++counter) |
1938 | + { |
1939 | + QString dirName(QString("extFsWatcherChangePathManyTimesModifyManyTimes") |
1940 | + + QString::number(counter)); |
1941 | + DeepDir *d = new DeepDir(dirName,0); |
1942 | + watcher.setCurrentPath(d->path()); |
1943 | + TempFiles file; |
1944 | + file.addSubDirLevel(dirName); |
1945 | + file.create(20); |
1946 | + QTest::qWait(watcher.getIntervalToNotifyChanges() + 20); |
1947 | + deepDirs.append(d); |
1948 | + } |
1949 | + QTest::qWait(TIME_TO_PROCESS); |
1950 | + qDeleteAll(deepDirs); |
1951 | + |
1952 | + QCOMPARE(m_extFSWatcherPathModifiedCounter, items); |
1953 | +} |
1954 | + |
1955 | +/*! |
1956 | + * \brief TestDirModel::extFsWatcherModifySamePathManyTimesWithInInterval() expects just one Notification |
1957 | + * |
1958 | + * A path is modified many times in a small time interval than ExternalFSWatcher class notifies changes, |
1959 | + * so only one Notification is expected. |
1960 | + */ |
1961 | +void TestDirModel::extFsWatcherModifySamePathManyTimesWithInInterval() |
1962 | +{ |
1963 | + ExternalFSWatcher watcher; |
1964 | + connect(&watcher, SIGNAL(pathModified()), |
1965 | + this, SLOT(slotExtFsWatcherPathModified())); |
1966 | + |
1967 | + QString dirName("extFsWatcher_expects_just_one_signal"); |
1968 | + m_deepDir_01 = new DeepDir(dirName,0); |
1969 | + watcher.setCurrentPath(m_deepDir_01->path()); |
1970 | + int loop = 10; |
1971 | + int waitTime = watcher.getIntervalToNotifyChanges() / loop - 10; |
1972 | + while (loop--) |
1973 | + { |
1974 | + TempFiles file; |
1975 | + file.addSubDirLevel(dirName); |
1976 | + file.create(QString("file_") + QString::number(loop), 1); |
1977 | + QTest::qWait(waitTime); |
1978 | + } |
1979 | + |
1980 | + QTest::qWait(TIME_TO_PROCESS); |
1981 | + QCOMPARE(m_extFSWatcherPathModifiedCounter, 1 ); |
1982 | +} |
1983 | + |
1984 | + |
1985 | +/*! |
1986 | + * \brief TestDirModel::extFsWatcherSetPathAndModifyManyTimesWithInInterval() expects just one Notification |
1987 | + */ |
1988 | +void TestDirModel::extFsWatcherSetPathAndModifyManyTimesWithInInterval() |
1989 | +{ |
1990 | + ExternalFSWatcher watcher; |
1991 | + connect(&watcher, SIGNAL(pathModified()), |
1992 | + this, SLOT(slotExtFsWatcherPathModified())); |
1993 | + |
1994 | + QList<DeepDir *> deepDirs; |
1995 | + |
1996 | + int loop = 5; |
1997 | + int waitTime = watcher.getIntervalToNotifyChanges() / loop - 5; |
1998 | + |
1999 | + for (int counter=1; counter <= loop ; ++counter) |
2000 | + { |
2001 | + QString dirName(QString("extModifyAll") + QString::number(counter)); |
2002 | + DeepDir *d = new DeepDir(dirName,0); |
2003 | + watcher.setCurrentPath(d->path()); |
2004 | + TempFiles file; |
2005 | + file.addSubDirLevel(dirName); |
2006 | + file.create(); |
2007 | + QTest::qWait(waitTime); |
2008 | + deepDirs.append(d); |
2009 | + } |
2010 | + QTest::qWait(TIME_TO_PROCESS); |
2011 | + qDeleteAll(deepDirs); |
2012 | + |
2013 | + QCOMPARE(m_extFSWatcherPathModifiedCounter, 1); |
2014 | +} |
2015 | + |
2016 | + |
2017 | + |
2018 | int main(int argc, char *argv[]) |
2019 | { |
2020 | QApplication app(argc, argv); |
PASSED: Continuous integration, rev:46 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- ci/9/ 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- raring- amd64-ci/ 9 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- saucy-amd64- ci/9 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- trusty- amd64-ci/ 6
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- ci/9/rebuild
http://