Merge lp:~carlos-mazieri/ubuntu-filemanager-app/samba-ui-02 into lp:ubuntu-filemanager-app
- samba-ui-02
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Arto Jalkanen |
Approved revision: | 461 |
Merged at revision: | 467 |
Proposed branch: | lp:~carlos-mazieri/ubuntu-filemanager-app/samba-ui-02 |
Merge into: | lp:ubuntu-filemanager-app |
Prerequisite: | lp:~carlos-mazieri/ubuntu-filemanager-app/samba-ui-01 |
Diff against target: |
593 lines (+394/-40) 4 files modified
src/plugin/placesmodel/placesmodel.cpp (+143/-34) src/plugin/placesmodel/placesmodel.h (+23/-6) src/plugin/test_placesmodel/placesmodeltest.cpp (+193/-0) src/plugin/test_placesmodel/test_placesmodel.pro (+35/-0) |
To merge this branch: | bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/samba-ui-02 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Arto Jalkanen | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
David Planella | Pending | ||
Review via email: mp+270335@code.launchpad.net |
Commit message
1. Added Samba Location as Network
2. Removed default locations from setting files, it allows adding new default locations in source code
3. Kept user added and removed locations in settings file.
4. Created a regression test for PlacesModel.
User can remove a default Location and then add it again.
Description of the change
Added Samba location as Network
Improved settings file content to allow add/remove places without affecting default places which are handled in the source code.
Added a regression testing for PlacesModel.
Added "/media/<user>" as watched directory because "/etc/mtab" was failing to fire changes.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Arto Jalkanen (ajalkane) wrote : | # |
Several inlined comments. The one about removing all keys but the new ones introduced in this change is the one that needs attention, others are more minor.
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
I agree with your comments and I will modify that according to that.
Thanks.
- 461. By Carlos Jose Mazieri
-
PlacesModel:
:addLocationWit houtStoring( ) renamed to PlacesModel: :addLocationNot RemovedWithoutS toring( )
Documented both PlacesModel::addLocation( ) and PlacesModel: :addLocationNot RemovedWithoutS toring( )
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:461
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Arto Jalkanen (ajalkane) : | # |
Preview Diff
1 | === modified file 'src/plugin/placesmodel/placesmodel.cpp' | |||
2 | --- src/plugin/placesmodel/placesmodel.cpp 2015-02-11 19:22:08 +0000 | |||
3 | +++ src/plugin/placesmodel/placesmodel.cpp 2015-09-19 22:49:08 +0000 | |||
4 | @@ -15,6 +15,7 @@ | |||
5 | 15 | * | 15 | * |
6 | 16 | * Author : David Planella <david.planella@ubuntu.com> | 16 | * Author : David Planella <david.planella@ubuntu.com> |
7 | 17 | * Arto Jalkanen <ajalkane@gmail.com> | 17 | * Arto Jalkanen <ajalkane@gmail.com> |
8 | 18 | * Carlos Mazieri <carlos.mazieri@gmail.com> | ||
9 | 18 | */ | 19 | */ |
10 | 19 | 20 | ||
11 | 20 | #include "placesmodel.h" | 21 | #include "placesmodel.h" |
12 | @@ -25,14 +26,20 @@ | |||
13 | 25 | #include <QStandardPaths> | 26 | #include <QStandardPaths> |
14 | 26 | #include <QDebug> | 27 | #include <QDebug> |
15 | 27 | 28 | ||
16 | 29 | namespace | ||
17 | 30 | { | ||
18 | 31 | const QString userSavedLocationsName("userSavedLocations"); | ||
19 | 32 | const QString userRemovedLocationsName("userRemovedLocations"); | ||
20 | 33 | } | ||
21 | 34 | |||
22 | 28 | PlacesModel::PlacesModel(QObject *parent) : | 35 | PlacesModel::PlacesModel(QObject *parent) : |
24 | 29 | QAbstractListModel(parent) | 36 | QAbstractListModel(parent) |
25 | 37 | , m_going_to_rescanMtab(false) | ||
26 | 30 | { | 38 | { |
27 | 31 | m_userMountLocation = "/media/" + qgetenv("USER"); | 39 | m_userMountLocation = "/media/" + qgetenv("USER"); |
28 | 32 | // For example /run/user/1000 | 40 | // For example /run/user/1000 |
29 | 33 | m_runtimeLocations = QStandardPaths::standardLocations(QStandardPaths::RuntimeLocation); | 41 | m_runtimeLocations = QStandardPaths::standardLocations(QStandardPaths::RuntimeLocation); |
30 | 34 | 42 | ||
31 | 35 | QStringList defaultLocations; | ||
32 | 36 | // Set the storage location to a path that works well | 43 | // Set the storage location to a path that works well |
33 | 37 | // with app isolation | 44 | // with app isolation |
34 | 38 | QString settingsLocation = | 45 | QString settingsLocation = |
35 | @@ -40,29 +47,41 @@ | |||
36 | 40 | + "/" + QCoreApplication::applicationName() + "/" + "places.conf"; | 47 | + "/" + QCoreApplication::applicationName() + "/" + "places.conf"; |
37 | 41 | m_settings = new QSettings(settingsLocation, QSettings::IniFormat, this); | 48 | m_settings = new QSettings(settingsLocation, QSettings::IniFormat, this); |
38 | 42 | 49 | ||
39 | 50 | m_userSavedLocations = m_settings->value(userSavedLocationsName).toStringList(); | ||
40 | 51 | m_userRemovedLocations = m_settings->value(userRemovedLocationsName).toStringList(); | ||
41 | 52 | |||
42 | 53 | //remove old key "storedLocations" which is no longer used | ||
43 | 54 | QLatin1String oldStoredLocations("storedLocations"); | ||
44 | 55 | if (m_settings->contains(oldStoredLocations)) { | ||
45 | 56 | m_settings->remove(oldStoredLocations); | ||
46 | 57 | } | ||
47 | 58 | |||
48 | 43 | // Prepopulate the model with the user locations | 59 | // Prepopulate the model with the user locations |
49 | 44 | // for the first time it's used | 60 | // for the first time it's used |
63 | 45 | defaultLocations.append(locationHome()); | 61 | addDefaultLocation(locationHome()); |
64 | 46 | defaultLocations.append(locationDocuments()); | 62 | addDefaultLocation(locationDocuments()); |
65 | 47 | defaultLocations.append(locationDownloads()); | 63 | addDefaultLocation(locationDownloads()); |
66 | 48 | defaultLocations.append(locationMusic()); | 64 | addDefaultLocation(locationMusic()); |
67 | 49 | defaultLocations.append(locationPictures()); | 65 | addDefaultLocation(locationPictures()); |
68 | 50 | defaultLocations.append(locationVideos()); | 66 | addDefaultLocation(locationVideos()); |
69 | 51 | // Add root also | 67 | |
70 | 52 | defaultLocations.append("/"); | 68 | //Network locations |
71 | 53 | 69 | addDefaultLocation(locationSamba()); | |
72 | 54 | if (!m_settings->contains("storedLocations")) { | 70 | |
73 | 55 | m_locations.append(defaultLocations); | 71 | //mounted locations |
74 | 56 | } else { | 72 | addDefaultLocation("/"); |
75 | 57 | m_locations = m_settings->value("storedLocations").toStringList(); | 73 | initNewUserMountsWatcher(); |
76 | 74 | rescanMtab(); | ||
77 | 75 | |||
78 | 76 | //other user saved locations | ||
79 | 77 | foreach (const QString& userLocation, m_userSavedLocations) { | ||
80 | 78 | addLocationNotRemovedWithoutStoring(userLocation); | ||
81 | 58 | } | 79 | } |
82 | 80 | m_settings->sync(); | ||
83 | 59 | 81 | ||
84 | 60 | foreach (const QString &location, m_locations) { | 82 | foreach (const QString &location, m_locations) { |
85 | 61 | qDebug() << "Location: " << location; | 83 | qDebug() << "Location: " << location; |
86 | 62 | } | 84 | } |
87 | 63 | |||
88 | 64 | initNewUserMountsWatcher(); | ||
89 | 65 | rescanMtab(); | ||
90 | 66 | } | 85 | } |
91 | 67 | 86 | ||
92 | 68 | PlacesModel::~PlacesModel() { | 87 | PlacesModel::~PlacesModel() { |
93 | @@ -73,17 +92,29 @@ | |||
94 | 73 | PlacesModel::initNewUserMountsWatcher() { | 92 | PlacesModel::initNewUserMountsWatcher() { |
95 | 74 | m_newUserMountsWatcher = new QFileSystemWatcher(this); | 93 | m_newUserMountsWatcher = new QFileSystemWatcher(this); |
96 | 75 | 94 | ||
98 | 76 | qDebug() << Q_FUNC_INFO << "Start watching mtab file for new mounts" << m_mtabParser.path(); | 95 | connect(m_newUserMountsWatcher, SIGNAL(fileChanged(QString)), this, SLOT(mtabChanged(QString))); |
99 | 96 | connect(m_newUserMountsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(mtabChanged(QString))); | ||
100 | 77 | 97 | ||
101 | 78 | m_newUserMountsWatcher->addPath(m_mtabParser.path()); | 98 | m_newUserMountsWatcher->addPath(m_mtabParser.path()); |
102 | 99 | /* | ||
103 | 100 | it looks like QFileSystemWatcher does not work for /etc/mtab sometimes, lets use /media/<user> as well | ||
104 | 101 | See: | ||
105 | 102 | https://forum.qt.io/topic/8566/qfilesystemwatcher-not-working-with-etc-mtab | ||
106 | 103 | https://bugs.launchpad.net/ubuntu-filemanager-app/+bug/1444367 | ||
107 | 104 | */ | ||
108 | 105 | m_newUserMountsWatcher->addPath(m_userMountLocation); | ||
109 | 79 | 106 | ||
111 | 80 | connect(m_newUserMountsWatcher, &QFileSystemWatcher::fileChanged, this, &PlacesModel::mtabChanged); | 107 | qDebug() << Q_FUNC_INFO << "Start watching mtab file for new mounts, using:" |
112 | 108 | << m_newUserMountsWatcher->files() << "and" << m_newUserMountsWatcher->directories(); | ||
113 | 81 | } | 109 | } |
114 | 82 | 110 | ||
115 | 83 | void | 111 | void |
116 | 84 | PlacesModel::mtabChanged(const QString &path) { | 112 | PlacesModel::mtabChanged(const QString &path) { |
117 | 85 | qDebug() << Q_FUNC_INFO << "file changed in " << path; | 113 | qDebug() << Q_FUNC_INFO << "file changed in " << path; |
119 | 86 | rescanMtab(); | 114 | if (!m_going_to_rescanMtab) { |
120 | 115 | m_going_to_rescanMtab = true; | ||
121 | 116 | QTimer::singleShot(100, this, SLOT(rescanMtab())); | ||
122 | 117 | } | ||
123 | 87 | // Since old mtab file is replaced with new contents, must readd filesystem watcher | 118 | // Since old mtab file is replaced with new contents, must readd filesystem watcher |
124 | 88 | m_newUserMountsWatcher->removePath(path); | 119 | m_newUserMountsWatcher->removePath(path); |
125 | 89 | m_newUserMountsWatcher->addPath(path); | 120 | m_newUserMountsWatcher->addPath(path); |
126 | @@ -91,6 +122,7 @@ | |||
127 | 91 | 122 | ||
128 | 92 | void | 123 | void |
129 | 93 | PlacesModel::rescanMtab() { | 124 | PlacesModel::rescanMtab() { |
130 | 125 | m_going_to_rescanMtab = false; | ||
131 | 94 | const QString& path = m_mtabParser.path(); | 126 | const QString& path = m_mtabParser.path(); |
132 | 95 | qDebug() << Q_FUNC_INFO << "rescanning mtab" << path; | 127 | qDebug() << Q_FUNC_INFO << "rescanning mtab" << path; |
133 | 96 | 128 | ||
134 | @@ -113,7 +145,7 @@ | |||
135 | 113 | 145 | ||
136 | 114 | foreach (QString addedMount, addedMounts) { | 146 | foreach (QString addedMount, addedMounts) { |
137 | 115 | qDebug() << Q_FUNC_INFO << "user mount added: " << addedMount; | 147 | qDebug() << Q_FUNC_INFO << "user mount added: " << addedMount; |
139 | 116 | addLocationWithoutStoring(addedMount); | 148 | addLocationNotRemovedWithoutStoring(addedMount); |
140 | 117 | emit userMountAdded(addedMount); | 149 | emit userMountAdded(addedMount); |
141 | 118 | } | 150 | } |
142 | 119 | 151 | ||
143 | @@ -203,6 +235,11 @@ | |||
144 | 203 | return standardLocation(QStandardPaths::MoviesLocation); | 235 | return standardLocation(QStandardPaths::MoviesLocation); |
145 | 204 | } | 236 | } |
146 | 205 | 237 | ||
147 | 238 | QString PlacesModel::locationSamba() const | ||
148 | 239 | { | ||
149 | 240 | return QLatin1Literal("smb://"); | ||
150 | 241 | } | ||
151 | 242 | |||
152 | 206 | int PlacesModel::rowCount(const QModelIndex &parent) const | 243 | int PlacesModel::rowCount(const QModelIndex &parent) const |
153 | 207 | { | 244 | { |
154 | 208 | Q_UNUSED(parent) | 245 | Q_UNUSED(parent) |
155 | @@ -227,10 +264,30 @@ | |||
156 | 227 | 264 | ||
157 | 228 | void PlacesModel::removeItem(int indexToRemove) | 265 | void PlacesModel::removeItem(int indexToRemove) |
158 | 229 | { | 266 | { |
163 | 230 | removeItemWithoutStoring(indexToRemove); | 267 | if (indexToRemove >= 0 && indexToRemove < m_locations.count()) |
164 | 231 | 268 | { | |
165 | 232 | // Remove the location permanently | 269 | bool sync_settings = false; |
166 | 233 | m_settings->setValue("storedLocations", m_locations); | 270 | const QString & location = m_locations.at(indexToRemove); |
167 | 271 | //check if the index belongs to a user saved location | ||
168 | 272 | int index_user_location = m_userSavedLocations.indexOf(location); | ||
169 | 273 | if (index_user_location > -1) | ||
170 | 274 | { | ||
171 | 275 | // Remove the User saved location permanently | ||
172 | 276 | m_userSavedLocations.removeAt(index_user_location); | ||
173 | 277 | m_settings->setValue(userSavedLocationsName, m_userSavedLocations); | ||
174 | 278 | sync_settings = true; | ||
175 | 279 | } | ||
176 | 280 | //save it as removed location, even a default location can be removed | ||
177 | 281 | if (!m_userRemovedLocations.contains(location)) { | ||
178 | 282 | m_userRemovedLocations.append(location); | ||
179 | 283 | m_settings->setValue(userRemovedLocationsName, m_userRemovedLocations); | ||
180 | 284 | sync_settings = true; | ||
181 | 285 | } | ||
182 | 286 | removeItemWithoutStoring(indexToRemove); | ||
183 | 287 | if (sync_settings) { | ||
184 | 288 | m_settings->sync(); | ||
185 | 289 | } | ||
186 | 290 | } | ||
187 | 234 | } | 291 | } |
188 | 235 | 292 | ||
189 | 236 | void PlacesModel::removeItemWithoutStoring(int indexToRemove) | 293 | void PlacesModel::removeItemWithoutStoring(int indexToRemove) |
190 | @@ -250,18 +307,58 @@ | |||
191 | 250 | endRemoveRows(); | 307 | endRemoveRows(); |
192 | 251 | } | 308 | } |
193 | 252 | 309 | ||
194 | 310 | /*! | ||
195 | 311 | * \brief PlacesModel::addLocation() | ||
196 | 312 | * | ||
197 | 313 | * Adds the location permanently in the settings file. | ||
198 | 314 | * | ||
199 | 315 | * If the location has already been deleted by the user it is first removed from the removed settings \a m_userRemovedLocations. | ||
200 | 316 | * | ||
201 | 317 | * The location is saved in settings file in \a m_userSavedLocations | ||
202 | 318 | * | ||
203 | 319 | * \param location | ||
204 | 320 | */ | ||
205 | 253 | void PlacesModel::addLocation(const QString &location) | 321 | void PlacesModel::addLocation(const QString &location) |
210 | 254 | { | 322 | { |
211 | 255 | if (addLocationWithoutStoring(location)) { | 323 | bool sync_settings = false; |
212 | 256 | // Store the location permanently | 324 | //verify it the user had deleted it before and now is inserting it again |
213 | 257 | m_settings->setValue("storedLocations", m_locations); | 325 | int indexRemoved = m_userRemovedLocations.indexOf(location); |
214 | 326 | if (indexRemoved > -1) { | ||
215 | 327 | m_userRemovedLocations.removeAt(indexRemoved); | ||
216 | 328 | m_settings->setValue(userRemovedLocationsName, m_userRemovedLocations); | ||
217 | 329 | sync_settings = true; | ||
218 | 330 | } | ||
219 | 331 | if (addLocationNotRemovedWithoutStoring(location)) { | ||
220 | 332 | // Store the location permanently if it is not default location | ||
221 | 333 | if (!isDefaultLocation(location) && !m_userSavedLocations.contains(location)) | ||
222 | 334 | { | ||
223 | 335 | m_userSavedLocations.append(location); | ||
224 | 336 | m_settings->setValue(userSavedLocationsName, m_userSavedLocations); | ||
225 | 337 | sync_settings = true; | ||
226 | 338 | } | ||
227 | 339 | } | ||
228 | 340 | if (sync_settings) { | ||
229 | 341 | m_settings->sync(); | ||
230 | 258 | } | 342 | } |
231 | 259 | } | 343 | } |
232 | 260 | 344 | ||
234 | 261 | bool PlacesModel::addLocationWithoutStoring(const QString &location) | 345 | /*! |
235 | 346 | * \brief PlacesModel::addLocationNotRemovedWithoutStoring() | ||
236 | 347 | * | ||
237 | 348 | * Add that location only if it was not removed before by the user. | ||
238 | 349 | * | ||
239 | 350 | * When the user removes a location from Places using \ref removeItem(int index) it is stored in settings file. | ||
240 | 351 | * The user must use \ref addLocation(const QString &location) to add back an already removed location. | ||
241 | 352 | * | ||
242 | 353 | * \param location | ||
243 | 354 | * | ||
244 | 355 | * \return true when the location was added (not existent in \a m_locations nor in \a m_userRemovedLocations), | ||
245 | 356 | * otherwise false | ||
246 | 357 | */ | ||
247 | 358 | bool PlacesModel::addLocationNotRemovedWithoutStoring(const QString &location) | ||
248 | 262 | { | 359 | { |
251 | 263 | // Do not allow for duplicates | 360 | // Do not allow for duplicates and look for removed locations from settings |
252 | 264 | if (!m_locations.contains(location)) { | 361 | if (!m_locations.contains(location) && !m_userRemovedLocations.contains(location)) { |
253 | 265 | // Tell Qt that we're going to be changing the model | 362 | // Tell Qt that we're going to be changing the model |
254 | 266 | // There's no tree-parent, first new item will be at | 363 | // There's no tree-parent, first new item will be at |
255 | 267 | // m_locations.count(), and the last one too | 364 | // m_locations.count(), and the last one too |
256 | @@ -270,7 +367,6 @@ | |||
257 | 270 | // Append the actual location | 367 | // Append the actual location |
258 | 271 | m_locations.append(location); | 368 | m_locations.append(location); |
259 | 272 | 369 | ||
260 | 273 | |||
261 | 274 | // Tell Qt we're done with modifying the model so that | 370 | // Tell Qt we're done with modifying the model so that |
262 | 275 | // it can update the UI and everything else to reflect | 371 | // it can update the UI and everything else to reflect |
263 | 276 | // the new state | 372 | // the new state |
264 | @@ -279,3 +375,16 @@ | |||
265 | 279 | } | 375 | } |
266 | 280 | return false; | 376 | return false; |
267 | 281 | } | 377 | } |
268 | 378 | |||
269 | 379 | void PlacesModel::addDefaultLocation(const QString &location) | ||
270 | 380 | { | ||
271 | 381 | // a Default location can be removed by the user | ||
272 | 382 | if (addLocationNotRemovedWithoutStoring(location)) { | ||
273 | 383 | m_defaultLocations.append(location); | ||
274 | 384 | } | ||
275 | 385 | } | ||
276 | 386 | |||
277 | 387 | void PlacesModel::removeItem(const QString &location) | ||
278 | 388 | { | ||
279 | 389 | removeItem(m_locations.indexOf(location)); | ||
280 | 390 | } | ||
281 | 282 | 391 | ||
282 | === modified file 'src/plugin/placesmodel/placesmodel.h' | |||
283 | --- src/plugin/placesmodel/placesmodel.h 2015-01-28 20:18:07 +0000 | |||
284 | +++ src/plugin/placesmodel/placesmodel.h 2015-09-19 22:49:08 +0000 | |||
285 | @@ -40,6 +40,7 @@ | |||
286 | 40 | Q_PROPERTY(QString locationMusic READ locationMusic CONSTANT) | 40 | Q_PROPERTY(QString locationMusic READ locationMusic CONSTANT) |
287 | 41 | Q_PROPERTY(QString locationPictures READ locationPictures CONSTANT) | 41 | Q_PROPERTY(QString locationPictures READ locationPictures CONSTANT) |
288 | 42 | Q_PROPERTY(QString locationVideos READ locationVideos CONSTANT) | 42 | Q_PROPERTY(QString locationVideos READ locationVideos CONSTANT) |
289 | 43 | Q_PROPERTY(QString locationSamba READ locationSamba CONSTANT) | ||
290 | 43 | 44 | ||
291 | 44 | public: | 45 | public: |
292 | 45 | explicit PlacesModel(QObject *parent = 0); | 46 | explicit PlacesModel(QObject *parent = 0); |
293 | @@ -50,7 +51,8 @@ | |||
294 | 50 | QString locationMusic() const; | 51 | QString locationMusic() const; |
295 | 51 | QString locationPictures() const; | 52 | QString locationPictures() const; |
296 | 52 | QString locationVideos() const; | 53 | QString locationVideos() const; |
298 | 53 | int rowCount(const QModelIndex &parent) const override; | 54 | QString locationSamba() const; |
299 | 55 | int rowCount(const QModelIndex &parent = QModelIndex() ) const override; | ||
300 | 54 | QVariant data(const QModelIndex &index, int role) const override; | 56 | QVariant data(const QModelIndex &index, int role) const override; |
301 | 55 | QHash<int, QByteArray> roleNames() const override; | 57 | QHash<int, QByteArray> roleNames() const override; |
302 | 56 | 58 | ||
303 | @@ -61,20 +63,28 @@ | |||
304 | 61 | public slots: | 63 | public slots: |
305 | 62 | void addLocation(const QString &location); | 64 | void addLocation(const QString &location); |
306 | 63 | void removeItem(int indexToRemove); | 65 | void removeItem(int indexToRemove); |
308 | 64 | inline bool isUserMountDirectory(const QString location) { | 66 | inline bool isUserMountDirectory(const QString& location) { |
309 | 65 | return m_userMounts.contains(location); | 67 | return m_userMounts.contains(location); |
310 | 66 | } | 68 | } |
311 | 69 | bool isDefaultLocation(const QString& location) const { | ||
312 | 70 | return m_defaultLocations.contains(location); | ||
313 | 71 | } | ||
314 | 72 | inline int indexOfLocation(const QString& location) const { | ||
315 | 73 | return m_locations.indexOf(location); | ||
316 | 74 | } | ||
317 | 67 | 75 | ||
318 | 68 | private slots: | 76 | private slots: |
319 | 69 | void mtabChanged(const QString &path); | 77 | void mtabChanged(const QString &path); |
320 | 70 | void rescanMtab(); | 78 | void rescanMtab(); |
321 | 71 | 79 | ||
322 | 72 | private: | 80 | private: |
326 | 73 | void initNewUserMountsWatcher(); | 81 | void initNewUserMountsWatcher(); |
327 | 74 | // Returns true if location was not known before, and false if it was known | 82 | bool addLocationNotRemovedWithoutStoring(const QString &location); |
325 | 75 | bool addLocationWithoutStoring(const QString &location); | ||
328 | 76 | // Returns true if location was not known before, and false if it was known | 83 | // Returns true if location was not known before, and false if it was known |
329 | 77 | void removeItemWithoutStoring(int itemToRemove); | 84 | void removeItemWithoutStoring(int itemToRemove); |
330 | 85 | //just add into m_locations, does not emit any signal | ||
331 | 86 | void addDefaultLocation(const QString& location); | ||
332 | 87 | void removeItem(const QString& location); | ||
333 | 78 | 88 | ||
334 | 79 | QMtabParser m_mtabParser; | 89 | QMtabParser m_mtabParser; |
335 | 80 | QStringList m_runtimeLocations; | 90 | QStringList m_runtimeLocations; |
336 | @@ -82,10 +92,17 @@ | |||
337 | 82 | bool isMtabEntryUserMount(const QMtabEntry &entry) const; | 92 | bool isMtabEntryUserMount(const QMtabEntry &entry) const; |
338 | 83 | bool isSubDirectory(const QString &dir, const QString &path) const; | 93 | bool isSubDirectory(const QString &dir, const QString &path) const; |
339 | 84 | QString standardLocation(QStandardPaths::StandardLocation location) const; | 94 | QString standardLocation(QStandardPaths::StandardLocation location) const; |
341 | 85 | QStringList m_locations; | 95 | QStringList m_locations; //<! m_locations = m_defaultLocations + m_userSavedLocations - m_userRemovedLocations |
342 | 96 | QStringList m_defaultLocations; | ||
343 | 97 | QStringList m_userSavedLocations; | ||
344 | 98 | QStringList m_userRemovedLocations; | ||
345 | 86 | QSettings *m_settings; | 99 | QSettings *m_settings; |
346 | 87 | QFileSystemWatcher *m_newUserMountsWatcher; | 100 | QFileSystemWatcher *m_newUserMountsWatcher; |
347 | 88 | QSet<QString> m_userMounts; | 101 | QSet<QString> m_userMounts; |
348 | 102 | bool m_going_to_rescanMtab; | ||
349 | 103 | #if defined(REGRESSION_TEST_PLACES_MODEL) | ||
350 | 104 | friend class PlacesmodelTest; | ||
351 | 105 | #endif | ||
352 | 89 | }; | 106 | }; |
353 | 90 | 107 | ||
354 | 91 | #endif // PLACESMODEL_H | 108 | #endif // PLACESMODEL_H |
355 | 92 | 109 | ||
356 | === added directory 'src/plugin/test_placesmodel' | |||
357 | === added file 'src/plugin/test_placesmodel/placesmodeltest.cpp' | |||
358 | --- src/plugin/test_placesmodel/placesmodeltest.cpp 1970-01-01 00:00:00 +0000 | |||
359 | +++ src/plugin/test_placesmodel/placesmodeltest.cpp 2015-09-19 22:49:08 +0000 | |||
360 | @@ -0,0 +1,193 @@ | |||
361 | 1 | #include "placesmodel.h" | ||
362 | 2 | |||
363 | 3 | #include <QString> | ||
364 | 4 | #include <QtTest> | ||
365 | 5 | #include <QSettings> | ||
366 | 6 | #include <QFile> | ||
367 | 7 | #include <QFileInfo> | ||
368 | 8 | #include <QTemporaryFile> | ||
369 | 9 | #include <QTemporaryDir> | ||
370 | 10 | |||
371 | 11 | |||
372 | 12 | class SaveSettings: public QTemporaryFile | ||
373 | 13 | { | ||
374 | 14 | public: | ||
375 | 15 | SaveSettings(QObject *parent = 0) : QTemporaryFile(parent) {} | ||
376 | 16 | bool openReadOnly() | ||
377 | 17 | { | ||
378 | 18 | return open(QFile::ReadOnly); | ||
379 | 19 | } | ||
380 | 20 | }; | ||
381 | 21 | |||
382 | 22 | class PlacesmodelTest : public QObject | ||
383 | 23 | { | ||
384 | 24 | Q_OBJECT | ||
385 | 25 | |||
386 | 26 | public: | ||
387 | 27 | PlacesmodelTest(); | ||
388 | 28 | |||
389 | 29 | private Q_SLOTS: | ||
390 | 30 | void init(); | ||
391 | 31 | void cleanup(); | ||
392 | 32 | void cleanupTestCase(); | ||
393 | 33 | void addUserPlace(); | ||
394 | 34 | void removeUserPlace(); | ||
395 | 35 | void addExistentDefaultPlace(); // should fail | ||
396 | 36 | void removeDefaultPlace(); | ||
397 | 37 | void addRemovedDefaultPlace(); | ||
398 | 38 | private: | ||
399 | 39 | SaveSettings *m_saved_settings; | ||
400 | 40 | }; | ||
401 | 41 | |||
402 | 42 | |||
403 | 43 | PlacesmodelTest::PlacesmodelTest() : m_saved_settings(0) | ||
404 | 44 | { | ||
405 | 45 | |||
406 | 46 | } | ||
407 | 47 | |||
408 | 48 | void PlacesmodelTest::init() | ||
409 | 49 | { | ||
410 | 50 | PlacesModel places; | ||
411 | 51 | QFileInfo saved(places.m_settings->fileName()); | ||
412 | 52 | if (saved.exists()) | ||
413 | 53 | { | ||
414 | 54 | QFile settings(saved.absoluteFilePath()); | ||
415 | 55 | QCOMPARE(settings.open(QFile::ReadOnly), true); | ||
416 | 56 | m_saved_settings = new SaveSettings(this); | ||
417 | 57 | QCOMPARE(m_saved_settings->open(), true); | ||
418 | 58 | QByteArray settings_data = settings.readAll(); | ||
419 | 59 | QCOMPARE(m_saved_settings->write(settings_data), (qint64)settings_data.size()); | ||
420 | 60 | m_saved_settings->close(); | ||
421 | 61 | } | ||
422 | 62 | } | ||
423 | 63 | |||
424 | 64 | void PlacesmodelTest::cleanupTestCase() | ||
425 | 65 | { | ||
426 | 66 | if (m_saved_settings) | ||
427 | 67 | { | ||
428 | 68 | QCOMPARE(m_saved_settings->openReadOnly(), true); | ||
429 | 69 | PlacesModel places; | ||
430 | 70 | QFile saved(places.m_settings->fileName()); | ||
431 | 71 | QCOMPARE(saved.open(QFile::WriteOnly | QFile::Truncate), true); | ||
432 | 72 | QByteArray saved_data = m_saved_settings->readAll(); | ||
433 | 73 | QCOMPARE(saved.write(saved_data), (qint64)saved_data.size()); | ||
434 | 74 | } | ||
435 | 75 | } | ||
436 | 76 | |||
437 | 77 | void PlacesmodelTest::cleanup() | ||
438 | 78 | { | ||
439 | 79 | cleanupTestCase(); | ||
440 | 80 | } | ||
441 | 81 | |||
442 | 82 | void PlacesmodelTest::addUserPlace() | ||
443 | 83 | { | ||
444 | 84 | QTemporaryDir tempDir; | ||
445 | 85 | PlacesModel places; | ||
446 | 86 | int locations_counter = places.rowCount(); | ||
447 | 87 | QCOMPARE(places.indexOfLocation(tempDir.path()), -1); | ||
448 | 88 | places.addLocation(tempDir.path()); | ||
449 | 89 | QTest::qWait(50); | ||
450 | 90 | QCOMPARE(places.rowCount(), locations_counter + 1); | ||
451 | 91 | QVERIFY(places.indexOfLocation(tempDir.path()) != -1); | ||
452 | 92 | |||
453 | 93 | //now try to add it again which must fail | ||
454 | 94 | places.addLocation(tempDir.path()); | ||
455 | 95 | QTest::qWait(50); | ||
456 | 96 | QCOMPARE(places.rowCount(), locations_counter + 1); | ||
457 | 97 | |||
458 | 98 | //another model instance | ||
459 | 99 | PlacesModel places2; | ||
460 | 100 | QVERIFY(places2.indexOfLocation(tempDir.path()) != -1); | ||
461 | 101 | //added item must be in m_userSavedLocations | ||
462 | 102 | QVERIFY(places2.m_userSavedLocations.indexOf(tempDir.path()) != -1); | ||
463 | 103 | QCOMPARE(places2.rowCount(), locations_counter + 1); | ||
464 | 104 | } | ||
465 | 105 | |||
466 | 106 | void PlacesmodelTest::removeUserPlace() | ||
467 | 107 | { | ||
468 | 108 | // first add a temporary place | ||
469 | 109 | QTemporaryDir tempDir; | ||
470 | 110 | PlacesModel places; | ||
471 | 111 | int locations_counter = places.rowCount(); | ||
472 | 112 | QCOMPARE(places.indexOfLocation(tempDir.path()), -1); | ||
473 | 113 | places.addLocation(tempDir.path()); | ||
474 | 114 | QTest::qWait(50); | ||
475 | 115 | QCOMPARE(places.rowCount(), locations_counter + 1); | ||
476 | 116 | QVERIFY(places.indexOfLocation(tempDir.path()) != -1); | ||
477 | 117 | //then remove it | ||
478 | 118 | places.removeItem(tempDir.path()); | ||
479 | 119 | QTest::qWait(50); | ||
480 | 120 | QCOMPARE(places.rowCount(), locations_counter); | ||
481 | 121 | QCOMPARE(places.indexOfLocation(tempDir.path()), -1); | ||
482 | 122 | |||
483 | 123 | //another PlacesModel instance | ||
484 | 124 | PlacesModel places2; | ||
485 | 125 | QCOMPARE(places2.rowCount(), locations_counter); | ||
486 | 126 | //item removed is not in the m_locations | ||
487 | 127 | QCOMPARE(places2.indexOfLocation(tempDir.path()), -1); | ||
488 | 128 | //item removed is in m_userRemovedLocations | ||
489 | 129 | QVERIFY(places2.m_userRemovedLocations.indexOf(tempDir.path()) != -1); | ||
490 | 130 | } | ||
491 | 131 | |||
492 | 132 | void PlacesmodelTest::addExistentDefaultPlace() | ||
493 | 133 | { | ||
494 | 134 | PlacesModel places; | ||
495 | 135 | int home_index = places.indexOfLocation(QDir::homePath()); | ||
496 | 136 | QVERIFY(home_index != -1); | ||
497 | 137 | int places_counter = places.rowCount(); | ||
498 | 138 | places.addLocation(QDir::homePath()); | ||
499 | 139 | QTest::qWait(50); | ||
500 | 140 | //counter must be the same which indicates nothing was added | ||
501 | 141 | QCOMPARE(places.rowCount(), places_counter); | ||
502 | 142 | } | ||
503 | 143 | |||
504 | 144 | void PlacesmodelTest::removeDefaultPlace() | ||
505 | 145 | { | ||
506 | 146 | PlacesModel places; | ||
507 | 147 | int home_index = places.indexOfLocation(QDir::homePath()); | ||
508 | 148 | QVERIFY(home_index != -1); | ||
509 | 149 | int places_counter = places.rowCount(); | ||
510 | 150 | places.removeItem(home_index); | ||
511 | 151 | QTest::qWait(50); | ||
512 | 152 | QCOMPARE(places.rowCount(), places_counter - 1); | ||
513 | 153 | QCOMPARE(places.indexOfLocation(QDir::homePath()), -1); | ||
514 | 154 | |||
515 | 155 | //use another instance to check | ||
516 | 156 | PlacesModel places2; | ||
517 | 157 | QCOMPARE(places2.rowCount(), places_counter - 1); | ||
518 | 158 | QCOMPARE(places2.indexOfLocation(QDir::homePath()), -1); | ||
519 | 159 | //default place is in m_userRemovedLocations | ||
520 | 160 | QVERIFY(places2.m_userRemovedLocations.indexOf(QDir::homePath()) != -1); | ||
521 | 161 | } | ||
522 | 162 | |||
523 | 163 | void PlacesmodelTest::addRemovedDefaultPlace() | ||
524 | 164 | { | ||
525 | 165 | //first remove a default place | ||
526 | 166 | PlacesModel places; | ||
527 | 167 | int home_index = places.indexOfLocation(QDir::homePath()); | ||
528 | 168 | QVERIFY(home_index != -1); | ||
529 | 169 | int places_counter = places.rowCount(); | ||
530 | 170 | places.removeItem(home_index); | ||
531 | 171 | QTest::qWait(50); | ||
532 | 172 | QCOMPARE(places.rowCount(), places_counter - 1); | ||
533 | 173 | QCOMPARE(places.indexOfLocation(QDir::homePath()), -1); | ||
534 | 174 | |||
535 | 175 | //now add the default location back | ||
536 | 176 | places.addLocation(QDir::homePath()); | ||
537 | 177 | QTest::qWait(50); | ||
538 | 178 | QCOMPARE(places.rowCount(), places_counter); | ||
539 | 179 | QVERIFY(places.indexOfLocation(QDir::homePath()) != -1); | ||
540 | 180 | //it must not exist neither on m_userSavedLocations nor m_userRemovedLocations | ||
541 | 181 | QCOMPARE(places.m_userSavedLocations.indexOf(QDir::homePath()), -1); | ||
542 | 182 | QCOMPARE(places.m_userRemovedLocations.indexOf(QDir::homePath()), -1); | ||
543 | 183 | |||
544 | 184 | //check on a second instance | ||
545 | 185 | PlacesModel places2; | ||
546 | 186 | QVERIFY(places2.indexOfLocation(QDir::homePath()) != -1); | ||
547 | 187 | QCOMPARE(places2.m_userSavedLocations.indexOf(QDir::homePath()), -1); | ||
548 | 188 | QCOMPARE(places2.m_userRemovedLocations.indexOf(QDir::homePath()), -1); | ||
549 | 189 | } | ||
550 | 190 | |||
551 | 191 | QTEST_MAIN(PlacesmodelTest) | ||
552 | 192 | |||
553 | 193 | #include "placesmodeltest.moc" | ||
554 | 0 | 194 | ||
555 | === added file 'src/plugin/test_placesmodel/test_placesmodel.pro' | |||
556 | --- src/plugin/test_placesmodel/test_placesmodel.pro 1970-01-01 00:00:00 +0000 | |||
557 | +++ src/plugin/test_placesmodel/test_placesmodel.pro 2015-09-19 22:49:08 +0000 | |||
558 | @@ -0,0 +1,35 @@ | |||
559 | 1 | #------------------------------------------------- | ||
560 | 2 | # | ||
561 | 3 | # Project created by QtCreator 2015-09-05T17:37:49 | ||
562 | 4 | # | ||
563 | 5 | #------------------------------------------------- | ||
564 | 6 | |||
565 | 7 | QT += testlib | ||
566 | 8 | |||
567 | 9 | QT -= gui | ||
568 | 10 | |||
569 | 11 | TARGET = tst_placesmodeltest | ||
570 | 12 | CONFIG += console | ||
571 | 13 | CONFIG += testcase | ||
572 | 14 | CONFIG -= app_bundle | ||
573 | 15 | |||
574 | 16 | TEMPLATE = app | ||
575 | 17 | |||
576 | 18 | DEFINES += REGRESSION_TEST_PLACES_MODEL | ||
577 | 19 | |||
578 | 20 | DEFINES += SRCDIR=\\\"$$PWD/\\\" | ||
579 | 21 | |||
580 | 22 | QMAKE_CXXFLAGS += -std=c++11 | ||
581 | 23 | |||
582 | 24 | |||
583 | 25 | SOURCES += placesmodeltest.cpp \ | ||
584 | 26 | ../placesmodel/placesmodel.cpp \ | ||
585 | 27 | ../placesmodel/qmtabparser.cpp | ||
586 | 28 | |||
587 | 29 | |||
588 | 30 | HEADERS += \ | ||
589 | 31 | ../placesmodel/placesmodel.h \ | ||
590 | 32 | ../placesmodel/qmtabparser.h | ||
591 | 33 | |||
592 | 34 | |||
593 | 35 | INCLUDEPATH += ../placesmodel |
PASSED: Continuous integration, rev:460 91.189. 93.70:8080/ job/ubuntu- filemanager- app-ci/ 543/ 91.189. 93.70:8080/ job/ubuntu- filemanager- app-vivid- amd64-ci/ 165
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- filemanager- app-ci/ 543/rebuild
http://