Merge lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-2 into lp:ubuntu-filemanager-app

Proposed by Carlos Jose Mazieri
Status: Merged
Approved by: Arto Jalkanen
Approved revision: 187
Merged at revision: 190
Proposed branch: lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-2
Merge into: lp:ubuntu-filemanager-app
Prerequisite: lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-1
Diff against target: 965 lines (+320/-214)
5 files modified
src/plugin/folderlistmodel/filesystemaction.cpp (+283/-180)
src/plugin/folderlistmodel/filesystemaction.h (+28/-30)
src/plugin/folderlistmodel/locationsfactory.cpp (+5/-1)
src/plugin/folderlistmodel/locationsfactory.h (+2/-2)
src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp (+2/-1)
To merge this branch: bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-2
Reviewer Review Type Date Requested Status
Arto Jalkanen Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+219940@code.launchpad.net

Commit message

ActionPaths now is used in Actions

Description of the change

ActionPaths now is used in Actions.
FileSystemAction::Action::type is kept to indentify the whole Action.

Each entry (item being handled) has its own FileSystemAction::ActionEntry::type,
so they are independent from the whole Action itself.

When restoring items from Trash for example they need to be independent;
the check for different file systems is also made for every item (when moving items),
it used to be done just once for the whole Action.
There will be a "ActionRestoreFromTrash" for the whole action where some items can be retored to different file system while others to the same file system. Items restored to the same file system will have FileSystemAction::ActionEntry::type = ActionMove, while items restored to different file systems will perform two actions: FileSystemAction::ActionEntry::type = ActionHardMoveCopy and FileSystemAction::ActionEntry::type = ActionHardMoveRemove.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Arto Jalkanen (ajalkane) wrote :

1)

39 + delete auxAction;
40 + auxAction = 0;

On line incorrect indentation.

2)

FileSystemAction::Action::~Action()

why not delete auxAction like in reset() ? Looks like it could leak memory.

3)

Not part of the diff, but noticed during review:

void FileSystemAction::processAction()
{
    if (m_curAction)
    {
            delete m_curAction;
            m_curAction = 0;
    }
    if (!m_curAction && m_queuedActions.count())

if (!m_curAction) is unnecessary since it can never happen as it's been deleted just above.

4)

446 + m_errorTitle = QObject::tr("Could remove the directory/file ") +
447 + targetInfo.absoluteFilePath();

Should be "Could not remove ..."

5)

500 + Action *myAction = 0;
501 + myAction = createAction(actionType);

For clarity, replace with:

Action *myAction = createAction(actionType);

6)

Weird function name:
542 +QString FileSystemAction::targetFom

This probably is meant to be targetFrom?

review: Needs Fixing
187. By Carlos Jose Mazieri

renamed FileSystemAction::targetFom() para FileSystemAction::targetFrom()
fixed memory leak in FileSystemAction::addEntry()
fixed memory leak in FileSystemAction::~FileSystemAction()
fixed memory leak in LocationsFactory::~LocationsFactory()

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Carlos Jose Mazieri (carlos-mazieri) wrote :

revision 187 solves all requirements.

The auxAction commented in item 2) does not need be deleted in FileSystemAction::Action::~Action(), when it is created is stored in the array as other Actions, the auxAction variable is kept only because two Actions need this relationship.

Revision history for this message
Arto Jalkanen (ajalkane) wrote :

Thanks for the fixes and the explanation.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/plugin/folderlistmodel/filesystemaction.cpp'
2--- src/plugin/folderlistmodel/filesystemaction.cpp 2014-02-05 15:31:44 +0000
3+++ src/plugin/folderlistmodel/filesystemaction.cpp 2014-05-24 01:40:38 +0000
4@@ -70,7 +70,97 @@
5 #define COMMON_SIZE_ITEM 120
6
7
8-
9+//===============================================================================================
10+FileSystemAction::CopyFile::CopyFile():
11+ bytesWritten(0),
12+ source(0),
13+ target(0),
14+ isEntryItem(false) ,
15+ amountSavedToRefresh(AMOUNT_COPIED_TO_REFRESH_ITEM_INFO)
16+{
17+
18+}
19+
20+
21+FileSystemAction::CopyFile::~CopyFile()
22+{
23+ clear();
24+}
25+
26+
27+
28+//===============================================================================================
29+FileSystemAction::Action::Action()
30+ : auxAction(0), isAux(false)
31+{
32+ reset();
33+}
34+
35+FileSystemAction::Action::~Action()
36+{
37+ ::qDeleteAll(entries);
38+ entries.clear();
39+ copyFile.clear();
40+ //it is not necessary to delete auxAction, because it should be
41+ //inside FileSystemAction::m_queuedActions
42+}
43+
44+/*!
45+ * \brief FileSystemAction::Action::reset() Used for Undo operations
46+ */
47+void FileSystemAction::Action::reset()
48+{
49+ totalItems = 0;
50+ currItem = 0;
51+ currEntryIndex = 0;
52+ totalBytes = 0;
53+ bytesWritten = 0;
54+ done = false;
55+ isAux = false;
56+ currEntry = 0;
57+ steps = 1;
58+ //auxAction should be in FileSystemAction::m_queuedActions
59+ //it is not necessary to delete
60+ auxAction = 0;
61+ copyFile.clear();
62+
63+}
64+
65+
66+
67+//===============================================================================================
68+FileSystemAction::ActionEntry::ActionEntry(): newName(0)
69+{
70+ init();
71+}
72+
73+FileSystemAction::ActionEntry::~ActionEntry()
74+{
75+ reversedOrder.clear();
76+ if (newName) { delete newName; }
77+}
78+
79+void FileSystemAction::ActionEntry::init()
80+{
81+ currItem = 0 ;
82+ currStep = 0;
83+ added = false;
84+ alreadyExists = false;
85+ if (newName)
86+ {
87+ delete newName;
88+ newName = 0;
89+ }
90+}
91+
92+/*!
93+ * \brief FileSystemAction::Action::reset() Used for Undo operations
94+ */
95+void FileSystemAction::ActionEntry::reset()
96+{
97+ init();
98+ reversedOrder.clear();
99+}
100
101 void FileSystemAction::CopyFile::clear()
102 {
103@@ -94,6 +184,9 @@
104 , m_cancelCurrentAction(false)
105 , m_busy(false)
106 , m_clipboardChanged(false)
107+#if defined(REGRESSION_TEST_FOLDERLISTMODEL) //used in Unit/Regression tests
108+ , m_forceUsingOtherFS(false)
109+#endif
110 {
111
112 }
113@@ -104,7 +197,12 @@
114 */
115 FileSystemAction::~FileSystemAction()
116 {
117-
118+ if (m_curAction)
119+ {
120+ delete m_curAction;
121+ }
122+ ::qDeleteAll(m_queuedActions);
123+ m_queuedActions.clear();
124 }
125
126 //===============================================================================================
127@@ -124,23 +222,10 @@
128 * \param origBase
129 * \return
130 */
131-FileSystemAction::Action* FileSystemAction::createAction(ActionType type, int origBase)
132+FileSystemAction::Action* FileSystemAction::createAction(ActionType type)
133 {
134 Action * action = new Action();
135- action->type = type;
136- action->baseOrigSize = origBase;
137- action->targetPath = m_path;
138- action->totalItems = 0;
139- action->currItem = 0;
140- action->currEntryIndex = 0;
141- action->totalBytes = 0;
142- action->bytesWritten = 0;
143- action->done = false;
144- action->auxAction = 0;
145- action->isAux = false;
146- action->currEntry = 0;
147- action->steps = 1;
148-
149+ action->type = type;
150 return action;
151 }
152
153@@ -150,36 +235,54 @@
154 * \param action
155 * \param pathname
156 */
157-void FileSystemAction::addEntry(Action* action, const QString& pathname)
158+void FileSystemAction::addEntry(Action* action, const ActionPaths& pairPaths)
159 {
160 #if DEBUG_MESSAGES
161- qDebug() << Q_FUNC_INFO << pathname;
162+ qDebug() << Q_FUNC_INFO << pairPaths.source();
163 #endif
164- DirItemInfo info(pathname);
165- if (!info.isAbsolute())
166- {
167- info.setFile(action->targetPath, pathname);
168- }
169+
170+ ActionEntry * entry = new ActionEntry();
171+ entry->itemPaths = pairPaths;
172+ if (populateEntry(action, entry))
173+ {
174+ //now put the Entry in the Action
175+ action->entries.append(entry);
176+ }
177+ else
178+ {
179+ delete entry;
180+ }
181+}
182+
183+bool FileSystemAction::populateEntry(Action* action, ActionEntry* entry)
184+{
185+ DirItemInfo info(entry->itemPaths.source());
186 if (!info.exists())
187 {
188 emit error(QObject::tr("File or Directory does not exist"),
189- pathname + QObject::tr(" does not exist")
190- );
191- return;
192+ info.absoluteFilePath() + QObject::tr(" does not exist")
193+ );
194+ return false;
195 }
196- ActionEntry * entry = new ActionEntry();
197+ //action->type is top level for all items, entry->type drives item behaviour
198+ entry->type = action->type; //normal behaviour
199 //this is the item being handled
200 entry->reversedOrder.append(info);
201- // verify if the destination item already exists
202- if (action->type == ActionCopy ||
203- action->type == ActionMove ||
204- action->type == ActionHardMoveCopy)
205+ // verify if the destination item already exists and it the destination path is in other file system
206+ if (entry->type == ActionCopy ||
207+ entry->type == ActionMove
208+ )
209 {
210- DirItemInfo destination(targetFom(info.absoluteFilePath(), action));
211+ DirItemInfo destination(entry->itemPaths.target());
212 entry->alreadyExists = destination.exists();
213+ //check if it is possible to move items
214+ if (entry->type == ActionMove && !moveUsingSameFileSystem(entry->itemPaths) )
215+ {
216+ entry->type = ActionHardMoveCopy; // first step
217+ }
218 }
219 //ActionMove will perform a rename, so no Directory expanding is necessary
220- if (action->type != ActionMove && info.isDir() && !info.isSymLink())
221+ if (entry->type != ActionMove && info.isDir() && !info.isSymLink())
222 {
223 QDirIterator it(info.absoluteFilePath(),
224 QDir::AllEntries | QDir::System |
225@@ -196,23 +299,23 @@
226 int sizeSteps = 0;
227 int bufferSize = (COPY_BUFFER_SIZE * STEP_FILES);
228 while (counter--)
229- {
230+ {
231 const DirItemInfo & item = entry->reversedOrder.at(counter);
232 size = (item.isFile() && !item.isDir() && !item.isSymLink()) ?
233 item.size() : COMMON_SIZE_ITEM;
234 action->totalBytes += size;
235- if (action->type == ActionCopy || action->type == ActionHardMoveCopy)
236+ if (entry->type == ActionCopy || entry->type == ActionHardMoveCopy)
237 {
238 if ( (sizeSteps = size / bufferSize) )
239 {
240 if ( !(size % bufferSize) )
241 {
242 --sizeSteps;
243+ }
244 }
245- action->steps += sizeSteps ;
246+ action->steps += sizeSteps ;
247 }
248 }
249- }
250 //set final steps for the Entry based on Items number
251 int entrySteps = entry->reversedOrder.count() / STEP_FILES;
252 if ( entry->reversedOrder.count() % STEP_FILES) entrySteps++;
253@@ -222,8 +325,8 @@
254 qDebug() << "entrySteps" << entrySteps << "from entry counter" << entry->reversedOrder.count()
255 << "total steps" << action->steps;
256 #endif
257- //now put the Entry in the Action
258- action->entries.append(entry);
259+
260+ return true;
261 }
262
263 //===============================================================================================
264@@ -233,16 +336,11 @@
265 void FileSystemAction::processAction()
266 {
267 if (m_curAction)
268- {
269- //it will be ActionHardMoveRemove only when switched from ActionHardMoveCopy
270- //in this case the move is done in two steps COPY and REMOVE
271- if (m_curAction->type != ActionHardMoveCopy)
272- {
273+ {
274 delete m_curAction;
275 m_curAction = 0;
276- }
277 }
278- if (!m_curAction && m_queuedActions.count())
279+ if (m_queuedActions.count())
280 {
281 m_curAction = m_queuedActions.at(0);
282 m_curAction->currEntry = static_cast<ActionEntry*>
283@@ -277,12 +375,12 @@
284 */
285 void FileSystemAction::processActionEntry()
286 {
287-#if DEBUG_MESSAGES
288- qDebug() << Q_FUNC_INFO;
289-#endif
290-
291 ActionEntry * curEntry = m_curAction->currEntry;
292
293+#if DEBUG_MESSAGES
294+ qDebug() << Q_FUNC_INFO << "entry:" << curEntry << "type:" << curEntry->type;
295+#endif
296+
297 #if defined(SIMULATE_LONG_ACTION)
298 {
299 unsigned int delay = SIMULATE_LONG_ACTION;
300@@ -295,7 +393,7 @@
301 #endif
302 if (!m_cancelCurrentAction)
303 {
304- switch(m_curAction->type)
305+ switch(curEntry->type)
306 {
307 case ActionRemove:
308 case ActionHardMoveRemove:
309@@ -310,6 +408,8 @@
310 moveEntry(curEntry);
311 endActionEntry();
312 break;
313+ default:
314+ break;
315 }
316 }
317 }
318@@ -320,11 +420,12 @@
319 */
320 void FileSystemAction::endActionEntry()
321 {
322-#if DEBUG_MESSAGES
323- qDebug() << Q_FUNC_INFO;
324-#endif
325 ActionEntry * curEntry = m_curAction->currEntry;
326
327+#if DEBUG_MESSAGES
328+ qDebug() << Q_FUNC_INFO << "entry:" << curEntry << "type:" << curEntry->type;
329+#endif
330+
331 // first of all check for any error or a cancel issued by the user
332 if (m_cancelCurrentAction)
333 {
334@@ -336,60 +437,54 @@
335 scheduleSlot(SLOT(processAction()));
336 return;
337 }
338+
339+ int percent = notifyProgress();
340+
341 // check if the current entry has finished
342 // if so Views need to receive the notification about that
343 if (curEntry->currItem == curEntry->reversedOrder.count())
344 {
345 const DirItemInfo & mainItem = curEntry->reversedOrder.at(curEntry->currItem -1);
346 m_curAction->currEntryIndex++;
347- switch(m_curAction->type)
348- {
349- case ActionRemove:
350+
351+ switch(curEntry->type)
352+ {
353+ case ActionRemove:
354 emit removed(mainItem);
355 break;
356- case ActionHardMoveRemove: // nothing to do
357- break;
358- case ActionHardMoveCopy:
359- //check if is doing a hard move and the copy part has finished
360- //if so switch the action to remove
361- if (m_curAction->currEntryIndex == m_curAction->entries.count())
362- {
363- m_curAction->type = ActionHardMoveRemove;
364- m_curAction->currEntryIndex = 0;
365- int entryCounter = m_curAction->entries.count();
366- ActionEntry * entry;
367- while (entryCounter--)
368- {
369- entry = m_curAction->entries.at(entryCounter);
370- entry->currItem = 0;
371- entry->currStep = 0;
372- }
373- }
374- case ActionCopy: // ActionHardMoveCopy is also checked here
375- case ActionMove:
376- {
377- QString addedItem = targetFom(mainItem.absoluteFilePath(), m_curAction);
378- if (!curEntry->added && !curEntry->alreadyExists)
379- {
380- emit added(addedItem);
381- curEntry->added = true;
382- }
383- else
384- {
385- emit changed(DirItemInfo(addedItem));
386- }
387- }
388- break;
389- }//switch
390-
391+ case ActionHardMoveRemove: // nothing to do
392+ break;
393+ case ActionHardMoveCopy:
394+ case ActionCopy: // ActionHardMoveCopy is lso checked here
395+ case ActionMove:
396+ if (!curEntry->added && !curEntry->alreadyExists)
397+ {
398+ emit added(curEntry->itemPaths.target());
399+ curEntry->added = true;
400+ }
401+ else
402+ {
403+ emit changed(DirItemInfo(curEntry->itemPaths.target()));
404+ }
405+ if (curEntry->type == ActionHardMoveCopy)
406+ {
407+ //process same Entry again,
408+ m_curAction->currEntryIndex--;
409+ curEntry->type = ActionHardMoveRemove;
410+ m_curAction->currItem -= curEntry->reversedOrder.count();
411+ curEntry->init();
412+ }
413+ break;
414+ default:
415+ break;
416+ }//switch
417 }//end if (curEntry->currItem == curEntry->reversedOrder.count())
418
419 if (curEntry->currStep == STEP_FILES)
420 {
421 curEntry->currStep = 0;
422- }
423+ }
424
425- int percent = notifyProgress();
426 //Check if the current action has finished or cancelled
427 if (m_cancelCurrentAction ||
428 m_curAction->currEntryIndex == m_curAction->entries.count())
429@@ -485,14 +580,14 @@
430 //first item from an Entry,
431 if (entry->currItem == 0 && entry->alreadyExists && entry->newName == 0)
432 {
433- //making backup only if the targetpath == origPath, otherwise the item is overwritten
434- if (m_curAction->targetPath == m_curAction->origPath)
435+ //making backup only if the targetpath == origPath, otherwise the item is overwritten
436+ if (entry->itemPaths.areEquals())
437 {
438 //it will check again if the target exists
439 //if so, sets the entry->newName
440 //then targetFom() will use entry->newName for
441 // sub items in the Entry if the Entry is a directory
442- if (!makeBackupNameForCurrentItem(m_curAction) )
443+ if (!makeBackupNameForCurrentItem(entry) )
444 {
445 m_cancelCurrentAction = true;
446 m_errorTitle = QObject::tr("Could not find a suitable name to backup");
447@@ -520,7 +615,7 @@
448 {
449 const DirItemInfo &fi = entry->reversedOrder.at(entry->currItem);
450 QString orig = fi.absoluteFilePath();
451- QString target = targetFom(orig, m_curAction);
452+ QString target = targetFrom(orig, entry);
453 QString path(target);
454 // do this here to allow progress send right item number, copySingleFile will emit progress()
455 m_curAction->currItem++;
456@@ -537,7 +632,7 @@
457 && !entry->reversedOrder.last().isSymLink()
458 )
459 {
460- QString entryDir = targetFom(entry->reversedOrder.last().absoluteFilePath(), m_curAction);
461+ QString entryDir = targetFrom(entry->reversedOrder.last().absoluteFilePath(), entry);
462 QDir entryDirObj(entryDir);
463 if (!entryDirObj.exists() && entryDirObj.mkpath(entryDir))
464 {
465@@ -600,7 +695,7 @@
466 m_curAction->copyFile.target->close();
467 }
468 //check if there is disk space to copy source to target
469- if (needsSize > 0 && !isThereDiskSpace( needsSize ))
470+ if (needsSize > 0 && !isThereDiskSpace(entry, needsSize ))
471 {
472 m_cancelCurrentAction = true;
473 m_errorTitle = QObject::tr("There is no space on disk to copy");
474@@ -666,8 +761,7 @@
475 {
476 const DirItemInfo &fi = entry->reversedOrder.at(entry->currItem);
477 file.setFileName(fi.absoluteFilePath());
478- QString target(targetFom(fi.absoluteFilePath(), m_curAction));
479- DirItemInfo targetInfo(target);
480+ DirItemInfo targetInfo(entry->itemPaths.target());
481 //rename will fail
482 if (targetInfo.exists())
483 {
484@@ -675,10 +769,11 @@
485 entry->added = true;
486 if (targetInfo.isFile() || targetInfo.isSymLink())
487 {
488- if (!QFile::remove(target))
489+ if (!QFile::remove(targetInfo.absoluteFilePath()))
490 {
491 m_cancelCurrentAction = true;
492- m_errorTitle = QObject::tr("Could remove the directory/file ") + target;
493+ m_errorTitle = QObject::tr("Could not remove the directory/file ") +
494+ targetInfo.absoluteFilePath();
495 m_errorMsg = ::strerror(errno);
496 }
497 }
498@@ -687,13 +782,14 @@
499 {
500 //move target to /tmp and remove it later by creating an Remove action
501 //this will emit removed()
502- moveDirToTempAndRemoveItLater(target);
503+ moveDirToTempAndRemoveItLater(targetInfo.absoluteFilePath());
504 }
505 }
506- if (!m_cancelCurrentAction && !file.rename(target))
507+ if (!m_cancelCurrentAction && !file.rename(entry->itemPaths.target()))
508 {
509 m_cancelCurrentAction = true;
510- m_errorTitle = QObject::tr("Could not move the directory/file ") + target;
511+ m_errorTitle = QObject::tr("Could not move the directory/file ") +
512+ targetInfo.absoluteFilePath();
513 m_errorMsg = ::strerror(errno);
514 }
515 }//for
516@@ -759,12 +855,7 @@
517 {
518 emit error(titleError, noWriteError + origin.absoluteFilePath());
519 return;
520- }
521- //check if it is possible to move items
522- if ( !moveUsingSameFileSystem(items.at(0)) )
523- {
524- actionType = ActionHardMoveCopy; // first step
525- }
526+ }
527 if (!destination.isWritable())
528 {
529 emit error(titleError, noWriteError + destination.absoluteFilePath());
530@@ -780,28 +871,33 @@
531 * \brief FileSystemAction::createAndProcessAction
532 * \param actionType
533 * \param paths
534- * \param operation
535+ *
536 */
537 void FileSystemAction::createAndProcessAction(ActionType actionType, const QStringList& paths)
538 {
539 #if DEBUG_MESSAGES
540 qDebug() << Q_FUNC_INFO << paths;
541 #endif
542- Action *myAction = 0;
543- int origPathLen = 0;
544- myAction = createAction(actionType, origPathLen);
545- myAction->origPath = DirItemInfo(paths.at(0)).absolutePath();
546- myAction->baseOrigSize = myAction->origPath.length();
547+ Action *myAction = createAction(actionType);
548 for (int counter=0; counter < paths.count(); counter++)
549 {
550- addEntry(myAction, paths.at(counter));
551+ DirItemInfo info(paths.at(counter));
552+ if (!info.isAbsolute())
553+ {
554+ info.setFile(m_path, paths.at(counter));
555+ }
556+ ActionPaths pairPaths(info.absoluteFilePath());
557+ pairPaths.setTargetPathOnly(m_path);
558+ addEntry(myAction, pairPaths);
559 }
560+ queueAction(myAction);
561+}
562+
563+
564+void FileSystemAction::queueAction(Action *myAction)
565+{
566 if (myAction->totalItems > 0)
567- {
568- if (actionType == ActionHardMoveCopy)
569- {
570- myAction->totalItems *= 2; //duplicate this
571- }
572+ {
573 /*
574 if (actionType == ActionHardMoveCopy || actionType == ActionCopy)
575 {
576@@ -830,21 +926,24 @@
577 //===============================================================================================
578 /*!
579 * \brief FileSystemAction::targetFom() makes a destination full pathname from \a origItem
580- * \param origItem full pathname from a item intended to be copied or moved into current path
581+ * \param origItem full pathname from a item intended to be copied or moved under entry->itemPaths.target
582+ * \param entry which the item belongs to (item may be a sub item if the entry is a Directory)
583 * \return full pathname of target
584+ *
585+ * \sa makeBackupNameForCurrentItem()
586 */
587-QString FileSystemAction::targetFom(const QString& origItem, const Action* const action)
588+QString FileSystemAction::targetFrom(const QString& origItem, ActionEntry *entry)
589 {
590- QString destinationUnderTarget(origItem.mid(action->baseOrigSize));
591- if (action->currEntry && action->currEntry->newName)
592+ QString destinationUnderTarget(origItem.mid(entry->itemPaths.baseOrigSize()));
593+ if (entry->newName)
594 {
595 int len = destinationUnderTarget.indexOf(QDir::separator(), 1);
596 if (len == -1) {
597 len = destinationUnderTarget.size();
598 }
599- destinationUnderTarget.replace(1, len -1, *action->currEntry->newName);
600+ destinationUnderTarget.replace(1, len -1, *entry->newName);
601 }
602- QString target(action->targetPath + destinationUnderTarget);
603+ QString target(entry->itemPaths.targetPath() + destinationUnderTarget);
604
605 #if DEBUG_MESSAGES
606 qDebug() << Q_FUNC_INFO << "orig" << origItem
607@@ -856,31 +955,39 @@
608
609 //===============================================================================================
610 /*!
611- * \brief FileSystemAction::moveUsingSameFileSystem() Checks if the item being moved to
612- * current m_path belongs to the same File System
613+ * \brief FileSystemAction::moveUsingSameFileSystem() Checks if the item being moved to another path
614+ * belongs to the same File System as the target path
615 *
616 * It is used to set ActionHardMoveCopy or ActionMove for cut operations.
617 *
618- * \param itemToMovePathname first item being moved from a paste operation
619+ * \param paths
620 *
621- * \return true if the item being moved to the current m_path belongs to the same file system as m_path
622+ * \return true if the operation is going to performed in the same file system
623 */
624-bool FileSystemAction::moveUsingSameFileSystem(const QString& itemToMovePathname)
625+bool FileSystemAction::moveUsingSameFileSystem(const ActionPaths& movedItem)
626 {
627 unsigned long targetFsId = 0xffff;
628 unsigned long originFsId = 0xfffe;
629+
630+#if defined(REGRESSION_TEST_FOLDERLISTMODEL)
631+ if (m_forceUsingOtherFS)
632+ {
633+ return false;
634+ }
635+#endif
636+
637 #if defined(Q_OS_UNIX)
638 struct statvfs vfs;
639- if ( ::statvfs( QFile::encodeName(m_path).constData(), &vfs) == 0 )
640+ if ( ::statvfs( QFile::encodeName(movedItem.source()).constData(), &vfs) == 0 )
641 {
642 targetFsId = vfs.f_fsid;
643 }
644- if ( ::statvfs(QFile::encodeName(itemToMovePathname).constData(), &vfs) == 0)
645+ if ( ::statvfs(QFile::encodeName(movedItem.targetPath()).constData(), &vfs) == 0)
646 {
647 originFsId = vfs.f_fsid;
648 }
649 #else
650- Q_UNUSED(itemToMovePathname);
651+ Q_UNUSED(movedItem);
652 #endif
653 return targetFsId == originFsId;
654 }
655@@ -899,26 +1006,23 @@
656 void FileSystemAction::endCurrentAction()
657 {
658
659- if ( !m_clipboardChanged &&
660- m_curAction->origPath != m_curAction->targetPath &&
661- (m_curAction->type == ActionMove || m_curAction->type == ActionHardMoveRemove)
662- )
663- {
664- QStringList items;
665- const ActionEntry *entry;
666- int last;
667- for(int e = 0; e < m_curAction->entries.count(); e++)
668- {
669- entry = m_curAction->entries.at(e);
670- last = entry->reversedOrder.count() -1;
671- QString item(targetFom(entry->reversedOrder.at(last).absoluteFilePath(), m_curAction));
672- items.append(item);
673- }
674- if (items.count())
675- {
676- QString targetPath = m_curAction->targetPath;
677- //it is not necessary to handle own clipboard here
678- emit recopy(items, targetPath);
679+ if ( !m_clipboardChanged && m_curAction->type == ActionMove )
680+ {
681+ const ActionEntry *entry = m_curAction->entries.at(0);
682+ if (!entry->itemPaths.arePathsEquals())
683+ {
684+ QString destinationPath = entry->itemPaths.targetPath();
685+ QStringList items;
686+ for(int e = 0; e < m_curAction->entries.count(); e++)
687+ {
688+ entry = m_curAction->entries.at(e);
689+ items.append(entry->itemPaths.target());
690+ }
691+ if (items.count())
692+ {
693+ //it is not necessary to handle own clipboard here
694+ emit recopy(items, destinationPath);
695+ }
696 }
697 }
698 }
699@@ -1055,7 +1159,9 @@
700
701 //copying empty files will have totalBytes==0
702 if ( m_curAction->totalBytes > 0 &&
703- (m_curAction->type == ActionCopy || m_curAction->type == ActionHardMoveCopy)
704+ (m_curAction->currEntry->type == ActionCopy ||
705+ m_curAction->currEntry->type == ActionHardMoveCopy
706+ )
707 )
708 {
709 percent = (m_curAction->bytesWritten * 100) / m_curAction->totalBytes ;
710@@ -1086,17 +1192,12 @@
711 {
712 percent = 1;
713 }
714- if (SHOULD_EMIT_PROGRESS_SIGNAL(m_curAction) && !m_curAction->done)
715- {
716- if (m_curAction->type == ActionHardMoveCopy ||
717- m_curAction->type ==ActionHardMoveRemove)
718- {
719- emit progress(m_curAction->currItem/2, m_curAction->totalItems/2, percent);
720- }
721- else
722- {
723- emit progress(m_curAction->currItem, m_curAction->totalItems, percent);
724- }
725+ if ( SHOULD_EMIT_PROGRESS_SIGNAL(m_curAction) &&
726+ !m_curAction->done &&
727+ m_curAction->currEntry->type != ActionHardMoveRemove
728+ )
729+ {
730+ emit progress(m_curAction->currItem, m_curAction->totalItems, percent);
731 if (percent == 100 && m_curAction->currItem == m_curAction->totalItems)
732 {
733 m_curAction->done = true;
734@@ -1171,13 +1272,14 @@
735 #endif
736 if (QFile::rename(dir, tempDir))
737 {
738- if (!m_curAction->auxAction)
739+ if (m_curAction->auxAction == 0)
740 { // this new action as Remove will remove all dirs
741 m_curAction->auxAction = createAction(ActionRemove);
742 m_curAction->auxAction->isAux = true;
743 m_queuedActions.append(m_curAction->auxAction);
744 }
745- addEntry(m_curAction->auxAction, tempDir);
746+ ActionPaths pathToRemove(tempDir);
747+ addEntry(m_curAction->auxAction, pathToRemove);
748 }
749 }
750
751@@ -1199,13 +1301,13 @@
752 * The newName field from current entry will be set to a suitable name
753 * \param action
754 */
755-bool FileSystemAction::makeBackupNameForCurrentItem(Action *action)
756+bool FileSystemAction::makeBackupNameForCurrentItem(ActionEntry *entry)
757 {
758 bool ret = false;
759- if (action->currEntry->alreadyExists)
760+ if (entry->alreadyExists)
761 {
762 const DirItemInfo& fi =
763- action->currEntry->reversedOrder.at(action->currEntry->reversedOrder.count() -1);
764+ entry->reversedOrder.at(entry->reversedOrder.count() -1);
765 DirItemInfo backuped;
766 int counter=0;
767 QString name;
768@@ -1233,7 +1335,8 @@
769 } while (backuped.exists() && counter < 100);
770 if (counter < 100)
771 {
772- action->currEntry->newName = new QString(backuped.fileName());
773+ entry->newName = new QString(backuped.fileName());
774+ entry->itemPaths.setTargetFullName( backuped.absoluteFilePath() );
775 ret = true;
776 }
777 }
778@@ -1275,12 +1378,12 @@
779 }
780
781 //==================================================================
782-bool FileSystemAction::isThereDiskSpace(qint64 requiredSize)
783+bool FileSystemAction::isThereDiskSpace(const ActionEntry *entry, qint64 requiredSize)
784 {
785 bool ret = true;
786 #if defined(Q_OS_UNIX)
787 struct statvfs vfs;
788- if ( ::statvfs( QFile::encodeName(m_path).constData(), &vfs) == 0 )
789+ if ( ::statvfs( QFile::encodeName(entry->itemPaths.targetPath()).constData(), &vfs) == 0 )
790 {
791 qint64 free = vfs.f_bsize * vfs.f_bfree;
792 ret = free > requiredSize;
793
794=== modified file 'src/plugin/folderlistmodel/filesystemaction.h'
795--- src/plugin/folderlistmodel/filesystemaction.h 2014-02-05 15:31:44 +0000
796+++ src/plugin/folderlistmodel/filesystemaction.h 2014-05-24 01:40:38 +0000
797@@ -142,12 +142,9 @@
798 struct CopyFile
799 {
800 public:
801- CopyFile() : bytesWritten(0), source(0), target(0),
802- isEntryItem(false) , amountSavedToRefresh(AMOUNT_COPIED_TO_REFRESH_ITEM_INFO)
803- {}
804- ~CopyFile() { clear(); }
805+ CopyFile();
806+ ~CopyFile();
807 void clear();
808-
809 qint64 bytesWritten; // set 0 when reach bytesToNotify, notify progress
810 QFile * source;
811 QFile * target;
812@@ -164,42 +161,40 @@
813 struct ActionEntry
814 {
815 public:
816- ActionEntry(): currStep(0),currItem(0),alreadyExists(false), newName(0), added(false) {}
817- ~ActionEntry()
818- {
819- reversedOrder.clear();
820- if (newName) { delete newName; }
821- }
822- QList<DirItemInfo> reversedOrder; //!< last item must be the item from the list
823+ ActionEntry();
824+ ~ActionEntry();
825+ void init();
826+ void reset();
827+ ActionPaths itemPaths; //!< identifies the item being handled source and destination
828+ ActionType type;
829+ QList<DirItemInfo> reversedOrder; //!< last item must be the item from the list
830 int currStep;
831- int currItem;
832- bool alreadyExists;
833+ int currItem;
834 QString * newName; //TODO: allow to rename an existent file when it already exists.
835 // So far it is possible to backup items when copy/paste in the
836 // same place, in this case it is renamed to "<name> Copy (%d).termination"
837-
838- bool added; //!< signal added() already emitted for the current ActionEntry
839+ bool added :1; //!< signal added() already emitted for the current ActionEntry
840+ bool alreadyExists :1;
841 };
842
843 struct Action
844 {
845 public:
846- ~Action() {qDeleteAll(entries); entries.clear(); copyFile.clear();}
847+ Action();
848+ ~Action();
849+ void reset();
850 ActionType type;
851 QList<ActionEntry*> entries;
852 int totalItems;
853- int currItem;
854- int baseOrigSize;
855- QString origPath;
856- QString targetPath;
857+ int currItem;
858 quint64 totalBytes;
859 quint64 bytesWritten;
860 int currEntryIndex;
861 ActionEntry * currEntry;
862- CopyFile copyFile;
863- bool done;
864+ CopyFile copyFile;
865 Action * auxAction;
866- bool isAux;
867+ bool isAux :1;
868+ bool done :1;
869 int steps;
870 };
871
872@@ -215,12 +210,13 @@
873
874
875 private:
876- Action * createAction(ActionType, int origBase = 0);
877- void addEntry(Action* action, const QString &pathname);
878+ Action * createAction(ActionType);
879+ void addEntry(Action* action, const ActionPaths& pairPaths);
880+ bool populateEntry(Action* action, ActionEntry* entry);
881 void removeEntry(ActionEntry *);
882 void moveEntry(ActionEntry *entry);
883- bool moveUsingSameFileSystem(const QString& itemToMovePathname);
884- QString targetFom(const QString& origItem, const Action * const action);
885+ bool moveUsingSameFileSystem(const ActionPaths &movedItem);
886+ QString targetFrom(const QString& origItem, ActionEntry * entry);
887 void endCurrentAction();
888 int percentWorkDone();
889 int notifyProgress(int forcePercent = 0);
890@@ -228,11 +224,13 @@
891 bool copySymLink(const QString& target, const QFileInfo& orig);
892 void scheduleSlot(const char *slot);
893 void moveDirToTempAndRemoveItLater(const QString& dir);
894- bool makeBackupNameForCurrentItem(Action *action);
895+ bool makeBackupNameForCurrentItem(ActionEntry *entry);
896 bool endCopySingleFile();
897- bool isThereDiskSpace(qint64 requiredSize);
898+ bool isThereDiskSpace(const ActionEntry *entry, qint64 requiredSize);
899+ void queueAction(Action *myAction);
900
901 #if defined(REGRESSION_TEST_FOLDERLISTMODEL) //used in Unit/Regression tests
902+ bool m_forceUsingOtherFS;
903 friend class TestDirModel;
904 #endif
905 };
906
907=== modified file 'src/plugin/folderlistmodel/locationsfactory.cpp'
908--- src/plugin/folderlistmodel/locationsfactory.cpp 2014-05-17 12:57:46 +0000
909+++ src/plugin/folderlistmodel/locationsfactory.cpp 2014-05-24 01:40:38 +0000
910@@ -46,6 +46,10 @@
911 {
912 ::qDeleteAll(m_locations);
913 m_locations.clear();
914+ if (m_lastValidFileInfo)
915+ {
916+ delete m_lastValidFileInfo;
917+ }
918 }
919
920
921@@ -173,7 +177,7 @@
922 }
923
924
925-void LocationsFactory::storeValidFileInfo(const DirItemInfo *item)
926+void LocationsFactory::storeValidFileInfo(DirItemInfo *item)
927 {
928 if (m_lastValidFileInfo)
929 {
930
931=== modified file 'src/plugin/folderlistmodel/locationsfactory.h'
932--- src/plugin/folderlistmodel/locationsfactory.h 2014-05-14 22:51:47 +0000
933+++ src/plugin/folderlistmodel/locationsfactory.h 2014-05-24 01:40:38 +0000
934@@ -113,7 +113,7 @@
935 */
936 const DirItemInfo* lastValidFileInfo() const { return m_lastValidFileInfo; }
937
938- void storeValidFileInfo(const DirItemInfo *item);
939+ void storeValidFileInfo(DirItemInfo *item);
940
941 signals:
942 void locationChanged(const Location *old, const Location *current);
943@@ -125,7 +125,7 @@
944 Location * m_curLoc;
945 QList<Location*> m_locations;
946 QString m_tmpPath;
947- const DirItemInfo * m_lastValidFileInfo;
948+ DirItemInfo * m_lastValidFileInfo;
949
950 #if defined(REGRESSION_TEST_FOLDERLISTMODEL)
951 friend class TestDirModel;
952
953=== modified file 'src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp'
954--- src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-05-02 12:22:11 +0000
955+++ src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-05-24 01:40:38 +0000
956@@ -914,7 +914,8 @@
957 QStringList allFiles(m_deepDir_01->firstLevel());
958 allFiles.append(tempFiles.createdList());
959
960- m_dirModel_02->m_fsAction->createAndProcessAction(FileSystemAction::ActionHardMoveCopy,
961+ m_dirModel_02->m_fsAction->m_forceUsingOtherFS = true;
962+ m_dirModel_02->m_fsAction->createAndProcessAction(FileSystemAction::ActionMove,
963 allFiles);
964
965 QTest::qWait(TIME_TO_PROCESS);

Subscribers

People subscribed via source and target branches