← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

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

 

Review: Approve

Small typo in method name, otherwise fine.

Diff comments:

> === 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

Typo: Should be lastUrlNeedsAuthentication

> +{
> +    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
>       *
> 


-- 
https://code.launchpad.net/~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-03/+merge/252219
Your team Ubuntu File Manager Developers is subscribed to branch lp:ubuntu-filemanager-app.


Follow ups