Merge lp:~carlos-mazieri/ubuntu-filemanager-app/app-devel-pre4 into lp:ubuntu-filemanager-app
- app-devel-pre4
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | David Planella |
Approved revision: | 175 |
Merged at revision: | 182 |
Proposed branch: | lp:~carlos-mazieri/ubuntu-filemanager-app/app-devel-pre4 |
Merge into: | lp:ubuntu-filemanager-app |
Prerequisite: | lp:~carlos-mazieri/ubuntu-filemanager-app/app-devel-pre3 |
Diff against target: |
1605 lines (+1155/-164) 14 files modified
src/plugin/folderlistmodel/CMakeLists.txt (+10/-0) src/plugin/folderlistmodel/dirmodel.cpp (+106/-139) src/plugin/folderlistmodel/dirmodel.h (+11/-16) src/plugin/folderlistmodel/disk/disklocation.cpp (+222/-0) src/plugin/folderlistmodel/disk/disklocation.h (+81/-0) src/plugin/folderlistmodel/filecompare.cpp (+2/-3) src/plugin/folderlistmodel/folderlistmodel.pri (+14/-5) src/plugin/folderlistmodel/location.cpp (+140/-0) src/plugin/folderlistmodel/location.h (+132/-0) src/plugin/folderlistmodel/locationsfactory.cpp (+181/-0) src/plugin/folderlistmodel/locationsfactory.h (+136/-0) src/plugin/folderlistmodel/locationurl.cpp (+34/-0) src/plugin/folderlistmodel/locationurl.h (+40/-0) src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp (+46/-1) |
To merge this branch: | bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/app-devel-pre4 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Arto Jalkanen | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+218040@code.launchpad.net |
Commit message
it is the fourth part of https:/
Description of the change
Introduces Location, it basicaly handles Urls and their internal paths.
IORequest/
Location provides:
current path/url -> Location::urlPath()
its content -> Location:
navigation -> up=Location:
Changed navigation in the file manager:
DirModel:
DirModel::cdUp()
DirModel:
DirModel:
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Alan Pope πΊπ§π± π¦ (popey) wrote : | # |
I've asked Michael Spencer to take a look at this and the other related branches and review. If he has difficulty with that I've asked him to get back to me so we can find another reviewer.
- 173. By Carlos Jose Mazieri
-
Fixed using m_info when it can be null.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:173
http://
Executed test runs:
SUCCESS: http://
deb: http://
FAILURE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Arto Jalkanen (ajalkane) wrote : | # |
1)
Non-virtual destructors on classes that either inherit or are inherited other classes with virtual functions, these should be virtual destructors:
~Location()
~DiskLocation()
~LocationsFactory()
Especially important are the Location ones and the classes deriving from it. A basic rule-of-thumb is to have a virtual destructor on any class that has virtual functions or that derives from a class that has virtual destructors. Deviating from this rule-of-thumb is sometimes acceptable but there should be heavy reasons for it, and some comment for why it is so would be appreciated. Right now I do not see anything in the code that would warrant them not-being virtual destructors.
It'd be good to check the code on the whole that there's not more than what I noticed in this code-review.
2)
There is const_cast<...> calls. It's a red flag, casting should only be used if definitely needed. Either document why it's needed or try to refactor the code to get rid of it. For example:
const Location * LocationsFactor
Why does it need to return const pointer as it's used in such a way that it's modified? Why not have it return non-const pointer and get rid of the const_casts.
3)
in someplaces when checking pointer there is:
if (m_somePointer == 0)
and other times just:
if (m_somePointer)
Either is fine IMO, but it'd be good to keep the code-base consistent. So use one or the other.
4)
This perplexes me:
void Location:
917 +{
918 + if (m_info)
919 + {
920 + delete m_info;
921 + }
922 + m_info = const_cast<
923 +}
the name of the function, setFromInfoItem, along with the const parameter to me gives an impression that it will make a copy for the class to use. Instead it does a cast and uses the pointer directly. Perhaps do not use parameter as "const" and rename the function to setInfoItem(
5)
Typos:
LocationsFactor
DiskLocation:
- 174. By Carlos Jose Mazieri
-
* changed destructor to virtual from classes Location() and DiskLocation
* changed Location::setFromInfoIte m(const DirItemInfo *itemInfo) to:
Location: :setInfoItem( DireItemInfo *itemInfo)
* changed const Location * LocationsFactory::setNewPath( const QString& uPath) to
Location * LocationsFactor y::setNewPath( const QString& uPath)
* changed const Location * LocationsFactory::parse( const QString& urlPath) to
Location * LocationsFactor y::parse( const QString& urlPath)
* changed const Location * LocationsFactory::location( ) const to
Location * LocationsFactor y::location( ) const
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:174
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
> 1)
>
> Non-virtual destructors on classes that either inherit or are inherited other
> classes with virtual functions, these should be virtual destructors:
> ~Location()
> ~DiskLocation()
> ~LocationsFactory()
>
> Especially important are the Location ones and the classes deriving from it. A
> basic rule-of-thumb is to have a virtual destructor on any class that has
> virtual functions or that derives from a class that has virtual destructors.
> Deviating from this rule-of-thumb is sometimes acceptable but there should be
> heavy reasons for it, and some comment for why it is so would be appreciated.
> Right now I do not see anything in the code that would warrant them not-being
> virtual destructors.
>
> It'd be good to check the code on the whole that there's not more than what I
> noticed in this code-review
DONE. added virtual for destructors. LocationsFactory does not have any virtual method nor any descendent class.
.
>
> 2)
>
> There is const_cast<...> calls. It's a red flag, casting should only be used
> if definitely needed. Either document why it's needed or try to refactor the
> code to get rid of it. For example:
> const Location * LocationsFactor
>
> Why does it need to return const pointer as it's used in such a way that it's
> modified? Why not have it return non-const pointer and get rid of the
> const_casts.
DONE. removed const
>
> 3)
>
> in someplaces when checking pointer there is:
> if (m_somePointer == 0)
> and other times just:
> if (m_somePointer)
>
> Either is fine IMO, but it'd be good to keep the code-base consistent. So use
> one or the other.
I am used to use "if (pointer)" when asking for avalid address and "if (pointer == 0)" when asking if a pointer is NULL, I could use "if (pointer != 0)" when asking for avalid address, but not "if (!pointer)" which looks like the variable is a bool.
>
> 4)
>
> This perplexes me:
>
> void Location:
> 917 +{
> 918 + if (m_info)
> 919 + {
> 920 + delete m_info;
> 921 + }
> 922 + m_info = const_cast<
> 923 +}
>
DONE. Changed to Location:
>
> the name of the function, setFromInfoItem, along with the const parameter to
> me gives an impression that it will make a copy for the class to use. Instead
> it does a cast and uses the pointer directly. Perhaps do not use parameter as
> "const" and rename the function to setInfoItem(
> I may not understand some details, so feel free to correct me.
>
> 5)
>
> Typos:
>
> LocationsFactor
> LocationsFactor
> DiskLocation:
> DiskLocation:
DONE. Changed.
Arto Jalkanen (ajalkane) wrote : | # |
Thanks for the fixes! A couple of things anymore:
> > It'd be good to check the code on the whole that there's not more than what
> I
> > noticed in this code-review
>
>
> DONE. added virtual for destructors. LocationsFactory does not have any
> virtual method nor any descendent class.
But LocationsFactory inherits QObject which does have virtual methods so it's a potential hard to find error even if it's not a problem in code-base currently. Consider for example Qt's resource management where parent QObject is responsible for deleting its children. If LocationsFactory (or any other similar class) is set as a child of some other QObject (practically speaking using the new LocationsFactor
> I am used to use "if (pointer)" when asking for avalid address and "if
> (pointer == 0)" when asking if a pointer is NULL, I could use "if (pointer !=
> 0)" when asking for avalid address, but not "if (!pointer)" which looks like
> the variable is a bool.
That makes sense, I misread that line. It's good.
> >
> > 4)
> >
> > This perplexes me:
> >
> > void Location:
> > 917 +{
> > 918 + if (m_info)
> > 919 + {
> > 920 + delete m_info;
> > 921 + }
> > 922 + m_info = const_cast<
> > 923 +}
> >
>
> DONE. Changed to Location:
There's still two places with unnecessary const_casts:
143 + mCurLocation = const_cast<
235 + mCurLocation = const_cast<
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
> Thanks for the fixes! A couple of things anymore:
>
> > > It'd be good to check the code on the whole that there's not more than
> what
> > I
> > > noticed in this code-review
> >
> >
> > DONE. added virtual for destructors. LocationsFactory does not have any
> > virtual method nor any descendent class.
>
> But LocationsFactory inherits QObject which does have virtual methods so it's
> a potential hard to find error even if it's not a problem in code-base
> currently. Consider for example Qt's resource management where parent QObject
> is responsible for deleting its children. If LocationsFactory (or any other
> similar class) is set as a child of some other QObject (practically speaking
> using the new LocationsFactor
> not null), then when the parent QObject is deleted then LocationsFactory's
> destructor is not called - unless you make it virtual.
>
I agree that it is a good programming practice and I can do it, no problem.
But I am not sure it happens, QObject DOES HAVE virtual destructor which in my opinion makes all descendant destructors to be called.
> > I am used to use "if (pointer)" when asking for avalid address and "if
> > (pointer == 0)" when asking if a pointer is NULL, I could use "if (pointer
> !=
> > 0)" when asking for avalid address, but not "if (!pointer)" which looks like
> > the variable is a bool.
>
> That makes sense, I misread that line. It's good.
>
> > >
> > > 4)
> > >
> > > This perplexes me:
> > >
> > > void Location:
> > > 917 +{
> > > 918 + if (m_info)
> > > 919 + {
> > > 920 + delete m_info;
> > > 921 + }
> > > 922 + m_info = const_cast<
> > > 923 +}
> > >
> >
> > DONE. Changed to Location:
> removed)
>
> There's still two places with unnecessary const_casts:
>
> 143 + mCurLocation = const_cast<
> 235 + mCurLocation = const_cast<
Arto Jalkanen (ajalkane) wrote : | # |
> > Thanks for the fixes! A couple of things anymore:
> >
> > > > It'd be good to check the code on the whole that there's not more than
> > what
> > > I
> > > > noticed in this code-review
> > >
> > >
> > > DONE. added virtual for destructors. LocationsFactory does not have any
> > > virtual method nor any descendent class.
> >
> > But LocationsFactory inherits QObject which does have virtual methods so
> it's
> > a potential hard to find error even if it's not a problem in code-base
> > currently. Consider for example Qt's resource management where parent
> QObject
> > is responsible for deleting its children. If LocationsFactory (or any other
> > similar class) is set as a child of some other QObject (practically speaking
> > using the new LocationsFactor
> > not null), then when the parent QObject is deleted then LocationsFactory's
> > destructor is not called - unless you make it virtual.
> >
>
> I agree that it is a good programming practice and I can do it, no problem.
> But I am not sure it happens, QObject DOES HAVE virtual destructor which in
> my opinion makes all descendant destructors to be called.
You're right. Shame on me forgetting that when base class has virtual destructor, it makes all descendant classes destructors virtual automatic even without specifically declaring them such.
So yes, it's not a problem.
>
> > > I am used to use "if (pointer)" when asking for avalid address and "if
> > > (pointer == 0)" when asking if a pointer is NULL, I could use "if (pointer
> > !=
> > > 0)" when asking for avalid address, but not "if (!pointer)" which looks
> like
> > > the variable is a bool.
> >
> > That makes sense, I misread that line. It's good.
> >
> > > >
> > > > 4)
> > > >
> > > > This perplexes me:
> > > >
> > > > void Location:
> > > > 917 +{
> > > > 918 + if (m_info)
> > > > 919 + {
> > > > 920 + delete m_info;
> > > > 921 + }
> > > > 922 + m_info = const_cast<
> > > > 923 +}
> > > >
> > >
> > > DONE. Changed to Location:
> > removed)
> >
> > There's still two places with unnecessary const_casts:
> >
> > 143 + mCurLocation = const_cast<
> > 235 + mCurLocation = const_cast<
- 175. By Carlos Jose Mazieri
-
removed row no necessary const_cast<
Location* >
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:175
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
revision 175 removes:
143 + mCurLocation = const_cast<
235 + mCurLocation = const_cast<
I think that completes those 5 items, they all have been solved.
Arto Jalkanen (ajalkane) wrote : | # |
Thank you for doing these!
David Planella (dpm) wrote : | # |
Thanks guys, top-approving as per Arto's last comment.
@Arto, in the future, please feel free to top-approve the merge proposal yourself if you think it's ready to land. Thanks!
Preview Diff
1 | === modified file 'src/plugin/folderlistmodel/CMakeLists.txt' |
2 | --- src/plugin/folderlistmodel/CMakeLists.txt 2014-04-28 10:21:05 +0000 |
3 | +++ src/plugin/folderlistmodel/CMakeLists.txt 2014-05-15 23:31:23 +0000 |
4 | @@ -1,5 +1,7 @@ |
5 | include_directories( |
6 | ${CMAKE_CURRENT_SOURCE_DIR} |
7 | + disk |
8 | + trash |
9 | ) |
10 | |
11 | set(PLUGIN_DIR org/nemomobile/folderlistmodel) |
12 | @@ -32,6 +34,14 @@ |
13 | ioworkerthread.h |
14 | plugin.cpp |
15 | plugin.h |
16 | + location.cpp |
17 | + location.h |
18 | + locationsfactory.cpp |
19 | + locationsfactory.h |
20 | + locationurl.cpp |
21 | + locationurl.h |
22 | + disk/disklocation.cpp |
23 | + disk/disklocation.h |
24 | trash/qtrashdir.cpp |
25 | trash/qtrashdir.h |
26 | ) |
27 | |
28 | === modified file 'src/plugin/folderlistmodel/dirmodel.cpp' |
29 | --- src/plugin/folderlistmodel/dirmodel.cpp 2014-05-15 23:31:22 +0000 |
30 | +++ src/plugin/folderlistmodel/dirmodel.cpp 2014-05-15 23:31:23 +0000 |
31 | @@ -31,12 +31,13 @@ |
32 | |
33 | #include "dirselection.h" |
34 | #include "dirmodel.h" |
35 | -#include "iorequest.h" |
36 | -#include "ioworkerthread.h" |
37 | #include "filesystemaction.h" |
38 | -#include "externalfswatcher.h" |
39 | #include "clipboard.h" |
40 | #include "fmutil.h" |
41 | +#include "locationsfactory.h" |
42 | +#include "location.h" |
43 | +#include "locationurl.h" |
44 | +#include "disklocation.h" |
45 | |
46 | |
47 | #ifndef DO_NOT_USE_TAG_LIB |
48 | @@ -75,7 +76,6 @@ |
49 | #define IS_FILE_MANAGER_IDLE() (!mAwaitingResults) |
50 | |
51 | |
52 | -Q_GLOBAL_STATIC(IOWorkerThread, ioWorkerThread) |
53 | |
54 | namespace { |
55 | QHash<QByteArray, int> roleMapping; |
56 | @@ -108,9 +108,11 @@ |
57 | , mSortBy(SortByName) |
58 | , mSortOrder(SortAscending) |
59 | , mCompareFunction(0) |
60 | - , mExtFSWatcher(0) |
61 | - , mClipboard(new Clipboard(this)) |
62 | - , m_fsAction(new FileSystemAction(this) ) |
63 | + , mExtFSWatcher(false) |
64 | + , mClipboard(new Clipboard(this)) |
65 | + , mLocationFactory(new LocationsFactory(this)) |
66 | + , mCurLocation(0) |
67 | + , m_fsAction(new FileSystemAction(this) ) |
68 | { |
69 | mNameFilters = QStringList() << "*"; |
70 | |
71 | @@ -155,13 +157,40 @@ |
72 | { |
73 | FMUtil::setThemeName(); |
74 | } |
75 | + |
76 | + foreach (const Location* l, mLocationFactory->availableLocations()) |
77 | + { |
78 | + connect(l, SIGNAL(itemsAdded(DirItemInfoList)), |
79 | + this, SLOT(onItemsAdded(DirItemInfoList))); |
80 | + |
81 | + connect(l, SIGNAL(itemsFetched()), |
82 | + this, SLOT(onItemsFetched())); |
83 | + |
84 | + connect(l, SIGNAL(extWatcherItemAdded(DirItemInfo)), |
85 | + this, SLOT(onItemAddedOutsideFm(DirItemInfo))); |
86 | + |
87 | + connect(l, SIGNAL(extWatcherItemRemoved(DirItemInfo)), |
88 | + this, SLOT(onItemRemovedOutSideFm(DirItemInfo))); |
89 | + |
90 | + connect(l, SIGNAL(extWatcherItemChanged(DirItemInfo)), |
91 | + this, SLOT(onItemChangedOutSideFm(DirItemInfo))); |
92 | + |
93 | + connect(l, SIGNAL(extWatcherChangesFetched(int)), |
94 | + this, SLOT(onExternalFsWorkerFinished(int))); |
95 | + |
96 | + connect(l, SIGNAL(extWatcherPathChanged(QString)), |
97 | + this, SLOT(onThereAreExternalChanges(QString))); |
98 | + |
99 | + connect(this, SIGNAL(enabledExternalFSWatcherChanged(bool)), |
100 | + l, SLOT(setUsingExternalWatcher(bool))); |
101 | + } |
102 | } |
103 | |
104 | |
105 | |
106 | DirModel::~DirModel() |
107 | { |
108 | - stoptExternalFsWatcher(); |
109 | + |
110 | } |
111 | |
112 | |
113 | @@ -371,38 +400,48 @@ |
114 | if (pathName.isEmpty()) |
115 | return; |
116 | |
117 | - if (!canReadDir(pathName)) |
118 | - { |
119 | - emit error(tr("cannot read path"), pathName); |
120 | - return; |
121 | - } |
122 | - |
123 | - if (mAwaitingResults) { |
124 | + if (mAwaitingResults) { |
125 | // TODO: handle the case where pathName != our current path, cancel old |
126 | // request, start a new one |
127 | - qDebug() << Q_FUNC_INFO << this << "Ignoring path change request, request already running"; |
128 | - return; |
129 | - } |
130 | - |
131 | + qDebug() << Q_FUNC_INFO << this << "Ignoring path change request, request already running in" << pathName; |
132 | + return; |
133 | + } |
134 | + |
135 | + Location *location = mLocationFactory->setNewPath(pathName); |
136 | + if (location == 0) |
137 | + { |
138 | + emit error(tr("path or url may not exist or cannot be read"), pathName); |
139 | + qDebug() << Q_FUNC_INFO << this << "path or url may not exist or cannot be read:" << pathName; |
140 | + return; |
141 | + } |
142 | + |
143 | + mCurLocation = location; |
144 | + setPathFromCurrentLocation(); |
145 | +} |
146 | + |
147 | +/*! |
148 | + * \brief DirModel::setPathFromCurrentLocation() changes current Path using current Location |
149 | + * |
150 | + * Used in \ref cdUp() and \ref cdIntoIndex() |
151 | + */ |
152 | +void DirModel::setPathFromCurrentLocation() |
153 | +{ |
154 | mAwaitingResults = true; |
155 | emit awaitingResultsChanged(); |
156 | #if DEBUG_MESSAGES |
157 | - qDebug() << Q_FUNC_INFO << this << "Changing to " << pathName << " on " << QThread::currentThreadId(); |
158 | + qDebug() << Q_FUNC_INFO << this << "Changing to " << mCurLocation->urlPath(); |
159 | #endif |
160 | |
161 | clear(); |
162 | |
163 | - DirListWorker *dlw = createWorkerRequest(IORequest::DirList, pathName); |
164 | - connect(dlw, SIGNAL(itemsAdded(DirItemInfoList)), SLOT(onItemsAdded(DirItemInfoList))); |
165 | - connect(dlw, SIGNAL(workerFinished()), SLOT(onResultsFetched())); |
166 | - ioWorkerThread()->addRequest(dlw); |
167 | + mCurLocation->fetchItems(currentDirFilter(), mIsRecursive); |
168 | |
169 | - mCurrentDir = pathName; |
170 | - emit pathChanged(pathName); |
171 | + mCurrentDir = mCurLocation->urlPath(); |
172 | + emit pathChanged(mCurLocation->urlPath()); |
173 | } |
174 | |
175 | |
176 | -void DirModel::onResultsFetched() { |
177 | +void DirModel::onItemsFetched() { |
178 | if (mAwaitingResults) { |
179 | #if DEBUG_MESSAGES |
180 | qDebug() << Q_FUNC_INFO << this << "No longer awaiting results"; |
181 | @@ -611,7 +650,9 @@ |
182 | } |
183 | ExternalFSWatcher * DirModel::getExternalFSWatcher() const |
184 | { |
185 | - return mExtFSWatcher; |
186 | + const Location *l = mLocationFactory->availableLocations().at(LocationsFactory::LocalDisk); |
187 | + const DiskLocation *disk = static_cast<const DiskLocation*> (l); |
188 | + return disk->getExternalFSWatcher(); |
189 | } |
190 | #endif |
191 | |
192 | @@ -624,15 +665,10 @@ |
193 | |
194 | bool DirModel::cdUp() |
195 | { |
196 | - int ret = false; |
197 | - if (!mCurrentDir.isEmpty()) // we are in any dir |
198 | + int ret = mCurLocation && mCurLocation->becomeParent(); |
199 | + if (ret) |
200 | { |
201 | - QDir current(mCurrentDir); |
202 | - if (current.cdUp()) |
203 | - { |
204 | - setPath(current.absolutePath()); |
205 | - ret = true; |
206 | - } |
207 | + setPathFromCurrentLocation(); |
208 | } |
209 | return ret; |
210 | } |
211 | @@ -720,7 +756,9 @@ |
212 | mDirectoryContents.at(row).isDir() && |
213 | mDirectoryContents.at(row).isContentReadable()) |
214 | { |
215 | - ret = cdInto(mDirectoryContents.at(row)); |
216 | + mCurLocation->setInfoItem(mDirectoryContents.at(row)); |
217 | + setPathFromCurrentLocation(); |
218 | + ret = true; |
219 | } |
220 | else |
221 | { |
222 | @@ -1114,8 +1152,28 @@ |
223 | |
224 | bool DirModel::openPath(const QString &filename) |
225 | { |
226 | - DirItemInfo fi(setParentIfRelative(filename)); |
227 | - return openItem(fi); |
228 | + bool ret = false; |
229 | + //first void any relative path when is root |
230 | + if ( !(mCurLocation && mCurLocation->isRoot() && filename.startsWith(QLatin1String(".."))) ) |
231 | + { |
232 | + Location *location = mLocationFactory->setNewPath(filename); |
233 | + if (location) |
234 | + { |
235 | + mCurLocation = location; |
236 | + setPathFromCurrentLocation(); |
237 | + ret = true; |
238 | + } |
239 | + else |
240 | + { |
241 | + const DirItemInfo *item = mLocationFactory->lastValidFileInfo(); |
242 | + // DirItemInfo fi(setParentIfRelative(filename)); |
243 | + if (item && item->isFile()) |
244 | + { |
245 | + ret = openItem(*item); |
246 | + } |
247 | + } |
248 | + } |
249 | + return ret; |
250 | } |
251 | |
252 | /*! |
253 | @@ -1144,76 +1202,8 @@ |
254 | return ret; |
255 | } |
256 | |
257 | -/*! |
258 | - * \brief DirModel::createWorkerRequest() create a request for IORequestWorker |
259 | - * \param requestType the common IORequest::DirList to fill a directory content |
260 | - * or IORequest::DirAutoRefresh that will verify any external File System modification |
261 | - * \param pathName the path to get content |
262 | - * \return the thread object |
263 | - */ |
264 | -DirListWorker * DirModel::createWorkerRequest(IORequest::RequestType requestType, |
265 | - const QString& pathName) |
266 | -{ |
267 | - DirListWorker * reqThread = 0; |
268 | - QDir::Filter dirFilter = currentDirFilter(); |
269 | - if (requestType == IORequest::DirList) |
270 | - { |
271 | - // TODO: we need to set a spinner active before we start getting results from DirListWorker |
272 | - reqThread = new DirListWorker(pathName, dirFilter, mIsRecursive); |
273 | - } |
274 | - else |
275 | - { |
276 | - reqThread = new ExternalFileSystemChangesWorker(mDirectoryContents, |
277 | - pathName, |
278 | - dirFilter, mIsRecursive); |
279 | - } |
280 | - return reqThread; |
281 | -} |
282 | - |
283 | - |
284 | - |
285 | -/*! |
286 | - * \brief DirModel::startExternalFsWatcher() starts the External File System Watcher |
287 | - */ |
288 | -void DirModel::startExternalFsWatcher() |
289 | -{ |
290 | -#if DEBUG_EXT_FS_WATCHER |
291 | - qDebug() << "[extFsWorker]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
292 | - << Q_FUNC_INFO << this; |
293 | - |
294 | -#endif |
295 | - if (!mExtFSWatcher) |
296 | - { |
297 | - mExtFSWatcher = new ExternalFSWatcher(this); |
298 | - mExtFSWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL); |
299 | - connect(this, SIGNAL(pathChanged(QString)), |
300 | - mExtFSWatcher, SLOT(setCurrentPath(QString))); |
301 | - |
302 | - connect(mExtFSWatcher, SIGNAL(pathModified(QString)), |
303 | - this, SLOT(onThereAreExternalChanges(QString))); |
304 | - |
305 | - //setCurrentPath() checks for empty paths |
306 | - mExtFSWatcher->setCurrentPath(mCurrentDir); |
307 | - } |
308 | -} |
309 | - |
310 | - |
311 | - |
312 | -/*! |
313 | - * \brief DirModel::stoptExternalFsWatcher stops the External File System Watcher |
314 | - */ |
315 | -void DirModel::stoptExternalFsWatcher() |
316 | -{ |
317 | -#if DEBUG_EXT_FS_WATCHER |
318 | - qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
319 | - << Q_FUNC_INFO << this; |
320 | -#endif |
321 | - if (mExtFSWatcher) |
322 | - { |
323 | - delete mExtFSWatcher; |
324 | - mExtFSWatcher = 0; |
325 | - } |
326 | -} |
327 | + |
328 | + |
329 | |
330 | |
331 | void DirModel::onThereAreExternalChanges(const QString& pathModifiedOutside) |
332 | @@ -1222,27 +1212,11 @@ |
333 | { |
334 | #if DEBUG_EXT_FS_WATCHER |
335 | qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") |
336 | - << Q_FUNC_INFO << this << "File System modified" << pathModifiedOutside; |
337 | -#else |
338 | - Q_UNUSED(pathModifiedOutside); |
339 | + << Q_FUNC_INFO << this << "File System modified in" << pathModifiedOutside; |
340 | #endif |
341 | - DirListWorker *w = |
342 | - createWorkerRequest(IORequest::DirListExternalFSChanges, |
343 | - mCurrentDir |
344 | - ); |
345 | - ExternalFileSystemChangesWorker *extFsWorker = |
346 | - static_cast<ExternalFileSystemChangesWorker*> (w); |
347 | - |
348 | - connect(extFsWorker, SIGNAL(added(DirItemInfo)), |
349 | - this, SLOT(onItemAddedOutsideFm(DirItemInfo))); |
350 | - connect(extFsWorker, SIGNAL(removed(DirItemInfo)), |
351 | - this, SLOT(onItemRemovedOutSideFm(DirItemInfo))); |
352 | - connect(extFsWorker, SIGNAL(changed(DirItemInfo)), |
353 | - this, SLOT(onItemChangedOutSideFm(DirItemInfo))); |
354 | - connect(extFsWorker, SIGNAL(finished(int)), |
355 | - this, SLOT(onExternalFsWorkerFinished(int))); |
356 | - |
357 | - ioWorkerThread()->addRequest(extFsWorker); |
358 | + mCurLocation->fetchExternalChanges(pathModifiedOutside, |
359 | + mDirectoryContents, |
360 | + currentDirFilter()); |
361 | } |
362 | #if DEBUG_EXT_FS_WATCHER |
363 | else |
364 | @@ -1342,7 +1316,7 @@ |
365 | */ |
366 | bool DirModel::getEnabledExternalFSWatcher() const |
367 | { |
368 | - return mExtFSWatcher ? true : false; |
369 | + return mExtFSWatcher; |
370 | } |
371 | |
372 | |
373 | @@ -1351,15 +1325,8 @@ |
374 | * \param enable |
375 | */ |
376 | void DirModel::setEnabledExternalFSWatcher(bool enable) |
377 | -{ |
378 | - if(enable) |
379 | - { |
380 | - startExternalFsWatcher(); |
381 | - } |
382 | - else |
383 | - { |
384 | - stoptExternalFsWatcher(); |
385 | - } |
386 | +{ |
387 | + emit enabledExternalFSWatcherChanged(enable); |
388 | } |
389 | |
390 | |
391 | |
392 | === modified file 'src/plugin/folderlistmodel/dirmodel.h' |
393 | --- src/plugin/folderlistmodel/dirmodel.h 2014-05-15 23:31:22 +0000 |
394 | +++ src/plugin/folderlistmodel/dirmodel.h 2014-05-15 23:31:23 +0000 |
395 | @@ -42,17 +42,11 @@ |
396 | #include "diriteminfo.h" |
397 | |
398 | class FileSystemAction; |
399 | -class ExternalFSWatcher; |
400 | class Clipboard; |
401 | class DirSelection; |
402 | - |
403 | -/*! |
404 | - * When the External File System Wathcer is enabled, |
405 | - * this is the interval used to check if there has been any change in the current path |
406 | - * |
407 | - * \sa setEnabledExternalFSWatcher() |
408 | - */ |
409 | -#define EX_FS_WATCHER_TIMER_INTERVAL 900 |
410 | +class LocationsFactory; |
411 | +class Location; |
412 | +class ExternalFSWatcher; |
413 | |
414 | class DirModel : public DirItemAbstractListModel |
415 | { |
416 | @@ -150,7 +144,7 @@ |
417 | |
418 | public slots: |
419 | void onItemsAdded(const DirItemInfoList &newFiles); |
420 | - void onResultsFetched(); |
421 | + void onItemsFetched(); |
422 | |
423 | signals: |
424 | void awaitingResultsChanged(); |
425 | @@ -206,7 +200,7 @@ |
426 | Q_PROPERTY(int clipboardUrlsCounter READ getClipboardUrlsCounter NOTIFY clipboardChanged) |
427 | int getClipboardUrlsCounter() const; |
428 | |
429 | - Q_PROPERTY(bool enableExternalFSWatcher READ getEnabledExternalFSWatcher WRITE setEnabledExternalFSWatcher) |
430 | + Q_PROPERTY(bool enableExternalFSWatcher READ getEnabledExternalFSWatcher WRITE setEnabledExternalFSWatcher NOTIFY enabledExternalFSWatcherChanged) |
431 | bool getEnabledExternalFSWatcher() const; |
432 | |
433 | Q_INVOKABLE QString homePath() const; |
434 | @@ -360,8 +354,8 @@ |
435 | void showHiddenFilesChanged(); |
436 | void sortByChanged(); |
437 | void sortOrderChanged(); |
438 | - |
439 | void clipboardChanged(); |
440 | + void enabledExternalFSWatcherChanged(bool); |
441 | |
442 | private slots: |
443 | void onItemRemoved(const QString&); |
444 | @@ -377,12 +371,11 @@ |
445 | QDir::Filter currentDirFilter() const; |
446 | QString dirItems(const DirItemInfo& fi) const; |
447 | bool cdInto(const DirItemInfo& fi); |
448 | - bool openItem(const DirItemInfo& fi); |
449 | - DirListWorker * createWorkerRequest(IORequest::RequestType requestType, |
450 | - const QString& pathName); |
451 | + bool openItem(const DirItemInfo& fi); |
452 | bool canReadDir(const QFileInfo& d) const; |
453 | bool canReadFile(const QFileInfo& f) const; |
454 | QFileInfo setParentIfRelative(const QString &fileOrDir) const; |
455 | + void setPathFromCurrentLocation(); |
456 | |
457 | private: |
458 | void startExternalFsWatcher(); |
459 | @@ -401,9 +394,11 @@ |
460 | SortBy mSortBy; |
461 | SortOrder mSortOrder; |
462 | CompareFunction mCompareFunction; |
463 | - ExternalFSWatcher* mExtFSWatcher; |
464 | + bool mExtFSWatcher; |
465 | Clipboard * mClipboard; |
466 | DirSelection * mSelection; |
467 | + LocationsFactory * mLocationFactory; |
468 | + Location * mCurLocation; |
469 | |
470 | |
471 | private: |
472 | |
473 | === added directory 'src/plugin/folderlistmodel/disk' |
474 | === added file 'src/plugin/folderlistmodel/disk/disklocation.cpp' |
475 | --- src/plugin/folderlistmodel/disk/disklocation.cpp 1970-01-01 00:00:00 +0000 |
476 | +++ src/plugin/folderlistmodel/disk/disklocation.cpp 2014-05-15 23:31:23 +0000 |
477 | @@ -0,0 +1,222 @@ |
478 | +/************************************************************************** |
479 | + * |
480 | + * Copyright 2014 Canonical Ltd. |
481 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
482 | + * |
483 | + * This program is free software; you can redistribute it and/or modify |
484 | + * it under the terms of the GNU Lesser General Public License as published by |
485 | + * the Free Software Foundation; version 3. |
486 | + * |
487 | + * This program is distributed in the hope that it will be useful, |
488 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
489 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
490 | + * GNU Lesser General Public License for more details. |
491 | + * |
492 | + * You should have received a copy of the GNU Lesser General Public License |
493 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
494 | + * |
495 | + * File: disklocation.cpp |
496 | + * Date: 08/03/2014 |
497 | + */ |
498 | + |
499 | +#include "disklocation.h" |
500 | +#include "iorequest.h" |
501 | +#include "ioworkerthread.h" |
502 | +#include "externalfswatcher.h" |
503 | + |
504 | +#include <QDebug> |
505 | + |
506 | +#if defined(DEBUG_EXT_FS_WATCHER) |
507 | +# define DEBUG_WATCHER() qDebug() << "[extFsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") \ |
508 | + << Q_FUNC_INFO << this |
509 | +#else |
510 | +# define DEBUG_WATCHER() /**/ |
511 | +#endif |
512 | + |
513 | +DiskLocation::DiskLocation(int type, QObject *parent) |
514 | + : Location(type, parent) |
515 | + , m_extWatcher(0) |
516 | +{ |
517 | +} |
518 | + |
519 | + |
520 | +DiskLocation::~ DiskLocation() |
521 | +{ |
522 | + stopExternalFsWatcher(); |
523 | +} |
524 | + |
525 | + |
526 | +void DiskLocation::fetchItems(QDir::Filter dirFilter, bool recursive) |
527 | +{ |
528 | + DirListWorker *dlw = new DirListWorker(m_info->absoluteFilePath(), dirFilter, recursive); |
529 | + connect(dlw, SIGNAL(itemsAdded(DirItemInfoList)), |
530 | + this, SIGNAL(itemsAdded(DirItemInfoList))); |
531 | + connect(dlw, SIGNAL(workerFinished()), |
532 | + this, SLOT(onItemsFetched())); |
533 | + workerThread()->addRequest(dlw); |
534 | +} |
535 | + |
536 | + |
537 | +bool DiskLocation::becomeParent() |
538 | +{ |
539 | + bool ret = false; |
540 | + if (m_info && !m_info->isRoot()) |
541 | + { |
542 | + DirItemInfo *other = new DirItemInfo(m_info->absolutePath()); |
543 | + if (other->isValid()) |
544 | + { |
545 | + delete m_info; |
546 | + m_info = other; |
547 | + ret = true; |
548 | + } |
549 | + else |
550 | + { |
551 | + delete other; |
552 | + } |
553 | + } |
554 | + return ret; |
555 | +} |
556 | + |
557 | + |
558 | +void DiskLocation::refreshInfo() |
559 | +{ |
560 | + if (m_info) |
561 | + { |
562 | + DirItemInfo *item = new DirItemInfo(m_info->absoluteFilePath()); |
563 | + delete m_info; |
564 | + m_info = item; |
565 | + } |
566 | +} |
567 | + |
568 | + |
569 | +/*! |
570 | + * \brief DiskLocation::stopExternalFsWatcher() stops the External File System Watcher |
571 | + */ |
572 | +void DiskLocation::stopExternalFsWatcher() |
573 | +{ |
574 | + if (m_extWatcher) |
575 | + { |
576 | + DEBUG_WATCHER(); |
577 | + delete m_extWatcher; |
578 | + m_extWatcher = 0; |
579 | + } |
580 | +} |
581 | + |
582 | + |
583 | +/*! |
584 | + * \brief DiskLocation::startExternalFsWatcher() starts the External File System Watcher |
585 | + */ |
586 | +void DiskLocation::startExternalFsWatcher() |
587 | +{ |
588 | + if (m_extWatcher == 0) |
589 | + { |
590 | + DEBUG_WATCHER(); |
591 | + m_extWatcher = new ExternalFSWatcher(this); |
592 | + m_extWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL); |
593 | + |
594 | + connect(m_extWatcher, SIGNAL(pathModified(QString)), |
595 | + this, SIGNAL(extWatcherPathChanged(QString))); |
596 | + if (m_info) |
597 | + { //setCurrentPath() checks for empty paths |
598 | + m_extWatcher->setCurrentPath(m_info->absoluteFilePath()); |
599 | + } |
600 | + } |
601 | +} |
602 | + |
603 | + |
604 | +void DiskLocation::onItemsFetched() |
605 | +{ |
606 | + if (m_extWatcher) |
607 | + { |
608 | + m_extWatcher->setCurrentPath(m_info->absoluteFilePath()); |
609 | + } |
610 | + emit itemsFetched(); |
611 | +} |
612 | + |
613 | + |
614 | +void DiskLocation::startWorking() |
615 | +{ |
616 | + if (m_usingExternalWatcher) |
617 | + { |
618 | + startExternalFsWatcher(); |
619 | + } |
620 | +} |
621 | + |
622 | + |
623 | +void DiskLocation::stopWorking() |
624 | +{ |
625 | + stopExternalFsWatcher(); |
626 | +} |
627 | + |
628 | + |
629 | +void DiskLocation::fetchExternalChanges(const QString &path, |
630 | + const DirItemInfoList &list, |
631 | + QDir::Filter dirFilter) |
632 | +{ |
633 | + ExternalFileSystemChangesWorker *extFsWorker = |
634 | + new ExternalFileSystemChangesWorker(list, |
635 | + path, |
636 | + dirFilter, false); |
637 | + addExternalFsWorkerRequest(extFsWorker); |
638 | + |
639 | + |
640 | +} |
641 | + |
642 | +void DiskLocation::addExternalFsWorkerRequest(ExternalFileSystemChangesWorker *extFsWorker) |
643 | +{ |
644 | + connect(extFsWorker, SIGNAL(added(DirItemInfo)), |
645 | + this, SIGNAL(extWatcherItemAdded(DirItemInfo))); |
646 | + |
647 | + connect(extFsWorker, SIGNAL(removed(DirItemInfo)), |
648 | + this, SIGNAL(extWatcherItemRemoved(DirItemInfo))); |
649 | + |
650 | + connect(extFsWorker, SIGNAL(changed(DirItemInfo)), |
651 | + this, SIGNAL(extWatcherItemChanged(DirItemInfo))); |
652 | + |
653 | + connect(extFsWorker, SIGNAL(finished(int)), |
654 | + this, SIGNAL(extWatcherChangesFetched(int))); |
655 | + |
656 | + workerThread()->addRequest(extFsWorker); |
657 | +} |
658 | + |
659 | + |
660 | +ExternalFSWatcher * DiskLocation::getExternalFSWatcher() const |
661 | +{ |
662 | + return m_extWatcher; |
663 | +} |
664 | + |
665 | + |
666 | +void DiskLocation::setUsingExternalWatcher(bool use) |
667 | +{ |
668 | + Location::setUsingExternalWatcher(use); |
669 | + if (m_usingExternalWatcher) |
670 | + { |
671 | + startExternalFsWatcher(); |
672 | + } |
673 | + else |
674 | + { |
675 | + stopExternalFsWatcher(); |
676 | + } |
677 | +} |
678 | + |
679 | + |
680 | +DirItemInfo * DiskLocation::validateUrlPath(const QString& uPath) |
681 | +{ |
682 | + QString myPath(uPath); |
683 | + QFileInfo tmpUrl(uPath); |
684 | + if (tmpUrl.isRelative() && m_info) |
685 | + { |
686 | + tmpUrl.setFile(m_info->absoluteFilePath(), uPath); |
687 | + myPath = tmpUrl.absoluteFilePath(); |
688 | + } |
689 | +#if DEBUG_MESSAGES |
690 | + qDebug() << Q_FUNC_INFO << "path:" << myPath; |
691 | +#endif |
692 | + DirItemInfo * item = new DirItemInfo(myPath); |
693 | + if (!item->isValid() || !item->exists() || !item->isContentReadable()) |
694 | + { |
695 | + delete item; |
696 | + item = 0; |
697 | + } |
698 | + return item; |
699 | +} |
700 | |
701 | === added file 'src/plugin/folderlistmodel/disk/disklocation.h' |
702 | --- src/plugin/folderlistmodel/disk/disklocation.h 1970-01-01 00:00:00 +0000 |
703 | +++ src/plugin/folderlistmodel/disk/disklocation.h 2014-05-15 23:31:23 +0000 |
704 | @@ -0,0 +1,81 @@ |
705 | +/************************************************************************** |
706 | + * |
707 | + * Copyright 2014 Canonical Ltd. |
708 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
709 | + * |
710 | + * This program is free software; you can redistribute it and/or modify |
711 | + * it under the terms of the GNU Lesser General Public License as published by |
712 | + * the Free Software Foundation; version 3. |
713 | + * |
714 | + * This program is distributed in the hope that it will be useful, |
715 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
716 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
717 | + * GNU Lesser General Public License for more details. |
718 | + * |
719 | + * You should have received a copy of the GNU Lesser General Public License |
720 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
721 | + * |
722 | + * File: disklocation.h |
723 | + * Date: 08/03/2014 |
724 | + */ |
725 | + |
726 | +#ifndef DISKLOCATION_H |
727 | +#define DISKLOCATION_H |
728 | + |
729 | +#include "location.h" |
730 | +#include <QList> |
731 | + |
732 | +/*! |
733 | + * When the External File System Wathcer is enabled, |
734 | + * this is the interval used to check if there has been any change in the current path |
735 | + * |
736 | + * \sa setEnabledExternalFSWatcher() |
737 | + */ |
738 | +#define EX_FS_WATCHER_TIMER_INTERVAL 900 |
739 | + |
740 | + |
741 | +class ExternalFSWatcher; |
742 | +class ExternalFileSystemChangesWorker; |
743 | + |
744 | +/*! |
745 | + * \brief The DiskLocation class extends \ref Location for Local Disk and provides a External File System watcher |
746 | + */ |
747 | +class DiskLocation : public Location |
748 | +{ |
749 | + Q_OBJECT |
750 | +public: |
751 | + explicit DiskLocation(int type, QObject *parent=0); |
752 | + virtual ~DiskLocation(); |
753 | + |
754 | + ExternalFSWatcher * getExternalFSWatcher() const; |
755 | + |
756 | + virtual void fetchItems(QDir::Filter dirFilter, bool recursive = false) ; |
757 | + virtual void fetchExternalChanges(const QString& urlPath, |
758 | + const DirItemInfoList& list, |
759 | + QDir::Filter dirFilter) ; |
760 | + virtual bool becomeParent(); |
761 | + virtual void refreshInfo(); |
762 | + |
763 | + virtual void startExternalFsWatcher(); |
764 | + virtual void stopExternalFsWatcher(); |
765 | + |
766 | + virtual void startWorking(); |
767 | + virtual void stopWorking(); |
768 | + |
769 | + virtual DirItemInfo *validateUrlPath(const QString& urlPath); |
770 | + |
771 | +protected: |
772 | + void addExternalFsWorkerRequest(ExternalFileSystemChangesWorker *); |
773 | + |
774 | +public slots: |
775 | + virtual void setUsingExternalWatcher(bool use); |
776 | + |
777 | +protected slots: |
778 | + void onItemsFetched(); |
779 | + |
780 | +protected: |
781 | + ExternalFSWatcher * m_extWatcher ; |
782 | + |
783 | +}; |
784 | + |
785 | +#endif // DISKLOCATION_H |
786 | |
787 | === modified file 'src/plugin/folderlistmodel/filecompare.cpp' |
788 | --- src/plugin/folderlistmodel/filecompare.cpp 2014-02-05 15:31:44 +0000 |
789 | +++ src/plugin/folderlistmodel/filecompare.cpp 2014-05-15 23:31:23 +0000 |
790 | @@ -50,11 +50,10 @@ |
791 | if (b.isDir() && !a.isDir()) |
792 | return false; |
793 | |
794 | - bool ret = QString::localeAwareCompare(a.fileName(), b.fileName()) < 0; |
795 | + bool ret = QString::localeAwareCompare(a.absoluteFilePath(), b.absoluteFilePath()) < 0; |
796 | #if DEBUG_MESSAGES |
797 | - qDebug() << Q_FUNC_INFO << ret << a.fileName() << b.fileName(); |
798 | + qDebug() << Q_FUNC_INFO << ret << a.absoluteFilePath() << b.absoluteFilePath(); |
799 | #endif |
800 | - |
801 | return ret; |
802 | } |
803 | |
804 | |
805 | === modified file 'src/plugin/folderlistmodel/folderlistmodel.pri' |
806 | --- src/plugin/folderlistmodel/folderlistmodel.pri 2014-02-10 23:41:50 +0000 |
807 | +++ src/plugin/folderlistmodel/folderlistmodel.pri 2014-05-15 23:31:23 +0000 |
808 | @@ -9,7 +9,12 @@ |
809 | $$PWD/fmutil.cpp \ |
810 | $$PWD/dirselection.cpp \ |
811 | $$PWD/diriteminfo.cpp \ |
812 | - $$PWD/trash/qtrashdir.cpp |
813 | + $$PWD/trash/qtrashdir.cpp \ |
814 | + $$PWD/location.cpp \ |
815 | + $$PWD/locationsfactory.cpp \ |
816 | + $$PWD/disk/disklocation.cpp \ |
817 | + $$PWD/locationurl.cpp \ |
818 | + |
819 | |
820 | |
821 | HEADERS += $$PWD/dirmodel.h \ |
822 | @@ -24,10 +29,14 @@ |
823 | $$PWD/dirselection.h \ |
824 | $$PWD/diritemabstractlistmodel.h \ |
825 | $$PWD/diriteminfo.h \ |
826 | - $$PWD/trash/qtrashdir.h |
827 | - |
828 | - |
829 | -INCLUDEPATH += $$PWD $$PWD/trash |
830 | + $$PWD/trash/qtrashdir.h \ |
831 | + $$PWD/location.h \ |
832 | + $$PWD/locationsfactory.h \ |
833 | + $$PWD/disk/disklocation.h \ |
834 | + $$PWD/locationurl.h \ |
835 | + |
836 | + |
837 | +INCLUDEPATH += $$PWD $$PWD/trash $$PWD/disk |
838 | |
839 | greaterThan(QT_MAJOR_VERSION, 4) { |
840 | QT += qml |
841 | |
842 | === added file 'src/plugin/folderlistmodel/location.cpp' |
843 | --- src/plugin/folderlistmodel/location.cpp 1970-01-01 00:00:00 +0000 |
844 | +++ src/plugin/folderlistmodel/location.cpp 2014-05-15 23:31:23 +0000 |
845 | @@ -0,0 +1,140 @@ |
846 | +/************************************************************************** |
847 | + * |
848 | + * Copyright 2014 Canonical Ltd. |
849 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
850 | + * |
851 | + * This program is free software; you can redistribute it and/or modify |
852 | + * it under the terms of the GNU Lesser General Public License as published by |
853 | + * the Free Software Foundation; version 3. |
854 | + * |
855 | + * This program is distributed in the hope that it will be useful, |
856 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
857 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
858 | + * GNU Lesser General Public License for more details. |
859 | + * |
860 | + * You should have received a copy of the GNU Lesser General Public License |
861 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
862 | + * |
863 | + * File: location.cpp |
864 | + * Date: 08/03/2014 |
865 | + */ |
866 | +/************************************************************************** |
867 | + * |
868 | + * Copyright 2014 Canonical Ltd. |
869 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
870 | + * |
871 | + * This program is free software; you can redistribute it and/or modify |
872 | + * it under the terms of the GNU Lesser General Public License as published by |
873 | + * the Free Software Foundation; version 3. |
874 | + * |
875 | + * This program is distributed in the hope that it will be useful, |
876 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
877 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
878 | + * GNU Lesser General Public License for more details. |
879 | + * |
880 | + * You should have received a copy of the GNU Lesser General Public License |
881 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
882 | + * |
883 | + * File: locations.cpp |
884 | + * Date: 04/03/2014 |
885 | + */ |
886 | + |
887 | +#include "location.h" |
888 | +#include "ioworkerthread.h" |
889 | + |
890 | +Q_GLOBAL_STATIC(IOWorkerThread, ioWorkerThread) |
891 | + |
892 | + |
893 | +Location::Location(int type, QObject *parent) |
894 | + : QObject(parent) |
895 | + , m_info(0) |
896 | + , m_type(type) |
897 | + , m_usingExternalWatcher(false) |
898 | +{ |
899 | + |
900 | +} |
901 | + |
902 | +Location::~Location() |
903 | +{ |
904 | + if (m_info) |
905 | + { |
906 | + delete m_info; |
907 | + m_info = 0; |
908 | + } |
909 | +} |
910 | + |
911 | + |
912 | +bool Location::isRoot() const |
913 | +{ |
914 | + return m_info ? m_info->isRoot() : false; |
915 | +} |
916 | + |
917 | + |
918 | +bool Location::isWritable() const |
919 | +{ |
920 | + return m_info->isWritable(); |
921 | +} |
922 | + |
923 | + |
924 | +bool Location::isReadable() const |
925 | +{ |
926 | + return m_info ? m_info->isContentReadable() : false; |
927 | +} |
928 | + |
929 | +void Location::setInfoItem(const DirItemInfo &itemInfo) |
930 | +{ |
931 | + setInfoItem (new DirItemInfo(itemInfo)); |
932 | +} |
933 | + |
934 | +void Location::setInfoItem(DirItemInfo *itemInfo) |
935 | +{ |
936 | + if (m_info) |
937 | + { |
938 | + delete m_info; |
939 | + } |
940 | + m_info = itemInfo; |
941 | +} |
942 | + |
943 | + |
944 | +QString Location::urlPath() const |
945 | +{ |
946 | + return m_info ? m_info->urlPath(): QString(); |
947 | +} |
948 | + |
949 | + |
950 | +void Location::startWorking() |
951 | +{ |
952 | + |
953 | +} |
954 | + |
955 | +void Location::stopWorking() |
956 | +{ |
957 | + |
958 | +} |
959 | + |
960 | +bool Location::becomeParent() |
961 | +{ |
962 | + return false; |
963 | +} |
964 | + |
965 | +IOWorkerThread * Location::workerThread() const |
966 | +{ |
967 | + return ioWorkerThread(); |
968 | +} |
969 | + |
970 | + |
971 | +//providing an empty method |
972 | +void Location::fetchExternalChanges(const QString &path, |
973 | + const DirItemInfoList &list, |
974 | + QDir::Filter dirFilter) |
975 | +{ |
976 | + Q_UNUSED(path); |
977 | + Q_UNUSED(list); |
978 | + Q_UNUSED(dirFilter); |
979 | +} |
980 | + |
981 | + |
982 | +void Location::setUsingExternalWatcher(bool use) |
983 | +{ |
984 | + m_usingExternalWatcher = use; |
985 | +} |
986 | |
987 | === added file 'src/plugin/folderlistmodel/location.h' |
988 | --- src/plugin/folderlistmodel/location.h 1970-01-01 00:00:00 +0000 |
989 | +++ src/plugin/folderlistmodel/location.h 2014-05-15 23:31:23 +0000 |
990 | @@ -0,0 +1,132 @@ |
991 | +/************************************************************************** |
992 | + * |
993 | + * Copyright 2014 Canonical Ltd. |
994 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
995 | + * |
996 | + * This program is free software; you can redistribute it and/or modify |
997 | + * it under the terms of the GNU Lesser General Public License as published by |
998 | + * the Free Software Foundation; version 3. |
999 | + * |
1000 | + * This program is distributed in the hope that it will be useful, |
1001 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1002 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1003 | + * GNU Lesser General Public License for more details. |
1004 | + * |
1005 | + * You should have received a copy of the GNU Lesser General Public License |
1006 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1007 | + * |
1008 | + * File: location.h |
1009 | + * Date: 08/03/2014 |
1010 | + */ |
1011 | + |
1012 | +#ifndef LOCATION_H |
1013 | +#define LOCATION_H |
1014 | + |
1015 | +#include "diriteminfo.h" |
1016 | + |
1017 | +#include <QObject> |
1018 | + |
1019 | +class IOWorkerThread; |
1020 | + |
1021 | +/*! |
1022 | + * \brief The Location class represents any location (full path) where there are items to browse: directories, shares, from Disk and from Network. |
1023 | + * |
1024 | + * It is an abstract class the must be inherited for specific Location handling as example: \ref DiskLocation and \ref TrashLocation |
1025 | + * |
1026 | + * The location must be able to: |
1027 | + * \li provide the browsing for the location in \ref fetchItems() |
1028 | + * \li become itself its parent in \ref becomeParent() it will allow easy \ref DirModel::cdUp() |
1029 | + * \li refresh its information in \ref refreshInfo() |
1030 | + * \li validate its location (creates a valid DirItemInfo object or any descendent) from a url string |
1031 | + * |
1032 | + * The \ref startWorking() is called by \ref LocationsFactory just before this location becomes the current in the File Manager |
1033 | + * 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 |
1034 | + */ |
1035 | +class Location : public QObject |
1036 | +{ |
1037 | + Q_OBJECT |
1038 | +public: |
1039 | + explicit Location( int type, QObject *parent=0); |
1040 | + virtual ~Location(); |
1041 | + |
1042 | + IOWorkerThread * workerThread() const; |
1043 | + |
1044 | +signals: |
1045 | + void itemsAdded(const DirItemInfoList &files); |
1046 | + void itemsFetched(); |
1047 | + void extWatcherPathChanged(const QString&); |
1048 | + void extWatcherItemRemoved(const DirItemInfo&); |
1049 | + void extWatcherItemChanged(const DirItemInfo&); |
1050 | + void extWatcherItemAdded(const DirItemInfo&); |
1051 | + void extWatcherChangesFetched(int); |
1052 | + |
1053 | +public slots: |
1054 | + virtual void setUsingExternalWatcher(bool use); |
1055 | + |
1056 | +public: //pure functions |
1057 | + /*! |
1058 | + * \brief fetchItems() gets the content of the Location |
1059 | + * |
1060 | + * \param dirFilter current Filter |
1061 | + * \param recursive should get the content all sub dirs or not, (hardly ever it is true) |
1062 | + */ |
1063 | + virtual void fetchItems(QDir::Filter dirFilter, bool recursive=0) = 0; |
1064 | + |
1065 | + /*! |
1066 | + * \brief refreshInfo() It must refresh the DirItemInfo |
1067 | + * |
1068 | + * It can be used for example after receiving the signal about external disk file system changes |
1069 | + * due to the current path permissions might have changed. |
1070 | + */ |
1071 | + virtual void refreshInfo() = 0; |
1072 | + |
1073 | + /*! |
1074 | + * \brief becomeParent() The current path location becomes the parent Location |
1075 | + * |
1076 | + * When \ref isRoot() returns false the current path location becomes the parent path location |
1077 | + * in order to make it the current. |
1078 | + * It acts like a cdUp, but without fetching items; then calling \ref fetchItems() may get contents. |
1079 | + * |
1080 | + * \note It must take care of deleting \ref m_info when creating a new DirItemInfo/TrashItemInfo etc. |
1081 | + * |
1082 | + * \return true if it is possible to do like a cdUp. |
1083 | + */ |
1084 | + virtual bool becomeParent() = 0; |
1085 | + |
1086 | + /*! |
1087 | + * \brief validateUrlPath() Validates the urlPath (file or Directory) and creates a new Obeject from this path |
1088 | + * |
1089 | + * If urlPath is a valid Directory it can be used later to set a new Location. |
1090 | + * |
1091 | + * \param urlPath |
1092 | + * \return a valid pointer to DirItemInfo object or NULL indicating something wrong with the path |
1093 | + */ |
1094 | + virtual DirItemInfo * validateUrlPath(const QString& urlPath) = 0; |
1095 | + |
1096 | +public: |
1097 | + virtual void fetchExternalChanges(const QString& urlPath, |
1098 | + const DirItemInfoList& list, |
1099 | + QDir::Filter dirFilter) ; |
1100 | + virtual void setInfoItem(const DirItemInfo &itemInfo); |
1101 | + virtual void setInfoItem(DirItemInfo *itemInfo); |
1102 | + virtual bool isRoot() const; |
1103 | + virtual bool isWritable() const; |
1104 | + virtual bool isReadable() const; |
1105 | + virtual QString urlPath() const; |
1106 | + virtual void startWorking(); |
1107 | + virtual void stopWorking(); |
1108 | + |
1109 | + inline const DirItemInfo* info() const { return m_info; } |
1110 | + inline int type() const { return m_type; } |
1111 | + |
1112 | +protected: |
1113 | + DirItemInfo * m_info; |
1114 | + int m_type; |
1115 | + bool m_usingExternalWatcher; |
1116 | + |
1117 | +#if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
1118 | + friend class TestDirModel; |
1119 | +#endif |
1120 | + |
1121 | +}; |
1122 | +#endif // LOCATION_H |
1123 | |
1124 | === added file 'src/plugin/folderlistmodel/locationsfactory.cpp' |
1125 | --- src/plugin/folderlistmodel/locationsfactory.cpp 1970-01-01 00:00:00 +0000 |
1126 | +++ src/plugin/folderlistmodel/locationsfactory.cpp 2014-05-15 23:31:23 +0000 |
1127 | @@ -0,0 +1,181 @@ |
1128 | +/************************************************************************** |
1129 | + * |
1130 | + * Copyright 2014 Canonical Ltd. |
1131 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1132 | + * |
1133 | + * This program is free software; you can redistribute it and/or modify |
1134 | + * it under the terms of the GNU Lesser General Public License as published by |
1135 | + * the Free Software Foundation; version 3. |
1136 | + * |
1137 | + * This program is distributed in the hope that it will be useful, |
1138 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1139 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1140 | + * GNU Lesser General Public License for more details. |
1141 | + * |
1142 | + * You should have received a copy of the GNU Lesser General Public License |
1143 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1144 | + * |
1145 | + * File: locationsfactory.cpp |
1146 | + * Date: 05/03/2014 |
1147 | + */ |
1148 | + |
1149 | +#include "diriteminfo.h" |
1150 | +#include "locationsfactory.h" |
1151 | +#include "location.h" |
1152 | +#include "locationurl.h" |
1153 | +#include "disklocation.h" |
1154 | + |
1155 | + |
1156 | +#include <QDir> |
1157 | +#include <QDebug> |
1158 | + |
1159 | + |
1160 | + |
1161 | +LocationsFactory::LocationsFactory(QObject *parent) |
1162 | + : QObject(parent) |
1163 | + , m_curLoc(0) |
1164 | + , m_lastValidFileInfo(0) |
1165 | +{ |
1166 | + m_locations.append(new DiskLocation(LocalDisk)); |
1167 | +} |
1168 | + |
1169 | + |
1170 | +LocationsFactory::~LocationsFactory() |
1171 | +{ |
1172 | + ::qDeleteAll(m_locations); |
1173 | + m_locations.clear(); |
1174 | +} |
1175 | + |
1176 | + |
1177 | +/*! |
1178 | + * \brief LocationsFactory::parse() identifies what main location that path/url refers to |
1179 | + * \param path it is supposed to be always a full path like: file:///myDir /myDir trash:/// trash:///myDir |
1180 | + * \return |
1181 | + */ |
1182 | + |
1183 | +Location * LocationsFactory::parse(const QString& uPath) |
1184 | +{ |
1185 | + int index = -1; |
1186 | + int type = -1; |
1187 | + Location * location = 0; |
1188 | + if ( (index = uPath.indexOf(QChar(':'))) != -1 ) |
1189 | + { |
1190 | +#if defined(Q_OS_WIN) |
1191 | +#else |
1192 | +#if defined(Q_OS_UNIX) |
1193 | + if (uPath.startsWith(LocationUrl::TrashRootURL.midRef(0,6))) |
1194 | + { |
1195 | + type = TrashDisk; |
1196 | + m_tmpPath = LocationUrl::TrashRootURL + stringAfterSlashes(uPath, index+1); |
1197 | + } |
1198 | + else |
1199 | +#endif //Q_OS_UNIX |
1200 | +#endif //Q_OS_UNIX |
1201 | + if (uPath.startsWith(LocationUrl::DiskRootURL.midRef(0,5))) |
1202 | + { |
1203 | + type = LocalDisk; |
1204 | + m_tmpPath = QDir::rootPath() + stringAfterSlashes(uPath, index+1); |
1205 | + } |
1206 | + } |
1207 | + else |
1208 | + { |
1209 | + m_tmpPath = stringAfterSlashes(uPath, -1); |
1210 | + type = LocalDisk; |
1211 | + if (!m_tmpPath.startsWith(QDir::rootPath()) && m_curLoc) |
1212 | + { |
1213 | + //it can be any, check current location |
1214 | + type = m_curLoc->type(); |
1215 | + } |
1216 | + } |
1217 | + if (!m_tmpPath.isEmpty() && type != -1) |
1218 | + { |
1219 | + location = m_locations.at(type); |
1220 | + } |
1221 | +#if DEBUG_MESSAGES |
1222 | + qDebug() << Q_FUNC_INFO << "input path:" << uPath << "location result:" << location; |
1223 | +#endif |
1224 | + return location; |
1225 | +} |
1226 | + |
1227 | + |
1228 | +Location * LocationsFactory::setNewPath(const QString& uPath) |
1229 | +{ |
1230 | + storeValidFileInfo(0); |
1231 | + Location *location = parse(uPath); |
1232 | + if (location) |
1233 | + { |
1234 | + DirItemInfo *item = location->validateUrlPath(m_tmpPath); |
1235 | + if (item) |
1236 | + { |
1237 | + //isContentReadable() must already carry execution permission |
1238 | + if (item->isValid() && item->isDir() && item->isContentReadable()) |
1239 | + { |
1240 | + location->setInfoItem(item); |
1241 | + if (location != m_curLoc) |
1242 | + { |
1243 | + if (m_curLoc) |
1244 | + { |
1245 | + m_curLoc->stopWorking(); |
1246 | + } |
1247 | + emit locationChanged(m_curLoc, location); |
1248 | + location->startWorking(); |
1249 | + m_curLoc = location; |
1250 | + } |
1251 | + } |
1252 | + else |
1253 | + { |
1254 | + storeValidFileInfo(item); |
1255 | + } |
1256 | + } |
1257 | + else |
1258 | + { // not valid |
1259 | + location = 0; |
1260 | + } |
1261 | + } |
1262 | +#if DEBUG_MESSAGES |
1263 | + qDebug() << Q_FUNC_INFO << "input path:" << uPath << "location result:" << location; |
1264 | +#endif |
1265 | + return location; |
1266 | +} |
1267 | + |
1268 | + |
1269 | +QString LocationsFactory::stringAfterSlashes(const QString &url, int firstSlashIndex) const |
1270 | +{ |
1271 | + QString ret; |
1272 | + if (firstSlashIndex >=0) |
1273 | + { |
1274 | + while ( firstSlashIndex < url.length() && url.at(firstSlashIndex) == QDir::separator()) |
1275 | + { |
1276 | + ++firstSlashIndex; |
1277 | + } |
1278 | + if (firstSlashIndex < url.length()) |
1279 | + { |
1280 | + ret = url.mid(firstSlashIndex); |
1281 | + } |
1282 | + } |
1283 | + else |
1284 | + { |
1285 | + ret = url; |
1286 | + firstSlashIndex = 0; |
1287 | + } |
1288 | + //replace any double slashes by just one |
1289 | + for(int charCounter = ret.size() -1; charCounter > 0; --charCounter) |
1290 | + { |
1291 | + if (ret.at(charCounter) == QDir::separator() && |
1292 | + ret.at(charCounter-1) == QDir::separator()) |
1293 | + { |
1294 | + ret.remove(charCounter,1); |
1295 | + } |
1296 | + } |
1297 | + return ret; |
1298 | +} |
1299 | + |
1300 | + |
1301 | +void LocationsFactory::storeValidFileInfo(const DirItemInfo *item) |
1302 | +{ |
1303 | + if (m_lastValidFileInfo) |
1304 | + { |
1305 | + delete m_lastValidFileInfo; |
1306 | + } |
1307 | + m_lastValidFileInfo = item; |
1308 | +} |
1309 | |
1310 | === added file 'src/plugin/folderlistmodel/locationsfactory.h' |
1311 | --- src/plugin/folderlistmodel/locationsfactory.h 1970-01-01 00:00:00 +0000 |
1312 | +++ src/plugin/folderlistmodel/locationsfactory.h 2014-05-15 23:31:23 +0000 |
1313 | @@ -0,0 +1,136 @@ |
1314 | +/************************************************************************** |
1315 | + * |
1316 | + * Copyright 2014 Canonical Ltd. |
1317 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1318 | + * |
1319 | + * This program is free software; you can redistribute it and/or modify |
1320 | + * it under the terms of the GNU Lesser General Public License as published by |
1321 | + * the Free Software Foundation; version 3. |
1322 | + * |
1323 | + * This program is distributed in the hope that it will be useful, |
1324 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1325 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1326 | + * GNU Lesser General Public License for more details. |
1327 | + * |
1328 | + * You should have received a copy of the GNU Lesser General Public License |
1329 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1330 | + * |
1331 | + * File: locationsfactory.h |
1332 | + * Date: 05/03/2014 |
1333 | + */ |
1334 | + |
1335 | +#ifndef LOCATIONSFACTORY_H |
1336 | +#define LOCATIONSFACTORY_H |
1337 | + |
1338 | +#include <QObject> |
1339 | +#include <QList> |
1340 | + |
1341 | + |
1342 | +class Location; |
1343 | +class DirItemInfo; |
1344 | + |
1345 | +/*! |
1346 | + * \brief The LocationsFactory class represents the set of main |
1347 | + * URL locations the File Manager supports. |
1348 | + * |
1349 | + * It is basically devided into main groups: |
1350 | + * \li Disk: \ref LocalDisk and \ref TrashDisk |
1351 | + * \li Net: \ref NetSambaShare and NetFishShare |
1352 | + * |
1353 | + * smb:// browses workgroup |
1354 | + * |
1355 | + * Location parser: \ref parser() |
1356 | + * \li \\workkgroup becomes smb://workgroup |
1357 | + * \li \\ becomes smb:// |
1358 | + * \li trash:/ and trash:// becomes trash:/// |
1359 | + * \li fish:/ and fish:// becomes fish:/// |
1360 | + * \li file:/ , file:// and file:/// becomes / |
1361 | + * |
1362 | + * \note Due to current File Manager UI typing method both: "file:" and "trash:" are supported |
1363 | + */ |
1364 | +class LocationsFactory : public QObject |
1365 | +{ |
1366 | + Q_OBJECT |
1367 | +public: |
1368 | + explicit LocationsFactory(QObject *parent = 0); |
1369 | + ~LocationsFactory(); |
1370 | + |
1371 | + Q_ENUMS(Locations) |
1372 | + enum Locations |
1373 | + { |
1374 | + LocalDisk, //<! any mounted file system |
1375 | + TrashDisk //<! special trash location in the disk |
1376 | +#if 0 |
1377 | + NetSambaShare //<! SAMBA or CIFS shares |
1378 | + NetFishShare //<! FISH protocol over ssh that provides file sharing |
1379 | +#endif |
1380 | + }; |
1381 | + |
1382 | + inline const Location * getLocation(Locations index) const {return m_locations.at(index);} |
1383 | + |
1384 | + |
1385 | + /*! |
1386 | + * \brief parse() Just parses (does not set/change the current location) according to \a urlPath |
1387 | + * \param urlPath urlPath the url like: file:///Item trash:///item /item, it MUST point to a valid Directory |
1388 | + * \return The location which supports the \a urlPath |
1389 | + */ |
1390 | + Location * parse(const QString& urlPath); |
1391 | + |
1392 | + /*! |
1393 | + * \brief setNewPath() Sets a new path, it can be in the current location or on another location |
1394 | + * |
1395 | + * When the location changes, the signal \ref locationChanged() is fired. |
1396 | + * |
1397 | + * \param urlPath the url like: file:///Item trash:///item /item, it MUST point to a valid Directory |
1398 | + * \return the location that supports the urlPath or NULL when \a urlPath is NOT a valid url or it is not a valid Directory |
1399 | + * |
1400 | + * \sa \ref parse() \ref location() |
1401 | + */ |
1402 | + Location * setNewPath(const QString& urlPath); |
1403 | + |
1404 | + /*! |
1405 | + * \brief location() |
1406 | + * \return The current location |
1407 | + */ |
1408 | + Location * location() const { return m_curLoc; } |
1409 | + |
1410 | + /*! |
1411 | + * \brief availableLocations() |
1412 | + * \return |
1413 | + */ |
1414 | + const QList<Location*>& |
1415 | + availableLocations() const { return m_locations; } |
1416 | + |
1417 | + /*! |
1418 | + * \brief lastValidFileInfo() |
1419 | + * |
1420 | + * When calling setNewPath(file_path) using a path to a File instead of a Directory |
1421 | + * the setNewPath() is not able to set a new path (current location or other), however it uses |
1422 | + * Location::validateUrlPath() which validates the path for files also, then this valid DirItemInfo object |
1423 | + * is saved using \ref storeValidFileInfo() for further use. |
1424 | + * |
1425 | + * \return The last valid DirItemInfo parsed which is not a Directory |
1426 | + */ |
1427 | + const DirItemInfo* lastValidFileInfo() const { return m_lastValidFileInfo; } |
1428 | + |
1429 | + void storeValidFileInfo(const DirItemInfo *item); |
1430 | + |
1431 | +signals: |
1432 | + void locationChanged(const Location *old, const Location *current); |
1433 | + |
1434 | +private: |
1435 | + QString stringAfterSlashes(const QString& url, int firstSlashIndex) const; |
1436 | + |
1437 | +private: |
1438 | + Location * m_curLoc; |
1439 | + QList<Location*> m_locations; |
1440 | + QString m_tmpPath; |
1441 | + const DirItemInfo * m_lastValidFileInfo; |
1442 | + |
1443 | +#if defined(REGRESSION_TEST_FOLDERLISTMODEL) |
1444 | + friend class TestDirModel; |
1445 | +#endif |
1446 | + |
1447 | +}; |
1448 | + |
1449 | +#endif // LOCATIONSFACTORY_H |
1450 | |
1451 | === added file 'src/plugin/folderlistmodel/locationurl.cpp' |
1452 | --- src/plugin/folderlistmodel/locationurl.cpp 1970-01-01 00:00:00 +0000 |
1453 | +++ src/plugin/folderlistmodel/locationurl.cpp 2014-05-15 23:31:23 +0000 |
1454 | @@ -0,0 +1,34 @@ |
1455 | +/************************************************************************** |
1456 | + * |
1457 | + * Copyright 2014 Canonical Ltd. |
1458 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1459 | + * |
1460 | + * This program is free software; you can redistribute it and/or modify |
1461 | + * it under the terms of the GNU Lesser General Public License as published by |
1462 | + * the Free Software Foundation; version 3. |
1463 | + * |
1464 | + * This program is distributed in the hope that it will be useful, |
1465 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1466 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1467 | + * GNU Lesser General Public License for more details. |
1468 | + * |
1469 | + * You should have received a copy of the GNU Lesser General Public License |
1470 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1471 | + * |
1472 | + * File: locationurl.cpp |
1473 | + * Date: 11/03/2014 |
1474 | + */ |
1475 | + |
1476 | +#include "locationurl.h" |
1477 | + |
1478 | +const QString LocationUrl::TrashRootURL("trash:///"); |
1479 | +const QString LocationUrl::DiskRootURL("file:///"); |
1480 | +#if 0 |
1481 | +QString LocationURL::SmbURL("smb://"); |
1482 | +QString LocationURL::FishURL("fish:///"); |
1483 | +#endif |
1484 | + |
1485 | + |
1486 | +LocationUrl::LocationUrl() |
1487 | +{ |
1488 | +} |
1489 | |
1490 | === added file 'src/plugin/folderlistmodel/locationurl.h' |
1491 | --- src/plugin/folderlistmodel/locationurl.h 1970-01-01 00:00:00 +0000 |
1492 | +++ src/plugin/folderlistmodel/locationurl.h 2014-05-15 23:31:23 +0000 |
1493 | @@ -0,0 +1,40 @@ |
1494 | +/************************************************************************** |
1495 | + * |
1496 | + * Copyright 2014 Canonical Ltd. |
1497 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1498 | + * |
1499 | + * This program is free software; you can redistribute it and/or modify |
1500 | + * it under the terms of the GNU Lesser General Public License as published by |
1501 | + * the Free Software Foundation; version 3. |
1502 | + * |
1503 | + * This program is distributed in the hope that it will be useful, |
1504 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1505 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1506 | + * GNU Lesser General Public License for more details. |
1507 | + * |
1508 | + * You should have received a copy of the GNU Lesser General Public License |
1509 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1510 | + * |
1511 | + * File: locationurl.h |
1512 | + * Date: 11/03/2014 |
1513 | + */ |
1514 | + |
1515 | +#ifndef LOCATIONURL_H |
1516 | +#define LOCATIONURL_H |
1517 | + |
1518 | +#include <QString> |
1519 | + |
1520 | +class LocationUrl |
1521 | +{ |
1522 | +public: |
1523 | + static const QString DiskRootURL; |
1524 | + static const QString TrashRootURL; |
1525 | +#if 0 |
1526 | + static const QString SmbURL; |
1527 | + static const QString FishURL; |
1528 | +#endif |
1529 | +private: |
1530 | + LocationUrl(); |
1531 | +}; |
1532 | + |
1533 | +#endif // LOCATIONURL_H |
1534 | |
1535 | === modified file 'src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp' |
1536 | --- src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-05-15 23:31:22 +0000 |
1537 | +++ src/plugin/test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-05-15 23:31:23 +0000 |
1538 | @@ -3,7 +3,11 @@ |
1539 | #include "tempfiles.h" |
1540 | #include "externalfswatcher.h" |
1541 | #include "dirselection.h" |
1542 | -#include "trash/qtrashdir.h" |
1543 | +#include "qtrashdir.h" |
1544 | +#include "location.h" |
1545 | +#include "locationurl.h" |
1546 | +#include "locationsfactory.h" |
1547 | +#include "disklocation.h" |
1548 | |
1549 | #if defined(Q_OS_UNIX) |
1550 | #include <stdio.h> |
1551 | @@ -143,6 +147,8 @@ |
1552 | void modelSelectionItemsRange(); |
1553 | |
1554 | void trashDiretories(); |
1555 | + void locationFactory(); |
1556 | + |
1557 | |
1558 | private: |
1559 | void initDeepDirs(); |
1560 | @@ -2389,6 +2395,45 @@ |
1561 | } |
1562 | |
1563 | |
1564 | +void TestDirModel::locationFactory() |
1565 | +{ |
1566 | + LocationsFactory factoryLocations(this); |
1567 | + const Location *location = 0; |
1568 | + |
1569 | + //Due to current File Manager UI typing method both: "file:" and "trash:" are supported |
1570 | + // location = factoryLocations.setNewPath("trash:"); |
1571 | + // QVERIFY(location == 0); |
1572 | + |
1573 | + location = factoryLocations.setNewPath("file://////"); |
1574 | + QVERIFY(location); |
1575 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
1576 | + QCOMPARE(location->info()->absoluteFilePath(), QDir::rootPath()); |
1577 | + QCOMPARE(location->urlPath(), QDir::rootPath()); |
1578 | + QCOMPARE(location->isRoot(), true); |
1579 | + |
1580 | + location = factoryLocations.setNewPath("/"); |
1581 | + QVERIFY(location); |
1582 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
1583 | + QCOMPARE(location->info()->absoluteFilePath(), QDir::rootPath()); |
1584 | + QCOMPARE(location->urlPath(), QDir::rootPath()); |
1585 | + QCOMPARE(location->isRoot(), true); |
1586 | + |
1587 | + location = factoryLocations.setNewPath("//"); |
1588 | + QVERIFY(location); |
1589 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
1590 | + QCOMPARE(location->info()->absoluteFilePath(), QDir::rootPath()); |
1591 | + QCOMPARE(location->urlPath(), QDir::rootPath()); |
1592 | + QCOMPARE(location->isRoot(), true); |
1593 | + |
1594 | + location = factoryLocations.setNewPath("//bin"); |
1595 | + QVERIFY(location); |
1596 | + QVERIFY(location->type() == LocationsFactory::LocalDisk); |
1597 | + QCOMPARE(location->info()->absoluteFilePath(), QLatin1String("/bin")); |
1598 | + QCOMPARE(location->urlPath(), QLatin1String("/bin")); |
1599 | + QCOMPARE(location->isRoot(), false); |
1600 | +} |
1601 | + |
1602 | + |
1603 | int main(int argc, char *argv[]) |
1604 | { |
1605 | QApplication app(argc, argv); |
PASSED: Continuous integration, rev:172 91.189. 93.70:8080/ job/ubuntu- filemanager- app-ci/ 193/ 91.189. 93.70:8080/ job/generic- mediumtests- trusty/ 2360 91.189. 93.70:8080/ job/ubuntu- filemanager- app-raring- amd64-ci/ 193 91.189. 93.70:8080/ job/ubuntu- filemanager- app-saucy- amd64-ci/ 193 91.189. 93.70:8080/ job/ubuntu- filemanager- app-trusty- amd64-ci/ 143
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- filemanager- app-ci/ 193/rebuild
http://