Merge lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03 into lp:ubuntu-filemanager-app

Proposed by Carlos Jose Mazieri
Status: Merged
Approved by: Arto Jalkanen
Approved revision: 388
Merged at revision: 397
Proposed branch: lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03
Merge into: lp:ubuntu-filemanager-app
Prerequisite: lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-02
Diff against target: 1628 lines (+1015/-172)
20 files modified
src/plugin/folderlistmodel/CMakeLists.txt (+10/-2)
src/plugin/folderlistmodel/cleanurl.cpp (+73/-0)
src/plugin/folderlistmodel/cleanurl.h (+47/-0)
src/plugin/folderlistmodel/dirmodel.cpp (+7/-4)
src/plugin/folderlistmodel/dirmodel.h (+1/-0)
src/plugin/folderlistmodel/disk/disklocation.cpp (+18/-70)
src/plugin/folderlistmodel/disk/disklocation.h (+4/-4)
src/plugin/folderlistmodel/folderlistmodel.pri (+23/-21)
src/plugin/folderlistmodel/iorequest.cpp (+17/-5)
src/plugin/folderlistmodel/iorequest.h (+3/-1)
src/plugin/folderlistmodel/location.cpp (+174/-8)
src/plugin/folderlistmodel/location.h (+44/-9)
src/plugin/folderlistmodel/locationitemdiriterator.cpp (+44/-0)
src/plugin/folderlistmodel/locationitemdiriterator.h (+68/-0)
src/plugin/folderlistmodel/locationsfactory.cpp (+85/-42)
src/plugin/folderlistmodel/locationsfactory.h (+46/-4)
src/plugin/folderlistmodel/net/netauthenticationdata.cpp (+219/-0)
src/plugin/folderlistmodel/net/netauthenticationdata.h (+97/-0)
src/plugin/folderlistmodel/trash/trashlocation.cpp (+30/-2)
src/plugin/folderlistmodel/trash/trashlocation.h (+5/-0)
To merge this branch: bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03
Reviewer Review Type Date Requested Status
Arto Jalkanen Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+252219@code.launchpad.net

Commit message

Refactoring in the Location class to be more suitable for new protocols browsing implementation

Description of the change

Refactoring in the Location class to be more suitable for new protocols browsing implementation

Some pure methods from Location class now have a default implementatation.
Location class now is responsable to create other objects, added 2 pure methods:
 DirItemInfo * newItemInfo()
 DirListWorkder * newListWorker()

Added signal Location::needsAuthentication()

Added class NetAuthenticationDataList to store user/password for URLs.

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

Small typo in method name, otherwise fine.

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

> Small typo in method name, otherwise fine.

Let me know where so I can fix that.

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

> > Small typo in method name, otherwise fine.
>
> Let me know where so I can fix that.

Yeah sorry, those inlined comments are really hard to find. It's this:

bool LocationsFactory::lastUrlNeedsAuthencation() const
->
bool LocationsFactory::lastUrlNeedsAuthentication() const

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

Thanks,

That has been changed on MP 09 -> https://code.launchpad.net/~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-09/+merge/252979 which finishes authentication stuff.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/plugin/folderlistmodel/CMakeLists.txt'
2--- src/plugin/folderlistmodel/CMakeLists.txt 2014-05-02 12:22:11 +0000
3+++ src/plugin/folderlistmodel/CMakeLists.txt 2015-03-08 12:31:26 +0000
4@@ -1,7 +1,8 @@
5 include_directories(
6 ${CMAKE_CURRENT_SOURCE_DIR}
7 disk
8- trash
9+ trash
10+ net
11 )
12
13 set(PLUGIN_DIR org/nemomobile/folderlistmodel)
14@@ -40,6 +41,10 @@
15 locationsfactory.h
16 locationurl.cpp
17 locationurl.h
18+ locationitemdiriterator.cpp
19+ locationitemdiriterator.h
20+ cleanurl.cpp
21+ cleanurl.h
22 disk/disklocation.cpp
23 disk/disklocation.h
24 trash/qtrashdir.cpp
25@@ -49,7 +54,9 @@
26 trash/trashiteminfo.cpp
27 trash/trashiteminfo.h
28 trash/trashlocation.cpp
29- trash/trashlocation.h
30+ trash/trashlocation.h
31+ net/netauthenticationdata.cpp
32+ net/netauthenticationdata.h
33 )
34
35 add_library(nemofolderlistmodel MODULE
36@@ -58,6 +65,7 @@
37
38 qt5_use_modules(nemofolderlistmodel Gui Qml Quick Widgets)
39
40+
41 # Copy the plugin, the qmldir file and other assets to the build dir for running in QtCreator
42 if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
43 add_custom_command(TARGET nemofolderlistmodel POST_BUILD
44
45=== added file 'src/plugin/folderlistmodel/cleanurl.cpp'
46--- src/plugin/folderlistmodel/cleanurl.cpp 1970-01-01 00:00:00 +0000
47+++ src/plugin/folderlistmodel/cleanurl.cpp 2015-03-08 12:31:26 +0000
48@@ -0,0 +1,73 @@
49+/**************************************************************************
50+ *
51+ * Copyright 2015 Canonical Ltd.
52+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@gmail.com>
53+ *
54+ * This program is free software; you can redistribute it and/or modify
55+ * it under the terms of the GNU Lesser General Public License as published by
56+ * the Free Software Foundation; version 3.
57+ *
58+ * This program is distributed in the hope that it will be useful,
59+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
60+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61+ * GNU Lesser General Public License for more details.
62+ *
63+ * You should have received a copy of the GNU Lesser General Public License
64+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
65+ *
66+ * File: cleanurl.cpp
67+ * Date: 04/02/2015
68+ */
69+
70+#include "cleanurl.h"
71+
72+#include <QUrl>
73+
74+CleanUrl::CleanUrl(const QString &urlPath) : m_user(0), m_password(0)
75+{
76+ QUrl url(urlPath);
77+ if (url.isValid())
78+ {
79+ QString user = url.userName();
80+ if (!user.isEmpty())
81+ {
82+ m_user = new QString(user);
83+ m_password = new QString(url.password());
84+ url.setPassword(QLatin1String(0));
85+ url.setUserName(QLatin1String(0));
86+ }
87+ m_url = url.toString();
88+ }
89+ else
90+ {
91+ m_url = urlPath;
92+ }
93+}
94+
95+
96+CleanUrl::~CleanUrl()
97+{
98+ if (m_user) { delete m_user; }
99+ if (m_password) { delete m_password;}
100+}
101+
102+
103+bool CleanUrl::hasAuthenticationData() const
104+{
105+ return m_user ? true : false;
106+}
107+
108+QString CleanUrl::user() const
109+{
110+ return m_user ? *m_user : QString();
111+}
112+
113+QString CleanUrl::password() const
114+{
115+ return m_password ? *m_password : QString();
116+}
117+
118+QString CleanUrl::cleanUrl() const
119+{
120+ return m_url;
121+}
122
123=== added file 'src/plugin/folderlistmodel/cleanurl.h'
124--- src/plugin/folderlistmodel/cleanurl.h 1970-01-01 00:00:00 +0000
125+++ src/plugin/folderlistmodel/cleanurl.h 2015-03-08 12:31:26 +0000
126@@ -0,0 +1,47 @@
127+/**************************************************************************
128+ *
129+ * Copyright 2015 Canonical Ltd.
130+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@gmail.com>
131+ *
132+ * This program is free software; you can redistribute it and/or modify
133+ * it under the terms of the GNU Lesser General Public License as published by
134+ * the Free Software Foundation; version 3.
135+ *
136+ * This program is distributed in the hope that it will be useful,
137+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
138+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
139+ * GNU Lesser General Public License for more details.
140+ *
141+ * You should have received a copy of the GNU Lesser General Public License
142+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
143+ *
144+ * File: cleanurl.h
145+ * Date: 04/02/2015
146+ */
147+
148+#ifndef CLEANURL_H
149+#define CLEANURL_H
150+
151+#include <QString>
152+
153+/*!
154+ * \brief The CleanUrl class
155+ *
156+ * Just returns a URL without user/password if exists
157+ */
158+class CleanUrl
159+{
160+public:
161+ CleanUrl(const QString &urlPath);
162+ ~CleanUrl();
163+ bool hasAuthenticationData() const;
164+ QString cleanUrl() const;
165+ QString user() const;
166+ QString password() const;
167+private:
168+ QString m_url; //!< keeps the url without user/password
169+ QString * m_user;
170+ QString * m_password;
171+};
172+
173+#endif // CLEANURL_H
174
175=== modified file 'src/plugin/folderlistmodel/dirmodel.cpp'
176--- src/plugin/folderlistmodel/dirmodel.cpp 2015-03-08 12:31:26 +0000
177+++ src/plugin/folderlistmodel/dirmodel.cpp 2015-03-08 12:31:26 +0000
178@@ -218,10 +218,11 @@
179 roles.insert(FilePathRole, QByteArray("filePath"));
180 roles.insert(IsDirRole, QByteArray("isDir"));
181 roles.insert(IsHostRole, QByteArray("isHost"));
182- roles.insert(IsSmbWorkgroupRole, QByteArray("IsSmbWorkgroup"));
183- roles.insert(IsSmbShareRole, QByteArray("IsSmbShare"));
184- roles.insert(IsSharedDirRole, QByteArray("IsSharedDir"));
185- roles.insert(IsSharingAllowedRole, QByteArray("IsSharingAllowed"));
186+ roles.insert(IsSmbWorkgroupRole, QByteArray("isSmbWorkgroup"));
187+ roles.insert(IsSmbShareRole, QByteArray("isSmbShare"));
188+ roles.insert(IsSharedDirRole, QByteArray("isSharedDir"));
189+ roles.insert(IsSharingAllowedRole, QByteArray("isSharingAllowed"));
190+ roles.insert(IsBrowsableRole, QByteArray("isBrowsable"));
191 roles.insert(IsFileRole, QByteArray("isFile"));
192 roles.insert(IsReadableRole, QByteArray("isReadable"));
193 roles.insert(IsWritableRole, QByteArray("isWritable"));
194@@ -383,6 +384,8 @@
195 return fi.isWorkGroup();
196 case IsSmbShareRole:
197 return fi.isShare();
198+ case IsBrowsableRole:
199+ return fi.isBrowsable();
200 case IsSharingAllowedRole:
201 return fi.isDir() && !fi.isSymLink() && !fi.isSharedDir()
202 && mCurLocation->type() == LocationsFactory::LocalDisk
203
204=== modified file 'src/plugin/folderlistmodel/dirmodel.h'
205--- src/plugin/folderlistmodel/dirmodel.h 2015-03-08 12:31:26 +0000
206+++ src/plugin/folderlistmodel/dirmodel.h 2015-03-08 12:31:26 +0000
207@@ -67,6 +67,7 @@
208 IsSmbShareRole,
209 IsSharedDirRole, //!< it can also be used for other protocols than smb/cifs
210 IsSharingAllowedRole,//!< true for local directories (not in Trash) and not IsSharedDirRole
211+ IsBrowsableRole, //!< any Dir, Host, WorkGroup or Share
212 IsFileRole,
213 IsReadableRole,
214 IsWritableRole,
215
216=== modified file 'src/plugin/folderlistmodel/disk/disklocation.cpp'
217--- src/plugin/folderlistmodel/disk/disklocation.cpp 2014-05-14 22:51:47 +0000
218+++ src/plugin/folderlistmodel/disk/disklocation.cpp 2015-03-08 12:31:26 +0000
219@@ -46,49 +46,6 @@
220 }
221
222
223-void DiskLocation::fetchItems(QDir::Filter dirFilter, bool recursive)
224-{
225- DirListWorker *dlw = new DirListWorker(m_info->absoluteFilePath(), dirFilter, recursive);
226- connect(dlw, SIGNAL(itemsAdded(DirItemInfoList)),
227- this, SIGNAL(itemsAdded(DirItemInfoList)));
228- connect(dlw, SIGNAL(workerFinished()),
229- this, SLOT(onItemsFetched()));
230- workerThread()->addRequest(dlw);
231-}
232-
233-
234-bool DiskLocation::becomeParent()
235-{
236- bool ret = false;
237- if (m_info && !m_info->isRoot())
238- {
239- DirItemInfo *other = new DirItemInfo(m_info->absolutePath());
240- if (other->isValid())
241- {
242- delete m_info;
243- m_info = other;
244- ret = true;
245- }
246- else
247- {
248- delete other;
249- }
250- }
251- return ret;
252-}
253-
254-
255-void DiskLocation::refreshInfo()
256-{
257- if (m_info)
258- {
259- DirItemInfo *item = new DirItemInfo(m_info->absoluteFilePath());
260- delete m_info;
261- m_info = item;
262- }
263-}
264-
265-
266 /*!
267 * \brief DiskLocation::stopExternalFsWatcher() stops the External File System Watcher
268 */
269@@ -115,11 +72,12 @@
270 m_extWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL);
271
272 connect(m_extWatcher, SIGNAL(pathModified(QString)),
273- this, SIGNAL(extWatcherPathChanged(QString)));
274- if (m_info)
275- { //setCurrentPath() checks for empty paths
276+ this, SIGNAL(extWatcherPathChanged(QString)));
277+ }
278+ if (m_extWatcher && m_info)
279+ {
280+ //setCurrentPath() checks for empty paths
281 m_extWatcher->setCurrentPath(m_info->absoluteFilePath());
282- }
283 }
284 }
285
286@@ -187,9 +145,8 @@
287
288
289 void DiskLocation::setUsingExternalWatcher(bool use)
290-{
291- Location::setUsingExternalWatcher(use);
292- if (m_usingExternalWatcher)
293+{
294+ if ((m_usingExternalWatcher = use))
295 {
296 startExternalFsWatcher();
297 }
298@@ -200,23 +157,14 @@
299 }
300
301
302-DirItemInfo * DiskLocation::validateUrlPath(const QString& uPath)
303-{
304- QString myPath(uPath);
305- QFileInfo tmpUrl(uPath);
306- if (tmpUrl.isRelative() && m_info)
307- {
308- tmpUrl.setFile(m_info->absoluteFilePath(), uPath);
309- myPath = tmpUrl.absoluteFilePath();
310- }
311-#if DEBUG_MESSAGES
312- qDebug() << Q_FUNC_INFO << "path:" << myPath;
313-#endif
314- DirItemInfo * item = new DirItemInfo(myPath);
315- if (!item->isValid() || !item->exists() || !item->isContentReadable())
316- {
317- delete item;
318- item = 0;
319- }
320- return item;
321-}
322+DirItemInfo * DiskLocation::newItemInfo(const QString &urlPath)
323+{
324+ return new DirItemInfo(urlPath);
325+}
326+
327+
328+DirListWorker * DiskLocation::newListWorker(const QString &urlPath, QDir::Filter filter, const bool isRecursive)
329+{
330+ return new DirListWorker(urlPath,filter,isRecursive);
331+}
332+
333
334=== modified file 'src/plugin/folderlistmodel/disk/disklocation.h'
335--- src/plugin/folderlistmodel/disk/disklocation.h 2014-05-14 22:51:47 +0000
336+++ src/plugin/folderlistmodel/disk/disklocation.h 2015-03-08 12:31:26 +0000
337@@ -49,12 +49,9 @@
338
339 ExternalFSWatcher * getExternalFSWatcher() const;
340
341- virtual void fetchItems(QDir::Filter dirFilter, bool recursive = false) ;
342 virtual void fetchExternalChanges(const QString& urlPath,
343 const DirItemInfoList& list,
344 QDir::Filter dirFilter) ;
345- virtual bool becomeParent();
346- virtual void refreshInfo();
347
348 virtual void startExternalFsWatcher();
349 virtual void stopExternalFsWatcher();
350@@ -62,7 +59,10 @@
351 virtual void startWorking();
352 virtual void stopWorking();
353
354- virtual DirItemInfo *validateUrlPath(const QString& urlPath);
355+ virtual DirItemInfo * newItemInfo(const QString& urlPath);
356+ virtual DirListWorker * newListWorker(const QString &urlPath,
357+ QDir::Filter filter,
358+ const bool isRecursive);
359
360 protected:
361 void addExternalFsWorkerRequest(ExternalFileSystemChangesWorker *);
362
363=== modified file 'src/plugin/folderlistmodel/folderlistmodel.pri'
364--- src/plugin/folderlistmodel/folderlistmodel.pri 2014-05-02 12:22:11 +0000
365+++ src/plugin/folderlistmodel/folderlistmodel.pri 2015-03-08 12:31:26 +0000
366@@ -8,16 +8,12 @@
367 $$PWD/clipboard.cpp \
368 $$PWD/fmutil.cpp \
369 $$PWD/dirselection.cpp \
370- $$PWD/diriteminfo.cpp \
371- $$PWD/trash/qtrashdir.cpp \
372- $$PWD/trash/trashiteminfo.cpp \
373+ $$PWD/diriteminfo.cpp \
374 $$PWD/location.cpp \
375- $$PWD/locationsfactory.cpp \
376- $$PWD/disk/disklocation.cpp \
377- $$PWD/trash/trashlocation.cpp \
378- $$PWD/locationurl.cpp \
379- $$PWD/trash/qtrashutilinfo.cpp
380-
381+ $$PWD/locationsfactory.cpp \
382+ $$PWD/locationurl.cpp \
383+ $$PWD/locationitemdiriterator.cpp \
384+ $$PWD/cleanurl.cpp
385
386 HEADERS += $$PWD/dirmodel.h \
387 $$PWD/iorequest.h \
388@@ -29,19 +25,25 @@
389 $$PWD/clipboard.h \
390 $$PWD/fmutil.h \
391 $$PWD/dirselection.h \
392- $$PWD/diritemabstractlistmodel.h \
393- $$PWD/diriteminfo.h \
394- $$PWD/trash/qtrashdir.h \
395- $$PWD/trash/trashiteminfo.h \
396+ $$PWD/diritemabstractlistmodel.h \
397 $$PWD/location.h \
398- $$PWD/locationsfactory.h \
399- $$PWD/disk/disklocation.h \
400- $$PWD/trash/trashlocation.h \
401- $$PWD/locationurl.h \
402- $$PWD/trash/qtrashutilinfo.h
403-
404-
405-INCLUDEPATH += $$PWD $$PWD/trash $$PWD/disk
406+ $$PWD/locationsfactory.h \
407+ $$PWD/locationurl.h \
408+ $$PWD/locationitemdiriterator.h \
409+ $$PWD/cleanurl.h
410+
411+SOURCES += $$PWD/disk/disklocation.cpp
412+HEADERS += $$PWD/disk/disklocation.h
413+
414+SOURCES += $$PWD/trash/qtrashdir.cpp $$PWD/trash/trashiteminfo.cpp \
415+ $$PWD/trash/qtrashutilinfo.cpp $$PWD/trash/trashlocation.cpp
416+HEADERS += $$PWD/trash/qtrashdir.h $$PWD/trash/trashiteminfo.h \
417+ $$PWD/trash/qtrashutilinfo.h $$PWD/trash/trashlocation.h
418+
419+SOURCES += $$PWD/net/netauthenticationdata.cpp
420+HEADERS += $$PWD/net/netauthenticationdata.h
421+
422+INCLUDEPATH += $$PWD $$PWD/trash $$PWD/disk $$PWD/net
423
424 greaterThan(QT_MAJOR_VERSION, 4) {
425 QT += qml
426
427=== modified file 'src/plugin/folderlistmodel/iorequest.cpp'
428--- src/plugin/folderlistmodel/iorequest.cpp 2014-12-30 18:23:15 +0000
429+++ src/plugin/folderlistmodel/iorequest.cpp 2015-03-08 12:31:26 +0000
430@@ -89,9 +89,14 @@
431
432 DirItemInfoList IORequestLoader::getContents()
433 {
434- return mLoaderType == NormalLoader ?
435- getNormalContent() :
436- getTrashContent();
437+ DirItemInfoList list;
438+ switch(mLoaderType)
439+ {
440+ case NormalLoader: list = getNormalContent(); break;
441+ case TrashLoader: list = getTrashContent(); break;
442+ case NetworkLoader: list = getNetworkContent(); break;
443+ }
444+ return list;
445 }
446
447 DirItemInfoList IORequestLoader::getNormalContent()
448@@ -112,8 +117,7 @@
449 {
450 QDir tmpDir = QDir(pathName, QString(), QDir::NoSort, filter);
451 QDirIterator it(tmpDir);
452- while (it.hasNext())
453- {
454+ while (it.hasNext()) {
455 it.next();
456 if(it.fileInfo().isDir() && isRecursive) {
457 directoryContents = add(it.fileInfo().filePath(),
458@@ -150,6 +154,14 @@
459 }
460
461
462+DirItemInfoList IORequestLoader::getNetworkContent()
463+{
464+ DirItemInfoList emptyContent;
465+ return emptyContent;
466+}
467+
468+
469+
470 //-----------------------------------------------------------------------------------------------
471 DirListWorker::DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive)
472 : IORequestLoader(pathName, filter, isRecursive)
473
474=== modified file 'src/plugin/folderlistmodel/iorequest.h'
475--- src/plugin/folderlistmodel/iorequest.h 2014-05-15 00:18:54 +0000
476+++ src/plugin/folderlistmodel/iorequest.h 2015-03-08 12:31:26 +0000
477@@ -70,7 +70,8 @@
478 enum LoaderType
479 {
480 NormalLoader,
481- TrashLoader
482+ TrashLoader,
483+ NetworkLoader
484 };
485
486 IORequestLoader( const QString &pathName,
487@@ -91,6 +92,7 @@
488 private:
489 DirItemInfoList getNormalContent();
490 DirItemInfoList getTrashContent();
491+ virtual DirItemInfoList getNetworkContent();
492 DirItemInfoList add(const QString &pathName, QDir::Filter filter,
493 bool isRecursive, DirItemInfoList directoryContents);
494 protected:
495
496=== modified file 'src/plugin/folderlistmodel/location.cpp'
497--- src/plugin/folderlistmodel/location.cpp 2014-05-14 22:51:47 +0000
498+++ src/plugin/folderlistmodel/location.cpp 2015-03-08 12:31:26 +0000
499@@ -41,6 +41,7 @@
500
501 #include "location.h"
502 #include "ioworkerthread.h"
503+#include "netauthenticationdata.h"
504
505 Q_GLOBAL_STATIC(IOWorkerThread, ioWorkerThread)
506
507@@ -72,7 +73,7 @@
508
509 bool Location::isWritable() const
510 {
511- return m_info->isWritable();
512+ return m_info ? m_info->isWritable() : false;
513 }
514
515
516@@ -112,10 +113,6 @@
517
518 }
519
520-bool Location::becomeParent()
521-{
522- return false;
523-}
524
525 IOWorkerThread * Location::workerThread() const
526 {
527@@ -133,8 +130,177 @@
528 Q_UNUSED(dirFilter);
529 }
530
531-
532+//======================================================================================================
533+/*!
534+ * \brief Location::setUsingExternalWatcher() Default implementation sets nothing
535+ *
536+ * It considers that there is no external Watcher
537+ * \param use
538+ */
539 void Location::setUsingExternalWatcher(bool use)
540 {
541- m_usingExternalWatcher = use;
542-}
543+ Q_UNUSED(use)
544+ m_usingExternalWatcher = false;
545+}
546+
547+
548+/*!
549+ * \brief Location::setAuthentication()
550+ *
551+ * Default implementation does nothing as local disk does not need it
552+ *
553+ * Network Locations need to reimplement this
554+ *
555+ * \param user
556+ * \param password
557+ */
558+void Location::setAuthentication(const QString &user,
559+ const QString &password)
560+
561+{
562+ Q_UNUSED(user);
563+ Q_UNUSED(password);
564+}
565+
566+/*!
567+ * \brief Location::currentAuthenticationUser()
568+ *
569+ * Default implementation returns current user
570+ *
571+ * \return
572+ */
573+QString Location::currentAuthenticationUser()
574+{
575+ return QString(::qgetenv("USER"));
576+}
577+
578+/*!
579+ * \brief Location::currentAuthenticationPassword()
580+ *
581+ * Default implementation returns empty string
582+ *
583+ * \return
584+ */
585+QString Location::currentAuthenticationPassword()
586+{
587+ return QString();
588+}
589+
590+/*!
591+ * \brief Location::notifyItemNeedsAuthentication()
592+ * \param item
593+ *
594+ * \note
595+ * The connection between Location objects and the \class DirModel is Qt::QueuedConnection
596+ * It allows a UI to continuosly show dialogs asking the user to provide User and Password
597+ * to authenticate the current URL
598+ */
599+void Location::notifyItemNeedsAuthentication(const DirItemInfo *item)
600+{
601+ if (item == 0)
602+ {
603+ item = m_info;
604+ }
605+ if (item != 0)
606+ {
607+ emit needsAuthentication(currentAuthenticationUser(), item->urlPath());
608+ }
609+}
610+
611+
612+
613+bool Location::useAuthenticationDataIfExists(const DirItemInfo& item)
614+{
615+ NetAuthenticationDataList *authData = NetAuthenticationDataList::getInstance(this);
616+ const NetAuthenticationData *auth = authData->get(item.authenticationPath());
617+ bool ret = false;
618+ if (auth && !( auth->user == currentAuthenticationUser()
619+ && auth->password == currentAuthenticationPassword()
620+ )
621+ )
622+ {
623+ setAuthentication(auth->user, auth->password);
624+ ret = true;
625+ }
626+ NetAuthenticationDataList::releaseInstance(this);
627+ return ret;
628+}
629+
630+
631+
632+void Location::refreshInfo()
633+{
634+ if (m_info)
635+ {
636+ DirItemInfo *item = newItemInfo(m_info->absoluteFilePath());
637+ delete m_info;
638+ m_info = item;
639+ }
640+}
641+
642+
643+bool Location::becomeParent()
644+{
645+ bool ret = false;
646+ if (m_info && !m_info->isRoot())
647+ {
648+ DirItemInfo *other = newItemInfo(m_info->absolutePath());
649+ if (other->isValid())
650+ {
651+ delete m_info;
652+ m_info = other;
653+ ret = true;
654+ }
655+ else
656+ {
657+ delete other;
658+ }
659+ }
660+ return ret;
661+}
662+
663+
664+DirItemInfo * Location::validateUrlPath(const QString & uPath)
665+{
666+ QString myPath(uPath);
667+ DirItemInfo * item = newItemInfo(myPath);
668+ if (item->isRelative() && m_info)
669+ {
670+ item->setFile(m_info->urlPath(), uPath);
671+ myPath = item->urlPath();
672+ }
673+
674+#if DEBUG_MESSAGES
675+ qDebug() << Q_FUNC_INFO << "path:" << myPath << "needsAuthentication:" << item->needsAuthentication();
676+#endif
677+
678+ // the isContentReadable() is not checked here
679+ // because it will be false when authentication is required
680+ if (!item->isValid() || !item->exists())
681+ {
682+ delete item;
683+ item = 0;
684+ }
685+ return item;
686+}
687+
688+
689+void Location::fetchItems(QDir::Filter dirFilter, bool recursive)
690+{
691+ //it should never happen here
692+ if (m_info->needsAuthentication())
693+ {
694+ emit needsAuthentication(currentAuthenticationUser(), m_info->absoluteFilePath());
695+ }
696+ else
697+ {
698+ DirListWorker *dlw = newListWorker(m_info->absoluteFilePath(), dirFilter, recursive);
699+ connect(dlw, SIGNAL(itemsAdded(DirItemInfoList)),
700+ this, SIGNAL(itemsAdded(DirItemInfoList)));
701+ connect(dlw, SIGNAL(workerFinished()),
702+ this, SIGNAL(itemsFetched()));
703+ workerThread()->addRequest(dlw);
704+ }
705+}
706+
707+
708
709=== modified file 'src/plugin/folderlistmodel/location.h'
710--- src/plugin/folderlistmodel/location.h 2014-05-14 22:51:47 +0000
711+++ src/plugin/folderlistmodel/location.h 2015-03-08 12:31:26 +0000
712@@ -27,6 +27,7 @@
713 #include <QObject>
714
715 class IOWorkerThread;
716+class DirListWorker;
717
718 /*!
719 * \brief The Location class represents any location (full path) where there are items to browse: directories, shares, from Disk and from Network.
720@@ -45,9 +46,10 @@
721 class Location : public QObject
722 {
723 Q_OBJECT
724-public:
725+public:
726+ virtual ~Location();
727+protected:
728 explicit Location( int type, QObject *parent=0);
729- virtual ~Location();
730
731 IOWorkerThread * workerThread() const;
732
733@@ -59,18 +61,44 @@
734 void extWatcherItemChanged(const DirItemInfo&);
735 void extWatcherItemAdded(const DirItemInfo&);
736 void extWatcherChangesFetched(int);
737+ void needsAuthentication(const QString& user, const QString& urlPath);
738
739 public slots:
740 virtual void setUsingExternalWatcher(bool use);
741+ virtual void setAuthentication(const QString& user,
742+ const QString& password);
743+
744
745 public: //pure functions
746 /*!
747+ * \brief newItemInfo() returns a Location suitable DirItemInfo object
748+ *
749+ * Every Locations must create its own DirItemInfo object with all the information set
750+ * \param urlPath it can also contain User and Password when in the form of an URL
751+ * \return the object created
752+ */
753+ virtual DirItemInfo * newItemInfo(const QString& urlPath) = 0;
754+
755+ /*!
756+ * \brief newListWorker() creates a Location suitable DirListWorker object which will create a new \ref DirItemInfoList for browsing items
757+ *
758+ * The DirListWorker object will be used in \ref fetchItems()
759+ *
760+ * \param urlPath urlPath it can also contain User and Password when in the form of an URL
761+ * \param filter
762+ * \param isRecursive
763+ * \return the object which will fill a new \ref DirItemInfoList for browsing items
764+ */
765+ virtual DirListWorker * newListWorker(const QString &urlPath, QDir::Filter filter, const bool isRecursive) = 0;
766+
767+public:
768+ /*!
769 * \brief fetchItems() gets the content of the Location
770 *
771 * \param dirFilter current Filter
772 * \param recursive should get the content all sub dirs or not, (hardly ever it is true)
773 */
774- virtual void fetchItems(QDir::Filter dirFilter, bool recursive=0) = 0;
775+ virtual void fetchItems(QDir::Filter dirFilter, bool recursive=false);
776
777 /*!
778 * \brief refreshInfo() It must refresh the DirItemInfo
779@@ -78,9 +106,9 @@
780 * It can be used for example after receiving the signal about external disk file system changes
781 * due to the current path permissions might have changed.
782 */
783- virtual void refreshInfo() = 0;
784+ virtual void refreshInfo();
785
786- /*!
787+ /*!
788 * \brief becomeParent() The current path location becomes the parent Location
789 *
790 * When \ref isRoot() returns false the current path location becomes the parent path location
791@@ -91,7 +119,7 @@
792 *
793 * \return true if it is possible to do like a cdUp.
794 */
795- virtual bool becomeParent() = 0;
796+ virtual bool becomeParent();
797
798 /*!
799 * \brief validateUrlPath() Validates the urlPath (file or Directory) and creates a new Obeject from this path
800@@ -101,9 +129,10 @@
801 * \param urlPath
802 * \return a valid pointer to DirItemInfo object or NULL indicating something wrong with the path
803 */
804- virtual DirItemInfo * validateUrlPath(const QString& urlPath) = 0;
805-
806-public:
807+ virtual DirItemInfo * validateUrlPath(const QString& urlPath);
808+
809+
810+public: //virtual
811 virtual void fetchExternalChanges(const QString& urlPath,
812 const DirItemInfoList& list,
813 QDir::Filter dirFilter) ;
814@@ -115,6 +144,12 @@
815 virtual QString urlPath() const;
816 virtual void startWorking();
817 virtual void stopWorking();
818+ virtual QString currentAuthenticationUser();
819+ virtual QString currentAuthenticationPassword();
820+
821+public: //non virtual
822+ void notifyItemNeedsAuthentication(const DirItemInfo *item = 0);
823+ bool useAuthenticationDataIfExists(const DirItemInfo &item);
824
825 inline const DirItemInfo* info() const { return m_info; }
826 inline int type() const { return m_type; }
827
828=== added file 'src/plugin/folderlistmodel/locationitemdiriterator.cpp'
829--- src/plugin/folderlistmodel/locationitemdiriterator.cpp 1970-01-01 00:00:00 +0000
830+++ src/plugin/folderlistmodel/locationitemdiriterator.cpp 2015-03-08 12:31:26 +0000
831@@ -0,0 +1,44 @@
832+/**************************************************************************
833+ *
834+ * Copyright 2015 Canonical Ltd.
835+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@gmail.com>
836+ *
837+ * This program is free software; you can redistribute it and/or modify
838+ * it under the terms of the GNU Lesser General Public License as published by
839+ * the Free Software Foundation; version 3.
840+ *
841+ * This program is distributed in the hope that it will be useful,
842+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
843+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
844+ * GNU Lesser General Public License for more details.
845+ *
846+ * You should have received a copy of the GNU Lesser General Public License
847+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
848+ *
849+ * File: locationitemdiriterator.cpp
850+ * Date: 10/01/2015
851+ */
852+
853+#include "locationitemdiriterator.h"
854+
855+LocationItemDirIterator::LocationItemDirIterator(const QString &, const QStringList &, QDir::Filters, QDirIterator::IteratorFlags )
856+{
857+}
858+
859+
860+LocationItemDirIterator::LocationItemDirIterator(const QString &, QDir::Filters , QDirIterator::IteratorFlags)
861+{
862+
863+}
864+
865+LocationItemDirIterator::LocationItemDirIterator(const QString &, QDirIterator::IteratorFlags )
866+{
867+
868+}
869+
870+LocationItemDirIterator::~LocationItemDirIterator()
871+{
872+
873+}
874+
875+
876
877=== added file 'src/plugin/folderlistmodel/locationitemdiriterator.h'
878--- src/plugin/folderlistmodel/locationitemdiriterator.h 1970-01-01 00:00:00 +0000
879+++ src/plugin/folderlistmodel/locationitemdiriterator.h 2015-03-08 12:31:26 +0000
880@@ -0,0 +1,68 @@
881+/**************************************************************************
882+ *
883+ * Copyright 2015 Canonical Ltd.
884+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@gmail.com>
885+ *
886+ * This program is free software; you can redistribute it and/or modify
887+ * it under the terms of the GNU Lesser General Public License as published by
888+ * the Free Software Foundation; version 3.
889+ *
890+ * This program is distributed in the hope that it will be useful,
891+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
892+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
893+ * GNU Lesser General Public License for more details.
894+ *
895+ * You should have received a copy of the GNU Lesser General Public License
896+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
897+ *
898+ * File: locationitemdiriterator.h
899+ * Date: 10/01/2015
900+ */
901+
902+#ifndef LOCATIONITEMDIRITERATOR_H
903+#define LOCATIONITEMDIRITERATOR_H
904+
905+#include <QDirIterator>
906+#include "diriteminfo.h"
907+
908+/*!
909+ * \brief The LocationItemDirIterator class is an abstract similar to Qt QDirIterator
910+ *
911+ * Different protocols supported by filemanager (different Locations) must provide a class like that.
912+ */
913+
914+class LocationItemDirIterator
915+{
916+public:
917+ virtual ~LocationItemDirIterator();
918+public:
919+ virtual bool hasNext() const = 0;
920+ virtual QString next() = 0;
921+
922+ virtual DirItemInfo fileInfo() const = 0;
923+ /*!
924+ * \brief fileName()
925+ * \return the file name for the current directory entry, without the path prepended.
926+ */
927+ virtual QString fileName() const = 0;
928+
929+ /*!
930+ * \brief filePath()
931+ * \return the full pathname of the current item
932+ */
933+ virtual QString filePath() const = 0;
934+
935+ /*!
936+ * \brief path()
937+ * \return the base directory of the iterator path (not the current item)
938+ */
939+ virtual QString path() const = 0;
940+
941+protected:
942+ LocationItemDirIterator(const QString & path, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
943+ LocationItemDirIterator(const QString & path, QDir::Filters filters, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
944+ LocationItemDirIterator(const QString & path, const QStringList & nameFilters, QDir::Filters filters = QDir::NoFilter, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
945+};
946+
947+
948+#endif // LOCATIONITEMDIRITERATOR_H
949
950=== modified file 'src/plugin/folderlistmodel/locationsfactory.cpp'
951--- src/plugin/folderlistmodel/locationsfactory.cpp 2014-06-25 22:54:59 +0000
952+++ src/plugin/folderlistmodel/locationsfactory.cpp 2015-03-08 12:31:26 +0000
953@@ -26,22 +26,33 @@
954 #include "disklocation.h"
955 #include "trashlocation.h"
956 #include "trashiteminfo.h"
957+#include "cleanurl.h"
958+#include "netauthenticationdata.h"
959
960 #include <QDir>
961 #include <QDebug>
962
963
964-
965+/*!
966+ * \brief LocationsFactory::LocationsFactory()
967+ * \param parent
968+ *
969+ * Locations emit needsAuthentication() signal, the connection
970+ * with LocationsFactory is Direct, but the connection between
971+ * the Location and the \ref DirModel is Queued
972+ * \sa Location::notifyItemNeedsAuthentication()
973+ */
974 LocationsFactory::LocationsFactory(QObject *parent)
975 : QObject(parent)
976 , m_curLoc(0)
977 , m_lastValidFileInfo(0)
978+ , m_authDataStore(NetAuthenticationDataList::getInstance(this))
979+ , m_lastUrlNeedsAuthentication(false)
980 {
981 m_locations.append(new DiskLocation(LocalDisk));
982 m_locations.append(new TrashLocation(TrashDisk));
983 }
984
985-
986 LocationsFactory::~LocationsFactory()
987 {
988 ::qDeleteAll(m_locations);
989@@ -50,6 +61,7 @@
990 {
991 delete m_lastValidFileInfo;
992 }
993+ NetAuthenticationDataList::releaseInstance(this);
994 }
995
996
997@@ -72,20 +84,20 @@
998 if (uPath.startsWith(LocationUrl::TrashRootURL.midRef(0,6)))
999 {
1000 type = TrashDisk;
1001- m_tmpPath = LocationUrl::TrashRootURL + stringAfterSlashes(uPath, index+1);
1002+ m_tmpPath = LocationUrl::TrashRootURL + DirItemInfo::removeExtraSlashes(uPath, index+1);
1003 }
1004 else
1005 #endif //Q_OS_UNIX
1006-#endif //Q_OS_UNIX
1007+#endif
1008 if (uPath.startsWith(LocationUrl::DiskRootURL.midRef(0,5)))
1009 {
1010 type = LocalDisk;
1011- m_tmpPath = QDir::rootPath() + stringAfterSlashes(uPath, index+1);
1012+ m_tmpPath = QDir::rootPath() + DirItemInfo::removeExtraSlashes(uPath, index+1);
1013 }
1014 }
1015 else
1016 {
1017- m_tmpPath = stringAfterSlashes(uPath, -1);
1018+ m_tmpPath = DirItemInfo::removeExtraSlashes(uPath, -1);
1019 type = LocalDisk;
1020 if (!m_tmpPath.startsWith(QDir::rootPath()) && m_curLoc)
1021 {
1022@@ -104,17 +116,34 @@
1023 }
1024
1025
1026-Location * LocationsFactory::setNewPath(const QString& uPath)
1027+Location * LocationsFactory::setNewPath(const QString& uPath, const QString& authUser, const QString& passwd, bool savePassword)
1028 {
1029 storeValidFileInfo(0);
1030- Location *location = parse(uPath);
1031+ CleanUrl url(uPath);
1032+ m_lastUrlNeedsAuthentication = false;
1033+ NetAuthenticationData authData(authUser, passwd);
1034+ if (authData.isEmpty() && url.hasAuthenticationData())
1035+ {
1036+ authData.user = url.user();
1037+ authData.password = url.password();
1038+ }
1039+ Location *location = parse(url.cleanUrl());
1040 if (location)
1041 {
1042- DirItemInfo *item = location->validateUrlPath(m_tmpPath);
1043+ DirItemInfo *item = validateCurrentUrl(location,authData);
1044 if (item)
1045 {
1046+ //now if there is Authentication Data
1047+ //at this point item is ready and authentication if necessary worked
1048+ if (item && !authData.isEmpty())
1049+ {
1050+ m_authDataStore->store(item->authenticationPath(),
1051+ authData.user,
1052+ authData.password,
1053+ savePassword);
1054+ }
1055 //isContentReadable() must already carry execution permission
1056- if (item->isValid() && item->isDir() && item->isContentReadable())
1057+ if (item->isValid() && item->isBrowsable() && item->isContentReadable())
1058 {
1059 location->setInfoItem(item);
1060 if (location != m_curLoc)
1061@@ -146,38 +175,6 @@
1062 }
1063
1064
1065-QString LocationsFactory::stringAfterSlashes(const QString &url, int firstSlashIndex) const
1066-{
1067- QString ret;
1068- if (firstSlashIndex >=0)
1069- {
1070- while ( firstSlashIndex < url.length() && url.at(firstSlashIndex) == QDir::separator())
1071- {
1072- ++firstSlashIndex;
1073- }
1074- if (firstSlashIndex < url.length())
1075- {
1076- ret = url.mid(firstSlashIndex);
1077- }
1078- }
1079- else
1080- {
1081- ret = url;
1082- firstSlashIndex = 0;
1083- }
1084- //replace any double slashes by just one
1085- for(int charCounter = ret.size() -1; charCounter > 0; --charCounter)
1086- {
1087- if (ret.at(charCounter) == QDir::separator() &&
1088- ret.at(charCounter-1) == QDir::separator())
1089- {
1090- ret.remove(charCounter,1);
1091- }
1092- }
1093- return ret;
1094-}
1095-
1096-
1097 void LocationsFactory::storeValidFileInfo(DirItemInfo *item)
1098 {
1099 if (m_lastValidFileInfo)
1100@@ -186,3 +183,49 @@
1101 }
1102 m_lastValidFileInfo = item;
1103 }
1104+
1105+
1106+void LocationsFactory::onUrlNeedsAuthentication(QString, QString)
1107+{
1108+ m_lastUrlNeedsAuthentication = true;
1109+}
1110+
1111+
1112+bool LocationsFactory::lastUrlNeedsAuthencation() const
1113+{
1114+ return m_lastUrlNeedsAuthentication;
1115+}
1116+
1117+
1118+DirItemInfo * LocationsFactory::validateCurrentUrl(Location *location, const NetAuthenticationData &authData)
1119+{
1120+ //when there is authentication data, set the authentication before validating an item
1121+ if (!authData.isEmpty())
1122+ {
1123+ location->setAuthentication(authData.user, authData.password);
1124+ }
1125+
1126+ DirItemInfo *item = location->validateUrlPath(m_tmpPath);
1127+
1128+ //for remote locations, authentication might have failed
1129+ //if so try to use a stored authentication data and authenticate it again
1130+ if ( item && item->needsAuthentication()
1131+ && location->useAuthenticationDataIfExists(*item))
1132+ {
1133+ delete item;
1134+ item = location->validateUrlPath(m_tmpPath);
1135+ }
1136+ //if failed it is necessary to ask the user to provide user/password
1137+ if ( item && item->needsAuthentication() )
1138+ {
1139+ location->notifyItemNeedsAuthentication(item);
1140+ delete item;
1141+ item = 0;
1142+ }
1143+ if (item && !item->isContentReadable())
1144+ {
1145+ delete item;
1146+ item = 0;
1147+ }
1148+ return item;
1149+}
1150
1151=== modified file 'src/plugin/folderlistmodel/locationsfactory.h'
1152--- src/plugin/folderlistmodel/locationsfactory.h 2014-05-24 01:40:01 +0000
1153+++ src/plugin/folderlistmodel/locationsfactory.h 2015-03-08 12:31:26 +0000
1154@@ -28,6 +28,8 @@
1155
1156 class Location;
1157 class DirItemInfo;
1158+class NetAuthenticationDataList;
1159+class NetAuthenticationData;
1160
1161 /*!
1162 * \brief The LocationsFactory class represents the set of main
1163@@ -82,11 +84,17 @@
1164 * When the location changes, the signal \ref locationChanged() is fired.
1165 *
1166 * \param urlPath the url like: file:///Item trash:///item /item, it MUST point to a valid Directory
1167+ * \param user an user when the URL requires authentication [optional]
1168+ * \param password when the URL requires authentication [optional]
1169+ *
1170 * \return the location that supports the urlPath or NULL when \a urlPath is NOT a valid url or it is not a valid Directory
1171 *
1172 * \sa \ref parse() \ref location()
1173 */
1174- Location * setNewPath(const QString& urlPath);
1175+ Location * setNewPath(const QString& urlPath,
1176+ const QString& user = QString(),
1177+ const QString& password = QString(),
1178+ bool savePassword = false);
1179
1180 /*!
1181 * \brief location()
1182@@ -113,19 +121,53 @@
1183 */
1184 const DirItemInfo* lastValidFileInfo() const { return m_lastValidFileInfo; }
1185
1186+ /*!
1187+ * \brief lastUrlNeedsAuthencation()
1188+ * \return true when last URL used in setNewPath() needs authentication
1189+ *
1190+ * It can be used to show a dialog to the user asking for user/password
1191+ * instead of showing a message saying that url does not exist
1192+ */
1193+ bool lastUrlNeedsAuthencation() const;
1194+
1195+private:
1196+ /*!
1197+ * \brief storeValidFileInfo() saves an item created by \ref setNewPath() when
1198+ * the item is not Browsable.
1199+ *
1200+ * It happens for example when the \a urlPath entered
1201+ * in \ref setNewPath() is a file (not a DIR nor other Browsable item)
1202+ *
1203+ * \param item
1204+ */
1205 void storeValidFileInfo(DirItemInfo *item);
1206
1207+ /*!
1208+ * \brief validateCurrentUrl() it attempts to validate the current URL being parsed
1209+ *
1210+ * The validation includes authentication, if a Authentication Data is already avaialable
1211+ * it is set to the location being parsed.
1212+ * When authentication fails the signal Location::needsAuthentication() is emitted
1213+ *
1214+ * \param location current Location for the current urlPath entered in \ref setNewPath()
1215+ *
1216+ * \return new Item validated (authenticated when remote authentication is required), otherwise NULL
1217+ */
1218+ DirItemInfo *validateCurrentUrl(Location *location, const NetAuthenticationData&);
1219+
1220 signals:
1221 void locationChanged(const Location *old, const Location *current);
1222
1223-private:
1224- QString stringAfterSlashes(const QString& url, int firstSlashIndex) const;
1225+private slots:
1226+ void onUrlNeedsAuthentication(QString, QString);
1227
1228 private:
1229 Location * m_curLoc;
1230 QList<Location*> m_locations;
1231 QString m_tmpPath;
1232- DirItemInfo * m_lastValidFileInfo;
1233+ DirItemInfo * m_lastValidFileInfo;
1234+ NetAuthenticationDataList * m_authDataStore;
1235+ bool m_lastUrlNeedsAuthentication;
1236
1237 #if defined(REGRESSION_TEST_FOLDERLISTMODEL)
1238 friend class TestDirModel;
1239
1240=== added directory 'src/plugin/folderlistmodel/net'
1241=== added file 'src/plugin/folderlistmodel/net/netauthenticationdata.cpp'
1242--- src/plugin/folderlistmodel/net/netauthenticationdata.cpp 1970-01-01 00:00:00 +0000
1243+++ src/plugin/folderlistmodel/net/netauthenticationdata.cpp 2015-03-08 12:31:26 +0000
1244@@ -0,0 +1,219 @@
1245+/**************************************************************************
1246+ *
1247+ * Copyright 2014 Canonical Ltd.
1248+ * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com>
1249+ *
1250+ * This program is free software; you can redistribute it and/or modify
1251+ * it under the terms of the GNU Lesser General Public License as published by
1252+ * the Free Software Foundation; version 3.
1253+ *
1254+ * This program is distributed in the hope that it will be useful,
1255+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1256+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1257+ * GNU Lesser General Public License for more details.
1258+ *
1259+ * You should have received a copy of the GNU Lesser General Public License
1260+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1261+ *
1262+ * File: netauthenticationdata.cpp
1263+ * Date: 29/11/2014
1264+ */
1265+
1266+#include "netauthenticationdata.h"
1267+
1268+#include <QStandardPaths>
1269+#include <QDir>
1270+#include <QSettings>
1271+#include <QCoreApplication>
1272+#include <QDebug>
1273+
1274+#define CHAR_CRYPT_OFFSET 31
1275+
1276+NetAuthenticationDataList * NetAuthenticationDataList::m_instance = 0;
1277+void * NetAuthenticationDataList::m_parent = 0;
1278+
1279+
1280+NetAuthenticationDataList::NetAuthenticationDataList(): m_savedAuths(0)
1281+{
1282+ //settings file does not need to open all the time
1283+ loadSavedAuthenticationData();
1284+}
1285+
1286+
1287+NetAuthenticationDataList::~NetAuthenticationDataList()
1288+{
1289+ qDeleteAll(m_urlEntries);
1290+ m_urlEntries.clear();
1291+ m_parent = 0;
1292+ m_instance = 0;
1293+ closeAuthenticationStore();
1294+}
1295+
1296+
1297+NetAuthenticationDataList * NetAuthenticationDataList::getInstance(void *parent)
1298+{
1299+ if (m_instance == 0)
1300+ {
1301+ m_instance = new NetAuthenticationDataList();
1302+ m_parent = parent;
1303+ }
1304+ return m_instance;
1305+}
1306+
1307+
1308+void NetAuthenticationDataList::releaseInstance(void *parent)
1309+{
1310+ if (parent == m_parent && m_instance != 0)
1311+ {
1312+ delete m_instance;
1313+ m_instance = 0;
1314+ m_parent = 0;
1315+ }
1316+}
1317+
1318+
1319+const NetAuthenticationData * NetAuthenticationDataList::get(const QString& url) const
1320+{
1321+ const NetAuthenticationData * ret = 0;
1322+ if (!url.isEmpty())
1323+ {
1324+ ret = m_urlEntries.value(url);
1325+ }
1326+ return ret;
1327+}
1328+
1329+bool NetAuthenticationDataList::store(const QString &url, const QString &u, const QString &p, bool save)
1330+{
1331+ bool ret = false;
1332+ if (!url.isEmpty())
1333+ {
1334+ ret = true;
1335+ NetAuthenticationData * data = 0;
1336+ if ( (data = const_cast<NetAuthenticationData*> (get(url))) == 0)
1337+ {
1338+ data = new NetAuthenticationData();
1339+ m_urlEntries.insert(url, data);
1340+ }
1341+ data->user = u;
1342+ data->password = p;
1343+ if (save )
1344+ {
1345+ ret = saveAuthenticationData(url, data);
1346+ }
1347+ }
1348+ return ret;
1349+}
1350+
1351+
1352+
1353+bool NetAuthenticationDataList::store(const QUrl &url, bool save)
1354+{
1355+ QString user = url.userName();
1356+ QString passwd = url.password();
1357+
1358+ QUrl url2(url);
1359+ url2.setUserName(QLatin1String(0));
1360+ url2.setPassword(QLatin1String(0));
1361+
1362+ return store(url2.toString(), user,passwd, save);
1363+}
1364+
1365+
1366+void NetAuthenticationDataList::loadSavedAuthenticationData()
1367+{
1368+ QLatin1Char slash('/');
1369+ QLatin1String userKey("user");
1370+ QLatin1String passKey("password");
1371+ openAuthenticationStore();
1372+ QStringList urls = m_savedAuths->childGroups();
1373+ int counter = urls.count();
1374+ while(counter--)
1375+ {
1376+ m_savedAuths->beginGroup(urls.at(counter));
1377+ QString cleanUrl = urls.at(counter);
1378+ cleanUrl.replace(QLatin1Char('}'), slash);
1379+ QString user = m_savedAuths->value(userKey).toString();
1380+ QString pass = m_savedAuths->value(passKey).toString();
1381+ store(cleanUrl, user, decryptPassword(pass));
1382+ m_savedAuths->endGroup();
1383+ }
1384+ closeAuthenticationStore();
1385+}
1386+
1387+bool NetAuthenticationDataList::saveAuthenticationData(const QString& url, const NetAuthenticationData *d)
1388+{
1389+ QLatin1Char slash('/');
1390+ QLatin1String userKey("user");
1391+ QLatin1String passKey("password");
1392+ QString keyUrl(url);
1393+ keyUrl.replace(slash, QLatin1Char('}'));
1394+
1395+ openAuthenticationStore();
1396+ m_savedAuths->setValue(keyUrl + slash + userKey, d->user);
1397+ m_savedAuths->setValue(keyUrl + slash + passKey, encryptPassord(d->password));
1398+ m_savedAuths->sync();
1399+ bool ret = m_savedAuths->status() == QSettings::NoError;
1400+ if (!ret)
1401+ {
1402+ qDebug() << Q_FUNC_INFO << "ERROR: could not save settings:" << m_savedAuths->fileName();
1403+ }
1404+ closeAuthenticationStore();
1405+ return ret;
1406+}
1407+
1408+/*!
1409+ * \brief NetAuthenticationDataList::encryptPassord() simple crypt function hide the user password
1410+ *
1411+ * \param p the ascii password
1412+ * \return
1413+ */
1414+QString NetAuthenticationDataList::encryptPassord(const QString &p)
1415+{
1416+ QString crypted;
1417+ short unicode = 0;
1418+ for (int counter=0; counter < p.size(); ++counter)
1419+ {
1420+ unicode = p.at(counter).unicode() - CHAR_CRYPT_OFFSET + counter;
1421+ crypted.append( QChar(unicode) );
1422+ }
1423+ return crypted.toLocal8Bit().toHex();
1424+}
1425+
1426+
1427+QString NetAuthenticationDataList::decryptPassword(const QString &p)
1428+{
1429+ QString crypted( QByteArray::fromHex(p.toLocal8Bit()) );
1430+ QString decrypted;
1431+ short unicode = 0;
1432+ for (int counter=0; counter < crypted.size(); ++counter)
1433+ {
1434+ unicode = crypted.at(counter).unicode() + CHAR_CRYPT_OFFSET - counter;
1435+ decrypted.append( QChar(unicode) );
1436+ }
1437+ return decrypted;
1438+}
1439+
1440+void NetAuthenticationDataList::openAuthenticationStore()
1441+{
1442+ if (m_savedAuths == 0)
1443+ {
1444+ QString settingsLocation =
1445+ QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first()
1446+ + QLatin1Char('/') + QCoreApplication::applicationName()
1447+ + QLatin1Char('/') + QLatin1String("authentication.conf");
1448+ m_savedAuths = new QSettings(settingsLocation, QSettings::IniFormat);
1449+#if DEBUG_MESSAGES
1450+ qDebug() << Q_FUNC_INFO << "auth file:" << m_savedAuths->fileName();
1451+#endif
1452+ }
1453+}
1454+
1455+
1456+void NetAuthenticationDataList::closeAuthenticationStore()
1457+{
1458+ if (m_savedAuths != 0)
1459+ {
1460+ delete m_savedAuths;
1461+ m_savedAuths = 0;
1462+ }
1463+}
1464
1465=== added file 'src/plugin/folderlistmodel/net/netauthenticationdata.h'
1466--- src/plugin/folderlistmodel/net/netauthenticationdata.h 1970-01-01 00:00:00 +0000
1467+++ src/plugin/folderlistmodel/net/netauthenticationdata.h 2015-03-08 12:31:26 +0000
1468@@ -0,0 +1,97 @@
1469+/**************************************************************************
1470+ *
1471+ * Copyright 2014 Canonical Ltd.
1472+ * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com>
1473+ *
1474+ * This program is free software; you can redistribute it and/or modify
1475+ * it under the terms of the GNU Lesser General Public License as published by
1476+ * the Free Software Foundation; version 3.
1477+ *
1478+ * This program is distributed in the hope that it will be useful,
1479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1481+ * GNU Lesser General Public License for more details.
1482+ *
1483+ * You should have received a copy of the GNU Lesser General Public License
1484+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1485+ *
1486+ * File: netauthenticationdata.h
1487+ * Date: 29/11/2014
1488+ */
1489+
1490+#ifndef NETAUTHENTICATIONDATA_H
1491+#define NETAUTHENTICATIONDATA_H
1492+
1493+#include <QHash>
1494+#include <QUrl>
1495+
1496+class QSettings;
1497+
1498+/*!
1499+ * \brief The NetAuthenticationData struct
1500+ *
1501+ * Just keeps data for Network authentication (protocol independent)
1502+ */
1503+
1504+struct NetAuthenticationData
1505+{
1506+public:
1507+ NetAuthenticationData() {}
1508+ NetAuthenticationData(const QString&u, const QString& p) :
1509+ user(u), password(p) {}
1510+ inline bool isEmpty() const { return user.isEmpty(); }
1511+ QString user;
1512+ QString password;
1513+};
1514+
1515+
1516+/*!
1517+ * \brief The NetAuthenticationDataList class
1518+ *
1519+ * It keeps a list of the current URLs being used and their Authentication data
1520+ *
1521+ * This information may be required for every connection (e.g. Samba shares).
1522+ *
1523+ * It implements a singleton design pattern to keep a unique Authentication Data list per application
1524+ * \sa \ref getInstance() and \ref releaseInstance()
1525+ *
1526+ * The authentication data can be saved for NOT always asking the user
1527+ *
1528+ * \note It is intended to be used for any protocol.
1529+ * The URL being stored must be the part or prefix which requires authentication
1530+ * Example for Samba: if a user enters with a url like smb://localhost/any_share/folder1/folder2
1531+ * only the share part requires authentication with is smb://localhost/any_share
1532+ * The same authentication data can be used for any smb://localhost/any_share sub-items
1533+ *
1534+ */
1535+class NetAuthenticationDataList
1536+{
1537+public:
1538+ static NetAuthenticationDataList * getInstance(void *parent);
1539+ static void releaseInstance(void *parent);
1540+ ~NetAuthenticationDataList();
1541+
1542+public:
1543+ bool store(const QUrl& url, bool save = false);
1544+ bool store(const QString& url, const QString& u, const QString& p, bool save =false);
1545+ const NetAuthenticationData * get(const QString&) const;
1546+
1547+private:
1548+ NetAuthenticationDataList();
1549+
1550+private:
1551+ void openAuthenticationStore();
1552+ void closeAuthenticationStore();
1553+ QString encryptPassord(const QString& p);
1554+ QString decryptPassword(const QString& p);
1555+ void loadSavedAuthenticationData();
1556+ bool saveAuthenticationData(const QString& url, const NetAuthenticationData * );
1557+
1558+private: //url authentication data
1559+ QHash <QString , NetAuthenticationData*> m_urlEntries;
1560+ static NetAuthenticationDataList * m_instance;
1561+ static void * m_parent;
1562+ QSettings * m_savedAuths;
1563+};
1564+
1565+#endif // NETAUTHENTICATIONDATA_H
1566
1567=== modified file 'src/plugin/folderlistmodel/trash/trashlocation.cpp'
1568--- src/plugin/folderlistmodel/trash/trashlocation.cpp 2014-05-17 18:07:11 +0000
1569+++ src/plugin/folderlistmodel/trash/trashlocation.cpp 2015-03-08 12:31:26 +0000
1570@@ -180,8 +180,7 @@
1571
1572
1573 void TrashLocation::startExternalFsWatcher()
1574-{
1575- //TODO implement a Watcher for this
1576+{
1577 //modify the existent watcher to work having a list of paths
1578 if (m_usingExternalWatcher && m_extWatcher == 0 && isRoot())
1579 {
1580@@ -286,3 +285,32 @@
1581 ret.setTargetFullName( trashInfo.absFile );
1582 return ret;
1583 }
1584+
1585+
1586+DirItemInfo * TrashLocation::newItemInfo(const QString &urlPath)
1587+{
1588+ return new TrashItemInfo(urlPath);
1589+}
1590+
1591+
1592+/*!
1593+ * \brief TrashLocation::newListWorker() It is provided only because it is a pure method
1594+ *
1595+ * As \rev fetchItems() is reemplemented this method should never be used
1596+ *
1597+ * \param urlPath
1598+ * \param filter
1599+ * \param isRecursive
1600+ * \return
1601+ */
1602+DirListWorker * TrashLocation::newListWorker(const QString &urlPath, QDir::Filter filter, const bool isRecursive)
1603+{
1604+ Q_UNUSED(isRecursive);
1605+ QString trashDir;
1606+ if (m_info && !m_info->isRoot())
1607+ {
1608+ TrashItemInfo *item = static_cast<TrashItemInfo*> (m_info);
1609+ trashDir = item->getTrashDir();
1610+ }
1611+ return new TrashListWorker(trashDir, urlPath, filter);
1612+}
1613
1614=== modified file 'src/plugin/folderlistmodel/trash/trashlocation.h'
1615--- src/plugin/folderlistmodel/trash/trashlocation.h 2014-05-17 18:07:11 +0000
1616+++ src/plugin/folderlistmodel/trash/trashlocation.h 2015-03-08 12:31:26 +0000
1617@@ -45,6 +45,11 @@
1618
1619 virtual DirItemInfo *validateUrlPath(const QString& urlPath);
1620
1621+ virtual DirItemInfo * newItemInfo(const QString& urlPath);
1622+ virtual DirListWorker * newListWorker(const QString &urlPath,
1623+ QDir::Filter filter,
1624+ const bool isRecursive);
1625+
1626 /*!
1627 * \brief getMovePairPaths() Get: original path and destination trash path
1628 *

Subscribers

People subscribed via source and target branches