← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

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

 

Carlos Jose Mazieri has proposed merging lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03 into lp:ubuntu-filemanager-app with lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-02 as a prerequisite.

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

Requested reviews:
  Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot): continuous-integration
  Ubuntu File Manager Developers (ubuntu-filemanager-dev)

For more details, see:
https://code.launchpad.net/~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03/+merge/252219

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.
-- 
Your team Ubuntu File Manager Developers is requested to review the proposed merge of lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03 into lp:ubuntu-filemanager-app.
=== modified file 'src/plugin/folderlistmodel/CMakeLists.txt'
--- src/plugin/folderlistmodel/CMakeLists.txt	2014-05-02 12:22:11 +0000
+++ src/plugin/folderlistmodel/CMakeLists.txt	2015-03-08 12:31:26 +0000
@@ -1,7 +1,8 @@
 include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     disk
-    trash
+    trash   
+    net
 )
 
 set(PLUGIN_DIR org/nemomobile/folderlistmodel)
@@ -40,6 +41,10 @@
     locationsfactory.h
     locationurl.cpp
     locationurl.h
+    locationitemdiriterator.cpp
+    locationitemdiriterator.h
+    cleanurl.cpp
+    cleanurl.h  
     disk/disklocation.cpp
     disk/disklocation.h
     trash/qtrashdir.cpp
@@ -49,7 +54,9 @@
     trash/trashiteminfo.cpp
     trash/trashiteminfo.h
     trash/trashlocation.cpp
-    trash/trashlocation.h
+    trash/trashlocation.h          
+    net/netauthenticationdata.cpp
+    net/netauthenticationdata.h   
 )
 
 add_library(nemofolderlistmodel MODULE
@@ -58,6 +65,7 @@
 
 qt5_use_modules(nemofolderlistmodel Gui Qml Quick Widgets)
 
+
 # Copy the plugin, the qmldir file and other assets to the build dir for running in QtCreator
 if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
     add_custom_command(TARGET nemofolderlistmodel POST_BUILD

=== added file 'src/plugin/folderlistmodel/cleanurl.cpp'
--- src/plugin/folderlistmodel/cleanurl.cpp	1970-01-01 00:00:00 +0000
+++ src/plugin/folderlistmodel/cleanurl.cpp	2015-03-08 12:31:26 +0000
@@ -0,0 +1,73 @@
+/**************************************************************************
+ *
+ * Copyright 2015 Canonical Ltd.
+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * File: cleanurl.cpp
+ * Date: 04/02/2015
+ */
+
+#include "cleanurl.h"
+
+#include <QUrl>
+
+CleanUrl::CleanUrl(const QString &urlPath) : m_user(0), m_password(0)
+{
+    QUrl  url(urlPath);
+    if (url.isValid())
+    {
+        QString user = url.userName();
+        if (!user.isEmpty())
+        {
+            m_user     = new QString(user);
+            m_password = new QString(url.password());
+            url.setPassword(QLatin1String(0));
+            url.setUserName(QLatin1String(0));
+        }
+        m_url = url.toString();
+    }
+    else
+    {
+        m_url = urlPath;
+    }
+}
+
+
+CleanUrl::~CleanUrl()
+{
+    if (m_user)     { delete m_user; }
+    if (m_password) { delete m_password;}
+}
+
+
+bool CleanUrl::hasAuthenticationData() const
+{
+    return m_user ? true : false;
+}
+
+QString CleanUrl::user() const
+{
+    return m_user ? *m_user : QString();
+}
+
+QString CleanUrl::password() const
+{
+    return m_password ? *m_password : QString();
+}
+
+QString CleanUrl::cleanUrl() const
+{
+    return m_url;
+}

=== added file 'src/plugin/folderlistmodel/cleanurl.h'
--- src/plugin/folderlistmodel/cleanurl.h	1970-01-01 00:00:00 +0000
+++ src/plugin/folderlistmodel/cleanurl.h	2015-03-08 12:31:26 +0000
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * Copyright 2015 Canonical Ltd.
+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * File: cleanurl.h
+ * Date: 04/02/2015
+ */
+
+#ifndef CLEANURL_H
+#define CLEANURL_H
+
+#include <QString>
+
+/*!
+ * \brief The CleanUrl class
+ *
+ *  Just returns a URL without user/password if exists
+ */
+class CleanUrl
+{
+public:
+    CleanUrl(const QString &urlPath);
+    ~CleanUrl();
+    bool         hasAuthenticationData() const;
+    QString      cleanUrl() const;
+    QString      user() const;
+    QString      password() const; 
+private:
+    QString      m_url;   //!<  keeps the url without user/password
+    QString    * m_user;
+    QString    * m_password;
+};
+
+#endif // CLEANURL_H

=== modified file 'src/plugin/folderlistmodel/dirmodel.cpp'
--- src/plugin/folderlistmodel/dirmodel.cpp	2015-03-08 12:31:26 +0000
+++ src/plugin/folderlistmodel/dirmodel.cpp	2015-03-08 12:31:26 +0000
@@ -218,10 +218,11 @@
         roles.insert(FilePathRole, QByteArray("filePath"));
         roles.insert(IsDirRole, QByteArray("isDir"));        
         roles.insert(IsHostRole, QByteArray("isHost"));
-        roles.insert(IsSmbWorkgroupRole, QByteArray("IsSmbWorkgroup"));
-        roles.insert(IsSmbShareRole, QByteArray("IsSmbShare"));
-        roles.insert(IsSharedDirRole, QByteArray("IsSharedDir"));
-        roles.insert(IsSharingAllowedRole, QByteArray("IsSharingAllowed"));
+        roles.insert(IsSmbWorkgroupRole, QByteArray("isSmbWorkgroup"));
+        roles.insert(IsSmbShareRole, QByteArray("isSmbShare"));
+        roles.insert(IsSharedDirRole, QByteArray("isSharedDir"));
+        roles.insert(IsSharingAllowedRole, QByteArray("isSharingAllowed"));
+        roles.insert(IsBrowsableRole, QByteArray("isBrowsable"));
         roles.insert(IsFileRole, QByteArray("isFile"));
         roles.insert(IsReadableRole, QByteArray("isReadable"));
         roles.insert(IsWritableRole, QByteArray("isWritable"));
@@ -383,6 +384,8 @@
             return fi.isWorkGroup();
         case IsSmbShareRole:
             return fi.isShare();
+        case IsBrowsableRole:
+            return fi.isBrowsable();
         case IsSharingAllowedRole:
             return     fi.isDir() && !fi.isSymLink() && !fi.isSharedDir()
                     && mCurLocation->type() == LocationsFactory::LocalDisk

=== modified file 'src/plugin/folderlistmodel/dirmodel.h'
--- src/plugin/folderlistmodel/dirmodel.h	2015-03-08 12:31:26 +0000
+++ src/plugin/folderlistmodel/dirmodel.h	2015-03-08 12:31:26 +0000
@@ -67,6 +67,7 @@
         IsSmbShareRole,
         IsSharedDirRole,    //!< it can also be used for other protocols than smb/cifs
         IsSharingAllowedRole,//!< true for local directories (not in Trash) and not IsSharedDirRole
+        IsBrowsableRole,     //!< any Dir, Host, WorkGroup or Share
         IsFileRole,
         IsReadableRole,
         IsWritableRole,

=== modified file 'src/plugin/folderlistmodel/disk/disklocation.cpp'
--- src/plugin/folderlistmodel/disk/disklocation.cpp	2014-05-14 22:51:47 +0000
+++ src/plugin/folderlistmodel/disk/disklocation.cpp	2015-03-08 12:31:26 +0000
@@ -46,49 +46,6 @@
 }
 
 
-void DiskLocation::fetchItems(QDir::Filter dirFilter, bool recursive)
-{
-    DirListWorker *dlw  = new DirListWorker(m_info->absoluteFilePath(), dirFilter, recursive);
-    connect(dlw,  SIGNAL(itemsAdded(DirItemInfoList)),
-            this, SIGNAL(itemsAdded(DirItemInfoList)));
-    connect(dlw,  SIGNAL(workerFinished()),
-            this, SLOT(onItemsFetched()));
-    workerThread()->addRequest(dlw);
-}
-
-
-bool DiskLocation::becomeParent()
-{
-    bool ret = false;
-    if (m_info && !m_info->isRoot())
-    {
-        DirItemInfo *other = new DirItemInfo(m_info->absolutePath());
-        if (other->isValid())
-        {
-            delete m_info;
-            m_info = other;
-            ret = true;
-        }
-        else
-        {
-            delete other;
-        }
-    }
-    return ret;
-}
-
-
-void DiskLocation::refreshInfo()
-{
-    if (m_info)
-    {
-        DirItemInfo *item = new DirItemInfo(m_info->absoluteFilePath());
-        delete m_info;
-        m_info = item;
-    }
-}
-
-
 /*!
  * \brief DiskLocation::stopExternalFsWatcher() stops the External File System Watcher
  */
@@ -115,11 +72,12 @@
         m_extWatcher->setIntervalToNotifyChanges(EX_FS_WATCHER_TIMER_INTERVAL);
 
         connect(m_extWatcher, SIGNAL(pathModified(QString)),
-                this,         SIGNAL(extWatcherPathChanged(QString)));       
-       if (m_info)
-       {               //setCurrentPath() checks for empty paths
+                this,         SIGNAL(extWatcherPathChanged(QString)));            
+    }
+    if (m_extWatcher && m_info)
+    {
+          //setCurrentPath() checks for empty paths
            m_extWatcher->setCurrentPath(m_info->absoluteFilePath());
-       }     
     }
 }
 
@@ -187,9 +145,8 @@
 
 
 void DiskLocation::setUsingExternalWatcher(bool use)
-{
-    Location::setUsingExternalWatcher(use);
-    if (m_usingExternalWatcher)
+{   
+    if ((m_usingExternalWatcher = use))
     {
         startExternalFsWatcher();
     }
@@ -200,23 +157,14 @@
 }
 
 
-DirItemInfo * DiskLocation::validateUrlPath(const QString& uPath)
-{
-    QString myPath(uPath);
-    QFileInfo tmpUrl(uPath);
-    if (tmpUrl.isRelative() && m_info)
-    {
-        tmpUrl.setFile(m_info->absoluteFilePath(), uPath);
-        myPath  =  tmpUrl.absoluteFilePath();
-    }
-#if DEBUG_MESSAGES
-    qDebug() << Q_FUNC_INFO << "path:" << myPath;
-#endif
-    DirItemInfo * item = new DirItemInfo(myPath);
-    if (!item->isValid() || !item->exists() || !item->isContentReadable())
-    {
-        delete item;
-        item = 0;
-    }
-    return item;
-}
+DirItemInfo * DiskLocation::newItemInfo(const QString &urlPath)
+{
+    return new DirItemInfo(urlPath);
+}
+
+
+DirListWorker * DiskLocation::newListWorker(const QString &urlPath, QDir::Filter filter, const bool isRecursive)
+{
+    return new DirListWorker(urlPath,filter,isRecursive);
+}
+

=== modified file 'src/plugin/folderlistmodel/disk/disklocation.h'
--- src/plugin/folderlistmodel/disk/disklocation.h	2014-05-14 22:51:47 +0000
+++ src/plugin/folderlistmodel/disk/disklocation.h	2015-03-08 12:31:26 +0000
@@ -49,12 +49,9 @@
 
     ExternalFSWatcher  * getExternalFSWatcher() const;
 
-    virtual void        fetchItems(QDir::Filter dirFilter, bool recursive = false) ;
     virtual void        fetchExternalChanges(const QString& urlPath,
                                              const DirItemInfoList& list,
                                              QDir::Filter dirFilter) ;
-    virtual bool        becomeParent();
-    virtual void        refreshInfo();
 
     virtual void        startExternalFsWatcher();
     virtual void        stopExternalFsWatcher();
@@ -62,7 +59,10 @@
     virtual void        startWorking();
     virtual void        stopWorking();
 
-    virtual DirItemInfo *validateUrlPath(const QString& urlPath);
+    virtual DirItemInfo * newItemInfo(const QString& urlPath);
+    virtual DirListWorker * newListWorker(const QString &urlPath,
+                                          QDir::Filter filter,
+                                          const bool isRecursive);
 
 protected:
     void    addExternalFsWorkerRequest(ExternalFileSystemChangesWorker *);

=== modified file 'src/plugin/folderlistmodel/folderlistmodel.pri'
--- src/plugin/folderlistmodel/folderlistmodel.pri	2014-05-02 12:22:11 +0000
+++ src/plugin/folderlistmodel/folderlistmodel.pri	2015-03-08 12:31:26 +0000
@@ -8,16 +8,12 @@
            $$PWD/clipboard.cpp \
            $$PWD/fmutil.cpp \
            $$PWD/dirselection.cpp \
-           $$PWD/diriteminfo.cpp \
-           $$PWD/trash/qtrashdir.cpp \
-           $$PWD/trash/trashiteminfo.cpp \
+           $$PWD/diriteminfo.cpp \         
            $$PWD/location.cpp \
-           $$PWD/locationsfactory.cpp \
-           $$PWD/disk/disklocation.cpp \
-           $$PWD/trash/trashlocation.cpp \
-           $$PWD/locationurl.cpp \
-           $$PWD/trash/qtrashutilinfo.cpp
-
+           $$PWD/locationsfactory.cpp \                    
+           $$PWD/locationurl.cpp \             
+           $$PWD/locationitemdiriterator.cpp \
+           $$PWD/cleanurl.cpp
 
 HEADERS += $$PWD/dirmodel.h \
            $$PWD/iorequest.h \
@@ -29,19 +25,25 @@
            $$PWD/clipboard.h \
            $$PWD/fmutil.h  \
            $$PWD/dirselection.h \          
-           $$PWD/diritemabstractlistmodel.h \
-           $$PWD/diriteminfo.h \
-           $$PWD/trash/qtrashdir.h \
-           $$PWD/trash/trashiteminfo.h \
+           $$PWD/diritemabstractlistmodel.h \               
            $$PWD/location.h \
-           $$PWD/locationsfactory.h \
-           $$PWD/disk/disklocation.h \
-           $$PWD/trash/trashlocation.h \
-           $$PWD/locationurl.h \
-           $$PWD/trash/qtrashutilinfo.h
-
-
-INCLUDEPATH  += $$PWD $$PWD/trash $$PWD/disk
+           $$PWD/locationsfactory.h \                   
+           $$PWD/locationurl.h \          
+           $$PWD/locationitemdiriterator.h \
+           $$PWD/cleanurl.h
+
+SOURCES +=  $$PWD/disk/disklocation.cpp
+HEADERS +=  $$PWD/disk/disklocation.h
+
+SOURCES +=  $$PWD/trash/qtrashdir.cpp $$PWD/trash/trashiteminfo.cpp  \
+            $$PWD/trash/qtrashutilinfo.cpp $$PWD/trash/trashlocation.cpp
+HEADERS +=  $$PWD/trash/qtrashdir.h       $$PWD/trash/trashiteminfo.h    \
+            $$PWD/trash/qtrashutilinfo.h  $$PWD/trash/trashlocation.h
+
+SOURCES +=  $$PWD/net/netauthenticationdata.cpp
+HEADERS +=  $$PWD/net/netauthenticationdata.h
+
+INCLUDEPATH  += $$PWD $$PWD/trash $$PWD/disk $$PWD/net
 
 greaterThan(QT_MAJOR_VERSION, 4) {
    QT += qml

=== modified file 'src/plugin/folderlistmodel/iorequest.cpp'
--- src/plugin/folderlistmodel/iorequest.cpp	2014-12-30 18:23:15 +0000
+++ src/plugin/folderlistmodel/iorequest.cpp	2015-03-08 12:31:26 +0000
@@ -89,9 +89,14 @@
 
 DirItemInfoList  IORequestLoader::getContents()
 {
-   return mLoaderType == NormalLoader ?
-                getNormalContent() :
-                getTrashContent();
+   DirItemInfoList list;
+   switch(mLoaderType)
+   {
+      case  NormalLoader:  list = getNormalContent();  break;
+      case  TrashLoader:   list = getTrashContent();   break;
+      case  NetworkLoader: list = getNetworkContent(); break;
+   }   
+   return list;
 }
 
 DirItemInfoList  IORequestLoader::getNormalContent()
@@ -112,8 +117,7 @@
 {
     QDir tmpDir = QDir(pathName, QString(), QDir::NoSort, filter);
     QDirIterator it(tmpDir);
-    while (it.hasNext())
-    {
+    while (it.hasNext()) {
         it.next();
         if(it.fileInfo().isDir() && isRecursive) {
             directoryContents = add(it.fileInfo().filePath(),
@@ -150,6 +154,14 @@
 }
 
 
+DirItemInfoList IORequestLoader::getNetworkContent()
+{
+  DirItemInfoList emptyContent;
+  return emptyContent;
+}
+
+
+
 //-----------------------------------------------------------------------------------------------
 DirListWorker::DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive)
     : IORequestLoader(pathName, filter, isRecursive)

=== modified file 'src/plugin/folderlistmodel/iorequest.h'
--- src/plugin/folderlistmodel/iorequest.h	2014-05-15 00:18:54 +0000
+++ src/plugin/folderlistmodel/iorequest.h	2015-03-08 12:31:26 +0000
@@ -70,7 +70,8 @@
     enum LoaderType
     {
         NormalLoader,
-        TrashLoader
+        TrashLoader,
+        NetworkLoader
     };
 
     IORequestLoader( const QString &pathName,
@@ -91,6 +92,7 @@
 private:
     DirItemInfoList getNormalContent();
     DirItemInfoList getTrashContent();
+    virtual DirItemInfoList getNetworkContent();
     DirItemInfoList add(const QString &pathName, QDir::Filter filter,
                         bool isRecursive, DirItemInfoList directoryContents);
 protected:

=== modified file 'src/plugin/folderlistmodel/location.cpp'
--- src/plugin/folderlistmodel/location.cpp	2014-05-14 22:51:47 +0000
+++ src/plugin/folderlistmodel/location.cpp	2015-03-08 12:31:26 +0000
@@ -41,6 +41,7 @@
 
 #include "location.h"
 #include "ioworkerthread.h"
+#include "netauthenticationdata.h"
 
 Q_GLOBAL_STATIC(IOWorkerThread, ioWorkerThread)
 
@@ -72,7 +73,7 @@
 
 bool Location::isWritable() const
 {
-    return m_info->isWritable();
+    return m_info ? m_info->isWritable() : false;
 }
 
 
@@ -112,10 +113,6 @@
 
 }
 
-bool Location::becomeParent()
-{
-    return false;
-}
 
 IOWorkerThread * Location::workerThread() const
 {
@@ -133,8 +130,177 @@
     Q_UNUSED(dirFilter);
 }
 
-
+//======================================================================================================
+/*!
+ * \brief Location::setUsingExternalWatcher() Default implementation sets nothing
+ *
+ *  It considers that there is no external Watcher
+ * \param use
+ */
 void Location::setUsingExternalWatcher(bool use)
 {
-    m_usingExternalWatcher = use;
-}
+   Q_UNUSED(use)
+   m_usingExternalWatcher = false;
+}
+
+
+/*!
+ * \brief Location::setAuthentication()
+ *
+ * Default implementation does nothing as local disk does not need it
+ *
+ * Network Locations need to reimplement this
+ *
+ * \param user
+ * \param password
+ */
+void Location::setAuthentication(const QString &user,
+                                 const QString &password)
+
+{
+    Q_UNUSED(user);
+    Q_UNUSED(password);   
+}
+
+/*!
+ * \brief Location::currentAuthenticationUser()
+ *
+ * Default implementation returns current user
+ *
+ * \return
+ */
+QString Location::currentAuthenticationUser()
+{
+    return QString(::qgetenv("USER"));
+}
+
+/*!
+ * \brief Location::currentAuthenticationPassword()
+ *
+ * Default implementation returns empty string
+ *
+ * \return
+ */
+QString  Location::currentAuthenticationPassword()
+{
+    return QString();
+}
+
+/*!
+ * \brief Location::notifyItemNeedsAuthentication()
+ * \param item
+ *
+ * \note
+ *    The connection between Location objects and the \class DirModel is Qt::QueuedConnection
+ *    It allows a UI to continuosly show dialogs asking the user to provide User and Password
+ *     to authenticate the current URL
+ */
+void Location::notifyItemNeedsAuthentication(const DirItemInfo *item)
+{
+    if (item == 0)
+    {
+        item = m_info;
+    }
+    if (item != 0)
+    {
+        emit needsAuthentication(currentAuthenticationUser(), item->urlPath());
+    }
+}
+
+
+
+bool Location::useAuthenticationDataIfExists(const DirItemInfo& item)
+{
+    NetAuthenticationDataList *authData = NetAuthenticationDataList::getInstance(this);
+    const NetAuthenticationData *auth = authData->get(item.authenticationPath());
+    bool ret = false;
+    if (auth && !(     auth->user      == currentAuthenticationUser()
+                   &&  auth->password  == currentAuthenticationPassword()
+                 )
+       )
+    {
+        setAuthentication(auth->user, auth->password);
+        ret =  true;
+    }
+    NetAuthenticationDataList::releaseInstance(this);
+    return ret;
+}
+
+
+
+void Location::refreshInfo()
+{
+    if (m_info)
+    {
+        DirItemInfo *item = newItemInfo(m_info->absoluteFilePath());
+        delete m_info;
+        m_info = item;
+    }
+}
+
+
+bool Location::becomeParent()
+{
+    bool ret = false;
+    if (m_info && !m_info->isRoot())
+    {
+        DirItemInfo *other = newItemInfo(m_info->absolutePath());
+        if (other->isValid())
+        {
+            delete m_info;
+            m_info = other;
+            ret = true;
+        }
+        else
+        {
+            delete other;
+        }
+    }
+    return ret;
+}
+
+
+DirItemInfo * Location::validateUrlPath(const QString & uPath)
+{
+    QString myPath(uPath);
+    DirItemInfo * item = newItemInfo(myPath);
+    if (item->isRelative() && m_info)
+    {
+        item->setFile(m_info->urlPath(), uPath);
+        myPath  =  item->urlPath();
+    }
+
+#if DEBUG_MESSAGES
+    qDebug() << Q_FUNC_INFO << "path:" << myPath << "needsAuthentication:" << item->needsAuthentication();
+#endif
+
+    // the isContentReadable() is not checked here
+    // because it will be false when authentication is required
+    if (!item->isValid() || !item->exists())
+    {
+        delete item;
+        item = 0;
+    }
+    return item;
+}
+
+
+void Location::fetchItems(QDir::Filter dirFilter, bool recursive)
+{
+    //it should never happen here
+    if (m_info->needsAuthentication())
+    {
+        emit needsAuthentication(currentAuthenticationUser(), m_info->absoluteFilePath());
+    }
+    else
+    {
+        DirListWorker *dlw  = newListWorker(m_info->absoluteFilePath(), dirFilter, recursive);
+        connect(dlw,  SIGNAL(itemsAdded(DirItemInfoList)),
+                this, SIGNAL(itemsAdded(DirItemInfoList)));
+        connect(dlw,  SIGNAL(workerFinished()),
+            this,     SIGNAL(itemsFetched()));
+        workerThread()->addRequest(dlw);
+    }
+}
+
+

=== modified file 'src/plugin/folderlistmodel/location.h'
--- src/plugin/folderlistmodel/location.h	2014-05-14 22:51:47 +0000
+++ src/plugin/folderlistmodel/location.h	2015-03-08 12:31:26 +0000
@@ -27,6 +27,7 @@
 #include <QObject>
 
 class IOWorkerThread;
+class DirListWorker;
 
 /*!
  * \brief The Location class represents any location (full path) where there are items to browse: directories, shares, from Disk and from Network.
@@ -45,9 +46,10 @@
 class Location : public QObject
 {
    Q_OBJECT
-public:
+public:  
+    virtual ~Location();
+protected:
     explicit Location( int type, QObject *parent=0);
-    virtual ~Location();
 
     IOWorkerThread * workerThread() const;
 
@@ -59,18 +61,44 @@
     void     extWatcherItemChanged(const DirItemInfo&);
     void     extWatcherItemAdded(const   DirItemInfo&);
     void     extWatcherChangesFetched(int);
+    void     needsAuthentication(const QString& user, const QString& urlPath);
 
 public slots:
     virtual void setUsingExternalWatcher(bool use);
+    virtual void setAuthentication(const QString& user,
+                                   const QString& password);
+
 
 public: //pure functions
     /*!
+     * \brief newItemInfo()  returns a Location suitable DirItemInfo object
+     *
+     * Every Locations must create its own DirItemInfo object with all the information set
+     * \param urlPath  it can also contain User and Password when in the form of an URL
+     * \return the object created
+     */
+    virtual DirItemInfo *    newItemInfo(const QString& urlPath) = 0;
+
+    /*!
+     * \brief newListWorker() creates a Location suitable DirListWorker object which will create a new \ref DirItemInfoList for browsing items
+     *
+     *  The DirListWorker object will be used in \ref fetchItems()
+     *
+     * \param urlPath  urlPath  it can also contain User and Password when in the form of an URL
+     * \param filter
+     * \param isRecursive
+     * \return the object which will fill a new \ref DirItemInfoList for browsing items
+     */
+    virtual DirListWorker *  newListWorker(const QString &urlPath, QDir::Filter filter, const bool isRecursive) = 0;
+
+public:
+    /*!
      * \brief fetchItems() gets the content of the Location
      *
      * \param dirFilter   current Filter
      * \param recursive   should get the content all sub dirs or not, (hardly ever it is true)
      */
-    virtual void        fetchItems(QDir::Filter dirFilter, bool recursive=0) = 0;
+     virtual void        fetchItems(QDir::Filter dirFilter, bool recursive=false);
 
     /*!
      * \brief refreshInfo() It must refresh the DirItemInfo
@@ -78,9 +106,9 @@
      *  It can be used for example after receiving the signal about external disk file system changes
      *  due to the current path permissions might have changed.
      */
-    virtual void        refreshInfo() = 0;
+    virtual void        refreshInfo();
 
-     /*!
+    /*!
      * \brief becomeParent() The current path location becomes the parent Location
      *
      * When \ref isRoot() returns false  the current path location becomes the parent path location
@@ -91,7 +119,7 @@
      *
      * \return true if it is possible to do like a cdUp.
      */
-     virtual bool        becomeParent() = 0;
+     virtual bool        becomeParent();
 
     /*!
       * \brief validateUrlPath()  Validates the urlPath (file or Directory) and creates a new Obeject from this path
@@ -101,9 +129,10 @@
       * \param urlPath
       * \return a valid pointer to DirItemInfo object or NULL indicating something wrong with the path
       */
-     virtual DirItemInfo *       validateUrlPath(const QString& urlPath)  = 0;
-
-public:
+     virtual DirItemInfo *       validateUrlPath(const QString& urlPath);
+
+
+public: //virtual
     virtual void        fetchExternalChanges(const QString& urlPath,
                                              const DirItemInfoList& list,
                                              QDir::Filter dirFilter) ;
@@ -115,6 +144,12 @@
     virtual QString     urlPath() const;
     virtual void        startWorking();
     virtual void        stopWorking();
+    virtual QString     currentAuthenticationUser();
+    virtual QString     currentAuthenticationPassword();
+
+public: //non virtual
+    void                notifyItemNeedsAuthentication(const DirItemInfo *item = 0);
+    bool                useAuthenticationDataIfExists(const DirItemInfo &item);
 
     inline const DirItemInfo*  info() const  { return m_info; }
     inline int                 type() const  { return m_type; }

=== added file 'src/plugin/folderlistmodel/locationitemdiriterator.cpp'
--- src/plugin/folderlistmodel/locationitemdiriterator.cpp	1970-01-01 00:00:00 +0000
+++ src/plugin/folderlistmodel/locationitemdiriterator.cpp	2015-03-08 12:31:26 +0000
@@ -0,0 +1,44 @@
+/**************************************************************************
+ *
+ * Copyright 2015 Canonical Ltd.
+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * File: locationitemdiriterator.cpp
+ * Date: 10/01/2015
+ */
+
+#include "locationitemdiriterator.h"
+
+LocationItemDirIterator::LocationItemDirIterator(const QString &, const QStringList &, QDir::Filters, QDirIterator::IteratorFlags )
+{
+}
+
+
+LocationItemDirIterator::LocationItemDirIterator(const QString &, QDir::Filters , QDirIterator::IteratorFlags)
+{
+
+}
+
+LocationItemDirIterator::LocationItemDirIterator(const QString &, QDirIterator::IteratorFlags )
+{
+
+}
+
+LocationItemDirIterator::~LocationItemDirIterator()
+{
+
+}
+
+

=== added file 'src/plugin/folderlistmodel/locationitemdiriterator.h'
--- src/plugin/folderlistmodel/locationitemdiriterator.h	1970-01-01 00:00:00 +0000
+++ src/plugin/folderlistmodel/locationitemdiriterator.h	2015-03-08 12:31:26 +0000
@@ -0,0 +1,68 @@
+/**************************************************************************
+ *
+ * Copyright 2015 Canonical Ltd.
+ * Copyright 2015 Carlos J Mazieri <carlos.mazieri@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * File: locationitemdiriterator.h
+ * Date: 10/01/2015
+ */
+
+#ifndef LOCATIONITEMDIRITERATOR_H
+#define LOCATIONITEMDIRITERATOR_H
+
+#include <QDirIterator>
+#include "diriteminfo.h"
+
+/*!
+ * \brief The LocationItemDirIterator class is an abstract similar to Qt QDirIterator
+ *
+ *   Different protocols supported by filemanager (different Locations) must provide a class like that.
+ */
+
+class LocationItemDirIterator
+{
+public:
+   virtual ~LocationItemDirIterator();
+public:
+   virtual bool	        hasNext()  const = 0;
+   virtual QString	    next()           = 0;
+
+   virtual DirItemInfo	fileInfo() const = 0;
+    /*!
+    * \brief fileName()
+    * \return the file name for the current directory entry, without the path prepended.
+    */
+   virtual QString	    fileName() const = 0;
+
+    /*!
+    * \brief filePath()
+    * \return the full pathname of the current item
+    */
+   virtual QString	    filePath() const = 0;
+
+    /*!
+    * \brief path()
+    * \return  the base directory of the iterator path (not the current item)
+    */
+   virtual QString	    path()     const = 0;
+
+protected:
+   LocationItemDirIterator(const QString & path, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
+   LocationItemDirIterator(const QString & path, QDir::Filters filters, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
+   LocationItemDirIterator(const QString & path, const QStringList & nameFilters, QDir::Filters filters = QDir::NoFilter, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
+};
+
+
+#endif // LOCATIONITEMDIRITERATOR_H

=== modified file 'src/plugin/folderlistmodel/locationsfactory.cpp'
--- src/plugin/folderlistmodel/locationsfactory.cpp	2014-06-25 22:54:59 +0000
+++ src/plugin/folderlistmodel/locationsfactory.cpp	2015-03-08 12:31:26 +0000
@@ -26,22 +26,33 @@
 #include "disklocation.h"
 #include "trashlocation.h"
 #include "trashiteminfo.h"
+#include "cleanurl.h"
+#include "netauthenticationdata.h"
 
 #include <QDir>
 #include <QDebug>
 
 
-
+/*!
+ * \brief LocationsFactory::LocationsFactory()
+ * \param parent
+ *
+ * Locations emit needsAuthentication() signal, the connection
+ * with LocationsFactory is Direct,  but the connection between
+ * the Location and the \ref DirModel is Queued
+ * \sa Location::notifyItemNeedsAuthentication()
+ */
 LocationsFactory::LocationsFactory(QObject *parent)
  : QObject(parent)
  , m_curLoc(0)
  , m_lastValidFileInfo(0)
+ , m_authDataStore(NetAuthenticationDataList::getInstance(this))
+ , m_lastUrlNeedsAuthentication(false)
 {
    m_locations.append(new DiskLocation(LocalDisk));
    m_locations.append(new TrashLocation(TrashDisk));
 }
 
-
 LocationsFactory::~LocationsFactory()
 {
     ::qDeleteAll(m_locations);
@@ -50,6 +61,7 @@
     {
         delete m_lastValidFileInfo;
     }
+    NetAuthenticationDataList::releaseInstance(this);
 }
 
 
@@ -72,20 +84,20 @@
         if (uPath.startsWith(LocationUrl::TrashRootURL.midRef(0,6)))
         {
             type = TrashDisk;
-            m_tmpPath  = LocationUrl::TrashRootURL + stringAfterSlashes(uPath, index+1);
+            m_tmpPath  = LocationUrl::TrashRootURL + DirItemInfo::removeExtraSlashes(uPath, index+1);
         }
         else
 #endif //Q_OS_UNIX
-#endif //Q_OS_UNIX
+#endif
         if (uPath.startsWith(LocationUrl::DiskRootURL.midRef(0,5)))
         {
             type = LocalDisk;
-            m_tmpPath  = QDir::rootPath() + stringAfterSlashes(uPath, index+1);
+            m_tmpPath  = QDir::rootPath() + DirItemInfo::removeExtraSlashes(uPath, index+1);
         }
     }
     else
     {
-        m_tmpPath = stringAfterSlashes(uPath, -1);
+        m_tmpPath = DirItemInfo::removeExtraSlashes(uPath, -1);
         type    = LocalDisk;
         if (!m_tmpPath.startsWith(QDir::rootPath()) && m_curLoc)
         {
@@ -104,17 +116,34 @@
 }
 
 
-Location * LocationsFactory::setNewPath(const QString& uPath)
+Location * LocationsFactory::setNewPath(const QString& uPath, const QString& authUser, const QString& passwd, bool savePassword)
 {
     storeValidFileInfo(0);
-    Location *location = parse(uPath);
+    CleanUrl url(uPath);
+    m_lastUrlNeedsAuthentication = false;
+    NetAuthenticationData authData(authUser, passwd);
+    if (authData.isEmpty() && url.hasAuthenticationData())
+    {
+        authData.user      = url.user();
+        authData.password  = url.password();
+    }
+    Location *location = parse(url.cleanUrl());
     if (location)
     {
-        DirItemInfo *item = location->validateUrlPath(m_tmpPath);
+        DirItemInfo *item = validateCurrentUrl(location,authData);
         if (item)
         {
+            //now if there is Authentication Data
+            //at this point item is ready and authentication if necessary worked
+            if (item && !authData.isEmpty())
+            {
+                m_authDataStore->store(item->authenticationPath(),
+                                       authData.user,
+                                       authData.password,
+                                       savePassword);
+            }
             //isContentReadable() must already carry execution permission
-            if (item->isValid() && item->isDir() && item->isContentReadable())
+            if (item->isValid() && item->isBrowsable() && item->isContentReadable())
             {
                 location->setInfoItem(item);
                 if (location != m_curLoc)
@@ -146,38 +175,6 @@
 }
 
 
-QString  LocationsFactory::stringAfterSlashes(const QString &url, int firstSlashIndex) const
-{
-    QString ret;
-    if (firstSlashIndex >=0)
-    {
-        while ( firstSlashIndex < url.length() && url.at(firstSlashIndex) == QDir::separator())
-        {
-            ++firstSlashIndex;
-        }
-        if (firstSlashIndex < url.length())
-        {
-            ret = url.mid(firstSlashIndex);
-        }
-    }
-    else
-    {
-        ret = url;
-        firstSlashIndex = 0;
-    }
-    //replace any double slashes by just one
-    for(int charCounter = ret.size() -1; charCounter > 0; --charCounter)
-    {
-        if (ret.at(charCounter) == QDir::separator() &&
-                ret.at(charCounter-1) == QDir::separator())
-        {
-            ret.remove(charCounter,1);
-        }
-    }
-    return ret;
-}
-
-
 void LocationsFactory::storeValidFileInfo(DirItemInfo *item)
 {
     if (m_lastValidFileInfo)
@@ -186,3 +183,49 @@
     }
     m_lastValidFileInfo = item;
 }
+
+
+void LocationsFactory::onUrlNeedsAuthentication(QString, QString)
+{
+    m_lastUrlNeedsAuthentication = true;
+}
+
+
+bool LocationsFactory::lastUrlNeedsAuthencation() const
+{
+    return m_lastUrlNeedsAuthentication;
+}
+
+
+DirItemInfo * LocationsFactory::validateCurrentUrl(Location *location, const NetAuthenticationData &authData)
+{
+    //when there is authentication data, set the authentication before validating an item
+    if (!authData.isEmpty())
+    {
+        location->setAuthentication(authData.user, authData.password);
+    }
+
+    DirItemInfo *item = location->validateUrlPath(m_tmpPath);
+
+    //for remote locations, authentication might have failed
+    //if so try to use a stored authentication data and authenticate it again
+    if (   item && item->needsAuthentication()
+        && location->useAuthenticationDataIfExists(*item))
+    {
+        delete item;
+        item = location->validateUrlPath(m_tmpPath);
+    }
+    //if failed it is necessary to ask the user to provide user/password
+    if ( item && item->needsAuthentication() )
+    {
+        location->notifyItemNeedsAuthentication(item);
+        delete item;
+        item = 0;
+    }
+    if (item && !item->isContentReadable())
+    {
+        delete item;
+        item = 0;
+    }
+    return item;
+}

=== modified file 'src/plugin/folderlistmodel/locationsfactory.h'
--- src/plugin/folderlistmodel/locationsfactory.h	2014-05-24 01:40:01 +0000
+++ src/plugin/folderlistmodel/locationsfactory.h	2015-03-08 12:31:26 +0000
@@ -28,6 +28,8 @@
 
 class Location;
 class DirItemInfo;
+class NetAuthenticationDataList;
+class NetAuthenticationData;
 
 /*!
  * \brief The LocationsFactory class represents the set of main
@@ -82,11 +84,17 @@
      *   When the location changes, the signal \ref locationChanged() is fired.
      *
      * \param urlPath the url like: file:///Item trash:///item /item, it MUST point to a valid Directory
+     * \param user     an user when the URL requires authentication [optional]
+     * \param password when the URL requires authentication [optional]
+     *
      * \return the location that supports the urlPath or NULL when \a urlPath is NOT a valid url or it is not a valid Directory
      *
      *  \sa \ref parse() \ref location()
      */
-    Location * setNewPath(const QString& urlPath);
+    Location * setNewPath(const QString& urlPath,
+                          const QString& user = QString(),
+                          const QString& password = QString(),
+                          bool savePassword = false);
 
     /*!
      * \brief location()
@@ -113,19 +121,53 @@
      */
     const DirItemInfo* lastValidFileInfo() const { return m_lastValidFileInfo; }
 
+    /*!
+     * \brief lastUrlNeedsAuthencation()
+     * \return true when last URL used in setNewPath() needs authentication
+     *
+     * It can be used to show a dialog to the user asking for user/password
+     * instead of showing a message saying that url does not exist
+     */
+    bool        lastUrlNeedsAuthencation() const;
+
+private:
+    /*!
+     * \brief storeValidFileInfo() saves an item created by \ref setNewPath() when
+     *  the item is not Browsable.
+     *
+     *  It happens for example when the \a urlPath entered
+     *  in \ref setNewPath() is a file (not a DIR nor other Browsable item)
+     *
+     * \param item
+     */
     void        storeValidFileInfo(DirItemInfo *item);
 
+    /*!
+     * \brief validateCurrentUrl() it attempts to validate the current URL being parsed
+     *
+     * The validation includes authentication, if a Authentication Data is already avaialable
+     * it is set to the location being parsed.
+     * When authentication fails the signal Location::needsAuthentication() is emitted
+     *
+     * \param location current Location for the current urlPath entered in \ref setNewPath()
+     *
+     * \return new Item validated (authenticated when remote authentication is required), otherwise NULL
+     */
+    DirItemInfo *validateCurrentUrl(Location *location, const NetAuthenticationData&);
+
 signals:
     void        locationChanged(const Location *old, const Location *current);
 
-private:
-    QString     stringAfterSlashes(const QString& url, int firstSlashIndex) const;
+private slots:
+    void        onUrlNeedsAuthentication(QString, QString);
 
 private:
      Location         *  m_curLoc;
      QList<Location*>    m_locations;
      QString             m_tmpPath;
-     DirItemInfo      * m_lastValidFileInfo;
+     DirItemInfo      *  m_lastValidFileInfo;
+     NetAuthenticationDataList * m_authDataStore;
+     bool                m_lastUrlNeedsAuthentication;
 
 #if defined(REGRESSION_TEST_FOLDERLISTMODEL)
     friend class TestDirModel;

=== added directory 'src/plugin/folderlistmodel/net'
=== added file 'src/plugin/folderlistmodel/net/netauthenticationdata.cpp'
--- src/plugin/folderlistmodel/net/netauthenticationdata.cpp	1970-01-01 00:00:00 +0000
+++ src/plugin/folderlistmodel/net/netauthenticationdata.cpp	2015-03-08 12:31:26 +0000
@@ -0,0 +1,219 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Canonical Ltd.
+ * Copyright 2014 Carlos J Mazieri <carlos.mazieri@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * File: netauthenticationdata.cpp
+ * Date: 29/11/2014
+ */
+
+#include "netauthenticationdata.h"
+
+#include <QStandardPaths>
+#include <QDir>
+#include <QSettings>
+#include <QCoreApplication>
+#include <QDebug>
+
+#define CHAR_CRYPT_OFFSET  31
+
+NetAuthenticationDataList *  NetAuthenticationDataList::m_instance = 0;
+void *                       NetAuthenticationDataList::m_parent   = 0;
+
+
+NetAuthenticationDataList::NetAuthenticationDataList(): m_savedAuths(0)
+{   
+    //settings file does not need to open  all the time
+    loadSavedAuthenticationData();
+}
+
+
+NetAuthenticationDataList::~NetAuthenticationDataList()
+{
+   qDeleteAll(m_urlEntries);
+   m_urlEntries.clear();
+   m_parent  = 0;
+   m_instance = 0;
+   closeAuthenticationStore();
+}
+
+
+NetAuthenticationDataList * NetAuthenticationDataList::getInstance(void *parent)
+{
+    if (m_instance == 0)
+    {
+        m_instance = new NetAuthenticationDataList();
+        m_parent  = parent;
+    }
+    return m_instance;
+}
+
+
+void NetAuthenticationDataList::releaseInstance(void *parent)
+{
+    if (parent == m_parent && m_instance != 0)
+    {
+        delete m_instance;
+        m_instance = 0;
+        m_parent = 0;
+    }
+}
+
+
+const NetAuthenticationData * NetAuthenticationDataList::get(const QString& url) const
+{
+    const NetAuthenticationData * ret = 0;   
+    if (!url.isEmpty())
+    {
+        ret = m_urlEntries.value(url);
+    }
+    return ret;
+}
+
+bool  NetAuthenticationDataList::store(const QString &url, const QString &u, const QString &p, bool save)
+{
+    bool ret = false;
+    if (!url.isEmpty())
+    {
+        ret = true;
+        NetAuthenticationData * data = 0;
+        if ( (data = const_cast<NetAuthenticationData*> (get(url))) == 0)
+        {
+            data = new NetAuthenticationData();
+            m_urlEntries.insert(url, data);
+        }
+        data->user     = u;
+        data->password = p;
+        if (save )
+        {
+            ret = saveAuthenticationData(url, data);
+        }
+    }  
+   return ret;
+}
+
+
+
+bool  NetAuthenticationDataList::store(const QUrl &url, bool save)
+{
+   QString user   = url.userName();
+   QString passwd = url.password();
+
+   QUrl url2(url);
+   url2.setUserName(QLatin1String(0));
+   url2.setPassword(QLatin1String(0));
+
+   return store(url2.toString(), user,passwd, save);
+}
+
+
+void NetAuthenticationDataList::loadSavedAuthenticationData()
+{
+    QLatin1Char slash('/');
+    QLatin1String userKey("user");
+    QLatin1String passKey("password");
+    openAuthenticationStore();
+    QStringList urls = m_savedAuths->childGroups();
+    int counter = urls.count();  
+    while(counter--)
+    {
+        m_savedAuths->beginGroup(urls.at(counter));
+        QString cleanUrl = urls.at(counter);
+        cleanUrl.replace(QLatin1Char('}'), slash);
+        QString user = m_savedAuths->value(userKey).toString();
+        QString pass = m_savedAuths->value(passKey).toString();
+        store(cleanUrl, user, decryptPassword(pass));
+        m_savedAuths->endGroup();
+    }
+    closeAuthenticationStore();
+}
+
+bool NetAuthenticationDataList::saveAuthenticationData(const QString& url, const NetAuthenticationData *d)
+{
+    QLatin1Char slash('/');
+    QLatin1String userKey("user");
+    QLatin1String passKey("password");
+    QString keyUrl(url);
+    keyUrl.replace(slash, QLatin1Char('}'));
+
+    openAuthenticationStore();
+    m_savedAuths->setValue(keyUrl + slash + userKey, d->user);
+    m_savedAuths->setValue(keyUrl + slash + passKey, encryptPassord(d->password));
+    m_savedAuths->sync();
+    bool ret = m_savedAuths->status() == QSettings::NoError;
+    if (!ret)
+    {
+        qDebug() << Q_FUNC_INFO << "ERROR: could not save settings:" << m_savedAuths->fileName();
+    }
+    closeAuthenticationStore();
+    return ret;
+}
+
+/*!
+ * \brief NetAuthenticationDataList::encryptPassord() simple crypt function hide the user password
+ *
+ * \param p  the ascii password
+ * \return
+ */
+QString NetAuthenticationDataList::encryptPassord(const QString &p)
+{
+    QString crypted;
+    short unicode = 0;
+    for (int counter=0; counter < p.size(); ++counter)
+    {
+        unicode = p.at(counter).unicode() - CHAR_CRYPT_OFFSET + counter;
+        crypted.append( QChar(unicode) );
+    }
+    return crypted.toLocal8Bit().toHex();
+}
+
+
+QString NetAuthenticationDataList::decryptPassword(const QString &p)
+{
+    QString crypted( QByteArray::fromHex(p.toLocal8Bit()) );
+    QString decrypted;
+    short unicode = 0;
+    for (int counter=0; counter < crypted.size(); ++counter)
+    {
+       unicode = crypted.at(counter).unicode() + CHAR_CRYPT_OFFSET - counter;
+       decrypted.append( QChar(unicode) );
+    }
+    return decrypted;
+}
+
+void NetAuthenticationDataList::openAuthenticationStore()
+{
+    if (m_savedAuths == 0)
+    {
+         QString settingsLocation =
+            QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first()
+            + QLatin1Char('/') + QCoreApplication::applicationName()
+            + QLatin1Char('/') + QLatin1String("authentication.conf");
+         m_savedAuths = new QSettings(settingsLocation, QSettings::IniFormat);
+#if DEBUG_MESSAGES
+     qDebug() << Q_FUNC_INFO << "auth file:" << m_savedAuths->fileName();
+#endif
+    }
+}
+
+
+void NetAuthenticationDataList::closeAuthenticationStore()
+{
+     if (m_savedAuths != 0)
+     {
+         delete m_savedAuths;
+         m_savedAuths = 0;
+     }
+}

=== added file 'src/plugin/folderlistmodel/net/netauthenticationdata.h'
--- src/plugin/folderlistmodel/net/netauthenticationdata.h	1970-01-01 00:00:00 +0000
+++ src/plugin/folderlistmodel/net/netauthenticationdata.h	2015-03-08 12:31:26 +0000
@@ -0,0 +1,97 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Canonical Ltd.
+ * Copyright 2014 Carlos J Mazieri <carlos.mazieri@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * File: netauthenticationdata.h
+ * Date: 29/11/2014
+ */
+
+#ifndef NETAUTHENTICATIONDATA_H
+#define NETAUTHENTICATIONDATA_H
+
+#include <QHash>
+#include <QUrl>
+
+class QSettings;
+
+/*!
+ * \brief The NetAuthenticationData struct
+ *
+ *  Just keeps data for Network authentication (protocol independent)
+ */
+
+struct NetAuthenticationData
+{
+public:
+    NetAuthenticationData() {}
+    NetAuthenticationData(const QString&u, const QString& p) :
+         user(u), password(p) {}
+    inline bool isEmpty() const { return user.isEmpty(); }
+    QString user;
+    QString password; 
+};
+
+
+/*!
+ * \brief The NetAuthenticationDataList class
+ *
+ *  It keeps a list of the current URLs being used and their Authentication data
+ *
+ *  This information may be required for every connection (e.g. Samba shares).
+ *
+ *  It implements a singleton design pattern to keep a unique Authentication Data list per application
+ *    \sa \ref getInstance() and \ref releaseInstance()
+ *
+ *  The authentication data can be saved for NOT always asking the user
+ *
+ *  \note It is intended to be used for any protocol.
+ *        The URL being stored must be the part or prefix which requires authentication
+ *        Example for Samba: if a user enters with a url like smb://localhost/any_share/folder1/folder2
+ *                           only the share part requires authentication with is smb://localhost/any_share
+ *                           The same authentication data can be used for any smb://localhost/any_share sub-items
+ *
+ */
+class NetAuthenticationDataList
+{
+public:
+  static  NetAuthenticationDataList *  getInstance(void *parent);
+  static  void                         releaseInstance(void *parent);
+  ~NetAuthenticationDataList();
+
+public:
+  bool                           store(const QUrl& url, bool save = false);
+  bool                           store(const QString& url, const QString& u, const QString& p, bool save =false);
+  const NetAuthenticationData *  get(const QString&) const;
+
+private:
+  NetAuthenticationDataList();
+
+private:
+  void                  openAuthenticationStore();
+  void                  closeAuthenticationStore();
+  QString               encryptPassord(const QString& p);
+  QString               decryptPassword(const QString& p);
+  void                  loadSavedAuthenticationData();
+  bool                  saveAuthenticationData(const QString& url, const NetAuthenticationData * );
+
+private:  //url     authentication data
+  QHash <QString , NetAuthenticationData*>  m_urlEntries;
+  static NetAuthenticationDataList *        m_instance;
+  static void                      *        m_parent;
+  QSettings                        *        m_savedAuths;
+};
+
+#endif // NETAUTHENTICATIONDATA_H

=== modified file 'src/plugin/folderlistmodel/trash/trashlocation.cpp'
--- src/plugin/folderlistmodel/trash/trashlocation.cpp	2014-05-17 18:07:11 +0000
+++ src/plugin/folderlistmodel/trash/trashlocation.cpp	2015-03-08 12:31:26 +0000
@@ -180,8 +180,7 @@
 
 
 void TrashLocation::startExternalFsWatcher()
-{
-    //TODO implement a Watcher for this
+{   
     //modify the existent watcher to work having  a list of paths
     if (m_usingExternalWatcher && m_extWatcher == 0 && isRoot())
     {     
@@ -286,3 +285,32 @@
     ret.setTargetFullName( trashInfo.absFile );
     return ret;
 }
+
+
+DirItemInfo * TrashLocation::newItemInfo(const QString &urlPath)
+{
+    return new TrashItemInfo(urlPath);
+}
+
+
+/*!
+ * \brief TrashLocation::newListWorker() It is provided only because it is a pure method
+ *
+ *   As \rev fetchItems() is reemplemented this method should never be used
+ *
+ * \param urlPath
+ * \param filter
+ * \param isRecursive
+ * \return
+ */
+DirListWorker * TrashLocation::newListWorker(const QString &urlPath, QDir::Filter filter, const bool isRecursive)
+{
+    Q_UNUSED(isRecursive);
+    QString trashDir;
+    if (m_info && !m_info->isRoot())
+    {
+        TrashItemInfo *item = static_cast<TrashItemInfo*> (m_info);
+        trashDir = item->getTrashDir();
+    }
+    return new TrashListWorker(trashDir, urlPath, filter);
+}

=== modified file 'src/plugin/folderlistmodel/trash/trashlocation.h'
--- src/plugin/folderlistmodel/trash/trashlocation.h	2014-05-17 18:07:11 +0000
+++ src/plugin/folderlistmodel/trash/trashlocation.h	2015-03-08 12:31:26 +0000
@@ -45,6 +45,11 @@
 
     virtual DirItemInfo *validateUrlPath(const QString& urlPath);
 
+    virtual DirItemInfo * newItemInfo(const QString& urlPath);
+    virtual DirListWorker * newListWorker(const QString &urlPath,
+                                          QDir::Filter filter,
+                                          const bool isRecursive);
+
     /*!
      * \brief getMovePairPaths() Get: original path and destination trash path
      *