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: | 63 |
Merged at revision: | 48 |
Proposed branch: | lp:~carlos-mazieri/ubuntu-filemanager-app/model |
Merge into: | lp:ubuntu-filemanager-app/plugin |
Diff against target: |
3582 lines (+2441/-386) 27 files modified
folderlistmodel/diriteminfo.cpp (+50/-69) folderlistmodel/diriteminfo.h (+47/-5) folderlistmodel/dirmodel.cpp (+151/-158) folderlistmodel/dirmodel.h (+20/-24) folderlistmodel/disk/disklocation.cpp (+222/-0) folderlistmodel/disk/disklocation.h (+81/-0) folderlistmodel/externalfswatcher.cpp (+35/-18) folderlistmodel/externalfswatcher.h (+11/-6) folderlistmodel/filecompare.cpp (+2/-3) folderlistmodel/folderlistmodel.pri (+16/-2) folderlistmodel/iorequest.cpp (+139/-36) folderlistmodel/iorequest.h (+76/-15) folderlistmodel/location.cpp (+140/-0) folderlistmodel/location.h (+132/-0) folderlistmodel/locationsfactory.cpp (+183/-0) folderlistmodel/locationsfactory.h (+133/-0) folderlistmodel/locationurl.cpp (+34/-0) folderlistmodel/locationurl.h (+40/-0) folderlistmodel/trash/qtrashdir.cpp (+21/-18) folderlistmodel/trash/qtrashdir.h (+3/-14) folderlistmodel/trash/qtrashutilinfo.cpp (+87/-0) folderlistmodel/trash/qtrashutilinfo.h (+57/-0) folderlistmodel/trash/trashiteminfo.cpp (+141/-0) folderlistmodel/trash/trashiteminfo.h (+58/-0) folderlistmodel/trash/trashlocation.cpp (+255/-0) folderlistmodel/trash/trashlocation.h (+54/-0) test_folderlistmodel/regression/tst_folderlistmodel.cpp (+253/-18) |
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 | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+212319@code.launchpad.net |
Commit message
File Manager UI will requires changes from this point.
Description of the change
Redesign:
* Created Location class which represents a URL supported in the File Manager
- DiskLocation represents any url/path like file:/// or normal /
- TrashLocation represents any url/path like trash:///
- There will be a SmbLocation for samba/cifs network sharing
* Browsing items (IOReuest/
* External File system watcher handling was moved into DiskLocation class
* Navigation into child folders and up to parent folder were delegated to the Location
* Created LocationsFactory class which keeps the supported Locations, it provides a URL
parser that sets the current Location.
Trash:
* implemented browsing: missing carry orignal item properties
* implemented a specific External File system watcher for trash
* missing Move/Restore to/from Trash (NOT YET IMPLEMENTED)
OBS:
* due to current File Manager UI typing method both: "file:" and "trash:" are supported.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
Due to there were no comments from anyone else, I have to approve it myself.
David Planella (dpm) wrote : | # |
Carlos, could you check this MP as well?
https:/
It'd be good if we could land that and do any new changes in there
On Sat, Apr 5, 2014 at 3:20 PM, <email address hidden> wrote:
> The proposal to merge lp:~carlos-mazieri/ubuntu-filemanager-app/model into
> lp:ubuntu-filemanager-app/plugin has been updated.
>
> Status: Approved => Merged
>
> For more details, see:
>
> https:/
> --
>
> https:/
> Your team Ubuntu File Manager Developers is subscribed to branch
> lp:ubuntu-filemanager-app/plugin.
>
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
David,
Sure, I will take a look on that.
Carlos
On 4/7/14, David Planella <email address hidden> wrote:
> Carlos, could you check this MP as well?
> https:/
>
> It'd be good if we could land that and do any new changes in there
>
>
> On Sat, Apr 5, 2014 at 3:20 PM, <email address hidden> wrote:
>
>> The proposal to merge lp:~carlos-mazieri/ubuntu-filemanager-app/model
>> into
>> lp:ubuntu-filemanager-app/plugin has been updated.
>>
>> Status: Approved => Merged
>>
>> For more details, see:
>>
>> https:/
>> --
>>
>> https:/
>> Your team Ubuntu File Manager Developers is subscribed to branch
>> lp:ubuntu-filemanager-app/plugin.
>>
>
> --
> https:/
> You are the owner of lp:~carlos-mazieri/ubuntu-filemanager-app/model.
>
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
David,
The Status from this MP says "Work in progress",
What do you expect me to do in this MP?
Carlos
On Monday 07 April 2014 18:36:25 you wrote:
> David,
>
> Sure, I will take a look on that.
>
> Carlos
>
> On 4/7/14, David Planella <email address hidden> wrote:
> > Carlos, could you check this MP as well?
> > https:/
> > ge/213368
> >
> > It'd be good if we could land that and do any new changes in there
> >
> > On Sat, Apr 5, 2014 at 3:20 PM, <email address hidden> wrote:
> >> The proposal to merge lp:~carlos-mazieri/ubuntu-filemanager-app/model
> >> into
> >> lp:ubuntu-filemanager-app/plugin has been updated.
> >>
> >> Status: Approved => Merged
> >>
> >> For more details, see:
> >>
> >> https:/
> >> merge/212319 --
> >>
> >> https:/
> >> merge/212319 Your team Ubuntu File Manager Developers is subscribed to
> >> branch
> >> lp:ubuntu-filemanager-app/plugin.
> >
> > --
> > https:/
> > erge/212319 You are the owner of
> > lp:~carlos-mazieri/ubuntu-filemanager-app/model.
David Planella (dpm) wrote : | # |
Hi Carlos,
I think it should be ready for review now after the latest changes. Let me
change the status to Needs Review, and if you could do a review of the MP,
that'd be awesome.
Thanks!
On Tue, Apr 8, 2014 at 1:24 AM, Carlos Jose Mazieri <
<email address hidden>> wrote:
> David,
>
> The Status from this MP says "Work in progress",
> What do you expect me to do in this MP?
>
> Carlos
>
> On Monday 07 April 2014 18:36:25 you wrote:
> > David,
> >
> > Sure, I will take a look on that.
> >
> > Carlos
> >
> > On 4/7/14, David Planella <email address hidden> wrote:
> > > Carlos, could you check this MP as well?
> > >
> https:/
> > > ge/213368
> > >
> > > It'd be good if we could land that and do any new changes in there
> > >
> > > On Sat, Apr 5, 2014 at 3:20 PM, <email address hidden> wrote:
> > >> The proposal to merge lp:~carlos-mazieri/ubuntu-filemanager-app/model
> > >> into
> > >> lp:ubuntu-filemanager-app/plugin has been updated.
> > >>
> > >> Status: Approved => Merged
> > >>
> > >> For more details, see:
> > >>
> > >>
> https:/
> > >> merge/212319 --
> > >>
> > >>
> https:/
> > >> merge/212319 Your team Ubuntu File Manager Developers is subscribed to
> > >> branch
> > >> lp:ubuntu-filemanager-app/plugin.
> > >
> > > --
> > >
> https:/
> > > erge/212319 You are the owner of
> > > lp:~carlos-mazieri/ubuntu-filemanager-app/model.
>
>
> --
>
> https:/
> Your team Ubuntu File Manager Developers is subscribed to branch
> lp:ubuntu-filemanager-app/plugin.
>
Preview Diff
1 | === modified file 'folderlistmodel/diriteminfo.cpp' |
2 | --- folderlistmodel/diriteminfo.cpp 2014-02-07 13:22:44 +0000 |
3 | +++ folderlistmodel/diriteminfo.cpp 2014-03-23 13:46:13 +0000 |
4 | @@ -22,45 +22,6 @@ |
5 | #include "diriteminfo.h" |
6 | |
7 | |
8 | - |
9 | - |
10 | -#include <QUrl> |
11 | -#include <QDir> |
12 | - |
13 | - |
14 | -class DirItemInfoPrivate : public QSharedData |
15 | -{ |
16 | -public: |
17 | - DirItemInfoPrivate(); |
18 | - DirItemInfoPrivate(const DirItemInfoPrivate& other); |
19 | - DirItemInfoPrivate(const QFileInfo& fi); |
20 | - void setFileInfo(const QFileInfo&); |
21 | - |
22 | -public: |
23 | - bool _isValid :1; |
24 | - bool _isLocal :1; |
25 | - bool _isRemote :1; |
26 | - bool _isSelected :1; |
27 | - bool _isAbsolute :1; |
28 | - bool _exists :1; |
29 | - bool _isFile :1; |
30 | - bool _isDir :1; |
31 | - bool _isSymLink :1; |
32 | - bool _isRoot :1; |
33 | - bool _isReadable :1; |
34 | - bool _isWritable :1; |
35 | - bool _isExecutable:1; |
36 | - QFile::Permissions _permissions; |
37 | - qint64 _size; |
38 | - QDateTime _created; |
39 | - QDateTime _lastModified; |
40 | - QDateTime _lastRead; |
41 | - QString _path; |
42 | - QString _fileName; |
43 | - static QMimeDatabase mimeDatabase; |
44 | -}; |
45 | - |
46 | - |
47 | QMimeDatabase DirItemInfoPrivate::mimeDatabase; |
48 | |
49 | |
50 | @@ -128,22 +89,23 @@ |
51 | } |
52 | else |
53 | { |
54 | - _path = fi.absolutePath(); |
55 | - _fileName = fi.fileName(); |
56 | - _isAbsolute = fi.isAbsolute(); |
57 | - _exists = fi.exists(); |
58 | - _isDir = fi.isDir(); |
59 | - _isFile = fi.isFile(); |
60 | - _isSymLink = fi.isSymLink(); |
61 | - _isRoot = fi.isRoot(); |
62 | - _isReadable = fi.isReadable(); |
63 | - _isWritable = fi.isWritable(); |
64 | - _isExecutable = fi.isExecutable(); |
65 | - _permissions = fi.permissions(); |
66 | - _size = fi.size(); |
67 | - _created = fi.created(); |
68 | - _lastRead = fi.lastRead(); |
69 | - _lastModified = fi.lastModified(); |
70 | + _path = fi.absolutePath(); |
71 | + _normalizedPath = _path; |
72 | + _fileName = fi.fileName(); |
73 | + _isAbsolute = fi.isAbsolute(); |
74 | + _exists = fi.exists(); |
75 | + _isDir = fi.isDir(); |
76 | + _isFile = fi.isFile(); |
77 | + _isSymLink = fi.isSymLink(); |
78 | + _isRoot = fi.isRoot(); |
79 | + _isReadable = fi.isReadable(); |
80 | + _isWritable = fi.isWritable(); |
81 | + _isExecutable = fi.isExecutable(); |
82 | + _permissions = fi.permissions(); |
83 | + _size = fi.size(); |
84 | + _created = fi.created(); |
85 | + _lastRead = fi.lastRead(); |
86 | + _lastModified = fi.lastModified(); |
87 | } |
88 | } |
89 | |
90 | @@ -168,8 +130,8 @@ |
91 | |
92 | |
93 | |
94 | -DirItemInfo::DirItemInfo(const QString& urlOrPath): |
95 | - d_ptr( new DirItemInfoPrivate(QFileInfo(urlOrPath)) ) |
96 | +DirItemInfo::DirItemInfo(const QString& filePath): |
97 | + d_ptr( new DirItemInfoPrivate(QFileInfo(filePath)) ) |
98 | { |
99 | |
100 | } |
101 | @@ -219,21 +181,14 @@ |
102 | return d_ptr->_exists; |
103 | } |
104 | |
105 | + |
106 | + |
107 | QString DirItemInfo::filePath() const |
108 | { |
109 | - QString filepath; |
110 | - if (!d_ptr->_path.isEmpty()) |
111 | - { |
112 | - filepath = d_ptr->_path; |
113 | - if (d_ptr->_path != QDir::rootPath()) |
114 | - { |
115 | - filepath += QDir::separator(); |
116 | - } |
117 | - } |
118 | - filepath += d_ptr->_fileName; |
119 | - return filepath; |
120 | + return filePathFrom(d_ptr->_path); |
121 | } |
122 | |
123 | + |
124 | QString DirItemInfo::fileName() const |
125 | { |
126 | return d_ptr->_fileName; |
127 | @@ -251,7 +206,12 @@ |
128 | |
129 | bool DirItemInfo::isReadable() const |
130 | { |
131 | - return d_ptr->_isReadable; |
132 | + bool readable = d_ptr->_isReadable; |
133 | + if (isDir() && !isSymLink()) |
134 | + { |
135 | + readable &= isExecutable(); |
136 | + } |
137 | + return readable; |
138 | } |
139 | |
140 | bool DirItemInfo::isWritable() const |
141 | @@ -343,3 +303,24 @@ |
142 | return d_ptr->mimeDatabase.mimeTypeForFile(diskFileInfo()); |
143 | } |
144 | |
145 | + |
146 | +QString DirItemInfo::urlPath() const |
147 | +{ |
148 | + return filePathFrom(d_ptr->_normalizedPath); |
149 | +} |
150 | + |
151 | + |
152 | +QString DirItemInfo::filePathFrom(const QString& p) const |
153 | +{ |
154 | + QString filepath; |
155 | + if (!p.isEmpty()) |
156 | + { |
157 | + filepath = p; |
158 | + if (!p.endsWith(QDir::separator()) && !d_ptr->_fileName.isEmpty()) |
159 | + { |
160 | + filepath += QDir::separator(); |
161 | + } |
162 | + } |
163 | + filepath += d_ptr->_fileName; |
164 | + return filepath; |
165 | +} |
166 | |
167 | === modified file 'folderlistmodel/diriteminfo.h' |
168 | --- folderlistmodel/diriteminfo.h 2014-02-07 13:22:44 +0000 |
169 | +++ folderlistmodel/diriteminfo.h 2014-03-23 13:46:13 +0000 |
170 | @@ -27,7 +27,7 @@ |
171 | #include <QFileInfo> |
172 | #include <QSharedData> |
173 | #include <QDateTime> |
174 | - |
175 | +#include <QDir> |
176 | #include <QMimeType> |
177 | #include <QMimeDatabase> |
178 | |
179 | @@ -46,9 +46,10 @@ |
180 | { |
181 | public: |
182 | DirItemInfo(); |
183 | - DirItemInfo(const QString& urlOrPath); |
184 | - DirItemInfo(const QFileInfo&); |
185 | + DirItemInfo(const QString& filePath); |
186 | DirItemInfo(const DirItemInfo& other); |
187 | + DirItemInfo(const QFileInfo& fi); |
188 | + |
189 | |
190 | virtual ~DirItemInfo(); |
191 | |
192 | @@ -74,7 +75,7 @@ |
193 | inline void swap(DirItemInfo &other) |
194 | { qSwap(d_ptr, other.d_ptr); } |
195 | |
196 | - inline DirItemInfo& operator=(const DirItemInfo &other) |
197 | + virtual inline DirItemInfo& operator=(const DirItemInfo &other) |
198 | { swap(*(const_cast<DirItemInfo*>(&other))); return *this; } |
199 | |
200 | virtual bool exists() const; |
201 | @@ -82,7 +83,8 @@ |
202 | virtual QString fileName() const; |
203 | virtual QString path() const; |
204 | virtual QString absolutePath() const; |
205 | - virtual QString absoluteFilePath() const; |
206 | + virtual QString absoluteFilePath() const; |
207 | + virtual QString urlPath() const; |
208 | virtual bool isReadable() const; |
209 | virtual bool isWritable() const; |
210 | virtual bool isExecutable() const; |
211 | @@ -110,6 +112,8 @@ |
212 | virtual bool permission(QFile::Permissions permissions) const; |
213 | #endif |
214 | |
215 | +protected: |
216 | + QString filePathFrom(const QString& path) const; |
217 | |
218 | protected: |
219 | QSharedDataPointer<DirItemInfoPrivate> d_ptr; |
220 | @@ -120,4 +124,42 @@ |
221 | Q_DECLARE_SHARED(DirItemInfo) |
222 | Q_DECLARE_METATYPE(DirItemInfo) |
223 | |
224 | + |
225 | + |
226 | + |
227 | +class DirItemInfoPrivate : public QSharedData |
228 | +{ |
229 | +public: |
230 | + DirItemInfoPrivate(); |
231 | + DirItemInfoPrivate(const DirItemInfoPrivate& other); |
232 | + DirItemInfoPrivate(const QFileInfo& fi); |
233 | + void setFileInfo(const QFileInfo&); |
234 | + |
235 | +public: |
236 | + bool _isValid :1; |
237 | + bool _isLocal :1; |
238 | + bool _isRemote :1; |
239 | + bool _isSelected :1; |
240 | + bool _isAbsolute :1; |
241 | + bool _exists :1; |
242 | + bool _isFile :1; |
243 | + bool _isDir :1; |
244 | + bool _isSymLink :1; |
245 | + bool _isRoot :1; |
246 | + bool _isReadable :1; |
247 | + bool _isWritable :1; |
248 | + bool _isExecutable:1; |
249 | + QFile::Permissions _permissions; |
250 | + qint64 _size; |
251 | + QDateTime _created; |
252 | + QDateTime _lastModified; |
253 | + QDateTime _lastRead; |
254 | + QString _path; |
255 | + QString _fileName; |
256 | + QString _normalizedPath; |
257 | + static QMimeDatabase mimeDatabase; |
258 | +}; |
259 | + |
260 | + |
261 | + |
262 | #endif // DIRITEMINFO_H |
263 | |
264 | === modified file 'folderlistmodel/dirmodel.cpp' |
265 | --- folderlistmodel/dirmodel.cpp 2014-03-03 17:19:49 +0000 |
266 | +++ folderlistmodel/dirmodel.cpp 2014-03-23 13:46:13 +0000 |
267 | @@ -31,12 +31,13 @@ |
268 | |
269 | #include "dirselection.h" |
270 | #include "dirmodel.h" |
271 | -#include "iorequest.h" |
272 | -#include "ioworkerthread.h" |
273 | #include "filesystemaction.h" |
274 | -#include "externalfswatcher.h" |
275 | #include "clipboard.h" |
276 | #include "fmutil.h" |
277 | +#include "locationsfactory.h" |
278 | +#include "location.h" |
279 | +#include "locationurl.h" |
280 | +#include "disk/disklocation.h" |
281 | |
282 | |
283 | #ifndef DO_NOT_USE_TAG_LIB |
284 | @@ -75,7 +76,6 @@ |
285 | #define IS_FILE_MANAGER_IDLE() (!mAwaitingResults) |
286 | |
287 | |
288 | -Q_GLOBAL_STATIC(IOWorkerThread, ioWorkerThread) |
289 | |
290 | namespace { |
291 | QHash<QByteArray, int> roleMapping; |
292 | @@ -108,9 +108,11 @@ |
293 | , mSortBy(SortByName) |
294 | , mSortOrder(SortAscending) |
295 | , mCompareFunction(0) |
296 | - , mExtFSWatcher(0) |
297 | - , mClipboard(new Clipboard(this)) |
298 | - , m_fsAction(new FileSystemAction(this) ) |
299 | + , mExtFSWatcher(false) |
300 | + , mClipboard(new Clipboard(this)) |
301 | + , mLocationFactory(new LocationsFactory(this)) |
302 | + , mCurLocation(0) |
303 | + , m_fsAction(new FileSystemAction(this) ) |
304 | { |
305 | mNameFilters = QStringList() << "*"; |
306 | |
307 | @@ -155,13 +157,40 @@ |
308 | { |
309 | FMUtil::setThemeName(); |
310 | } |
311 | + |
312 | + foreach (const Location* l, mLocationFactory->availableLocations()) |
313 | + { |
314 | + connect(l, SIGNAL(itemsAdded(DirItemInfoList)), |
315 | + this, SLOT(onItemsAdded(DirItemInfoList))); |
316 | + |
317 | + connect(l, SIGNAL(itemsFetched()), |
318 | + this, SLOT(onItemsFetched())); |
319 | + |
320 | + connect(l, SIGNAL(extWatcherItemAdded(DirItemInfo)), |
321 | + this, SLOT(onItemAddedOutsideFm(DirItemInfo))); |
322 | + |
323 | + connect(l, SIGNAL(extWatcherItemRemoved(DirItemInfo)), |
324 | + this, SLOT(onItemRemovedOutSideFm(DirItemInfo))); |
325 | + |
326 | + connect(l, SIGNAL(extWatcherItemChanged(DirItemInfo)), |
327 | + this, SLOT(onItemChangedOutSideFm(DirItemInfo))); |
328 | + |
329 | + connect(l, SIGNAL(extWatcherChangesFetched(int)), |
330 | + this, SLOT(onExternalFsWorkerFinished(int))); |
331 | + |
332 | + connect(l, SIGNAL(extWatcherPathChanged(QString)), |
333 | + this, SLOT(onThereAreExternalChanges(QString))); |
334 | + |
335 | + connect(this, SIGNAL(enabledExternalFSWatcherChanged(bool)), |
336 | + l, SLOT(setUsingExternalWatcher(bool))); |
337 | + } |
338 | } |
339 | |
340 | |
341 | |
342 | DirModel::~DirModel() |
343 | { |
344 | - stoptExternalFsWatcher(); |
345 | + |
346 | } |
347 | |
348 | |
349 | @@ -178,7 +207,6 @@ |
350 | |
351 | |
352 | |
353 | - |
354 | QHash<int, QByteArray> DirModel::buildRoleNames() const |
355 | { |
356 | QHash<int, QByteArray> roles; |
357 | @@ -366,43 +394,54 @@ |
358 | return QVariant(); |
359 | } |
360 | |
361 | + |
362 | void DirModel::setPath(const QString &pathName) |
363 | { |
364 | if (pathName.isEmpty()) |
365 | return; |
366 | |
367 | - if (!canReadDir(pathName)) |
368 | - { |
369 | - emit error(tr("cannot read path"), pathName); |
370 | - return; |
371 | - } |
372 | - |
373 | - if (mAwaitingResults) { |
374 | + if (mAwaitingResults) { |
375 | // TODO: handle the case where pathName != our current path, cancel old |
376 | // request, start a new one |
377 | - qDebug() << Q_FUNC_INFO << this << "Ignoring path change request, request already running"; |
378 | - return; |
379 | - } |
380 | - |
381 | + qDebug() << Q_FUNC_INFO << this << "Ignoring path change request, request already running in" << pathName; |
382 | + return; |
383 | + } |
384 | + |
385 | + const Location *location = mLocationFactory->setNewPath(pathName); |
386 | + if (location == 0) |
387 | + { |
388 | + emit error(tr("path or url may not exist or cannot be read"), pathName); |
389 | + qDebug() << Q_FUNC_INFO << this << "path or url may not exist or cannot be read:" << pathName; |
390 | + return; |
391 | + } |
392 | + |
393 | + mCurLocation = const_cast<Location*> (location); |
394 | + setPathFromCurrentLocation(); |
395 | +} |
396 | + |
397 | +/*! |
398 | + * \brief DirModel::setPathFromCurrentLocation() changes current Path using current Location |
399 | + * |
400 | + * Used in \ref cdUp() and \ref cdIntoIndex() |
401 | + */ |
402 | +void DirModel::setPathFromCurrentLocation() |
403 | +{ |
404 | mAwaitingResults = true; |
405 | emit awaitingResultsChanged(); |
406 | #if DEBUG_MESSAGES |
407 | - qDebug() << Q_FUNC_INFO << this << "Changing to " << pathName << " on " << QThread::currentThreadId(); |
408 | + qDebug() << Q_FUNC_INFO << this << "Changing to " << mCurLocation->urlPath(); |
409 | #endif |
410 | |
411 | clear(); |
412 | |
413 | - DirListWorker *dlw = createWorkerRequest(IORequest::DirList, pathName); |
414 | - connect(dlw, SIGNAL(itemsAdded(DirItemInfoList)), SLOT(onItemsAdded(DirItemInfoList))); |
415 | - connect(dlw, SIGNAL(workerFinished()), SLOT(onResultsFetched())); |
416 | - ioWorkerThread()->addRequest(dlw); |
417 | + mCurLocation->fetchItems(currentDirFilter(), mIsRecursive); |
418 | |
419 | - mCurrentDir = pathName; |
420 | - emit pathChanged(pathName); |
421 | + mCurrentDir = mCurLocation->urlPath(); |
422 | + emit pathChanged(mCurLocation->urlPath()); |
423 | } |
424 | |
425 | |
426 | -void DirModel::onResultsFetched() { |
427 | +void DirModel::onItemsFetched() { |
428 | if (mAwaitingResults) { |
429 | #if DEBUG_MESSAGES |
430 | qDebug() << Q_FUNC_INFO << this << "No longer awaiting results"; |
431 | @@ -588,22 +627,33 @@ |
432 | } |
433 | |
434 | #if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
435 | - QVariant DirModel::headerData(int section, Qt::Orientation orientation, int role) const |
436 | - { |
437 | - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) |
438 | - { |
439 | - QVariant ret; |
440 | - QHash<int, QByteArray> roles = this->roleNames(); |
441 | - section += FileNameRole; |
442 | - if (roles.contains(section)) |
443 | - { |
444 | - QString header= QString(roles.value(section)); |
445 | - ret = header; |
446 | - } |
447 | - return ret; |
448 | - } |
449 | - return QAbstractItemModel::headerData(section, orientation, role); |
450 | - } |
451 | +int DirModel::columnCount(const QModelIndex &parent) const |
452 | +{ |
453 | + Q_UNUSED(parent); |
454 | + return TrackCoverRole - FileNameRole + 1; |
455 | +} |
456 | +QVariant DirModel::headerData(int section, Qt::Orientation orientation, int role) const |
457 | +{ |
458 | + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) |
459 | + { |
460 | + QVariant ret; |
461 | + QHash<int, QByteArray> roles = this->roleNames(); |
462 | + section += FileNameRole; |
463 | + if (roles.contains(section)) |
464 | + { |
465 | + QString header= QString(roles.value(section)); |
466 | + ret = header; |
467 | + } |
468 | + return ret; |
469 | + } |
470 | + return QAbstractItemModel::headerData(section, orientation, role); |
471 | +} |
472 | +ExternalFSWatcher * DirModel::getExternalFSWatcher() const |
473 | +{ |
474 | + const Location *l = mLocationFactory->availableLocations().at(LocationsFactory::LocalDisk); |
475 | + const DiskLocation *disk = static_cast<const DiskLocation*> (l); |
476 | + return disk->getExternalFSWatcher(); |
477 | +} |
478 | #endif |
479 | |
480 | |
481 | @@ -613,17 +663,18 @@ |
482 | } |
483 | |
484 | |
485 | +void DirModel::goTrash() |
486 | +{ |
487 | + setPath(LocationUrl::TrashRootURL); |
488 | +} |
489 | + |
490 | + |
491 | bool DirModel::cdUp() |
492 | { |
493 | - int ret = false; |
494 | - if (!mCurrentDir.isEmpty()) // we are in any dir |
495 | + int ret = mCurLocation && mCurLocation->becomeParent(); |
496 | + if (ret) |
497 | { |
498 | - QDir current(mCurrentDir); |
499 | - if (current.cdUp()) |
500 | - { |
501 | - setPath(current.absolutePath()); |
502 | - ret = true; |
503 | - } |
504 | + setPathFromCurrentLocation(); |
505 | } |
506 | return ret; |
507 | } |
508 | @@ -707,9 +758,13 @@ |
509 | bool DirModel::cdIntoIndex(int row) |
510 | { |
511 | bool ret = false; |
512 | - if (IS_VALID_ROW(row)) |
513 | + if (IS_VALID_ROW(row) && |
514 | + mDirectoryContents.at(row).isDir() && |
515 | + mDirectoryContents.at(row).isReadable()) |
516 | { |
517 | - ret = cdInto(mDirectoryContents.at(row)); |
518 | + mCurLocation->setFromInfoItem(mDirectoryContents.at(row)); |
519 | + setPathFromCurrentLocation(); |
520 | + ret = true; |
521 | } |
522 | else |
523 | { |
524 | @@ -1085,7 +1140,14 @@ |
525 | bool ret = false; |
526 | if (IS_VALID_ROW(row)) |
527 | { |
528 | - ret = openItem(mDirectoryContents.at(row)); |
529 | + if (mDirectoryContents.at(row).isDir()) |
530 | + { |
531 | + ret = cdIntoIndex(row); |
532 | + } |
533 | + else |
534 | + { |
535 | + ret = openItem(mDirectoryContents.at(row)); |
536 | + } |
537 | } |
538 | else |
539 | { |
540 | @@ -1096,8 +1158,28 @@ |
541 | |
542 | bool DirModel::openPath(const QString &filename) |
543 | { |
544 | - DirItemInfo fi(setParentIfRelative(filename)); |
545 | - return openItem(fi); |
546 | + bool ret = false; |
547 | + //first void any relative path when is root |
548 | + if ( !(mCurLocation && mCurLocation->isRoot() && filename.startsWith(QLatin1String(".."))) ) |
549 | + { |
550 | + const Location *location = mLocationFactory->setNewPath(filename); |
551 | + if (location) |
552 | + { |
553 | + mCurLocation = const_cast<Location*> (location); |
554 | + setPathFromCurrentLocation(); |
555 | + ret = true; |
556 | + } |
557 | + else |
558 | + { |
559 | + const DirItemInfo *item = mLocationFactory->lastValidFileInfo(); |
560 | + // DirItemInfo fi(setParentIfRelative(filename)); |
561 | + if (item && item->isFile()) |
562 | + { |
563 | + ret = openItem(*item); |
564 | + } |
565 | + } |
566 | + } |
567 | + return ret; |
568 | } |
569 | |
570 | /*! |
571 | @@ -1126,103 +1208,21 @@ |
572 | return ret; |
573 | } |
574 | |
575 | -/*! |
576 | - * \brief DirModel::createWorkerRequest() create a request for IORequestWorker |
577 | - * \param requestType the common IORequest::DirList to fill a directory content |
578 | - * or IORequest::DirAutoRefresh that will verify any external File System modification |
579 | - * \param pathName the path to get content |
580 | - * \return the thread object |
581 | - */ |
582 | -DirListWorker * DirModel::createWorkerRequest(IORequest::RequestType requestType, |
583 | - const QString& pathName) |
584 | -{ |
585 | - DirListWorker * reqThread = 0; |
586 | - QDir::Filter dirFilter = currentDirFilter(); |
587 | - if (requestType == IORequest::DirList) |
588 | - { |
589 | - // TODO: we need to set a spinner active before we start getting results from DirListWorker |
590 | - reqThread = new DirListWorker(pathName, dirFilter, mIsRecursive); |
591 | - } |
592 | - else |
593 | - { |
594 | - reqThread = new ExternalFileSystemChangesWorker(mDirectoryContents, |
595 | - pathName, |
596 | - dirFilter, mIsRecursive); |
597 | - } |
598 | - return reqThread; |
599 | -} |
600 | - |
601 | - |
602 | - |
603 | -/*! |
604 | - * \brief DirModel::startExternalFsWatcher() starts the External File System Watcher |
605 | - */ |
606 | -void DirModel::startExternalFsWatcher() |
607 | -{ |
608 | -#if DEBUG_EXT_FS_WATCHER |
609 | - qDebug() << "[extFsWorker]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
610 | - << Q_FUNC_INFO << this; |
611 | - |
612 | -#endif |
613 | - if (!mExtFSWatcher) |
614 | - { |
615 | - mExtFSWatcher = new ExternalFSWatcher(this); |
616 | - mExtFSWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL); |
617 | - connect(this, SIGNAL(pathChanged(QString)), |
618 | - mExtFSWatcher, SLOT(setCurrentPath(QString))); |
619 | - |
620 | - connect(mExtFSWatcher, SIGNAL(pathModified()), |
621 | - this, SLOT(onThereAreExternalChanges())); |
622 | - |
623 | - //setCurrentPath() checks for empty paths |
624 | - mExtFSWatcher->setCurrentPath(mCurrentDir); |
625 | - } |
626 | -} |
627 | - |
628 | - |
629 | - |
630 | -/*! |
631 | - * \brief DirModel::stoptExternalFsWatcher stops the External File System Watcher |
632 | - */ |
633 | -void DirModel::stoptExternalFsWatcher() |
634 | -{ |
635 | -#if DEBUG_EXT_FS_WATCHER |
636 | - qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
637 | - << Q_FUNC_INFO << this; |
638 | -#endif |
639 | - if (mExtFSWatcher) |
640 | - { |
641 | - delete mExtFSWatcher; |
642 | - mExtFSWatcher = 0; |
643 | - } |
644 | -} |
645 | - |
646 | - |
647 | -void DirModel::onThereAreExternalChanges() |
648 | + |
649 | + |
650 | + |
651 | + |
652 | +void DirModel::onThereAreExternalChanges(const QString& pathModifiedOutside) |
653 | { |
654 | if ( IS_FILE_MANAGER_IDLE() ) |
655 | { |
656 | #if DEBUG_EXT_FS_WATCHER |
657 | qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
658 | - << Q_FUNC_INFO << this << "File System modified"; |
659 | + << Q_FUNC_INFO << this << "File System modified in" << pathModifiedOutside; |
660 | #endif |
661 | - DirListWorker *w = |
662 | - createWorkerRequest(IORequest::DirListExternalFSChanges, |
663 | - mCurrentDir |
664 | - ); |
665 | - ExternalFileSystemChangesWorker *extFsWorker = |
666 | - static_cast<ExternalFileSystemChangesWorker*> (w); |
667 | - |
668 | - connect(extFsWorker, SIGNAL(added(DirItemInfo)), |
669 | - this, SLOT(onItemAddedOutsideFm(DirItemInfo))); |
670 | - connect(extFsWorker, SIGNAL(removed(DirItemInfo)), |
671 | - this, SLOT(onItemRemovedOutSideFm(DirItemInfo))); |
672 | - connect(extFsWorker, SIGNAL(changed(DirItemInfo)), |
673 | - this, SLOT(onItemChangedOutSideFm(DirItemInfo))); |
674 | - connect(extFsWorker, SIGNAL(finished(int)), |
675 | - this, SLOT(onExternalFsWorkerFinished(int))); |
676 | - |
677 | - ioWorkerThread()->addRequest(extFsWorker); |
678 | + mCurLocation->fetchExternalChanges(pathModifiedOutside, |
679 | + mDirectoryContents, |
680 | + currentDirFilter()); |
681 | } |
682 | #if DEBUG_EXT_FS_WATCHER |
683 | else |
684 | @@ -1322,7 +1322,7 @@ |
685 | */ |
686 | bool DirModel::getEnabledExternalFSWatcher() const |
687 | { |
688 | - return mExtFSWatcher ? true : false; |
689 | + return mExtFSWatcher; |
690 | } |
691 | |
692 | |
693 | @@ -1331,15 +1331,8 @@ |
694 | * \param enable |
695 | */ |
696 | void DirModel::setEnabledExternalFSWatcher(bool enable) |
697 | -{ |
698 | - if(enable) |
699 | - { |
700 | - startExternalFsWatcher(); |
701 | - } |
702 | - else |
703 | - { |
704 | - stoptExternalFsWatcher(); |
705 | - } |
706 | +{ |
707 | + emit enabledExternalFSWatcherChanged(enable); |
708 | } |
709 | |
710 | |
711 | |
712 | === modified file 'folderlistmodel/dirmodel.h' |
713 | --- folderlistmodel/dirmodel.h 2014-02-07 13:22:44 +0000 |
714 | +++ folderlistmodel/dirmodel.h 2014-03-23 13:46:13 +0000 |
715 | @@ -42,17 +42,11 @@ |
716 | #include "diriteminfo.h" |
717 | |
718 | class FileSystemAction; |
719 | -class ExternalFSWatcher; |
720 | class Clipboard; |
721 | class DirSelection; |
722 | - |
723 | -/*! |
724 | - * When the External File System Wathcer is enabled, |
725 | - * this is the interval used to check if there has been any change in the current path |
726 | - * |
727 | - * \sa setEnabledExternalFSWatcher() |
728 | - */ |
729 | -#define EX_FS_WATCHER_TIMER_INTERVAL 900 |
730 | +class LocationsFactory; |
731 | +class Location; |
732 | +class ExternalFSWatcher; |
733 | |
734 | class DirModel : public DirItemAbstractListModel |
735 | { |
736 | @@ -150,7 +144,7 @@ |
737 | |
738 | public slots: |
739 | void onItemsAdded(const DirItemInfoList &newFiles); |
740 | - void onResultsFetched(); |
741 | + void onItemsFetched(); |
742 | |
743 | signals: |
744 | void awaitingResultsChanged(); |
745 | @@ -206,7 +200,7 @@ |
746 | Q_PROPERTY(int clipboardUrlsCounter READ getClipboardUrlsCounter NOTIFY clipboardChanged) |
747 | int getClipboardUrlsCounter() const; |
748 | |
749 | - Q_PROPERTY(bool enableExternalFSWatcher READ getEnabledExternalFSWatcher WRITE setEnabledExternalFSWatcher) |
750 | + Q_PROPERTY(bool enableExternalFSWatcher READ getEnabledExternalFSWatcher WRITE setEnabledExternalFSWatcher NOTIFY enabledExternalFSWatcherChanged) |
751 | bool getEnabledExternalFSWatcher() const; |
752 | |
753 | Q_INVOKABLE QString homePath() const; |
754 | @@ -303,6 +297,11 @@ |
755 | void goHome(); |
756 | |
757 | /*! |
758 | + * \brief goTrash() goes to logical folder trash:/// |
759 | + */ |
760 | + void goTrash(); |
761 | + |
762 | + /*! |
763 | * \brief cdUp() sets the parent directory as current directory |
764 | * |
765 | * It can work as a back function if there is no user input path |
766 | @@ -360,8 +359,8 @@ |
767 | void showHiddenFilesChanged(); |
768 | void sortByChanged(); |
769 | void sortOrderChanged(); |
770 | - |
771 | void clipboardChanged(); |
772 | + void enabledExternalFSWatcherChanged(bool); |
773 | |
774 | private slots: |
775 | void onItemRemoved(const QString&); |
776 | @@ -377,12 +376,11 @@ |
777 | QDir::Filter currentDirFilter() const; |
778 | QString dirItems(const DirItemInfo& fi) const; |
779 | bool cdInto(const DirItemInfo& fi); |
780 | - bool openItem(const DirItemInfo& fi); |
781 | - DirListWorker * createWorkerRequest(IORequest::RequestType requestType, |
782 | - const QString& pathName); |
783 | + bool openItem(const DirItemInfo& fi); |
784 | bool canReadDir(const QFileInfo& d) const; |
785 | bool canReadFile(const QFileInfo& f) const; |
786 | QFileInfo setParentIfRelative(const QString &fileOrDir) const; |
787 | + void setPathFromCurrentLocation(); |
788 | |
789 | private: |
790 | void startExternalFsWatcher(); |
791 | @@ -392,7 +390,7 @@ |
792 | void onItemAddedOutsideFm(const DirItemInfo&fi); |
793 | void onItemRemovedOutSideFm(const DirItemInfo&); |
794 | void onItemChangedOutSideFm(const DirItemInfo&fi); |
795 | - void onThereAreExternalChanges(); |
796 | + void onThereAreExternalChanges(const QString &); |
797 | void onExternalFsWorkerFinished(int); |
798 | |
799 | |
800 | @@ -401,9 +399,11 @@ |
801 | SortBy mSortBy; |
802 | SortOrder mSortOrder; |
803 | CompareFunction mCompareFunction; |
804 | - ExternalFSWatcher* mExtFSWatcher; |
805 | + bool mExtFSWatcher; |
806 | Clipboard * mClipboard; |
807 | DirSelection * mSelection; |
808 | + LocationsFactory * mLocationFactory; |
809 | + Location * mCurLocation; |
810 | |
811 | |
812 | private: |
813 | @@ -414,13 +414,9 @@ |
814 | #endif |
815 | //[0] |
816 | |
817 | -#if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
818 | - //make this work with tables |
819 | - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const |
820 | - { |
821 | - Q_UNUSED(parent); |
822 | - return TrackCoverRole - FileNameRole + 1; |
823 | - } |
824 | +#if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
825 | + ExternalFSWatcher * getExternalFSWatcher() const; |
826 | + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; |
827 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; |
828 | friend class TestDirModel; |
829 | #endif |
830 | |
831 | === added directory 'folderlistmodel/disk' |
832 | === added file 'folderlistmodel/disk/disklocation.cpp' |
833 | --- folderlistmodel/disk/disklocation.cpp 1970-01-01 00:00:00 +0000 |
834 | +++ folderlistmodel/disk/disklocation.cpp 2014-03-23 13:46:13 +0000 |
835 | @@ -0,0 +1,222 @@ |
836 | +/************************************************************************** |
837 | + * |
838 | + * Copyright 2014 Canonical Ltd. |
839 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
840 | + * |
841 | + * This program is free software; you can redistribute it and/or modify |
842 | + * it under the terms of the GNU Lesser General Public License as published by |
843 | + * the Free Software Foundation; version 3. |
844 | + * |
845 | + * This program is distributed in the hope that it will be useful, |
846 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
847 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
848 | + * GNU Lesser General Public License for more details. |
849 | + * |
850 | + * You should have received a copy of the GNU Lesser General Public License |
851 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
852 | + * |
853 | + * File: disklocation.cpp |
854 | + * Date: 08/03/2014 |
855 | + */ |
856 | + |
857 | +#include "disklocation.h" |
858 | +#include "iorequest.h" |
859 | +#include "ioworkerthread.h" |
860 | +#include "externalfswatcher.h" |
861 | + |
862 | +#include <QDebug> |
863 | + |
864 | +#if defined(DEBUG_EXT_FS_WATCHER) |
865 | +# define DEBUG_WATCHER() qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") \ |
866 | + << Q_FUNC_INFO << this |
867 | +#else |
868 | +# define DEBUG_WATCHER() /**/ |
869 | +#endif |
870 | + |
871 | +DiskLocation::DiskLocation(int type, QObject *parent) |
872 | + : Location(type, parent) |
873 | + , m_extWatcher(0) |
874 | +{ |
875 | +} |
876 | + |
877 | + |
878 | +DiskLocation::~ DiskLocation() |
879 | +{ |
880 | + stoptExternalFsWatcher(); |
881 | +} |
882 | + |
883 | + |
884 | +void DiskLocation::fetchItems(QDir::Filter dirFilter, bool recursive) |
885 | +{ |
886 | + DirListWorker *dlw = new DirListWorker(m_info->absoluteFilePath(), dirFilter, recursive); |
887 | + connect(dlw, SIGNAL(itemsAdded(DirItemInfoList)), |
888 | + this, SIGNAL(itemsAdded(DirItemInfoList))); |
889 | + connect(dlw, SIGNAL(workerFinished()), |
890 | + this, SLOT(onItemsFetched())); |
891 | + workerThread()->addRequest(dlw); |
892 | +} |
893 | + |
894 | + |
895 | +bool DiskLocation::becomeParent() |
896 | +{ |
897 | + bool ret = false; |
898 | + if (m_info && !m_info->isRoot()) |
899 | + { |
900 | + DirItemInfo *other = new DirItemInfo(m_info->absolutePath()); |
901 | + if (other->isValid()) |
902 | + { |
903 | + delete m_info; |
904 | + m_info = other; |
905 | + ret = true; |
906 | + } |
907 | + else |
908 | + { |
909 | + delete other; |
910 | + } |
911 | + } |
912 | + return ret; |
913 | +} |
914 | + |
915 | + |
916 | +void DiskLocation::refreshInfo() |
917 | +{ |
918 | + if (m_info) |
919 | + { |
920 | + DirItemInfo *item = new DirItemInfo(m_info->absoluteFilePath()); |
921 | + delete m_info; |
922 | + m_info = item; |
923 | + } |
924 | +} |
925 | + |
926 | + |
927 | +/*! |
928 | + * \brief DiskLocation::stoptExternalFsWatcher stops the External File System Watcher |
929 | + */ |
930 | +void DiskLocation::stoptExternalFsWatcher() |
931 | +{ |
932 | + if (m_extWatcher) |
933 | + { |
934 | + DEBUG_WATCHER(); |
935 | + delete m_extWatcher; |
936 | + m_extWatcher = 0; |
937 | + } |
938 | +} |
939 | + |
940 | + |
941 | +/*! |
942 | + * \brief DiskLocation::startExternalFsWatcher() starts the External File System Watcher |
943 | + */ |
944 | +void DiskLocation::startExternalFsWatcher() |
945 | +{ |
946 | + if (m_extWatcher == 0) |
947 | + { |
948 | + DEBUG_WATCHER(); |
949 | + m_extWatcher = new ExternalFSWatcher(this); |
950 | + m_extWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL); |
951 | + |
952 | + connect(m_extWatcher, SIGNAL(pathModified(QString)), |
953 | + this, SIGNAL(extWatcherPathChanged(QString))); |
954 | + if (m_info) |
955 | + { //setCurrentPath() checks for empty paths |
956 | + m_extWatcher->setCurrentPath(m_info->absoluteFilePath()); |
957 | + } |
958 | + } |
959 | +} |
960 | + |
961 | + |
962 | +void DiskLocation::onItemsFetched() |
963 | +{ |
964 | + if (m_extWatcher) |
965 | + { |
966 | + m_extWatcher->setCurrentPath(m_info->absoluteFilePath()); |
967 | + } |
968 | + emit itemsFetched(); |
969 | +} |
970 | + |
971 | + |
972 | +void DiskLocation::startWorking() |
973 | +{ |
974 | + if (m_usingExternalWatcher) |
975 | + { |
976 | + startExternalFsWatcher(); |
977 | + } |
978 | +} |
979 | + |
980 | + |
981 | +void DiskLocation::stopWorking() |
982 | +{ |
983 | + stoptExternalFsWatcher(); |
984 | +} |
985 | + |
986 | + |
987 | +void DiskLocation::fetchExternalChanges(const QString &path, |
988 | + const DirItemInfoList &list, |
989 | + QDir::Filter dirFilter) |
990 | +{ |
991 | + ExternalFileSystemChangesWorker *extFsWorker = |
992 | + new ExternalFileSystemChangesWorker(list, |
993 | + path, |
994 | + dirFilter, false); |
995 | + addExternalFsWorkerRequest(extFsWorker); |
996 | + |
997 | + |
998 | +} |
999 | + |
1000 | +void DiskLocation::addExternalFsWorkerRequest(ExternalFileSystemChangesWorker *extFsWorker) |
1001 | +{ |
1002 | + connect(extFsWorker, SIGNAL(added(DirItemInfo)), |
1003 | + this, SIGNAL(extWatcherItemAdded(DirItemInfo))); |
1004 | + |
1005 | + connect(extFsWorker, SIGNAL(removed(DirItemInfo)), |
1006 | + this, SIGNAL(extWatcherItemRemoved(DirItemInfo))); |
1007 | + |
1008 | + connect(extFsWorker, SIGNAL(changed(DirItemInfo)), |
1009 | + this, SIGNAL(extWatcherItemChanged(DirItemInfo))); |
1010 | + |
1011 | + connect(extFsWorker, SIGNAL(finished(int)), |
1012 | + this, SIGNAL(extWatcherChangesFetched(int))); |
1013 | + |
1014 | + workerThread()->addRequest(extFsWorker); |
1015 | +} |
1016 | + |
1017 | + |
1018 | +ExternalFSWatcher * DiskLocation::getExternalFSWatcher() const |
1019 | +{ |
1020 | + return m_extWatcher; |
1021 | +} |
1022 | + |
1023 | + |
1024 | +void DiskLocation::setUsingExternalWatcher(bool use) |
1025 | +{ |
1026 | + Location::setUsingExternalWatcher(use); |
1027 | + if (m_usingExternalWatcher) |
1028 | + { |
1029 | + startExternalFsWatcher(); |
1030 | + } |
1031 | + else |
1032 | + { |
1033 | + stoptExternalFsWatcher(); |
1034 | + } |
1035 | +} |
1036 | + |
1037 | + |
1038 | +DirItemInfo * DiskLocation::validateUrlPath(const QString& uPath) |
1039 | +{ |
1040 | + QString myPath(uPath); |
1041 | + QFileInfo tmpUrl(uPath); |
1042 | + if (tmpUrl.isRelative() && m_info) |
1043 | + { |
1044 | + tmpUrl.setFile(m_info->absoluteFilePath(), uPath); |
1045 | + myPath = tmpUrl.absoluteFilePath(); |
1046 | + } |
1047 | +#if DEBUG_MESSAGES |
1048 | + qDebug() << Q_FUNC_INFO << "path:" << myPath; |
1049 | +#endif |
1050 | + DirItemInfo * item = new DirItemInfo(myPath); |
1051 | + if (!item->isValid() || !item->exists() || !item->isReadable()) |
1052 | + { |
1053 | + delete item; |
1054 | + item = 0; |
1055 | + } |
1056 | + return item; |
1057 | +} |
1058 | |
1059 | === added file 'folderlistmodel/disk/disklocation.h' |
1060 | --- folderlistmodel/disk/disklocation.h 1970-01-01 00:00:00 +0000 |
1061 | +++ folderlistmodel/disk/disklocation.h 2014-03-23 13:46:13 +0000 |
1062 | @@ -0,0 +1,81 @@ |
1063 | +/************************************************************************** |
1064 | + * |
1065 | + * Copyright 2014 Canonical Ltd. |
1066 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1067 | + * |
1068 | + * This program is free software; you can redistribute it and/or modify |
1069 | + * it under the terms of the GNU Lesser General Public License as published by |
1070 | + * the Free Software Foundation; version 3. |
1071 | + * |
1072 | + * This program is distributed in the hope that it will be useful, |
1073 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1074 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1075 | + * GNU Lesser General Public License for more details. |
1076 | + * |
1077 | + * You should have received a copy of the GNU Lesser General Public License |
1078 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1079 | + * |
1080 | + * File: disklocation.h |
1081 | + * Date: 08/03/2014 |
1082 | + */ |
1083 | + |
1084 | +#ifndef DISKLOCATION_H |
1085 | +#define DISKLOCATION_H |
1086 | + |
1087 | +#include "location.h" |
1088 | +#include <QList> |
1089 | + |
1090 | +/*! |
1091 | + * When the External File System Wathcer is enabled, |
1092 | + * this is the interval used to check if there has been any change in the current path |
1093 | + * |
1094 | + * \sa setEnabledExternalFSWatcher() |
1095 | + */ |
1096 | +#define EX_FS_WATCHER_TIMER_INTERVAL 900 |
1097 | + |
1098 | + |
1099 | +class ExternalFSWatcher; |
1100 | +class ExternalFileSystemChangesWorker; |
1101 | + |
1102 | +/*! |
1103 | + * \brief The DiskLocation class extends \ref Location for Local Disk and provides a External File System watcher |
1104 | + */ |
1105 | +class DiskLocation : public Location |
1106 | +{ |
1107 | + Q_OBJECT |
1108 | +public: |
1109 | + explicit DiskLocation(int type, QObject *parent=0); |
1110 | + ~DiskLocation(); |
1111 | + |
1112 | + ExternalFSWatcher * getExternalFSWatcher() const; |
1113 | + |
1114 | + virtual void fetchItems(QDir::Filter dirFilter, bool recursive = false) ; |
1115 | + virtual void fetchExternalChanges(const QString& urlPath, |
1116 | + const DirItemInfoList& list, |
1117 | + QDir::Filter dirFilter) ; |
1118 | + virtual bool becomeParent(); |
1119 | + virtual void refreshInfo(); |
1120 | + |
1121 | + virtual void startExternalFsWatcher(); |
1122 | + virtual void stoptExternalFsWatcher(); |
1123 | + |
1124 | + virtual void startWorking(); |
1125 | + virtual void stopWorking(); |
1126 | + |
1127 | + virtual DirItemInfo *validateUrlPath(const QString& urlPath); |
1128 | + |
1129 | +protected: |
1130 | + void addExternalFsWorkerRequest(ExternalFileSystemChangesWorker *); |
1131 | + |
1132 | +public slots: |
1133 | + virtual void setUsingExternalWatcher(bool use); |
1134 | + |
1135 | +protected slots: |
1136 | + void onItemsFetched(); |
1137 | + |
1138 | +protected: |
1139 | + ExternalFSWatcher * m_extWatcher ; |
1140 | + |
1141 | +}; |
1142 | + |
1143 | +#endif // DISKLOCATION_H |
1144 | |
1145 | === modified file 'folderlistmodel/externalfswatcher.cpp' |
1146 | --- folderlistmodel/externalfswatcher.cpp 2013-11-17 14:27:10 +0000 |
1147 | +++ folderlistmodel/externalfswatcher.cpp 2014-03-23 13:46:13 +0000 |
1148 | @@ -40,6 +40,7 @@ |
1149 | QFileSystemWatcher(parent) |
1150 | , m_waitingEmitCounter(0) |
1151 | , m_msWaitTime(DEFAULT_NOTICATION_PERIOD) |
1152 | + , m_lastChangedIndex(0) |
1153 | { |
1154 | connect(this, SIGNAL(directoryChanged(QString)), |
1155 | this, SLOT(slotDirChanged(QString))); |
1156 | @@ -49,31 +50,45 @@ |
1157 | void ExternalFSWatcher::setCurrentPath(const QString &curPath) |
1158 | { |
1159 | if (!curPath.isEmpty()) |
1160 | + { |
1161 | + if (m_setPath.count() == 1 && m_setPath.at(0) != curPath) |
1162 | + { |
1163 | + m_setPath.removeFirst(); |
1164 | + } |
1165 | + if (m_setPath.count() == 0) |
1166 | + { |
1167 | + m_setPath.append(curPath); |
1168 | + QFileSystemWatcher::addPath(curPath); |
1169 | + } |
1170 | + } |
1171 | + DEBUG_FSWATCHER(); |
1172 | +} |
1173 | + |
1174 | + |
1175 | +void ExternalFSWatcher::setCurrentPaths(const QStringList &paths) |
1176 | +{ |
1177 | + QStringList myPaths(paths); |
1178 | + ::qSort(myPaths); |
1179 | + QStringList existentPaths = QFileSystemWatcher::directories(); |
1180 | + if (existentPaths.count() > 0) |
1181 | { |
1182 | - if (m_setPath != curPath) |
1183 | - { |
1184 | - if (!m_setPath.isEmpty()) |
1185 | - { |
1186 | - removePath(m_setPath); |
1187 | - } |
1188 | - m_setPath = curPath; |
1189 | - addPath(m_setPath); |
1190 | - } |
1191 | + QFileSystemWatcher::removePaths(existentPaths); |
1192 | } |
1193 | - DEBUG_FSWATCHER(); |
1194 | + m_setPath = myPaths; |
1195 | + QFileSystemWatcher::addPaths(paths); |
1196 | } |
1197 | |
1198 | |
1199 | void ExternalFSWatcher::slotDirChanged(const QString &dir) |
1200 | { |
1201 | DEBUG_FSWATCHER(); |
1202 | - if ( (m_setPath == dir) |
1203 | - && ( m_waitingEmitCounter == 0 || m_setPath != m_changedPath ) |
1204 | + if ( ((m_lastChangedIndex = m_setPath.indexOf(dir)) != -1) |
1205 | + && ( m_waitingEmitCounter == 0 || dir != m_changedPath ) |
1206 | ) |
1207 | { |
1208 | - removePath(m_setPath); |
1209 | + removePath(m_setPath.at(m_lastChangedIndex)); |
1210 | ++m_waitingEmitCounter; |
1211 | - m_changedPath = m_setPath; |
1212 | + m_changedPath = dir; |
1213 | QTimer::singleShot(m_msWaitTime, this, SLOT(slotFireChanges())); |
1214 | } |
1215 | } |
1216 | @@ -87,12 +102,14 @@ |
1217 | */ |
1218 | void ExternalFSWatcher::slotFireChanges() |
1219 | { |
1220 | - if (--m_waitingEmitCounter == 0) |
1221 | + if ( --m_waitingEmitCounter == 0 |
1222 | + && m_lastChangedIndex != -1 |
1223 | + && m_lastChangedIndex < m_setPath.count() ) |
1224 | { |
1225 | - addPath(m_setPath); |
1226 | - if (m_setPath == m_changedPath) |
1227 | + addPath(m_setPath.at(m_lastChangedIndex)); |
1228 | + if (m_setPath.at(m_lastChangedIndex) == m_changedPath) |
1229 | { |
1230 | - emit pathModified(); |
1231 | + emit pathModified(m_changedPath); |
1232 | #if DEBUG_EXT_FS_WATCHER |
1233 | DEBUG_FSWATCHER() << "emit pathModified()"; |
1234 | #endif |
1235 | |
1236 | === modified file 'folderlistmodel/externalfswatcher.h' |
1237 | --- folderlistmodel/externalfswatcher.h 2013-10-20 16:58:41 +0000 |
1238 | +++ folderlistmodel/externalfswatcher.h 2014-03-23 13:46:13 +0000 |
1239 | @@ -23,6 +23,7 @@ |
1240 | #define EXTERNALFSWATCHER_H |
1241 | |
1242 | #include <QFileSystemWatcher> |
1243 | +#include <QStringList> |
1244 | |
1245 | #define DEFAULT_NOTICATION_PERIOD 500 |
1246 | |
1247 | @@ -47,11 +48,14 @@ |
1248 | explicit ExternalFSWatcher(QObject *parent = 0); |
1249 | int getIntervalToNotifyChanges() const; |
1250 | |
1251 | + inline const QStringList& pathsWatched() const { return m_setPath;} |
1252 | + |
1253 | signals: |
1254 | - void pathModified(); |
1255 | + void pathModified(const QString& path); |
1256 | |
1257 | - public slots: |
1258 | +public slots: |
1259 | void setCurrentPath(const QString& curPath); |
1260 | + void setCurrentPaths(const QStringList& paths); |
1261 | void setIntervalToNotifyChanges(int ms); |
1262 | |
1263 | private slots: |
1264 | @@ -59,10 +63,11 @@ |
1265 | void slotFireChanges(); |
1266 | |
1267 | private: |
1268 | - QString m_setPath; |
1269 | - QString m_changedPath; |
1270 | - unsigned m_waitingEmitCounter; |
1271 | - int m_msWaitTime; |
1272 | + QStringList m_setPath; |
1273 | + QString m_changedPath; |
1274 | + unsigned m_waitingEmitCounter; |
1275 | + int m_msWaitTime; |
1276 | + int m_lastChangedIndex; |
1277 | }; |
1278 | |
1279 | #endif // EXTERNALFSWATCHER_H |
1280 | |
1281 | === modified file 'folderlistmodel/filecompare.cpp' |
1282 | --- folderlistmodel/filecompare.cpp 2014-02-05 15:31:44 +0000 |
1283 | +++ folderlistmodel/filecompare.cpp 2014-03-23 13:46:13 +0000 |
1284 | @@ -50,11 +50,10 @@ |
1285 | if (b.isDir() && !a.isDir()) |
1286 | return false; |
1287 | |
1288 | - bool ret = QString::localeAwareCompare(a.fileName(), b.fileName()) < 0; |
1289 | + bool ret = QString::localeAwareCompare(a.absoluteFilePath(), b.absoluteFilePath()) < 0; |
1290 | #if DEBUG_MESSAGES |
1291 | - qDebug() << Q_FUNC_INFO << ret << a.fileName() << b.fileName(); |
1292 | + qDebug() << Q_FUNC_INFO << ret << a.absoluteFilePath() << b.absoluteFilePath(); |
1293 | #endif |
1294 | - |
1295 | return ret; |
1296 | } |
1297 | |
1298 | |
1299 | === modified file 'folderlistmodel/folderlistmodel.pri' |
1300 | --- folderlistmodel/folderlistmodel.pri 2014-02-10 23:41:50 +0000 |
1301 | +++ folderlistmodel/folderlistmodel.pri 2014-03-23 13:46:13 +0000 |
1302 | @@ -9,7 +9,14 @@ |
1303 | $$PWD/fmutil.cpp \ |
1304 | $$PWD/dirselection.cpp \ |
1305 | $$PWD/diriteminfo.cpp \ |
1306 | - $$PWD/trash/qtrashdir.cpp |
1307 | + $$PWD/trash/qtrashdir.cpp \ |
1308 | + $$PWD/trash/trashiteminfo.cpp \ |
1309 | + $$PWD/location.cpp \ |
1310 | + $$PWD/locationsfactory.cpp \ |
1311 | + $$PWD/disk/disklocation.cpp \ |
1312 | + $$PWD/trash/trashlocation.cpp \ |
1313 | + $$PWD/locationurl.cpp \ |
1314 | + $$PWD/trash/qtrashutilinfo.cpp |
1315 | |
1316 | |
1317 | HEADERS += $$PWD/dirmodel.h \ |
1318 | @@ -24,7 +31,14 @@ |
1319 | $$PWD/dirselection.h \ |
1320 | $$PWD/diritemabstractlistmodel.h \ |
1321 | $$PWD/diriteminfo.h \ |
1322 | - $$PWD/trash/qtrashdir.h |
1323 | + $$PWD/trash/qtrashdir.h \ |
1324 | + $$PWD/trash/trashiteminfo.h \ |
1325 | + $$PWD/location.h \ |
1326 | + $$PWD/locationsfactory.h \ |
1327 | + $$PWD/disk/disklocation.h \ |
1328 | + $$PWD/trash/trashlocation.h \ |
1329 | + $$PWD/locationurl.h \ |
1330 | + $$PWD/trash/qtrashutilinfo.h |
1331 | |
1332 | |
1333 | INCLUDEPATH += $$PWD $$PWD/trash |
1334 | |
1335 | === modified file 'folderlistmodel/iorequest.cpp' |
1336 | --- folderlistmodel/iorequest.cpp 2014-02-05 15:31:44 +0000 |
1337 | +++ folderlistmodel/iorequest.cpp 2014-03-23 13:46:13 +0000 |
1338 | @@ -30,6 +30,9 @@ |
1339 | */ |
1340 | |
1341 | #include "iorequest.h" |
1342 | +#include "qtrashutilinfo.h" |
1343 | +#include "diriteminfo.h" |
1344 | +#include "trashiteminfo.h" |
1345 | |
1346 | #include <QDirIterator> |
1347 | #include <QDebug> |
1348 | @@ -48,31 +51,40 @@ |
1349 | return m_type; |
1350 | } |
1351 | |
1352 | - |
1353 | -DirListWorker::DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive) |
1354 | - : mPathName(pathName) |
1355 | - , mFilter(filter) |
1356 | - , mIsRecursive(isRecursive) |
1357 | -{ |
1358 | - |
1359 | -} |
1360 | - |
1361 | - |
1362 | -void DirListWorker::run() |
1363 | -{ |
1364 | -#if DEBUG_MESSAGES |
1365 | - qDebug() << Q_FUNC_INFO << "Running on: " << QThread::currentThreadId(); |
1366 | -#endif |
1367 | - |
1368 | - DirItemInfoList directoryContents = getContents(); |
1369 | - |
1370 | - // last batch |
1371 | - emit itemsAdded(directoryContents); |
1372 | - emit workerFinished(); |
1373 | -} |
1374 | - |
1375 | - |
1376 | -DirItemInfoList DirListWorker::getContents() |
1377 | +//---------------------------------------------------------------------------------- |
1378 | +IORequestLoader::IORequestLoader(const QString &pathName, |
1379 | + QDir::Filter filter, |
1380 | + bool isRecursive) |
1381 | + : IORequest() |
1382 | + , mLoaderType(NormalLoader) |
1383 | + , mPathName(pathName) |
1384 | + , mFilter(filter) |
1385 | + , mIsRecursive(isRecursive) |
1386 | +{ |
1387 | +} |
1388 | + |
1389 | +IORequestLoader::IORequestLoader(const QString& trashRootDir, |
1390 | + const QString &pathName, |
1391 | + QDir::Filter filter, |
1392 | + bool isRecursive) |
1393 | + : IORequest() |
1394 | + , mLoaderType(TrashLoader) |
1395 | + , mPathName(pathName) |
1396 | + , mFilter(filter) |
1397 | + , mIsRecursive(isRecursive) |
1398 | + , mTtrashRootDir(trashRootDir) |
1399 | +{ |
1400 | + |
1401 | +} |
1402 | + |
1403 | +DirItemInfoList IORequestLoader::getContents() |
1404 | +{ |
1405 | + return mLoaderType == NormalLoader ? |
1406 | + getNormalContent() : |
1407 | + getTrashContent(); |
1408 | +} |
1409 | + |
1410 | +DirItemInfoList IORequestLoader::getNormalContent() |
1411 | { |
1412 | #if DEBUG_EXT_FS_WATCHER |
1413 | qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
1414 | @@ -83,10 +95,9 @@ |
1415 | return directoryContents; |
1416 | } |
1417 | |
1418 | - |
1419 | -DirItemInfoList DirListWorker::add(const QString &pathName, |
1420 | +DirItemInfoList IORequestLoader::add(const QString &pathName, |
1421 | QDir::Filter filter, |
1422 | - const bool isRecursive, |
1423 | + bool isRecursive, |
1424 | DirItemInfoList directoryContents) |
1425 | { |
1426 | QDir tmpDir = QDir(pathName, QString(), QDir::NoSort, filter); |
1427 | @@ -108,17 +119,79 @@ |
1428 | directoryContents.erase(directoryContents.begin(), directoryContents.end()); |
1429 | } |
1430 | } |
1431 | - |
1432 | return directoryContents; |
1433 | } |
1434 | |
1435 | +DirItemInfoList IORequestLoader::getTrashContent() |
1436 | +{ |
1437 | + DirItemInfoList directoryContents; |
1438 | + QTrashUtilInfo trashInfo; |
1439 | + QDir tmpDir = QDir(mPathName, QString(), QDir::NoSort, mFilter); |
1440 | + bool isTopLevel = QFileInfo(mPathName).absolutePath() == mTtrashRootDir; |
1441 | + QDirIterator it(tmpDir); |
1442 | + while (it.hasNext()) |
1443 | + { |
1444 | + it.next(); |
1445 | + trashInfo.setInfo(mTtrashRootDir, it.fileInfo().absoluteFilePath()); |
1446 | + if (!isTopLevel || (isTopLevel && trashInfo.existsInfoFile() && trashInfo.existsFile()) ) |
1447 | + { |
1448 | + //TODO read the trashinfo file and set it into a display field |
1449 | + // the display field can be a string the usally points to absoluteFilePath() |
1450 | + // it would be used only in the DirModel::data() |
1451 | + TrashItemInfo item(QTrashUtilInfo::filesTrashDir(mTtrashRootDir), |
1452 | + it.fileInfo().absoluteFilePath()); |
1453 | + directoryContents.append(item); |
1454 | + } |
1455 | + } |
1456 | + return directoryContents; |
1457 | +} |
1458 | + |
1459 | + |
1460 | +//----------------------------------------------------------------------------------------------- |
1461 | +DirListWorker::DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive) |
1462 | + : IORequestLoader(pathName, filter, isRecursive) |
1463 | +{ |
1464 | + |
1465 | +} |
1466 | + |
1467 | + |
1468 | +DirListWorker::DirListWorker(const QString& trashRootDir, const QString &pathName, QDir::Filter filter, const bool isRecursive) |
1469 | + : IORequestLoader(trashRootDir, pathName, filter, isRecursive) |
1470 | +{ |
1471 | + |
1472 | +} |
1473 | + |
1474 | + |
1475 | +void DirListWorker::run() |
1476 | +{ |
1477 | +#if DEBUG_MESSAGES |
1478 | + qDebug() << Q_FUNC_INFO << "Running on: " << QThread::currentThreadId(); |
1479 | +#endif |
1480 | + |
1481 | + DirItemInfoList directoryContents = getContents(); |
1482 | + |
1483 | + // last batch |
1484 | + emit itemsAdded(directoryContents); |
1485 | + emit workerFinished(); |
1486 | +} |
1487 | + |
1488 | + |
1489 | + |
1490 | + |
1491 | +//------------------------------------------------------------------------------------- |
1492 | +TrashListWorker::TrashListWorker(const QString& trashRoot, const QString &path, QDir::Filter filter) |
1493 | + : DirListWorker(trashRoot, path, filter, false) |
1494 | +{ |
1495 | + mLoaderType = TrashLoader; |
1496 | +} |
1497 | + |
1498 | |
1499 | //--------------------------------------------------------------------------------------------------------- |
1500 | ExternalFileSystemChangesWorker::ExternalFileSystemChangesWorker(const DirItemInfoList &content, |
1501 | const QString &pathName, |
1502 | QDir::Filter filter, |
1503 | const bool isRecursive) |
1504 | - : DirListWorker(pathName, filter, isRecursive) |
1505 | + : IORequestLoader(pathName, filter, isRecursive) |
1506 | |
1507 | { |
1508 | m_type = DirListExternalFSChanges; |
1509 | @@ -130,24 +203,23 @@ |
1510 | } |
1511 | |
1512 | |
1513 | -void ExternalFileSystemChangesWorker::run() |
1514 | +int ExternalFileSystemChangesWorker::compareItems(const DirItemInfoList& contentNew) |
1515 | { |
1516 | - DirItemInfoList directoryContents = getContents(); |
1517 | int addedCounter=0; |
1518 | int removedCounter=0; |
1519 | #if DEBUG_EXT_FS_WATCHER |
1520 | qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
1521 | << Q_FUNC_INFO |
1522 | << "m_curContent.count():" << m_curContent.count() |
1523 | - << "directoryContents.count():" << directoryContents.count(); |
1524 | + << "contentNew.count():" << contentNew.count(); |
1525 | #endif |
1526 | - int counter = directoryContents.count(); |
1527 | + int counter = contentNew.count(); |
1528 | if (counter > 0) |
1529 | { |
1530 | int tmpCounter = counter; |
1531 | while (tmpCounter--) |
1532 | { |
1533 | - const DirItemInfo& originalItem = directoryContents.at(tmpCounter); |
1534 | + const DirItemInfo& originalItem = contentNew.at(tmpCounter); |
1535 | const DirItemInfo existItem = m_curContent.value(originalItem.absoluteFilePath()); |
1536 | if ( existItem.exists() ) |
1537 | { |
1538 | @@ -181,5 +253,36 @@ |
1539 | << "addedCounter:" << addedCounter |
1540 | << "removedCounter:" << removedCounter; |
1541 | #endif |
1542 | - emit finished(counter); |
1543 | + |
1544 | + return counter; |
1545 | +} |
1546 | + |
1547 | +void ExternalFileSystemChangesWorker::run() |
1548 | +{ |
1549 | + DirItemInfoList directoryContents = getContents(); |
1550 | + int remainingitemsCounter = compareItems(directoryContents); |
1551 | + emit finished(remainingitemsCounter); |
1552 | +} |
1553 | + |
1554 | + |
1555 | +//--------------------------------------------------------------------- |
1556 | +ExternalFileSystemTrashChangesWorker::ExternalFileSystemTrashChangesWorker(const QStringList &pathNames, |
1557 | + const DirItemInfoList &list, |
1558 | + QDir::Filter filter) |
1559 | + : ExternalFileSystemChangesWorker(list, pathNames.at(0), filter, false) |
1560 | + , m_pathList(pathNames) |
1561 | +{ |
1562 | + mLoaderType = TrashLoader; |
1563 | +} |
1564 | + |
1565 | +void ExternalFileSystemTrashChangesWorker::run() |
1566 | +{ |
1567 | + DirItemInfoList directoryContents; |
1568 | + for(int counter = 0; counter < m_pathList.count(); counter++) |
1569 | + { |
1570 | + mPathName = QTrashUtilInfo::filesTrashDir(m_pathList.at(counter)); |
1571 | + directoryContents += getContents(); |
1572 | + } |
1573 | + int remainingitemsCounter = compareItems(directoryContents); |
1574 | + emit finished(remainingitemsCounter); |
1575 | } |
1576 | |
1577 | === modified file 'folderlistmodel/iorequest.h' |
1578 | --- folderlistmodel/iorequest.h 2014-02-05 15:31:44 +0000 |
1579 | +++ folderlistmodel/iorequest.h 2014-03-23 13:46:13 +0000 |
1580 | @@ -62,31 +62,72 @@ |
1581 | |
1582 | |
1583 | |
1584 | -class DirListWorker : public IORequest |
1585 | +class IORequestLoader : public IORequest |
1586 | { |
1587 | - Q_OBJECT |
1588 | + Q_OBJECT |
1589 | public: |
1590 | - explicit DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive); |
1591 | - void run(); |
1592 | + enum LoaderType |
1593 | + { |
1594 | + NormalLoader, |
1595 | + TrashLoader |
1596 | + }; |
1597 | + |
1598 | + IORequestLoader( const QString &pathName, |
1599 | + QDir::Filter filter, |
1600 | + bool isRecursive |
1601 | + ); |
1602 | + IORequestLoader( const QString& trashRootDir, |
1603 | + const QString &pathName, |
1604 | + QDir::Filter filter, |
1605 | + bool isRecursive |
1606 | + ); |
1607 | + DirItemInfoList getContents(); |
1608 | + |
1609 | signals: |
1610 | void itemsAdded(const DirItemInfoList &files); |
1611 | - void workerFinished(); |
1612 | - |
1613 | -protected: |
1614 | - DirItemInfoList getContents(); |
1615 | |
1616 | private: |
1617 | + DirItemInfoList getNormalContent(); |
1618 | + DirItemInfoList getTrashContent(); |
1619 | DirItemInfoList add(const QString &pathName, QDir::Filter filter, |
1620 | - const bool isRecursive, DirItemInfoList directoryContents); |
1621 | -private: |
1622 | + bool isRecursive, DirItemInfoList directoryContents); |
1623 | +protected: |
1624 | + LoaderType mLoaderType; |
1625 | QString mPathName; |
1626 | QDir::Filter mFilter; |
1627 | bool mIsRecursive; |
1628 | -}; |
1629 | - |
1630 | - |
1631 | - |
1632 | -class ExternalFileSystemChangesWorker : public DirListWorker |
1633 | + QString mTtrashRootDir; |
1634 | +}; |
1635 | + |
1636 | + |
1637 | + |
1638 | + |
1639 | +class DirListWorker : public IORequestLoader |
1640 | +{ |
1641 | + Q_OBJECT |
1642 | +public: |
1643 | + explicit DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive); |
1644 | + explicit DirListWorker(const QString& trashRootDir, const QString &pathName, QDir::Filter filter, const bool isRecursive); |
1645 | + void run(); |
1646 | +protected: |
1647 | +signals: |
1648 | + void workerFinished(); |
1649 | + |
1650 | +}; |
1651 | + |
1652 | + |
1653 | + |
1654 | + |
1655 | +class TrashListWorker : public DirListWorker |
1656 | +{ |
1657 | + Q_OBJECT |
1658 | +public: |
1659 | + explicit TrashListWorker(const QString &trashRoot, const QString& path, QDir::Filter filter); |
1660 | +}; |
1661 | + |
1662 | + |
1663 | + |
1664 | +class ExternalFileSystemChangesWorker : public IORequestLoader |
1665 | { |
1666 | Q_OBJECT |
1667 | public: |
1668 | @@ -95,6 +136,10 @@ |
1669 | QDir::Filter filter, |
1670 | const bool isRecursive); |
1671 | void run(); |
1672 | + |
1673 | +protected: |
1674 | + int compareItems(const DirItemInfoList& contentNew); |
1675 | + |
1676 | signals: |
1677 | void removed(const DirItemInfo&); |
1678 | void changed(const DirItemInfo&); |
1679 | @@ -106,4 +151,20 @@ |
1680 | |
1681 | |
1682 | |
1683 | +class ExternalFileSystemTrashChangesWorker : public ExternalFileSystemChangesWorker |
1684 | +{ |
1685 | + Q_OBJECT |
1686 | + |
1687 | +public: |
1688 | + ExternalFileSystemTrashChangesWorker(const QStringList& pathNames, |
1689 | + const DirItemInfoList& list, |
1690 | + QDir::Filter filter); |
1691 | + |
1692 | + void run(); |
1693 | +private: |
1694 | + QStringList m_pathList; |
1695 | +}; |
1696 | + |
1697 | + |
1698 | + |
1699 | #endif // IOREQUEST_H |
1700 | |
1701 | === added file 'folderlistmodel/location.cpp' |
1702 | --- folderlistmodel/location.cpp 1970-01-01 00:00:00 +0000 |
1703 | +++ folderlistmodel/location.cpp 2014-03-23 13:46:13 +0000 |
1704 | @@ -0,0 +1,140 @@ |
1705 | +/************************************************************************** |
1706 | + * |
1707 | + * Copyright 2014 Canonical Ltd. |
1708 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1709 | + * |
1710 | + * This program is free software; you can redistribute it and/or modify |
1711 | + * it under the terms of the GNU Lesser General Public License as published by |
1712 | + * the Free Software Foundation; version 3. |
1713 | + * |
1714 | + * This program is distributed in the hope that it will be useful, |
1715 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1716 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1717 | + * GNU Lesser General Public License for more details. |
1718 | + * |
1719 | + * You should have received a copy of the GNU Lesser General Public License |
1720 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1721 | + * |
1722 | + * File: location.cpp |
1723 | + * Date: 08/03/2014 |
1724 | + */ |
1725 | +/************************************************************************** |
1726 | + * |
1727 | + * Copyright 2014 Canonical Ltd. |
1728 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1729 | + * |
1730 | + * This program is free software; you can redistribute it and/or modify |
1731 | + * it under the terms of the GNU Lesser General Public License as published by |
1732 | + * the Free Software Foundation; version 3. |
1733 | + * |
1734 | + * This program is distributed in the hope that it will be useful, |
1735 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1736 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1737 | + * GNU Lesser General Public License for more details. |
1738 | + * |
1739 | + * You should have received a copy of the GNU Lesser General Public License |
1740 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1741 | + * |
1742 | + * File: locations.cpp |
1743 | + * Date: 04/03/2014 |
1744 | + */ |
1745 | + |
1746 | +#include "location.h" |
1747 | +#include "ioworkerthread.h" |
1748 | + |
1749 | +Q_GLOBAL_STATIC(IOWorkerThread, ioWorkerThread) |
1750 | + |
1751 | + |
1752 | +Location::Location(int type, QObject *parent) |
1753 | + : QObject(parent) |
1754 | + , m_info(0) |
1755 | + , m_type(type) |
1756 | + , m_usingExternalWatcher(false) |
1757 | +{ |
1758 | + |
1759 | +} |
1760 | + |
1761 | +Location::~Location() |
1762 | +{ |
1763 | + if (m_info) |
1764 | + { |
1765 | + delete m_info; |
1766 | + m_info = 0; |
1767 | + } |
1768 | +} |
1769 | + |
1770 | + |
1771 | +bool Location::isRoot() const |
1772 | +{ |
1773 | + return m_info->isRoot(); |
1774 | +} |
1775 | + |
1776 | + |
1777 | +bool Location::isWritable() const |
1778 | +{ |
1779 | + return m_info->isWritable(); |
1780 | +} |
1781 | + |
1782 | + |
1783 | +bool Location::isReadable() const |
1784 | +{ |
1785 | + return m_info->isReadable(); |
1786 | +} |
1787 | + |
1788 | +void Location::setFromInfoItem(const DirItemInfo &itemInfo) |
1789 | +{ |
1790 | + setFromInfoItem (new DirItemInfo(itemInfo)); |
1791 | +} |
1792 | + |
1793 | +void Location::setFromInfoItem(const DirItemInfo *itemInfo) |
1794 | +{ |
1795 | + if (m_info) |
1796 | + { |
1797 | + delete m_info; |
1798 | + } |
1799 | + m_info = const_cast<DirItemInfo*> (itemInfo); |
1800 | +} |
1801 | + |
1802 | + |
1803 | +QString Location::urlPath() const |
1804 | +{ |
1805 | + return m_info->urlPath(); |
1806 | +} |
1807 | + |
1808 | + |
1809 | +void Location::startWorking() |
1810 | +{ |
1811 | + |
1812 | +} |
1813 | + |
1814 | +void Location::stopWorking() |
1815 | +{ |
1816 | + |
1817 | +} |
1818 | + |
1819 | +bool Location::becomeParent() |
1820 | +{ |
1821 | + return false; |
1822 | +} |
1823 | + |
1824 | +IOWorkerThread * Location::workerThread() const |
1825 | +{ |
1826 | + return ioWorkerThread(); |
1827 | +} |
1828 | + |
1829 | + |
1830 | +//providing an empty method |
1831 | +void Location::fetchExternalChanges(const QString &path, |
1832 | + const DirItemInfoList &list, |
1833 | + QDir::Filter dirFilter) |
1834 | +{ |
1835 | + Q_UNUSED(path); |
1836 | + Q_UNUSED(list); |
1837 | + Q_UNUSED(dirFilter); |
1838 | +} |
1839 | + |
1840 | + |
1841 | +void Location::setUsingExternalWatcher(bool use) |
1842 | +{ |
1843 | + m_usingExternalWatcher = use; |
1844 | +} |
1845 | |
1846 | === added file 'folderlistmodel/location.h' |
1847 | --- folderlistmodel/location.h 1970-01-01 00:00:00 +0000 |
1848 | +++ folderlistmodel/location.h 2014-03-23 13:46:13 +0000 |
1849 | @@ -0,0 +1,132 @@ |
1850 | +/************************************************************************** |
1851 | + * |
1852 | + * Copyright 2014 Canonical Ltd. |
1853 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1854 | + * |
1855 | + * This program is free software; you can redistribute it and/or modify |
1856 | + * it under the terms of the GNU Lesser General Public License as published by |
1857 | + * the Free Software Foundation; version 3. |
1858 | + * |
1859 | + * This program is distributed in the hope that it will be useful, |
1860 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1861 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1862 | + * GNU Lesser General Public License for more details. |
1863 | + * |
1864 | + * You should have received a copy of the GNU Lesser General Public License |
1865 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1866 | + * |
1867 | + * File: location.h |
1868 | + * Date: 08/03/2014 |
1869 | + */ |
1870 | + |
1871 | +#ifndef LOCATION_H |
1872 | +#define LOCATION_H |
1873 | + |
1874 | +#include "diriteminfo.h" |
1875 | + |
1876 | +#include <QObject> |
1877 | + |
1878 | +class IOWorkerThread; |
1879 | + |
1880 | +/*! |
1881 | + * \brief The Location class represents any location (full path) where there are items to browse: directories, shares, from Disk and from Network. |
1882 | + * |
1883 | + * It is an abstract class the must be inherited for specific Location handling as example: \ref DiskLocation and \ref TrashLocation |
1884 | + * |
1885 | + * The location must be able to: |
1886 | + * \li provide the browsing for the location in \ref fetchItems() |
1887 | + * \li become itself its parent in \ref becomeParent() it will allow easy \ref DirModel::cdUp() |
1888 | + * \li refresh its information in \ref refreshInfo() |
1889 | + * \li validate its location (creates a valid DirItemInfo object or any descendent) from a url string |
1890 | + * |
1891 | + * The \ref startWorking() is called by \ref LocationsFactory just before this location becomes the current in the File Manager |
1892 | + * In the same way the \ref stopWorking() is called by \ref LocationsFactory just before this location no longer be the current in the File Manager |
1893 | + */ |
1894 | +class Location : public QObject |
1895 | +{ |
1896 | + Q_OBJECT |
1897 | +public: |
1898 | + explicit Location( int type, QObject *parent=0); |
1899 | + ~Location(); |
1900 | + |
1901 | + IOWorkerThread * workerThread() const; |
1902 | + |
1903 | +signals: |
1904 | + void itemsAdded(const DirItemInfoList &files); |
1905 | + void itemsFetched(); |
1906 | + void extWatcherPathChanged(const QString&); |
1907 | + void extWatcherItemRemoved(const DirItemInfo&); |
1908 | + void extWatcherItemChanged(const DirItemInfo&); |
1909 | + void extWatcherItemAdded(const DirItemInfo&); |
1910 | + void extWatcherChangesFetched(int); |
1911 | + |
1912 | +public slots: |
1913 | + virtual void setUsingExternalWatcher(bool use); |
1914 | + |
1915 | +public: //pure functions |
1916 | + /*! |
1917 | + * \brief fetchItems() gets the content of the Location |
1918 | + * |
1919 | + * \param dirFilter current Filter |
1920 | + * \param recursive should get the content all sub dirs or not, (hardly ever it is true) |
1921 | + */ |
1922 | + virtual void fetchItems(QDir::Filter dirFilter, bool recursive=0) = 0; |
1923 | + |
1924 | + /*! |
1925 | + * \brief refreshInfo() It must refresh the DirItemInfo |
1926 | + * |
1927 | + * It can be used for example after receiving the signal about external disk file system changes |
1928 | + * due to the current path permissions might have changed. |
1929 | + */ |
1930 | + virtual void refreshInfo() = 0; |
1931 | + |
1932 | + /*! |
1933 | + * \brief becomeParent() The current path location becomes the parent Location |
1934 | + * |
1935 | + * When \ref isRoot() returns false the current path location becomes the parent path location |
1936 | + * in order to make it the current. |
1937 | + * It acts like a cdUp, but without fetching items; then calling \ref fetchItems() may get contents. |
1938 | + * |
1939 | + * \note It must take care of deleting \ref m_info when creating a new DirItemInfo/TrashItemInfo etc. |
1940 | + * |
1941 | + * \return true if it is possible to do like a cdUp. |
1942 | + */ |
1943 | + virtual bool becomeParent() = 0; |
1944 | + |
1945 | + /*! |
1946 | + * \brief validateUrlPath() Validates the urlPath (file or Directory) and creates a new Obeject from this path |
1947 | + * |
1948 | + * If urlPath is a valid Directory it can be used later to set a new Location. |
1949 | + * |
1950 | + * \param urlPath |
1951 | + * \return a valid pointer to DirItemInfo object or NULL indicating something wrong with the path |
1952 | + */ |
1953 | + virtual DirItemInfo * validateUrlPath(const QString& urlPath) = 0; |
1954 | + |
1955 | +public: |
1956 | + virtual void fetchExternalChanges(const QString& urlPath, |
1957 | + const DirItemInfoList& list, |
1958 | + QDir::Filter dirFilter) ; |
1959 | + virtual void setFromInfoItem(const DirItemInfo &itemInfo); |
1960 | + virtual void setFromInfoItem(const DirItemInfo *itemInfo); |
1961 | + virtual bool isRoot() const; |
1962 | + virtual bool isWritable() const; |
1963 | + virtual bool isReadable() const; |
1964 | + virtual QString urlPath() const; |
1965 | + virtual void startWorking(); |
1966 | + virtual void stopWorking(); |
1967 | + |
1968 | + inline const DirItemInfo* info() const { return m_info; } |
1969 | + inline int type() const { return m_type; } |
1970 | + |
1971 | +protected: |
1972 | + DirItemInfo * m_info; |
1973 | + int m_type; |
1974 | + bool m_usingExternalWatcher; |
1975 | + |
1976 | +#if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
1977 | + friend class TestDirModel; |
1978 | +#endif |
1979 | + |
1980 | +}; |
1981 | +#endif // LOCATION_H |
1982 | |
1983 | === added file 'folderlistmodel/locationsfactory.cpp' |
1984 | --- folderlistmodel/locationsfactory.cpp 1970-01-01 00:00:00 +0000 |
1985 | +++ folderlistmodel/locationsfactory.cpp 2014-03-23 13:46:13 +0000 |
1986 | @@ -0,0 +1,183 @@ |
1987 | +/************************************************************************** |
1988 | + * |
1989 | + * Copyright 2014 Canonical Ltd. |
1990 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1991 | + * |
1992 | + * This program is free software; you can redistribute it and/or modify |
1993 | + * it under the terms of the GNU Lesser General Public License as published by |
1994 | + * the Free Software Foundation; version 3. |
1995 | + * |
1996 | + * This program is distributed in the hope that it will be useful, |
1997 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1998 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1999 | + * GNU Lesser General Public License for more details. |
2000 | + * |
2001 | + * You should have received a copy of the GNU Lesser General Public License |
2002 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2003 | + * |
2004 | + * File: locationsfactory.cpp |
2005 | + * Date: 05/03/2014 |
2006 | + */ |
2007 | + |
2008 | +#include "diriteminfo.h" |
2009 | +#include "locationsfactory.h" |
2010 | +#include "location.h" |
2011 | +#include "locationurl.h" |
2012 | +#include "disk/disklocation.h" |
2013 | +#include "trash/trashlocation.h" |
2014 | +#include "trashiteminfo.h" |
2015 | + |
2016 | +#include <QDir> |
2017 | +#include <QDebug> |
2018 | + |
2019 | + |
2020 | + |
2021 | +LocationsFactory::LocationsFactory(QObject *parent) |
2022 | + : QObject(parent) |
2023 | + , m_curLoc(0) |
2024 | + , m_lastValidFileInfo(0) |
2025 | +{ |
2026 | + m_locations.append(new DiskLocation(LocalDisk)); |
2027 | + m_locations.append(new TrashLocation(TrashDisk)); |
2028 | +} |
2029 | + |
2030 | + |
2031 | +LocationsFactory::~LocationsFactory() |
2032 | +{ |
2033 | + ::qDeleteAll(m_locations); |
2034 | + m_locations.clear(); |
2035 | +} |
2036 | + |
2037 | + |
2038 | +/*! |
2039 | + * \brief LocationsFactory::parse() identifies what main location that path/url refers to |
2040 | + * \param path it is supposed to be always a full path like: file:///myDir /myDir trash:/// trash:///myDir |
2041 | + * \return |
2042 | + */ |
2043 | + |
2044 | +const Location * LocationsFactory::parse(const QString& uPath) |
2045 | +{ |
2046 | + int index = -1; |
2047 | + int type = -1; |
2048 | + Location * location = 0; |
2049 | + if ( (index = uPath.indexOf(QChar(':'))) != -1 ) |
2050 | + { |
2051 | +#if defined(Q_OS_WIN) |
2052 | +#else |
2053 | +#if defined(Q_OS_UNIX) |
2054 | + if (uPath.startsWith(LocationUrl::TrashRootURL.midRef(0,6))) |
2055 | + { |
2056 | + type = TrashDisk; |
2057 | + m_tmpPath = LocationUrl::TrashRootURL + stringAfterSlahes(uPath, index+1); |
2058 | + } |
2059 | + else |
2060 | +#endif //Q_OS_UNIX |
2061 | +#endif //Q_OS_UNIX |
2062 | + if (uPath.startsWith(LocationUrl::DiskRootURL.midRef(0,5))) |
2063 | + { |
2064 | + type = LocalDisk; |
2065 | + m_tmpPath = QDir::rootPath() + stringAfterSlahes(uPath, index+1); |
2066 | + } |
2067 | + } |
2068 | + else |
2069 | + { |
2070 | + m_tmpPath = stringAfterSlahes(uPath, -1); |
2071 | + type = LocalDisk; |
2072 | + if (!m_tmpPath.startsWith(QDir::rootPath()) && m_curLoc) |
2073 | + { |
2074 | + //it can be any, check current location |
2075 | + type = m_curLoc->type(); |
2076 | + } |
2077 | + } |
2078 | + if (!m_tmpPath.isEmpty() && type != -1) |
2079 | + { |
2080 | + location = m_locations.at(type); |
2081 | + } |
2082 | +#if DEBUG_MESSAGES |
2083 | + qDebug() << Q_FUNC_INFO << "input path:" << uPath << "location result:" << location; |
2084 | +#endif |
2085 | + return location; |
2086 | +} |
2087 | + |
2088 | + |
2089 | +const Location * LocationsFactory::setNewPath(const QString& uPath) |
2090 | +{ |
2091 | + storeValidFileInfo(0); |
2092 | + Location *location = const_cast<Location*> (parse(uPath)); |
2093 | + if (location) |
2094 | + { |
2095 | + const DirItemInfo *item = location->validateUrlPath(m_tmpPath); |
2096 | + if (item) |
2097 | + { |
2098 | + //isReadable() must already carry execution permission |
2099 | + if (item->isValid() && item->isDir() && item->isReadable()) |
2100 | + { |
2101 | + location->setFromInfoItem(item); |
2102 | + if (location != m_curLoc) |
2103 | + { |
2104 | + if (m_curLoc) |
2105 | + { |
2106 | + m_curLoc->stopWorking(); |
2107 | + } |
2108 | + emit locationChanged(m_curLoc, location); |
2109 | + location->startWorking(); |
2110 | + m_curLoc = location; |
2111 | + } |
2112 | + } |
2113 | + else |
2114 | + { |
2115 | + storeValidFileInfo(item); |
2116 | + } |
2117 | + } |
2118 | + else |
2119 | + { // not valid |
2120 | + location = 0; |
2121 | + } |
2122 | + } |
2123 | +#if DEBUG_MESSAGES |
2124 | + qDebug() << Q_FUNC_INFO << "input path:" << uPath << "location result:" << location; |
2125 | +#endif |
2126 | + return location; |
2127 | +} |
2128 | + |
2129 | + |
2130 | +QString LocationsFactory::stringAfterSlahes(const QString &url, int firstSlashIndex) const |
2131 | +{ |
2132 | + QString ret; |
2133 | + if (firstSlashIndex >=0) |
2134 | + { |
2135 | + while ( firstSlashIndex < url.length() && url.at(firstSlashIndex) == QDir::separator()) |
2136 | + { |
2137 | + ++firstSlashIndex; |
2138 | + } |
2139 | + if (firstSlashIndex < url.length()) |
2140 | + { |
2141 | + ret = url.mid(firstSlashIndex); |
2142 | + } |
2143 | + } |
2144 | + else |
2145 | + { |
2146 | + ret = url; |
2147 | + firstSlashIndex = 0; |
2148 | + } |
2149 | + //replace any double slashes by just one |
2150 | + for(int charCounter = ret.size() -1; charCounter > 0; --charCounter) |
2151 | + { |
2152 | + if (ret.at(charCounter) == QDir::separator() && |
2153 | + ret.at(charCounter-1) == QDir::separator()) |
2154 | + { |
2155 | + ret.remove(charCounter,1); |
2156 | + } |
2157 | + } |
2158 | + return ret; |
2159 | +} |
2160 | + |
2161 | + |
2162 | +void LocationsFactory::storeValidFileInfo(const DirItemInfo *item) |
2163 | +{ |
2164 | + if (m_lastValidFileInfo) |
2165 | + { |
2166 | + delete m_lastValidFileInfo; |
2167 | + } |
2168 | + m_lastValidFileInfo = item; |
2169 | +} |
2170 | |
2171 | === added file 'folderlistmodel/locationsfactory.h' |
2172 | --- folderlistmodel/locationsfactory.h 1970-01-01 00:00:00 +0000 |
2173 | +++ folderlistmodel/locationsfactory.h 2014-03-23 13:46:13 +0000 |
2174 | @@ -0,0 +1,133 @@ |
2175 | +/************************************************************************** |
2176 | + * |
2177 | + * Copyright 2014 Canonical Ltd. |
2178 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2179 | + * |
2180 | + * This program is free software; you can redistribute it and/or modify |
2181 | + * it under the terms of the GNU Lesser General Public License as published by |
2182 | + * the Free Software Foundation; version 3. |
2183 | + * |
2184 | + * This program is distributed in the hope that it will be useful, |
2185 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2186 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2187 | + * GNU Lesser General Public License for more details. |
2188 | + * |
2189 | + * You should have received a copy of the GNU Lesser General Public License |
2190 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2191 | + * |
2192 | + * File: locationsfactory.h |
2193 | + * Date: 05/03/2014 |
2194 | + */ |
2195 | + |
2196 | +#ifndef LOCATIONSFACTORY_H |
2197 | +#define LOCATIONSFACTORY_H |
2198 | + |
2199 | +#include <QObject> |
2200 | +#include <QList> |
2201 | + |
2202 | + |
2203 | +class Location; |
2204 | +class DirItemInfo; |
2205 | + |
2206 | +/*! |
2207 | + * \brief The LocationsFactory class represents the set of main |
2208 | + * URL locations the File Manager supports. |
2209 | + * |
2210 | + * It is basically devided into main groups: |
2211 | + * \li Disk: \ref LocalDisk and \ref TrashDisk |
2212 | + * \li Net: \ref NetSambaShare and NetFishShare |
2213 | + * |
2214 | + * smb:// browses workgroup |
2215 | + * |
2216 | + * Location parser: \ref parser() |
2217 | + * \li \\workkgroup becomes smb://workgroup |
2218 | + * \li \\ becomes smb:// |
2219 | + * \li trash:/ and trash:// becomes trash:/// |
2220 | + * \li fish:/ and fish:// becomes fish:/// |
2221 | + * \li file:/ , file:// and file:/// becomes / |
2222 | + * |
2223 | + * \note Due to current File Manager UI typing method both: "file:" and "trash:" are supported |
2224 | + */ |
2225 | +class LocationsFactory : public QObject |
2226 | +{ |
2227 | + Q_OBJECT |
2228 | +public: |
2229 | + explicit LocationsFactory(QObject *parent = 0); |
2230 | + ~LocationsFactory(); |
2231 | + |
2232 | + Q_ENUMS(Locations) |
2233 | + enum Locations |
2234 | + { |
2235 | + LocalDisk, //<! any mounted file system |
2236 | + TrashDisk //<! special trash location in the disk |
2237 | +#if 0 |
2238 | + NetSambaShare //<! SAMBA or CIFS shares |
2239 | + NetFishShare //<! FISH protocol over ssh that provides file sharing |
2240 | +#endif |
2241 | + }; |
2242 | + |
2243 | + /*! |
2244 | + * \brief parse() Just parses (does not set/change the current location) according to \a urlPath |
2245 | + * \param urlPath urlPath the url like: file:///Item trash:///item /item, it MUST point to a valid Directory |
2246 | + * \return The location which supports the \a urlPath |
2247 | + */ |
2248 | + const Location * parse(const QString& urlPath); |
2249 | + |
2250 | + /*! |
2251 | + * \brief setNewPath() Sets a new path, it can be in the current location or on another location |
2252 | + * |
2253 | + * When the location changes, the signal \ref locationChanged() is fired. |
2254 | + * |
2255 | + * \param urlPath the url like: file:///Item trash:///item /item, it MUST point to a valid Directory |
2256 | + * \return the location that supports the urlPath or NULL when \a urlPath is NOT a valid url or it is not a valid Directory |
2257 | + * |
2258 | + * \sa \ref parse() \ref location() |
2259 | + */ |
2260 | + const Location * setNewPath(const QString& urlPath); |
2261 | + |
2262 | + /*! |
2263 | + * \brief location() |
2264 | + * \return The current location |
2265 | + */ |
2266 | + const Location * location() const { return m_curLoc; } |
2267 | + |
2268 | + /*! |
2269 | + * \brief availableLocations() |
2270 | + * \return |
2271 | + */ |
2272 | + const QList<Location*>& |
2273 | + availableLocations() const { return m_locations; } |
2274 | + |
2275 | + /*! |
2276 | + * \brief lastValidFileInfo() |
2277 | + * |
2278 | + * When calling setNewPath(file_path) using a path to a File instead of a Directory |
2279 | + * the setNewPath() is not able to set a new path (current location or other), however it uses |
2280 | + * Location::validateUrlPath() which validates the path for files also, then this valid DirItemInfo object |
2281 | + * is saved using \ref storeValidFileInfo() for further use. |
2282 | + * |
2283 | + * \return The last valid DirItemInfo parsed which is not a Directory |
2284 | + */ |
2285 | + const DirItemInfo* lastValidFileInfo() const { return m_lastValidFileInfo; } |
2286 | + |
2287 | + void storeValidFileInfo(const DirItemInfo *item); |
2288 | + |
2289 | +signals: |
2290 | + void locationChanged(const Location *old, const Location *current); |
2291 | + |
2292 | +private: |
2293 | + QString stringAfterSlahes(const QString& url, int firstSlashIndex) const; |
2294 | + |
2295 | +private: |
2296 | + Location * m_curLoc; |
2297 | + QList<Location*> m_locations; |
2298 | + QString m_tmpPath; |
2299 | + const DirItemInfo * m_lastValidFileInfo; |
2300 | + |
2301 | +#if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
2302 | + friend class TestDirModel; |
2303 | +#endif |
2304 | + |
2305 | +}; |
2306 | + |
2307 | +#endif // LOCATIONSFACTORY_H |
2308 | |
2309 | === added file 'folderlistmodel/locationurl.cpp' |
2310 | --- folderlistmodel/locationurl.cpp 1970-01-01 00:00:00 +0000 |
2311 | +++ folderlistmodel/locationurl.cpp 2014-03-23 13:46:13 +0000 |
2312 | @@ -0,0 +1,34 @@ |
2313 | +/************************************************************************** |
2314 | + * |
2315 | + * Copyright 2014 Canonical Ltd. |
2316 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2317 | + * |
2318 | + * This program is free software; you can redistribute it and/or modify |
2319 | + * it under the terms of the GNU Lesser General Public License as published by |
2320 | + * the Free Software Foundation; version 3. |
2321 | + * |
2322 | + * This program is distributed in the hope that it will be useful, |
2323 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2324 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2325 | + * GNU Lesser General Public License for more details. |
2326 | + * |
2327 | + * You should have received a copy of the GNU Lesser General Public License |
2328 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2329 | + * |
2330 | + * File: locationurl.cpp |
2331 | + * Date: 11/03/2014 |
2332 | + */ |
2333 | + |
2334 | +#include "locationurl.h" |
2335 | + |
2336 | +const QString LocationUrl::TrashRootURL("trash:///"); |
2337 | +const QString LocationUrl::DiskRootURL("file:///"); |
2338 | +#if 0 |
2339 | +QString LocationURL::SmbURL("smb://"); |
2340 | +QString LocationURL::FishURL("fish:///"); |
2341 | +#endif |
2342 | + |
2343 | + |
2344 | +LocationUrl::LocationUrl() |
2345 | +{ |
2346 | +} |
2347 | |
2348 | === added file 'folderlistmodel/locationurl.h' |
2349 | --- folderlistmodel/locationurl.h 1970-01-01 00:00:00 +0000 |
2350 | +++ folderlistmodel/locationurl.h 2014-03-23 13:46:13 +0000 |
2351 | @@ -0,0 +1,40 @@ |
2352 | +/************************************************************************** |
2353 | + * |
2354 | + * Copyright 2014 Canonical Ltd. |
2355 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2356 | + * |
2357 | + * This program is free software; you can redistribute it and/or modify |
2358 | + * it under the terms of the GNU Lesser General Public License as published by |
2359 | + * the Free Software Foundation; version 3. |
2360 | + * |
2361 | + * This program is distributed in the hope that it will be useful, |
2362 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2363 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2364 | + * GNU Lesser General Public License for more details. |
2365 | + * |
2366 | + * You should have received a copy of the GNU Lesser General Public License |
2367 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2368 | + * |
2369 | + * File: locationurl.h |
2370 | + * Date: 11/03/2014 |
2371 | + */ |
2372 | + |
2373 | +#ifndef LOCATIONURL_H |
2374 | +#define LOCATIONURL_H |
2375 | + |
2376 | +#include <QString> |
2377 | + |
2378 | +class LocationUrl |
2379 | +{ |
2380 | +public: |
2381 | + static const QString DiskRootURL; |
2382 | + static const QString TrashRootURL; |
2383 | +#if 0 |
2384 | + static const QString SmbURL; |
2385 | + static const QString FishURL; |
2386 | +#endif |
2387 | +private: |
2388 | + LocationUrl(); |
2389 | +}; |
2390 | + |
2391 | +#endif // LOCATIONURL_H |
2392 | |
2393 | === modified file 'folderlistmodel/trash/qtrashdir.cpp' |
2394 | --- folderlistmodel/trash/qtrashdir.cpp 2014-02-15 15:18:24 +0000 |
2395 | +++ folderlistmodel/trash/qtrashdir.cpp 2014-03-23 13:46:13 +0000 |
2396 | @@ -20,6 +20,7 @@ |
2397 | */ |
2398 | |
2399 | #include "qtrashdir.h" |
2400 | +#include "qtrashutilinfo.h" |
2401 | |
2402 | #include <QFileInfo> |
2403 | #include <QDir> |
2404 | @@ -34,10 +35,6 @@ |
2405 | #endif |
2406 | |
2407 | |
2408 | -QTrashDir::QTrashDir() : m_userId(::getuid()) |
2409 | -{ |
2410 | - |
2411 | -} |
2412 | |
2413 | bool QTrashDir::validate(const QString &trashDir, bool create) const |
2414 | { |
2415 | @@ -49,8 +46,8 @@ |
2416 | } |
2417 | if (checkUserDirPermissions(trashDir)) |
2418 | { |
2419 | - QString files(filesTrashDir(trashDir)); |
2420 | - QString info(infoTrashDir(trashDir)); |
2421 | + QString files(QTrashUtilInfo::filesTrashDir(trashDir)); |
2422 | + QString info(QTrashUtilInfo::infoTrashDir(trashDir)); |
2423 | if ( (checkUserDirPermissions(files) || (create && createUserDir(files))) && |
2424 | (checkUserDirPermissions(info) || (create && createUserDir(info))) |
2425 | ) |
2426 | @@ -170,18 +167,6 @@ |
2427 | } |
2428 | |
2429 | |
2430 | -QString QTrashDir::filesTrashDir(const QString &trashDir) const |
2431 | -{ |
2432 | - QString filesDir(trashDir + QDir::separator() + QLatin1String("files")); |
2433 | - return filesDir; |
2434 | -} |
2435 | - |
2436 | - |
2437 | -QString QTrashDir::infoTrashDir(const QString &trashDir) const |
2438 | -{ |
2439 | - QString infoDir(trashDir + QDir::separator() + QLatin1String("info")); |
2440 | - return infoDir; |
2441 | -} |
2442 | |
2443 | |
2444 | /*! |
2445 | @@ -333,3 +318,21 @@ |
2446 | } |
2447 | return trashDir; |
2448 | } |
2449 | + |
2450 | + |
2451 | +bool QTrashDir:: suitableTrash(const QString &fullPathName, QTrashUtilInfo &fullInfo) const |
2452 | +{ |
2453 | + fullInfo.setInfo(suitableTrash(fullPathName), fullPathName); |
2454 | + return fullInfo.isValid(); |
2455 | +} |
2456 | + |
2457 | + |
2458 | + |
2459 | + |
2460 | + |
2461 | +QTrashDir::QTrashDir() : m_userId(::getuid()) |
2462 | +{ |
2463 | + |
2464 | +} |
2465 | + |
2466 | + |
2467 | |
2468 | === modified file 'folderlistmodel/trash/qtrashdir.h' |
2469 | --- folderlistmodel/trash/qtrashdir.h 2014-02-15 15:18:24 +0000 |
2470 | +++ folderlistmodel/trash/qtrashdir.h 2014-03-23 13:46:13 +0000 |
2471 | @@ -24,7 +24,7 @@ |
2472 | |
2473 | #include <QStringList> |
2474 | #include <QDateTime> |
2475 | - |
2476 | +struct QTrashUtilInfo; |
2477 | |
2478 | /*! |
2479 | * \brief The QTrashDir class is a Qt implementation of the Trash Directories specification |
2480 | @@ -93,19 +93,8 @@ |
2481 | */ |
2482 | QString suitableTrash(const QString &fullPathName) const; |
2483 | |
2484 | - /*! |
2485 | - * \brief filesTrashDir() gets the "files" directory under Trash Dir |
2486 | - * \param trashDir |
2487 | - * \return trashDir/files |
2488 | - */ |
2489 | - QString filesTrashDir(const QString& trashDir) const; |
2490 | + bool suitableTrash(const QString &fullPathName, QTrashUtilInfo& fullInfo) const; |
2491 | |
2492 | - /*! |
2493 | - * \brief infoTrashDir() gets gets the "info" directory under Trash Dir |
2494 | - * \param trashDir |
2495 | - * \return trashDir/info |
2496 | - */ |
2497 | - QString infoTrashDir(const QString& trashDir) const; |
2498 | |
2499 | private: |
2500 | bool validate(const QString& trashDir, bool create=false) const; |
2501 | @@ -120,7 +109,7 @@ |
2502 | |
2503 | private: |
2504 | uint m_userId; |
2505 | - #if defined(REGRESSION_TEST_FOLDERLISTMODEL) //used in Unit/Regression tests |
2506 | +#if defined(REGRESSION_TEST_FOLDERLISTMODEL) //used in Unit/Regression tests |
2507 | friend class TestDirModel; |
2508 | #endif |
2509 | }; |
2510 | |
2511 | === added file 'folderlistmodel/trash/qtrashutilinfo.cpp' |
2512 | --- folderlistmodel/trash/qtrashutilinfo.cpp 1970-01-01 00:00:00 +0000 |
2513 | +++ folderlistmodel/trash/qtrashutilinfo.cpp 2014-03-23 13:46:13 +0000 |
2514 | @@ -0,0 +1,87 @@ |
2515 | +/************************************************************************** |
2516 | + * |
2517 | + * Copyright 2014 Canonical Ltd. |
2518 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2519 | + * |
2520 | + * This program is free software; you can redistribute it and/or modify |
2521 | + * it under the terms of the GNU Lesser General Public License as published by |
2522 | + * the Free Software Foundation; version 3. |
2523 | + * |
2524 | + * This program is distributed in the hope that it will be useful, |
2525 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2526 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2527 | + * GNU Lesser General Public License for more details. |
2528 | + * |
2529 | + * You should have received a copy of the GNU Lesser General Public License |
2530 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2531 | + * |
2532 | + * File: qtrashutilinfo.cpp |
2533 | + * Date: 16/03/2014 |
2534 | + */ |
2535 | + |
2536 | +#include "qtrashutilinfo.h" |
2537 | + |
2538 | +#include <QDir> |
2539 | + |
2540 | + |
2541 | +void QTrashUtilInfo::clear() |
2542 | +{ |
2543 | + trashRoot.clear(); |
2544 | + filesDir.clear(); |
2545 | + absFile.clear(); |
2546 | + infoDir.clear(); |
2547 | + absInfo.clear(); |
2548 | + valid = false; |
2549 | +} |
2550 | + |
2551 | + |
2552 | +QString QTrashUtilInfo::filesTrashDir(const QString &trashDir) |
2553 | +{ |
2554 | + QString filesDir(trashDir + QDir::separator() + QLatin1String("files")); |
2555 | + return filesDir; |
2556 | +} |
2557 | + |
2558 | + |
2559 | +QString QTrashUtilInfo::infoTrashDir(const QString &trashDir) |
2560 | +{ |
2561 | + QString infoDir(trashDir + QDir::separator() + QLatin1String("info")); |
2562 | + return infoDir; |
2563 | +} |
2564 | + |
2565 | + |
2566 | +void QTrashUtilInfo:: setInfo(const QString& trashDir, const QString& filename) |
2567 | +{ |
2568 | + valid = !trashDir.isEmpty(); |
2569 | + if (valid) |
2570 | + { |
2571 | + QFileInfo f(filename); |
2572 | + trashRoot = trashDir; |
2573 | + filesDir = filesTrashDir(trashDir); |
2574 | + absFile = filesDir + QDir::separator() + f.fileName(); |
2575 | + infoDir = infoTrashDir(trashDir) ; |
2576 | + absInfo = infoDir + QDir::separator() + f.fileName() + |
2577 | + QLatin1String(".trashinfo"); |
2578 | + } |
2579 | + else |
2580 | + { |
2581 | + clear(); |
2582 | + } |
2583 | +} |
2584 | + |
2585 | + |
2586 | +bool QTrashUtilInfo::isValid() |
2587 | +{ |
2588 | + return valid; |
2589 | +} |
2590 | + |
2591 | + |
2592 | +bool QTrashUtilInfo::existsFile() |
2593 | +{ |
2594 | + return QFileInfo(absFile).exists(); |
2595 | +} |
2596 | + |
2597 | + |
2598 | +bool QTrashUtilInfo::existsInfoFile() |
2599 | +{ |
2600 | + return QFileInfo(absInfo).exists(); |
2601 | +} |
2602 | |
2603 | === added file 'folderlistmodel/trash/qtrashutilinfo.h' |
2604 | --- folderlistmodel/trash/qtrashutilinfo.h 1970-01-01 00:00:00 +0000 |
2605 | +++ folderlistmodel/trash/qtrashutilinfo.h 2014-03-23 13:46:13 +0000 |
2606 | @@ -0,0 +1,57 @@ |
2607 | +/************************************************************************** |
2608 | + * |
2609 | + * Copyright 2014 Canonical Ltd. |
2610 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2611 | + * |
2612 | + * This program is free software; you can redistribute it and/or modify |
2613 | + * it under the terms of the GNU Lesser General Public License as published by |
2614 | + * the Free Software Foundation; version 3. |
2615 | + * |
2616 | + * This program is distributed in the hope that it will be useful, |
2617 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2618 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2619 | + * GNU Lesser General Public License for more details. |
2620 | + * |
2621 | + * You should have received a copy of the GNU Lesser General Public License |
2622 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2623 | + * |
2624 | + * File: qtrashutilinfo.h |
2625 | + * Date: 16/03/2014 |
2626 | + */ |
2627 | + |
2628 | +#ifndef QTRASHUTILINFO_H |
2629 | +#define QTRASHUTILINFO_H |
2630 | + |
2631 | +#include <QString> |
2632 | + |
2633 | +struct QTrashUtilInfo |
2634 | +{ |
2635 | +public: |
2636 | + void setInfo(const QString& trashDir, const QString& filename); |
2637 | + void clear(); |
2638 | + bool existsInfoFile(); |
2639 | + bool existsFile(); |
2640 | + bool isValid(); |
2641 | + /*! |
2642 | + * \brief filesTrashDir() gets the "files" directory under Trash Dir |
2643 | + * \param trashDir |
2644 | + * \return trashDir/files |
2645 | + */ |
2646 | + static QString filesTrashDir(const QString& trashDir); |
2647 | + |
2648 | + /*! |
2649 | + * \brief infoTrashDir() gets gets the "info" directory under Trash Dir |
2650 | + * \param trashDir |
2651 | + * \return trashDir/info |
2652 | + */ |
2653 | + static QString infoTrashDir(const QString& trashDir); |
2654 | + |
2655 | + QString trashRoot; // root |
2656 | + QString filesDir; // root/files |
2657 | + QString absFile; // root/files/item |
2658 | + QString infoDir; // root/info |
2659 | + QString absInfo; // root/info/item.trashinfo |
2660 | + bool valid; |
2661 | +}; |
2662 | + |
2663 | +#endif // QTRASHUTILINFO_H |
2664 | |
2665 | === added file 'folderlistmodel/trash/trashiteminfo.cpp' |
2666 | --- folderlistmodel/trash/trashiteminfo.cpp 1970-01-01 00:00:00 +0000 |
2667 | +++ folderlistmodel/trash/trashiteminfo.cpp 2014-03-23 13:46:13 +0000 |
2668 | @@ -0,0 +1,141 @@ |
2669 | +/************************************************************************** |
2670 | + * |
2671 | + * Copyright 2014 Canonical Ltd. |
2672 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2673 | + * |
2674 | + * This program is free software; you can redistribute it and/or modify |
2675 | + * it under the terms of the GNU Lesser General Public License as published by |
2676 | + * the Free Software Foundation; version 3. |
2677 | + * |
2678 | + * This program is distributed in the hope that it will be useful, |
2679 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2680 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2681 | + * GNU Lesser General Public License for more details. |
2682 | + * |
2683 | + * You should have received a copy of the GNU Lesser General Public License |
2684 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2685 | + * |
2686 | + * File: trashiteminfo.cpp |
2687 | + * Date: 05/03/2014 |
2688 | + */ |
2689 | + |
2690 | +#include "trashiteminfo.h" |
2691 | +#include "locationurl.h" |
2692 | + |
2693 | + |
2694 | +TrashItemInfo::TrashItemInfo(const QString &urlPath) |
2695 | + : DirItemInfo() |
2696 | +{ |
2697 | + d_ptr->_path = urlPath; |
2698 | + d_ptr->_isLocal = true; |
2699 | + d_ptr->_normalizedPath = urlPath; |
2700 | + if (urlPath == LocationUrl::TrashRootURL) |
2701 | + { |
2702 | + setRoot(); |
2703 | + } |
2704 | +} |
2705 | + |
2706 | + |
2707 | +TrashItemInfo::TrashItemInfo(const TrashItemInfo &other) |
2708 | + : DirItemInfo(other) |
2709 | +{ |
2710 | +} |
2711 | + |
2712 | + |
2713 | +TrashItemInfo::TrashItemInfo(const QString& trashPath, const QString &urlPath) |
2714 | + : DirItemInfo(urlPath) |
2715 | +{ |
2716 | + init(trashPath); |
2717 | +} |
2718 | + |
2719 | + |
2720 | +void TrashItemInfo::setRoot() |
2721 | +{ |
2722 | + d_ptr->_isValid = true; |
2723 | + d_ptr->_isRoot = true; |
2724 | + d_ptr->_isDir = true; |
2725 | + d_ptr->_isReadable = true; |
2726 | + d_ptr->_isExecutable = true; |
2727 | + d_ptr->_exists = true; |
2728 | + d_ptr->_fileName.clear(); |
2729 | +} |
2730 | + |
2731 | + |
2732 | +void TrashItemInfo::init(const QString& trashPath) |
2733 | +{ |
2734 | + if (trashPath == absoluteFilePath()) |
2735 | + { |
2736 | + d_ptr->_path = trashPath; |
2737 | + setRoot(); |
2738 | + } |
2739 | + else |
2740 | + { |
2741 | + if (!d_ptr->_path.startsWith(trashPath)) |
2742 | + { |
2743 | + d_ptr->_isValid = false; |
2744 | + } |
2745 | + } |
2746 | + QString abs(d_ptr->_path); |
2747 | + d_ptr->_normalizedPath = abs.replace(0,trashPath.length()+1, LocationUrl::TrashRootURL); |
2748 | +} |
2749 | + |
2750 | + |
2751 | +TrashItemInfo& TrashItemInfo::operator=(const DirItemInfo &other) |
2752 | +{ |
2753 | + DirItemInfo::operator = (other); |
2754 | + const TrashItemInfo *isTrash = dynamic_cast<const TrashItemInfo*> (&other); |
2755 | + if (isTrash) |
2756 | + { |
2757 | + // move extra data here when exist, avoid extra data than DirItemInfo |
2758 | + } |
2759 | + return *this; |
2760 | +} |
2761 | + |
2762 | + |
2763 | +TrashItemInfo& TrashItemInfo::operator=(const TrashItemInfo &other) |
2764 | +{ |
2765 | + DirItemInfo::operator = (other); |
2766 | + return *this; |
2767 | +} |
2768 | + |
2769 | + |
2770 | +/*! |
2771 | + * \brief TrashItemInfo::getTrashDir() |
2772 | + * |
2773 | + * Lets suppose a directory in the trash named DIR: |
2774 | + * absFilePath() = /home/user/.local/share/Trash/files/DIR |
2775 | + * normalizedFilePath() = trash:///DIR |
2776 | + * |
2777 | + * The trash dir is /home/user/.local/share/Trash/files |
2778 | + * |
2779 | + * \return The trash dir |
2780 | + */ |
2781 | +QString TrashItemInfo::getTrashDir() const |
2782 | +{ |
2783 | + QString trashDir; |
2784 | + QString norm(urlPath()); |
2785 | + if ( norm.length() > LocationUrl::TrashRootURL.length() |
2786 | + && norm.startsWith(LocationUrl::TrashRootURL) |
2787 | + ) |
2788 | + { |
2789 | + QStringRef trashItemRef(norm.midRef(LocationUrl::TrashRootURL.length())); |
2790 | + QString abs(absoluteFilePath()); |
2791 | + int length = abs.lastIndexOf(trashItemRef); |
2792 | + if (length > 0) |
2793 | + { |
2794 | + trashDir = abs.left(length-1); |
2795 | + } |
2796 | + } |
2797 | + return trashDir; |
2798 | +} |
2799 | + |
2800 | + |
2801 | +QString TrashItemInfo::getRootTrashDir() const |
2802 | +{ |
2803 | + QString ret = getTrashDir(); |
2804 | + if (!isRoot()) |
2805 | + { |
2806 | + ret = QFileInfo(ret).absolutePath(); |
2807 | + } |
2808 | + return ret; |
2809 | +} |
2810 | |
2811 | === added file 'folderlistmodel/trash/trashiteminfo.h' |
2812 | --- folderlistmodel/trash/trashiteminfo.h 1970-01-01 00:00:00 +0000 |
2813 | +++ folderlistmodel/trash/trashiteminfo.h 2014-03-23 13:46:13 +0000 |
2814 | @@ -0,0 +1,58 @@ |
2815 | +/************************************************************************** |
2816 | + * |
2817 | + * Copyright 2014 Canonical Ltd. |
2818 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2819 | + * |
2820 | + * This program is free software; you can redistribute it and/or modify |
2821 | + * it under the terms of the GNU Lesser General Public License as published by |
2822 | + * the Free Software Foundation; version 3. |
2823 | + * |
2824 | + * This program is distributed in the hope that it will be useful, |
2825 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2826 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2827 | + * GNU Lesser General Public License for more details. |
2828 | + * |
2829 | + * You should have received a copy of the GNU Lesser General Public License |
2830 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2831 | + * |
2832 | + * File: trashiteminfo.h |
2833 | + * Date: 05/03/2014 |
2834 | + */ |
2835 | + |
2836 | +#ifndef TRASHITEMINFO_H |
2837 | +#define TRASHITEMINFO_H |
2838 | + |
2839 | +#include "diriteminfo.h" |
2840 | + |
2841 | + |
2842 | +/*! |
2843 | + * \brief The TrashItemInfo class provides a QFileInfo like information for files in Trash |
2844 | + * |
2845 | + * Basically it differs from DirItemInfo in the field \a d_ptr->_normalizedPath, it must store the |
2846 | + * url like trash:///Item, while the field d_ptr->_path stores the current path in the file system as usual. |
2847 | + * |
2848 | + * So suppose a Item in the trash: |
2849 | + * \li \ref absoluteFilePath() returns like /home/user/.local/share/Trash/files/Item |
2850 | + * \li \ref urlPath() returns trash:///Item |
2851 | + * \li \ref getTrashDir() does a right-to-left comparing in order to find out the Trash Dir, in this case /home/user/.local/share/Trash/files |
2852 | + * |
2853 | + * The constructor \ref TrashItemInfo(const QString& urlPath) is used only to store the logical root trash folder trash:/// |
2854 | + */ |
2855 | +class TrashItemInfo : public DirItemInfo |
2856 | +{ |
2857 | +public: |
2858 | + TrashItemInfo(const QString& urlPath); |
2859 | + TrashItemInfo(const QString& trashPath, const QString& urlPath); |
2860 | + TrashItemInfo(const TrashItemInfo &other); |
2861 | +public: |
2862 | + virtual TrashItemInfo& operator=(const DirItemInfo &other); |
2863 | + virtual TrashItemInfo& operator=(const TrashItemInfo &other); |
2864 | +public: |
2865 | + QString getTrashDir() const; |
2866 | + QString getRootTrashDir() const; |
2867 | +private: |
2868 | + void setRoot(); |
2869 | + void init(const QString& trashPath); |
2870 | +}; |
2871 | + |
2872 | +#endif // TRASHITEMINFO_H |
2873 | |
2874 | === added file 'folderlistmodel/trash/trashlocation.cpp' |
2875 | --- folderlistmodel/trash/trashlocation.cpp 1970-01-01 00:00:00 +0000 |
2876 | +++ folderlistmodel/trash/trashlocation.cpp 2014-03-23 13:46:13 +0000 |
2877 | @@ -0,0 +1,255 @@ |
2878 | +/************************************************************************** |
2879 | + * |
2880 | + * Copyright 2014 Canonical Ltd. |
2881 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
2882 | + * |
2883 | + * This program is free software; you can redistribute it and/or modify |
2884 | + * it under the terms of the GNU Lesser General Public License as published by |
2885 | + * the Free Software Foundation; version 3. |
2886 | + * |
2887 | + * This program is distributed in the hope that it will be useful, |
2888 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2889 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2890 | + * GNU Lesser General Public License for more details. |
2891 | + * |
2892 | + * You should have received a copy of the GNU Lesser General Public License |
2893 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2894 | + * |
2895 | + * File: trashlocation.cpp |
2896 | + * Date: 08/03/2014 |
2897 | + */ |
2898 | + |
2899 | +#include "iorequest.h" |
2900 | +#include "ioworkerthread.h" |
2901 | +#include "trashlocation.h" |
2902 | +#include "trashiteminfo.h" |
2903 | +#include "qtrashutilinfo.h" |
2904 | +#include "locationurl.h" |
2905 | +#include "externalfswatcher.h" |
2906 | + |
2907 | +#include <QDebug> |
2908 | + |
2909 | +TrashLocation::TrashLocation(int type, QObject *parent) : |
2910 | + DiskLocation(type, parent) |
2911 | + ,QTrashDir() |
2912 | + |
2913 | +{ |
2914 | +} |
2915 | + |
2916 | + |
2917 | +bool TrashLocation::becomeParent() |
2918 | +{ |
2919 | + |
2920 | + bool ret = false; |
2921 | + TrashItemInfo *trashInfo = static_cast<TrashItemInfo*> (m_info); |
2922 | + if (trashInfo && !trashInfo->isRoot()) |
2923 | + { |
2924 | + QString trashDir = trashInfo->getTrashDir(); |
2925 | + if (!trashDir.isEmpty()) |
2926 | + { |
2927 | + TrashItemInfo *other = new TrashItemInfo(trashDir, trashInfo->absolutePath()); |
2928 | + if (other->isValid() && other->isDir()) |
2929 | + { |
2930 | + delete m_info; |
2931 | + m_info = other; |
2932 | + ret = true; |
2933 | + } |
2934 | + else |
2935 | + { |
2936 | + delete other; |
2937 | + } |
2938 | + } |
2939 | + } |
2940 | + return ret; |
2941 | +} |
2942 | + |
2943 | + |
2944 | +DirItemInfo * TrashLocation::validateUrlPath(const QString& urlPath) |
2945 | +{ |
2946 | + TrashItemInfo *item = 0; |
2947 | + QString myPath(urlPath); |
2948 | + |
2949 | + //first void any relative path when is root |
2950 | + if (m_info && m_info->isRoot() && myPath.startsWith(QLatin1String(".."))) |
2951 | + { |
2952 | + return item; |
2953 | + } |
2954 | + |
2955 | + int firstSlash = -1; |
2956 | + |
2957 | + // handle relative paths to the current |
2958 | + if (!myPath.startsWith(LocationUrl::TrashRootURL) && m_info) |
2959 | + { |
2960 | + QFileInfo f; |
2961 | + f.setFile(m_info->absoluteFilePath(), myPath); |
2962 | + if (f.exists() && f.isDir()) |
2963 | + { |
2964 | + TrashItemInfo *trashItem = static_cast<TrashItemInfo*> (m_info); |
2965 | + item = new TrashItemInfo(trashItem->getTrashDir(), f.canonicalFilePath()); |
2966 | +#if DEBUG_MESSAGES |
2967 | + qDebug() << Q_FUNC_INFO << "cur path:" << m_info->absoluteFilePath() |
2968 | + << " new path:" << item->absoluteFilePath() |
2969 | + << "url:" << item->urlPath(); |
2970 | +#endif |
2971 | + } |
2972 | + else |
2973 | + { |
2974 | + myPath = LocationUrl::TrashRootURL + urlPath; |
2975 | + } |
2976 | + } |
2977 | + else |
2978 | + { |
2979 | + item = new TrashItemInfo(myPath); |
2980 | + if (!item->isRoot()) |
2981 | + { |
2982 | + delete item; |
2983 | + item = 0; |
2984 | + } |
2985 | + } |
2986 | + |
2987 | + //Not Relative, handle absolute path but it is not root |
2988 | + if (item == 0) |
2989 | + { |
2990 | + QString absTrashItem; |
2991 | + QString trashItemFromRoot = myPath.mid(LocationUrl::TrashRootURL.size()); |
2992 | + foreach(const QString& trashRoot, allTrashes()) |
2993 | + { |
2994 | + //this is the full path of the item, it does not mean it is a Trash top level item |
2995 | + //example: trash:///Dir1/Dir2/Dir3 may be in /home/user/.local/share/Trash//Dir1/Dir2/Dir3 |
2996 | + absTrashItem = QTrashUtilInfo::filesTrashDir(trashRoot) + QDir::separator() + trashItemFromRoot; |
2997 | + const QFileInfo info(absTrashItem); |
2998 | + if (info.exists()) |
2999 | + { |
3000 | + //check top level trash item |
3001 | + firstSlash = trashItemFromRoot.indexOf(QDir::separator()); |
3002 | + QString toplevelDir = firstSlash != -1 ? trashItemFromRoot.left(firstSlash) |
3003 | + : trashItemFromRoot; |
3004 | + |
3005 | + QTrashUtilInfo topLevelTrashDirInfo; |
3006 | + topLevelTrashDirInfo.setInfo(trashRoot, toplevelDir); |
3007 | +#if DEBUG_MESSAGES |
3008 | + qDebug() << Q_FUNC_INFO |
3009 | + << topLevelTrashDirInfo.absFile << "exists" << topLevelTrashDirInfo.existsFile() |
3010 | + << topLevelTrashDirInfo.absInfo << "exists" << topLevelTrashDirInfo.existsInfoFile(); |
3011 | +#endif |
3012 | + //check if a .trashinfo file for toplevel dir exists |
3013 | + if (topLevelTrashDirInfo.existsInfoFile()) |
3014 | + { |
3015 | + item = new TrashItemInfo(QTrashUtilInfo::filesTrashDir(trashRoot), absTrashItem); |
3016 | + break; |
3017 | + } |
3018 | + } |
3019 | + } |
3020 | + } |
3021 | + |
3022 | + if (item) |
3023 | + { |
3024 | + if (!item->isValid() || !item->isReadable()) |
3025 | + { |
3026 | + delete item; |
3027 | + item = 0; |
3028 | + } |
3029 | + else |
3030 | + { |
3031 | + if (firstSlash != -1) |
3032 | + { |
3033 | + // TODO get the trashinfo information and carry into the item |
3034 | + } |
3035 | + } |
3036 | + } |
3037 | + return item; |
3038 | +} |
3039 | + |
3040 | + |
3041 | + |
3042 | + |
3043 | +void TrashLocation::refreshInfo() |
3044 | +{ |
3045 | + if (m_info && !m_info->isRoot()) |
3046 | + { |
3047 | + TrashItemInfo *trashItem = static_cast<TrashItemInfo*>(m_info); |
3048 | + TrashItemInfo *item = new TrashItemInfo(trashItem->getTrashDir(), trashItem->absoluteFilePath()); |
3049 | + delete m_info; |
3050 | + m_info = item; |
3051 | + } |
3052 | +} |
3053 | + |
3054 | + |
3055 | +void TrashLocation::startExternalFsWatcher() |
3056 | +{ |
3057 | + //TODO implement a Watcher for this |
3058 | + //modify the existent watcher to work having a list of paths |
3059 | + if (m_extWatcher == 0) |
3060 | + { |
3061 | + m_extWatcher = new ExternalFSWatcher(this); |
3062 | + m_extWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL); |
3063 | + |
3064 | + connect(m_extWatcher, SIGNAL(pathModified(QString)), |
3065 | + this, SIGNAL(extWatcherPathChanged(QString))); |
3066 | + } |
3067 | +} |
3068 | + |
3069 | + |
3070 | +void TrashLocation::fetchItems(QDir::Filter dirFilter, bool recursive) |
3071 | +{ |
3072 | + Q_UNUSED(recursive) |
3073 | + if (!m_info->isRoot()) //any item under the logical trash folder |
3074 | + { |
3075 | + //sub items inside Trash do not need external watcher, they will never be updated |
3076 | + stoptExternalFsWatcher(); |
3077 | + TrashItemInfo *trashItem = static_cast<TrashItemInfo*> (m_info); |
3078 | + TrashListWorker *dlw = new TrashListWorker(trashItem->getRootTrashDir(), |
3079 | + trashItem->absoluteFilePath(), |
3080 | + dirFilter); |
3081 | + addTrashFetchRequest(dlw); |
3082 | + } |
3083 | + else |
3084 | + { |
3085 | + QStringList trashes = allTrashes(); |
3086 | + startExternalFsWatcher(); |
3087 | + m_extWatcher->setCurrentPaths(trashes); |
3088 | + //the trash a is logical folder, its content can be composed by more than one physical folder |
3089 | + foreach (const QString& trashRootDir, trashes) |
3090 | + { |
3091 | + TrashListWorker *dlw = new TrashListWorker(trashRootDir, |
3092 | + QTrashUtilInfo::filesTrashDir(trashRootDir), |
3093 | + dirFilter); |
3094 | + addTrashFetchRequest(dlw); |
3095 | + } |
3096 | + } |
3097 | +} |
3098 | + |
3099 | + |
3100 | +void TrashLocation::addTrashFetchRequest(TrashListWorker *workerObject) |
3101 | +{ |
3102 | + connect(workerObject, SIGNAL(itemsAdded(DirItemInfoList)), |
3103 | + this, SIGNAL(itemsAdded(DirItemInfoList))); |
3104 | + //it differs from DiskLocation |
3105 | + connect(workerObject, SIGNAL(workerFinished()), |
3106 | + this, SIGNAL(itemsFetched())); |
3107 | + workerThread()->addRequest(workerObject); |
3108 | +} |
3109 | + |
3110 | + |
3111 | + |
3112 | +void TrashLocation::fetchExternalChanges(const QString& urlPath, |
3113 | + const DirItemInfoList& list, |
3114 | + QDir::Filter dirFilter) |
3115 | +{ |
3116 | + Q_UNUSED(urlPath); |
3117 | + if (m_extWatcher) |
3118 | + { |
3119 | + ExternalFileSystemTrashChangesWorker * extFsWorker = |
3120 | + new ExternalFileSystemTrashChangesWorker( m_extWatcher->pathsWatched(), |
3121 | + list, |
3122 | + dirFilter |
3123 | + ); |
3124 | + addExternalFsWorkerRequest(extFsWorker); |
3125 | + } |
3126 | +} |
3127 | + |
3128 | + |
3129 | +void TrashLocation::startWorking() |
3130 | +{ |
3131 | + // do nothing, the startExternalFsWatcher() is called in fetchItems() |
3132 | +} |
3133 | |
3134 | === added file 'folderlistmodel/trash/trashlocation.h' |
3135 | --- folderlistmodel/trash/trashlocation.h 1970-01-01 00:00:00 +0000 |
3136 | +++ folderlistmodel/trash/trashlocation.h 2014-03-23 13:46:13 +0000 |
3137 | @@ -0,0 +1,54 @@ |
3138 | +/************************************************************************** |
3139 | + * |
3140 | + * Copyright 2014 Canonical Ltd. |
3141 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
3142 | + * |
3143 | + * This program is free software; you can redistribute it and/or modify |
3144 | + * it under the terms of the GNU Lesser General Public License as published by |
3145 | + * the Free Software Foundation; version 3. |
3146 | + * |
3147 | + * This program is distributed in the hope that it will be useful, |
3148 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3149 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3150 | + * GNU Lesser General Public License for more details. |
3151 | + * |
3152 | + * You should have received a copy of the GNU Lesser General Public License |
3153 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3154 | + * |
3155 | + * File: trashlocation.h |
3156 | + * Date: 08/03/2014 |
3157 | + */ |
3158 | + |
3159 | +#ifndef TRASHLOCATION_H |
3160 | +#define TRASHLOCATION_H |
3161 | + |
3162 | +#include "disk/disklocation.h" |
3163 | +#include "trash/qtrashdir.h" |
3164 | + |
3165 | +class TrashListWorker; |
3166 | + |
3167 | +class TrashLocation : public DiskLocation, public QTrashDir |
3168 | +{ |
3169 | + Q_OBJECT |
3170 | +public: |
3171 | + explicit TrashLocation(int type, QObject *parent=0); |
3172 | + virtual bool becomeParent(); |
3173 | + virtual void refreshInfo(); |
3174 | + virtual void fetchItems(QDir::Filter dirFilter, bool recursive=0); |
3175 | + virtual void fetchExternalChanges(const QString& urlPath, |
3176 | + const DirItemInfoList& list, |
3177 | + QDir::Filter dirFilter) ; |
3178 | + |
3179 | + virtual void startWorking(); |
3180 | + virtual void startExternalFsWatcher(); |
3181 | + |
3182 | + virtual DirItemInfo *validateUrlPath(const QString& urlPath); |
3183 | + |
3184 | +private: |
3185 | + void addTrashFetchRequest(TrashListWorker *workerObject); |
3186 | + |
3187 | +public slots: |
3188 | + |
3189 | +}; |
3190 | + |
3191 | +#endif // TRASHLOCATION_H |
3192 | |
3193 | === modified file 'test_folderlistmodel/regression/tst_folderlistmodel.cpp' |
3194 | --- test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-03-03 17:19:49 +0000 |
3195 | +++ test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-03-23 13:46:13 +0000 |
3196 | @@ -4,6 +4,11 @@ |
3197 | #include "externalfswatcher.h" |
3198 | #include "dirselection.h" |
3199 | #include "trash/qtrashdir.h" |
3200 | +#include "location.h" |
3201 | +#include "locationurl.h" |
3202 | +#include "locationsfactory.h" |
3203 | +#include "disk/disklocation.h" |
3204 | +#include "qtrashutilinfo.h" |
3205 | |
3206 | #if defined(Q_OS_UNIX) |
3207 | #include <stdio.h> |
3208 | @@ -77,7 +82,7 @@ |
3209 | void cancel(int index, int, int percent); |
3210 | void slotclipboardChanged(); |
3211 | void slotError(QString title, QString message); |
3212 | - void slotExtFsWatcherPathModified() { ++m_extFSWatcherPathModifiedCounter; } |
3213 | + void slotExtFsWatcherPathModified(const QString&) { ++m_extFSWatcherPathModifiedCounter; } |
3214 | void slotSelectionChanged(int counter) { m_selectedItemsCounter = counter; } |
3215 | void slotSelectionModeChanged(int m) { m_selectionMode = m;} |
3216 | |
3217 | @@ -144,7 +149,10 @@ |
3218 | |
3219 | void trashDiretories(); |
3220 | |
3221 | + void locationFactory(); |
3222 | + |
3223 | private: |
3224 | + bool createTempHomeTrashDir(const QString& existentDir); |
3225 | void initDeepDirs(); |
3226 | void cleanDeepDirs(); |
3227 | void initModels(); |
3228 | @@ -1409,16 +1417,114 @@ |
3229 | QCOMPARE(ret, true); |
3230 | QCOMPARE(m_currentPath, m_deepDir_01->path()); |
3231 | QCOMPARE(m_dirModel_01->rowCount(), 1); |
3232 | + QCOMPARE(m_receivedErrorSignal, false); |
3233 | |
3234 | ret = m_dirModel_01->openPath(QLatin1String("..")); |
3235 | QTest::qWait(TIME_TO_REFRESH_DIR); |
3236 | QCOMPARE(ret, true); |
3237 | QCOMPARE(m_currentPath, QDir::tempPath()); |
3238 | + QCOMPARE(m_receivedErrorSignal, false); |
3239 | |
3240 | ret = m_dirModel_01->openPath(orig); |
3241 | QTest::qWait(TIME_TO_REFRESH_DIR); |
3242 | QCOMPARE(ret, true); |
3243 | QCOMPARE(m_currentPath, m_deepDir_01->path()); |
3244 | + QCOMPARE(m_receivedErrorSignal, false); |
3245 | + |
3246 | + // trash -------------------------------------- |
3247 | + TempFiles files; |
3248 | + QCOMPARE(files.addSubDirLevel(m_deepDir_01->path()), true); |
3249 | + |
3250 | + createTempHomeTrashDir(m_deepDir_01->path()); |
3251 | + |
3252 | + QTrashDir tempTrash; |
3253 | + QCOMPARE(files.addSubDirLevel(tempTrash.homeTrash()), true); |
3254 | + QCOMPARE(files.addSubDirLevel(QTrashUtilInfo::filesTrashDir(tempTrash.homeTrash())), true); |
3255 | + |
3256 | + QString level1("Level1"); |
3257 | + QCOMPARE(files.addSubDirLevel(level1), true); |
3258 | + |
3259 | + QTrashUtilInfo trashInfo; |
3260 | + trashInfo.setInfo(tempTrash.homeTrash(), level1); |
3261 | + QCOMPARE(trashInfo.existsFile() , true); |
3262 | + QFile infoFile(trashInfo.absInfo); |
3263 | + QCOMPARE(infoFile.open(QFile::WriteOnly), true); |
3264 | + infoFile.close(); |
3265 | + |
3266 | + //check if "Level1" is valid item under trash |
3267 | + QCOMPARE(trashInfo.existsInfoFile() , true); |
3268 | + |
3269 | + QString level2("level2"); |
3270 | + QString level3("level3"); |
3271 | + |
3272 | + QCOMPARE(files.addSubDirLevel(level2), true); |
3273 | + QCOMPARE(files.addSubDirLevel(level3), true); |
3274 | + |
3275 | + files.create(1); |
3276 | + |
3277 | + // using trash:/// |
3278 | + ret = m_dirModel_01->openPath(LocationUrl::TrashRootURL); |
3279 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3280 | + QCOMPARE(ret, true); |
3281 | + QCOMPARE(m_currentPath, LocationUrl::TrashRootURL); |
3282 | + QCOMPARE(m_receivedErrorSignal, false); |
3283 | + |
3284 | + // using relative "Level1" |
3285 | + ret = m_dirModel_01->openPath(level1); |
3286 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3287 | + QCOMPARE(ret, true); |
3288 | + QCOMPARE(m_currentPath, QString(LocationUrl::TrashRootURL + level1) ); |
3289 | + QCOMPARE(m_receivedErrorSignal, false); |
3290 | + |
3291 | + //using trash:///Level1/Level2/Level3 |
3292 | + QString deep(LocationUrl::TrashRootURL + level1 + QDir::separator() + level2 + QDir::separator() + level3); |
3293 | + ret = m_dirModel_01->openPath(deep); |
3294 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3295 | + QCOMPARE(ret, true); |
3296 | + QCOMPARE(m_receivedErrorSignal, false); |
3297 | + |
3298 | + //using ../ to go up into Level2 |
3299 | + ret = m_dirModel_01->openPath("../"); |
3300 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3301 | + QCOMPARE(ret, true); |
3302 | + QCOMPARE(m_receivedErrorSignal, false); |
3303 | + |
3304 | + //using .. to go up into Level1 |
3305 | + ret = m_dirModel_01->openPath(".."); |
3306 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3307 | + QCOMPARE(ret, true); |
3308 | + QCOMPARE(m_receivedErrorSignal, false); |
3309 | + |
3310 | + //back to trash:/// |
3311 | + ret = m_dirModel_01->openPath(".."); |
3312 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3313 | + QCOMPARE(ret, true); |
3314 | + QCOMPARE(m_currentPath, LocationUrl::TrashRootURL); |
3315 | + QCOMPARE(m_receivedErrorSignal, false); |
3316 | + |
3317 | + //now it must fail |
3318 | + ret = m_dirModel_01->openPath(".."); |
3319 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3320 | + QCOMPARE(ret, false); |
3321 | + QCOMPARE(m_receivedErrorSignal, false); |
3322 | + |
3323 | + ret = m_dirModel_01->openPath("file:///"); |
3324 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3325 | + QCOMPARE(ret, true); |
3326 | + QCOMPARE(m_currentPath, QDir::rootPath()); |
3327 | + QCOMPARE(m_receivedErrorSignal, false); |
3328 | + |
3329 | + ret = m_dirModel_01->openPath("file://"); |
3330 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3331 | + QCOMPARE(ret, true); |
3332 | + QCOMPARE(m_currentPath, QDir::rootPath()); |
3333 | + QCOMPARE(m_receivedErrorSignal, false); |
3334 | + |
3335 | + ret = m_dirModel_01->openPath("file:/"); |
3336 | + QTest::qWait(TIME_TO_REFRESH_DIR); |
3337 | + QCOMPARE(ret, true); |
3338 | + QCOMPARE(m_currentPath, QDir::rootPath()); |
3339 | + QCOMPARE(m_receivedErrorSignal, false); |
3340 | } |
3341 | |
3342 | |
3343 | @@ -1859,8 +1965,8 @@ |
3344 | void TestDirModel::extFsWatcherChangePathManyTimesModifyAllPathsLessLast() |
3345 | { |
3346 | ExternalFSWatcher watcher; |
3347 | - connect(&watcher, SIGNAL(pathModified()), |
3348 | - this, SLOT(slotExtFsWatcherPathModified())); |
3349 | + connect(&watcher, SIGNAL(pathModified(QString)), |
3350 | + this, SLOT(slotExtFsWatcherPathModified(QString))); |
3351 | |
3352 | const int items = 150; |
3353 | QVector<DeepDir *> deepDirs; |
3354 | @@ -1896,8 +2002,8 @@ |
3355 | void TestDirModel::extFsWatcherChangePathManyTimesModifyManyTimes() |
3356 | { |
3357 | ExternalFSWatcher watcher; |
3358 | - connect(&watcher, SIGNAL(pathModified()), |
3359 | - this, SLOT(slotExtFsWatcherPathModified())); |
3360 | + connect(&watcher, SIGNAL(pathModified(QString)), |
3361 | + this, SLOT(slotExtFsWatcherPathModified(QString))); |
3362 | |
3363 | const int items = 50; |
3364 | QVector<DeepDir *> deepDirs; |
3365 | @@ -1930,8 +2036,8 @@ |
3366 | void TestDirModel::extFsWatcherModifySamePathManyTimesWithInInterval() |
3367 | { |
3368 | ExternalFSWatcher watcher; |
3369 | - connect(&watcher, SIGNAL(pathModified()), |
3370 | - this, SLOT(slotExtFsWatcherPathModified())); |
3371 | + connect(&watcher, SIGNAL(pathModified(QString)), |
3372 | + this, SLOT(slotExtFsWatcherPathModified(QString))); |
3373 | |
3374 | QString dirName("extFsWatcher_expects_just_one_signal"); |
3375 | m_deepDir_01 = new DeepDir(dirName,0); |
3376 | @@ -1957,8 +2063,8 @@ |
3377 | void TestDirModel::extFsWatcherSetPathAndModifyManyTimesWithInInterval() |
3378 | { |
3379 | ExternalFSWatcher watcher; |
3380 | - connect(&watcher, SIGNAL(pathModified()), |
3381 | - this, SLOT(slotExtFsWatcherPathModified())); |
3382 | + connect(&watcher, SIGNAL(pathModified(QString)), |
3383 | + this, SLOT(slotExtFsWatcherPathModified(QString))); |
3384 | |
3385 | QList<DeepDir *> deepDirs; |
3386 | |
3387 | @@ -1995,8 +2101,8 @@ |
3388 | { |
3389 | bool updateAndSetModificationTime(const QString& filename, QDateTime& desiredTime); |
3390 | |
3391 | - connect( m_dirModel_01->mExtFSWatcher, SIGNAL(pathModified()), |
3392 | - this, SLOT(slotExtFsWatcherPathModified())); |
3393 | + connect( m_dirModel_01->getExternalFSWatcher(), SIGNAL(pathModified(QString)), |
3394 | + this, SLOT(slotExtFsWatcherPathModified(QString))); |
3395 | |
3396 | QString dirName("extFsWatcher_generate_fileswithsameTimeStamp"); |
3397 | m_deepDir_01 = new DeepDir(dirName,0); |
3398 | @@ -2029,7 +2135,7 @@ |
3399 | QFileInfo firstFile(firstPathName); |
3400 | QCOMPARE(firstFile.lastModified(), timeStamp); |
3401 | |
3402 | - const int maxWait = m_dirModel_01->mExtFSWatcher->getIntervalToNotifyChanges() + 10; |
3403 | + const int maxWait = m_dirModel_01->getExternalFSWatcher()->getIntervalToNotifyChanges() + 10; |
3404 | int counter = 0; |
3405 | |
3406 | //make sure ExternalFSWatcher has not notified any change |
3407 | @@ -2308,9 +2414,9 @@ |
3408 | QCOMPARE(trash.checkUserDirPermissions(trashDir), true); |
3409 | |
3410 | //create files in Trash |
3411 | - QCOMPARE(trash.createUserDir(trash.filesTrashDir(trashDir)), true); |
3412 | + QCOMPARE(trash.createUserDir(QTrashUtilInfo::filesTrashDir(trashDir)), true); |
3413 | //create info in Trash |
3414 | - QCOMPARE(trash.createUserDir(trash.infoTrashDir(trashDir)), true); |
3415 | + QCOMPARE(trash.createUserDir(QTrashUtilInfo::infoTrashDir(trashDir)), true); |
3416 | //test validate Trash Dir(), now it MUST pass |
3417 | QCOMPARE(trash.validate(trashDir, false), true); |
3418 | |
3419 | @@ -2327,16 +2433,18 @@ |
3420 | QString xdgTrash("xdg_Trash"); |
3421 | m_deepDir_02 = new DeepDir(xdgTrash,0); |
3422 | |
3423 | + if (::qgetenv("XDG_DATA_HOME").size() == 0) |
3424 | + { |
3425 | + QString myTrash(QDir::homePath() + "/.local/share/Trash"); |
3426 | + QCOMPARE(trash.homeTrash(), myTrash); |
3427 | + } |
3428 | + |
3429 | //test XDG Home Trash |
3430 | ::setenv("XDG_DATA_HOME", m_deepDir_02->path().toLatin1().constData(), true ); |
3431 | - |
3432 | QString xdgTrashDir(trash.homeTrash()); |
3433 | QCOMPARE(trash.validate(xdgTrashDir, false), true); |
3434 | QCOMPARE(trash.homeTrash() , xdgTrashDir); |
3435 | |
3436 | - ::setenv("XDG_DATA_HOME", "\0", true ); |
3437 | - QCOMPARE(trash.homeTrash() , QDir::homePath() + "/.local/share/Trash"); |
3438 | - |
3439 | QCOMPARE(trash.getMountPoint(QDir::rootPath()), QDir::rootPath()); |
3440 | |
3441 | QStringList mountedPoints = trash.mountedPoints(); |
3442 | @@ -2389,6 +2497,118 @@ |
3443 | } |
3444 | |
3445 | |
3446 | +void TestDirModel::locationFactory() |
3447 | +{ |
3448 | + LocationsFactory factoryLocations(this); |
3449 | + const Location *location = 0; |
3450 | + |
3451 | + QString validTrashURL(LocationUrl::TrashRootURL); |
3452 | + |
3453 | + //Due to current File Manager UI typing method both: "file:" and "trash:" are supported |
3454 | + // location = factoryLocations.setNewPath("trash:"); |
3455 | + // QVERIFY(location == 0); |
3456 | + |
3457 | + location = factoryLocations.setNewPath("trash:/"); |
3458 | + QVERIFY(location); |
3459 | + QVERIFY(location->type() == LocationsFactory::TrashDisk); |
3460 | + QCOMPARE(location->info()->absoluteFilePath(), validTrashURL); |
3461 | + QCOMPARE(location->urlPath(), validTrashURL); |
3462 | + QCOMPARE(location->isRoot(), true); |
3463 | + |
3464 | + location = factoryLocations.setNewPath("trash://"); |
3465 | + QVERIFY(location); |
3466 | + QVERIFY(location->type() == LocationsFactory::TrashDisk); |
3467 | + QCOMPARE(location->info()->absoluteFilePath(), validTrashURL); |
3468 | + QCOMPARE(location->urlPath(), validTrashURL); |
3469 | + QCOMPARE(location->isRoot(), true); |
3470 | + |
3471 | + location = factoryLocations.setNewPath("trash:///"); |
3472 | + QVERIFY(location); |
3473 | + QVERIFY(location->type() == LocationsFactory::TrashDisk); |
3474 | + QCOMPARE(location->info()->absoluteFilePath(), validTrashURL); |
3475 | + QCOMPARE(location->urlPath(), validTrashURL); |
3476 | + QCOMPARE(location->isRoot(), true); |
3477 | + |
3478 | + location = factoryLocations.setNewPath("trash://////"); |
3479 | + QVERIFY(location); |
3480 | + QVERIFY(location->type() == LocationsFactory::TrashDisk); |
3481 | + QCOMPARE(location->info()->absoluteFilePath(), validTrashURL); |
3482 | + QCOMPARE(location->urlPath(), validTrashURL); |
3483 | + QCOMPARE(location->isRoot(), true); |
3484 | + |
3485 | + QString myDir("___myDir_must_NOT_EXIST___"); |
3486 | + location = factoryLocations.setNewPath(QString("trash:/") + myDir); |
3487 | + QVERIFY(location == 0); |
3488 | + |
3489 | + location = factoryLocations.setNewPath("file://////"); |
3490 | + QVERIFY(location); |
3491 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
3492 | + QCOMPARE(location->info()->absoluteFilePath(), QDir::rootPath()); |
3493 | + QCOMPARE(location->urlPath(), QDir::rootPath()); |
3494 | + QCOMPARE(location->isRoot(), true); |
3495 | + |
3496 | + location = factoryLocations.setNewPath("/"); |
3497 | + QVERIFY(location); |
3498 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
3499 | + QCOMPARE(location->info()->absoluteFilePath(), QDir::rootPath()); |
3500 | + QCOMPARE(location->urlPath(), QDir::rootPath()); |
3501 | + QCOMPARE(location->isRoot(), true); |
3502 | + |
3503 | + location = factoryLocations.setNewPath("//"); |
3504 | + QVERIFY(location); |
3505 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
3506 | + QCOMPARE(location->info()->absoluteFilePath(), QDir::rootPath()); |
3507 | + QCOMPARE(location->urlPath(), QDir::rootPath()); |
3508 | + QCOMPARE(location->isRoot(), true); |
3509 | + |
3510 | + location = factoryLocations.setNewPath("//bin"); |
3511 | + QVERIFY(location); |
3512 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
3513 | + QCOMPARE(location->info()->absoluteFilePath(), QLatin1String("/bin")); |
3514 | + QCOMPARE(location->urlPath(), QLatin1String("/bin")); |
3515 | + QCOMPARE(location->isRoot(), false); |
3516 | + |
3517 | + QTrashDir trash; |
3518 | + QString dirName("trashDirectory"); |
3519 | + m_deepDir_01 = new DeepDir(dirName,0); |
3520 | + |
3521 | + //create a Trash to have |
3522 | + |
3523 | + ::setenv("XDG_DATA_HOME", m_deepDir_01->path().toLatin1().constData(), true ); |
3524 | + QString xdgTrashDir(trash.homeTrash()); |
3525 | + QCOMPARE(trash.validate(xdgTrashDir, true), true); |
3526 | + QCOMPARE(trash.homeTrash() , xdgTrashDir); |
3527 | + |
3528 | + QString trash3("trash:///Dir1/Dir2/Dir3"); |
3529 | + QString trash2("trash:///Dir1/Dir2"); |
3530 | + QString trash1("trash:///Dir1"); |
3531 | + |
3532 | + QCOMPARE(QDir().mkpath(QTrashUtilInfo::filesTrashDir(xdgTrashDir) + "/Dir1/Dir2/Dir3"), true); |
3533 | + |
3534 | + |
3535 | + //create a empty .trashinfo file to validate the Trash |
3536 | + QFile trashinfo (QTrashUtilInfo::infoTrashDir(xdgTrashDir) + "/Dir1.trashinfo"); |
3537 | + QCOMPARE(trashinfo.open(QFile::WriteOnly), true); |
3538 | + trashinfo.close(); |
3539 | + |
3540 | + location = factoryLocations.setNewPath(trash3); |
3541 | + Location * myLocation = const_cast<Location*> (location); |
3542 | + QCOMPARE(myLocation->becomeParent(), true); |
3543 | + QCOMPARE(location->urlPath(), trash2); |
3544 | + QCOMPARE(location->isRoot(), false); |
3545 | + |
3546 | + location = factoryLocations.setNewPath(trash2); |
3547 | + myLocation = const_cast<Location*> (location); |
3548 | + QCOMPARE(myLocation->becomeParent(), true); |
3549 | + QCOMPARE(location->urlPath(), trash1); |
3550 | + QCOMPARE(location->isRoot(), false); |
3551 | + |
3552 | + myLocation = const_cast<Location*> (location); |
3553 | + QCOMPARE(myLocation->becomeParent(), true); |
3554 | + QCOMPARE(location->urlPath(), LocationUrl::TrashRootURL); |
3555 | + QCOMPARE(location->isRoot(), true); |
3556 | +} |
3557 | + |
3558 | int main(int argc, char *argv[]) |
3559 | { |
3560 | QApplication app(argc, argv); |
3561 | @@ -2444,6 +2664,21 @@ |
3562 | return ret; |
3563 | } |
3564 | |
3565 | + |
3566 | +bool TestDirModel::createTempHomeTrashDir(const QString& existentDir) |
3567 | +{ |
3568 | + QDir d(existentDir); |
3569 | + bool ret = false; |
3570 | + if (existentDir.startsWith(QDir::tempPath()) && (d.exists() || d.mkpath(existentDir))) |
3571 | + { |
3572 | + QTrashDir trash; |
3573 | + ::setenv("XDG_DATA_HOME", existentDir.toLatin1().constData(), true ); |
3574 | + QString xdgTrashDir(trash.homeTrash()); |
3575 | + ret = trash.validate(xdgTrashDir, true); |
3576 | + } |
3577 | + return ret; |
3578 | +} |
3579 | + |
3580 | #if defined(Q_OS_UNIX) |
3581 | /*! |
3582 | * \brief updateAndSetModificationTime() |
PASSED: Continuous integration, rev:63 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- ci/117/ 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- raring- amd64-ci/ 117 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- saucy-amd64- ci/117 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- trusty- amd64-ci/ 114
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/117/ rebuild
http://