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

Proposed by Carlos Jose Mazieri
Status: Merged
Approved by: Francis Ginther
Approved revision: 188
Merged at revision: 206
Proposed branch: lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-3
Merge into: lp:ubuntu-filemanager-app
Prerequisite: lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-2
Diff against target: 429 lines (+294/-8)
6 files modified
src/plugin/folderlistmodel/dirmodel.cpp (+110/-2)
src/plugin/folderlistmodel/dirmodel.h (+21/-1)
src/plugin/folderlistmodel/filesystemaction.cpp (+103/-3)
src/plugin/folderlistmodel/filesystemaction.h (+10/-2)
src/plugin/folderlistmodel/trash/trashlocation.cpp (+28/-0)
src/plugin/folderlistmodel/trash/trashlocation.h (+22/-0)
To merge this branch: bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/trash-operations-3
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Arto Jalkanen Approve
Review via email: mp+219943@code.launchpad.net

Commit message

Code to complete Trash opearations: move into / restore from / restore all / empty trash

Description of the change

Code to complete Trash opearations: move into / restore from / restore all / empty trash

Removing items from trash is driven to DirModel::rm() as normal remove, the operation differs from a normal remove only that for each top level item the ".trashinfo" file is also removed, but removing sub items from Trash is not allowed.

All Trash operations in Trash sub items (not in top level) are not allowed, that means, items in Trash sub folders are not allowed to be restored neither removed, these actions are supported on the top Trash root only.

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: Needs Fixing (continuous-integration)
Revision history for this message
Arto Jalkanen (ajalkane) wrote :

1)

#define IS_BROWSING_TRASH() (mCurLocation && mCurLocation->type() == LocationsFactory::TrashDisk && mCurLocation->isRoot())

Wouldn't this be clearer if it was IS_BROWSING_TRASH_ROOTDIR or something like that?

2)
297 +void FileSystemAction::createTrashInfoFileFromEnry(ActionEntry *entry)
Typo: should be createTrashInfoFileFromEntry
310 +void FileSystemAction::removeTrashInfoFileFromEnry(ActionEntry *entry)
Typo: should be removeTrashInfoFileFromEntry

3)
This is not anything that should be changed, just a note if there's a problem later when doing QML work:
Q_INVOKABLE void moveIndexesToTrash(const QList<int>&);

And functions like this, that take const reference to a list. I have an impression these were a problem in Qt 4.8 for QML, and if I remember correctly QML needed a QVariantList pointer. But lots have changed for Qt5 so perhaps this cleaner way works now. Let's only do some QML specific functions if there is a problem.

So in summary, only the cosmetic change of 2) is needed, and I'd think 1) would be a change that would make the macro's intent clearer.

review: Needs Fixing
Revision history for this message
Carlos Jose Mazieri (carlos-mazieri) wrote :

Thanks,

All items have been addressed in revision 189.

I was not aware about item 3), Q_INVOKABLE was removed, it'd better to create a better QML interface for that.
The last MP has functions using selections like moveSelectionToTrash(), and restoreSelectionFromTrash().

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Arto Jalkanen (ajalkane) wrote :

Thank you, looks good.

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

Ready to approve once Jenkins is not failing.

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

Can anyone help here?

I think that needs manual fixing in the build process,it has happened once more.

Revision history for this message
Francis Ginther (fginther) wrote :

The trusty testing has been disabled for dependency reasons. Re-approving to try autolanding again.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/plugin/folderlistmodel/dirmodel.cpp'
2--- src/plugin/folderlistmodel/dirmodel.cpp 2014-05-17 12:57:46 +0000
3+++ src/plugin/folderlistmodel/dirmodel.cpp 2014-05-28 21:14:07 +0000
4@@ -38,6 +38,7 @@
5 #include "location.h"
6 #include "locationurl.h"
7 #include "disklocation.h"
8+#include "trashlocation.h"
9
10
11 #ifndef DO_NOT_USE_TAG_LIB
12@@ -75,7 +76,7 @@
13
14 #define IS_FILE_MANAGER_IDLE() (!mAwaitingResults)
15
16-
17+#define IS_BROWSING_TRASH_ROOTDIR() (mCurLocation && mCurLocation->type() == LocationsFactory::TrashDisk && mCurLocation->isRoot())
18
19 namespace {
20 QHash<QByteArray, int> roleMapping;
21@@ -482,7 +483,18 @@
22
23 void DirModel::rm(const QStringList &paths)
24 {
25- m_fsAction->remove(paths);
26+ //if current location is Trash only in the root is allowed to remove Items
27+ if (mCurLocation->type() == LocationsFactory::TrashDisk)
28+ {
29+ if (IS_BROWSING_TRASH_ROOTDIR())
30+ {
31+ m_fsAction->removeFromTrash(paths);
32+ }
33+ }
34+ else
35+ {
36+ m_fsAction->remove(paths);
37+ }
38 }
39
40
41@@ -1509,6 +1521,102 @@
42 }
43
44
45+void DirModel:: moveIndexesToTrash(const QList<int>& items)
46+{
47+ if (mCurLocation->type() == LocationsFactory::LocalDisk)
48+ {
49+ const TrashLocation *trashLocation = static_cast<const TrashLocation*>
50+ (mLocationFactory->getLocation(LocationsFactory::TrashDisk));
51+ ActionPathList itemsAndTrashPath;
52+ int index = 0;
53+ for (int counter=0; counter < items.count(); ++counter)
54+ {
55+ index = items.at(counter);
56+ if (IS_VALID_ROW(index))
57+ {
58+ const DirItemInfo &it = mDirectoryContents.at(index);
59+ itemsAndTrashPath.append(trashLocation->getMovePairPaths(it));
60+ }
61+ }
62+ if (itemsAndTrashPath.count() > 0)
63+ {
64+ m_fsAction->moveToTrash(itemsAndTrashPath);
65+ }
66+ }
67+}
68+
69+
70+void DirModel:: moveIndexToTrash(int index)
71+{
72+ QList<int> list;
73+ list.append(index);
74+ return moveIndexesToTrash(list);
75+}
76+
77+
78+void DirModel::restoreTrash()
79+{
80+ if ( IS_BROWSING_TRASH_ROOTDIR() )
81+ {
82+ QList<int> allItems;
83+ for (int counter=0; counter < rowCount(); ++counter)
84+ {
85+ allItems.append(counter);
86+ }
87+ restoreIndexesFromTrash(allItems);
88+ }
89+}
90+
91+
92+void DirModel::emptyTrash()
93+{
94+ if ( IS_BROWSING_TRASH_ROOTDIR() )
95+ {
96+ QStringList allItems;
97+ for (int counter=0; counter < rowCount(); ++counter)
98+ {
99+ allItems.append(mDirectoryContents.at(counter).absoluteFilePath());
100+ }
101+ if (allItems.count() > 0)
102+ {
103+ m_fsAction->removeFromTrash(allItems);
104+ }
105+ }
106+}
107+
108+
109+void DirModel::restoreIndexFromTrash(int index)
110+{
111+ QList<int> item;
112+ item.append(index);
113+ restoreIndexesFromTrash(item);
114+}
115+
116+
117+void DirModel::restoreIndexesFromTrash(const QList<int> &items)
118+{
119+ if ( IS_BROWSING_TRASH_ROOTDIR() )
120+ {
121+ TrashLocation *trashLocation = static_cast<TrashLocation*> (mCurLocation);
122+ ActionPathList itemsAndOriginalPaths;
123+ int index = 0;
124+ for (int counter=0; counter < items.count(); ++counter)
125+ {
126+ index = items.at(counter);
127+ if (IS_VALID_ROW(index))
128+ {
129+ const DirItemInfo &it = mDirectoryContents.at(index);
130+ itemsAndOriginalPaths.append(trashLocation->getRestorePairPaths(it));
131+ }
132+ }
133+ if (itemsAndOriginalPaths.count() > 0)
134+ {
135+ m_fsAction->restoreFromTrash(itemsAndOriginalPaths);
136+ }
137+ }
138+}
139+
140+
141 #ifndef DO_NOT_USE_TAG_LIB
142 QVariant DirModel::getAudioMetaData(const QFileInfo& fi, int role) const
143 {
144
145=== modified file 'src/plugin/folderlistmodel/dirmodel.h'
146--- src/plugin/folderlistmodel/dirmodel.h 2014-05-02 12:22:11 +0000
147+++ src/plugin/folderlistmodel/dirmodel.h 2014-05-28 21:14:07 +0000
148@@ -289,7 +289,27 @@
149 Q_INVOKABLE bool existsFile(const QString& fileName) const;
150 Q_INVOKABLE bool canReadFile(const QString& fileName) const;
151
152-public slots:
153+ // Trash functions
154+ Q_INVOKABLE void moveIndexToTrash(int index);
155+ void moveIndexesToTrash(const QList<int>&);
156+ Q_INVOKABLE void restoreIndexFromTrash(int index);
157+ void restoreIndexesFromTrash(const QList<int>&);
158+
159+public slots:
160+ /*!
161+ * \brief restoreTrash() restore all items being actually browsed in the Trash
162+ *
163+ */
164+ void restoreTrash();
165+
166+ /*!
167+ * \brief emptyTrash() remove definitely all items being actually browsed in the Trash
168+ *
169+ * \sa \ref removeSelection() and \ref rm()
170+ *
171+ */
172+ void emptyTrash();
173+
174 /*!
175 * \brief goHome() goes to user home dir
176 * Go to user home dir, we may have a tab for places or something like that
177
178=== modified file 'src/plugin/folderlistmodel/filesystemaction.cpp'
179--- src/plugin/folderlistmodel/filesystemaction.cpp 2014-05-24 01:40:01 +0000
180+++ src/plugin/folderlistmodel/filesystemaction.cpp 2014-05-28 21:14:07 +0000
181@@ -36,6 +36,7 @@
182
183 #include "filesystemaction.h"
184 #include "clipboard.h"
185+#include "qtrashutilinfo.h"
186
187 #if defined(Q_OS_UNIX)
188 #include <sys/statvfs.h>
189@@ -264,8 +265,17 @@
190 );
191 return false;
192 }
193- //action->type is top level for all items, entry->type drives item behaviour
194- entry->type = action->type; //normal behaviour
195+ //action->type is top level for all items, entry->type drives item behaviour
196+ switch(action->type)
197+ {
198+ case ActionMoveToTrash:
199+ case ActionRestoreFromTrash: entry->type = ActionMove; //needs create .trashinfo file
200+ break;
201+ case ActionRemoveFromTrash: entry->type = ActionRemove; //needs remove .trashinfo file
202+ break;
203+ default: entry->type = action->type; //normal behaviour
204+ break;
205+ }
206 //this is the item being handled
207 entry->reversedOrder.append(info);
208 // verify if the destination item already exists and it the destination path is in other file system
209@@ -447,9 +457,31 @@
210 const DirItemInfo & mainItem = curEntry->reversedOrder.at(curEntry->currItem -1);
211 m_curAction->currEntryIndex++;
212
213+ //check Trash operations
214+ if ( (m_curAction->type == ActionMoveToTrash || m_curAction->type == ActionRestoreFromTrash)
215+ && (curEntry->type == ActionMove || curEntry->type == ActionHardMoveRemove)
216+ )
217+ {
218+ if ( m_curAction->type == ActionMoveToTrash )
219+ {
220+ createTrashInfoFileFromEntry(curEntry);
221+ }
222+ else
223+ {
224+ removeTrashInfoFileFromEntry(curEntry);
225+ }
226+ emit removed(mainItem);
227+ }
228+ else
229+ {
230 switch(curEntry->type)
231 {
232- case ActionRemove:
233+ case ActionRemove:
234+ if (m_curAction->type == ActionRemoveFromTrash)
235+ {
236+ //it is necessary to remove also (file).trashinfo file
237+ removeTrashInfoFileFromEntry(curEntry);
238+ }
239 emit removed(mainItem);
240 break;
241 case ActionHardMoveRemove: // nothing to do
242@@ -478,6 +510,7 @@
243 default:
244 break;
245 }//switch
246+ }
247 }//end if (curEntry->currItem == curEntry->reversedOrder.count())
248
249 if (curEntry->currStep == STEP_FILES)
250@@ -1403,3 +1436,70 @@
251 {
252 m_clipboardChanged = true;
253 }
254+
255+
256+//==================================================================
257+/*!
258+ * \brief FileSystemAction::moveToTrash() Move a set of files to Trash
259+ * \param items files/dirs that belong to the same parent directory
260+ */
261+void FileSystemAction::moveToTrash(const ActionPathList &pairPaths)
262+{
263+ Action *moveAction = createAction(ActionMoveToTrash);
264+ for (int counter=0; counter < pairPaths.count(); ++counter)
265+ {
266+ addEntry(moveAction, pairPaths.at(counter));
267+ }
268+ queueAction(moveAction);
269+}
270+
271+//==================================================================
272+/*!
273+ * \brief FileSystemAction::restoreFromTrash() restore a set of Files to
274+ * their original path
275+ * \param pairPaths
276+ */
277+void FileSystemAction::restoreFromTrash(const ActionPathList &pairPaths)
278+{
279+ Action *moveAction = createAction(ActionRestoreFromTrash);
280+ for (int counter=0; counter < pairPaths.count(); ++counter)
281+ {
282+ addEntry(moveAction, pairPaths.at(counter));
283+ }
284+ queueAction(moveAction);
285+}
286+
287+/*!
288+ * \brief FileSystemAction::removeFromTrash
289+ * \param paths
290+ */
291+void FileSystemAction::removeFromTrash(const QStringList &paths)
292+{
293+ createAndProcessAction(ActionRemoveFromTrash, paths);
294+}
295+
296+
297+void FileSystemAction::createTrashInfoFileFromEntry(ActionEntry *entry)
298+{
299+ QTrashUtilInfo trashUtil;
300+ trashUtil.setInfoFromTrashItem(entry->itemPaths.target());
301+ if (!trashUtil.createTrashInfoFile(entry->itemPaths.source()))
302+ {
303+ m_cancelCurrentAction = true;
304+ m_errorTitle = QObject::tr("Could not create trash info file");
305+ m_errorMsg = trashUtil.absInfo;
306+ }
307+}
308+
309+
310+void FileSystemAction::removeTrashInfoFileFromEntry(ActionEntry *entry)
311+{
312+ QTrashUtilInfo trashUtil;
313+ trashUtil.setInfoFromTrashItem(entry->itemPaths.source());
314+ if (!trashUtil.removeTrashInfoFile())
315+ {
316+ m_cancelCurrentAction = true;
317+ m_errorTitle = QObject::tr("Could not remove the trash info file");
318+ m_errorMsg = trashUtil.absInfo;
319+ }
320+}
321
322=== modified file 'src/plugin/folderlistmodel/filesystemaction.h'
323--- src/plugin/folderlistmodel/filesystemaction.h 2014-05-24 01:40:01 +0000
324+++ src/plugin/folderlistmodel/filesystemaction.h 2014-05-28 21:14:07 +0000
325@@ -108,6 +108,9 @@
326 void pathChanged(const QString& path);
327 void copyIntoCurrentPath(const QStringList& items);
328 void moveIntoCurrentPath(const QStringList& items);
329+ void moveToTrash(const ActionPathList& pairPaths );
330+ void restoreFromTrash(const ActionPathList& pairPaths);
331+ void removeFromTrash(const QStringList& paths);
332 void onClipboardChanged();
333
334
335@@ -134,7 +137,10 @@
336 ActionCopy,
337 ActionMove,
338 ActionHardMoveCopy,
339- ActionHardMoveRemove
340+ ActionHardMoveRemove,
341+ ActionMoveToTrash,
342+ ActionRestoreFromTrash,
343+ ActionRemoveFromTrash
344 };
345
346 void createAndProcessAction(ActionType actionType, const QStringList& paths);
347@@ -227,7 +233,9 @@
348 bool makeBackupNameForCurrentItem(ActionEntry *entry);
349 bool endCopySingleFile();
350 bool isThereDiskSpace(const ActionEntry *entry, qint64 requiredSize);
351- void queueAction(Action *myAction);
352+ void queueAction(Action *myAction);
353+ void createTrashInfoFileFromEntry(ActionEntry *entry);
354+ void removeTrashInfoFileFromEntry(ActionEntry *entry);
355
356 #if defined(REGRESSION_TEST_FOLDERLISTMODEL) //used in Unit/Regression tests
357 bool m_forceUsingOtherFS;
358
359=== modified file 'src/plugin/folderlistmodel/trash/trashlocation.cpp'
360--- src/plugin/folderlistmodel/trash/trashlocation.cpp 2014-05-17 11:47:11 +0000
361+++ src/plugin/folderlistmodel/trash/trashlocation.cpp 2014-05-28 21:14:07 +0000
362@@ -258,3 +258,31 @@
363 {
364 // do nothing, the startExternalFsWatcher() is called in fetchItems()
365 }
366+
367+
368+ActionPaths
369+TrashLocation::getRestorePairPaths(const DirItemInfo& item) const
370+{
371+ const TrashItemInfo* ptrash = static_cast<const TrashItemInfo*> (&item);
372+ QTrashUtilInfo trashInfo;
373+
374+ trashInfo.setInfo(ptrash->getRootTrashDir(), ptrash->absoluteFilePath());
375+
376+ ActionPaths ret(ptrash->absoluteFilePath());
377+ ret.setTargetFullName(trashInfo.getOriginalPathName());
378+
379+ return ret;
380+}
381+
382+
383+ActionPaths
384+TrashLocation::getMovePairPaths(const DirItemInfo &item) const
385+{
386+ ActionPaths ret(item.absoluteFilePath());
387+
388+ QTrashUtilInfo trashInfo;
389+ trashInfo.setInfo(suitableTrash(item.absoluteFilePath()), item.absoluteFilePath());
390+
391+ ret.setTargetFullName( trashInfo.absFile );
392+ return ret;
393+}
394
395=== modified file 'src/plugin/folderlistmodel/trash/trashlocation.h'
396--- src/plugin/folderlistmodel/trash/trashlocation.h 2014-05-15 00:18:54 +0000
397+++ src/plugin/folderlistmodel/trash/trashlocation.h 2014-05-28 21:14:07 +0000
398@@ -45,10 +45,32 @@
399
400 virtual DirItemInfo *validateUrlPath(const QString& urlPath);
401
402+ /*!
403+ * \brief getMovePairPaths() Get: original path and destination trash path
404+ *
405+ *
406+ * \param item desired item to be moved into Trash
407+ *
408+ * \return an \ref ActionPaths that contains the source orginal file and
409+ * the suitable Trash path where the source will moved into
410+ */
411+ ActionPaths getMovePairPaths(const DirItemInfo& item) const;
412+
413+ /*!
414+ * \brief getRestorePairPaths() Get: Trash path as source and item original path as destination
415+ *
416+ * \param item desired to be restored from Trash
417+ *
418+ * \return n \ref ActionPaths that contains the thash item and
419+ * the original source path as destionation
420+ */
421+ ActionPaths getRestorePairPaths(const DirItemInfo& item) const;
422+
423 private:
424 void addTrashFetchRequest(TrashListWorker *workerObject);
425
426 private:
427+ ActionPathList m_actionPathList;
428 QStringList m_currentPaths; //!< also used in the startExternalFsWatcher(), it can br activated any time
429 };
430

Subscribers

People subscribed via source and target branches