[X2Go-Commits] [x2goclient] 01/01: Add support for sessions folders.

git-admin at x2go.org git-admin at x2go.org
Tue Jul 29 17:01:14 CEST 2014


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2goclient.

commit 5293d719e7fba0c956983ce9b3c89f7f91895a20
Author: Oleksandr Shneyder <o.shneyder at phoca-gmbh.de>
Date:   Tue Jul 29 17:01:04 2014 +0200

    Add support for sessions folders.
---
 debian/changelog                  |    1 +
 exportdialog.cpp                  |  191 +++++-----
 folderbutton.cpp                  |  149 ++++++++
 sessionbutton.h => folderbutton.h |   68 ++--
 icons/128x128/folder.png          |  Bin 0 -> 3220 bytes
 onmainwindow.cpp                  |  325 ++++-------------
 onmainwindow.h                    |   46 ++-
 onmainwindow_privat.h             |    1 +
 resources.rcc                     |    3 +
 sessionbutton.cpp                 |  123 ++++---
 sessionbutton.h                   |    5 +
 sessionexplorer.cpp               |  387 +++++++++++++++++++++
 sessionexplorer.h                 |   85 +++++
 sessionmanagedialog.cpp           |  219 ++++++------
 svg/folder.svg                    |  696 +++++++++++++++++++++++++++++++++++++
 svg/folder_grey.svg               |  513 +++++++++++++++++++++++++++
 x2goclient.pro                    |    8 +-
 17 files changed, 2244 insertions(+), 576 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 52ee219..4f63a21 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -28,6 +28,7 @@ x2goclient (4.0.3.0-0x2go1) UNRELEASED; urgency=low
     - Start x2gohelper from X2Go Client. Revert name changing of X2Go Client and
       x2gohelper.
     - Add Makefile for x2gohelper.
+    - Add support for sessions folders.
 
   [ Mike DePaulo ]
   * New upstream release (4.0.3.0):
diff --git a/exportdialog.cpp b/exportdialog.cpp
index a7dae27..9f902ba 100644
--- a/exportdialog.cpp
+++ b/exportdialog.cpp
@@ -30,58 +30,59 @@
 #include "sessionbutton.h"
 #include "onmainwindow.h"
 #include <QFileDialog>
+#include "sessionexplorer.h"
 
 ExportDialog::ExportDialog ( QString sid,QWidget * par, Qt::WFlags f )
-		: QDialog ( par,f )
+    : QDialog ( par,f )
 {
-	sessionId=sid;
-	QVBoxLayout* ml=new QVBoxLayout ( this );
-	QFrame *fr=new QFrame ( this );
-	QHBoxLayout* frLay=new QHBoxLayout ( fr );
-
-	parent= ( ONMainWindow* ) par;
-
-	QPushButton* cancel=new QPushButton ( tr ( "&Cancel" ),this );
-	QHBoxLayout* bLay=new QHBoxLayout();
-
-	sessions=new QListView ( fr );
-	frLay->addWidget ( sessions );
-
-	exportDir=new QPushButton ( tr ( "&share" ),fr );
-	editSession=new QPushButton ( tr ( "&Preferences ..." ),fr );
-	newDir=new QPushButton ( tr ( "&Custom folder ..." ),fr );
-
-
-	QVBoxLayout* actLay=new QVBoxLayout();
-	actLay->addWidget ( exportDir );
-	actLay->addWidget ( editSession );
-	actLay->addWidget ( newDir );
-	actLay->addStretch();
-	frLay->addLayout ( actLay );
-
-	QShortcut* sc=new QShortcut ( QKeySequence ( tr ( "Delete","Delete" ) ),
-	                              this );
-	connect ( cancel,SIGNAL ( clicked() ),this,SLOT ( close() ) );
-	connect ( sc,SIGNAL ( activated() ),exportDir,SIGNAL ( clicked() ) );
-	connect ( editSession,SIGNAL ( clicked() ),this,SLOT ( slot_edit() ) );
-	connect ( newDir,SIGNAL ( clicked() ),this,SLOT ( slotNew() ) );
-	connect ( exportDir,SIGNAL ( clicked() ),this,SLOT ( slot_accept() ) );
-	bLay->setSpacing ( 5 );
-	bLay->addStretch();
-	bLay->addWidget ( cancel );
-	ml->addWidget ( fr );
-	ml->addLayout ( bLay );
-
-	fr->setFrameStyle ( QFrame::StyledPanel | QFrame::Raised );
-	fr->setLineWidth ( 2 );
-
-	setSizeGripEnabled ( true );
-	setWindowTitle ( tr ( "share folders" ) );
-	connect ( sessions,SIGNAL ( clicked ( const QModelIndex& ) ),
-	          this,SLOT ( slot_activated ( const QModelIndex& ) ) );
-	connect ( sessions,SIGNAL ( doubleClicked ( const QModelIndex& ) ),
-	          this,SLOT ( slot_dclicked ( const QModelIndex& ) ) );
-	loadSessions();
+    sessionId=sid;
+    QVBoxLayout* ml=new QVBoxLayout ( this );
+    QFrame *fr=new QFrame ( this );
+    QHBoxLayout* frLay=new QHBoxLayout ( fr );
+
+    parent= ( ONMainWindow* ) par;
+
+    QPushButton* cancel=new QPushButton ( tr ( "&Cancel" ),this );
+    QHBoxLayout* bLay=new QHBoxLayout();
+
+    sessions=new QListView ( fr );
+    frLay->addWidget ( sessions );
+
+    exportDir=new QPushButton ( tr ( "&share" ),fr );
+    editSession=new QPushButton ( tr ( "&Preferences ..." ),fr );
+    newDir=new QPushButton ( tr ( "&Custom folder ..." ),fr );
+
+
+    QVBoxLayout* actLay=new QVBoxLayout();
+    actLay->addWidget ( exportDir );
+    actLay->addWidget ( editSession );
+    actLay->addWidget ( newDir );
+    actLay->addStretch();
+    frLay->addLayout ( actLay );
+
+    QShortcut* sc=new QShortcut ( QKeySequence ( tr ( "Delete","Delete" ) ),
+                                  this );
+    connect ( cancel,SIGNAL ( clicked() ),this,SLOT ( close() ) );
+    connect ( sc,SIGNAL ( activated() ),exportDir,SIGNAL ( clicked() ) );
+    connect ( editSession,SIGNAL ( clicked() ),this,SLOT ( slot_edit() ) );
+    connect ( newDir,SIGNAL ( clicked() ),this,SLOT ( slotNew() ) );
+    connect ( exportDir,SIGNAL ( clicked() ),this,SLOT ( slot_accept() ) );
+    bLay->setSpacing ( 5 );
+    bLay->addStretch();
+    bLay->addWidget ( cancel );
+    ml->addWidget ( fr );
+    ml->addLayout ( bLay );
+
+    fr->setFrameStyle ( QFrame::StyledPanel | QFrame::Raised );
+    fr->setLineWidth ( 2 );
+
+    setSizeGripEnabled ( true );
+    setWindowTitle ( tr ( "share folders" ) );
+    connect ( sessions,SIGNAL ( clicked ( const QModelIndex& ) ),
+              this,SLOT ( slot_activated ( const QModelIndex& ) ) );
+    connect ( sessions,SIGNAL ( doubleClicked ( const QModelIndex& ) ),
+              this,SLOT ( slot_dclicked ( const QModelIndex& ) ) );
+    loadSessions();
 }
 
 
@@ -90,89 +91,89 @@ ExportDialog::~ExportDialog()
 
 void ExportDialog::loadSessions()
 {
-	QStringListModel *model= ( QStringListModel* ) sessions->model();
-	if ( !model )
-		model=new QStringListModel();
-	sessions->setModel ( model );
+    QStringListModel *model= ( QStringListModel* ) sessions->model();
+    if ( !model )
+        model=new QStringListModel();
+    sessions->setModel ( model );
 
-	QStringList dirs;
-	model->setStringList ( dirs );
+    QStringList dirs;
+    model->setStringList ( dirs );
 
-	X2goSettings st ( "sessions" );
+    X2goSettings st ( "sessions" );
 
 
-	QString exports=st.setting()->value ( sessionId+"/export",
-	                           ( QVariant ) QString::null ).toString();
+    QString exports=st.setting()->value ( sessionId+"/export",
+                                          ( QVariant ) QString::null ).toString();
 
-	QStringList lst=exports.split ( ";",QString::SkipEmptyParts );
-	for ( int i=0;i<lst.size();++i )
-	{
+    QStringList lst=exports.split ( ";",QString::SkipEmptyParts );
+    for ( int i=0; i<lst.size(); ++i )
+    {
 #ifndef Q_OS_WIN
-		QStringList tails=lst[i].split ( ":",QString::SkipEmptyParts );
+        QStringList tails=lst[i].split ( ":",QString::SkipEmptyParts );
 #else
-		QStringList tails=lst[i].split ( "#",QString::SkipEmptyParts );
+        QStringList tails=lst[i].split ( "#",QString::SkipEmptyParts );
 #endif
-		dirs<<tails[0];
-	}
+        dirs<<tails[0];
+    }
 
 
-	model->setStringList ( dirs );
+    model->setStringList ( dirs );
 
 
-	//     removeSession->setEnabled(false);
-	exportDir->setEnabled ( false );
-	sessions->setEditTriggers ( QAbstractItemView::NoEditTriggers );
+    //     removeSession->setEnabled(false);
+    exportDir->setEnabled ( false );
+    sessions->setEditTriggers ( QAbstractItemView::NoEditTriggers );
 }
 
 
 void ExportDialog::slot_activated ( const QModelIndex& )
 {
-	//     removeSession->setEnabled(true);
-	exportDir->setEnabled ( true );
+    //     removeSession->setEnabled(true);
+    exportDir->setEnabled ( true );
 }
 
 void ExportDialog::slot_dclicked ( const QModelIndex& )
 {
-	slot_accept();
+    slot_accept();
 }
 
 
 void ExportDialog::slotNew()
 {
-	directory=QString::null;
-	directory= QFileDialog::getExistingDirectory (
-	               this,
-	               tr ( "Select folder" ),
-	               QDir::homePath() );
+    directory=QString::null;
+    directory= QFileDialog::getExistingDirectory (
+                   this,
+                   tr ( "Select folder" ),
+                   QDir::homePath() );
 
-	if ( directory!=QString::null )
-		accept();
+    if ( directory!=QString::null )
+        accept();
 
 }
 
 
 void ExportDialog::slot_edit()
 {
-	const QList<SessionButton*>* sess=parent->getSessionsList();
-	for ( int i=0;i< sess->size();++i )
-	{
-		if ( sess->at ( i )->id() ==sessionId )
-		{
-			parent->exportsEdit ( sess->at ( i ) );
-			break;
-		}
-	}
-	loadSessions();
+    const QList<SessionButton*>* sess=parent->getSessionExplorer()->getSessionsList();
+    for ( int i=0; i< sess->size(); ++i )
+    {
+        if ( sess->at ( i )->id() ==sessionId )
+        {
+            parent->getSessionExplorer()->exportsEdit ( sess->at ( i ) );
+            break;
+        }
+    }
+    loadSessions();
 }
 
 
 
 void ExportDialog::slot_accept()
 {
-	int ind=sessions->currentIndex().row();
-	if ( ind<0 )
-		return;
-	QStringListModel *model= ( QStringListModel* ) sessions->model();
-	directory=model->stringList() [ind];
-	accept();
+    int ind=sessions->currentIndex().row();
+    if ( ind<0 )
+        return;
+    QStringListModel *model= ( QStringListModel* ) sessions->model();
+    directory=model->stringList() [ind];
+    accept();
 }
diff --git a/folderbutton.cpp b/folderbutton.cpp
new file mode 100644
index 0000000..28c7a2b
--- /dev/null
+++ b/folderbutton.cpp
@@ -0,0 +1,149 @@
+/**************************************************************************
+*   Copyright (C) 2005-2014 by Oleksandr Shneyder                         *
+*   o.shneyder at phoca-gmbh.de                                              *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*   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 General Public License for more details.                          *
+*                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
+***************************************************************************/
+
+#include "folderbutton.h"
+#include "x2goclientconfig.h"
+#include "x2goutils.h"
+
+#include <QFont>
+#include <QPixmap>
+#include <QLabel>
+#include "x2gosettings.h"
+#include <QDir>
+#include <QLayout>
+#include <QPushButton>
+#include "onmainwindow.h"
+#include "x2gologdebug.h"
+#include <QApplication>
+#include <QDesktopWidget>
+#include "sessionexplorer.h"
+#include <QMouseEvent>
+
+
+FolderButton::FolderButton ( ONMainWindow* mw,QWidget *parent, QString folderPath, QString folderName )
+    : SVGFrame ( ":/svg/folder.svg",false,parent )
+{
+    QPalette pal=palette();
+    pal.setColor ( QPalette::Active, QPalette::WindowText, QPalette::Mid );
+    pal.setColor ( QPalette::Active, QPalette::ButtonText, QPalette::Mid );
+    pal.setColor ( QPalette::Active, QPalette::Text, QPalette::Mid );
+    pal.setColor ( QPalette::Inactive, QPalette::WindowText, QPalette::Mid );
+    pal.setColor ( QPalette::Inactive, QPalette::ButtonText, QPalette::Mid );
+    pal.setColor ( QPalette::Inactive, QPalette::Text, QPalette::Mid );
+
+    setPalette(pal);
+
+    path=folderPath;
+    name=folderName;
+
+    QFont fnt=font();
+    if ( mw->retMiniMode() )
+#ifdef Q_WS_HILDON
+        fnt.setPointSize ( 10 );
+#else
+        fnt.setPointSize ( 9 );
+#endif
+    setFont ( fnt );
+    setFocusPolicy ( Qt::NoFocus );
+    bool miniMode=mw->retMiniMode();
+    if ( !miniMode )
+        setFixedSize ( 340,190 );
+    else
+        setFixedSize ( 250,145 );
+
+    par= mw;
+    connect ( this,SIGNAL ( clicked() ),this,SLOT ( slotClicked() ) );
+
+
+    nameLabel=new QLabel ( this );
+    description=tr("Sessions folder");
+
+    setChildrenList(QStringList() );
+
+    icon=new QLabel ( this );
+
+    QString sessIcon=":icons/128x128/folder.png";
+    QPixmap* pix=new QPixmap( sessIcon );
+    nameLabel->setWordWrap(true);
+    nameLabel->setTextInteractionFlags(Qt::NoTextInteraction);
+
+    icon->move ( 10,10 );
+
+    if ( !miniMode )
+    {
+        nameLabel->move ( 80,34 );
+        nameLabel->setFixedSize(235,135);
+        icon->setPixmap ( pix->scaled ( 64,64,Qt::IgnoreAspectRatio,
+                                        Qt::SmoothTransformation ) );
+    }
+    else
+    {
+        nameLabel->move ( 64,18 );
+        nameLabel->setFixedSize(170,120);
+        icon->setPixmap ( pix->scaled ( 48,48,Qt::IgnoreAspectRatio,
+                                        Qt::SmoothTransformation ) );
+    }
+    delete pix;
+
+}
+
+FolderButton::~FolderButton()
+{}
+
+void FolderButton::slotClicked()
+{
+    emit folderSelected ( this );
+}
+
+bool FolderButton::lessThen ( const FolderButton* b1,
+                              const FolderButton* b2 )
+{
+    return b1->name.toLower().localeAwareCompare (
+               b2->name.toLower() ) <0;
+}
+
+void FolderButton::mousePressEvent ( QMouseEvent * event )
+{
+    x2goDebug<<"mpress";
+    SVGFrame::mousePressEvent ( event );
+    loadBg ( ":/svg/folder_grey.svg" );
+}
+
+void FolderButton::mouseReleaseEvent ( QMouseEvent * event )
+{
+    x2goDebug<<"mrelease";
+    SVGFrame::mouseReleaseEvent ( event );
+    int x=event->x();
+    int y=event->y();
+    loadBg ( ":/svg/folder.svg" );
+    if ( x>=0 && x< width() && y>=0 && y<height() )
+        emit clicked();
+}
+
+void FolderButton::setChildrenList(QStringList children)
+{
+    QString text="<b>"+name+"</b>";
+    if(description.length()>0)
+    {
+        text+="<br>("+description+")";
+    }
+    if(children.count())
+    {
+        text+="<p style=\"color:grey\">"+children.join(", ")+"</p>";
+    }
+    nameLabel->setText(text);
+}
diff --git a/sessionbutton.h b/folderbutton.h
similarity index 56%
copy from sessionbutton.h
copy to folderbutton.h
index d4e51a4..a5eaf99 100644
--- a/sessionbutton.h
+++ b/folderbutton.h
@@ -15,8 +15,8 @@
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/
 
-#ifndef SESSIONBUTTON_H
-#define SESSIONBUTTON_H
+#ifndef FOLDERBUTTON_H
+#define FOLDERBUTTON_H
 
 #include "SVGFrame.h"
 #include <QPushButton>
@@ -28,64 +28,40 @@ class QPushButton;
 /**
 	@author Oleksandr Shneyder <oleksandr.shneyder at obviously-nice.de>
 */
-class SessionButton : public SVGFrame
+class FolderButton : public SVGFrame
 {
     Q_OBJECT
 public:
-    enum {KDE,GNOME,LXDE,XFCE,MATE,UNITY,RDP,XDMCP,SHADOW,PUBLISHED,OTHER,APPLICATION};
-    SessionButton ( ONMainWindow* mw, QWidget* parent,QString id );
-    ~SessionButton();
-    QString id() {
-        return sid;
-    }
-    void redraw();
-    const QPixmap* sessIcon() {
+    FolderButton ( ONMainWindow* mw, QWidget* parent, QString folderPath, QString folderName );
+    ~FolderButton();
+
+    const QPixmap* folderIcon() {
         return icon->pixmap();
     }
-    static bool lessThen ( const SessionButton* b1, const SessionButton* b2 );
-    QString name();
+    static bool lessThen ( const FolderButton* b1, const FolderButton* b2 );
+    QString getName()
+    {
+        return name;
+    }
+    QString getPath()
+    {
+        return path;
+    }
+    void setChildrenList(QStringList children);
 private:
-    QString sid;
-    QLabel* sessName;
-    QLabel* sessStatus;
+    QString path;
+    QString name;
+    QString description;
+    QLabel* nameLabel;
     QLabel* icon;
-    QComboBox* cmdBox;
-    QLabel* cmd;
-    QLabel* serverIcon;
-    QLabel* geomIcon;
-    QLabel* cmdIcon;
-    QLabel* server;
-    QPushButton* editBut;
-    QLabel* geom;
-    QMenu* sessMenu;
-    QComboBox* geomBox;
-    QPushButton* sound;
-    QLabel* soundIcon;
     ONMainWindow* par;
-    QAction* act_edit;
-    QAction* act_createIcon;
-    QAction* act_remove;
-    bool rootless;
-    bool published;
-    bool editable;
 
 private slots:
     void slotClicked();
-    void slotEdit();
-    void slot_soundClicked();
-    void slot_cmd_change ( const QString& command );
-    void slot_geom_change ( const QString& new_g );
-    void slotRemove();
-    void slotMenuHide();
-    void slotShowMenu();
-    void slotCreateSessionIcon();
 signals:
-    void sessionSelected ( SessionButton* );
-    void signal_edit ( SessionButton* );
-    void signal_remove ( SessionButton* );
+    void folderSelected ( FolderButton* );
     void clicked();
 protected:
-    virtual void mouseMoveEvent ( QMouseEvent * event );
     virtual void mousePressEvent ( QMouseEvent * event );
     virtual void mouseReleaseEvent ( QMouseEvent * event );
 };
diff --git a/icons/128x128/folder.png b/icons/128x128/folder.png
new file mode 100644
index 0000000..f237d70
Binary files /dev/null and b/icons/128x128/folder.png differ
diff --git a/onmainwindow.cpp b/onmainwindow.cpp
index 8acec61..4f4bceb 100644
--- a/onmainwindow.cpp
+++ b/onmainwindow.cpp
@@ -44,7 +44,6 @@ bool ONMainWindow::debugging=false;
 
 ONMainWindow::ONMainWindow ( QWidget *parent ) :QMainWindow ( parent )
 {
-
     haveTerminal=false;
 #ifndef Q_OS_WIN
     QFile fl("/dev/tty");
@@ -113,7 +112,6 @@ ONMainWindow::ONMainWindow ( QWidget *parent ) :QMainWindow ( parent )
     sshConnection=0;
     sessionStatusDlg=0;
     noSessionEdit=false;
-    lastSession=0l;
     changeBrokerPass=false;
     resumeAfterSuspending=false;
     forceToShowTrayicon=false;
@@ -399,6 +397,9 @@ ONMainWindow::ONMainWindow ( QWidget *parent ) :QMainWindow ( parent )
               SLOT ( slotAbout() ) );
 
 
+    sessionExplorer=new SessionExplorer(this);
+
+
 #ifdef Q_OS_DARWIN
     embedMode=false;
 #endif
@@ -749,7 +750,15 @@ void ONMainWindow::initWidgetsNormal()
     u->show();
     uname->show();
 
+
+    QVBoxLayout* vblay=new QVBoxLayout();
+
+
     users=new QScrollArea ( fr );
+    vblay->addLayout(sessionExplorer->getNavigationLayout());
+    vblay->addWidget(users);
+
+
     pal=users->verticalScrollBar()->palette();
     pal.setBrush ( QPalette::Window, QColor ( 110,112,127,255 ) );
     pal.setBrush ( QPalette::Base, QColor ( 110,112,127,255 ) );
@@ -768,7 +777,8 @@ void ONMainWindow::initWidgetsNormal()
     users->setWidget ( uframe );
 
     mainL->insertWidget ( 1, ln );
-    mainL->addWidget ( users );
+//     mainL->addWidget ( users );
+    mainL->addLayout(vblay);
 
     QAction *act_exit=new QAction (
         QIcon ( iconsPath ( "/32x32/exit.png" ) ),
@@ -1102,7 +1112,7 @@ void ONMainWindow::trayIconInit()
             if (sessionStatusDlg && sessionStatusDlg->isVisible())
             {
                 if (!useLdap)
-                    trayIconActiveConnectionMenu->setTitle(lastSession->name());
+                    trayIconActiveConnectionMenu->setTitle(sessionExplorer->getLastSession()->name());
                 else
                     trayIconActiveConnectionMenu->setTitle(lastUser->username());
             }
@@ -1263,9 +1273,8 @@ void ONMainWindow::slotResize ( const QSize sz )
             else
             {
                 QList<SessionButton*>::iterator it;
-                QList<SessionButton*>::iterator end=
-                    sessions.end();
-                for ( it=sessions.begin(); it!=end; it++ )
+                QList<SessionButton*>::iterator end=sessionExplorer->getSessionsList()->end();
+                for ( it=sessionExplorer->getSessionsList()->begin(); it!=end; it++ )
                 {
                     if ( !miniMode )
                         ( *it )->move (
@@ -1290,6 +1299,7 @@ void ONMainWindow::slotResize ( const QSize sz )
         uname->setMinimumWidth ( rwidth );
         u->move ( upos,height/2 );
         uname->move ( u->pos().x() +u->width() +5,u->pos().y() );
+        sessionExplorer->resize();
     }
 }
 
@@ -1685,10 +1695,10 @@ void ONMainWindow::slotClosePass()
         }
         else
         {
-            if (lastSession)
+            if (sessionExplorer->getLastSession())
             {
-                lastSession->show();
-                uname->setText ( lastSession->name() );
+                sessionExplorer->getLastSession()->show();
+                uname->setText ( sessionExplorer->getLastSession()->name() );
             }
         }
         uname->setEnabled ( true );
@@ -1878,8 +1888,8 @@ void ONMainWindow::slotUnameEntered()
     {
         SessionButton* sess=NULL;
         QList<SessionButton*>::iterator it;
-        QList<SessionButton*>::iterator endit=sessions.end();
-        for ( it=sessions.begin(); it!=endit; it++ )
+        QList<SessionButton*>::iterator endit=sessionExplorer->getSessionsList()->end();
+        for ( it=sessionExplorer->getSessionsList()->begin(); it!=endit; it++ )
         {
             QString name= ( *it )->name();
             if ( name==text )
@@ -2022,11 +2032,10 @@ void ONMainWindow::slotConfig()
 
             for ( i=0; i<names.size(); ++i )
                 names[i]->close();
-            for ( i=0; i<sessions.size(); ++i )
-                sessions[i]->close();
+
+            sessionExplorer->cleanSessions();
 
             userList.clear();
-            sessions.clear();
         }
         loadSettings();
         trayIconInit();
@@ -2049,117 +2058,6 @@ void ONMainWindow::slotConfig()
     }
 }
 
-void ONMainWindow::slotEdit ( SessionButton* bt )
-{
-    EditConnectionDialog dlg ( bt->id(),this );
-    if ( dlg.exec() ==QDialog::Accepted )
-    {
-        bt->redraw();
-        placeButtons();
-        users->ensureVisible ( bt->x(),bt->y(),50,220 );
-    }
-}
-
-void ONMainWindow::slotCreateDesktopIcon ( SessionButton* bt )
-{
-    QMessageBox messageBox(QMessageBox::Question,
-                           tr ( "Create session icon on desktop" ),
-                           tr ( "Desktop icons can be configured "
-                                "not to show x2goclient (hidden mode). "
-                                "If you like to use this feature you'll "
-                                "need to configure login by a gpg key "
-                                "or gpg smart card.\n\n"
-                                "Use x2goclient hidden mode?" ),
-                           QMessageBox::Yes|QMessageBox::No,
-                           this);
-
-    //adding a chekbox to know if user want to enable trayicon in hide sessions
-    QCheckBox cbShowTrayIcon(tr("Show session tray icon when running"));
-    messageBox.layout()->addWidget(&cbShowTrayIcon);
-    QGridLayout* gridLayout = (QGridLayout*) messageBox.layout();
-    gridLayout->addWidget(&cbShowTrayIcon, gridLayout->rowCount(), 0, 1, gridLayout->columnCount());
-    cbShowTrayIcon.blockSignals(true);
-
-    //getting the result
-    bool crHidden = (messageBox.exec() == QMessageBox::Yes);
-    bool bShowTrayicon = (cbShowTrayIcon.checkState() == Qt::Checked);
-
-
-    X2goSettings st ( "sessions" );
-
-    QString name=st.setting()->value ( bt->id() +"/name",
-                                       ( QVariant ) tr ( "New Session" ) ).toString() ;
-
-    // PyHoca-GUI uses the slash as separator for cascaded menus, so let's handle these on the file system
-    name.replace("/","::");
-
-    QString sessIcon=st.setting()->value (
-                         bt->id() +"/icon",
-                         ( QVariant )
-                         ":icons/128x128/x2gosession.png"
-                     ).toString();
-    sessIcon = expandHome(sessIcon);
-    if ( sessIcon.startsWith ( ":icons",Qt::CaseInsensitive ) ||
-            !sessIcon.endsWith ( ".png",Qt::CaseInsensitive ) )
-    {
-        sessIcon="/usr/share/x2goclient/icons/x2gosession.png";
-    }
-#ifndef Q_OS_WIN
-    QFile file (
-        QDesktopServices::storageLocation (
-            QDesktopServices::DesktopLocation ) +"/"+name+".desktop" );
-    if ( !file.open ( QIODevice::WriteOnly | QIODevice::Text ) )
-        return;
-
-    QString cmd="x2goclient";
-    if ( crHidden )
-        cmd="x2goclient --hide";
-
-    if (bShowTrayicon)
-        cmd += " --tray-icon";
-
-    QTextStream out ( &file );
-    out << "[Desktop Entry]\n"<<
-        "Exec="<<cmd<<" --sessionid="<<bt->id() <<"\n"<<
-        "Icon="<<sessIcon<<"\n"<<
-        "Name="<<name<<"\n"<<
-        "StartupNotify=true\n"<<
-        "Terminal=false\n"<<
-        "Type=Application\n"<<
-        "X-KDE-SubstituteUID=false\n";
-    file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ExeOwner);
-    file.close();
-#else
-    QString scrname=QDir::tempPath() +"\\mklnk.vbs";
-    QFile file ( scrname );
-    if ( !file.open ( QIODevice::WriteOnly | QIODevice::Text ) )
-        return;
-
-    QSettings xst ( "HKEY_LOCAL_MACHINE\\SOFTWARE\\x2goclient",
-                    QSettings::NativeFormat );
-    QString workDir=xst.value ( "Default" ).toString();
-    QString progname=workDir+"\\x2goclient.exe";
-    QString args="--sessionid="+bt->id();
-    if ( crHidden )
-        args+=" --hide";
-    QTextStream out ( &file );
-    out << "Set Shell = CreateObject(\"WScript.Shell\")\n"<<
-        "DesktopPath = Shell.SpecialFolders(\"Desktop\")\n"<<
-        "Set link = Shell.CreateShortcut(DesktopPath & \"\\"<<name<<
-        ".lnk\")\n"<<
-        "link.Arguments = \""<<args<<"\"\n"<<
-        "link.Description = \""<<tr ( "X2Go Link to session " ) <<
-        "--"<<name<<"--"<<"\"\n"<<
-        "link.TargetPath = \""<<progname<<"\"\n"<<
-        "link.iconLocation = \""<<progname<<"\"\n"<<
-        "link.WindowStyle = 1\n"<<
-        "link.WorkingDirectory = \""<<workDir<<"\"\n"<<
-        "link.Save\n";
-    file.close();
-    system ( scrname.toAscii() );
-    QFile::remove ( scrname );
-#endif
-}
 
 
 void ONMainWindow::slotReadSessions()
@@ -2175,7 +2073,8 @@ void ONMainWindow::slotReadSessions()
     }
 
     X2goSettings *st;
-    lastSession=0;
+    sessionExplorer->cleanSessions();
+    sessionExplorer->setLastSession(0);
 
     if (brokerMode)
     {
@@ -2184,9 +2083,9 @@ void ONMainWindow::slotReadSessions()
         config.key=QString::null;
         config.user=QString::null;
         config.sessiondata=QString::null;
-        for (int i=sessions.count()-1; i>=0; --i)
+        for (int i=sessionExplorer->getSessionsList()->count()-1; i>=0; --i)
         {
-            SessionButton* but=sessions.takeAt(i);
+            SessionButton* but=sessionExplorer->getSessionsList()->takeAt(i);
             if (but)
                 delete but;
         }
@@ -2217,9 +2116,9 @@ void ONMainWindow::slotReadSessions()
     for ( int i=0; i<slst.size(); ++i )
     {
         if ( slst[i]!="embedded" )
-            createBut ( slst[i] );
+            sessionExplorer->createBut ( slst[i] );
     }
-    placeButtons();
+    sessionExplorer->placeButtons();
     if ( slst.size() ==0 )
         slotNewSession();
     uname->setText ( "" );
@@ -2230,9 +2129,9 @@ void ONMainWindow::slotReadSessions()
 
     if(usePGPCard &&brokerMode&&cardReady)
     {
-        if(sessions.count()==1)
+        if(sessionExplorer->getSessionsList()->count()==1)
         {
-            slotSelectedFromList(sessions[0]);
+            slotSelectedFromList(sessionExplorer->getSessionsList()->at(0));
         }
     }
 
@@ -2251,21 +2150,21 @@ void ONMainWindow::slotReadSessions()
         defaultSession=false;
         if ( defaultSessionId.length() >0 )
         {
-            for ( int i=0; i<sessions.size(); ++i )
+            for ( int i=0; i< sessionExplorer->getSessionsList()->size(); ++i )
             {
-                if ( sessions[i]->id() ==defaultSessionId )
+                if ( sessionExplorer->getSessionsList()->at(i)->id() ==defaultSessionId )
                 {
                     sfound=true;
-                    slotSelectedFromList ( sessions[i] );
+                    slotSelectedFromList ( sessionExplorer->getSessionsList()->at(i) );
                     break;
                 }
             }
         }
         else
         {
-            for ( int i=0; i<sessions.size(); ++i )
+            for ( int i=0; i<sessionExplorer->getSessionsList()->size(); ++i )
             {
-                if ( sessions[i]->name() ==defaultSessionName )
+                if ( sessionExplorer->getSessionsList()->at(i)->name() ==defaultSessionName )
                 {
                     sfound=true;
                     uname->setText ( defaultSessionName );
@@ -2297,8 +2196,8 @@ void ONMainWindow::slotNewSession()
     EditConnectionDialog dlg ( id, this );
     if ( dlg.exec() ==QDialog::Accepted )
     {
-        SessionButton* bt=createBut ( id );
-        placeButtons();
+        SessionButton* bt=sessionExplorer->createBut ( id );
+        sessionExplorer->placeButtons();
         users->ensureVisible ( bt->x(),bt->y(),50,220 );
     }
 }
@@ -2315,74 +2214,6 @@ void ONMainWindow::slotCreateSessionIcon()
     dlg.exec();
 }
 
-SessionButton* ONMainWindow::createBut ( const QString& id )
-{
-    SessionButton* l;
-    l=new SessionButton ( this,uframe,id );
-    sessions.append ( l );
-    connect ( l,SIGNAL ( signal_edit ( SessionButton* ) ),
-              this,SLOT ( slotEdit ( SessionButton* ) ) );
-
-    connect ( l,SIGNAL ( signal_remove ( SessionButton* ) ),
-              this,SLOT ( slotDeleteButton ( SessionButton* ) ) );
-
-    connect ( l,SIGNAL ( sessionSelected ( SessionButton* ) ),this,
-              SLOT ( slotSelectedFromList ( SessionButton* ) ) );
-
-    return l;
-}
-
-
-void ONMainWindow::placeButtons()
-{
-    qSort ( sessions.begin(),sessions.end(),SessionButton::lessThen );
-    for ( int i=0; i<sessions.size(); ++i )
-    {
-        if ( !miniMode )
-            sessions[i]->move ( ( users->width()-360 ) /2,
-                                i*220+i*25+5 );
-        else
-            sessions[i]->move ( ( users->width()-260 ) /2,
-                                i*155+i*20+5 );
-        if (brokerMode)
-            sessions[i]->move ( ( users->width()-360 ) /2,
-                                i*150+i*25+5 );
-        sessions[i]->show();
-    }
-    if ( sessions.size() )
-    {
-        if ( !miniMode )
-            uframe->setFixedHeight (
-                sessions.size() *220+ ( sessions.size()-1 ) *25 );
-        else
-            uframe->setFixedHeight (
-                sessions.size() *155+ ( sessions.size()-1 ) *20 );
-        if (brokerMode)
-            uframe->setFixedHeight (
-                sessions.size() *150+ ( sessions.size()-1 ) *25 );
-    }
-
-}
-
-void ONMainWindow::slotDeleteButton ( SessionButton * bt )
-{
-    if ( QMessageBox::warning (
-                this,bt->name(),
-                tr ( "Are you sure you want to delete this session?" ),
-                QMessageBox::Yes,QMessageBox::No ) !=QMessageBox::Yes )
-        return;
-
-    X2goSettings st ( "sessions" );
-
-    st.setting()->beginGroup ( bt->id() );
-    st.setting()->remove ( "" );
-    st.setting()->sync();
-    sessions.removeAll ( bt );
-    bt->close();
-    placeButtons();
-    users->ensureVisible ( 0,0,50,220 );
-}
-
 
 void ONMainWindow::displayToolBar ( bool show )
 {
@@ -2621,8 +2452,8 @@ void ONMainWindow::slotSnameChanged ( const QString& text )
     if ( text=="" )
         return;
     QList<SessionButton*>::iterator it;
-    QList<SessionButton*>::iterator endit=sessions.end();
-    for ( it=sessions.begin(); it!=endit; it++ )
+    QList<SessionButton*>::iterator endit=sessionExplorer->getSessionsList()->end();
+    for ( it=sessionExplorer->getSessionsList()->begin(); it!=endit; it++ )
     {
         QString name= ( *it )->name();
         if ( name.indexOf ( text,0,Qt::CaseInsensitive ) ==0 )
@@ -2648,7 +2479,7 @@ void ONMainWindow::slotSnameChanged ( const QString& text )
 void ONMainWindow::slotSelectedFromList ( SessionButton* session )
 {
     pass->setText ( "" );
-    lastSession=session;
+    sessionExplorer->setLastSession(session);
     QString command;
     QString server;
     QString userName;
@@ -3177,8 +3008,8 @@ void ONMainWindow::slotSessEnter()
 
     if(brokerMode)
     {
-        broker->selectUserSession(lastSession->id());
-        config.session=lastSession->id();
+        broker->selectUserSession(sessionExplorer->getLastSession()->id());
+        config.session=sessionExplorer->getLastSession()->id();
         setStatStatus ( tr ( "Connecting to broker" ) );
         stInfo->insertPlainText ( "broker url: "+config.brokerurl );
         setEnabled ( false );
@@ -3189,7 +3020,7 @@ void ONMainWindow::slotSessEnter()
 
     QString sid="";
     if ( !embedMode )
-        sid=lastSession->id();
+        sid=sessionExplorer->getLastSession()->id();
     startSession ( sid );
 }
 
@@ -3221,7 +3052,7 @@ void ONMainWindow::startDirectRDP()
     X2goSettings st ( "sessions" );
     QString sid;
     if ( !embedMode )
-        sid=lastSession->id();
+        sid=sessionExplorer->getLastSession()->id();
     else
         sid="embedded";
 
@@ -3295,7 +3126,7 @@ void ONMainWindow::startDirectRDP()
 
     resumingSession.display="RDP";
     resumingSession.server=host;
-    resumingSession.sessionId=lastSession->name();
+    resumingSession.sessionId=sessionExplorer->getLastSession()->name();
     resumingSession.crTime=QDateTime::currentDateTime().toString("dd.MM.yy HH:mm:ss");
 
     showSessionStatus();
@@ -3771,7 +3602,7 @@ void ONMainWindow::startNewSession()
 
         QString sid;
         if ( !embedMode )
-            sid=lastSession->id();
+            sid=sessionExplorer->getLastSession()->id();
         else
             sid="embedded";
         pack=st->setting()->value ( sid+"/pack",
@@ -4113,7 +3944,7 @@ void ONMainWindow::resumeSession ( const x2goSession& s )
 
         QString sid;
         if ( !embedMode )
-            sid=lastSession->id();
+            sid=sessionExplorer->getLastSession()->id();
         else
             sid="embedded";
         X2goSettings* st;
@@ -4320,7 +4151,7 @@ void ONMainWindow::resumeSession ( const x2goSession& s )
 void ONMainWindow::setTrayIconToSessionIcon(QString info) {
 
     //set session icon to tray icon
-    if (trayIcon && lastSession) {
+    if (trayIcon && sessionExplorer->getLastSession()) {
 
         X2goSettings* st;
 
@@ -4331,7 +4162,7 @@ void ONMainWindow::setTrayIconToSessionIcon(QString info) {
 
         QString sid;
         if ( !embedMode )
-            sid=lastSession->id();
+            sid=sessionExplorer->getLastSession()->id();
         else
             sid="embedded";
 
@@ -4467,7 +4298,7 @@ void ONMainWindow::selectSession ( QStringList& sessions )
             {
                 st=new X2goSettings( "sessions" );
 
-                QString sid=lastSession->id();
+                QString sid=sessionExplorer->getLastSession()->id();
                 QString suser = st->setting()->value(sid + "/shadowuser", (QVariant) QString::null).toString();
                 QString sdisplay = st->setting()->value(sid + "/shadowdisplay", (QVariant) QString::null).toString();
                 bool fullAccess= st->setting()->value(sid + "/shadowfullaccess", (QVariant) false).toBool();
@@ -4645,7 +4476,7 @@ void ONMainWindow::slotSuspendSess()
         else
         {
             X2goSettings st ( "sessions" );
-            QString sid=lastSession->id();
+            QString sid=sessionExplorer->getLastSession()->id();
             host=st.setting()->value ( sid+"/host",
                                        ( QVariant ) host ).toString();
         }
@@ -4789,7 +4620,7 @@ void ONMainWindow::slotTermSess()
         {
             X2goSettings st ( "sessions" );
 
-            QString sid=lastSession->id();
+            QString sid=sessionExplorer->getLastSession()->id();
         }
     }
     else
@@ -4909,7 +4740,7 @@ void ONMainWindow::slotRetResumeSess ( bool result,
     {
         QString sid;
         if ( !embedMode )
-            sid=lastSession->id();
+            sid=sessionExplorer->getLastSession()->id();
         else
             sid="embedded";
         X2goSettings st ( "sessions" );
@@ -5065,7 +4896,7 @@ void ONMainWindow::slotRetResumeSess ( bool result,
         {
             X2goSettings st ( "sessions" );
 
-            QString sid=lastSession->id();
+            QString sid=sessionExplorer->getLastSession()->id();
             host=st.setting()->value ( sid+"/host",
                                        ( QVariant ) host ).toString();
         }
@@ -5817,7 +5648,7 @@ void ONMainWindow::slotProxyStderr()
         if (trayEnabled)
         {
             if (!useLdap)
-                trayIconActiveConnectionMenu->setTitle(lastSession->name());
+                trayIconActiveConnectionMenu->setTitle(sessionExplorer->getLastSession()->name());
             else
                 trayIconActiveConnectionMenu->setTitle(lastUser->username());
             trayIconActiveConnectionMenu->setEnabled(true);
@@ -6275,7 +6106,7 @@ void ONMainWindow::runCommand()
             command=sessionCmd;
         else
         {
-            QString sid=lastSession->id();
+            QString sid=sessionExplorer->getLastSession()->id();
             command=st->setting()->value (
                         sid+"/command",
                         ( QVariant ) tr ( "KDE" ) ).toString();
@@ -7604,7 +7435,7 @@ void ONMainWindow::slotExportDirectory()
     QString path;
     if ( !useLdap && !embedMode )
     {
-        ExportDialog dlg ( lastSession->id(),this );
+        ExportDialog dlg ( sessionExplorer->getLastSession()->id(),this );
         if ( dlg.exec() ==QDialog::Accepted )
             path=dlg.getExport();
     }
@@ -7659,7 +7490,7 @@ void ONMainWindow::exportDirs ( QString exports,bool removable )
         {
             X2goSettings st ( "sessions" );
 
-            QString sid=lastSession->id();
+            QString sid=sessionExplorer->getLastSession()->id();
 
             fsInTun=st.setting()->value ( sid+"/fstunnel",
                                           ( QVariant ) true ).toBool();
@@ -7704,11 +7535,11 @@ void ONMainWindow::exportDefaultDirs()
 
             X2goSettings st ( "sessions" );
             clientPrinting= st.setting()->value (
-                                lastSession->id() +
+                                sessionExplorer->getLastSession()->id() +
                                 "/print", true ).toBool();
 
             QString exd=st.setting()->value (
-                            lastSession->id() +"/export",
+                            sessionExplorer->getLastSession()->id() +"/export",
                             ( QVariant ) QString::null ).toString();
             QStringList lst=exd.split ( ";",
                                         QString::SkipEmptyParts );
@@ -8018,21 +7849,6 @@ void ONMainWindow::slotRetExportDir ( bool result,QString output,
 }
 
 
-
-void ONMainWindow::exportsEdit ( SessionButton* bt )
-{
-    EditConnectionDialog dlg ( bt->id(),this,3 );
-    if ( dlg.exec() ==QDialog::Accepted )
-    {
-        bt->redraw();
-        bool vis=bt->isVisible();
-        placeButtons();
-        users->ensureVisible ( bt->x(),bt->y(),50,220 );
-        bt->setVisible ( vis );
-    }
-}
-
-
 void ONMainWindow::slotExtTimer()
 {
 
@@ -8310,11 +8126,10 @@ void ONMainWindow::reloadUsers()
     int i;
     for ( i=0; i<names.size(); ++i )
         names[i]->close();
-    for ( i=0; i<sessions.size(); ++i )
-        sessions[i]->close();
 
     userList.clear();
-    sessions.clear();
+
+    sessionExplorer->cleanSessions();
 
 
     loadSettings();
@@ -9249,7 +9064,7 @@ void ONMainWindow::startX2goMount()
     {
         QString sid;
         if ( !embedMode )
-            sid=lastSession->id();
+            sid=sessionExplorer->getLastSession()->id();
         else
             sid="embedded";
         if ( st.setting()->value (
@@ -10072,7 +9887,7 @@ void ONMainWindow::setProxyWinTitle()
     QString title;
 
     if (!useLdap)
-        title=lastSession->name();
+        title=sessionExplorer->getLastSession()->name();
     else
         title=getCurrentUname()+"@"+resumingSession.server;
 
@@ -10081,7 +9896,7 @@ void ONMainWindow::setProxyWinTitle()
     if (useLdap)
         pixmap=lastUser->foto();
     else
-        pixmap=*(lastSession->sessIcon());
+        pixmap=*(sessionExplorer->getLastSession()->sessIcon());
 
 #ifdef Q_OS_LINUX
 
@@ -10329,7 +10144,7 @@ void ONMainWindow::slotFindProxyWin()
                 X2goSettings *st;
                 QString sid;
                 if ( !embedMode )
-                    sid=lastSession->id();
+                    sid=sessionExplorer->getLastSession()->id();
                 else
                     sid="embedded";
 
@@ -11272,7 +11087,7 @@ void ONMainWindow::initSelectSessDlg()
     sessTv->setItemsExpandable ( false );
     sessTv->setRootIsDecorated ( false );
 
-    model=new QStandardItemModel ( sessions.size(), 8 );
+    model=new QStandardItemModel ( sessionExplorer->getSessionsList()->size(), 8 );
     model->setHeaderData ( S_DISPLAY,Qt::Horizontal,
                            QVariant ( ( QString ) tr ( "Display" ) ) );
     model->setHeaderData ( S_STATUS,Qt::Horizontal,
@@ -11291,7 +11106,7 @@ void ONMainWindow::initSelectSessDlg()
     model->setHeaderData ( S_ID,Qt::Horizontal,
                            QVariant ( ( QString ) tr ( "Session ID" ) ) );
 
-    modelDesktop=new QStandardItemModel ( sessions.size(), 2 );
+    modelDesktop=new QStandardItemModel ( sessionExplorer->getSessionsList()->size(), 2 );
     modelDesktop->setHeaderData ( D_USER,Qt::Horizontal,
                                   QVariant ( ( QString ) tr ( "User" ) ) );
     modelDesktop->setHeaderData (
diff --git a/onmainwindow.h b/onmainwindow.h
index 9954c3d..f3e589c 100644
--- a/onmainwindow.h
+++ b/onmainwindow.h
@@ -80,6 +80,8 @@ class QStandardItemModel;
 class HttpBrokerClient;
 class QMenu;
 class QComboBox;
+
+class SessionExplorer;
 struct user
 {
     int uin;
@@ -339,10 +341,6 @@ public:
     ~ONMainWindow();
     static void installTranslator();
     QString iconsPath ( QString fname );
-    const QList<SessionButton*> * getSessionsList()
-    {
-        return &sessions;
-    }
     static bool isServerRunning ( int port );
     void startNewSession();
     void suspendSession ( QString sessId );
@@ -502,6 +500,36 @@ public:
         return hideFolderSharing;
     }
 
+    SessionExplorer* getSessionExplorer()
+    {
+        return sessionExplorer;
+    }
+
+    bool getBrokerMode()
+    {
+        return brokerMode;
+    }
+
+    bool getMiniMode()
+    {
+        return miniMode;
+    }
+
+    QScrollArea* getUsersArea()
+    {
+        return users;
+    }
+
+    QFrame* getUsersFrame()
+    {
+        return uframe;
+    }
+
+    IMGFrame* getCentralFrame()
+    {
+        return fr;
+    }
+
     void runApplication(QString exec);
 
 
@@ -631,6 +659,8 @@ private:
     QLineEdit* desktopFilter;
     QCheckBox* desktopFilterCb;
 
+    SessionExplorer* sessionExplorer;
+
     IMGFrame* fr;
     SVGFrame *bgFrame;
     QLineEdit* uname;
@@ -670,9 +700,7 @@ private:
     QHBoxLayout* mainL;
     QHBoxLayout* bgLay;
     QList<UserButton*> names;
-    QList<SessionButton*> sessions;
     UserButton* lastUser;
-    SessionButton* lastSession;
     QString prevText;
     QString onserver;
     QString id;
@@ -881,8 +909,6 @@ private:
     QString defaultSessionId;
     QString defaultUserName;
     bool defaultUser;
-    SessionButton* createBut ( const QString& id );
-    void placeButtons();
     QString getKdeIconsPath();
     QString findTheme ( QString theme );
     bool initLdapSession ( bool showBox=true );
@@ -979,10 +1005,6 @@ private slots:
 public slots:
     void slotConfig();
     void slotNewSession();
-    void slotDeleteButton ( SessionButton * bt );
-    void slotEdit ( SessionButton* );
-    void slotCreateDesktopIcon ( SessionButton* bt );
-    void exportsEdit ( SessionButton* bt );
     void slotEmbedControlAction();
     void slotDetachProxyWindow();
     void slotActivateWindow();
diff --git a/onmainwindow_privat.h b/onmainwindow_privat.h
index c93ddba..037483f 100644
--- a/onmainwindow_privat.h
+++ b/onmainwindow_privat.h
@@ -137,6 +137,7 @@
 #include "configdialog.h"
 #include "editconnectiondialog.h"
 #include "sessionbutton.h"
+#include "sessionexplorer.h"
 #include "sessionmanagedialog.h"
 #include "x2gologdebug.h"
 #include <QMouseEvent>
diff --git a/resources.rcc b/resources.rcc
index b6f80c0..3021bf2 100644
--- a/resources.rcc
+++ b/resources.rcc
@@ -7,6 +7,8 @@
        <file>svg/x2gologo.svg</file>
        <file>svg/passform.svg</file>
        <file>svg/sessionbut.svg</file>
+       <file>svg/folder.svg</file>
+       <file>svg/folder_grey.svg</file>
        <file>svg/sessionbut_grey.svg</file>
        <file>png/ico.png</file>
        <file>png/ico_mini.png</file>
@@ -14,6 +16,7 @@
        <file>png/ico_440x180.png</file>
        <file>png/power-button.png</file>
        <file>icons/128x128/x2go.png</file>
+       <file>icons/128x128/folder.png</file>
        <file>icons/128x128/x2gosession.png</file>
        <file>icons/128x128/create_file.png</file>
        <file>icons/128x128/lxde.png</file>
diff --git a/sessionbutton.cpp b/sessionbutton.cpp
index aaa0b2e..dc81171 100644
--- a/sessionbutton.cpp
+++ b/sessionbutton.cpp
@@ -33,10 +33,11 @@
 #include "x2gologdebug.h"
 #include <QApplication>
 #include <QDesktopWidget>
+#include "sessionexplorer.h"
 
 
 SessionButton::SessionButton ( ONMainWindow* mw,QWidget *parent, QString id )
-        : SVGFrame ( ":/svg/sessionbut.svg",false,parent )
+    : SVGFrame ( ":/svg/sessionbut.svg",false,parent )
 {
     editable=mw->sessionEditEnabled();
 
@@ -287,9 +288,19 @@ void SessionButton::redraw()
 
 
 
-    sessName->setText (
-        st->setting()->value ( sid+"/name",
-                               ( QVariant ) tr ( "New Session" ) ).toString());
+    QString name=st->setting()->value ( sid+"/name",
+                                        ( QVariant ) tr ( "New Session" ) ).toString();
+
+    QStringList tails=name.split("/",QString::SkipEmptyParts);
+    if(tails.count()>0)
+    {
+        name=tails.last();
+        tails.pop_back();
+        path=tails.join("/");
+    }
+
+    sessName->setText (name);
+
     QString status=st->setting()->value ( sid+"/status",
                                           ( QVariant ) QString::null ).toString();
     if (status == "R")
@@ -333,7 +344,7 @@ void SessionButton::redraw()
     QString command=st->setting()->value ( sid+"/command",
                                            ( QVariant )
                                            tr (
-                                               "KDE" ) ).
+                                                   "KDE" ) ).
                     toString();
     rootless=st->setting()->value ( sid+"/rootless",
                                     false ).toBool();
@@ -438,7 +449,7 @@ void SessionButton::redraw()
     geomBox->addItem ( tr ( "fullscreen" ) );
     uint displays=QApplication::desktop()->numScreens();
     if (!directRDP)
-        for (uint i=0;i<displays;++i)
+        for (uint i=0; i<displays; ++i)
         {
             geomBox->addItem ( tr( "Display " )+QString::number(i+1));
 
@@ -462,43 +473,42 @@ void SessionButton::redraw()
     {
         geom->setText ( tr ( "fullscreen" ) );
     }
-    else
-        if (st->setting()->value ( sid+"/multidisp",
-                                   ( QVariant ) false ).toBool() && !directRDP)
+    else if (st->setting()->value ( sid+"/multidisp",
+                                    ( QVariant ) false ).toBool() && !directRDP)
+    {
+        uint disp=st->setting()->value ( sid+"/display",
+                                         ( QVariant ) 1 ).toUInt();
+        if (disp<=displays)
         {
-            uint disp=st->setting()->value ( sid+"/display",
-                                             ( QVariant ) 1 ).toUInt();
-            if (disp<=displays)
-            {
-                geom->setText( tr( "Display " )+QString::number(disp));
-            }
-            else
-            {
-                geom->setText( tr( "Display " )+QString::number(1));
-            }
-            for (int i=0;i<geomBox->count();++i)
-                if (geomBox->itemText(i)==geom->text())
-                {
-                    geomBox->setCurrentIndex(i);
-                    break;
-                }
+            geom->setText( tr( "Display " )+QString::number(disp));
         }
         else
         {
+            geom->setText( tr( "Display " )+QString::number(1));
+        }
+        for (int i=0; i<geomBox->count(); ++i)
+            if (geomBox->itemText(i)==geom->text())
+            {
+                geomBox->setCurrentIndex(i);
+                break;
+            }
+    }
+    else
+    {
 #ifndef	Q_WS_HILDON
-            QString g=QString::number ( st->setting()->value (
-                                            sid+"/width" ).toInt() );
-            g+="x"+QString::number ( st->setting()->value (
-                                         sid+"/height" ).toInt() );
-            geom->setText ( g );
-            if ( geomBox->findText ( g ) ==-1 )
-                geomBox->addItem ( g );
-            geomBox->setCurrentIndex ( geomBox->findText ( g ) );
+        QString g=QString::number ( st->setting()->value (
+                                        sid+"/width" ).toInt() );
+        g+="x"+QString::number ( st->setting()->value (
+                                     sid+"/height" ).toInt() );
+        geom->setText ( g );
+        if ( geomBox->findText ( g ) ==-1 )
+            geomBox->addItem ( g );
+        geomBox->setCurrentIndex ( geomBox->findText ( g ) );
 #else
-            geom->setText ( tr ( "window" ) );
-            geomBox->setCurrentIndex ( 1 );
+        geom->setText ( tr ( "window" ) );
+        geomBox->setCurrentIndex ( 1 );
 #endif
-        }
+    }
 
     if (directRDP)
     {
@@ -781,29 +791,28 @@ void SessionButton::slot_geom_change ( const QString& new_g )
         st.setting()->setValue ( sid+"/multidisp", ( QVariant ) false );
         st.setting()->setValue ( sid+"/maxdim", ( QVariant ) true );
     }
+    else if (new_g.indexOf(tr("Display "))==0)
+    {
+        QString g= new_g;
+        g.replace(tr("Display "),"");
+        st.setting()->setValue ( sid+"/multidisp", ( QVariant ) true );
+        st.setting()->setValue ( sid+"/display", ( QVariant ) g.toUInt());
+        st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
+        st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
+    }
     else
-        if (new_g.indexOf(tr("Display "))==0)
-        {
-            QString g= new_g;
-            g.replace(tr("Display "),"");
-            st.setting()->setValue ( sid+"/multidisp", ( QVariant ) true );
-            st.setting()->setValue ( sid+"/display", ( QVariant ) g.toUInt());
-            st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
-            st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
-        }
-        else
-        {
-            QString new_geom=new_g;
+    {
+        QString new_geom=new_g;
 #ifdef Q_WS_HILDON
-            new_geom="800x600";
+        new_geom="800x600";
 #endif
-            st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
-            st.setting()->setValue ( sid+"/multidisp", ( QVariant ) false );
-            st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
-            QStringList lst=new_geom.split ( 'x' );
-            st.setting()->setValue ( sid+"/width", ( QVariant ) lst[0] );
-            st.setting()->setValue ( sid+"/height", ( QVariant ) lst[1] );
-        }
+        st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
+        st.setting()->setValue ( sid+"/multidisp", ( QVariant ) false );
+        st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
+        QStringList lst=new_geom.split ( 'x' );
+        st.setting()->setValue ( sid+"/width", ( QVariant ) lst[0] );
+        st.setting()->setValue ( sid+"/height", ( QVariant ) lst[1] );
+    }
     st.setting()->sync();
 }
 
@@ -835,5 +844,5 @@ void SessionButton::slotShowMenu()
 
 void SessionButton::slotCreateSessionIcon()
 {
-    par->slotCreateDesktopIcon ( this );
+    par->getSessionExplorer()->slotCreateDesktopIcon ( this );
 }
diff --git a/sessionbutton.h b/sessionbutton.h
index d4e51a4..bc4d8f9 100644
--- a/sessionbutton.h
+++ b/sessionbutton.h
@@ -44,8 +44,13 @@ public:
     }
     static bool lessThen ( const SessionButton* b1, const SessionButton* b2 );
     QString name();
+    QString getPath()
+    {
+        return path;
+    }
 private:
     QString sid;
+    QString path;
     QLabel* sessName;
     QLabel* sessStatus;
     QLabel* icon;
diff --git a/sessionexplorer.cpp b/sessionexplorer.cpp
new file mode 100644
index 0000000..d1604f3
--- /dev/null
+++ b/sessionexplorer.cpp
@@ -0,0 +1,387 @@
+/**************************************************************************
+*   Copyright (C) 2005-2014 by Oleksandr Shneyder                         *
+*   o.shneyder at phoca-gmbh.de                                              *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*   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 General Public License for more details.                          *
+*                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
+***************************************************************************/
+
+#include "sessionexplorer.h"
+#include "sessionbutton.h"
+#include "folderbutton.h"
+#include "editconnectiondialog.h"
+#include "onmainwindow.h"
+#include <QMessageBox>
+#include <QCheckBox>
+#include "x2gosettings.h"
+#include <QGridLayout>
+#include <QScrollArea>
+#include <QFile>
+#include <QDesktopServices>
+#include "x2goutils.h"
+#include "imgframe.h"
+#include <QToolButton>
+#include "x2gologdebug.h"
+
+SessionExplorer::SessionExplorer(ONMainWindow* p):QObject(p)
+{
+    parent=p;
+    lastSession=0;
+    backButton=new QToolButton(parent->getCentralFrame());
+    backButton->setIcon(QIcon( parent->iconsPath ( "/32x32/tbhide.png" )));
+    backButton->setAutoRaise(true);
+    pathLabel=new QLabel(" ",parent->getCentralFrame());
+    backButton->setFixedWidth(36);
+    navigationLayout=new QHBoxLayout();
+    navigationLayout->addWidget(backButton);
+    navigationLayout->addWidget(pathLabel);
+    backButton->setToolTip(tr("Back"));
+    QPalette pal=backButton->palette();
+    pal.setBrush ( QPalette::Window, QColor ( 110,112,127,255 ) );
+    pal.setBrush ( QPalette::Base, QColor ( 110,112,127,255 ) );
+    pal.setBrush ( QPalette::Button, QColor ( 110,112,127,255 ) );
+
+    backButton->setPalette(pal);
+    backButton->setAutoFillBackground(true);
+    pal=pathLabel->palette();
+    pal.setBrush ( QPalette::Window, QColor ( 110,112,127,255 ) );
+    pal.setBrush ( QPalette::WindowText, QColor ( 200,200,200,255 ) );
+    pathLabel->setPalette(pal);
+    pathLabel->setAutoFillBackground(true);
+    setNavigationVisible(false);
+    connect(backButton,SIGNAL(clicked(bool)), this, SLOT(slotLevelUp()));
+}
+
+SessionExplorer::~SessionExplorer()
+{
+}
+
+void SessionExplorer::resize()
+{
+    pathLabel->setMaximumWidth(parent->getUsersArea()->width()-backButton->width());
+    QFontMetrics metrics(pathLabel->font());
+    QString displayText = metrics.elidedText(" "+currentPath, Qt::ElideLeft, pathLabel->width()-6);
+    pathLabel->setText(displayText);
+}
+
+void SessionExplorer::cleanSessions()
+{
+    for ( int i=0; i<sessions.size(); ++i )
+        sessions[i]->close();
+    sessions.clear();
+}
+
+void SessionExplorer::exportsEdit ( SessionButton* bt )
+{
+    EditConnectionDialog dlg ( bt->id(),parent,3 );
+    if ( dlg.exec() ==QDialog::Accepted )
+    {
+        bt->redraw();
+        bool vis=bt->isVisible();
+        placeButtons();
+        parent->getUsersArea()->ensureVisible ( bt->x(),bt->y(),50,220 );
+        bt->setVisible ( vis );
+    }
+}
+
+
+void SessionExplorer::slotEdit ( SessionButton* bt )
+{
+    EditConnectionDialog dlg ( bt->id(),parent );
+    if ( dlg.exec() ==QDialog::Accepted )
+    {
+        bt->redraw();
+        placeButtons();
+        parent->getUsersArea()->ensureVisible ( bt->x(),bt->y(),50,220 );
+    }
+}
+
+void SessionExplorer::slotCreateDesktopIcon ( SessionButton* bt )
+{
+    QMessageBox messageBox(QMessageBox::Question,
+                           tr ( "Create session icon on desktop" ),
+                           tr ( "Desktop icons can be configured "
+                                "not to show x2goclient (hidden mode). "
+                                "If you like to use this feature you'll "
+                                "need to configure login by a gpg key "
+                                "or gpg smart card.\n\n"
+                                "Use x2goclient hidden mode?" ),
+                           QMessageBox::Yes|QMessageBox::No,
+                           parent);
+
+    //adding a chekbox to know if user want to enable trayicon in hide sessions
+    QCheckBox cbShowTrayIcon(tr("Show session tray icon when running"));
+    messageBox.layout()->addWidget(&cbShowTrayIcon);
+    QGridLayout* gridLayout = (QGridLayout*) messageBox.layout();
+    gridLayout->addWidget(&cbShowTrayIcon, gridLayout->rowCount(), 0, 1, gridLayout->columnCount());
+    cbShowTrayIcon.blockSignals(true);
+
+    //getting the result
+    bool crHidden = (messageBox.exec() == QMessageBox::Yes);
+    bool bShowTrayicon = (cbShowTrayIcon.checkState() == Qt::Checked);
+
+
+    X2goSettings st ( "sessions" );
+
+    QString name=st.setting()->value ( bt->id() +"/name",
+                                       ( QVariant ) tr ( "New Session" ) ).toString() ;
+
+    // PyHoca-GUI uses the slash as separator for cascaded menus, so let's handle these on the file system
+    name.replace("/","::");
+
+    QString sessIcon=st.setting()->value (
+                         bt->id() +"/icon",
+                         ( QVariant )
+                         ":icons/128x128/x2gosession.png"
+                     ).toString();
+    sessIcon = expandHome(sessIcon);
+    if ( sessIcon.startsWith ( ":icons",Qt::CaseInsensitive ) ||
+            !sessIcon.endsWith ( ".png",Qt::CaseInsensitive ) )
+    {
+        sessIcon="/usr/share/x2goclient/icons/x2gosession.png";
+    }
+#ifndef Q_OS_WIN
+    QFile file (
+        QDesktopServices::storageLocation (
+            QDesktopServices::DesktopLocation ) +"/"+name+".desktop" );
+    if ( !file.open ( QIODevice::WriteOnly | QIODevice::Text ) )
+        return;
+
+    QString cmd="x2goclient";
+    if ( crHidden )
+        cmd="x2goclient --hide";
+
+    if (bShowTrayicon)
+        cmd += " --tray-icon";
+
+    QTextStream out ( &file );
+    out << "[Desktop Entry]\n"<<
+        "Exec="<<cmd<<" --sessionid="<<bt->id() <<"\n"<<
+        "Icon="<<sessIcon<<"\n"<<
+        "Name="<<name<<"\n"<<
+        "StartupNotify=true\n"<<
+        "Terminal=false\n"<<
+        "Type=Application\n"<<
+        "X-KDE-SubstituteUID=false\n";
+    file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ExeOwner);
+    file.close();
+#else
+    QString scrname=QDir::tempPath() +"\\mklnk.vbs";
+    QFile file ( scrname );
+    if ( !file.open ( QIODevice::WriteOnly | QIODevice::Text ) )
+        return;
+
+    QSettings xst ( "HKEY_LOCAL_MACHINE\\SOFTWARE\\x2goclient",
+                    QSettings::NativeFormat );
+    QString workDir=xst.value ( "Default" ).toString();
+    QString progname=workDir+"\\x2goclient.exe";
+    QString args="--sessionid="+bt->id();
+    if ( crHidden )
+        args+=" --hide";
+    QTextStream out ( &file );
+    out << "Set Shell = CreateObject(\"WScript.Shell\")\n"<<
+        "DesktopPath = Shell.SpecialFolders(\"Desktop\")\n"<<
+        "Set link = Shell.CreateShortcut(DesktopPath & \"\\"<<name<<
+        ".lnk\")\n"<<
+        "link.Arguments = \""<<args<<"\"\n"<<
+        "link.Description = \""<<tr ( "X2Go Link to session " ) <<
+        "--"<<name<<"--"<<"\"\n"<<
+        "link.TargetPath = \""<<progname<<"\"\n"<<
+        "link.iconLocation = \""<<progname<<"\"\n"<<
+        "link.WindowStyle = 1\n"<<
+        "link.WorkingDirectory = \""<<workDir<<"\"\n"<<
+        "link.Save\n";
+    file.close();
+    system ( scrname.toAscii() );
+    QFile::remove ( scrname );
+#endif
+}
+
+
+SessionButton* SessionExplorer::createBut ( const QString& id )
+{
+    SessionButton* l;
+    l=new SessionButton ( parent,parent->getUsersFrame(),id );
+    sessions.append ( l );
+    connect ( l,SIGNAL ( signal_edit ( SessionButton* ) ),
+              this,SLOT ( slotEdit ( SessionButton* ) ) );
+
+    connect ( l,SIGNAL ( signal_remove ( SessionButton* ) ),
+              this,SLOT ( slotDeleteButton ( SessionButton* ) ) );
+
+    connect ( l,SIGNAL ( sessionSelected ( SessionButton* ) ),parent,
+              SLOT ( slotSelectedFromList ( SessionButton* ) ) );
+
+    if(l->getPath()!="")
+    {
+        if(findFolder(l->getPath())==-1)
+        {
+            createFolder(l->getPath());
+        }
+    }
+
+    return l;
+}
+
+
+void SessionExplorer::placeButtons()
+{
+    setNavigationVisible(currentPath.length()>0);
+    resize();
+    int currentIndex=0;
+    qSort ( sessions.begin(),sessions.end(),SessionButton::lessThen );
+    qSort ( folders.begin(), folders.end(), FolderButton::lessThen );
+
+    for ( int i=0; i<folders.size(); ++i )
+    {
+        if(folders[i]->getPath() != currentPath)
+        {
+            folders[i]->hide();
+            continue;
+        }
+        if ( !parent->getMiniMode() )
+            folders[i]->move ( ( parent->getUsersArea()->width()-360 ) /2,
+                               currentIndex*220+currentIndex*25+5 );
+        else
+            folders[i]->move ( ( parent->getUsersArea()->width()-260 ) /2,
+                               currentIndex*155+currentIndex*20+5 );
+        if (parent->getBrokerMode())
+            folders[i]->move ( ( parent->getUsersArea()->width()-360 ) /2,
+                               currentIndex*150+currentIndex*25+5 );
+        folders[i]->show();
+        folders[i]->setChildrenList(getFolderChildren(folders[i]));
+        ++currentIndex;
+    }
+
+    for ( int i=0; i<sessions.size(); ++i )
+    {
+        if(sessions[i]->getPath() != currentPath)
+        {
+            sessions[i]->hide();
+            continue;
+        }
+        if ( !parent->getMiniMode() )
+            sessions[i]->move ( ( parent->getUsersArea()->width()-360 ) /2,
+                                currentIndex*220+currentIndex*25+5 );
+        else
+            sessions[i]->move ( ( parent->getUsersArea()->width()-260 ) /2,
+                                currentIndex*155+currentIndex*20+5 );
+        if (parent->getBrokerMode())
+            sessions[i]->move ( ( parent->getUsersArea()->width()-360 ) /2,
+                                currentIndex*150+currentIndex*25+5 );
+        sessions[i]->show();
+        ++currentIndex;
+    }
+
+    if ( currentIndex )
+    {
+        if ( !parent->getMiniMode() )
+            parent->getUsersFrame()->setFixedHeight (
+                currentIndex *220+ ( currentIndex -1 ) *25 );
+        else
+            parent->getUsersFrame()->setFixedHeight (
+                currentIndex *155+ ( currentIndex-1 ) *20 );
+        if (parent->getBrokerMode())
+            parent->getUsersFrame()->setFixedHeight (
+                currentIndex *150+ ( currentIndex-1 ) *25 );
+    }
+
+}
+
+QStringList SessionExplorer::getFolderChildren(FolderButton* folder)
+{
+    QStringList children;
+    QString normPath=(folder->getPath()+"/"+folder->getName()).split("/",QString::SkipEmptyParts).join("/");
+
+    for(int i=0; i<folders.count(); ++i)
+    {
+        if(folders[i]->getPath()==normPath)
+            children<<folders[i]->getName();
+    }
+    for(int i=0; i<sessions.count(); ++i)
+    {
+        if(sessions[i]->getPath()==normPath)
+            children<<sessions[i]->name();
+    }
+    return children;
+}
+
+
+void SessionExplorer::slotDeleteButton ( SessionButton * bt )
+{
+    if ( QMessageBox::warning (
+                parent,bt->name(),
+                tr ( "Are you sure you want to delete this session?" ),
+                QMessageBox::Yes,QMessageBox::No ) !=QMessageBox::Yes )
+        return;
+
+    X2goSettings st ( "sessions" );
+
+    st.setting()->beginGroup ( bt->id() );
+    st.setting()->remove ( "" );
+    st.setting()->sync();
+    sessions.removeAll ( bt );
+    bt->close();
+    placeButtons();
+    parent->getUsersArea()->ensureVisible ( 0,0,50,220 );
+}
+
+void SessionExplorer::setNavigationVisible(bool value)
+{
+    backButton->setVisible(value);
+    pathLabel->setVisible(value);
+}
+
+void SessionExplorer::createFolder(QString path)
+{
+    QStringList tails=path.split("/");
+    QStringList currentPath;
+    for(int i=0; i<tails.count()-1; ++i)
+    {
+        currentPath<<tails[i];
+        if(findFolder(currentPath.join("/"))==-1)
+        {
+            createFolder(currentPath.join("/"));
+        }
+    }
+    FolderButton* fb=new FolderButton(parent,parent->getUsersFrame(),currentPath.join("/"), tails.last());
+    connect(fb, SIGNAL(folderSelected(FolderButton*)), this, SLOT(slotFolderSelected(FolderButton*)));
+    folders<<fb;
+}
+
+int SessionExplorer::findFolder(QString path)
+{
+    for(int i=0; i<folders.count(); ++i)
+    {
+        QString normPath=(folders[i]->getPath()+"/"+folders[i]->getName()).split("/",QString::SkipEmptyParts).join("/");
+        if(normPath==path)
+            return i;
+    }
+    return -1;
+}
+
+void SessionExplorer::slotFolderSelected(FolderButton* bt)
+{
+    currentPath=(bt->getPath()+"/"+bt->getName()).split("/",QString::SkipEmptyParts).join("/");
+    placeButtons();
+}
+
+void SessionExplorer::slotLevelUp()
+{
+    QStringList levels=currentPath.split("/",QString::SkipEmptyParts);
+    if(levels.count())
+    {
+        levels.pop_back();
+        currentPath=levels.join("/");
+    }
+    placeButtons();
+}
diff --git a/sessionexplorer.h b/sessionexplorer.h
new file mode 100644
index 0000000..84b8867
--- /dev/null
+++ b/sessionexplorer.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+*   Copyright (C) 2005-2014 by Oleksandr Shneyder                         *
+*   o.shneyder at phoca-gmbh.de                                              *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*   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 General Public License for more details.                          *
+*                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
+***************************************************************************/
+
+#ifndef SESSIONEXPLORER_H
+#define SESSIONEXPLORER_H
+
+#include <QObject>
+#include <QList>
+#include <QStringList>
+
+class SessionButton;
+class FolderButton;
+class ONMainWindow;
+class QToolButton;
+class QLabel;
+class QHBoxLayout;
+
+class SessionExplorer: public QObject
+{
+    Q_OBJECT
+public:
+    SessionExplorer(ONMainWindow *p);
+    ~SessionExplorer();
+    QList<SessionButton*> * getSessionsList()
+    {
+        return &sessions;
+    }
+    SessionButton* getLastSession() {
+        return lastSession;
+    }
+    void setLastSession(SessionButton* s)
+    {
+        lastSession=s;
+    }
+    void cleanSessions();
+    SessionButton* createBut ( const QString& id );
+    void placeButtons();
+    QHBoxLayout* getNavigationLayout()
+    {
+        return navigationLayout;
+    }
+    void resize();
+//vars
+private:
+    QList<SessionButton*> sessions;
+    QList<FolderButton*> folders;
+    SessionButton* lastSession;
+    ONMainWindow* parent;
+    QToolButton* backButton;
+    QLabel* pathLabel;
+    QHBoxLayout* navigationLayout;
+    QString currentPath;
+
+//functions
+private:
+    void setNavigationVisible(bool value);
+    int findFolder(QString path);
+    void createFolder(QString path);
+
+public slots:
+    void slotDeleteButton ( SessionButton * bt );
+    void slotEdit ( SessionButton* );
+    void slotCreateDesktopIcon ( SessionButton* bt );
+    void exportsEdit ( SessionButton* bt );
+private slots:
+    void slotFolderSelected(FolderButton* bt);
+    void slotLevelUp();
+    QStringList getFolderChildren(FolderButton* folder);
+};
+
+#endif
diff --git a/sessionmanagedialog.cpp b/sessionmanagedialog.cpp
index 11a7790..ca11f31 100644
--- a/sessionmanagedialog.cpp
+++ b/sessionmanagedialog.cpp
@@ -27,97 +27,98 @@
 #include <QStringListModel>
 #include <QShortcut>
 #include "sessionbutton.h"
+#include "sessionexplorer.h"
 
 
 
 SessionManageDialog::SessionManageDialog ( QWidget * parent,
         bool onlyCreateIcon, Qt::WFlags f )
-		: QDialog ( parent, f )
+    : QDialog ( parent, f )
 {
-	QVBoxLayout* ml=new QVBoxLayout ( this );
-	QFrame *fr=new QFrame ( this );
-	QHBoxLayout* frLay=new QHBoxLayout ( fr );
+    QVBoxLayout* ml=new QVBoxLayout ( this );
+    QFrame *fr=new QFrame ( this );
+    QHBoxLayout* frLay=new QHBoxLayout ( fr );
 
-	QPushButton* ok=new QPushButton ( tr ( "E&xit" ),this );
-	QHBoxLayout* bLay=new QHBoxLayout();
+    QPushButton* ok=new QPushButton ( tr ( "E&xit" ),this );
+    QHBoxLayout* bLay=new QHBoxLayout();
 
-	sessions=new QListView ( fr );
-	frLay->addWidget ( sessions );
+    sessions=new QListView ( fr );
+    frLay->addWidget ( sessions );
 
-	QPushButton* newSession=new QPushButton ( tr ( "&New session" ),fr );
-	editSession=new QPushButton ( tr ( "&Session preferences" ),fr );
-	removeSession=new QPushButton ( tr ( "&Delete session" ),fr );
+    QPushButton* newSession=new QPushButton ( tr ( "&New session" ),fr );
+    editSession=new QPushButton ( tr ( "&Session preferences" ),fr );
+    removeSession=new QPushButton ( tr ( "&Delete session" ),fr );
 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
-	if ( !ONMainWindow::getPortable() )
-		createSessionIcon=new QPushButton (
-		    tr ( "&Create session icon on desktop..." ),fr );
+    if ( !ONMainWindow::getPortable() )
+        createSessionIcon=new QPushButton (
+            tr ( "&Create session icon on desktop..." ),fr );
 #endif
-	par= ( ONMainWindow* ) parent;
-	newSession->setIcon ( QIcon (
-	                          par->iconsPath ( "/16x16/new_file.png" ) ) );
-	editSession->setIcon ( QIcon (
-	                           par->iconsPath ( "/16x16/edit.png" ) ) );
+    par= ( ONMainWindow* ) parent;
+    newSession->setIcon ( QIcon (
+                              par->iconsPath ( "/16x16/new_file.png" ) ) );
+    editSession->setIcon ( QIcon (
+                               par->iconsPath ( "/16x16/edit.png" ) ) );
 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
-	if ( !ONMainWindow::getPortable() )
-		createSessionIcon->setIcon (
-		    QIcon ( par->iconsPath ( "/16x16/create_file.png" ) ) );
+    if ( !ONMainWindow::getPortable() )
+        createSessionIcon->setIcon (
+            QIcon ( par->iconsPath ( "/16x16/create_file.png" ) ) );
 #endif
-	removeSession->setIcon (
-	    QIcon ( par->iconsPath ( "/16x16/delete.png" ) ) );
+    removeSession->setIcon (
+        QIcon ( par->iconsPath ( "/16x16/delete.png" ) ) );
 
-	QVBoxLayout* actLay=new QVBoxLayout();
-	actLay->addWidget ( newSession );
-	actLay->addWidget ( editSession );
-	actLay->addWidget ( removeSession );
+    QVBoxLayout* actLay=new QVBoxLayout();
+    actLay->addWidget ( newSession );
+    actLay->addWidget ( editSession );
+    actLay->addWidget ( removeSession );
 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
-	if ( !ONMainWindow::getPortable() )
-		actLay->addWidget ( createSessionIcon );
+    if ( !ONMainWindow::getPortable() )
+        actLay->addWidget ( createSessionIcon );
 #endif
-	actLay->addStretch();
-	frLay->addLayout ( actLay );
-
-	if ( onlyCreateIcon )
-	{
-		newSession->hide();
-		editSession->hide();
-		removeSession->hide();
-	}
-
-	QShortcut* sc=new QShortcut (
-	    QKeySequence ( tr ( "Delete","Delete" ) ),this );
-	connect ( ok,SIGNAL ( clicked() ),this,SLOT ( close() ) );
-	connect (
-	    sc,SIGNAL ( activated() ),removeSession,SIGNAL ( clicked() ) );
-	connect (
-	    removeSession,SIGNAL ( clicked() ),this,SLOT ( slot_delete() ) );
-	connect ( editSession,SIGNAL ( clicked() ),this,SLOT ( slot_edit() ) );
+    actLay->addStretch();
+    frLay->addLayout ( actLay );
+
+    if ( onlyCreateIcon )
+    {
+        newSession->hide();
+        editSession->hide();
+        removeSession->hide();
+    }
+
+    QShortcut* sc=new QShortcut (
+        QKeySequence ( tr ( "Delete","Delete" ) ),this );
+    connect ( ok,SIGNAL ( clicked() ),this,SLOT ( close() ) );
+    connect (
+        sc,SIGNAL ( activated() ),removeSession,SIGNAL ( clicked() ) );
+    connect (
+        removeSession,SIGNAL ( clicked() ),this,SLOT ( slot_delete() ) );
+    connect ( editSession,SIGNAL ( clicked() ),this,SLOT ( slot_edit() ) );
 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
-	if ( !ONMainWindow::getPortable() )
-		connect ( createSessionIcon,SIGNAL ( clicked() ),
-		          this,SLOT ( slot_createSessionIcon() ) );
+    if ( !ONMainWindow::getPortable() )
+        connect ( createSessionIcon,SIGNAL ( clicked() ),
+                  this,SLOT ( slot_createSessionIcon() ) );
 #endif
-	connect ( newSession,SIGNAL ( clicked() ),this,SLOT ( slotNew() ) );
-	bLay->setSpacing ( 5 );
-	bLay->addStretch();
-	bLay->addWidget ( ok );
-	ml->addWidget ( fr );
-	ml->addLayout ( bLay );
-
-	fr->setFrameStyle ( QFrame::StyledPanel | QFrame::Raised );
-	fr->setLineWidth ( 2 );
-
-	setSizeGripEnabled ( true );
-	setWindowIcon (
-	    QIcon (
-	        ( ( ONMainWindow* ) parent )->iconsPath (
-	            "/32x32/edit.png" ) ) );
-
-	setWindowTitle ( tr ( "Session management" ) );
-	loadSessions();
-	connect ( sessions,SIGNAL ( clicked ( const QModelIndex& ) ),
-	          this,SLOT ( slot_activated ( const QModelIndex& ) ) );
-	connect ( sessions,SIGNAL ( doubleClicked ( const QModelIndex& ) ),
-	          this,SLOT ( slot_dclicked ( const QModelIndex& ) ) );
+    connect ( newSession,SIGNAL ( clicked() ),this,SLOT ( slotNew() ) );
+    bLay->setSpacing ( 5 );
+    bLay->addStretch();
+    bLay->addWidget ( ok );
+    ml->addWidget ( fr );
+    ml->addLayout ( bLay );
+
+    fr->setFrameStyle ( QFrame::StyledPanel | QFrame::Raised );
+    fr->setLineWidth ( 2 );
+
+    setSizeGripEnabled ( true );
+    setWindowIcon (
+        QIcon (
+            ( ( ONMainWindow* ) parent )->iconsPath (
+                "/32x32/edit.png" ) ) );
+
+    setWindowTitle ( tr ( "Session management" ) );
+    loadSessions();
+    connect ( sessions,SIGNAL ( clicked ( const QModelIndex& ) ),
+              this,SLOT ( slot_activated ( const QModelIndex& ) ) );
+    connect ( sessions,SIGNAL ( doubleClicked ( const QModelIndex& ) ),
+              this,SLOT ( slot_dclicked ( const QModelIndex& ) ) );
 }
 
 
@@ -127,75 +128,75 @@ SessionManageDialog::~SessionManageDialog()
 
 void SessionManageDialog::loadSessions()
 {
-	QStringListModel *model= ( QStringListModel* ) sessions->model();
-	if ( !model )
-		model=new QStringListModel();
-	sessions->setModel ( model );
-	QStringList lst;
-	model->setStringList ( lst );
+    QStringListModel *model= ( QStringListModel* ) sessions->model();
+    if ( !model )
+        model=new QStringListModel();
+    sessions->setModel ( model );
+    QStringList lst;
+    model->setStringList ( lst );
 
-	const QList<SessionButton*> *sess=par->getSessionsList();
+    const QList<SessionButton*> *sess=par->getSessionExplorer()->getSessionsList();
 
-	for ( int i=0;i<sess->size();++i )
-		lst<<sess->at ( i )->name();
+    for ( int i=0; i<sess->size(); ++i )
+        lst<<sess->at ( i )->name();
 
-	model->setStringList ( lst );
-	removeSession->setEnabled ( false );
-	editSession->setEnabled ( false );
+    model->setStringList ( lst );
+    removeSession->setEnabled ( false );
+    editSession->setEnabled ( false );
 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
-	if ( !ONMainWindow::getPortable() )
-		createSessionIcon->setEnabled ( false );
+    if ( !ONMainWindow::getPortable() )
+        createSessionIcon->setEnabled ( false );
 #endif
-	sessions->setEditTriggers ( QAbstractItemView::NoEditTriggers );
+    sessions->setEditTriggers ( QAbstractItemView::NoEditTriggers );
 }
 
 
 void SessionManageDialog::slot_activated ( const QModelIndex& )
 {
-	removeSession->setEnabled ( true );
-	editSession->setEnabled ( true );
+    removeSession->setEnabled ( true );
+    editSession->setEnabled ( true );
 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
-	if ( !ONMainWindow::getPortable() )
-		createSessionIcon->setEnabled ( true );
+    if ( !ONMainWindow::getPortable() )
+        createSessionIcon->setEnabled ( true );
 #endif
 }
 
 void SessionManageDialog::slot_dclicked ( const QModelIndex& )
 {
-	slot_edit();
+    slot_edit();
 }
 
 
 void SessionManageDialog::slotNew()
 {
-	par->slotNewSession();
-	loadSessions();
+    par->slotNewSession();
+    loadSessions();
 }
 
 
 void SessionManageDialog::slot_edit()
 {
-	int ind=sessions->currentIndex().row();
-	if ( ind<0 )
-		return;
-	par->slotEdit ( par->getSessionsList()->at ( ind ) );
-	loadSessions();
+    int ind=sessions->currentIndex().row();
+    if ( ind<0 )
+        return;
+    par->getSessionExplorer()->slotEdit ( par->getSessionExplorer()->getSessionsList()->at ( ind ) );
+    loadSessions();
 }
 
 void SessionManageDialog::slot_createSessionIcon()
 {
-	int ind=sessions->currentIndex().row();
-	if ( ind<0 )
-		return;
-	par->slotCreateDesktopIcon ( par->getSessionsList()->at ( ind ) );
+    int ind=sessions->currentIndex().row();
+    if ( ind<0 )
+        return;
+    par->getSessionExplorer()->slotCreateDesktopIcon ( par->getSessionExplorer()->getSessionsList()->at ( ind ) );
 }
 
 
 void SessionManageDialog::slot_delete()
 {
-	int ind=sessions->currentIndex().row();
-	if ( ind<0 )
-		return;
-	par->slotDeleteButton ( par->getSessionsList()->at ( ind ) );
-	loadSessions();
+    int ind=sessions->currentIndex().row();
+    if ( ind<0 )
+        return;
+    par->getSessionExplorer()->slotDeleteButton ( par->getSessionExplorer()->getSessionsList()->at ( ind ) );
+    loadSessions();
 }
diff --git a/svg/folder.svg b/svg/folder.svg
new file mode 100644
index 0000000..509c0e3
--- /dev/null
+++ b/svg/folder.svg
@@ -0,0 +1,696 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="340"
+   height="190"
+   id="svg2251"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="sessionbut.svg">
+  <metadata
+     id="metadata1343">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1060"
+     inkscape:window-width="1740"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="2.3263158"
+     inkscape:cx="170"
+     inkscape:cy="95"
+     inkscape:window-x="-3"
+     inkscape:window-y="-3"
+     inkscape:current-layer="svg2251"
+     showgrid="true"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2819"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       dotted="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs2253">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3585">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587" />
+      <stop
+         id="stop3593"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 95 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="340 : 95 : 1"
+       inkscape:persp3d-origin="170 : 63.333333 : 1"
+       id="perspective7" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585"
+       id="radialGradient3591"
+       cx="170.34201"
+       cy="95.038906"
+       fx="170.34201"
+       fy="95.038906"
+       r="169.7401"
+       gradientTransform="matrix(1,0,0,0.55567729,0,42.227945)"
+       gradientUnits="userSpaceOnUse" />
+    <inkscape:perspective
+       id="perspective2856"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2855"
+       id="linearGradient2861"
+       x1="880.47284"
+       y1="-340.41806"
+       x2="300.16119"
+       y2="219.88284"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient2855">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2857" />
+      <stop
+         style="stop-color:#246ed8;stop-opacity:1;"
+         offset="1"
+         id="stop2859" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0.99946294,0,0,0.99946294,-215,-204.76475)"
+       y2="219.88284"
+       x2="300.16119"
+       y1="-340.41806"
+       x1="880.47284"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2865"
+       xlink:href="#linearGradient2855"
+       inkscape:collect="always" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585"
+       id="radialGradient2866"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,1.4042554,42.928517)"
+       cx="170.34201"
+       cy="95.038906"
+       fx="170.34201"
+       fy="95.038906"
+       r="169.7401" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290"
+       id="linearGradient4296"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298"
+       id="linearGradient4304"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-2"
+       id="radialGradient2866-7"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,6.40426,37.92852)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       id="linearGradient3585-2">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587-8" />
+      <stop
+         id="stop3593-3"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589-8" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-2"
+       id="linearGradient4296-0"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(5,-5)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290-2">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292-8" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294-5" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-7"
+       id="linearGradient4304-9"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298-7">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300-2" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302-7" />
+    </linearGradient>
+    <linearGradient
+       y2="140"
+       x2="270"
+       y1="95"
+       x1="275"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7548"
+       xlink:href="#linearGradient4298-7"
+       inkscape:collect="always"
+       gradientTransform="translate(5,-5)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-4"
+       id="radialGradient2866-2"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,11.404255,32.92852)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       id="linearGradient3585-4">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587-3" />
+      <stop
+         id="stop3593-9"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589-6" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-0"
+       id="linearGradient4296-2"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(10,-10)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290-0">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292-3" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294-7" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-9"
+       id="linearGradient4304-3"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298-9">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300-6" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302-0" />
+    </linearGradient>
+    <linearGradient
+       y2="140"
+       x2="270"
+       y1="95"
+       x1="275"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7548-1"
+       xlink:href="#linearGradient4298-9"
+       inkscape:collect="always"
+       gradientTransform="translate(10,-10)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-8"
+       id="radialGradient2866-76"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,16.40426,27.92852)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       id="linearGradient3585-8">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587-9" />
+      <stop
+         id="stop3593-38"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589-7" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-21"
+       id="linearGradient4296-3"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(15,-15)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290-21">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292-86" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294-1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-0"
+       id="linearGradient4304-6"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298-0">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300-3" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302-9" />
+    </linearGradient>
+    <linearGradient
+       y2="140"
+       x2="270"
+       y1="95"
+       x1="275"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7548-7"
+       xlink:href="#linearGradient4298-0"
+       inkscape:collect="always"
+       gradientTransform="translate(15,-15)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585"
+       id="radialGradient7711"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0334139,0,0,0.59115143,-13.533793,46.31761)"
+       cx="170.34201"
+       cy="95.038906"
+       fx="170.34201"
+       fy="95.038906"
+       r="169.7401" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290"
+       id="linearGradient7713"
+       gradientUnits="userSpaceOnUse"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,-15,0)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298"
+       id="linearGradient7715"
+       gradientUnits="userSpaceOnUse"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,-15,0)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-2"
+       id="radialGradient7717"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0334139,0,0,0.59115143,-8.5337874,41.317614)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-2"
+       id="linearGradient7719"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,-10,-5)"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-7"
+       id="linearGradient7721"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,-10,-5)"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-4"
+       id="radialGradient7723"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0334139,0,0,0.59115143,-3.5337926,36.317614)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-0"
+       id="linearGradient7725"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,-5,-10)"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-9"
+       id="linearGradient7727"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,-5,-10)"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-8"
+       id="radialGradient7729"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0334139,0,0,0.59115143,1.4662126,31.317614)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-21"
+       id="linearGradient7731"
+       gradientUnits="userSpaceOnUse"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,0,-15)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-0"
+       id="linearGradient7733"
+       gradientUnits="userSpaceOnUse"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientTransform="matrix(1.0441176,0,0,1.0789474,0,-15)" />
+  </defs>
+  <g
+     id="g7685"
+     transform="matrix(0.95774648,0,0,0.92682927,14.366197,0)">
+    <g
+       id="g7455">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         d="m 333.15625,3.8125 -180.8125,101.03125 22.6875,23.375 L 339,70.34375 339,35 l 0,-10 0,-9.59375 c 0,-4.772242 -2.29432,-8.9744678 -5.84375,-11.59375 z"
+         id="path3621"
+         inkscape:connector-curvature="0" />
+      <rect
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+         id="rect1345"
+         width="340"
+         height="190"
+         x="0"
+         y="-3.5505453e-15"
+         rx="15.106382"
+         ry="15.698687" />
+      <rect
+         ry="15.368187"
+         rx="14.928659"
+         y="2"
+         x="2"
+         height="186"
+         width="336"
+         id="rect2823"
+         style="fill:url(#radialGradient7711);fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+      <path
+         style="fill:url(#linearGradient7713);fill-opacity:1;stroke:none"
+         d="m 223.8125,1 -94.65625,79.9375 23.1875,23.90625 L 333.15625,3.8125 c -0.0187,-0.013814 -0.0437,-0.017523 -0.0625,-0.03125 C 332.83238,3.5902996 332.58691,3.3923576 332.3125,3.21875 332.293,3.206404 332.2695,3.199755 332.25,3.1875 331.96672,3.0101846 331.67115,2.8454027 331.375,2.6875 331.3419,2.669844 331.3145,2.642402 331.2813,2.625 330.95052,2.4519533 330.59534,2.3038738 330.25,2.15625 329.90466,2.0086262 329.54623,1.8708336 329.1875,1.75 c -0.35873,-0.1208336 -0.72286,-0.2 [...]
+         id="rect3614"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:url(#linearGradient7715);fill-opacity:1;stroke:none"
+         d="m 339,70.34375 -163.96875,57.875 23.1875,23.875 L 339,125.1875 339,70.34375 z"
+         id="path2828"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       transform="translate(-5,5)"
+       id="g7455-1">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         d="m 333.15625,3.8125 -180.8125,101.03125 22.6875,23.375 L 339,70.34375 339,35 l 0,-10 0,-9.59375 c 0,-4.772242 -2.29432,-8.9744678 -5.84375,-11.59375 z"
+         id="path3621-6"
+         inkscape:connector-curvature="0" />
+      <rect
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+         id="rect1345-0"
+         width="340"
+         height="190"
+         x="0"
+         y="-3.5505453e-15"
+         rx="15.106382"
+         ry="15.698687" />
+      <rect
+         ry="15.368187"
+         rx="14.928659"
+         y="2"
+         x="2"
+         height="186"
+         width="336"
+         id="rect2823-6"
+         style="fill:url(#radialGradient7717);fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+      <path
+         style="fill:url(#linearGradient7719);fill-opacity:1;stroke:none"
+         d="m 223.8125,1 -94.65625,79.9375 23.1875,23.90625 L 333.15625,3.8125 c -0.0187,-0.013814 -0.0437,-0.017523 -0.0625,-0.03125 C 332.83238,3.5902996 332.58691,3.3923576 332.3125,3.21875 332.293,3.206404 332.2695,3.199755 332.25,3.1875 331.96672,3.0101846 331.67115,2.8454027 331.375,2.6875 331.3419,2.669844 331.3145,2.642402 331.2813,2.625 330.95052,2.4519533 330.59534,2.3038738 330.25,2.15625 329.90466,2.0086262 329.54623,1.8708336 329.1875,1.75 c -0.35873,-0.1208336 -0.72286,-0.2 [...]
+         id="rect3614-0"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:url(#linearGradient7721);fill-opacity:1;stroke:none"
+         d="m 339,70.34375 -163.96875,57.875 23.1875,23.875 L 339,125.1875 339,70.34375 z"
+         id="path2828-4"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       transform="translate(-10,10)"
+       id="g7455-4">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         d="m 333.15625,3.8125 -180.8125,101.03125 22.6875,23.375 L 339,70.34375 339,35 l 0,-10 0,-9.59375 c 0,-4.772242 -2.29432,-8.9744678 -5.84375,-11.59375 z"
+         id="path3621-5"
+         inkscape:connector-curvature="0" />
+      <rect
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+         id="rect1345-06"
+         width="340"
+         height="190"
+         x="0"
+         y="-3.5505453e-15"
+         rx="15.106382"
+         ry="15.698687" />
+      <rect
+         ry="15.368187"
+         rx="14.928659"
+         y="2"
+         x="2"
+         height="186"
+         width="336"
+         id="rect2823-9"
+         style="fill:url(#radialGradient7723);fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+      <path
+         style="fill:url(#linearGradient7725);fill-opacity:1;stroke:none"
+         d="m 223.8125,1 -94.65625,79.9375 23.1875,23.90625 L 333.15625,3.8125 c -0.0187,-0.013814 -0.0437,-0.017523 -0.0625,-0.03125 C 332.83238,3.5902996 332.58691,3.3923576 332.3125,3.21875 332.293,3.206404 332.2695,3.199755 332.25,3.1875 331.96672,3.0101846 331.67115,2.8454027 331.375,2.6875 331.3419,2.669844 331.3145,2.642402 331.2813,2.625 330.95052,2.4519533 330.59534,2.3038738 330.25,2.15625 329.90466,2.0086262 329.54623,1.8708336 329.1875,1.75 c -0.35873,-0.1208336 -0.72286,-0.2 [...]
+         id="rect3614-04"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:url(#linearGradient7727);fill-opacity:1;stroke:none"
+         d="m 339,70.34375 -163.96875,57.875 23.1875,23.875 L 339,125.1875 339,70.34375 z"
+         id="path2828-8"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       transform="translate(-15,15)"
+       id="g7455-6">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         d="m 333.15625,3.8125 -180.8125,101.03125 22.6875,23.375 L 339,70.34375 339,35 l 0,-10 0,-9.59375 c 0,-4.772242 -2.29432,-8.9744678 -5.84375,-11.59375 z"
+         id="path3621-1"
+         inkscape:connector-curvature="0" />
+      <rect
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+         id="rect1345-5"
+         width="340"
+         height="190"
+         x="0"
+         y="-3.5505453e-15"
+         rx="15.106382"
+         ry="15.698687" />
+      <rect
+         ry="15.368187"
+         rx="14.928659"
+         y="2"
+         x="2"
+         height="186"
+         width="336"
+         id="rect2823-8"
+         style="fill:url(#radialGradient7729);fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+      <path
+         style="fill:url(#linearGradient7731);fill-opacity:1;stroke:none"
+         d="m 223.8125,1 -94.65625,79.9375 23.1875,23.90625 L 333.15625,3.8125 c -0.0187,-0.013814 -0.0437,-0.017523 -0.0625,-0.03125 C 332.83238,3.5902996 332.58691,3.3923576 332.3125,3.21875 332.293,3.206404 332.2695,3.199755 332.25,3.1875 331.96672,3.0101846 331.67115,2.8454027 331.375,2.6875 331.3419,2.669844 331.3145,2.642402 331.2813,2.625 330.95052,2.4519533 330.59534,2.3038738 330.25,2.15625 329.90466,2.0086262 329.54623,1.8708336 329.1875,1.75 c -0.35873,-0.1208336 -0.72286,-0.2 [...]
+         id="rect3614-2"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:url(#linearGradient7733);fill-opacity:1;stroke:none"
+         d="m 339,70.34375 -163.96875,57.875 23.1875,23.875 L 339,125.1875 339,70.34375 z"
+         id="path2828-0"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/svg/folder_grey.svg b/svg/folder_grey.svg
new file mode 100644
index 0000000..b78e651
--- /dev/null
+++ b/svg/folder_grey.svg
@@ -0,0 +1,513 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="340"
+   height="190"
+   id="svg2251"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="folder_grey.svg">
+  <metadata
+     id="metadata1343">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1060"
+     inkscape:window-width="1740"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.2899074"
+     inkscape:cx="154.29827"
+     inkscape:cy="77.411535"
+     inkscape:window-x="-3"
+     inkscape:window-y="-3"
+     inkscape:current-layer="svg2251"
+     showgrid="true"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2819"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       dotted="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs2253">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3585">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587" />
+      <stop
+         id="stop3593"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 95 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="340 : 95 : 1"
+       inkscape:persp3d-origin="170 : 63.333333 : 1"
+       id="perspective7" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585"
+       id="radialGradient3591"
+       cx="170.34201"
+       cy="95.038906"
+       fx="170.34201"
+       fy="95.038906"
+       r="169.7401"
+       gradientTransform="matrix(1,0,0,0.55567729,0,42.227945)"
+       gradientUnits="userSpaceOnUse" />
+    <inkscape:perspective
+       id="perspective2856"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2855"
+       id="linearGradient2861"
+       x1="880.47284"
+       y1="-340.41806"
+       x2="300.16119"
+       y2="219.88284"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient2855">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2857" />
+      <stop
+         style="stop-color:#246ed8;stop-opacity:1;"
+         offset="1"
+         id="stop2859" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0.99946294,0,0,0.99946294,-215,-204.76475)"
+       y2="219.88284"
+       x2="300.16119"
+       y1="-340.41806"
+       x1="880.47284"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2865"
+       xlink:href="#linearGradient2855"
+       inkscape:collect="always" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585"
+       id="radialGradient2866"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,1.4042554,42.928517)"
+       cx="170.34201"
+       cy="95.038906"
+       fx="170.34201"
+       fy="95.038906"
+       r="169.7401" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290"
+       id="linearGradient4296"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298"
+       id="linearGradient4304"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-2"
+       id="radialGradient2866-7"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,6.40426,37.92852)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       id="linearGradient3585-2">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587-8" />
+      <stop
+         id="stop3593-3"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589-8" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-2"
+       id="linearGradient4296-0"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(5,-5)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290-2">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292-8" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294-5" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-7"
+       id="linearGradient4304-9"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298-7">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300-2" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302-7" />
+    </linearGradient>
+    <linearGradient
+       y2="140"
+       x2="270"
+       y1="95"
+       x1="275"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7548"
+       xlink:href="#linearGradient4298-7"
+       inkscape:collect="always"
+       gradientTransform="translate(5,-5)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-4"
+       id="radialGradient2866-2"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,11.404255,32.92852)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       id="linearGradient3585-4">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587-3" />
+      <stop
+         id="stop3593-9"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589-6" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-0"
+       id="linearGradient4296-2"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(10,-10)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290-0">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292-3" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294-7" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-9"
+       id="linearGradient4304-3"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298-9">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300-6" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302-0" />
+    </linearGradient>
+    <linearGradient
+       y2="140"
+       x2="270"
+       y1="95"
+       x1="275"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7548-1"
+       xlink:href="#linearGradient4298-9"
+       inkscape:collect="always"
+       gradientTransform="translate(10,-10)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3585-8"
+       id="radialGradient2866-76"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.98974848,0,0,0.54789645,16.40426,27.92852)"
+       cx="170.34201"
+       cy="95.038902"
+       fx="170.34201"
+       fy="95.038902"
+       r="169.7401" />
+    <linearGradient
+       id="linearGradient3585-8">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3587-9" />
+      <stop
+         id="stop3593-38"
+         offset="0.5"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e6e7e6;stop-opacity:1;"
+         offset="1"
+         id="stop3589-7" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4290-21"
+       id="linearGradient4296-3"
+       x1="215"
+       y1="10"
+       x2="230"
+       y2="55"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(15,-15)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4290-21">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4292-86" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4294-1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4298-0"
+       id="linearGradient4304-6"
+       x1="275"
+       y1="95"
+       x2="270"
+       y2="140"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4298-0">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4300-3" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4302-9" />
+    </linearGradient>
+    <linearGradient
+       y2="140"
+       x2="270"
+       y1="95"
+       x1="275"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7548-7"
+       xlink:href="#linearGradient4298-0"
+       inkscape:collect="always"
+       gradientTransform="translate(15,-15)" />
+  </defs>
+  <path
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     d="m 333.44542,3.5335366 -173.17253,93.6387194 21.72887,21.664634 157.04049,-53.640244 0,-32.757622 0,-9.268292 0,-8.891769 c 0,-4.4230531 -2.19737,-8.317799 -5.59683,-10.7454264 z"
+     id="path3621"
+     inkscape:connector-curvature="0" />
+  <rect
+     style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+     id="rect1345"
+     width="325.63379"
+     height="176.09756"
+     x="14.366197"
+     y="-3.2907493e-15"
+     rx="14.468084"
+     ry="14.550002" />
+  <rect
+     ry="14.243686"
+     rx="14.297871"
+     y="1.8536586"
+     x="16.281691"
+     height="172.39024"
+     width="321.80283"
+     id="rect2823"
+     style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+  <path
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     d="M 328.65669,8.1676829 155.48415,101.8064 l 21.72888,21.66464 157.04049,-53.640247 0,-32.757622 0,-9.268293 0,-8.891768 c 0,-4.423054 -2.19738,-8.3178 -5.59683,-10.7454271 z"
+     id="path3621-6"
+     inkscape:connector-curvature="0" />
+  <rect
+     style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+     id="rect1345-0"
+     width="325.63379"
+     height="176.09756"
+     x="9.5774651"
+     y="4.6341462"
+     rx="14.468084"
+     ry="14.550002" />
+  <rect
+     ry="14.243686"
+     rx="14.297871"
+     y="6.4878049"
+     x="11.492957"
+     height="172.39024"
+     width="321.80283"
+     id="rect2823-6"
+     style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+  <path
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     d="m 323.86796,12.801829 -173.17254,93.638721 21.72888,21.66463 157.04049,-53.640241 0,-32.757622 0,-9.268293 0,-8.891768 c 0,-4.423053 -2.19738,-8.317799 -5.59683,-10.745427 z"
+     id="path3621-5"
+     inkscape:connector-curvature="0" />
+  <rect
+     style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+     id="rect1345-06"
+     width="325.63379"
+     height="176.09756"
+     x="4.7887321"
+     y="9.2682924"
+     rx="14.468084"
+     ry="14.550002" />
+  <rect
+     ry="14.243686"
+     rx="14.297871"
+     y="11.121951"
+     x="6.7042251"
+     height="172.39024"
+     width="321.80283"
+     id="rect2823-9"
+     style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+  <path
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     d="m 319.07923,17.435976 -173.17254,93.638724 21.72887,21.66463 157.0405,-53.640245 0,-32.757622 0,-9.268292 0,-8.891769 c 0,-4.423053 -2.19738,-8.317799 -5.59683,-10.745426 z"
+     id="path3621-1"
+     inkscape:connector-curvature="0" />
+  <rect
+     style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none"
+     id="rect1345-5"
+     width="325.63379"
+     height="176.09756"
+     x="-2e-07"
+     y="13.902439"
+     rx="14.468084"
+     ry="14.550002" />
+  <rect
+     ry="14.243686"
+     rx="14.297871"
+     y="15.756098"
+     x="1.9154928"
+     height="172.39024"
+     width="321.80283"
+     id="rect2823-8"
+     style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:#a0a0a0;stroke-width:0;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none" />
+</svg>
diff --git a/x2goclient.pro b/x2goclient.pro
index 99d0fb7..22260fb 100755
--- a/x2goclient.pro
+++ b/x2goclient.pro
@@ -71,7 +71,9 @@ HEADERS += configdialog.h \
            xsettingswidget.h \
            appdialog.h \
            x2goutils.h \
-           helpdialog.h
+           helpdialog.h \
+           sessionexplorer.h \
+           folderbutton.h
 
 SOURCES += sharewidget.cpp \
            settingswidget.cpp\
@@ -108,7 +110,9 @@ SOURCES += sharewidget.cpp \
            xsettingswidget.cpp \
            appdialog.cpp \
            x2goutils.cpp \
-           helpdialog.cpp
+           helpdialog.cpp \
+           sessionexplorer.cpp \
+           folderbutton.cpp
 
 LIBS += -lssh
 

--
Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2goclient.git


More information about the x2go-commits mailing list