summaryrefslogtreecommitdiffstats
path: root/smb4k
diff options
context:
space:
mode:
Diffstat (limited to 'smb4k')
-rw-r--r--smb4k/Makefile.am22
-rw-r--r--smb4k/browser/Makefile.am15
-rw-r--r--smb4k/browser/smb4knetworkbrowser.cpp211
-rw-r--r--smb4k/browser/smb4knetworkbrowser.h153
-rw-r--r--smb4k/browser/smb4knetworkbrowser_part.cpp1929
-rw-r--r--smb4k/browser/smb4knetworkbrowser_part.h377
-rw-r--r--smb4k/browser/smb4knetworkbrowser_part.rc31
-rw-r--r--smb4k/browser/smb4knetworkbrowseritem.cpp228
-rw-r--r--smb4k/browser/smb4knetworkbrowseritem.h222
-rw-r--r--smb4k/browser/smb4knetworkbrowsertooltip.cpp378
-rw-r--r--smb4k/browser/smb4knetworkbrowsertooltip.h122
-rw-r--r--smb4k/configdlg/Makefile.am12
-rw-r--r--smb4k/configdlg/smb4kauthoptions.cpp135
-rw-r--r--smb4k/configdlg/smb4kauthoptions.h81
-rw-r--r--smb4k/configdlg/smb4kconfigdialog.cpp1222
-rw-r--r--smb4k/configdlg/smb4kconfigdialog.h208
-rw-r--r--smb4k/configdlg/smb4knetworkoptions.cpp107
-rw-r--r--smb4k/configdlg/smb4knetworkoptions.h63
-rw-r--r--smb4k/configdlg/smb4krsyncoptions.cpp351
-rw-r--r--smb4k/configdlg/smb4krsyncoptions.h108
-rw-r--r--smb4k/configdlg/smb4ksambaoptions.cpp1230
-rw-r--r--smb4k/configdlg/smb4ksambaoptions.h168
-rw-r--r--smb4k/configdlg/smb4kshareoptions.cpp98
-rw-r--r--smb4k/configdlg/smb4kshareoptions.h62
-rw-r--r--smb4k/configdlg/smb4ksuperuseroptions.cpp101
-rw-r--r--smb4k/configdlg/smb4ksuperuseroptions.h79
-rw-r--r--smb4k/configdlg/smb4kuserinterfaceoptions.cpp207
-rw-r--r--smb4k/configdlg/smb4kuserinterfaceoptions.h68
-rw-r--r--smb4k/core/Makefile.am35
-rw-r--r--smb4k/core/smb4k.kcfg998
-rw-r--r--smb4k/core/smb4kauthinfo.cpp63
-rw-r--r--smb4k/core/smb4kauthinfo.h148
-rw-r--r--smb4k/core/smb4kbookmark.cpp97
-rw-r--r--smb4k/core/smb4kbookmark.h212
-rw-r--r--smb4k/core/smb4kbookmarkhandler.cpp342
-rw-r--r--smb4k/core/smb4kbookmarkhandler.h162
-rw-r--r--smb4k/core/smb4kcore.cpp955
-rw-r--r--smb4k/core/smb4kcore.h354
-rw-r--r--smb4k/core/smb4kdefs.h147
-rw-r--r--smb4k/core/smb4kerror.cpp408
-rw-r--r--smb4k/core/smb4kerror.h92
-rw-r--r--smb4k/core/smb4kfileio.cpp1795
-rw-r--r--smb4k/core/smb4kfileio.h246
-rw-r--r--smb4k/core/smb4kglobal.cpp78
-rw-r--r--smb4k/core/smb4kglobal.h115
-rw-r--r--smb4k/core/smb4kglobal_p.cpp123
-rw-r--r--smb4k/core/smb4kglobal_p.h102
-rw-r--r--smb4k/core/smb4khomesshareshandler.cpp361
-rw-r--r--smb4k/core/smb4khomesshareshandler.h139
-rw-r--r--smb4k/core/smb4kmounter.cpp1718
-rw-r--r--smb4k/core/smb4kmounter.h343
-rw-r--r--smb4k/core/smb4kmounter_p.cpp135
-rw-r--r--smb4k/core/smb4kmounter_p.h126
-rw-r--r--smb4k/core/smb4knetworkitems.cpp239
-rw-r--r--smb4k/core/smb4knetworkitems.h487
-rw-r--r--smb4k/core/smb4kpasswordhandler.cpp1001
-rw-r--r--smb4k/core/smb4kpasswordhandler.h305
-rw-r--r--smb4k/core/smb4kpreviewer.cpp361
-rw-r--r--smb4k/core/smb4kpreviewer.h190
-rw-r--r--smb4k/core/smb4kpreviewitem.cpp101
-rw-r--r--smb4k/core/smb4kpreviewitem.h216
-rw-r--r--smb4k/core/smb4kprint.cpp372
-rw-r--r--smb4k/core/smb4kprint.h170
-rw-r--r--smb4k/core/smb4kprintinfo.cpp76
-rw-r--r--smb4k/core/smb4kprintinfo.h147
-rw-r--r--smb4k/core/smb4ksambaoptionshandler.cpp1559
-rw-r--r--smb4k/core/smb4ksambaoptionshandler.h253
-rw-r--r--smb4k/core/smb4ksambaoptionsinfo.cpp137
-rw-r--r--smb4k/core/smb4ksambaoptionsinfo.h291
-rw-r--r--smb4k/core/smb4kscanner.cpp1720
-rw-r--r--smb4k/core/smb4kscanner.h485
-rw-r--r--smb4k/core/smb4kscanner_p.cpp96
-rw-r--r--smb4k/core/smb4kscanner_p.h59
-rw-r--r--smb4k/core/smb4ksettings.cpp1092
-rw-r--r--smb4k/core/smb4ksettings.kcfgc6
-rw-r--r--smb4k/core/smb4kshare.cpp216
-rw-r--r--smb4k/core/smb4kshare.h291
-rw-r--r--smb4k/core/smb4ksynchronizationinfo.cpp76
-rw-r--r--smb4k/core/smb4ksynchronizationinfo.h176
-rw-r--r--smb4k/core/smb4ksynchronizer.cpp503
-rw-r--r--smb4k/core/smb4ksynchronizer.h194
-rw-r--r--smb4k/dialogs/Makefile.am11
-rw-r--r--smb4k/dialogs/smb4kbookmarkeditor.cpp258
-rw-r--r--smb4k/dialogs/smb4kbookmarkeditor.h137
-rw-r--r--smb4k/dialogs/smb4kcustomoptionsdialog.cpp1027
-rw-r--r--smb4k/dialogs/smb4kcustomoptionsdialog.h232
-rw-r--r--smb4k/dialogs/smb4kmountdialog.cpp172
-rw-r--r--smb4k/dialogs/smb4kmountdialog.h111
-rw-r--r--smb4k/dialogs/smb4kpreviewdialog.cpp399
-rw-r--r--smb4k/dialogs/smb4kpreviewdialog.h167
-rw-r--r--smb4k/dialogs/smb4kprintdialog.cpp196
-rw-r--r--smb4k/dialogs/smb4kprintdialog.h105
-rw-r--r--smb4k/dialogs/smb4ksynchronizationdialog.cpp239
-rw-r--r--smb4k/dialogs/smb4ksynchronizationdialog.h111
-rw-r--r--smb4k/icons/Makefile.am22
-rw-r--r--smb4k/icons/cr16-app-smb4k.pngbin0 -> 1123 bytes
-rw-r--r--smb4k/icons/cr32-app-smb4k.pngbin0 -> 2863 bytes
-rw-r--r--smb4k/icons/cr48-app-smb4k.pngbin0 -> 5139 bytes
-rw-r--r--smb4k/icons/cr64-app-smb4k.pngbin0 -> 7041 bytes
-rw-r--r--smb4k/iconview/Makefile.am16
-rw-r--r--smb4k/iconview/smb4ksharesiconview.cpp271
-rw-r--r--smb4k/iconview/smb4ksharesiconview.h139
-rw-r--r--smb4k/iconview/smb4ksharesiconview_part.cpp573
-rw-r--r--smb4k/iconview/smb4ksharesiconview_part.h232
-rw-r--r--smb4k/iconview/smb4ksharesiconview_part.rc25
-rw-r--r--smb4k/iconview/smb4ksharesiconviewitem.cpp148
-rw-r--r--smb4k/iconview/smb4ksharesiconviewitem.h173
-rw-r--r--smb4k/iconview/smb4ksharesiconviewtooltip.cpp429
-rw-r--r--smb4k/iconview/smb4ksharesiconviewtooltip.h160
-rw-r--r--smb4k/listview/Makefile.am14
-rw-r--r--smb4k/listview/smb4kshareslistview.cpp275
-rw-r--r--smb4k/listview/smb4kshareslistview.h157
-rw-r--r--smb4k/listview/smb4kshareslistview_part.cpp700
-rw-r--r--smb4k/listview/smb4kshareslistview_part.h234
-rw-r--r--smb4k/listview/smb4kshareslistview_part.rc25
-rw-r--r--smb4k/listview/smb4kshareslistviewitem.cpp353
-rw-r--r--smb4k/listview/smb4kshareslistviewitem.h203
-rw-r--r--smb4k/listview/smb4kshareslistviewtooltip.cpp429
-rw-r--r--smb4k/listview/smb4kshareslistviewtooltip.h160
-rw-r--r--smb4k/main.cpp161
-rw-r--r--smb4k/searchdlg/Makefile.am10
-rw-r--r--smb4k/searchdlg/smb4ksearchdialog.cpp200
-rw-r--r--smb4k/searchdlg/smb4ksearchdialog.h173
-rw-r--r--smb4k/searchdlg/smb4ksearchdialog_part.cpp277
-rw-r--r--smb4k/searchdlg/smb4ksearchdialog_part.h171
-rw-r--r--smb4k/searchdlg/smb4ksearchdialogitem.cpp140
-rw-r--r--smb4k/searchdlg/smb4ksearchdialogitem.h166
-rw-r--r--smb4k/smb4k.cpp1019
-rw-r--r--smb4k/smb4k.desktop81
-rw-r--r--smb4k/smb4k.h229
-rw-r--r--smb4k/smb4k_shell.rc37
-rw-r--r--smb4k/smb4ksystemtray.cpp1079
-rw-r--r--smb4k/smb4ksystemtray.h207
133 files changed, 39954 insertions, 0 deletions
diff --git a/smb4k/Makefile.am b/smb4k/Makefile.am
new file mode 100644
index 0000000..792b035
--- /dev/null
+++ b/smb4k/Makefile.am
@@ -0,0 +1,22 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+SUBDIRS = icons core configdlg dialogs browser iconview listview searchdlg
+
+# Main program
+bin_PROGRAMS = smb4k
+
+smb4k_SOURCES = main.cpp smb4k.cpp smb4ksystemtray.cpp
+smb4k_LDADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(top_builddir)/smb4k/dialogs/libsmb4kdialogs.la $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KFILE) $(LIB_KPARTS) $(LIB_QT)
+smb4k_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+
+KDE_ICON = smb4k
+
+xdg_apps_DATA = smb4k.desktop
+
+rcdir = $(kde_datadir)/smb4k
+rc_DATA = smb4k_shell.rc
+
+noinst_HEADERS = smb4ksystemtray.h
diff --git a/smb4k/browser/Makefile.am b/smb4k/browser/Makefile.am
new file mode 100644
index 0000000..1e0d279
--- /dev/null
+++ b/smb4k/browser/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+kde_module_LTLIBRARIES = libsmb4knetworkbrowser.la
+noinst_HEADERS = smb4knetworkbrowser_part.h smb4knetworkbrowser.h \
+ smb4knetworkbrowseritem.h smb4knetworkbrowsertooltip.h
+libsmb4knetworkbrowser_la_SOURCES = smb4knetworkbrowser_part.cpp \
+ smb4knetworkbrowser.cpp smb4knetworkbrowseritem.cpp \
+ smb4knetworkbrowsertooltip.cpp
+libsmb4knetworkbrowser_la_LIBADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(top_builddir)/smb4k/dialogs/libsmb4kdialogs.la $(LIB_KDECORE) \
+ $(LIB_KDEUI) $(KDE_PLUGIN) $(LIB_KPARTS) $(LIB_QT)
+libsmb4knetworkbrowser_la_LDFLAGS = -module -no-undefined $(all_libraries)
+
+partrcdir = $(kde_datadir)/smb4knetworkbrowserpart
+partrc_DATA = smb4knetworkbrowser_part.rc
diff --git a/smb4k/browser/smb4knetworkbrowser.cpp b/smb4k/browser/smb4knetworkbrowser.cpp
new file mode 100644
index 0000000..67c7b87
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowser.cpp
@@ -0,0 +1,211 @@
+/***************************************************************************
+ smb4knetworkbrowser - The network browser widget of Smb4K.
+ -------------------
+ begin : Mo Jan 8 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qheader.h>
+#include <qtimer.h>
+
+// KDE includes
+#include <klocale.h>
+
+// application specific includes
+#include "smb4knetworkbrowser.h"
+#include "smb4knetworkbrowseritem.h"
+#include "smb4knetworkbrowsertooltip.h"
+#include "../core/smb4ksettings.h"
+
+
+Smb4KNetworkBrowser::Smb4KNetworkBrowser( QWidget *parent, const char *name )
+: KListView( parent, name )
+{
+ setRootIsDecorated( true );
+ setAllColumnsShowFocus( false );
+ setMouseTracking( true );
+
+ m_tooltip = NULL;
+ m_block_tooltip = false;
+
+ addColumn( i18n( "Network" ), -1 );
+ addColumn( i18n( "Type" ), -1 );
+ addColumn( i18n( "IP Address" ), -1 );
+ addColumn( i18n( "Comment" ), -1 );
+
+ // Add some connections:
+ connect( this, SIGNAL( expanded( QListViewItem * ) ),
+ this, SLOT( slotItemExpandedCollapsed( QListViewItem * ) ) );
+
+ connect( this, SIGNAL( collapsed( QListViewItem * ) ),
+ this, SLOT( slotItemExpandedCollapsed( QListViewItem * ) ) );
+
+ connect( this, SIGNAL( executed( QListViewItem * ) ),
+ this, SLOT( slotItemExecuted( QListViewItem * ) ) );
+}
+
+
+Smb4KNetworkBrowser::~Smb4KNetworkBrowser()
+{
+}
+
+
+void Smb4KNetworkBrowser::blockToolTips( bool block )
+{
+ if ( block )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+
+ m_block_tooltip = block;
+}
+
+
+void Smb4KNetworkBrowser::contentsMouseMoveEvent( QMouseEvent *e )
+{
+ // Store the *global* position of the mouse:
+ m_pos = e->globalPos();
+
+ // Find the item over which the user moved the mouse:
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( itemAt( viewport()->mapFromGlobal( m_pos ) ) );
+
+ if ( item )
+ {
+ // Check if we are on the root decoration:
+ bool on_root = true;
+
+ if ( viewport()->mapFromGlobal( m_pos ).x() > header()->sectionPos( header()->mapToIndex( 0 ) ) +
+ treeStepSize() * ( item->depth() + ( rootIsDecorated() ? 1 : 0 ) ) + itemMargin() ||
+ viewport()->mapFromGlobal( m_pos ).x() < header()->sectionPos( header()->mapToIndex( 0 ) ) )
+ {
+ on_root = false;
+ }
+
+ if ( !on_root )
+ {
+ if ( m_tooltip )
+ {
+ if ( m_tooltip->item() != item )
+ {
+ delete m_tooltip;
+
+ if ( !m_block_tooltip && hasMouse() && isExecuteArea( viewport()->mapFromGlobal( m_pos ) ) &&
+ Smb4KSettings::showNetworkItemToolTip() )
+ {
+ m_tooltip = new Smb4KNetworkBrowserToolTip( item );
+
+ QTimer::singleShot( 2000, this, SLOT( slotShowToolTip() ) );
+ }
+ else
+ {
+ m_tooltip = NULL;
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ if ( !m_block_tooltip && hasMouse() && isExecuteArea( viewport()->mapFromGlobal( m_pos ) ) &&
+ Smb4KSettings::showNetworkItemToolTip() )
+ {
+ m_tooltip = new Smb4KNetworkBrowserToolTip( item );
+
+ QTimer::singleShot( 2000, this, SLOT( slotShowToolTip() ) );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ }
+ else
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+ }
+ else
+ {
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+ }
+
+ KListView::contentsMouseMoveEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KNetworkBrowser::slotItemExpandedCollapsed( QListViewItem *item )
+{
+ // Explicitly select the item, because this won't be
+ // done if the user clicked on the root decoration.
+
+ setSelected( item, true );
+}
+
+
+void Smb4KNetworkBrowser::slotItemExecuted( QListViewItem *item )
+{
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+
+ if ( item && item->isExpandable() )
+ {
+ setOpen( item, !item->isOpen() );
+ }
+}
+
+
+void Smb4KNetworkBrowser::slotShowToolTip()
+{
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( itemAt( viewport()->mapFromGlobal( m_pos ) ) );
+
+ if ( !m_block_tooltip && m_tooltip && hasMouse() &&
+ isExecuteArea( viewport()->mapFromGlobal( m_pos ) ) &&
+ Smb4KSettings::showNetworkItemToolTip() &&
+ (m_tooltip->item() == item) )
+ {
+ emit aboutToShowToolTip( item );
+
+ m_tooltip->showTip( m_pos );
+ }
+ else
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+}
+
+#include "smb4knetworkbrowser.moc"
diff --git a/smb4k/browser/smb4knetworkbrowser.h b/smb4k/browser/smb4knetworkbrowser.h
new file mode 100644
index 0000000..ade9e64
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowser.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ smb4knetworkbrowser - The network browser widget of Smb4K.
+ -------------------
+ begin : Mo Jan 8 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KNETWORKBROWSER_H
+#define SMB4KNETWORKBROWSER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <klistview.h>
+
+// forward declarations
+class Smb4KNetworkBrowserItem;
+class Smb4KNetworkBrowserToolTip;
+
+class Smb4KNetworkBrowser : public KListView
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent widget
+ *
+ * @param name The widget name
+ */
+ Smb4KNetworkBrowser( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KNetworkBrowser();
+
+ /**
+ * Enumeration for the columns in the list view.
+ */
+ enum Columns{ Network = 0, Type = 1, IP = 2, Comment = 3 };
+
+ /**
+ * Returns the global position of the mouse with respect
+ * to the viewport.
+ *
+ * @returns the position of the mouse.
+ */
+ const QPoint &mousePosition() { return m_pos; }
+
+ /**
+ * Returns a pointer to the current tool tip or NULL, if there
+ * is no tool tip at the moment. Please note, that the tool tip
+ * is generated 2 sec before it is shown.
+ *
+ * @returns a pointer to the current tool tip.
+ */
+ Smb4KNetworkBrowserToolTip *tooltip() { return m_tooltip; }
+
+ /**
+ * Block the showing of tool tips. If @p block is set to TRUE, the
+ * current tool tip gets deleted (if there is one) and no tool tip
+ * will be shown until @p block is reset to FALSE.
+ *
+ * @param block Set this parameter to TRUE to block the showing
+ * of tool tips.
+ */
+ void blockToolTips( bool block );
+
+ signals:
+ /**
+ * This signal is emitted when the tool tip is about to be shown.
+ *
+ * @param item The item for which the tool tip should be shown.
+ */
+ void aboutToShowToolTip( Smb4KNetworkBrowserItem *item );
+
+ /**
+ * This signal is emitted when the tool tip has been closed.
+ */
+ void closedToolTip();
+
+ protected:
+ /**
+ * Reimplemented from QListView. This slot keeps track of the
+ * mouse position and handles the tool tips.
+ *
+ * @param e The mouse event
+ */
+ void contentsMouseMoveEvent( QMouseEvent *e );
+
+ protected slots:
+ /**
+ * This slot is called whenever a QListViewItem is expanded or
+ * collapsed. At the moment it is only used to select the item.
+ *
+ * @param item The list view item that has been
+ * expanded/collapsed.
+ */
+ void slotItemExpandedCollapsed( QListViewItem *item );
+
+ /**
+ * This slot is called when the user executed an item. It is used
+ * to open the item if it is expandable.
+ *
+ * @param item The item that has been executed.
+ */
+ void slotItemExecuted( QListViewItem *item );
+
+ /**
+ * This slot shows the tool tip.
+ */
+ void slotShowToolTip();
+
+ private:
+ /**
+ * The global position of the mouse with respect to the widget.
+ */
+ QPoint m_pos;
+
+ /**
+ * The tool tip for the network browser
+ */
+ Smb4KNetworkBrowserToolTip *m_tooltip;
+
+ /**
+ * Block tool tips
+ */
+ bool m_block_tooltip;
+};
+
+#endif
diff --git a/smb4k/browser/smb4knetworkbrowser_part.cpp b/smb4k/browser/smb4knetworkbrowser_part.cpp
new file mode 100644
index 0000000..2773872
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowser_part.cpp
@@ -0,0 +1,1929 @@
+/***************************************************************************
+ smb4knetworkbrowser_part - This Part encapsulates the network
+ browser of Smb4K.
+ -------------------
+ begin : Fr Jan 5 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qheader.h>
+
+// KDE includes
+#include <kaboutdata.h>
+#include <kaction.h>
+#include <kshortcut.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kdeversion.h>
+
+// application specific includes
+#include "smb4knetworkbrowser_part.h"
+#include "smb4knetworkbrowser.h"
+#include "smb4knetworkbrowseritem.h"
+#include "smb4knetworkbrowsertooltip.h"
+#include "../dialogs/smb4kcustomoptionsdialog.h"
+#include "../dialogs/smb4kmountdialog.h"
+#include "../dialogs/smb4kprintdialog.h"
+#include "../dialogs/smb4kpreviewdialog.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4knetworkitems.h"
+#include "../core/smb4kshare.h"
+#include "../core/smb4kglobal.h"
+#include "../core/smb4kpasswordhandler.h"
+#include "../core/smb4ksettings.h"
+#include "../core/smb4kbookmark.h"
+#include "../core/smb4kdefs.h"
+
+using namespace Smb4KGlobal;
+
+KInstance *Smb4KNetworkBrowserPartFactory::m_instance = 0L;
+KAboutData *Smb4KNetworkBrowserPartFactory::m_about = 0L;
+
+
+Smb4KNetworkBrowserPart::Smb4KNetworkBrowserPart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name, Mode mode )
+: KParts::Part( parent, name ), m_mode( mode )
+{
+ // First of all we need an instance:
+ setInstance( Smb4KNetworkBrowserPartFactory::instance() );
+
+ // Set the XML file:
+ setXMLFile( "smb4knetworkbrowser_part.rc" );
+
+ // Set the widget of this part:
+ m_widget = new Smb4KNetworkBrowser( parentWidget, widgetName );
+ setWidget( m_widget );
+
+ // Set up the actions.
+ // Do not put this before setWidget() or the shortcuts of the
+ // actions will not be shown.
+ setupActions();
+
+ // Load the settings
+ loadSettings();
+
+ // Add some connections:
+ connect( m_widget, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint & , int ) ),
+ this, SLOT( slotContextMenuRequested( QListViewItem *, const QPoint &, int ) ) );
+
+ connect( m_widget, SIGNAL( selectionChanged( QListViewItem * ) ),
+ this, SLOT( slotSelectionChanged( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( pressed( QListViewItem * ) ),
+ this, SLOT( slotPressed( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( expanded( QListViewItem * ) ),
+ this, SLOT( slotItemExpanded( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( collapsed( QListViewItem * ) ),
+ this, SLOT( slotItemCollapsed( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( executed( QListViewItem * ) ),
+ this, SLOT( slotItemExecuted( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( aboutToShowToolTip( Smb4KNetworkBrowserItem * ) ),
+ this, SLOT( slotAboutToShowToolTip( Smb4KNetworkBrowserItem * ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( workgroups( const QValueList<Smb4KWorkgroupItem *> & ) ),
+ this, SLOT( slotWorkgroups( const QValueList<Smb4KWorkgroupItem *> & ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( members( const QString &, const QValueList<Smb4KHostItem *> & ) ),
+ this, SLOT( slotWorkgroupMembers( const QString &, const QValueList<Smb4KHostItem *> & ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( shares( const QString &, const QValueList<Smb4KShareItem *> & ) ),
+ this, SLOT( slotShares( const QString &, const QValueList<Smb4KShareItem *> & ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( ipAddress( Smb4KHostItem * ) ),
+ this, SLOT( slotAddIPAddress( Smb4KHostItem * ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( info( Smb4KHostItem * ) ),
+ this, SLOT( slotAddInformation( Smb4KHostItem * ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( hostAdded( Smb4KHostItem * ) ),
+ this, SLOT( slotInsertHost( Smb4KHostItem * ) ) );
+
+ connect( Smb4KCore::mounter(), SIGNAL( updated() ),
+ this, SLOT( slotMarkMountedShares() ) );
+
+ connect( Smb4KCore::self(), SIGNAL( runStateChanged() ),
+ this, SLOT( slotRunStateChanged() ) );
+}
+
+
+Smb4KNetworkBrowserPart::~Smb4KNetworkBrowserPart()
+{
+}
+
+
+void Smb4KNetworkBrowserPart::setupActions()
+{
+ KAction *rescan = new KAction( i18n( "Scan Netwo&rk" ), "reload", KShortcut( CTRL+Key_R ),
+ this, SLOT( slotRescan() ),
+ actionCollection(), "rescan_action" );
+ KAction *abort = new KAction( i18n( "&Abort" ) , "stop", KShortcut( CTRL+Key_A ),
+ this, SLOT( slotAbort() ),
+ actionCollection(), "abort_action" );
+ KActionSeparator *sep1 = new KActionSeparator( actionCollection(),
+ "separator_1" );
+ KAction *manual_mount = new KAction( i18n( "M&ount Manually" ), "connect_creating", KShortcut( CTRL+Key_O ),
+ this, SLOT( slotMountManually() ),
+ actionCollection(), "mount_manually_action" );
+ KActionSeparator *sep2 = new KActionSeparator( actionCollection(),
+ "separator_2" );
+ KAction *auth = new KAction( i18n( "Au&thentication" ), "identity", KShortcut( CTRL+Key_T ),
+ this, SLOT( slotAuthentication() ),
+ actionCollection(), "askpass_action" );
+ KAction *custom = new KAction( i18n( "&Custom Options" ), "samba", KShortcut( CTRL+Key_C ),
+ this, SLOT( slotCustomOptions() ),
+ actionCollection(), "custom_action" );
+ KAction *bookmark = new KAction( i18n( "Add &Bookmark" ), "bookmark_add", KShortcut( CTRL+Key_B ),
+ this, SLOT( slotBookmark() ),
+ actionCollection(), "bookmark_action" );
+ KAction *preview = new KAction( i18n( "Pre&view" ), "view_icon", KShortcut( CTRL+Key_V ),
+ this, SLOT( slotPreview() ),
+ actionCollection(), "preview_action" );
+ KAction *print = new KAction( i18n( "&Print File" ), "printer1", KShortcut( CTRL+Key_P ),
+ this, SLOT( slotPrint() ),
+ actionCollection(), "print_action" );
+ KAction *mount = new KAction( i18n( "&Mount" ), "hdd_mount", KShortcut( CTRL+Key_M ),
+ this, SLOT( slotMount() ),
+ actionCollection(), "mount_action" );
+
+ // Enable/disable the actions:
+ rescan->setEnabled( true );
+ abort->setEnabled( false );
+ manual_mount->setEnabled( true );
+ auth->setEnabled( false );
+ custom->setEnabled( false );
+ bookmark->setEnabled( false );
+ preview->setEnabled( false );
+ print->setEnabled( false );
+ mount->setEnabled( false );
+
+ // Plug the actions into the action menu:
+ m_menu = new KActionMenu( this, "NetworkActionMenu" );
+ m_menu->popupMenu()->insertTitle( SmallIcon( "network" ), i18n( "Network" ), 0 );
+ m_menu->insert( rescan, 1 );
+ m_menu->insert( abort, 2 );
+ m_menu->insert( sep1, 3 );
+ m_menu->insert( manual_mount, 4 );
+ m_menu->insert( sep2, 5 );
+ m_menu->insert( auth, 6 );
+ m_menu->insert( custom, 7 );
+ m_menu->insert( bookmark, 8 );
+ m_menu->insert( preview, 9 );
+ m_menu->insert( print, 10 );
+ m_menu->insert( mount, 11 );
+
+ // If we are in Konqueror plugin mode, an unmount action
+ // is also needed:
+ if ( m_mode == KonqPlugin )
+ {
+ KAction *unmount = new KAction( i18n( "&Unmount" ), "hdd_unmount", KShortcut( CTRL+Key_U ),
+ this, SLOT( slotUnmount() ),
+ actionCollection(), "konq_umount_action" );
+
+ unmount->setEnabled( false );
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::loadSettings()
+{
+ // Show/hide columns:
+ if ( Smb4KSettings::showIPAddress() )
+ {
+ m_widget->setColumnWidth( Smb4KNetworkBrowser::IP, 10 );
+ m_widget->setColumnWidthMode( Smb4KNetworkBrowser::IP, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KNetworkBrowser::IP );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KNetworkBrowser::IP, 0 );
+ m_widget->setColumnWidthMode( Smb4KNetworkBrowser::IP, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KNetworkBrowser::IP );
+ }
+
+ if ( Smb4KSettings::showType() )
+ {
+ m_widget->setColumnWidth( Smb4KNetworkBrowser::Type, 10 );
+ m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Type, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KNetworkBrowser::Type );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KNetworkBrowser::Type, 0 );
+ m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Type, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KNetworkBrowser::Type );
+ }
+
+ if ( Smb4KSettings::showComment() )
+ {
+ m_widget->setColumnWidth( Smb4KNetworkBrowser::Comment, 10 );
+ m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Comment, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KNetworkBrowser::Comment );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KNetworkBrowser::Comment, 0 );
+ m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Comment, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KNetworkBrowser::Comment );
+ }
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+
+ // The rest of the settings will be applied on the fly.
+}
+
+
+void Smb4KNetworkBrowserPart::customEvent( QCustomEvent *e )
+{
+ switch ( e->type() )
+ {
+ case EVENT_LOAD_SETTINGS:
+ {
+ loadSettings();
+
+ break;
+ }
+ case EVENT_SET_FOCUS:
+ {
+ KListView *view = static_cast<KListView *>( m_widget );
+
+ if ( view->childCount() != 0 )
+ {
+ view->setSelected( !view->currentItem() ?
+ view->firstChild() :
+ view->currentItem(), true );
+ }
+
+ view->setFocus();
+
+ break;
+ }
+ case EVENT_SCAN_NETWORK:
+ {
+ slotRescan();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ KParts::Part::customEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS (Smb4KNetworkBrowserPart)
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KNetworkBrowserPart::slotContextMenuRequested( QListViewItem *item, const QPoint &pos,
+ int /* column */ )
+{
+ m_widget->blockToolTips( true );
+
+ if ( !item )
+ {
+ m_menu->popupMenu()->changeTitle( 0, SmallIcon( "network" ), i18n( "Network" ) );
+ }
+ else
+ {
+ m_menu->popupMenu()->changeTitle( 0, *(item->pixmap( 0 )), item->text( 0 ) );
+ }
+
+ m_menu->popupMenu()->exec( pos, 0 );
+
+ m_widget->blockToolTips( false );
+}
+
+
+void Smb4KNetworkBrowserPart::slotSelectionChanged( QListViewItem *item )
+{
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ if ( browser_item )
+ {
+ switch ( m_mode )
+ {
+ case Normal:
+ {
+ if ( browser_item->type() == Smb4KNetworkBrowserItem::Share )
+ {
+ // Change the text of the rescan action:
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Compute&r" ) );
+
+ // Enable/disable the actions:
+ actionCollection()->action( "askpass_action" )->setEnabled( true );
+
+ if ( !browser_item->isPrinter() )
+ {
+ actionCollection()->action( "bookmark_action" )->setEnabled( true );
+ actionCollection()->action( "preview_action" )->setEnabled( true );
+ actionCollection()->action( "mount_action" )->setEnabled( true );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( true );
+ }
+ else
+ {
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( true );
+ actionCollection()->action( "custom_action" )->setEnabled( false );
+ }
+ }
+ else if ( browser_item->type() == Smb4KNetworkBrowserItem::Host )
+ {
+ // Change the text of the rescan action:
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Compute&r" ) );
+
+ // Enable/disable the actions:
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "askpass_action" )->setEnabled( true );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( true );
+ }
+ else
+ {
+ // Change the text of the rescan action:
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Wo&rkgroup" ) );
+
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "askpass_action" )->setEnabled( false );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( false );
+ }
+
+ break;
+ }
+ case KonqPlugin:
+ {
+ if ( browser_item->type() == Smb4KNetworkBrowserItem::Share )
+ {
+ // Change the text of the rescan action:
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Compute&r" ) );
+
+ // Enable/disable the actions:
+ actionCollection()->action( "askpass_action" )->setEnabled( true );
+
+ if ( !browser_item->isPrinter() )
+ {
+ actionCollection()->action( "bookmark_action" )->setEnabled( true );
+ actionCollection()->action( "preview_action" )->setEnabled( true );
+ actionCollection()->action( "mount_action" )->setEnabled( true );
+ actionCollection()->action( "konq_umount_action" )->setEnabled( true );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( true );
+
+ if ( !browser_item->isMounted() )
+ {
+ if ( actionCollection()->action( "konq_umount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "konq_umount_action" ) );
+ m_menu->insert( actionCollection()->action( "mount_action" ), 11 );
+ }
+ else
+ {
+ // Nothing to do
+ }
+ }
+ else
+ {
+ if ( actionCollection()->action( "mount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "mount_action" ) );
+ m_menu->insert( actionCollection()->action( "konq_umount_action" ), 11 );
+ }
+ else
+ {
+ // Nothing to do
+ }
+ }
+ }
+ else
+ {
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "konq_umount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( true );
+ actionCollection()->action( "custom_action" )->setEnabled( false );
+
+ if ( actionCollection()->action( "konq_umount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "konq_umount_action" ) );
+ m_menu->insert( actionCollection()->action( "mount_action" ), 11 );
+ }
+ else
+ {
+ // Nothing to do
+ }
+ }
+ }
+ else if ( browser_item->type() == Smb4KNetworkBrowserItem::Host )
+ {
+ // Change the text of the rescan action:
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Compute&r" ) );
+
+ // Enable/disable the actions:
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "askpass_action" )->setEnabled( true );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "konq_umount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( true );
+
+ if ( actionCollection()->action( "konq_umount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "konq_umount_action" ) );
+ m_menu->insert( actionCollection()->action( "mount_action" ), 11 );
+ }
+ else
+ {
+ // Nothing to do
+ }
+ }
+ else
+ {
+ // Change the text of the rescan action:
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Wo&rkgroup" ) );
+
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "askpass_action" )->setEnabled( false );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "konq_umount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( false );
+
+ if ( actionCollection()->action( "konq_umount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "konq_umount_action" ) );
+ m_menu->insert( actionCollection()->action( "mount_action" ), 11 );
+ }
+ else
+ {
+ // Nothing to do
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ // See Smb4KNetworkBrowserPart::slotPressed()
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotPressed( QListViewItem *item )
+{
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ switch ( m_mode )
+ {
+ case Normal:
+ {
+ if ( !browser_item && !m_widget->selectedItem() )
+ {
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Netwo&rk" ) );
+
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "askpass_action" )->setEnabled( false );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( false );
+ }
+ else
+ {
+ // See Smb4KNetworkBrowserPart::slotSelectionChanged()
+ }
+
+ break;
+ }
+ case KonqPlugin:
+ {
+ if ( !browser_item && !m_widget->selectedItem() )
+ {
+ actionCollection()->action( "rescan_action" )->setText( i18n( "Scan Netwo&rk" ) );
+
+ actionCollection()->action( "bookmark_action" )->setEnabled( false );
+ actionCollection()->action( "askpass_action" )->setEnabled( false );
+ actionCollection()->action( "preview_action" )->setEnabled( false );
+ actionCollection()->action( "mount_action" )->setEnabled( false );
+ actionCollection()->action( "konq_umount_action" )->setEnabled( false );
+ actionCollection()->action( "print_action" )->setEnabled( false );
+ actionCollection()->action( "custom_action" )->setEnabled( false );
+
+ if ( actionCollection()->action( "konq_umount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "konq_umount_action" ) );
+ m_menu->insert( actionCollection()->action( "mount_action" ), 11 );
+ }
+ else
+ {
+ // Nothing to do
+ }
+ }
+ else
+ {
+ // See Smb4KNetworkBrowserPart::slotSelectionChanged()
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotItemExpanded( QListViewItem *item )
+{
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ if ( browser_item )
+ {
+ switch ( browser_item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Workgroup:
+ {
+ Smb4KWorkgroupItem *i = browser_item->workgroupItem();
+ Smb4KCore::scanner()->getWorkgroupMembers( i->name(), i->master(), i->masterIP() );
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ Smb4KHostItem *i = browser_item->hostItem();
+ Smb4KCore::scanner()->getShares( i->workgroup(), i->name(), i->ip() );
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotItemCollapsed( QListViewItem *item )
+{
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ // Remove all children if we have a host item, because we
+ // do not want shares already displayed before the user provided
+ // the login data.
+ if ( browser_item && browser_item->type() == Smb4KNetworkBrowserItem::Host )
+ {
+ while ( browser_item->childCount() != 0 )
+ {
+ delete browser_item->firstChild();
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotItemExecuted( QListViewItem *item )
+{
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ if ( browser_item && browser_item->type() == Smb4KNetworkBrowserItem::Share )
+ {
+ if ( !browser_item->isPrinter() )
+ {
+ slotMount();
+ }
+ else
+ {
+ slotPrint();
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotAboutToShowToolTip( Smb4KNetworkBrowserItem *browser_item )
+{
+ if ( browser_item )
+ {
+ switch ( browser_item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Workgroup:
+ {
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ // Check if additional information is needed and send a request to the scanner,
+ // if necessary.
+ if ( !browser_item->hostItem()->infoChecked() )
+ {
+ Smb4KCore::scanner()->getInfo( browser_item->hostItem()->workgroup(),
+ browser_item->hostItem()->name(),
+ browser_item->hostItem()->ip() );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Do nothing --- BTW: Will this case occur at all?
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotWorkgroups( const QValueList<Smb4KWorkgroupItem *> &list )
+{
+ if ( !list.isEmpty() )
+ {
+ // Check if the workgroups in the list view are still
+ // valid. Remove obsolete ones and add new ones.
+
+ if ( m_widget->childCount() > 0 )
+ {
+ QListViewItemIterator it( m_widget );
+
+ while ( it.current() )
+ {
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( it.current() );
+
+ // We only want to check workgroup items:
+ if ( item->type() == Smb4KNetworkBrowserItem::Workgroup )
+ {
+ QValueList<Smb4KWorkgroupItem *>::ConstIterator i;
+
+ for ( i = list.begin(); i != list.end(); ++i )
+ {
+ if ( QString::compare( item->workgroupItem()->name(), (*i)->name() ) == 0 )
+ {
+ QString old_master = item->workgroupItem()->master();
+
+ // Found the workgroup item in the new list. Update it and stop here.
+ item->update( *i );
+
+ // We update the master as well, if it changed and the workgroup item is open.
+ // In the case the item is closed, Smb4KScanner::getWorkgroupMembers() will be
+ // called by setOpen() and an update will be done by slotWorkgroupMembers().
+ if ( QString::compare( old_master, (*i)->master() ) != 0 && item->isOpen() )
+ {
+ // Get the list view items:
+ Smb4KNetworkBrowserItem *oldMasterItem = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( old_master, Smb4KNetworkBrowser::Network, CaseSensitive|ExactMatch ) );
+ Smb4KNetworkBrowserItem *newMasterItem = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( (*i)->master(), Smb4KNetworkBrowser::Network, CaseSensitive|ExactMatch ) );
+
+ // Get the host item of the new master from the scanner. The old master
+ // has been removed from the internal host list, so we cannot search for
+ // it!
+ Smb4KHostItem *newMaster = Smb4KCore::scanner()->getHost( (*i)->master(), (*i)->name() );
+
+ if ( oldMasterItem )
+ {
+ // The old master item is still present, so update and tell it
+ // that it is no master anymore.
+ // NOTE: We cannot decide here whether the old master has
+ // to be removed because it vanished from the network. This
+ // has to be done by slotWorkgroupMembers()!
+ oldMasterItem->hostItem()->setMaster( false );
+ }
+ else
+ {
+ // Huh? It vanished...?
+ }
+
+ if ( newMasterItem )
+ {
+ // Tell the list view item that it is the new master.
+ // Note: Do not use Smb4KNetworkBrowserItem::update() here,
+ // because this will remove the comment and maybe also the
+ // IP address (depending on the lookup method the user chose).
+ // The update will be done by insertWorkgroupMembers().
+ newMasterItem->hostItem()->setMaster( true );
+ }
+ else
+ {
+ // We do not need to check if newMaster is NULL, because it won't be.
+ Smb4KNetworkBrowserItem *master = new Smb4KNetworkBrowserItem( item, newMaster );
+ master->setExpandable( true );
+ }
+ }
+
+ break;
+ }
+ else
+ {
+ // Is the list entry in the list view? If not, add it to the list
+ // view. (If it is, it will be found and updated by the code above.)
+ if ( m_widget->findItem( (*i)->name(), Smb4KNetworkBrowser::Network, CaseSensitive|ExactMatch ) == 0 )
+ {
+ Smb4KNetworkBrowserItem *workgroup = new Smb4KNetworkBrowserItem( m_widget, *i );
+ workgroup->setExpandable( true );
+ }
+
+ continue;
+ }
+ }
+
+ // The workgroup has vanished. Delete it from
+ // the list view:
+ if ( i == list.end() )
+ {
+ delete item;
+ }
+ }
+
+ ++it;
+ }
+ }
+ else
+ {
+ // Put the items in the empty list view:
+ for ( QValueList<Smb4KWorkgroupItem *>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ Smb4KNetworkBrowserItem *workgroup = new Smb4KNetworkBrowserItem( m_widget, *it );
+ workgroup->setExpandable( true );
+ }
+ }
+ }
+ else
+ {
+ // Nothing was found: Clear the list view and
+ // adjust the columns:
+ m_widget->clear();
+ }
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotWorkgroupMembers( const QString &workgroup, const QValueList<Smb4KHostItem *> &list )
+{
+ // Get the workgroup item:
+ Smb4KNetworkBrowserItem *workgroupItem = NULL;
+
+ if ( !workgroup.isEmpty() )
+ {
+ workgroupItem = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( workgroup, Smb4KNetworkBrowser::Network, ExactMatch|CaseSensitive ) );
+ }
+ else
+ {
+ return;
+ }
+
+ if ( workgroupItem )
+ {
+ if ( !list.isEmpty() )
+ {
+ // Check if the host items are still valid. Update
+ // them if they are and remove them if they are not:
+ if ( workgroupItem->childCount() > 0 )
+ {
+ // Traverse though the hosts:
+ QListViewItemIterator it( m_widget );
+
+ while ( it.current() )
+ {
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( it.current() );
+
+ // We will only take action if we have a host item that belongs
+ // to the workgroup 'workgroup':
+ if ( item->type() == Smb4KNetworkBrowserItem::Host &&
+ QString::compare( item->hostItem()->workgroup(), workgroupItem->workgroupItem()->name() ) == 0 )
+ {
+ QValueList<Smb4KHostItem *>::ConstIterator i;
+
+ for ( i = list.begin(); i != list.end(); ++i )
+ {
+ if ( QString::compare( item->hostItem()->name(), (*i)->name() ) == 0 )
+ {
+ // The host is already in the workgroup. Update it:
+ item->update( *i );
+
+ break;
+ }
+ else
+ {
+ // Is the list entry in the workgroup? If not, add it to it.
+ // (If it is, it will be found and updated by the code above.)
+ // Also: In case the whole list of known hosts is emitted by the
+ // scanner, we need omit all entries that do not belong to this
+ // workgroup.
+ if ( QString::compare( (*i)->workgroup(), workgroupItem->workgroupItem()->name() ) == 0 &&
+ m_widget->findItem( (*i)->name(), Smb4KNetworkBrowser::Network, CaseSensitive|ExactMatch ) == 0 )
+ {
+ Smb4KNetworkBrowserItem *hostItem = new Smb4KNetworkBrowserItem( workgroupItem, *i );
+ hostItem->setExpandable( true );
+ }
+
+ continue;
+ }
+ }
+
+ // The host has vanished. Delete it from the
+ // workgroup:
+ if ( i == list.end() )
+ {
+ delete item;
+ }
+ }
+
+ ++it;
+ }
+ }
+ else
+ {
+ // Add the children to the childless host item:
+ for ( QValueList<Smb4KHostItem *>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ // In case the whole list of known hosts is emitted by the scanner,
+ // we need omit all entries that do not belong to this workgroup.
+ if ( QString::compare( (*it)->workgroup(), workgroupItem->workgroupItem()->name() ) == 0 )
+ {
+ Smb4KNetworkBrowserItem *hostItem = new Smb4KNetworkBrowserItem( workgroupItem, *it );
+ hostItem->setExpandable( true );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Close the item:
+ m_widget->setOpen( workgroupItem, false );
+
+ // Delete all host items in this workgroup:
+ QListViewItem *child = workgroupItem->firstChild();
+
+ while ( child )
+ {
+ delete child;
+ child = workgroupItem->firstChild();
+ }
+ }
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+ }
+ else
+ {
+ // The workgroup item could not be found. So, do nothing.
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotShares( const QString &host, const QValueList<Smb4KShareItem *> &list )
+{
+ // Get the host item:
+ Smb4KNetworkBrowserItem *hostItem = NULL;
+
+ if ( !host.isEmpty() )
+ {
+ hostItem = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( host, Smb4KNetworkBrowser::Network, ExactMatch|CaseSensitive ) );
+ }
+ else
+ {
+ return;
+ }
+
+ if ( hostItem )
+ {
+ if ( !list.isEmpty() )
+ {
+ // Expand the host item, if it is collapsed:
+ if ( !hostItem->isOpen() )
+ {
+ m_widget->setOpen( hostItem, true );
+ }
+
+ if ( hostItem->childCount() > 0 )
+ {
+ QListViewItemIterator it( m_widget );
+
+ while( it.current() )
+ {
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( it.current() );
+
+ // We only take action, if the shares belong to hostItem:
+ if ( item->type() == Smb4KNetworkBrowserItem::Share &&
+ QString::compare( item->shareItem()->host(), hostItem->hostItem()->name() ) == 0 )
+ {
+ QValueList<Smb4KShareItem *>::ConstIterator i;
+
+ for ( i = list.begin(); i != list.end(); ++i )
+ {
+ if ( QString::compare( item->shareItem()->name(), (*i)->name() ) == 0 )
+ {
+ // Found the share. Now process it:
+ if ( !item->shareItem()->isHidden() )
+ {
+ if ( !item->shareItem()->isPrinter() )
+ {
+ // There are no restrictions for this kind of
+ // share. Update it.
+ item->update( *i );
+ }
+ else
+ {
+ // Does the user want to see printer shares
+ // or not? If not, delete the entry.
+ if ( !Smb4KSettings::showPrinterShares() )
+ {
+ delete item;
+ }
+ else
+ {
+ item->update( *i );
+ }
+ }
+ }
+ else
+ {
+ // Delete or update the item depending on the
+ // settings the user chose:
+ if ( !Smb4KSettings::showHiddenShares() )
+ {
+ delete item;
+ }
+ else
+ {
+ // Can we have hidden printers?
+ if ( item->shareItem()->isPrinter() )
+ {
+ if ( !Smb4KSettings::showPrinterShares() )
+ {
+ delete item;
+ }
+ else
+ {
+ item->update( *i );
+ }
+
+ break;
+ }
+
+ if ( item->shareItem()->isIPC() )
+ {
+ if ( !Smb4KSettings::showHiddenIPCShares() )
+ {
+ delete item;
+ }
+ else
+ {
+ item->update( *i );
+ }
+
+ break;
+ }
+
+ if ( item->shareItem()->isADMIN() )
+ {
+ if ( !Smb4KSettings::showHiddenADMINShares() )
+ {
+ delete item;
+ }
+ else
+ {
+ item->update( *i );
+ }
+
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ else
+ {
+ // Does the host carry the list entry? If not, add it to it.
+ // (If it is, it will be found and updated by the code above.)
+ if ( m_widget->findItem( (*i)->name(), Smb4KNetworkBrowser::Network, CaseSensitive|ExactMatch ) == 0 )
+ {
+ // Respect the settings the user chose to use:
+ if ( !(*i)->isHidden() )
+ {
+ if ( !(*i)->isPrinter() || (Smb4KSettings::showPrinterShares() && (*i)->isPrinter()) )
+ {
+ (void) new Smb4KNetworkBrowserItem( hostItem, *i );
+ }
+ else
+ {
+ // This share won't make it into the list view.
+ }
+
+ continue;
+ }
+ else
+ {
+ if ( Smb4KSettings::showHiddenShares() )
+ {
+ if ( !(*i)->isIPC() && !(*i)->isADMIN() && !(*i)->isPrinter() )
+ {
+ // The share is no IPC$ and no ADMIN$ share. Include it.
+ (void) new Smb4KNetworkBrowserItem( hostItem, *i );
+
+ continue;
+ }
+ else
+ {
+ if ( (Smb4KSettings::showHiddenIPCShares() && (*i)->isIPC()) ||
+ (Smb4KSettings::showHiddenADMINShares() && (*i)->isADMIN()) ||
+ (Smb4KSettings::showPrinterShares() && (*i)->isPrinter()) )
+ {
+ // We are allowed to put the IPC$/ADMIN$ share in:
+ (void) new Smb4KNetworkBrowserItem( hostItem, *i );
+
+ continue;
+ }
+ else
+ {
+ // The user does not want to see this item.
+
+ continue;
+ }
+ }
+ }
+ else
+ {
+ // This item won't be included.
+
+ continue;
+ }
+ }
+ }
+
+ continue;
+ }
+ }
+
+ // The share has vanished. Delete it from the
+ // host item:
+ if ( i == list.end() )
+ {
+ delete item;
+ }
+ }
+
+ ++it;
+ }
+ }
+ else
+ {
+ // Add the children to the childless host item:
+ for ( QValueList<Smb4KShareItem *>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ // Respect the settings the user chose to use:
+ if ( !(*it)->isHidden() )
+ {
+ if ( !(*it)->isPrinter() || (Smb4KSettings::showPrinterShares() && (*it)->isPrinter()) )
+ {
+ (void) new Smb4KNetworkBrowserItem( hostItem, *it );
+ }
+ else
+ {
+ // This share won't make it into the list view.
+ }
+
+ continue;
+ }
+ else
+ {
+ if ( Smb4KSettings::showHiddenShares() )
+ {
+ if ( !(*it)->isIPC() && !(*it)->isADMIN() && !(*it)->isPrinter() )
+ {
+ // The share is no IPC$ and no ADMIN$ share. Include it.
+ (void) new Smb4KNetworkBrowserItem( hostItem, *it );
+
+ continue;
+ }
+ else
+ {
+ if ( (Smb4KSettings::showHiddenIPCShares() && (*it)->isIPC()) ||
+ (Smb4KSettings::showHiddenADMINShares() && (*it)->isADMIN()) ||
+ (Smb4KSettings::showPrinterShares() && (*it)->isPrinter()) )
+ {
+ // We are allowed to put the IPC$/ADMIN$ share in:
+ (void) new Smb4KNetworkBrowserItem( hostItem, *it );
+
+ continue;
+ }
+ else
+ {
+ // The user does not want to see this item.
+
+ continue;
+ }
+ }
+ }
+ else
+ {
+ // This item won't be included.
+
+ continue;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Delete all shares of this host:
+ m_widget->setOpen( hostItem, false );
+
+ QListViewItem *child = hostItem->firstChild();
+
+ while ( child )
+ {
+ delete child;
+ child = hostItem->firstChild();
+ }
+ }
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+ }
+ else
+ {
+ // The host item could not be found. So, do nothing.
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotAddIPAddress( Smb4KHostItem *item )
+{
+ if ( item )
+ {
+ // Get the workgroup item the server is a child of and update
+ // it.
+ Smb4KNetworkBrowserItem *workgroup_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( item->workgroup(), Smb4KNetworkBrowser::Network, ExactMatch|CaseSensitive ) );
+
+ if ( workgroup_item && QString::compare( workgroup_item->workgroupItem()->name(), item->workgroup() ) == 0 )
+ {
+ Smb4KWorkgroupItem *workgroup = Smb4KCore::scanner()->getWorkgroup( item->workgroup() );
+
+ if ( workgroup )
+ {
+ workgroup_item->update( workgroup );
+
+ if ( m_widget->tooltip() && m_widget->tooltip()->isShown() &&
+ m_widget->tooltip()->item() == workgroup_item )
+ {
+ m_widget->tooltip()->update();
+ }
+ }
+ }
+
+ Smb4KNetworkBrowserItem *host_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( item->name(), Smb4KNetworkBrowser::Network, ExactMatch|CaseSensitive ) );
+
+ if ( host_item && host_item->parent() && QString::compare( host_item->hostItem()->workgroup(), item->workgroup() ) == 0 )
+ {
+ host_item->update( item );
+
+ if ( m_widget->tooltip() && m_widget->tooltip()->isShown() &&
+ m_widget->tooltip()->item() == host_item )
+ {
+ m_widget->tooltip()->update();
+ }
+
+ if ( m_widget->columnWidth( Smb4KNetworkBrowser::IP ) != 0 )
+ {
+ m_widget->adjustColumn( Smb4KNetworkBrowser::IP );
+ }
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotAddInformation( Smb4KHostItem *item )
+{
+ if ( item )
+ {
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( item->name(), Smb4KNetworkBrowser::Network, ExactMatch|CaseSensitive ) );
+
+ if ( browser_item )
+ {
+ // First update the browser item, if appropriate:
+ if ( QString::compare( browser_item->hostItem()->workgroup(), item->workgroup() ) == 0 )
+ {
+ browser_item->update( item );
+ }
+
+ // Now update the tool tip in case it is shown:
+ if ( m_widget->tooltip() && m_widget->tooltip()->isShown() &&
+ m_widget->tooltip()->item() == browser_item )
+ {
+ m_widget->tooltip()->update();
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotInsertHost( Smb4KHostItem *item )
+{
+ Smb4KNetworkBrowserItem *workgroup_item = NULL;
+
+ // Stop here, if we received a NULL pointer.
+ if ( item )
+ {
+ // Look up the workgroup:
+ workgroup_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->findItem( item->workgroup(),
+ Smb4KNetworkBrowser::Network, ExactMatch|CaseSensitive ) );
+ }
+ else
+ {
+ return;
+ }
+
+ if ( workgroup_item )
+ {
+ // Check if the host item is already there. We traverse
+ // workgroup's children for that:
+ Smb4KNetworkBrowserItem *host_item = static_cast<Smb4KNetworkBrowserItem *>( workgroup_item->firstChild() );
+
+ while ( host_item )
+ {
+ if ( QString::compare( host_item->text( Smb4KNetworkBrowser::Network ).upper(),
+ item->name().upper() ) == 0 )
+ {
+ break;
+ }
+
+ host_item = static_cast<Smb4KNetworkBrowserItem *>( host_item->nextSibling() );
+ }
+
+
+ if ( !host_item || (host_item && host_item->parent() &&
+ QString::compare( host_item->hostItem()->workgroup(), item->workgroup() ) != 0) )
+ {
+ // The host is not there. Insert it.
+ // NOTE: The following procedure will not produce a leak.
+ host_item = new Smb4KNetworkBrowserItem( workgroup_item, item );
+ host_item->setExpandable( true );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ // No item has been found that matches the workgroup name.
+ // Add a workgroup item and make the host a child of it.
+ // Since Smb4KScanner::insertHost() adds also a workgroup
+ // item, we get the workgroup from the scanner:
+ Smb4KWorkgroupItem *workgroup = Smb4KCore::scanner()->getWorkgroup( item->workgroup() );
+
+ if ( workgroup )
+ {
+ workgroup_item = new Smb4KNetworkBrowserItem( m_widget, workgroup );
+ workgroup_item->setExpandable( true );
+
+ Smb4KNetworkBrowserItem *host_item = new Smb4KNetworkBrowserItem( workgroup_item, item );
+ host_item->setExpandable( true );
+ }
+ else
+ {
+ // In this case we have the information we need, but the
+ // scanner does not know the workgroup. Complain about this
+ // and do nothing else:
+ kdError() << "Smb4KNetworkBrowserPart::slotInsertHost(): No workgroup found" << endl;
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotRescan()
+{
+ bool viewport_has_mouse;
+
+ // We transform the global mouse position to a local position:
+ QPoint pos = m_widget->mapFromGlobal( m_widget->mousePosition() );
+
+ if ( pos.x() <= 0 || m_widget->viewport()->width() <= pos.x() ||
+ pos.y() <= 0 || m_widget->viewport()->height() <= pos.y() )
+ {
+ viewport_has_mouse = false;
+ }
+ else
+ {
+ viewport_has_mouse = true;
+ }
+
+ if ( m_widget->currentItem() && m_widget->selectedItem() && viewport_has_mouse )
+ {
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( !m_widget->currentItem()->isOpen() && m_widget->currentItem()->isExpandable() )
+ {
+ // When opening the expandable item, slotItemExpanded() will be invoked
+ // automatically. It carries code that will activate the scan of the
+ // network.
+ m_widget->setOpen( browser_item, true );
+ }
+ else
+ {
+ // If the item is already open or if the user activated the action for
+ // a share item, we need to "manually" invoke the scanner here.
+ // NOTE: We do not use slotItemExpanded(), because that only works for
+ // workgroups and hosts:
+ switch ( browser_item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Workgroup:
+ {
+ Smb4KWorkgroupItem *item = browser_item->workgroupItem();
+ Smb4KCore::scanner()->getWorkgroupMembers( item->name(), item->master(), item->masterIP() );
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ Smb4KHostItem *item = browser_item->hostItem();
+ Smb4KCore::scanner()->getShares( item->workgroup(), item->name(), item->ip() );
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ Smb4KHostItem *item = static_cast<Smb4KNetworkBrowserItem *>( browser_item->parent() )->hostItem();
+ Smb4KCore::scanner()->getShares( item->workgroup(), item->name(), item->ip() );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // FIXME: Do we want to clear the list view here?
+
+ Smb4KCore::scanner()->rescan();
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotAbort()
+{
+ if ( Smb4KCore::scannerIsRunning() &&
+ Smb4KCore::scannerState() != SCANNER_SEARCHING )
+ {
+ Smb4KCore::scanner()->abort();
+ }
+
+ if ( Smb4KCore::mounterIsRunning() &&
+ Smb4KCore::mounterState() != MOUNTER_UNMOUNTING )
+ {
+ Smb4KCore::mounter()->abort();
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotMountManually()
+{
+ Smb4KMountDialog *dlg = static_cast<Smb4KMountDialog *>( m_widget->child( "MountDialog", "Smb4KMountDialog", true ) );
+
+ if ( !dlg )
+ {
+ dlg = new Smb4KMountDialog( m_widget, "MountDialog" );
+ }
+
+ // The dialog will be closed destructively.
+ if ( !dlg->isShown() )
+ {
+ dlg->exec();
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotAuthentication()
+{
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( item )
+ {
+ switch ( item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ passwordHandler()->askpass( item->hostItem()->workgroup(),
+ item->hostItem()->name(),
+ QString::null,
+ Smb4KPasswordHandler::NewData,
+ m_widget,
+ "AuthenticationDialog" );
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ passwordHandler()->askpass( item->shareItem()->workgroup(),
+ item->shareItem()->host(),
+ item->shareItem()->name(),
+ Smb4KPasswordHandler::NewData,
+ m_widget,
+ "AuthenticationDialog" );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotCustomOptions()
+{
+ Smb4KCustomOptionsDialog *dlg = static_cast<Smb4KCustomOptionsDialog *>(
+ m_widget->child( "CustomOptionsDialog", "Smb4KCustomOptionsDialog", true ) );
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( !dlg && item )
+ {
+ switch ( item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ dlg = new Smb4KCustomOptionsDialog( item->hostItem(), m_widget, "CustomOptionsDialog" );
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ dlg = new Smb4KCustomOptionsDialog( item->shareItem(), m_widget, "CustomOptionsDialog" );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ if ( dlg && !dlg->isShown() )
+ {
+ if ( dlg->isInitialized() )
+ {
+ dlg->exec();
+ }
+ else
+ {
+ delete dlg;
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotBookmark()
+{
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( item && item->type() == Smb4KNetworkBrowserItem::Share )
+ {
+ Smb4KNetworkBrowserItem *parent_item = static_cast<Smb4KNetworkBrowserItem *>( item->parent() );
+
+ // Add a bookmark. The alternative label can be set in the bookmark editor,
+ // so we won't do anything about it here.
+ Smb4KCore::bookmarkHandler()->addBookmark( new Smb4KBookmark( item->shareItem(), parent_item->hostItem()->ip() ) );
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotPreview()
+{
+ // The user should be able to open several dialogs at a time, so
+ // do not check for existing dialogs and use show() here.
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+ Smb4KPreviewDialog *dlg = NULL;
+
+ if ( item && item->type() == Smb4KNetworkBrowserItem::Share &&
+ !item->shareItem()->isPrinter() )
+ {
+ dlg = new Smb4KPreviewDialog( item->shareItem(), m_widget, "PreviewDialog" );
+ }
+
+ if ( dlg && !dlg->isShown() )
+ {
+ if ( dlg->isInitialized() )
+ {
+ dlg->show();
+ }
+ else
+ {
+ delete dlg;
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotPrint()
+{
+ Smb4KPrintDialog *dlg = static_cast<Smb4KPrintDialog *>( m_widget->child( "PrintDialog", "Smb4KPrintDialog", true ) );
+ Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( !dlg && item )
+ {
+ switch( item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ if ( item->shareItem()->isPrinter() )
+ {
+ dlg = new Smb4KPrintDialog( item->shareItem(), m_widget, "PrintDialog" );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ if ( dlg && !dlg->isShown() )
+ {
+ dlg->exec();
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotMount()
+{
+ // Get the current item:
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( browser_item && browser_item->type() == Smb4KNetworkBrowserItem::Share )
+ {
+ // If the item is a share item, get its parent and start mounting it:
+ Smb4KNetworkBrowserItem *parent_browser_item = static_cast<Smb4KNetworkBrowserItem *>( browser_item->parent() );
+
+ Smb4KCore::mounter()->mountShare( browser_item->shareItem()->workgroup(),
+ browser_item->shareItem()->host(),
+ parent_browser_item->hostItem()->ip() /* There is no better way ATM */,
+ browser_item->shareItem()->name() );
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotUnmount()
+{
+ if ( m_mode == KonqPlugin )
+ {
+ // Get the current item:
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( m_widget->currentItem() );
+
+ if ( browser_item && browser_item->type() == Smb4KNetworkBrowserItem::Share &&
+ browser_item->isMounted() )
+ {
+ QString share_name = QString( "//%1/%2" ).arg( browser_item->shareItem()->host(),
+ browser_item->shareItem()->name() );
+
+ QValueList<Smb4KShare> list = Smb4KCore::mounter()->findShareByName( share_name );
+ Smb4KShare *share = NULL;
+
+ for ( QValueList<Smb4KShare>::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it).isForeign() )
+ {
+ share = &(*it);
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !share )
+ {
+ share = &list.first();
+ }
+
+ // FIXME: Implement forced unmounting?
+ Smb4KCore::mounter()->unmountShare( share, false, false );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotMarkMountedShares()
+{
+ QListViewItemIterator it( m_widget );
+ QListViewItem *item;
+
+ while ((item = it.current()) != 0 )
+ {
+ ++it;
+
+ if ( item->depth() == 2 )
+ {
+ Smb4KShareItem *share_item = static_cast<Smb4KNetworkBrowserItem *>( item )->shareItem();
+
+ QValueList<Smb4KShare> list = Smb4KCore::mounter()->findShareByName( QString( "//%1/%2" ).arg( share_item->host(), share_item->name() ) );
+
+ if ( list.isEmpty() )
+ {
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ if ( browser_item->isMounted() )
+ {
+ browser_item->setMounted( false );
+
+ if ( m_mode == KonqPlugin )
+ {
+ // In case the user wants to unmount the share again
+ // immediately, we need to exchange the actions:
+ if ( actionCollection()->action( "konq_umount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "konq_umount_action" ) );
+ m_menu->insert( actionCollection()->action( "mount_action" ), 11 );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ }
+
+ continue;
+ }
+ else
+ {
+ for ( QValueList<Smb4KShare>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it).isForeign() || Smb4KSettings::showAllShares() )
+ {
+ Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>( item );
+
+ if ( !browser_item->isMounted() )
+ {
+ browser_item->setMounted( true );
+
+ if ( m_mode == KonqPlugin )
+ {
+ // In case the user wants to unmount the share again
+ // immediately, we need to exchange the actions:
+ if ( actionCollection()->action( "mount_action" )->isPlugged( m_menu->popupMenu() ) )
+ {
+ m_menu->remove( actionCollection()->action( "mount_action" ) );
+ m_menu->insert( actionCollection()->action( "konq_umount_action" ), 11 );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ }
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserPart::slotRunStateChanged()
+{
+ switch ( Smb4KCore::currentState() )
+ {
+ case SCANNER_INIT:
+ case SCANNER_OPENING_WORKGROUP:
+ case SCANNER_OPENING_HOST:
+ case SCANNER_RETRYING_OPENING_HOST:
+ case SCANNER_RETRIEVING_INFO:
+ {
+ actionCollection()->action( "rescan_action" )->setEnabled( false );
+ actionCollection()->action( "abort_action" )->setEnabled( true );
+
+ break;
+ }
+ case MOUNTER_MOUNTING:
+ {
+ actionCollection()->action( "abort_action" )->setEnabled( true );
+
+ break;
+ }
+ case SCANNER_STOP:
+ case MOUNTER_STOP:
+ case CORE_STOP:
+ {
+ actionCollection()->action( "rescan_action" )->setEnabled( true );
+
+ if ( Smb4KCore::scannerState() == SCANNER_SEARCHING ||
+ Smb4KCore::scannerState() == SCANNER_STOP ||
+ Smb4KCore::mounterState() != MOUNTER_MOUNTING )
+ {
+ actionCollection()->action( "abort_action" )->setEnabled( false );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// FACTORY STUFF
+/////////////////////////////////////////////////////////////////////////////
+
+Smb4KNetworkBrowserPartFactory::Smb4KNetworkBrowserPartFactory()
+: KParts::Factory()
+{
+}
+
+
+Smb4KNetworkBrowserPartFactory::~Smb4KNetworkBrowserPartFactory()
+{
+ delete m_instance;
+ delete m_about;
+
+ m_instance = 0L;
+}
+
+
+KParts::Part *Smb4KNetworkBrowserPartFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
+QObject *parent, const char *name, const char *, const QStringList &args )
+{
+ Smb4KNetworkBrowserPart *obj = NULL;
+
+ for ( QStringList::ConstIterator it = args.begin(); it != args.end(); ++it )
+ {
+ QString arg = (*it).section( "=", 0, 0 ).stripWhiteSpace();
+ QString value = (*it).section( "=", 1, -1 ).stripWhiteSpace();
+
+ if ( QString::compare( arg, "konqplugin" ) == 0 )
+ {
+ if ( QString::compare( value, "\"true\"" ) == 0 )
+ {
+ obj = new Smb4KNetworkBrowserPart( parentWidget, widgetName, parent, name, Smb4KNetworkBrowserPart::KonqPlugin );
+ }
+ else
+ {
+ obj = new Smb4KNetworkBrowserPart( parentWidget, widgetName, parent, name, Smb4KNetworkBrowserPart::Normal );
+ }
+ }
+ }
+
+ if ( !obj )
+ {
+ obj = new Smb4KNetworkBrowserPart( parentWidget, widgetName, parent, name, Smb4KNetworkBrowserPart::Normal );
+ }
+
+ return obj ;
+}
+
+
+KInstance *Smb4KNetworkBrowserPartFactory::instance()
+{
+ if( !m_instance )
+ {
+ m_about = new KAboutData( "smb4knetworkbrowserpart", I18N_NOOP( "Smb4KNetworkBrowserPart" ), "1.0" );
+ m_about->addAuthor("Alexander Reinholdt", 0, "[email protected]");
+ m_about->setLicense( KAboutData::License_GPL );
+ m_instance = new KInstance( m_about );
+ }
+
+ return m_instance;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// INIT
+/////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+{
+ void *init_libsmb4knetworkbrowser()
+ {
+ KGlobal::locale()->insertCatalogue( "smb4k" );
+ return new Smb4KNetworkBrowserPartFactory;
+ }
+}
+
+
+#include "smb4knetworkbrowser_part.moc"
diff --git a/smb4k/browser/smb4knetworkbrowser_part.h b/smb4k/browser/smb4knetworkbrowser_part.h
new file mode 100644
index 0000000..a3351dc
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowser_part.h
@@ -0,0 +1,377 @@
+/***************************************************************************
+ smb4knetworkbrowser_part - This Part encapsulates the network
+ browser of Smb4K.
+ -------------------
+ begin : Fr Jan 5 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KNETWORKBROWSERPART_H
+#define SMB4KNETWORKBROWSERPART_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kactionclasses.h>
+#include <kparts/part.h>
+#include <kparts/factory.h>
+
+// Qt includes
+#include <qptrlist.h>
+#include <qlistview.h>
+
+// forward declarations
+class Smb4KNetworkBrowser;
+class Smb4KNetworkBrowserItem;
+class Smb4KWorkgroupItem;
+class Smb4KHostItem;
+class Smb4KShareItem;
+
+/**
+ * This is one of the parts of Smb4K. It contains the network browser.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KNetworkBrowserPart : public KParts::Part
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Mode enumeration
+ */
+ enum Mode { Normal, KonqPlugin };
+
+ /**
+ * The constructor.
+ *
+ * @param parentWidget The parent widget
+ *
+ * @param widgetName The name the widget should have
+ *
+ * @param parent The parent object
+ *
+ * @param name The name this object should have
+ *
+ * @param mode Determines in which mode the KPart should be started
+ */
+ Smb4KNetworkBrowserPart( QWidget *parentWidget = 0,
+ const char *widgetName = 0,
+ QObject *parent = 0,
+ const char *name = 0,
+ Mode mode = Normal );
+
+ /**
+ * The destructor.
+ */
+ virtual ~Smb4KNetworkBrowserPart();
+
+ protected:
+ /**
+ * Reimplemented from KParts::Part.
+ */
+ void customEvent( QCustomEvent *e );
+
+ protected slots:
+ /**
+ * This slot is called if the user requests the context menu. It shows
+ * the menu with the actions defined for the widget.
+ *
+ * @param item The item for which the popup menu has been
+ * requested or NULL.
+ *
+ * @param pos The position where user clicked.
+ *
+ * @param col The column where the user clicked.
+ */
+ void slotContextMenuRequested( QListViewItem *item, const QPoint &pos, int col );
+
+ /**
+ * Is called when the selection changed. This slot takes care of the
+ * actions being enabled or disabled accordingly. All widget specific
+ * stuff has to be done in the browser widget itself.
+ *
+ * @param item The selection list view item.
+ */
+ void slotSelectionChanged( QListViewItem *item );
+
+ /**
+ * Is called when the user pressed a mouse button somewhere in the widget.
+ * In addition to Smb4KNetworkBrowserPart::slotSelectionChanged() this slot
+ * takes care of the actions being enabled or disabled accordingly. All
+ * widget specific stuff has to be done in the browser widget itself.
+ *
+ * @param item The selection list view item.
+ */
+ void slotPressed( QListViewItem *item );
+
+ /**
+ * This slot is called when an item of the browser's list view has been opened.
+ * It is used to invoke the functions of the scanner that need to be run.
+ *
+ * @param item The list view item that has been opened.
+ */
+ void slotItemExpanded( QListViewItem *item );
+
+ /**
+ * This slot is called when an item of the browser's list view has been closed.
+ *
+ * @param item The list view item that has been closed.
+ */
+ void slotItemCollapsed( QListViewItem *item );
+
+ /**
+ * This slot is invoked when the user executed an item. It is used to mount
+ * shares.
+ *
+ * @param item The list view item that has been executed.
+ */
+ void slotItemExecuted( QListViewItem *item );
+
+ /**
+ * This slot is called when the user moved the mouse over an @p item in the
+ * network browser's list view and a tool tip is about to be shown. It will
+ * initiate any actions that have to be taken by the scanner to complete
+ * the information on the network items shown in the browser.
+ *
+ * @param item The item for which the additional info should
+ * be retrieved
+ */
+ void slotAboutToShowToolTip( Smb4KNetworkBrowserItem *item );
+
+ /**
+ * This slot receives the workgroups/domains found by the scanner. It takes
+ * a list of workgroup items @p list and inserts the respective workgroups
+ * into the browser window. Obsolete items will be deleted from the network
+ * browser.
+ *
+ * @param list A list of Smb4KWorkgroupItem objects
+ */
+ void slotWorkgroups( const QValueList<Smb4KWorkgroupItem *> &list );
+
+ /**
+ * This slot receives the list of workgroup/domain members that were found
+ * by the scanner. It takes this @p list and inserts it into the list view.
+ * The parent of the items is the workgroup/domain item with the name
+ * @p workgroup. Obsolete items will be deleted from the network browser.
+ *
+ * @param workgroup The workgroup where the hosts belong
+ *
+ * @param list A list of Smb4KHostItem objects
+ */
+ void slotWorkgroupMembers( const QString &workgroup, const QValueList<Smb4KHostItem *> &list );
+
+ /**
+ * This slot receives the list of shared resources a host provides. It takes
+ * this @p list and inserts its items as children of @p host into the list
+ * view. Obsolete items will be deleted from the network browser.
+ *
+ * @param host The host where the shares belong
+ *
+ * @param list The list of shares that belong to @p host
+ */
+ void slotShares( const QString &host, const QValueList<Smb4KShareItem *> &list );
+
+ /**
+ * This slot takes a Smb4KHostItem object @p item, reads the IP address entry
+ * from it and updates the list view item representing the host with it.
+ *
+ * @param item A Smb4KHostItem with an updated IP address.
+ */
+ void slotAddIPAddress( Smb4KHostItem *item );
+
+ /**
+ * This slot adds additional information to a browser item. It takes an
+ * Smb4KHostItem @p item, searches the assossiated browser item and updates its
+ * contents.
+ *
+ * @param item A Smb4KHostItem with updated contents.
+ */
+ void slotAddInformation( Smb4KHostItem *item );
+
+ /**
+ * This slots is connected to the Smb4KScanner::hostAdded() signal and inserts
+ * a single host in the list view. If the host is already present, nothing is
+ * done.
+ *
+ * @param item A Smb4KHostItem that is to be added to the
+ * list view.
+ */
+ void slotInsertHost( Smb4KHostItem *item );
+
+ /**
+ * Rescan the network. This slot is connected to the 'Rescan' action.
+ */
+ void slotRescan();
+
+ /**
+ * Abort a network scan. This slot is connected to the 'Abort' action.
+ */
+ void slotAbort();
+
+ /**
+ * Manually mount a share. This slot is connected to the 'Mount Manually'
+ * action and opens a mount dialog.
+ */
+ void slotMountManually();
+
+ /**
+ * Provide authentication for the current network object. This slot is
+ * connected to the 'Authentication' action.
+ */
+ void slotAuthentication();
+
+ /**
+ * Provide custom options for a server or share. This slot is connected
+ * to the 'Custom Options' action.
+ */
+ void slotCustomOptions();
+
+ /**
+ * Bookmark a remote share. This slot is connected to the 'Add Bookmark'
+ * action.
+ */
+ void slotBookmark();
+
+ /**
+ * Preview a share. This slot is connected to the 'Preview' action.
+ */
+ void slotPreview();
+
+ /**
+ * Print a document on a remote printer. This slot is connected to the
+ * 'Print File' action.
+ */
+ void slotPrint();
+
+ /**
+ * Mount a remote share. This slot is connected to the 'Mount' action.
+ */
+ void slotMount();
+
+ /**
+ * Unmount a share. This slot is only relevant in the Konqueror plugin
+ * mode.
+ */
+ void slotUnmount();
+
+ /**
+ * This slot is invoked by the Smb4KMounter::updated() signal and changes
+ * the text and icon of all shares that are already mounted.
+ */
+ void slotMarkMountedShares();
+
+ /**
+ * This slot is connected to the Smb4KCore::runStateChanged() signal and
+ * is used to enable/disable actions.
+ */
+ void slotRunStateChanged();
+
+ private:
+ /**
+ * Set up the actions
+ */
+ void setupActions();
+
+ /**
+ * Load settings for the widget or the actions.
+ */
+ void loadSettings();
+
+ /**
+ * The action menu
+ */
+ KActionMenu *m_menu;
+
+ /**
+ * The network browser widget
+ */
+ Smb4KNetworkBrowser *m_widget;
+
+ /**
+ * Determines with which mode the KPart will be started
+ */
+ Mode m_mode;
+};
+
+
+class KInstance;
+class KAboutData;
+
+class Smb4KNetworkBrowserPartFactory : public KParts::Factory
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ */
+ Smb4KNetworkBrowserPartFactory();
+
+ /**
+ * The destructor
+ */
+ virtual ~Smb4KNetworkBrowserPartFactory();
+
+ /**
+ * Reimplemented from KParts::Factory. This function is used to
+ * create a part object.
+ *
+ * @param parentWidget The parent of the part's widget.
+ *
+ * @param widgetName The name of the part's widget.
+ *
+ * @param parent The parent of the part.
+ *
+ * @param name The name of the part.
+ *
+ * @param classname The class name of the part. This should be "KParts::Part".
+ *
+ * @param args A list of additional arguments. They have to be provided as
+ * name="value" pairs. At the moment this function understands
+ * the following pairs:
+ * konqplugin="true"|"false".
+ */
+ virtual KParts::Part *createPartObject( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name,
+ const char *classname, const QStringList &args = QStringList() );
+
+ /**
+ * The instance
+ */
+ static KInstance *instance();
+
+ private:
+ /**
+ * The factory's instance.
+ */
+ static KInstance *m_instance;
+
+ /**
+ * The factory's KAboutData object
+ */
+ static KAboutData *m_about;
+};
+
+#endif
diff --git a/smb4k/browser/smb4knetworkbrowser_part.rc b/smb4k/browser/smb4knetworkbrowser_part.rc
new file mode 100644
index 0000000..8a7d938
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowser_part.rc
@@ -0,0 +1,31 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="smb4knetworkbrowser_part" version="1">
+<MenuBar>
+ <Menu name="network"><text>&amp;Network</text>
+ <Action name="rescan_action"/>
+ <Action name="abort_action"/>
+ <Separator/>
+ <Action name="mount_manually_action"/>
+ <Separator/>
+ <Action name="askpass_action"/>
+ <Action name="custom_action"/>
+ <Action name="bookmark_action"/>
+ <Action name="preview_action"/>
+ <Action name="print_action"/>
+ <Action name="mount_action"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="networkToolBar">
+ <Action name="rescan_action"/>
+ <Action name="abort_action"/>
+ <Separator/>
+ <Action name="mount_manually_action"/>
+ <Separator/>
+ <Action name="askpass_action"/>
+ <Action name="custom_action"/>
+ <Action name="bookmark_action"/>
+ <Action name="preview_action"/>
+ <Action name="print_action"/>
+ <Action name="mount_action"/>
+</ToolBar>
+</kpartgui>
diff --git a/smb4k/browser/smb4knetworkbrowseritem.cpp b/smb4k/browser/smb4knetworkbrowseritem.cpp
new file mode 100644
index 0000000..c3f2ebe
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowseritem.cpp
@@ -0,0 +1,228 @@
+/***************************************************************************
+ smb4knetworkbrowseritem - Smb4K's network browser list item.
+ -------------------
+ begin : Mo Jan 8 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qpainter.h>
+
+// KDE includes
+#include <kiconloader.h>
+#include <kicontheme.h>
+
+// application specific includes
+#include "smb4knetworkbrowseritem.h"
+
+Smb4KNetworkBrowserItem::Smb4KNetworkBrowserItem( QListView *parent, Smb4KWorkgroupItem *item )
+: KListViewItem( parent, item->name() ), m_type( Workgroup ), m_workgroup( *item ),
+m_mounted( false )
+{
+ setIcon();
+}
+
+
+Smb4KNetworkBrowserItem::Smb4KNetworkBrowserItem( QListViewItem *parent, Smb4KHostItem *item )
+: KListViewItem( parent, item->name(), QString::null, item->ip(), item->comment() ),
+m_type( Host ), m_host( *item ), m_mounted( false )
+{
+ setIcon();
+}
+
+
+Smb4KNetworkBrowserItem::Smb4KNetworkBrowserItem( QListViewItem *parent, Smb4KShareItem *item )
+: KListViewItem( parent, item->name(), item->plainType(), QString::null, item->comment() ),
+m_type( Share ), m_share( *item ), m_mounted( false )
+{
+ setIcon();
+}
+
+
+Smb4KNetworkBrowserItem::~Smb4KNetworkBrowserItem()
+{
+}
+
+
+void Smb4KNetworkBrowserItem::setIcon()
+{
+ switch ( m_type )
+ {
+ case Workgroup:
+ {
+ m_desktop_icon = DesktopIcon( "network_local" );
+ setPixmap( 0, SmallIcon( "network_local" ) );
+ break;
+ }
+ case Host:
+ {
+ m_desktop_icon = DesktopIcon( "server" );
+ setPixmap( 0, SmallIcon( "server" ) );
+ break;
+ }
+ case Share:
+ {
+ if ( m_share.isPrinter() )
+ {
+ m_desktop_icon = DesktopIcon( "printer1" );
+ setPixmap( 0, SmallIcon( "printer1" ) );
+ }
+ else
+ {
+ if ( m_mounted )
+ {
+ m_desktop_icon = DesktopIcon( "folder_open", 0, KIcon::ActiveState );
+ setPixmap( 0, SmallIcon( "folder_open", 0, KIcon::ActiveState ) );
+ }
+ else
+ {
+ m_desktop_icon = DesktopIcon( "folder", 0, KIcon::DefaultState );
+ setPixmap( 0, SmallIcon( "folder", 0, KIcon::DefaultState ) );
+ }
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+Smb4KNetworkBrowserItem::ItemType Smb4KNetworkBrowserItem::type()
+{
+ return m_type;
+}
+
+
+Smb4KWorkgroupItem *Smb4KNetworkBrowserItem::workgroupItem()
+{
+ return (m_type == Workgroup ? &m_workgroup : NULL);
+}
+
+
+Smb4KHostItem *Smb4KNetworkBrowserItem::hostItem()
+{
+ return (m_type == Host ? &m_host : NULL);
+}
+
+
+Smb4KShareItem *Smb4KNetworkBrowserItem::shareItem()
+{
+ return (m_type == Share ? &m_share : NULL);
+}
+
+
+void Smb4KNetworkBrowserItem::update( Smb4KWorkgroupItem *item )
+{
+ m_workgroup = *item;
+}
+
+
+void Smb4KNetworkBrowserItem::update( Smb4KHostItem *item )
+{
+ m_host = *item;
+
+ if ( !m_host.ip().isEmpty() && QString::compare( text( IP ).stripWhiteSpace(), m_host.ip() ) != 0 )
+ {
+ setText( IP, m_host.ip() );
+ }
+
+ if ( QString::compare( text( Comment ).stripWhiteSpace(), m_host.comment() ) != 0 )
+ {
+ setText( Comment, m_host.comment() );
+ }
+}
+
+
+void Smb4KNetworkBrowserItem::update( Smb4KShareItem *item )
+{
+ m_share = *item;
+
+ if ( !m_share.comment().isEmpty() && QString::compare( text( Comment ).stripWhiteSpace(), m_share.comment() ) != 0 )
+ {
+ setText( Comment, m_share.comment() );
+ }
+}
+
+
+bool Smb4KNetworkBrowserItem::isPrinter()
+{
+ bool is_printer = false;
+
+ if ( m_type == Share )
+ {
+ is_printer = m_share.isPrinter();
+ }
+
+ return is_printer;
+}
+
+
+void Smb4KNetworkBrowserItem::setMounted( bool mounted )
+{
+ if ( m_type == Share && QString::compare( m_share.plainType(), "Disk" ) == 0 )
+ {
+ m_mounted = mounted;
+
+ setIcon();
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+bool Smb4KNetworkBrowserItem::isMounted()
+{
+ return m_mounted;
+}
+
+
+void Smb4KNetworkBrowserItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align )
+{
+ QFont f( p->font() );
+ QColorGroup colorgrp( cg );
+
+ if ( m_type == Share && m_mounted )
+ {
+ f.setItalic( true );
+ }
+ else
+ {
+ f.setItalic( false );
+ }
+
+ if ( m_type == Host && m_host.isMaster() )
+ {
+ colorgrp.setColor( QColorGroup::Text, Qt::darkBlue );
+ }
+ else
+ {
+ colorgrp.setColor( QColorGroup::Text, cg.text() );
+ }
+
+ p->setFont( f );
+
+ QListViewItem::paintCell( p, colorgrp, column, width, align );
+}
diff --git a/smb4k/browser/smb4knetworkbrowseritem.h b/smb4k/browser/smb4knetworkbrowseritem.h
new file mode 100644
index 0000000..141ae04
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowseritem.h
@@ -0,0 +1,222 @@
+/***************************************************************************
+ smb4knetworkbrowseritem - Smb4K's network browser list item.
+ -------------------
+ begin : Mo Jan 8 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KNETWORKBROWSERITEM_H
+#define SMB4KNETWORKBROWSERITEM_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qpixmap.h>
+
+// KDE includes
+#include <klistview.h>
+
+// application specific includes
+#include "../core/smb4knetworkitems.h"
+
+class Smb4KNetworkBrowser;
+class Smb4KNetworkBrowserItem : public KListViewItem
+{
+ public:
+ /**
+ * The constructor for toplevel (workgroup) items.
+ *
+ * @param parent The parent list view.
+ *
+ * @param item The Smb4KWorkgroupItem that carries all the data
+ * needed to set up a "workgroup item".
+ */
+ Smb4KNetworkBrowserItem( QListView *parent, Smb4KWorkgroupItem *item );
+
+ /**
+ * The constructor for the host items.
+ *
+ * @param parent The parent list view item.
+ *
+ * @param item The Smb4KHostItem that carries all the data.
+ */
+ Smb4KNetworkBrowserItem( QListViewItem *parent, Smb4KHostItem *item );
+
+ /**
+ * The constructor for the share items.
+ *
+ * @param parent The parent list view item.
+ *
+ * @param item The Smb4KShareItem that carries all the data.
+ */
+ Smb4KNetworkBrowserItem( QListViewItem *parent, Smb4KShareItem *item );
+
+ /**
+ * The destructor.
+ */
+ virtual ~Smb4KNetworkBrowserItem();
+
+ /**
+ * Enumeration that determines the type of the item.
+ */
+ enum ItemType{ Workgroup, Host, Share };
+
+ /**
+ * This function returns the type of the item according to the ItemType
+ * enumeration.
+ *
+ * @returns the type of the item.
+ */
+ Smb4KNetworkBrowserItem::ItemType type();
+
+ /**
+ * This function returns a pointer to the Smb4KWorkgroupItem object if it
+ * is present or NULL if it is not.
+ *
+ * @returns a pointer to the workgroup item or NULL.
+ */
+ Smb4KWorkgroupItem *workgroupItem();
+
+ /**
+ * This function returns a pointer to the Smb4KHostItem object if it
+ * is present or NULL if it is not.
+ *
+ * @returns a pointer to the host item or NULL.
+ */
+ Smb4KHostItem *hostItem();
+
+ /**
+ * This function returns a pointer to the Smb4KShareItem object if it
+ * is present or NULL if it is not.
+ *
+ * @returns a pointer to the share item or NULL.
+ */
+ Smb4KShareItem *shareItem();
+
+ /**
+ * This function updates the internal Smb4KWorkgroupItem object.
+ *
+ * @param item A Smb4KWorkgroupItem object
+ */
+ void update( Smb4KWorkgroupItem *item );
+
+ /**
+ * This function updates the internal Smb4KHostItem object and
+ * changes the text that's being displayed in the browser. Use this,
+ * if you have to alter the item in the browser.
+ *
+ * @param item A Smb4KHostItem
+ */
+ void update( Smb4KHostItem *item );
+
+ /**
+ * This function updates the internal Smb4KShareItem object and
+ * changes the text that's being displayed in the browser. Use this,
+ * if you have to alter the item in the browser.
+ *
+ * @param item A Smb4KShareItem
+ */
+ void update( Smb4KShareItem *item );
+
+ /**
+ * This is a convenience function. It returns TRUE if the item is a
+ * printer share and FALSE otherwise.
+ *
+ * @returns TRUE if the item is a printer share and FALSE otherwise.
+ */
+ bool isPrinter();
+
+ /**
+ * Tell the item that the share it represents is mounted. The icon will be
+ * changed by this function and the item text will be set to italic by
+ * Smb4KNetworkBrowserItem::paintCell().
+ *
+ * @param mounted TRUE if the share is mounted and FALSE otherwise
+ */
+ void setMounted( bool mounted = true );
+
+ /**
+ * Tells whether the respective share is shown as mounted or not. For non-share
+ * items this function will always return FALSE.
+ *
+ * @returns TRUE if the share is mounted and FALSE otherwise.
+ */
+ bool isMounted();
+
+ /**
+ * Returns the icon of this item in "Desktop" size.
+ *
+ * @returns a pixmap
+ */
+ const QPixmap &desktopIcon() { return m_desktop_icon; }
+
+ protected:
+ /**
+ * Reimplemented from QListViewItem.
+ */
+ void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align );
+
+ private:
+ /**
+ * This function sets the icon of the item according to
+ * the type and other factors.
+ */
+ void setIcon();
+
+ /**
+ * The type of the item.
+ */
+ ItemType m_type;
+
+ /**
+ * This enumeration enumerates the columns of the item.
+ */
+ enum Columns{ Network = 0, Type = 1, IP = 2, Comment = 3 };
+
+ /**
+ * The workgroup item
+ */
+ Smb4KWorkgroupItem m_workgroup;
+
+ /**
+ * The host item
+ */
+ Smb4KHostItem m_host;
+
+ /**
+ * The share item
+ */
+ Smb4KShareItem m_share;
+
+ /**
+ * Tells us that the share item is mounted
+ */
+ bool m_mounted;
+
+ /**
+ * The icon in "DesktopIcon" format
+ */
+ QPixmap m_desktop_icon;
+};
+
+#endif
diff --git a/smb4k/browser/smb4knetworkbrowsertooltip.cpp b/smb4k/browser/smb4knetworkbrowsertooltip.cpp
new file mode 100644
index 0000000..451344f
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowsertooltip.cpp
@@ -0,0 +1,378 @@
+/***************************************************************************
+ smb4knetworkbrowsertooltip - Tool tip for the network browser.
+ -------------------
+ begin : Sa Jan 20 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qtooltip.h>
+#include <qdesktopwidget.h>
+#include <qapplication.h>
+#include <qtimer.h>
+
+// KDE includes
+#include <klocale.h>
+
+// application specific includes
+#include "smb4knetworkbrowsertooltip.h"
+#include "smb4knetworkbrowseritem.h"
+
+Smb4KNetworkBrowserToolTip::Smb4KNetworkBrowserToolTip( Smb4KNetworkBrowserItem *item )
+: QLabel( 0, "NetworkBrowserToolTip", WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM | WDestructiveClose ), m_item( item )
+{
+ setPalette( QToolTip::palette() );
+ setLineWidth( 1 );
+ setMidLineWidth( 1 );
+ setFrameShape( Box );
+ setFrameShadow( Plain );
+ setMouseTracking( true );
+
+ m_layout = new QGridLayout( this );
+ m_layout->setMargin( 10 );
+ m_layout->setSpacing( 3 );
+
+ // We will set up the tip in the showTip() function.
+}
+
+
+Smb4KNetworkBrowserToolTip::~Smb4KNetworkBrowserToolTip()
+{
+ // Never touch the Smb4KNetworkBrowserItem object here
+}
+
+
+void Smb4KNetworkBrowserToolTip::showTip( const QPoint &pos )
+{
+ if ( !m_item || isShown() )
+ {
+ return;
+ }
+
+ setupTip();
+
+ adjustSize();
+
+ QPoint p( pos );
+
+ QDesktopWidget *d = QApplication::desktop();
+
+ if ( p.x() + width() > d->width() )
+ {
+ p.setX( p.x() - width() - 5 );
+ }
+ else
+ {
+ p.setX( p.x() + 5 );
+ }
+
+ if ( p.y() + height() > d->height() )
+ {
+ p.setY( p.y() - height() - 5 );
+ }
+ else
+ {
+ p.setY( p.y() + 5 );
+ }
+
+ setGeometry( p.x(), p.y(), width(), height() );
+ polish();
+ show();
+ QTimer::singleShot( 10000, this, SLOT( slotHideToolTip() ) );
+}
+
+
+void Smb4KNetworkBrowserToolTip::setupTip()
+{
+ switch ( m_item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Workgroup:
+ {
+ QLabel *workgroup_label = new QLabel( i18n( "Workgroup:" ), this );
+ QLabel *workgroup = new QLabel( m_item->workgroupItem()->name() , this );
+
+ QString master_label_entry = m_item->workgroupItem()->hasPseudoMaster() ? i18n( "Pseudo master browser:" ) : i18n( "Master browser:" );
+ QLabel *master_label = new QLabel( master_label_entry, this );
+
+ QString master_entry = m_item->workgroupItem()->masterIP().isEmpty() ?
+ (m_item->workgroupItem()->master().isEmpty() ? i18n( "Unknown" ) : m_item->workgroupItem()->master()) :
+ m_item->workgroupItem()->master() + " ("+m_item->workgroupItem()->masterIP()+")";
+ QLabel *master = new QLabel( master_entry, this, "MasterBrowser" );
+
+ m_layout->addWidget( workgroup_label, 0, 1, 0 );
+ m_layout->addWidget( workgroup, 0, 2, 0 );
+ m_layout->addWidget( master_label, 1, 1, 0 );
+ m_layout->addWidget( master, 1, 2, 0 );
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ QLabel *host_label = new QLabel( i18n( "Host:" ), this );
+ QLabel *host = new QLabel( m_item->hostItem()->name(), this );
+
+ QLabel *comment_label = new QLabel( i18n( "Comment:" ), this );
+ QLabel *comment = new QLabel( m_item->hostItem()->comment(), this );
+
+ QLabel *ip_label = new QLabel( i18n( "IP address:" ), this );
+ QString ip_entry = m_item->hostItem()->ip().isEmpty() ? i18n( "Unknown" ) : m_item->hostItem()->ip();
+ QLabel *ip_address = new QLabel( ip_entry, this, "IPAddress" );
+
+ QLabel *os_label = new QLabel( i18n( "Operating system:" ), this );
+ QLabel *operating_system = new QLabel( m_item->hostItem()->osString().isEmpty() ? i18n( "Unknown" ) :
+ m_item->hostItem()->osString(), this, "OSString" );
+
+ QLabel *server_label = new QLabel( i18n( "Server string:" ), this );
+ QLabel *server_string = new QLabel( m_item->hostItem()->serverString().isEmpty() ? i18n( "Unknown" ) :
+ m_item->hostItem()->serverString(), this, "ServerString" );
+
+ QFrame *line = new QFrame( this );
+ line->setLineWidth( 1 );
+ line->setMidLineWidth( 0 );
+ line->setFixedWidth( 100 );
+ line->setFrameShape( QFrame::HLine );
+ line->setFrameShadow( QFrame::Plain );
+
+ QLabel *workgroup_label = new QLabel( i18n( "Workgroup:" ), this );
+ QLabel *workgroup = new QLabel( m_item->hostItem()->workgroup(), this );
+
+ Smb4KWorkgroupItem *workgroup_item = static_cast<Smb4KNetworkBrowserItem *>( m_item->parent() )->workgroupItem();
+ QLabel *master_label = new QLabel( i18n( "Master browser:" ), this );
+ QLabel *master_yes_no = new QLabel( (workgroup_item && !workgroup_item->master().isEmpty()) ?
+ workgroup_item->master() : i18n( "Unknown" ), this );
+
+ m_layout->addWidget( host_label, 0, 1, 0 );
+ m_layout->addWidget( host, 0, 2, 0 );
+ m_layout->addWidget( comment_label, 1, 1, 0 );
+ m_layout->addWidget( comment, 1, 2, 0 );
+ m_layout->addWidget( ip_label, 2, 1, 0 );
+ m_layout->addWidget( ip_address, 2, 2, 0 );
+ m_layout->addWidget( os_label, 3, 1, 0 );
+ m_layout->addWidget( operating_system, 3, 2, 0 );
+ m_layout->addWidget( server_label, 4, 1, 0 );
+ m_layout->addWidget( server_string, 4, 2, 0 );
+ m_layout->addMultiCellWidget( line, 5, 5, 1, 2, Qt::AlignCenter );
+ m_layout->addWidget( workgroup_label, 6, 1, 0 );
+ m_layout->addWidget( workgroup, 6, 2, 0 );
+ m_layout->addWidget( master_label, 7, 1, 0 );
+ m_layout->addWidget( master_yes_no, 7, 2, 0 );
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ QLabel *share_label = new QLabel( i18n( "Share:" ), this );
+ QLabel *share = new QLabel( m_item->shareItem()->name(), this );
+
+ QLabel *comment_label = new QLabel( i18n( "Comment:" ), this );
+ QLabel *comment = new QLabel( m_item->shareItem()->comment(), this );
+
+ QLabel *type_label = new QLabel( i18n( "Type:" ), this );
+ QLabel *type = new QLabel( m_item->shareItem()->translatedType(), this );
+
+ QLabel *mounted_label = NULL;
+ QLabel *mounted = NULL;
+
+ if ( !m_item->isPrinter() )
+ {
+ mounted_label = new QLabel( i18n( "Mounted:" ), this );
+ mounted = new QLabel( m_item->isMounted() ? i18n( "Yes" ) : i18n( "No" ), this );
+ }
+
+ QFrame *line = new QFrame( this );
+ line->setLineWidth( 1 );
+ line->setMidLineWidth( 0 );
+ line->setFixedWidth( 100 );
+ line->setFrameShape( QFrame::HLine );
+ line->setFrameShadow( QFrame::Plain );
+
+ QLabel *host_label = new QLabel( i18n( "Host:" ), this );
+ QLabel *host = new QLabel( m_item->shareItem()->host(), this );
+
+ Smb4KHostItem *host_item = static_cast<Smb4KNetworkBrowserItem *>( m_item->parent() )->hostItem();
+ QLabel *ip_label = new QLabel( i18n( "IP address:" ), this );
+ QLabel *ip_address = new QLabel( (host_item && !host_item->ip().isEmpty()) ?
+ host_item->ip() : i18n( "Unknown" ), this, "IPAddress" );
+
+ m_layout->addWidget( share_label, 0, 1, 0 );
+ m_layout->addWidget( share, 0, 2, 0 );
+ m_layout->addWidget( comment_label, 1, 1, 0 );
+ m_layout->addWidget( comment, 1, 2, 0 );
+ m_layout->addWidget( type_label, 2, 1, 0 );
+ m_layout->addWidget( type, 2, 2, 0 );
+
+ if ( !m_item->isPrinter() )
+ {
+ m_layout->addWidget( mounted_label, 3, 1, 0 );
+ m_layout->addWidget( mounted, 3, 2, 0 );
+ m_layout->addMultiCellWidget( line, 4, 4, 1, 2, Qt::AlignCenter );
+ m_layout->addWidget( host_label, 5, 1, 0 );
+ m_layout->addWidget( host, 5, 2, 0 );
+ m_layout->addWidget( ip_label, 6, 1, 0 );
+ m_layout->addWidget( ip_address, 6, 2, 0 );
+ }
+ else
+ {
+ m_layout->addMultiCellWidget( line, 3, 3, 1, 2, Qt::AlignCenter );
+ m_layout->addWidget( host_label, 4, 1, 0 );
+ m_layout->addWidget( host, 4, 2, 0 );
+ m_layout->addWidget( ip_label, 5, 1, 0 );
+ m_layout->addWidget( ip_address, 5, 2, 0 );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ QLabel *pix_label = new QLabel( this );
+ pix_label->setPixmap( m_item->desktopIcon() );
+
+ m_layout->addMultiCellWidget( pix_label, 0, m_layout->numRows(), 0, 0, Qt::AlignCenter );
+}
+
+
+void Smb4KNetworkBrowserToolTip::update()
+{
+ // This function updates a tool tip that
+ // is shown. So, if the tool tip exists, but
+ // is not shown, stop here.
+ if ( !isShown() )
+ {
+ return;
+ }
+
+ switch ( m_item->type() )
+ {
+ case Smb4KNetworkBrowserItem::Workgroup:
+ {
+ QLabel *master_label = static_cast<QLabel *>( child( "MasterBrowser", "QLabel", true ) );
+
+ if ( master_label )
+ {
+ QString master_string = m_item->workgroupItem()->masterIP().isEmpty() ?
+ m_item->workgroupItem()->master() :
+ m_item->workgroupItem()->master() + " ("+m_item->workgroupItem()->masterIP()+")";
+
+ master_label->setText( master_string );
+ }
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Host:
+ {
+ QLabel *os_label = static_cast<QLabel *>( child( "OSString", "QLabel", true ) );
+ QLabel *server_label = static_cast<QLabel *>( child( "ServerString", "QLabel", true ) );
+ QLabel *ip_label = static_cast<QLabel *>( child( "IPAddress", "QLabel", true ) );
+
+ if ( os_label )
+ {
+ QString os_string = m_item->hostItem()->osString().isEmpty() ?
+ i18n( "Unknown" ) :
+ m_item->hostItem()->osString();
+
+ os_label->setText( os_string );
+ }
+
+ if ( server_label )
+ {
+ QString server_string = m_item->hostItem()->serverString().isEmpty() ?
+ i18n( "Unknown" ) :
+ m_item->hostItem()->serverString();
+
+ server_label->setText( server_string );
+ }
+
+ if ( ip_label )
+ {
+ QString ip_string = m_item->hostItem()->ip().isEmpty() ?
+ i18n( "Unknown" ) :
+ m_item->hostItem()->ip();
+
+ ip_label->setText( ip_string );
+ }
+
+ break;
+ }
+ case Smb4KNetworkBrowserItem::Share:
+ {
+ QLabel *ip_label = static_cast<QLabel *>( child( "IPAddress", "QLabel", true ) );
+
+ if ( ip_label )
+ {
+ Smb4KHostItem *host = static_cast<Smb4KNetworkBrowserItem *>( m_item->parent() )->hostItem();
+ QString ip_string;
+
+ if ( host )
+ {
+ ip_string = (host && !host->ip().isEmpty()) ?
+ host->ip() :
+ i18n( "Unknown" );
+ }
+ else
+ {
+ ip_string = i18n( "Unknown" );
+ }
+
+ ip_label->setText( ip_string );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KNetworkBrowserToolTip::mousePressEvent( QMouseEvent *e )
+{
+ hide();
+ QLabel::mousePressEvent( e );
+}
+
+
+void Smb4KNetworkBrowserToolTip::leaveEvent( QEvent *e )
+{
+ hide();
+ QLabel::leaveEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KNetworkBrowserToolTip::slotHideToolTip()
+{
+ if ( isShown() )
+ {
+ hide();
+ }
+}
+
+
+#include "smb4knetworkbrowsertooltip.moc"
diff --git a/smb4k/browser/smb4knetworkbrowsertooltip.h b/smb4k/browser/smb4knetworkbrowsertooltip.h
new file mode 100644
index 0000000..993f64c
--- /dev/null
+++ b/smb4k/browser/smb4knetworkbrowsertooltip.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ smb4knetworkbrowsertooltip - Tool tip for the network browser.
+ -------------------
+ begin : Sa Jan 20 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KNETWORKBROWSERTOOLTIP_H
+#define SMB4KNETWORKBROWSERTOOLTIP_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qlabel.h>
+#include <qlayout.h>
+
+// Forward declarations:
+class Smb4KNetworkBrowserItem;
+
+
+/**
+ * This class provides the tool tip for the network browser
+ * of Smb4K. It shows information about the associated share.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KNetworkBrowserToolTip : public QLabel
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param item The Smb4KNetworkBrowserItem object for which
+ * a tool tip should be shown.
+ */
+ Smb4KNetworkBrowserToolTip( Smb4KNetworkBrowserItem *item );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KNetworkBrowserToolTip();
+
+ /**
+ * Show the tool tip. Please note that the tool tip will not be shown
+ * exactly at position @p pos but with a displacement of 5 pixels in x-
+ * and y-direction.
+ */
+ void showTip( const QPoint &pos );
+
+ /**
+ * If you need to update the tool tip while it is shown, this is the function
+ * you want to use. It rereads the entries from the assossiated
+ * Smb4KNetworkBrowserItem object and modifies the tool tip if changes happened.
+ */
+ void update();
+
+ /**
+ * Returns the Smb4KNetworkBrowserItem object for which the tool tip
+ * should be shown.
+ *
+ * @returns a pointer to a Smb4KNetworkBrowserItem object.
+ */
+ Smb4KNetworkBrowserItem *item() { return m_item; }
+
+ protected:
+ /**
+ * Reimplemented from QLabel.
+ */
+ void mousePressEvent( QMouseEvent *e );
+
+ /**
+ * Reimplemented from QLabel.
+ */
+ void leaveEvent( QEvent *e );
+
+ protected slots:
+ /**
+ * This slot hides the tool tip after 10 sec.
+ */
+ void slotHideToolTip();
+
+ private:
+ /**
+ * The pointer to the Smb4KNetworkBrowserItem object
+ */
+ Smb4KNetworkBrowserItem *m_item;
+
+ /**
+ * The layout for the tool tip
+ */
+ QGridLayout *m_layout;
+
+ /**
+ * Set up the tool tip
+ */
+ void setupTip();
+};
+
+#endif
diff --git a/smb4k/configdlg/Makefile.am b/smb4k/configdlg/Makefile.am
new file mode 100644
index 0000000..6a85b0f
--- /dev/null
+++ b/smb4k/configdlg/Makefile.am
@@ -0,0 +1,12 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+kde_module_LTLIBRARIES = libsmb4kconfigdialog.la
+noinst_HEADERS = smb4kauthoptions.h smb4kconfigdialog.h smb4knetworkoptions.h \
+ smb4krsyncoptions.h smb4ksambaoptions.h smb4kshareoptions.h smb4ksuperuseroptions.h \
+ smb4kuserinterfaceoptions.h
+libsmb4kconfigdialog_la_SOURCES = smb4kauthoptions.cpp smb4kconfigdialog.cpp \
+ smb4knetworkoptions.cpp smb4krsyncoptions.cpp smb4ksambaoptions.cpp smb4kshareoptions.cpp \
+ smb4ksuperuseroptions.cpp smb4kuserinterfaceoptions.cpp
+libsmb4kconfigdialog_la_LIBADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_QT)
+libsmb4kconfigdialog_la_LDFLAGS = -module $(KDE_PLUGIN)
diff --git a/smb4k/configdlg/smb4kauthoptions.cpp b/smb4k/configdlg/smb4kauthoptions.cpp
new file mode 100644
index 0000000..1cafc91
--- /dev/null
+++ b/smb4k/configdlg/smb4kauthoptions.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ smb4kauthoptions - The configuration page for the authentication
+ settings of Smb4K
+ -------------------
+ begin : Sa Nov 15 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+
+// KDE includes
+#include <klocale.h>
+#include <klineedit.h>
+
+// application specific includes
+#include "smb4kauthoptions.h"
+
+Smb4KAuthOptions::Smb4KAuthOptions( QWidget *parent, const char *name )
+: QWidget( parent, name )
+{
+ //
+ // Default Authentication
+ //
+ QGridLayout *grid = new QGridLayout( this );
+ grid->setSpacing( 10 );
+
+ QButtonGroup *password_group = new QButtonGroup( 1, QButtonGroup::Horizontal,
+ i18n( "Password Storage" ), this );
+ QCheckBox *use_wallet = new QCheckBox( i18n( "Save the authentication data in a wallet" ),
+ password_group, "kcfg_UseWallet" );
+ (void) new QCheckBox( i18n( "If no wallet is used, remember authentication data during run time" ),
+ password_group, "kcfg_RememberPasswords" );
+
+ QGroupBox *login_box = new QGroupBox( 1, Qt::Horizontal, i18n( "Default Login" ),
+ this, "DefaultLoginBox" );
+// login_box->setInsideMargin( 10 );
+
+ QCheckBox *default_auth = new QCheckBox( i18n( "Use default login" ),
+ login_box, "kcfg_UseDefaultLogin" );
+
+ QWidget *auth_widget = new QWidget( login_box, "DefaultAuthWidget" );
+ QGridLayout *auth_grid = new QGridLayout( auth_widget );
+ auth_grid->setSpacing( 5 );
+
+ QLabel *login = new QLabel( i18n( "User:" ), auth_widget );
+ KLineEdit *default_login = new KLineEdit( auth_widget, "DefaultUserName" );
+ default_login->setMinimumWidth( 150 );
+ QWhatsThis::add( default_login, i18n( "This login name is used by default to authenticate to a remote server." ) );
+ QLabel *password = new QLabel( i18n( "Password:" ), auth_widget );
+ KLineEdit *default_password = new KLineEdit( auth_widget, "DefaultPassword" );
+ default_password->setEchoMode( KLineEdit::Password );
+ default_password->setMinimumWidth( 150 );
+ QWhatsThis::add( default_password, i18n( "This password is used by default to authenticate to a remote server. It may be empty." ) );
+
+ auth_grid->addWidget( login, 0, 0 );
+ auth_grid->addWidget( default_login, 0, 1 );
+ auth_grid->addWidget( password, 1, 0 );
+ auth_grid->addWidget( default_password, 1, 1 );
+
+ QSpacerItem *spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ grid->addWidget( password_group, 0, 0, 0 );
+ grid->addWidget( login_box, 1, 0, 0 );
+ grid->addItem( spacer2, 2, 0 );
+
+ connect( use_wallet, SIGNAL( stateChanged( int ) ),
+ this, SLOT( slotKWalletButtonState( int ) ) );
+ connect( default_auth, SIGNAL( stateChanged( int ) ),
+ this, SLOT( slotDefaultAuthButtonState( int ) ) );
+
+ slotKWalletButtonState( use_wallet->state() );
+ slotDefaultAuthButtonState( default_auth->state() );
+}
+
+
+Smb4KAuthOptions::~Smb4KAuthOptions()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KAuthOptions::slotKWalletButtonState( int state )
+{
+ if ( state == QCheckBox::On )
+ {
+ static_cast<QCheckBox *>( child( "DefaultLoginBox", "QGroupBox", true ) )->setEnabled( true );
+ }
+ else if ( state == QCheckBox::Off )
+ {
+ static_cast<QCheckBox *>( child( "DefaultLoginBox", "QGroupBox", true ) )->setEnabled( false );
+ }
+}
+
+
+void Smb4KAuthOptions::slotDefaultAuthButtonState( int state )
+{
+ if ( state == QCheckBox::On )
+ {
+ static_cast<QCheckBox *>( child( "DefaultAuthWidget", "QWidget", true ) )->setEnabled( true );
+ }
+ else if ( state == QCheckBox::Off )
+ {
+ static_cast<QCheckBox *>( child( "DefaultAuthWidget", "QWidget", true ) )->setEnabled( false );
+ }
+}
+
+
+
+#include "smb4kauthoptions.moc"
diff --git a/smb4k/configdlg/smb4kauthoptions.h b/smb4k/configdlg/smb4kauthoptions.h
new file mode 100644
index 0000000..5428ede
--- /dev/null
+++ b/smb4k/configdlg/smb4kauthoptions.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ smb4kauthoptions - The configuration page for the authentication
+ settings of Smb4K
+ -------------------
+ begin : Sa Nov 15 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KAUTHOPTIONS_H
+#define SMB4KAUTHOPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qwidget.h>
+
+
+/**
+ * This is the configuration tab for the authentication settings
+ * of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+
+class Smb4KAuthOptions : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KAuthOptions( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KAuthOptions();
+
+ protected slots:
+ /**
+ * This slot manages the toggling of the KWallet support button in the
+ * Authentication tab.
+ *
+ * @param state The toggle state
+ */
+ void slotKWalletButtonState( int state );
+ /**
+ * This slot manages the toggling of the default authentication button.
+ *
+ * @param state The toggle state
+ */
+ void slotDefaultAuthButtonState( int state );
+};
+
+#endif
diff --git a/smb4k/configdlg/smb4kconfigdialog.cpp b/smb4k/configdlg/smb4kconfigdialog.cpp
new file mode 100644
index 0000000..449aec3
--- /dev/null
+++ b/smb4k/configdlg/smb4kconfigdialog.cpp
@@ -0,0 +1,1222 @@
+/***************************************************************************
+ smb4kconfigdialog - The configuration dialog of Smb4K
+ -------------------
+ begin : Sa Apr 14 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+
+// KDE includes
+#include <klistview.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <kmessagebox.h>
+#include <kurlrequester.h>
+
+// system specific includes
+#include <unistd.h>
+#include <sys/types.h>
+
+// application specific includes
+#include "smb4kconfigdialog.h"
+#include "smb4kuserinterfaceoptions.h"
+#include "smb4knetworkoptions.h"
+#include "smb4kshareoptions.h"
+#include "smb4kauthoptions.h"
+#include "smb4ksuperuseroptions.h"
+#include "smb4ksambaoptions.h"
+#include "smb4krsyncoptions.h"
+#include "../core/smb4ksettings.h"
+#include "../core/smb4kglobal.h"
+#include "../core/smb4ksambaoptionsinfo.h"
+#include "../core/smb4ksambaoptionshandler.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4kauthinfo.h"
+#include "../core/smb4kpasswordhandler.h"
+
+using namespace Smb4KGlobal;
+
+KInstance *Smb4KConfigDialogFactory::m_instance = 0L;
+KAboutData *Smb4KConfigDialogFactory::m_about = 0L;
+
+// Variables we need to determine if super user entries
+// have to be written to /etc/sudoers or /etc/super.tab
+bool use_sudo = false;
+bool use_super = false;
+#ifdef __linux__
+bool force_unmount = false;
+#endif
+bool always_use_su = false;
+
+// Use this variable to determine if the dialog should be
+// closed after Smb4KFileIO::finished() was emitted.
+bool close_dialog = false;
+
+
+Smb4KConfigDialog::Smb4KConfigDialog( Smb4KSettings *settings, QWidget *parent, const char *name )
+: KConfigDialog( parent, name, settings )
+{
+ // FIXME: I guess, normally we would not need to close destructively,
+ // but at the moment there are issues with the KURLRequester in file
+ // mode. To work around those, we are closing the dialog destructively.
+ // Maybe we can remove this if we moved to KDE4.
+ setWFlags( Qt::WDestructiveClose );
+
+ // Add the pages:
+ Smb4KUserInterfaceOptions *interface_options = new Smb4KUserInterfaceOptions( this, "UserInterfaceOptions" );
+ Smb4KNetworkOptions* network_options = new Smb4KNetworkOptions( this, "NetworkOptions" );
+ Smb4KShareOptions *share_options= new Smb4KShareOptions( this, "ShareOptions" );
+ Smb4KAuthOptions *auth_options = new Smb4KAuthOptions( this, "AuthenticationOptions" );
+ Smb4KSambaOptions *samba_options = new Smb4KSambaOptions( this, "SambaOptions" );
+ Smb4KRsyncOptions *rsync_options = new Smb4KRsyncOptions( this, "SynchronizationOptions" );
+ Smb4KSuperUserOptions *super_user_options = new Smb4KSuperUserOptions( this, "SuperUserOptions" );
+
+ // Disable widgets if the respective programs are not installed.
+ if ( Smb4KSettings::rsync().isEmpty() )
+ {
+ rsync_options->setEnabled( false );
+ }
+
+ if ( Smb4KSettings::sudo().isEmpty() && Smb4KSettings::super().isEmpty() )
+ {
+ super_user_options->setEnabled( false );
+ }
+ else
+ {
+ // The search for the programs and all related actions have been
+ // done by the core. We only need to disable widgets here.
+ if ( Smb4KSettings::sudo().isEmpty() )
+ {
+ QRadioButton *sudo = static_cast<QRadioButton *>( super_user_options->child( "SudoButton", "QRadioButton", true ) );
+
+ if ( sudo )
+ {
+ sudo->setEnabled( false );
+ }
+ }
+ else if ( Smb4KSettings::super().isEmpty() )
+ {
+ QRadioButton *super = static_cast<QRadioButton *>( super_user_options->child( "SuperButton", "QRadioButton", true ) );
+
+ if ( super )
+ {
+ super->setEnabled( false );
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+
+ // There are a few settings we need to the initial values of.
+ // Initialize them here:
+ switch ( Smb4KSettings::superUserProgram() )
+ {
+ case Smb4KSettings::EnumSuperUserProgram::Sudo:
+ {
+ use_sudo = true;
+
+ break;
+ }
+ case Smb4KSettings::EnumSuperUserProgram::Super:
+ {
+ use_super = true;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+
+#ifdef __linux__
+ force_unmount = Smb4KSettings::useForceUnmount();
+#endif
+ always_use_su = Smb4KSettings::alwaysUseSuperUser();
+
+ // Now add the pages to the configuration dialog
+ addPage( interface_options, i18n( "User Interface" ), "view_choose" );
+ addPage( network_options, i18n( "Network" ), "network" );
+ addPage( share_options, i18n( "Shares" ), "hdd_mount" );
+ addPage( auth_options, i18n( "Authentication" ), "identity" );
+ addPage( samba_options, i18n( "Samba" ), "samba" );
+ addPage( rsync_options, i18n( "Synchronization" ), "bottom" );
+ addPage( super_user_options, i18n( "Super User" ), "penguin" );
+
+ // Stuff that's not managed by KConfig XT is loaded by
+ // Smb4KConfigDialog::showEvent()!
+
+ // Resize the dialog
+ setInitialSize( configDialogSize( *(Smb4KSettings::self()->config()), "ConfigDialog" ) );
+
+ // Connections
+ connect( samba_options, SIGNAL( customSettingsChanged() ),
+ this, SLOT( slotCustomSambaSettingsChanged() ) );
+
+ connect( super_user_options, SIGNAL( removeEntries() ),
+ this, SLOT( slotRemoveSuperUserEntries() ) );
+
+ connect( Smb4KCore::fileIO(), SIGNAL( failed() ),
+ this, SLOT( slotReceivedFileIOFailed() ) );
+
+ connect( Smb4KCore::fileIO(), SIGNAL( finished() ),
+ this, SLOT( slotReceivedFileIOFinished() ) );
+}
+
+
+Smb4KConfigDialog::~Smb4KConfigDialog()
+{
+}
+
+
+void Smb4KConfigDialog::loadCustomSambaOptions()
+{
+ // Get the list view:
+ KListView *custom_list = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( !custom_list )
+ {
+ return;
+ }
+
+ // First of all clear the list view:
+ custom_list->clear();
+
+ // Now get the default values:
+ QString default_filesystem, protocol_hint, default_uid, default_gid;
+ bool write_access = true;
+
+ switch( Smb4KSettings::filesystem() )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ default_filesystem = "cifs";
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ default_filesystem = "smbfs";
+
+ break;
+ }
+ default:
+ {
+ // FIXME: Set default_filesystem to "cifs"?
+ break;
+ }
+ }
+
+ switch ( Smb4KSettings::protocolHint() )
+ {
+ case Smb4KSettings::EnumProtocolHint::Automatic:
+ {
+ // In this case the user leaves it to the net
+ // command to determine the right protocol.
+ protocol_hint = QString::null;
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RPC:
+ {
+ protocol_hint = "rpc";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RAP:
+ {
+ protocol_hint = "rap";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::ADS:
+ {
+ protocol_hint = "ads";
+
+ break;
+ }
+ default:
+ {
+ protocol_hint = QString::null;
+
+ break;
+ }
+ }
+
+ switch( Smb4KSettings::writeAccess() )
+ {
+ case Smb4KSettings::EnumWriteAccess::ReadWrite:
+ {
+ write_access = true;
+
+ break;
+ }
+ case Smb4KSettings::EnumWriteAccess::ReadOnly:
+ {
+ write_access = false;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ const QValueList<Smb4KSambaOptionsInfo *> &list = optionsHandler()->customOptionsList();
+
+ for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = list.begin();
+ it != list.end(); ++it )
+ {
+ // If the only modification is that the share is to be remounted,
+ // we will not put it into the list:
+ if ( (*it)->type() == Smb4KSambaOptionsInfo::Share &&
+ (*it)->remount() &&
+ (*it)->port() == Smb4KSettings::remotePort() &&
+#ifndef __FreeBSD__
+ QString::compare( (*it)->filesystem(), default_filesystem ) == 0 &&
+ (*it)->writeAccess() == write_access &&
+ (*it)->kerberos() == Smb4KSettings::useKerberos() /* FreeBSD does not know Kerberos for mounting */ &&
+#endif
+ ((QString::compare( default_filesystem, "cifs" ) == 0 && (*it)->uid().toInt() == (int)getuid()) ||
+ (!(*it)->uid().isEmpty() && QString::compare( (*it)->uid(), Smb4KSettings::userID() ) == 0)) &&
+ ((QString::compare( default_filesystem, "cifs" ) == 0 && (*it)->gid().toInt() == (int)getgid()) ||
+ (!(*it)->gid().isEmpty() && QString::compare( (*it)->gid(), Smb4KSettings::groupID() ) == 0)) )
+ {
+ continue;
+ }
+
+ // Now put the item in the list:
+ KListViewItem *item = new KListViewItem( custom_list );
+
+ item->setText( Smb4KSambaOptions::ItemName, (*it)->itemName() );
+
+ item->setText( Smb4KSambaOptions::Port, ((*it)->port() != -1 ?
+ QString( "%1" ).arg( (*it)->port() ) :
+ QString( "%1" ).arg( Smb4KSettings::remotePort() )) );
+
+ switch ( (*it)->type() )
+ {
+ case Smb4KSambaOptionsInfo::Host:
+ {
+ item->setText( Smb4KSambaOptions::Protocol, !(*it)->protocol().isEmpty() ?
+ (QString::compare( (*it)->protocol(), "auto" ) == 0 ? i18n( "auto" ) : (*it)->protocol().upper()) :
+ (protocol_hint.isEmpty() ? i18n( "auto" ) : protocol_hint.upper()) );
+
+ item->setText( Smb4KSambaOptions::Kerberos, (*it)->kerberos() ?
+ i18n( "yes" ) :
+ i18n( "no" ) );
+
+#ifndef __FreeBSD__
+ item->setText( Smb4KSambaOptions::FileSystem, "-" );
+
+ item->setText( Smb4KSambaOptions::WriteAccess, "-" );
+#endif
+
+ item->setText( Smb4KSambaOptions::UID, "-" );
+
+ item->setText( Smb4KSambaOptions::GID, "-" );
+
+ break;
+ }
+ case Smb4KSambaOptionsInfo::Share:
+ {
+ item->setText( Smb4KSambaOptions::Protocol, "-" );
+
+#ifndef __FreeBSD__
+ item->setText( Smb4KSambaOptions::Kerberos, (*it)->kerberos() ?
+ i18n( "yes" ) :
+ i18n( "no" ) );
+
+ item->setText( Smb4KSambaOptions::FileSystem, !(*it)->filesystem().isEmpty() ?
+ (*it)->filesystem().upper() :
+ default_filesystem.upper() );
+
+ item->setText( Smb4KSambaOptions::WriteAccess, (*it)->writeAccess() ?
+ i18n( "read-write" ) :
+ i18n( "read-only" ) );
+#else
+ // FreeBSD does not know Kerberos for mounting
+ item->setText( Smb4KSambaOptions::Kerberos, "-" );
+#endif
+ item->setText( Smb4KSambaOptions::UID, !(*it)->uid().isEmpty() ?
+ (*it)->uid() :
+ Smb4KSettings::userID() );
+
+ item->setText( Smb4KSambaOptions::GID, !(*it)->gid().isEmpty() ?
+ (*it)->gid() :
+ Smb4KSettings::groupID() );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ Smb4KSambaOptions *samba_options = static_cast<Smb4KSambaOptions *>( child( "SambaOptions", "Smb4KSambaOptions", true ) );
+
+ if ( samba_options )
+ {
+ samba_options->resetCustomTab();
+ }
+}
+
+
+void Smb4KConfigDialog::saveCustomSambaOptions()
+{
+ // Get the list view:
+ KListView *custom_list = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( !custom_list )
+ {
+ return;
+ }
+
+ if ( custom_list->childCount() != 0 )
+ {
+ // First remove all items that have been deleted in the
+ // configuration dialog:
+ QValueList<Smb4KSambaOptionsInfo *> list = optionsHandler()->customOptionsList();
+
+ for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !custom_list->findItem( (*it)->itemName(), Smb4KSambaOptions::ItemName ) )
+ {
+ optionsHandler()->removeItem( (*it)->itemName(), false );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ // Now updated the remaining items:
+ QListViewItemIterator it( custom_list );
+
+ while ( it.current() )
+ {
+ QListViewItem *item = it.current();
+
+ Smb4KSambaOptionsInfo *info = optionsHandler()->findItem( item->text( Smb4KSambaOptions::ItemName ) );
+
+ if ( info )
+ {
+ switch( info->type() )
+ {
+ case Smb4KSambaOptionsInfo::Host:
+ {
+ info->setProtocol( (QString::compare( item->text( Smb4KSambaOptions::Protocol ), "-" ) != 0 ?
+ item->text( Smb4KSambaOptions::Protocol ).lower() :
+ QString::null) );
+
+ info->setKerberos( (QString::compare( item->text( Smb4KSambaOptions::Kerberos ), i18n( "yes" ) ) == 0) );
+
+ info->setPort( item->text( Smb4KSambaOptions::Port ).toInt() );
+
+ break;
+ }
+ case Smb4KSambaOptionsInfo::Share:
+ {
+#ifndef __FreeBSD__
+ // FreeBSD does not know Kerberos for mounting
+ info->setKerberos( (QString::compare( item->text( Smb4KSambaOptions::Kerberos ), i18n( "yes" ) ) == 0) );
+
+ info->setFilesystem( (QString::compare( item->text( Smb4KSambaOptions::FileSystem ), "-" ) != 0 ?
+ item->text( Smb4KSambaOptions::FileSystem ).lower() :
+ QString::null) );
+
+ info->setWriteAccess( (QString::compare( item->text( Smb4KSambaOptions::WriteAccess ),
+ i18n( "read-write" ) ) == 0) );
+#endif
+ info->setUID( (QString::compare( item->text( Smb4KSambaOptions::UID ), i18n( "default" ) ) != 0 &&
+ QString::compare( item->text( Smb4KSambaOptions::UID ), "-" ) != 0) ?
+ item->text( Smb4KSambaOptions::UID ) :
+ QString::null );
+
+ info->setGID( (QString::compare( item->text( Smb4KSambaOptions::GID ), i18n( "default" ) ) != 0 &&
+ QString::compare( item->text( Smb4KSambaOptions::GID ), "-" ) != 0) ?
+ item->text( Smb4KSambaOptions::GID ) :
+ QString::null );
+
+ info->setPort( item->text( Smb4KSambaOptions::Port ).toInt() );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ // We do not have this case.
+ }
+
+ ++it;
+ }
+ }
+ else
+ {
+ // Remove all items, if the list view is empty:
+ QValueList<Smb4KSambaOptionsInfo *> list = optionsHandler()->customOptionsList();
+
+ for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it)->remount() )
+ {
+ optionsHandler()->removeItem( (*it)->itemName(), false );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ optionsHandler()->sync();
+}
+
+
+void Smb4KConfigDialog::loadAuthenticationData()
+{
+ // Load the default login info and put it into the configuration
+ // page:
+ Smb4KAuthInfo auth( QString::null, QString::null, QString::null );
+
+ (void) passwordHandler()->readDefaultAuth( &auth );
+
+ KLineEdit *default_user = static_cast<KLineEdit *>( child( "DefaultUserName", "KLineEdit", true ) );
+
+ if ( default_user )
+ {
+ default_user->setText( auth.user() );
+ }
+
+ KLineEdit *default_pass = static_cast<KLineEdit *>( child( "DefaultPassword", "KLineEdit", true ) );
+
+ if ( default_pass )
+ {
+ default_pass->setText( auth.password() );
+ }
+}
+
+
+void Smb4KConfigDialog::saveAuthenticationData()
+{
+ // Read the default login info from the configuration page
+ // and pass it to the password handler, but only if the wallet
+ // is open at this time. Otherwise we could end up with empty
+ // entries:
+ if ( passwordHandler()->walletIsOpen() )
+ {
+ Smb4KAuthInfo auth( QString::null, QString::null, QString::null );
+
+ KLineEdit *default_user = static_cast<KLineEdit *>( child( "DefaultUserName", "KLineEdit", true ) );
+
+ if ( default_user )
+ {
+ auth.setUser( default_user->text() );
+ }
+
+ KLineEdit *default_pass = static_cast<KLineEdit *>( child( "DefaultPassword", "KLineEdit", true ) );
+
+ if ( default_pass )
+ {
+ auth.setPassword( default_pass->text() );
+ }
+
+ passwordHandler()->writeDefaultAuth( &auth );
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+bool Smb4KConfigDialog::writeSuperUserEntries()
+{
+ QRadioButton *sudo = static_cast<QRadioButton *>( child( "SudoButton", "QRadioButton", true ) );
+ QRadioButton *super = static_cast<QRadioButton *>( child( "SuperButton", "QRadioButton", true ) );
+#ifdef __linux__
+ QCheckBox *force = static_cast<QCheckBox *>( child( "kcfg_UseForceUnmount", "QCheckBox", true ) );
+#endif
+ QCheckBox *full_use = static_cast<QCheckBox *>( child( "kcfg_AlwaysUseSuperUser", "QCheckBox", true ) );
+
+ // Check if we need to write anything at all:
+ Smb4KFileIO::Operation op = Smb4KFileIO::NoOperation;
+ bool success = true;
+
+#ifdef __linux__
+ if ( sudo && super && force && full_use )
+#else
+ if ( sudo && super && full_use )
+#endif
+ {
+ if ( sudo->isChecked() )
+ {
+#ifdef __linux__
+ if ( (!use_sudo && (force->isChecked() || full_use->isChecked())) ||
+ (use_sudo &&
+ ((force->isChecked() && force_unmount != force->isChecked()) ||
+ (full_use->isChecked() && always_use_su != full_use->isChecked()))) )
+#else
+ if ( (!use_sudo && full_use->isChecked()) ||
+ (use_sudo &&
+ (full_use->isChecked() && always_use_su != full_use->isChecked())) )
+#endif
+ {
+ success = Smb4KCore::fileIO()->writeSudoers( (op = Smb4KFileIO::Insert) );
+ }
+ }
+ else if ( super->isChecked() )
+ {
+#ifdef __linux__
+ if ( (!use_super && (force->isChecked() || full_use->isChecked())) ||
+ (use_super &&
+ ((force->isChecked() && force_unmount != force->isChecked()) ||
+ (full_use->isChecked() && always_use_su != full_use->isChecked()))) )
+#else
+ if ( (!use_super && full_use->isChecked()) ||
+ (use_super &&
+ (full_use->isChecked() && always_use_su != full_use->isChecked())) )
+#endif
+ {
+ success = Smb4KCore::fileIO()->writeSuperTab( (op = Smb4KFileIO::Insert) );
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ use_sudo = sudo->isChecked();
+ use_super = super->isChecked();
+#ifdef __linux__
+ force_unmount = force->isChecked();
+#endif
+ always_use_su = full_use->isChecked();
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ return (!success || op == Smb4KFileIO::NoOperation) ? false : true;
+}
+
+
+void Smb4KConfigDialog::removeSuperUserEntries()
+{
+ QRadioButton *sudo = static_cast<QRadioButton *>( child( "SudoButton", "QRadioButton", true ) );
+ QRadioButton *super = static_cast<QRadioButton *>( child( "SuperButton", "QRadioButton", true ) );
+#ifdef __linux__
+ QCheckBox *force = static_cast<QCheckBox *>( child( "kcfg_UseForceUnmount", "QCheckBox", true ) );
+#endif
+ QCheckBox *full_use = static_cast<QCheckBox *>( child( "kcfg_AlwaysUseSuperUser", "QCheckBox", true ) );
+
+#ifdef __linux__
+ if ( sudo && super && force && full_use )
+#else
+ if ( sudo && super && full_use )
+#endif
+
+ {
+ if ( sudo->isChecked() )
+ {
+ Smb4KCore::fileIO()->writeSudoers( Smb4KFileIO::Remove );
+ }
+ else if ( super->isChecked() )
+ {
+ Smb4KCore::fileIO()->writeSuperTab( Smb4KFileIO::Remove );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+#ifdef __linux__
+ force->setChecked( false );
+#endif
+ full_use->setChecked( false );
+
+ use_sudo = sudo->isChecked();
+ use_super = super->isChecked();
+#ifdef __linux__
+ force_unmount = force->isChecked();
+#endif
+ always_use_su = full_use->isChecked();
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+bool Smb4KConfigDialog::checkSettings()
+{
+ bool ok = true;
+ QString issues = QString::null;
+ int index = 0;
+
+ // If the user chose "Query custom master browser" in the
+ // "Network" tab, there must be a master browser present:
+ QRadioButton *query_custom_master = static_cast<QRadioButton *>( child( "CustomMasterBrowserLabel", "QRadioButton", true ) );
+ KLineEdit *custom_master_input = static_cast<KLineEdit *>( child( "kcfg_CustomMasterBrowser", "KLineEdit", true ) );
+
+ if ( query_custom_master && custom_master_input &&
+ query_custom_master->isChecked() &&
+ custom_master_input->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Network] The custom master browser has not been entered.\n" ) );
+ }
+
+ // If the user chose "Scan broadcast areas" in the
+ // "Network" tab, there must broadcast areas present:
+ QRadioButton *scan_bcast_areas = static_cast<QRadioButton *>( child( "BroadcastAreasLabel", "QRadioButton", true ) );
+ KLineEdit *bcast_areas_input = static_cast<KLineEdit *>( child( "kcfg_BroadcastAreas", "KLineEdit", true ) );
+
+ if ( scan_bcast_areas && bcast_areas_input &&
+ scan_bcast_areas->isChecked() &&
+ bcast_areas_input->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Network] The broadcast areas have not been entered.\n" ) );
+ }
+
+ // The mount prefix must not be empty:
+ KURLRequester *mount_prefix = static_cast<KURLRequester *>( child( "kcfg_MountPrefix", "KURLRequester", true ) );
+
+ if ( mount_prefix && mount_prefix->url().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Shares] The mount prefix is empty.\n" ) );
+ }
+
+ // If the user wants to use a default login, the user
+ // name must not be empty.
+ QCheckBox *use_default_login = static_cast<QCheckBox *>( child( "kcfg_UseDefaultLogin", "QCheckBox", true ) );
+ KLineEdit *default_user_name = static_cast<KLineEdit *>( child( "kcfg_DefaultUserName", "KLineEdit", true ) );
+
+ if ( use_default_login && default_user_name &&
+ use_default_login->isChecked() &&
+ default_user_name->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Authentication] The default user name has not been entered.\n" ) );
+ }
+
+ // The file mask must not be empty.
+ KLineEdit *file_mask = static_cast<KLineEdit *>( child( "kcfg_FileMask", "KLineEdit", true ) );
+
+ if ( file_mask && file_mask->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Samba] The file mask is empty.\n" ) );
+ }
+
+ // The directory mask must not be empty.
+ KLineEdit *directory_mask = static_cast<KLineEdit *>( child( "kcfg_DirectoryMask", "KLineEdit", true ) );
+
+ if ( directory_mask && directory_mask->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Samba] The directory mask is empty.\n" ) );
+ }
+
+ // The UID must not be empty.
+ KLineEdit *user_id = static_cast<KLineEdit *>( child( "kcfg_UserID", "KLineEdit", true ) );
+
+ if ( user_id && user_id->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Samba] The UID is empty.\n" ) );
+ }
+
+ // The GID must not be empty.
+ KLineEdit *group_id = static_cast<KLineEdit *>( child( "kcfg_GroupID", "KLineEdit", true ) );
+
+ if ( group_id && group_id->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Samba] The GID is empty.\n" ) );
+ }
+
+ // The rsync prefix must not be empty.
+ KURLRequester *rsync_prefix = static_cast<KURLRequester *>( child( "kcfg_RsyncPrefix", "KURLRequester", true ) );
+
+ if ( rsync_prefix && rsync_prefix->url().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The rsync prefix is empty.\n" ) );
+ }
+
+ // The path where to store partial files must not be empty.
+ QCheckBox *use_partical_directory = static_cast<QCheckBox *>( child( "kcfg_UsePartialDirectory", "QCheckBox", true ) );
+ KURLRequester *partial_directory = static_cast<KURLRequester *>( child( "kcfg_PartialDirectory", "KURLRequester", true ) );
+
+ if ( use_partical_directory && use_partical_directory->isChecked() &&
+ partial_directory && partial_directory->url().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The directory where partially transferred files should be stored is empty.\n" ) );
+ }
+
+ // The the exclude patterns must not be empty.
+ QCheckBox *use_exclude_pattern = static_cast<QCheckBox *>( child( "kcfg_UseExcludePattern", "QCheckBox", true ) );
+ KLineEdit *exclude_pattern = static_cast<KLineEdit *>( child( "kcfg_ExcludePattern", "KLineEdit", true ) );
+
+ if ( use_exclude_pattern && use_exclude_pattern->isChecked() &&
+ exclude_pattern && exclude_pattern->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The exclude patterns have not been entered.\n" ) );
+ }
+
+ // The the path of the exclude file must not be empty.
+ QCheckBox *use_exclude_file = static_cast<QCheckBox *>( child( "kcfg_UseExcludeFrom", "QCheckBox", true ) );
+ KURLRequester *exclude_file = static_cast<KURLRequester *>( child( "kcfg_ExcludeFrom", "KURLRequester", true ) );
+
+ if ( use_exclude_file && use_exclude_file->isChecked() &&
+ exclude_file && exclude_file->url().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The path of the exclude file is empty.\n" ) );
+ }
+
+ // The the include patterns must not be empty.
+ QCheckBox *use_include_pattern = static_cast<QCheckBox *>( child( "kcfg_UseIncludePattern", "QCheckBox", true ) );
+ KLineEdit *include_pattern = static_cast<KLineEdit *>( child( "kcfg_IncludePattern", "KLineEdit", true ) );
+
+ if ( use_include_pattern && use_include_pattern->isChecked() &&
+ include_pattern && include_pattern->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The include patterns have not been entered.\n" ) );
+ }
+
+ // The the path of the exclude file must not be empty.
+ QCheckBox *use_include_file = static_cast<QCheckBox *>( child( "kcfg_UseIncludeFrom", "QCheckBox", true ) );
+ KURLRequester *include_file = static_cast<KURLRequester *>( child( "kcfg_IncludeFrom", "KURLRequester", true ) );
+
+ if ( use_include_file && use_include_file->isChecked() &&
+ include_file && include_file->url().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The path of the include file is empty.\n" ) );
+ }
+
+ // If you make backups, check that the suffix and that the
+ // backup directory is not empty.
+ QCheckBox *make_backups = static_cast<QCheckBox *>( child( "kcfg_MakeBackups", "QCheckBox", true ) );
+
+ if ( make_backups && make_backups->isChecked() )
+ {
+ // The backup suffix must not be empty.
+ QCheckBox *use_backup_suffix = static_cast<QCheckBox *>( child( "kcfg_UseBackupSuffix", "QCheckBox", true ) );
+ KLineEdit *backup_suffix = static_cast<KLineEdit *>( child( "kcfg_BackupSuffix", "KLineEdit", true ) );
+
+ if ( use_backup_suffix && use_backup_suffix->isChecked() &&
+ backup_suffix && backup_suffix->text().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The backup suffix has not been defined.\n" ) );
+ }
+
+ // The the path for backups must not be empty.
+ QCheckBox *use_backup_dir = static_cast<QCheckBox *>( child( "kcfg_UseBackupDirectory", "QCheckBox", true ) );
+ KURLRequester *backup_dir = static_cast<KURLRequester *>( child( "kcfg_BackupDirectory", "KURLRequester", true ) );
+
+ if ( use_backup_dir && use_backup_dir->isChecked() &&
+ backup_dir && backup_dir->url().stripWhiteSpace().isEmpty() )
+ {
+ ok = false;
+ index++;
+
+ issues.append( "* "+i18n( "[Synchronization] The backup directory is empty.\n" ) );
+ }
+ }
+
+ if ( !ok )
+ {
+ if ( index == 1 )
+ {
+ KMessageBox::error( this, i18n( "The configuration could not be written, because one setting is incomplete:\n%1Please correct this issue." ).arg( issues ) );
+ }
+ else
+ {
+ KMessageBox::error( this, i18n( "The configuration could not be written, because %1 settings are incomplete:\n%1Please correct these issues." ).arg( index ).arg( issues ) );
+ }
+ }
+
+ return ok;
+}
+
+
+void Smb4KConfigDialog::showEvent( QShowEvent *e )
+{
+ // Spontaneous show events come from outside the application.
+ // We do not want to react on them.
+ if ( !e->spontaneous() )
+ {
+ loadCustomSambaOptions();
+ loadAuthenticationData();
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KConfigDialog::slotApply()
+{
+ // If some settings are not complete, stop here and give
+ // the user the opportunity to fill in the needed string(s).
+ if ( !checkSettings() )
+ {
+ return;
+ }
+
+ saveCustomSambaOptions();
+ saveAuthenticationData();
+
+ if ( writeSuperUserEntries() )
+ {
+ // Disable this widget until Smb4KFileIO::finished()
+ // is received.
+ setEnabled( false );
+ }
+
+ // The 'Apply' button will be disabled by KConfigDialog, so we do not
+ // need to do it here.
+
+ KConfigDialog::slotApply();
+}
+
+
+void Smb4KConfigDialog::slotOk()
+{
+ // If some settings are not complete, stop here and give
+ // the user the opportunity to fill in the needed string(s).
+ if ( !checkSettings() )
+ {
+ return;
+ }
+
+ saveCustomSambaOptions();
+ saveAuthenticationData();
+
+ saveDialogSize( *(Smb4KSettings::self()->config()), "ConfigDialog" );
+
+ // If the something needs to be written to either /etc/super.tab
+ // or /etc/sudoers, do not close the dialog but wait until the
+ // Smb4KFileIO::finished() signal is received.
+ if ( !writeSuperUserEntries() )
+ {
+ KConfigDialog::slotOk();
+ }
+ else
+ {
+ // Disable this widget until Smb4KFileIO::finished()
+ // is received.
+ setEnabled( false );
+
+ // Tell Smb4KConfigDialog::slotReceivedFileIOFinished()
+ // to close the dialog.
+ close_dialog = true;
+ }
+}
+
+
+void Smb4KConfigDialog::slotCancel()
+{
+ // Reset the custom Samba options tab:
+ Smb4KSambaOptions *samba_options = static_cast<Smb4KSambaOptions *>( child( "SambaOptions", "Smb4KSambaOptions", true ) );
+
+ if ( samba_options )
+ {
+ samba_options->resetCustomTab();
+ }
+
+ KConfigDialog::slotCancel();
+}
+
+
+void Smb4KConfigDialog::slotCustomSambaSettingsChanged()
+{
+ // Get the list view and all other input widgets:
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( !view )
+ {
+ return;
+ }
+
+ // Get the list of custom options:
+ QValueList<Smb4KSambaOptionsInfo *> list = optionsHandler()->customOptionsList();
+
+ bool changed = false;
+
+ // Loop through the list view items to see what changed and if
+ // we need to enable the 'Apply' button:
+ for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = list.begin();
+ it != list.end(); ++it )
+ {
+ // Find the item in the list view:
+ QListViewItem *item = view->findItem( (*it)->itemName(), Smb4KSambaOptions::ItemName );
+
+ if ( item )
+ {
+ if ( (*it)->type() == Smb4KSambaOptionsInfo::Host )
+ {
+ // Check if the protocol changed.
+ if ( ((*it)->protocol().isEmpty() &&
+ QString::compare( item->text( Smb4KSambaOptions::Protocol ).lower(), i18n( "auto" ) ) != 0) ||
+ QString::compare( (*it)->protocol(), item->text( Smb4KSambaOptions::Protocol ).lower() ) != 0 )
+ {
+ changed = true;
+
+ break;
+ }
+ }
+ else if ( (*it)->type() == Smb4KSambaOptionsInfo::Share )
+ {
+#ifndef __FreeBSD__
+ // Check if the file system changed.
+ if ( QString::compare( (*it)->filesystem(), item->text( Smb4KSambaOptions::FileSystem ).lower() ) != 0 )
+ {
+ changed = true;
+
+ break;
+ }
+
+ // Check if the write access changed.
+ QString write_access = (*it)->writeAccess() ?
+ i18n( "read-write" ) :
+ i18n( "read-only" );
+
+ if ( QString::compare( write_access, item->text( Smb4KSambaOptions::WriteAccess ) ) != 0 )
+ {
+ changed = true;
+
+ break;
+ }
+#endif
+ // Check if the UID changed.
+ if ( ((*it)->uid().isEmpty() &&
+ QString::compare( i18n( "default" ), item->text( Smb4KSambaOptions::UID ) ) != 0) ||
+ QString::compare( (*it)->uid(), item->text( Smb4KSambaOptions::UID ) ) != 0 )
+ {
+ changed = true;
+
+ break;
+ }
+
+ // Check if the GID changed.
+ if ( ((*it)->gid().isEmpty() &&
+ QString::compare( i18n( "default" ), item->text( Smb4KSambaOptions::GID ) ) != 0) ||
+ QString::compare( (*it)->gid(), item->text( Smb4KSambaOptions::GID ) ) != 0 )
+ {
+ changed = true;
+
+ break;
+ }
+ }
+ else
+ {
+ // Something went wrong. Stop right here.
+ break;
+ }
+
+ // Check if the Kerberos entry changed.
+ QString kerberos = (*it)->kerberos() ?
+ i18n( "yes" ) :
+ i18n( "no" );
+
+ if ( QString::compare( kerberos, item->text( Smb4KSambaOptions::Kerberos ) ) != 0 )
+ {
+ changed = true;
+
+ break;
+ }
+
+ // Check if the port value changed.
+ if ( (*it)->port() != item->text( Smb4KSambaOptions::Port ).toInt() )
+ {
+ changed = true;
+
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ enableButtonApply( changed );
+}
+
+
+void Smb4KConfigDialog::slotRemoveSuperUserEntries()
+{
+ // Disable this widget until Smb4KFileIO::finished()
+ // is received.
+ setEnabled( false );
+
+ removeSuperUserEntries();
+}
+
+
+void Smb4KConfigDialog::slotReceivedFileIOFailed()
+{
+#ifdef __linux__
+ QCheckBox *force = static_cast<QCheckBox *>( child( "kcfg_UseForceUnmount", "QCheckBox", true ) );
+#endif
+ QCheckBox *full_use = static_cast<QCheckBox *>( child( "kcfg_AlwaysUseSuperUser", "QCheckBox", true ) );
+
+#ifdef __linux__
+ if ( force && full_use )
+ {
+ force->setChecked( false );
+#else
+ if ( full_use )
+ {
+#endif
+ full_use->setChecked( false );
+ }
+}
+
+
+void Smb4KConfigDialog::slotReceivedFileIOFinished()
+{
+ // Enable the widget again.
+ setEnabled( true );
+
+ if ( close_dialog )
+ {
+ KConfigDialog::slotOk();
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// FACTORY STUFF
+/////////////////////////////////////////////////////////////////////////////
+
+Smb4KConfigDialogFactory::Smb4KConfigDialogFactory()
+: KLibFactory()
+{
+}
+
+
+Smb4KConfigDialogFactory::~Smb4KConfigDialogFactory()
+{
+ delete m_instance;
+ delete m_about;
+
+ m_instance = 0L;
+}
+
+
+KInstance *Smb4KConfigDialogFactory::instance()
+{
+ if( !m_instance )
+ {
+ m_about = new KAboutData( "smb4kconfigdialog", I18N_NOOP( "Smb4KConfigDialog" ), "1.0" );
+ m_about->addAuthor("Alexander Reinholdt", 0, "[email protected]");
+ m_about->setLicense( KAboutData::License_GPL );
+ m_instance = new KInstance( m_about );
+ }
+
+ return m_instance;
+}
+
+
+QObject *Smb4KConfigDialogFactory::createObject( QObject *parent, const char *name, const char *,
+const QStringList & )
+{
+ return static_cast<QObject *>( new Smb4KConfigDialog( Smb4KSettings::self(), static_cast<QWidget *>( parent ), name ) );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// INIT
+/////////////////////////////////////////////////////////////////////////////
+
+
+extern "C"
+{
+ void *init_libsmb4kconfigdialog()
+ {
+ KGlobal::locale()->insertCatalogue( "smb4k" );
+ return new Smb4KConfigDialogFactory;
+ }
+}
+
+#include "smb4kconfigdialog.moc"
diff --git a/smb4k/configdlg/smb4kconfigdialog.h b/smb4k/configdlg/smb4kconfigdialog.h
new file mode 100644
index 0000000..8e6f9f8
--- /dev/null
+++ b/smb4k/configdlg/smb4kconfigdialog.h
@@ -0,0 +1,208 @@
+/***************************************************************************
+ smb4kconfigdialog - The configuration dialog of Smb4K
+ -------------------
+ begin : Sa Apr 14 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KCONFIGDIALOG_H
+#define SMB4KCONFIGDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kconfigdialog.h>
+#include <klibloader.h>
+#include <kaboutdata.h>
+#include <kinstance.h>
+
+// forward declarations
+class Smb4KSettings;
+
+/**
+ * This is the (new) configuration dialog of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KConfigDialog : public KConfigDialog
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param settings The Smb4KSettings object that needs to be passed
+ * so that the settings can be managed.
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this dialog
+ */
+ Smb4KConfigDialog( Smb4KSettings *settings, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KConfigDialog();
+
+ protected:
+ /**
+ * Reimplemented from QWidget to do last things before the
+ * configuration dialog is shown.
+ *
+ * @param e The show event object
+ */
+ void showEvent( QShowEvent *e );
+
+ protected slots:
+ /**
+ * Reimplemented from KConfigDialog. This slot does application
+ * specific stuff first and then executes KConfigDialog::slotApply().
+ */
+ void slotApply();
+
+ /**
+ * Reimplemented from KConfigDialog. This slot does application
+ * specific stuff first and then executes KConfigDialog::slotOk().
+ */
+ void slotOk();
+
+ /**
+ *Reimplemented from KConfigDialog. This slot does application
+ * specific stuff first and then executes KConfigDialog::slotCancel().
+ */
+ void slotCancel();
+
+ /**
+ * The custom Samba settings changed. Decide if we have to
+ * enable the 'Apply' button or not.
+ */
+ void slotCustomSambaSettingsChanged();
+
+ /**
+ * The 'Remove Entries' button in the 'Super User' page has been
+ * clicked. Initialize the removal of Smb4K's configuration entries
+ * from the configuration file of the currently chosen program.
+ */
+ void slotRemoveSuperUserEntries();
+
+ /**
+ * This slot is activated if the Smb4KFileIO::failed() signal is
+ * received. It deselects all check boxes in the "Super User" page.
+ */
+ void slotReceivedFileIOFailed();
+
+ /**
+ * This slot is activated if the Smb4KFileIO::finished() signal is
+ * received. It closes the dialog by invoking KConfigDialog::slotOk().
+ */
+ void slotReceivedFileIOFinished();
+
+ private:
+ /**
+ * Load the custom Samba options
+ */
+ void loadCustomSambaOptions();
+
+ /**
+ * Save the custom Samba options
+ */
+ void saveCustomSambaOptions();
+
+ /**
+ * Load the authentication data
+ */
+ void loadAuthenticationData();
+
+ /**
+ * Save the authentication data
+ */
+ void saveAuthenticationData();
+
+ /**
+ * Write super user configuration entries to configuration file.
+ *
+ * @returns TRUE if something needs to be written.
+ */
+ bool writeSuperUserEntries();
+
+ /**
+ * Remove super user configuration entries from the configuration file.
+ */
+ void removeSuperUserEntries();
+
+ /**
+ * Checks that mandatorily needed input is provided for settings that
+ * need it. This function will report all missing input to the user
+ * via a message box.
+ *
+ * @returns TRUE if the check passed and FALSE if it failed.
+ */
+ bool checkSettings();
+};
+
+
+class KInstance;
+class KAboutData;
+
+
+class Smb4KConfigDialogFactory : KLibFactory
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ */
+ Smb4KConfigDialogFactory();
+
+ /**
+ * The destructor.
+ */
+ virtual ~Smb4KConfigDialogFactory();
+
+ /**
+ * The instance
+ */
+ static KInstance *instance();
+
+ protected:
+ QObject *createObject( QObject *parent = 0, const char *name = 0,
+ const char *classname = "QObject",
+ const QStringList &args = QStringList() );
+
+ private:
+ /**
+ * The factory's instance
+ */
+ static KInstance *m_instance;
+
+ /**
+ * The factory's KAboutData object
+ */
+ static KAboutData *m_about;
+};
+
+#endif
diff --git a/smb4k/configdlg/smb4knetworkoptions.cpp b/smb4k/configdlg/smb4knetworkoptions.cpp
new file mode 100644
index 0000000..4c2244b
--- /dev/null
+++ b/smb4k/configdlg/smb4knetworkoptions.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ smb4knetworkoptions - The configuration page for the network
+ settings of Smb4K
+ -------------------
+ begin : Sa Nov 15 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qbuttongroup.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qlabel.h>
+
+// KDE includes
+#include <klocale.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+
+// application specific includes
+#include "smb4knetworkoptions.h"
+#include "../core/smb4ksettings.h"
+
+Smb4KNetworkOptions::Smb4KNetworkOptions( QWidget *parent, const char *name ) : QWidget( parent, name )
+{
+ QGridLayout *grid = new QGridLayout( this );
+ grid->setSpacing( 10 );
+
+ //
+ // The browse list group box.
+ //
+ QButtonGroup *browse_box = new QButtonGroup( 1, Qt::Horizontal, i18n( "Browse List" ),
+ this, "kcfg_BrowseList" );
+
+ browse_box->insert( new QRadioButton( i18n( "Scan the network neighborhood for available workgroups and domains" ),
+ browse_box ), Smb4KSettings::EnumBrowseList::LookupDomains );
+ browse_box->insert( new QRadioButton( i18n( "Query the current workgroup master browser" ),
+ browse_box), Smb4KSettings::EnumBrowseList::QueryCurrentMaster );
+
+ QWidget *buttonWidget = new QWidget( browse_box );
+ QGridLayout *buttonLayout = new QGridLayout( buttonWidget );
+ buttonLayout->setSpacing( 5 );
+
+ QRadioButton *use_host = new QRadioButton( i18n( "Query this master browser:" ),
+ buttonWidget, "CustomMasterBrowserLabel" );
+ KLineEdit *host_name = new KLineEdit( buttonWidget, "kcfg_CustomMasterBrowser" );
+ QRadioButton *use_scan = new QRadioButton( i18n( "Scan broadcast areas:" ),
+ buttonWidget, "BroadcastAreasLabel" );
+ KLineEdit *broadcast_addresses = new KLineEdit( buttonWidget, "kcfg_BroadcastAreas" );
+
+ buttonLayout->addWidget( use_host, 0, 0, 0 );
+ buttonLayout->addWidget( host_name, 0, 1, 0 );
+ buttonLayout->addWidget( use_scan, 1, 0, 0 );
+ buttonLayout->addWidget( broadcast_addresses, 1, 1, 0 );
+
+ browse_box->insert( use_host, Smb4KSettings::EnumBrowseList::QueryCustomMaster );
+ browse_box->insert( use_scan, Smb4KSettings::EnumBrowseList::ScanBroadcastAreas );
+
+ //
+ // The search group box
+ //
+ QButtonGroup *search_box = new QButtonGroup( 1, Qt::Horizontal, i18n( "Network Search" ),
+ this, "kcfg_SearchMethod" );
+ search_box->setInsideSpacing( 5 );
+
+ QLabel *description = new QLabel( search_box );
+ description->setText( i18n( "Smb4K uses \"nmblookup\" by default to search for remote hosts. This method is very reliable but fails sometimes if your network neighborhood is configured uncommonly. In this case you should try to use \"smbclient\"." ) );
+ description->setTextFormat( Qt::RichText );
+
+ search_box->insert( new QRadioButton( i18n( "Use nmblookup (recommended)" ),
+ search_box ), Smb4KSettings::EnumSearchMethod::Nmblookup );
+
+ search_box->insert( new QRadioButton( i18n( "Use smbclient" ),
+ search_box ), Smb4KSettings::EnumSearchMethod::Smbclient );
+
+ QSpacerItem *spacer4 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ grid->addWidget( browse_box, 0, 0, 0 );
+ grid->addWidget( search_box, 1, 0, 0 );
+ grid->addItem( spacer4, 2, 0 );
+}
+
+
+Smb4KNetworkOptions::~Smb4KNetworkOptions()
+{
+}
+
+
+#include "smb4knetworkoptions.moc"
diff --git a/smb4k/configdlg/smb4knetworkoptions.h b/smb4k/configdlg/smb4knetworkoptions.h
new file mode 100644
index 0000000..b3b47f3
--- /dev/null
+++ b/smb4k/configdlg/smb4knetworkoptions.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ smb4knetworkoptions - The configuration page for the network
+ settings of Smb4K
+ -------------------
+ begin : Sa Nov 15 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KNETWORKOPTIONS_H
+#define SMB4KNETWORKOPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qwidget.h>
+
+/**
+ * This is the configuration tab for the network settings
+ * of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KNetworkOptions : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent widget
+ *
+ * @param name The widget's name
+ */
+ Smb4KNetworkOptions( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KNetworkOptions();
+};
+#endif
diff --git a/smb4k/configdlg/smb4krsyncoptions.cpp b/smb4k/configdlg/smb4krsyncoptions.cpp
new file mode 100644
index 0000000..301ee30
--- /dev/null
+++ b/smb4k/configdlg/smb4krsyncoptions.cpp
@@ -0,0 +1,351 @@
+/***************************************************************************
+ smb4ksynchronizeoptions - The configuration page for the rsync options
+ -------------------
+ begin : So Nov 20 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
+#include <knuminput.h>
+#include <klineedit.h>
+#include <kfile.h>
+
+// application specific includes
+#include "smb4krsyncoptions.h"
+
+Smb4KRsyncOptions::Smb4KRsyncOptions( QWidget *parent, const char *name ) : QTabWidget( parent, name )
+{
+ setMargin( 10 );
+
+ //
+ // The Copying tab
+ //
+ QWidget *copying_tab = new QWidget( this, "RsyncCopying" );
+ QGridLayout *copying_layout = new QGridLayout( copying_tab );
+ copying_layout->setSpacing( 10 );
+
+ QGroupBox *directory_box = new QGroupBox( 2, QGroupBox::Horizontal, i18n( "Default Destination" ),
+ copying_tab, "RsyncDestinationBox" );
+ directory_box->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "Rsync prefix:" ), directory_box, "RsyncPrefixLabel" );
+ KURLRequester *prefix = new KURLRequester( directory_box, "kcfg_RsyncPrefix" );
+ prefix->setMode( KFile::Directory | KFile::LocalOnly );
+
+ QButtonGroup *general_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "General" ),
+ copying_tab, "RsyncModeBox" );
+ general_box->setInsideSpacing( 5 );
+
+ QCheckBox *archive_mode = new QCheckBox( i18n( "Archive mode" ), general_box, "kcfg_ArchiveMode" );
+ QCheckBox *recursive = new QCheckBox( i18n( "Recurse into directories" ), general_box, "kcfg_RecurseIntoDirectories" );
+ (void) new QCheckBox( i18n( "Skip files that are newer in target directory" ), general_box, "kcfg_UpdateTarget" );
+ (void) new QCheckBox( i18n( "Update destination files in place" ), general_box, "kcfg_UpdateInPlace" );
+ (void) new QCheckBox( i18n( "Use relative path names" ), general_box, "kcfg_RelativePathNames" );
+ (void) new QCheckBox( i18n( "Don't send implied directories" ), general_box, "kcfg_NoImpliedDirectories" );
+ (void) new QCheckBox( i18n( "Transfer directories without recursing" ), general_box, "kcfg_TransferDirectories" );
+ (void) new QCheckBox( i18n( "Compress data during transfer" ), general_box, "kcfg_CompressData" );
+
+ QButtonGroup *links_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "Links" ), copying_tab, "RsyncModeBox" );
+ links_box->setInsideSpacing( 5 );
+
+ QCheckBox *links = new QCheckBox( i18n( "Preserve symlinks" ), links_box, "kcfg_PreserveSymlinks" );
+ (void) new QCheckBox( i18n( "Transform symlinks" ), links_box, "kcfg_TransformSymlinks" );
+ (void) new QCheckBox( i18n( "Only transform unsafe symlinks" ), links_box, "kcfg_TransformUnsafeSymlinks" );
+ (void) new QCheckBox( i18n( "Ignore unsafe symlinks" ), links_box, "kcfg_IgnoreUnsafeSymlinks" );
+ (void) new QCheckBox( i18n( "Preserve hard links" ), links_box, "kcfg_PreserveHardLinks" );
+ (void) new QCheckBox( i18n( "Keep directory symlinks" ), links_box, "kcfg_KeepDirectorySymlinks" );
+
+ QButtonGroup *perm_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "File Permissions, etc." ),
+ copying_tab, "RsyncPreservationBox" );
+ perm_box->setInsideSpacing( 5 );
+
+ QCheckBox *perms = new QCheckBox( i18n( "Preserve permissions" ), perm_box, "kcfg_PreservePermissions" );
+ QCheckBox *group = new QCheckBox( i18n( "Preserve group" ), perm_box, "kcfg_PreserveGroup" );
+ QCheckBox *owner = new QCheckBox( i18n( "Preserve owner" ), perm_box, "kcfg_PreserveOwner" );
+ QCheckBox *devices = new QCheckBox( i18n( "Preserve device and special files" ), perm_box, "kcfg_PreserveDevicesAndSpecials" );
+ QCheckBox *times = new QCheckBox( i18n( "Preserve times" ), perm_box, "kcfg_PreserveTimes" );
+ (void) new QCheckBox( i18n( "Omit directories when preserving times" ), perm_box, "kcfg_OmitDirectoryTimes" );
+
+ QSpacerItem *spacer1 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ copying_layout->addWidget( directory_box, 0, 0, 0 );
+ copying_layout->addWidget( general_box, 1, 0, 0 );
+ copying_layout->addWidget( links_box, 2, 0, 0 );
+ copying_layout->addWidget( perm_box, 3, 0, 0 );
+ copying_layout->addItem( spacer1, 4, 0 );
+
+ addTab( copying_tab, i18n( "Copying" ) );
+
+
+ //
+ // The File Deletion & Transfer tab
+ //
+ QWidget *deltrans_tab = new QWidget( this, "RsyncFileDeletion" );
+ QGridLayout *deltrans_layout = new QGridLayout( deltrans_tab );
+ deltrans_layout->setSpacing( 10 );
+
+ QButtonGroup *delete_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "File Deletion" ), deltrans_tab, "RsyncDeleteBox" );
+ delete_box->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Remove synchronized source files" ), delete_box, "kcfg_RemoveSourceFiles" );
+ (void) new QCheckBox( i18n( "Delete extraneous files" ), delete_box, "kcfg_DeleteExtraneous" );
+ (void) new QCheckBox( i18n( "Delete files before transfer" ), delete_box, "kcfg_DeleteBefore" );
+ (void) new QCheckBox( i18n( "Delete files after transfer" ), delete_box, "kcfg_DeleteAfter" );
+ (void) new QCheckBox( i18n( "Delete files during transfer" ), delete_box, "kcfg_DeleteDuring" );
+ (void) new QCheckBox( i18n( "Also delete excluded files" ), delete_box, "kcfg_DeleteExcluded" );
+ (void) new QCheckBox( i18n( "Delete even if I/O errors occur" ), delete_box, "kcfg_IgnoreErrors" );
+ (void) new QCheckBox( i18n( "Force deletion of non-void directories" ), delete_box, "kcfg_ForceDirectoryDeletion" );
+
+ QButtonGroup *delete_restrictions_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "Restrictions" ), deltrans_tab, "RsyncDeleteRestrictionsBox" );
+ delete_restrictions_box->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Don't delete more than this many files:" ), delete_restrictions_box, "kcfg_UseMaximumDelete" );
+ (void) new KIntNumInput( delete_restrictions_box, "kcfg_MaximumDeleteValue" );
+
+ QButtonGroup *transfer_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "File Transfer" ),
+ deltrans_tab, "RsyncFileTransferBox" );
+ transfer_box->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Don't transfer any file smaller than:" ), transfer_box, "kcfg_UseMinimalTransferSize" );
+ KIntNumInput *min_size = new KIntNumInput( transfer_box, "kcfg_MinimalTransferSize" );
+ min_size->setSuffix( " kB" );
+ (void) new QCheckBox( i18n( "Don't transfer any file larger than:" ), transfer_box, "kcfg_UseMaximalTransferSize" );
+ KIntNumInput *max_size = new KIntNumInput( transfer_box, "kcfg_MaximalTransferSize" );
+ max_size->setSuffix( " kB" );
+ (void) new QCheckBox( i18n( "Keep partially transferred files" ), transfer_box, "kcfg_KeepPartial" );
+ transfer_box->addSpace( 0 );
+ (void) new QCheckBox( i18n( "Put a partially transferred file into:" ), transfer_box, "kcfg_UsePartialDirectory" );
+ KURLRequester *partial_dir = new KURLRequester( transfer_box, "kcfg_PartialDirectory" );
+ partial_dir->setMode( KFile::Directory | KFile::LocalOnly );
+
+ QSpacerItem *spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ deltrans_layout->addWidget( delete_box, 0, 0, 0 );
+ deltrans_layout->addWidget( delete_restrictions_box, 1, 0, 0 );
+ deltrans_layout->addWidget( transfer_box, 2, 0, 0 );
+ deltrans_layout->addItem( spacer2, 3, 0 );
+
+ addTab( deltrans_tab, i18n( "File Deletion && Transfer" ) );
+
+
+ //
+ // The Filter tab
+ //
+ QWidget *filter_tab = new QWidget( this, "RsyncFiltering" );
+ QGridLayout *filter_layout = new QGridLayout( filter_tab );
+ filter_layout->setSpacing( 10 );
+
+ QButtonGroup *general_filter_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "General" ),
+ filter_tab, "RsyncGeneralFilterBox" );
+ general_filter_box->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Auto-ignore files in the same way CVS does" ), general_filter_box, "kcfg_UseCVSExclude" );
+ general_filter_box->addSpace( 0 );
+ (void) new QCheckBox( i18n( "Exclude files matching this pattern:" ), general_filter_box, "kcfg_UseExcludePattern" );
+ (void) new KLineEdit( general_filter_box, "kcfg_ExcludePattern" );
+ (void) new QCheckBox( i18n( "Read exclude patterns from:" ), general_filter_box, "kcfg_UseExcludeFrom" );
+ KURLRequester *exclude_from = new KURLRequester( general_filter_box, "kcfg_ExcludeFrom" );
+ exclude_from->setMode( KFile::File | KFile::LocalOnly );
+ (void) new QCheckBox( i18n( "Don't exclude files matching this pattern:" ), general_filter_box, "kcfg_UseIncludePattern" );
+ (void) new KLineEdit( general_filter_box, "kcfg_IncludePattern" );
+ (void) new QCheckBox( i18n( "Read include patterns from:" ), general_filter_box, "kcfg_UseIncludeFrom" );
+ KURLRequester *include_from = new KURLRequester( general_filter_box, "kcfg_IncludeFrom" );
+ include_from->setMode( KFile::File | KFile::LocalOnly );
+
+ QButtonGroup *filter_rules_box = new QButtonGroup( 1, QGroupBox::Horizontal, i18n( "Filter Rules" ),
+ filter_tab, "RsyncFilterRulesBox" );
+ filter_rules_box->setInsideSpacing( 5 );
+ QLabel *filter_rules_label = new QLabel( i18n( "The rules defined below will be added to the \"rsync\" command as they are. Thus, you have to start with the --filter=... argument." ), filter_rules_box );
+ filter_rules_label->setTextFormat( Qt::RichText );
+ (void) new KLineEdit( filter_rules_box, "kcfg_CustomFilteringRules" );
+ (void) new QLabel( i18n( "Special filter rules:" ), filter_rules_box );
+ QCheckBox *f_filter = new QCheckBox( i18n( "Use --filter='dir-merge /.rsync-filter' filter rule" ), filter_rules_box, "kcfg_UseFFilterRule" );
+ QCheckBox *ff_filter = new QCheckBox( i18n( "Use --filter='exclude .rsync-filter' filter rule" ), filter_rules_box, "kcfg_UseFFFilterRule" );
+
+ QSpacerItem *spacer3 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ filter_layout->addWidget( general_filter_box, 0, 0, 0 );
+ filter_layout->addWidget( filter_rules_box, 1, 0, 0 );
+ filter_layout->addItem( spacer3, 2, 0 );
+
+ addTab( filter_tab, i18n( "Filtering" ) );
+
+
+ //
+ // The Advanced tab
+ //
+ QWidget *advanced_tab = new QWidget( this, "RsyncAdvanced" );
+ QGridLayout *advanced_layout = new QGridLayout( advanced_tab );
+ advanced_layout->setSpacing( 10 );
+
+ QButtonGroup *misc_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "General" ),
+ advanced_tab, "RsyncAdvancedMiscBox" );
+ misc_box->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Handle sparse files efficiently" ), misc_box, "kcfg_EfficientSparseFileHandling" );
+ (void) new QCheckBox( i18n( "Copy files whole (no rsync algorithm)" ), misc_box, "kcfg_CopyFilesWhole" );
+ (void) new QCheckBox( i18n( "Don't cross file system boundaries" ), misc_box, "kcfg_OneFileSystem" );
+ (void) new QCheckBox( i18n( "Only update files that already exist" ), misc_box, "kcfg_UpdateExisting" );
+ (void) new QCheckBox( i18n( "Ignore files that already exist" ), misc_box, "kcfg_IgnoreExisting" );
+ (void) new QCheckBox( i18n( "Delay updates until the end of transfer" ), misc_box, "kcfg_DelayUpdates" );
+
+ QButtonGroup *backup_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "Backup" ), advanced_tab, "RsyncBackupBox" );
+ backup_box->setInsideSpacing( 5 );
+
+ QCheckBox *backup = new QCheckBox( i18n( "Make backups" ), backup_box, "kcfg_MakeBackups" );
+ backup_box->addSpace( 0 );
+ (void) new QCheckBox( i18n( "Backup suffix:" ), backup_box, "kcfg_UseBackupSuffix" );
+ (void) new KLineEdit( backup_box, "kcfg_BackupSuffix" );
+ (void) new QCheckBox( i18n( "Backup directory:" ), backup_box, "kcfg_UseBackupDirectory" );
+ KURLRequester *backup_dir = new KURLRequester( backup_box, "kcfg_BackupDirectory" );
+ backup_dir->setMode( KFile::Directory | KFile::LocalOnly );
+
+ QButtonGroup *checksum_box = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "Checksums" ), advanced_tab, "RsyncChecksumsBox" );
+ checksum_box->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Force fixed checksum block size:" ), checksum_box, "kcfg_UseBlockSize" );
+ (void) new KIntNumInput( checksum_box, "kcfg_BlockSize" );
+ (void) new QCheckBox( i18n( "Set block/file checksum seed:" ), checksum_box, "kcfg_UseChecksumSeed" );
+ (void) new KIntNumInput( checksum_box, "kcfg_ChecksumSeed" );
+ (void) new QCheckBox( i18n( "Skip files based on checksum" ), checksum_box, "kcfg_UseChecksum" );
+ checksum_box->addSpace( 0 );
+
+ QSpacerItem *spacer4 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ advanced_layout->addWidget( misc_box, 0, 0, 0 );
+ advanced_layout->addWidget( backup_box, 1, 0, 0 );
+ advanced_layout->addWidget( checksum_box, 2, 0, 0 );
+ advanced_layout->addItem( spacer4, 3, 0 );
+
+ addTab( advanced_tab, i18n( "Advanced" ) );
+
+ connect( archive_mode, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotArchiveToggled( bool ) ) );
+
+ connect( recursive, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( links, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( perms, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( times, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( group, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( owner, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( devices, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotUncheckArchive( bool ) ) );
+
+ connect( backup, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotBackupToggled( bool ) ) );
+
+ connect( f_filter, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotFShortcutToggled( bool ) ) );
+
+ connect( ff_filter, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotFFShortcutToggled( bool ) ) );
+
+ slotArchiveToggled( true );
+ slotBackupToggled( false );
+}
+
+
+Smb4KRsyncOptions::~Smb4KRsyncOptions()
+{
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KRsyncOptions::slotArchiveToggled( bool on )
+{
+ if ( on )
+ {
+ static_cast<QCheckBox *>( child( "kcfg_RecurseIntoDirectories", "QCheckBox", true ) )->setChecked( on );
+ static_cast<QCheckBox *>( child( "kcfg_PreserveSymlinks", "QCheckBox", true ) )->setChecked( on );
+ static_cast<QCheckBox *>( child( "kcfg_PreservePermissions", "QCheckBox", true ) )->setChecked( on );
+ static_cast<QCheckBox *>( child( "kcfg_PreserveTimes", "QCheckBox", true ) )->setChecked( on );
+ static_cast<QCheckBox *>( child( "kcfg_PreserveGroup", "QCheckBox", true ) )->setChecked( on );
+ static_cast<QCheckBox *>( child( "kcfg_PreserveOwner", "QCheckBox", true ) )->setChecked( on );
+ static_cast<QCheckBox *>( child( "kcfg_PreserveDevicesAndSpecials", "QCheckBox", true ) )->setChecked( on );
+ }
+}
+
+
+void Smb4KRsyncOptions::slotUncheckArchive( bool on )
+{
+ if ( !on )
+ {
+ static_cast<QCheckBox *>( child( "kcfg_ArchiveMode", "QCheckBox", true ) )->setChecked( on );
+ }
+}
+
+
+void Smb4KRsyncOptions::slotBackupToggled( bool on )
+{
+ static_cast<QCheckBox *>( child( "kcfg_UseBackupDirectory", "QCheckBox", true ) )->setEnabled( on );
+ static_cast<KURLRequester *>( child( "kcfg_BackupDirectory", "KURLRequester", true ) )->setEnabled( on );
+ static_cast<QCheckBox *>( child( "kcfg_UseBackupSuffix", "QCheckBox", true ) )->setEnabled( on );
+ static_cast<KLineEdit *>( child( "kcfg_BackupSuffix", "KLineEdit", true ) )->setEnabled( on );
+}
+
+
+void Smb4KRsyncOptions::slotFShortcutToggled( bool on )
+{
+ QCheckBox *ff_filter = static_cast<QCheckBox *>( child( "kcfg_UseFFFilterRule", "QCheckBox", true ) );
+
+ if ( on && ff_filter->isChecked() )
+ {
+ ff_filter->setChecked( false );
+ }
+}
+
+
+void Smb4KRsyncOptions::slotFFShortcutToggled( bool on )
+{
+ QCheckBox *f_filter = static_cast<QCheckBox *>( child( "kcfg_UseFFilterRule", "QCheckBox", true ) );
+
+ if ( on && f_filter->isChecked() )
+ {
+ f_filter->setChecked( false );
+ }
+}
+
+#include "smb4krsyncoptions.moc"
diff --git a/smb4k/configdlg/smb4krsyncoptions.h b/smb4k/configdlg/smb4krsyncoptions.h
new file mode 100644
index 0000000..3559182
--- /dev/null
+++ b/smb4k/configdlg/smb4krsyncoptions.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ smb4krsyncoptions - The configuration page for the rsync options
+ -------------------
+ begin : So Nov 20 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KRSYNCOPTIONS_H
+#define SMB4KRSYNCOPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qtabwidget.h>
+
+
+/**
+ * This class belongs to the configuration dialog and takes
+ * care of the options that can be defined for rsync.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KRsyncOptions : public QTabWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KRsyncOptions( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KRsyncOptions();
+
+ protected slots:
+ /**
+ * This slot is invoked if the "Archive mode" checkbox has been
+ * toggled.
+ *
+ * @param on Is TRUE if the checkbox is checked and FALSE otherwise.
+ */
+ void slotArchiveToggled( bool on );
+
+ /**
+ * This slot is invoked if the --archive option has to be switched
+ * off.
+ *
+ * @param on Is FALSE if one of the connected checkboxes is unchecked
+ * and TRUE otherwise.
+ */
+ void slotUncheckArchive( bool on );
+
+ /**
+ * This slot is called, when the backup checkbox has been toggled.
+ * It enables/disables all other backup options according to the
+ * state the backup button is in.
+ *
+ * @param on Is TRUE if the m_backup check box has been
+ * checked and FALSE otherwise.
+ */
+ void slotBackupToggled( bool on );
+
+ /**
+ * This slot is called if the '-F' shortcut has been toggled.
+ * It unchecks the '-F -F' shortcut.
+ *
+ * @param on Is TRUE is m_f_filter is checked and FALSE otherwise.
+ */
+ void slotFShortcutToggled( bool on );
+
+ /**
+ * This slot is called if the '-F -F' shortcut has been toggled.
+ * It unchecks the '-F' shortcut.
+ *
+ * @param on Is TRUE is m_ff_filter is checked and FALSE otherwise.
+ */
+ void slotFFShortcutToggled( bool on );
+};
+
+#endif
diff --git a/smb4k/configdlg/smb4ksambaoptions.cpp b/smb4k/configdlg/smb4ksambaoptions.cpp
new file mode 100644
index 0000000..ab57b25
--- /dev/null
+++ b/smb4k/configdlg/smb4ksambaoptions.cpp
@@ -0,0 +1,1230 @@
+/***************************************************************************
+ smb4ksambaoptions.cpp - This is the configuration page for the
+ Samba settings of Smb4K
+ -------------------
+ begin : Mo Jan 26 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qmap.h>
+
+// KDE includes
+#include <klocale.h>
+#include <klineedit.h>
+#include <knuminput.h>
+#include <kcombobox.h>
+#include <kuser.h>
+#include <klistview.h>
+#include <kpushbutton.h>
+
+// System includes
+#include <unistd.h>
+#include <sys/types.h>
+
+// application specific includes
+#include "smb4ksambaoptions.h"
+#include "../core/smb4kglobal.h"
+#include "../core/smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KSambaOptions::Smb4KSambaOptions( QWidget *parent, const char *name )
+: QTabWidget( parent, name )
+{
+ setMargin( 10 );
+
+ //
+ // General options
+ //
+ QWidget *general_tab = new QWidget( this, "GeneralSambaOptions" );
+ QGridLayout *general_layout = new QGridLayout( general_tab );
+ general_layout->setSpacing( 10 );
+
+ QGroupBox *general_options = new QGroupBox( 2, Qt::Horizontal,
+ i18n( "General Options" ), general_tab );
+ general_options->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "NetBIOS name:"), general_options );
+ (void) new KLineEdit( general_options, "kcfg_NetBIOSName" );
+
+ (void) new QLabel( i18n( "Domain:" ), general_options );
+ (void) new KLineEdit( general_options, "kcfg_DomainName" );
+
+ (void) new QLabel( i18n( "Socket options:" ), general_options );
+ (void) new KLineEdit( general_options, "kcfg_SocketOptions" );
+
+ (void) new QLabel( i18n( "NetBIOS scope:" ), general_options );
+ (void) new KLineEdit( general_options, "kcfg_NetBIOSScope" );
+
+ (void) new QLabel( i18n( "Remote SMB port:" ), general_options );
+ (void) new KIntNumInput( general_options, "kcfg_RemotePort" );
+
+ QGroupBox *authentication = new QGroupBox( 1, Qt::Horizontal,
+ i18n( "Authentication" ), general_tab );
+
+ (void) new QCheckBox( i18n( "Try to authenticate with Kerberos" ), authentication, "kcfg_UseKerberos" );
+ (void) new QCheckBox( i18n( "Authenticate as machine account" ), authentication, "kcfg_MachineAccount" );
+
+ QSpacerItem *spacer1 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ general_layout->addWidget( general_options, 0, 0, 0 );
+ general_layout->addWidget( authentication, 1, 0, 0 );
+ general_layout->addItem( spacer1, 2, 0 );
+
+ addTab( general_tab, i18n( "General Settings" ) );
+
+ //
+ // Options for the mount commands
+ //
+ QWidget *mount_tab = new QWidget( this, "MountOptions" );
+ QGridLayout *mount_layout = new QGridLayout( mount_tab );
+ mount_layout->setSpacing( 10 );
+
+ QGroupBox *filesystem_box = new QGroupBox( 1, Qt::Horizontal,
+ i18n( "File System" ), mount_tab );
+
+#ifndef __FreeBSD__
+ KComboBox *filesystem = new KComboBox( filesystem_box, "kcfg_Filesystem" );
+ filesystem->insertItem( "CIFS", Smb4KSettings::EnumFilesystem::CIFS );
+ filesystem->insertItem( "SMBFS", Smb4KSettings::EnumFilesystem::SMBFS );
+#else
+ (void) new QLabel( "SMBFS", filesystem_box );
+#endif
+
+ QLabel *note = new QLabel( i18n( "NOTE: You might need to enable support for either \"super\" or \"sudo\" in the Super User page." ), filesystem_box );
+ note->setTextFormat( Qt::RichText );
+
+ QGroupBox *user_group_box = new QGroupBox( 2, Qt::Horizontal,
+ i18n( "User and Group" ), mount_tab );
+ user_group_box->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "User ID:" ), user_group_box );
+ KLineEdit *user_id = new KLineEdit( user_group_box, "kcfg_UserID" );
+ user_id->setAlignment( Qt::AlignRight );
+
+ (void) new QLabel( i18n( "Group ID:" ), user_group_box );
+ KLineEdit *group_id = new KLineEdit( user_group_box, "kcfg_GroupID" );
+ group_id->setAlignment( Qt::AlignRight );
+
+ QGroupBox *charset_box = new QGroupBox( 2, Qt::Horizontal,
+ i18n( "Charset and Codepage" ), mount_tab );
+ charset_box->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "Client charset:" ), charset_box );
+ KComboBox *charset = new KComboBox( charset_box, "kcfg_ClientCharset" );
+ charset->insertItem( i18n( "default" ), Smb4KSettings::EnumClientCharset::default_charset );
+ charset->insertItem( "iso8859-1", Smb4KSettings::EnumClientCharset::iso8859_1 );
+ charset->insertItem( "iso8859-2", Smb4KSettings::EnumClientCharset::iso8859_2 );
+ charset->insertItem( "iso8859-3", Smb4KSettings::EnumClientCharset::iso8859_3 );
+ charset->insertItem( "iso8859-4", Smb4KSettings::EnumClientCharset::iso8859_4 );
+ charset->insertItem( "iso8859-5", Smb4KSettings::EnumClientCharset::iso8859_5 );
+ charset->insertItem( "iso8859-6", Smb4KSettings::EnumClientCharset::iso8859_6 );
+ charset->insertItem( "iso8859-7", Smb4KSettings::EnumClientCharset::iso8859_7 );
+ charset->insertItem( "iso8859-8", Smb4KSettings::EnumClientCharset::iso8859_8 );
+ charset->insertItem( "iso8859-9", Smb4KSettings::EnumClientCharset::iso8859_9 );
+ charset->insertItem( "iso8859-13", Smb4KSettings::EnumClientCharset::iso8859_13 );
+ charset->insertItem( "iso8859-14", Smb4KSettings::EnumClientCharset::iso8859_14 );
+ charset->insertItem( "iso8859-15", Smb4KSettings::EnumClientCharset::iso8859_15 );
+ charset->insertItem( "utf8", Smb4KSettings::EnumClientCharset::utf8 );
+ charset->insertItem( "koi8-r", Smb4KSettings::EnumClientCharset::koi8_r );
+ charset->insertItem( "koi8-u", Smb4KSettings::EnumClientCharset::koi8_u );
+ charset->insertItem( "koi8-ru", Smb4KSettings::EnumClientCharset::koi8_ru );
+ charset->insertItem( "cp1251", Smb4KSettings::EnumClientCharset::cp1251 );
+ charset->insertItem( "gb2312", Smb4KSettings::EnumClientCharset::gb2312 );
+ charset->insertItem( "big5", Smb4KSettings::EnumClientCharset::big5 );
+ charset->insertItem( "euc-jp", Smb4KSettings::EnumClientCharset::euc_jp );
+ charset->insertItem( "euc-kr", Smb4KSettings::EnumClientCharset::euc_kr );
+ charset->insertItem( "tis-620", Smb4KSettings::EnumClientCharset::tis_620 );
+
+ (void) new QLabel( i18n( "Server codepage:" ), charset_box, "CodepageLabel" );
+ KComboBox *codepage = new KComboBox( charset_box, "kcfg_ServerCodepage" );
+ codepage->insertItem( i18n( "default" ), Smb4KSettings::EnumServerCodepage::default_codepage );
+ codepage->insertItem( "cp437", Smb4KSettings::EnumServerCodepage::cp437 );
+ codepage->insertItem( "cp720", Smb4KSettings::EnumServerCodepage::cp720 );
+ codepage->insertItem( "cp737", Smb4KSettings::EnumServerCodepage::cp737 );
+ codepage->insertItem( "cp775", Smb4KSettings::EnumServerCodepage::cp775 );
+ codepage->insertItem( "cp850", Smb4KSettings::EnumServerCodepage::cp850 );
+ codepage->insertItem( "cp852", Smb4KSettings::EnumServerCodepage::cp852 );
+ codepage->insertItem( "cp855", Smb4KSettings::EnumServerCodepage::cp855 );
+ codepage->insertItem( "cp857", Smb4KSettings::EnumServerCodepage::cp857 );
+ codepage->insertItem( "cp858", Smb4KSettings::EnumServerCodepage::cp858 );
+ codepage->insertItem( "cp860", Smb4KSettings::EnumServerCodepage::cp860 );
+ codepage->insertItem( "cp861", Smb4KSettings::EnumServerCodepage::cp861 );
+ codepage->insertItem( "cp862", Smb4KSettings::EnumServerCodepage::cp862 );
+ codepage->insertItem( "cp863", Smb4KSettings::EnumServerCodepage::cp863 );
+ codepage->insertItem( "cp864", Smb4KSettings::EnumServerCodepage::cp864 );
+ codepage->insertItem( "cp865", Smb4KSettings::EnumServerCodepage::cp865 );
+ codepage->insertItem( "cp866", Smb4KSettings::EnumServerCodepage::cp866 );
+ codepage->insertItem( "cp869", Smb4KSettings::EnumServerCodepage::cp869 );
+ codepage->insertItem( "cp874", Smb4KSettings::EnumServerCodepage::cp874 );
+ codepage->insertItem( "cp932", Smb4KSettings::EnumServerCodepage::cp932 );
+ codepage->insertItem( "cp936", Smb4KSettings::EnumServerCodepage::cp936 );
+ codepage->insertItem( "cp949", Smb4KSettings::EnumServerCodepage::cp949 );
+ codepage->insertItem( "cp950", Smb4KSettings::EnumServerCodepage::cp950 );
+ codepage->insertItem( "cp1250", Smb4KSettings::EnumServerCodepage::cp1250 );
+ codepage->insertItem( "cp1251", Smb4KSettings::EnumServerCodepage::cp1251 );
+ codepage->insertItem( "cp1252", Smb4KSettings::EnumServerCodepage::cp1252 );
+ codepage->insertItem( "cp1253", Smb4KSettings::EnumServerCodepage::cp1253 );
+ codepage->insertItem( "cp1254", Smb4KSettings::EnumServerCodepage::cp1254 );
+ codepage->insertItem( "cp1255", Smb4KSettings::EnumServerCodepage::cp1255 );
+ codepage->insertItem( "cp1256", Smb4KSettings::EnumServerCodepage::cp1256 );
+ codepage->insertItem( "cp1257", Smb4KSettings::EnumServerCodepage::cp1257 );
+ codepage->insertItem( "cp1258", Smb4KSettings::EnumServerCodepage::cp1258 );
+ codepage->insertItem( "unicode", Smb4KSettings::EnumServerCodepage::unicode );
+
+ QGroupBox *perms_box = new QGroupBox( 2, Qt::Horizontal,
+ i18n( "Permissions" ), mount_tab );
+ perms_box->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "File mask:" ), perms_box );
+ KLineEdit *fmask = new KLineEdit( perms_box, "kcfg_FileMask" );
+ fmask->setAlignment( Qt::AlignRight );
+
+ (void) new QLabel( i18n( "Directory mask:" ), perms_box );
+ KLineEdit *dmask = new KLineEdit( perms_box, "kcfg_DirectoryMask" );
+ dmask->setAlignment( Qt::AlignRight );
+
+ (void) new QLabel( i18n( "Write access:" ), perms_box );
+ KComboBox *read_mode = new KComboBox( perms_box, "kcfg_WriteAccess" );
+ read_mode->insertItem( i18n( "read-write" ), Smb4KSettings::EnumWriteAccess::ReadWrite );
+ read_mode->insertItem( i18n( "read-only" ), Smb4KSettings::EnumWriteAccess::ReadOnly );
+
+#ifndef __FreeBSD__
+ QGroupBox *advanced_cifs = new QGroupBox( 1, Qt::Horizontal,
+ i18n( "Advanced CIFS Options" ), mount_tab, "AdvancedCIFSOptions" );
+ advanced_cifs->setInsideSpacing( 5 );
+
+ QWidget *c_advanced_widget = new QWidget( advanced_cifs );
+ QGridLayout *c_advanced_layout = new QGridLayout( c_advanced_widget );
+ c_advanced_layout->setSpacing( 5 );
+ c_advanced_layout->setMargin( 0 );
+ c_advanced_layout->addWidget( new QCheckBox( i18n( "Do permission checks" ),
+ c_advanced_widget, "kcfg_PermissionChecks" ), 0, 0, 0 );
+ c_advanced_layout->addWidget( new QCheckBox( i18n( "Attempt to set UID and GID" ),
+ c_advanced_widget, "kcfg_ClientControlsIDs" ), 0, 1, 0 );
+ c_advanced_layout->addWidget( new QCheckBox( i18n( "Use server inode numbers" ),
+ c_advanced_widget, "kcfg_ServerInodeNumbers" ), 1, 0, 0 );
+ c_advanced_layout->addWidget( new QCheckBox( i18n( "Do not cache inode data" ),
+ c_advanced_widget, "kcfg_InodeDataCaching" ), 1, 1, 0 );
+ c_advanced_layout->addWidget( new QCheckBox( i18n( "Translate reserved characters" ),
+ c_advanced_widget, "kcfg_TranslateReservedChars" ), 2, 0, 0 );
+ c_advanced_layout->addWidget( new QCheckBox( i18n( "Do not use locking" ),
+ c_advanced_widget, "kcfg_NoLocking" ), 2, 1, 0 );
+
+ QWidget *c_extra_widget = new QWidget( advanced_cifs );
+ QGridLayout *c_extra_layout = new QGridLayout( c_extra_widget );
+ c_extra_layout->setSpacing( 5 );
+ c_extra_layout->setMargin( 0 );
+ c_extra_layout->addWidget( new QLabel( i18n( "Additional options:" ), c_extra_widget ), 0, 0, 0 );
+ c_extra_layout->addWidget( new KLineEdit( c_extra_widget, "kcfg_CustomCIFSOptions" ), 0, 1, 0 );
+
+ QGroupBox *advanced_smbfs = new QGroupBox( 1, Qt::Horizontal,
+ i18n( "Advanced SMBFS Options" ), mount_tab, "AdvancedSMBFSOptions" );
+ advanced_smbfs->setInsideSpacing( 5 );
+
+ (void) new QCheckBox( i18n( "Use Unicode when communicating with the server" ), advanced_smbfs, "kcfg_UnicodeSupport" );
+ (void) new QCheckBox( i18n( "Use large file support" ), advanced_smbfs, "kcfg_LargeFileSystemSupport" );
+
+ QWidget *s_advanced_widget = new QWidget( advanced_smbfs );
+ QGridLayout *s_advanced_layout = new QGridLayout( s_advanced_widget );
+ s_advanced_layout->setSpacing( 5 );
+ s_advanced_layout->setMargin( 0 );
+ s_advanced_layout->addWidget( new QLabel( i18n( "Caching time of directory listings:" ), s_advanced_widget ), 0, 0, 0 );
+ KIntNumInput *ttl = new KIntNumInput( s_advanced_widget, "kcfg_CachingTime" );
+ ttl->setSuffix( " ms" );
+ s_advanced_layout->addWidget( ttl, 0, 1, 0 );
+
+#endif
+
+ QSpacerItem *spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ mount_layout->addMultiCellWidget( filesystem_box, 0, 0, 0, 1, 0 );
+ mount_layout->addMultiCellWidget( perms_box, 0, 0, 2, 3, 0 );
+ mount_layout->addMultiCellWidget( charset_box, 1, 1, 0, 1, 0 );
+ mount_layout->addMultiCellWidget( user_group_box, 1, 1, 2, 3, 0 );
+#ifndef __FreeBSD__
+ mount_layout->addMultiCellWidget( advanced_cifs, 2, 2, 0, 3, 0 );
+ mount_layout->addMultiCellWidget( advanced_smbfs, 3, 3, 0, 3, 0 );
+ mount_layout->addMultiCell( spacer2, 4, 4, 0, 3, 0 );
+#else
+ mount_layout->addMultiCell( spacer2, 2, 2, 0, 3, 0 );
+#endif
+
+ addTab( mount_tab, "mount" );
+
+ //
+ // Options for the 'net' command
+ //
+ QWidget *net_tab = new QWidget( this, "NetOptions" );
+ QGridLayout *net_layout = new QGridLayout( net_tab );
+ net_layout->setSpacing( 10 );
+
+ QButtonGroup *protocol_hint = new QButtonGroup( 1, Qt::Horizontal,
+ i18n( "Protocol Hint" ), net_tab, "kcfg_ProtocolHint" );
+
+ protocol_hint->insert( new QRadioButton( i18n( "Automatic detection" ), protocol_hint ),
+ Smb4KSettings::EnumProtocolHint::Automatic );
+ protocol_hint->insert( new QRadioButton( i18n( "RPC: Modern operating systems" ), protocol_hint ),
+ Smb4KSettings::EnumProtocolHint::RPC );
+ protocol_hint->insert( new QRadioButton( i18n( "RAP: Older operating systems" ), protocol_hint ),
+ Smb4KSettings::EnumProtocolHint::RAP );
+ protocol_hint->insert( new QRadioButton( i18n( "ADS: Active Directory environment (LDAP/Kerberos)" ), protocol_hint ),
+ Smb4KSettings::EnumProtocolHint::ADS );
+
+ QSpacerItem *spacer3 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ net_layout->addWidget( protocol_hint, 0, 0, 0 );
+ net_layout->addItem( spacer3, 1, 0 );
+
+ addTab( net_tab, "net" );
+
+ //
+ // Options for the 'smbclient' command
+ //
+ QWidget *smbclient_tab = new QWidget( this, "SmbclientOptions" );
+ QGridLayout *smbclient_layout = new QGridLayout( smbclient_tab );
+ smbclient_layout->setSpacing( 10 );
+
+ QGroupBox *smbclient_misc = new QGroupBox( 2, Qt::Horizontal, i18n( "Miscellaneous" ),
+ smbclient_tab, "SmbclientMiscellaneous" );
+ smbclient_misc->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "Name resolve order:" ), smbclient_misc );
+ (void) new KLineEdit( smbclient_misc, "kcfg_NameResolveOrder" );
+
+ (void) new QLabel( i18n( "Buffer size:" ), smbclient_misc );
+ KIntNumInput *buffer_size = new KIntNumInput( smbclient_misc, "kcfg_BufferSize" );
+ buffer_size->setSuffix( i18n( " Bytes" ) );
+
+ (void) new QLabel( i18n( "Signing state:" ), smbclient_misc );
+ KComboBox *signing_state = new KComboBox( smbclient_misc, "kcfg_SigningState" );
+ signing_state->insertItem( i18n( "none" ), Smb4KSettings::EnumSigningState::None );
+ signing_state->insertItem( i18n( "on" ), Smb4KSettings::EnumSigningState::On );
+ signing_state->insertItem( i18n( "off" ), Smb4KSettings::EnumSigningState::Off );
+ signing_state->insertItem( i18n( "required" ), Smb4KSettings::EnumSigningState::Required );
+
+ QSpacerItem *spacer4 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ smbclient_layout->addWidget( smbclient_misc, 0, 0, 0 );
+ smbclient_layout->addItem( spacer4, 1, 0 );
+
+ addTab( smbclient_tab, "smbclient" );
+
+ //
+ // Options for the 'nmblookup' command
+ //
+ QWidget *nmblookup_tab = new QWidget( this, "NmblookupOptions" );
+ QGridLayout *nmblookup_layout = new QGridLayout( nmblookup_tab );
+ nmblookup_layout->setSpacing( 10 );
+
+ QGroupBox *nmblookup_misc = new QGroupBox( 1, Qt::Horizontal,
+ i18n( "Miscellaneous" ), nmblookup_tab );
+ nmblookup_misc->setInsideSpacing( 5 );
+
+ QWidget *broadcast_widget = new QWidget( nmblookup_misc );
+ QGridLayout *broadcast_layout = new QGridLayout( broadcast_widget );
+ broadcast_layout->setSpacing( 5 );
+ broadcast_layout->setMargin( 0 );
+ broadcast_layout->addWidget( new QLabel( i18n( "Broadcast address:" ), broadcast_widget ), 0, 0, 0 );
+ broadcast_layout->addWidget( new KLineEdit( broadcast_widget, "kcfg_BroadcastAddress" ), 0, 1, 0 );
+
+ (void) new QCheckBox( i18n( "Try and bind to UDP port 137 to send and receive UDP datagrams" ), nmblookup_misc, "kcfg_UsePort137" );
+
+ QSpacerItem *spacer5 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ nmblookup_layout->addWidget( nmblookup_misc, 0, 0, 0 );
+ nmblookup_layout->addItem( spacer5, 1, 0 );
+
+ addTab( nmblookup_tab, "nmblookup" );
+
+
+ //
+ // Custom options
+ //
+ QWidget *custom_tab = new QWidget( this, "CustomOptions" );
+ QGridLayout *custom_layout = new QGridLayout( custom_tab );
+ custom_layout->setSpacing( 10 );
+
+
+ // FIXME: Set "What's this' texts!!!
+
+ KListView *custom_options = new KListView( custom_tab, "CustomOptionsList" );
+// custom_options->setAllColumnsShowFocus( true );
+ custom_options->setSelectionMode( QListView::Single );
+ custom_options->setVScrollBarMode( KListView::Auto );
+ custom_options->addColumn( i18n( "Item" ), -1 );
+ custom_options->addColumn( i18n( "Protocol" ), -1 );
+#ifndef __FreeBSD__
+ custom_options->addColumn( i18n( "File System" ), -1 );
+ custom_options->addColumn( i18n( "Write Access" ), -1 );
+#endif
+ custom_options->addColumn( i18n( "Kerberos" ), -1 );
+ custom_options->addColumn( i18n( "UID" ), -1 );
+ custom_options->addColumn( i18n( "GID" ), -1 );
+ custom_options->addColumn( i18n( "Port" ), -1 );
+
+ QWidget *custom_input = new QWidget( custom_tab, "CustomInputWidget" );
+ QGridLayout *custom_input_layout = new QGridLayout( custom_input );
+ custom_input_layout->setSpacing( 5 );
+
+ QLabel *custom_proto_label = new QLabel( i18n( "Protocol:" ), custom_input, "CustomProtocolLabel" );
+
+ KComboBox *custom_protocol = new KComboBox( custom_input, "CustomProtocol" );
+ custom_protocol->insertItem( "-", -1 );
+ custom_protocol->insertItem( i18n( "auto" ), -1 );
+ custom_protocol->insertItem( "RPC", -1 );
+ custom_protocol->insertItem( "RAP", -1 );
+ custom_protocol->insertItem( "ADS", -1 );
+
+#ifndef __FreeBSD__
+
+ QLabel *custom_fs_label = new QLabel( i18n( "File system:" ), custom_input, "CustomFileSystemLabel" );
+
+ KComboBox *custom_fs = new KComboBox( custom_input, "CustomFileSystem" );
+ custom_fs->insertItem( "-", -1 );
+ custom_fs->insertItem( "CIFS", -1 );
+ custom_fs->insertItem( "SMBFS", -1 );
+
+ QLabel *custom_rw_label = new QLabel( i18n( "Write access:" ), custom_input, "CustomWriteAccessLabel" );
+
+ KComboBox *custom_rw = new KComboBox( custom_input, "CustomWriteAccess" );
+ custom_rw->insertItem( "-", -1 );
+ custom_rw->insertItem( i18n( "read-write" ), -1 );
+ custom_rw->insertItem( i18n( "read-only" ), -1 );
+
+#endif
+
+ QLabel *custom_krb_label = new QLabel( i18n( "Kerberos:" ), custom_input, "CustomKerberosLabel" );
+
+ KComboBox *custom_krb = new KComboBox( custom_input, "CustomKerberos" );
+ custom_krb->insertItem( "-", -1 );
+ custom_krb->insertItem( i18n( "no" ), -1 );
+ custom_krb->insertItem( i18n( "yes" ), -1 );
+
+ QLabel *custom_uid_label = new QLabel( i18n( "User ID:" ), custom_input, "CustomUIDLabel" );
+
+ KLineEdit *custom_uid = new KLineEdit( custom_input, "CustomUID" );
+ custom_uid->setText( "-" );
+
+ QLabel *custom_gid_label = new QLabel( i18n( "Group ID:" ), custom_input, "CustomGIDLabel" );
+
+ KLineEdit *custom_gid = new KLineEdit( custom_input, "CustomGID" );
+ custom_gid->setText( "-" );
+
+ QLabel *custom_port_label = new QLabel( i18n( "Port:" ), custom_input, "CustomPortLabel" );
+
+ KIntNumInput *custom_port = new KIntNumInput( Smb4KSettings::remotePort(), custom_input, 10, "CustomPort" );
+ custom_port->setMinValue( 0 );
+ custom_port->setMaxValue( 65535 );
+
+ QWidget *custom_rm = new QWidget( custom_input );
+ QGridLayout *custom_rm_layout = new QGridLayout( custom_rm );
+ custom_rm_layout->setSpacing( 5 );
+
+ KPushButton *remove_custom = new KPushButton( KGuiItem( i18n( "Remove" ), "remove" ), custom_rm, "CustomRemoveItem" );
+ KPushButton *rm_all_custom = new KPushButton( KGuiItem( i18n( "Remove All" ), "editdelete" ), custom_rm, "CustomRemoveAllItems" );
+
+ QSpacerItem *spacer6 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred );
+
+ custom_rm_layout->addItem( spacer6, 0, 0 );
+ custom_rm_layout->addWidget( remove_custom, 0, 1, 0 );
+ custom_rm_layout->addWidget( rm_all_custom, 0, 2, 0 );
+
+ custom_input_layout->addWidget( custom_proto_label, 0, 0, 0 );
+ custom_input_layout->addWidget( custom_protocol, 0, 1, 0 );
+#ifndef __FreeBSD__
+ custom_input_layout->addWidget( custom_fs_label, 0, 2, 0 );
+ custom_input_layout->addWidget( custom_fs, 0, 3, 0 );
+ custom_input_layout->addWidget( custom_rw_label, 1, 0, 0 );
+ custom_input_layout->addWidget( custom_rw, 1, 1, 0 );
+ custom_input_layout->addWidget( custom_krb_label, 1, 2, 0 );
+ custom_input_layout->addWidget( custom_krb, 1, 3, 0 );
+ custom_input_layout->addWidget( custom_uid_label, 2, 0, 0 );
+ custom_input_layout->addWidget( custom_uid, 2, 1, 0 );
+ custom_input_layout->addWidget( custom_gid_label, 2, 2, 0 );
+ custom_input_layout->addWidget( custom_gid, 2, 3, 0 );
+ custom_input_layout->addWidget( custom_port_label, 3, 0, 0 );
+ custom_input_layout->addWidget( custom_port, 3, 1, 0 );
+ custom_input_layout->addMultiCellWidget( custom_rm, 3, 3, 2, 3, 0 );
+#else
+ custom_input_layout->addWidget( custom_krb_label, 0, 2, 0 );
+ custom_input_layout->addWidget( custom_krb, 0, 3, 0 );
+ custom_input_layout->addWidget( custom_uid_label, 1, 0, 0 );
+ custom_input_layout->addWidget( custom_uid, 1, 1, 0 );
+ custom_input_layout->addWidget( custom_gid_label, 1, 2, 0 );
+ custom_input_layout->addWidget( custom_gid, 1, 3, 0 );
+ custom_input_layout->addWidget( custom_port_label, 2, 0, 0 );
+ custom_input_layout->addWidget( custom_port, 2, 1, 0 );
+ custom_input_layout->addMultiCellWidget( custom_rm, 2, 2, 2, 3, 0 );
+#endif
+
+ QSpacerItem *spacer7 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Minimum );
+
+ custom_layout->addWidget( custom_options, 0, 0, 0 );
+ custom_layout->addWidget( custom_input, 1, 0, 0 );
+ custom_layout->addItem( spacer7, 2, 0 );
+
+ addTab( custom_tab, i18n( "Custom" ) );
+
+ //
+ // Connections
+ //
+#ifndef __FreeBSD__
+ connect( filesystem, SIGNAL( activated( int ) ),
+ this, SLOT( slotSambaFileSystem( int ) ) );
+#endif
+
+ connect( remove_custom, SIGNAL( clicked() ),
+ this, SLOT( slotRemoveCustomOption() ) );
+
+ connect( rm_all_custom, SIGNAL( clicked() ),
+ this, SLOT( slotRemoveAllCustomOptions() ) );
+
+ connect( custom_options, SIGNAL( clicked( QListViewItem * ) ),
+ this, SLOT( slotCustomItemClicked( QListViewItem * ) ) );
+
+ connect( custom_protocol, SIGNAL( activated( int ) ),
+ this, SLOT( slotCustomProtocolChanged( int ) ) );
+
+#ifndef __FreeBSD__
+ connect( custom_fs, SIGNAL( activated( int ) ),
+ this, SLOT( slotCustomFileSystemChanged( int ) ) );
+
+ connect( custom_rw, SIGNAL( activated( int ) ),
+ this, SLOT( slotCustomWriteAccessChanged( int ) ) );
+#endif
+
+ connect( custom_krb, SIGNAL( activated( int ) ),
+ this, SLOT( slotCustomKerberosChanged( int ) ) );
+
+ connect( custom_uid, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotCustomUIDChanged( const QString & ) ) );
+
+ connect( custom_gid, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotCustomGIDChanged( const QString & ) ) );
+
+ connect( custom_port, SIGNAL( valueChanged( int ) ),
+ this, SLOT( slotCustomPortChanged( int ) ) );
+
+ //
+ // Do last things before we are ready to go
+ //
+#ifndef __FreeBSD__
+ slotSambaFileSystem( filesystem->currentItem() );
+#endif
+ slotCustomItemClicked( NULL );
+}
+
+
+Smb4KSambaOptions::~Smb4KSambaOptions()
+{
+}
+
+
+void Smb4KSambaOptions::resetCustomTab()
+{
+ slotCustomItemClicked( NULL );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __FreeBSD__
+void Smb4KSambaOptions::slotSambaFileSystem( int item_index )
+{
+ switch ( item_index )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ QGroupBox *adv_cifs = static_cast<QGroupBox *>( child( "AdvancedCIFSOptions", "QGroupBox", true ) );
+
+ if ( adv_cifs )
+ {
+ adv_cifs->setEnabled( true );
+ }
+
+ QGroupBox *adv_smbfs = static_cast<QGroupBox *>( child( "AdvancedSMBFSOptions", "QGroupBox", true ) );
+
+ if ( adv_smbfs )
+ {
+ adv_smbfs->setEnabled( false );
+ }
+
+ QLabel *codepage = static_cast<QLabel *>( child( "CodepageLabel", "QLabel", true ) );
+
+ if ( codepage )
+ {
+ codepage->setEnabled( false );
+ }
+
+ KComboBox *srv_codepage = static_cast<KComboBox *>( child( "kcfg_ServerCodepage", "KComboBox", true ) );
+
+ if ( srv_codepage )
+ {
+ srv_codepage->setEnabled( false );
+ }
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ QGroupBox *adv_cifs = static_cast<QGroupBox *>( child( "AdvancedCIFSOptions", "QGroupBox", true ) );
+
+ if ( adv_cifs )
+ {
+ adv_cifs->setEnabled( false );
+ }
+
+ QGroupBox *adv_smbfs = static_cast<QGroupBox *>( child( "AdvancedSMBFSOptions", "QGroupBox", true ) );
+
+ if ( adv_smbfs )
+ {
+ adv_smbfs->setEnabled( true );
+ }
+
+ QLabel *codepage = static_cast<QLabel *>( child( "CodepageLabel", "QLabel", true ) );
+
+ if ( codepage )
+ {
+ codepage->setEnabled( true );
+ }
+
+ KComboBox *srv_codepage = static_cast<KComboBox *>( child( "kcfg_ServerCodepage", "KComboBox", true ) );
+
+ if ( srv_codepage )
+ {
+ srv_codepage->setEnabled( true );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ };
+#else
+void Smb4KSambaOptions::slotSambaFileSystem( int )
+{
+#endif
+}
+
+
+void Smb4KSambaOptions::slotCustomItemClicked( QListViewItem *item )
+{
+ if ( item )
+ {
+ // Enable the input widget:
+ QWidget *input = static_cast<QGroupBox *>( child( "CustomInputWidget", "QGroupBox", true ) );
+
+ if ( input )
+ {
+ input->setEnabled( true );
+ }
+
+ // Enable/disable the labels, combo boxes, buttons, etc:
+ QLabel *protocol_label = static_cast<QLabel *>( child( "CustomProtocolLabel", "QLabel", true ) );
+
+ if ( protocol_label )
+ {
+ if ( QString::compare( item->text( Protocol ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ protocol_label->setEnabled( false );
+ }
+ else
+ {
+ protocol_label->setEnabled( true );
+ }
+ }
+
+ KComboBox *protocol = static_cast<KComboBox *>( child( "CustomProtocol", "KComboBox", true ) );
+
+ if ( protocol )
+ {
+ if ( QString::compare( item->text( Protocol ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ protocol->setEnabled( false );
+ }
+ else
+ {
+ protocol->setEnabled( true );
+ }
+
+ protocol->setCurrentText( item->text( Protocol ) );
+ }
+
+#ifndef __FreeBSD__
+
+ QLabel *fs_label = static_cast<QLabel *>( child( "CustomFileSystemLabel", "QLabel", true ) );
+
+ if ( fs_label )
+ {
+ if ( QString::compare( item->text( FileSystem ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ fs_label->setEnabled( false );
+ }
+ else
+ {
+ fs_label->setEnabled( true );
+ }
+ }
+
+ KComboBox *filesystem = static_cast<KComboBox *>( child( "CustomFileSystem", "KComboBox", true ) );
+
+ if ( filesystem )
+ {
+ if ( QString::compare( item->text( FileSystem ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ filesystem->setEnabled( false );
+ }
+ else
+ {
+ filesystem->setEnabled( true );
+ }
+
+ filesystem->setCurrentText( item->text( FileSystem ) );
+ }
+
+ QLabel *write_access_label = static_cast<QLabel *>( child( "CustomWriteAccessLabel", "QLabel", true ) );
+
+ if ( write_access_label )
+ {
+ if ( QString::compare( item->text( WriteAccess ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ write_access_label->setEnabled( false );
+ }
+ else
+ {
+ write_access_label->setEnabled( true );
+ }
+ }
+
+ KComboBox *write_access = static_cast<KComboBox *>( child( "CustomWriteAccess", "KComboBox", true ) );
+
+ if ( write_access )
+ {
+ if ( QString::compare( item->text( WriteAccess ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ write_access->setEnabled( false );
+ }
+ else
+ {
+ write_access->setEnabled( true );
+ }
+
+ write_access->setCurrentText( item->text( WriteAccess ) );
+ }
+
+#endif
+
+ QLabel *krb_label = static_cast<QLabel *>( child( "CustomKerberosLabel", "QLabel", true ) );
+
+ if ( krb_label )
+ {
+ if ( QString::compare( item->text( Kerberos ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ krb_label->setEnabled( false );
+ }
+ else
+ {
+ krb_label->setEnabled( true );
+ }
+ }
+
+ KComboBox *kerberos = static_cast<KComboBox *>( child( "CustomKerberos", "KComboBox", true ) );
+
+ if ( kerberos )
+ {
+ if ( QString::compare( item->text( Kerberos ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ kerberos->setEnabled( false );
+ }
+ else
+ {
+ kerberos->setEnabled( true );
+ }
+
+ kerberos->setCurrentText( item->text( Kerberos ) );
+ }
+
+ QLabel *uid_label = static_cast<QLabel *>( child( "CustomUIDLabel", "QLabel", true ) );
+
+ if ( uid_label )
+ {
+ if ( QString::compare( item->text( UID ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ uid_label->setEnabled( false );
+ }
+ else
+ {
+ uid_label->setEnabled( true );
+ }
+ }
+
+ KLineEdit *uid = static_cast<KLineEdit *>( child( "CustomUID", "KLineEdit", true ) );
+
+ if ( uid )
+ {
+ if ( QString::compare( item->text( UID ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ uid->setEnabled( false );
+ }
+ else
+ {
+ uid->setEnabled( true );
+ }
+
+ uid->setText( item->text( UID ) );
+ }
+
+ QLabel *gid_label = static_cast<QLabel *>( child( "CustomGIDLabel", "QLabel", true ) );
+
+ if ( gid_label )
+ {
+ if ( QString::compare( item->text( GID ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ gid_label->setEnabled( false );
+ }
+ else
+ {
+ gid_label->setEnabled( true );
+ }
+ }
+
+ KLineEdit *gid = static_cast<KLineEdit *>( child( "CustomGID", "KLineEdit", true ) );
+
+ if ( gid )
+ {
+ if ( QString::compare( item->text( GID ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ gid->setEnabled( false );
+ }
+ else
+ {
+ gid->setEnabled( true );
+ }
+
+ gid->setText( item->text( GID ) );
+ }
+
+ QLabel *port_label = static_cast<QLabel *>( child( "CustomPortLabel", "QLabel", true ) );
+
+ if ( port_label )
+ {
+ if ( QString::compare( item->text( Port ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ port_label->setEnabled( false );
+ }
+ else
+ {
+ port_label->setEnabled( true );
+ }
+ }
+
+ KIntNumInput *port = static_cast<KIntNumInput *>( child( "CustomPort", "KIntNumInput", true ) );
+
+ if ( port )
+ {
+ if ( QString::compare( item->text( Port ).stripWhiteSpace(), "-" ) == 0 )
+ {
+ port->setEnabled( false );
+ }
+ else
+ {
+ port->setEnabled( true );
+ }
+
+ port->setValue( item->text( Port ).toInt() );
+ }
+
+ KPushButton *remove = static_cast<KPushButton *>( child( "CustomRemoveItem", "KPushButton", true ) );
+
+ if ( remove )
+ {
+ remove->setEnabled( true );
+ }
+
+ KPushButton *remove_all = static_cast<KPushButton *>( child( "CustomRemoveAllItems", "KPushButton", true ) );
+
+ if ( remove_all )
+ {
+ remove_all->setEnabled( true );
+ }
+ }
+ else
+ {
+ // Get the list view:
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( view )
+ {
+ QLabel *protocol_label = static_cast<QLabel *>( child( "CustomProtocolLabel", "QLabel", true ) );
+
+ if ( protocol_label )
+ {
+ protocol_label->setEnabled( false );
+ }
+
+ KComboBox *protocol = static_cast<KComboBox *>( child( "CustomProtocol", "KComboBox", true ) );
+
+ if ( protocol )
+ {
+ protocol->setCurrentText( "-" );
+ protocol->setEnabled( false );
+ }
+
+#ifndef __FreeBSD__
+
+ QLabel *fs_label = static_cast<QLabel *>( child( "CustomFileSystemLabel", "QLabel", true ) );
+
+ if ( fs_label )
+ {
+ fs_label->setEnabled( false );
+ }
+
+ KComboBox *filesystem = static_cast<KComboBox *>( child( "CustomFileSystem", "KComboBox", true ) );
+
+ if ( filesystem )
+ {
+ filesystem->setCurrentText( "-" );
+ filesystem->setEnabled( false );
+ }
+
+ QLabel *write_access_label = static_cast<QLabel *>( child( "CustomWriteAccessLabel", "QLabel", true ) );
+
+ if ( write_access_label )
+ {
+ write_access_label->setEnabled( false );
+ }
+
+ KComboBox *write_access = static_cast<KComboBox *>( child( "CustomWriteAccess", "KComboBox", true ) );
+
+ if ( write_access )
+ {
+ write_access->setCurrentText( "-" );
+ write_access->setEnabled( false );
+ }
+
+#endif
+
+ QLabel *krb_label = static_cast<QLabel *>( child( "CustomKerberosLabel", "QLabel", true ) );
+
+ if ( krb_label )
+ {
+ krb_label->setEnabled( false );
+ }
+
+ KComboBox *kerberos = static_cast<KComboBox *>( child( "CustomKerberos", "KComboBox", true ) );
+
+ if ( kerberos )
+ {
+ kerberos->setCurrentText( "-" );
+ kerberos->setEnabled( false );
+ }
+
+ QLabel *uid_label = static_cast<QLabel *>( child( "CustomUIDLabel", "QLabel", true ) );
+
+ if ( uid_label )
+ {
+ uid_label->setEnabled( false );
+ }
+
+ KLineEdit *uid = static_cast<KLineEdit *>( child( "CustomUID", "KLineEdit", true ) );
+
+ if ( uid )
+ {
+ uid->setText( "-" );
+ uid->setEnabled( false );
+ }
+
+ QLabel *gid_label = static_cast<QLabel *>( child( "CustomGIDLabel", "QLabel", true ) );
+
+ if ( gid_label )
+ {
+ gid_label->setEnabled( false );
+ }
+
+ KLineEdit *gid = static_cast<KLineEdit *>( child( "CustomGID", "KLineEdit", true ) );
+
+ if ( gid )
+ {
+ gid->setText( "-" );
+ gid->setEnabled( false );
+ }
+
+ QLabel *port_label = static_cast<QLabel *>( child( "CustomPortLabel", "QLabel", true ) );
+
+ if ( port_label )
+ {
+ port_label->setEnabled( false );
+ }
+
+ KIntNumInput *port = static_cast<KIntNumInput *>( child( "CustomPort", "KIntNumInput", true ) );
+
+ if ( port )
+ {
+ port->setValue( Smb4KSettings::remotePort() );
+ port->setEnabled( false );
+ }
+
+ KPushButton *remove = static_cast<KPushButton *>( child( "CustomRemoveItem", "KPushButton", true ) );
+
+ if ( remove )
+ {
+ remove->setEnabled( false );
+ }
+
+ KPushButton *remove_all = static_cast<KPushButton *>( child( "CustomRemoveAllItems", "KPushButton", true ) );
+
+ if ( remove_all )
+ {
+ remove_all->setEnabled( (view->childCount() != 0) );
+ }
+ }
+ }
+}
+
+
+void Smb4KSambaOptions::slotCustomProtocolChanged( int index )
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+ KComboBox *custom_protocol = static_cast<KComboBox *>( child( "CustomProtocol", "KComboBox", true ) );
+
+ if ( view && view->selectedItem() && custom_protocol )
+ {
+ if ( QString::compare( "-", custom_protocol->text( index ) ) != 0 )
+ {
+ // Set the new value:
+ view->selectedItem()->setText( Protocol, custom_protocol->text( index ) );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Reset the combo box:
+ custom_protocol->setCurrentText( view->selectedItem()->text( Protocol ) );
+ }
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+
+#ifndef __FreeBSD__
+void Smb4KSambaOptions::slotCustomFileSystemChanged( int index )
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+ KComboBox *custom_filesystem = static_cast<KComboBox *>( child( "CustomFileSystem", "KComboBox", true ) );
+
+ if ( view && view->selectedItem() && custom_filesystem )
+ {
+ if ( QString::compare( "-", custom_filesystem->text( index ) ) != 0 )
+ {
+ // Set the new value:
+ view->selectedItem()->setText( FileSystem, custom_filesystem->text( index ) );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Reset the combo box:
+ custom_filesystem->setCurrentText( view->selectedItem()->text( FileSystem ) );
+ }
+ }
+ else
+ {
+ // Nothing to do.
+ }
+#else
+void Smb4KSambaOptions::slotCustomFileSystemChanged( int )
+{
+#endif
+}
+
+
+#ifndef __FreeBSD__
+void Smb4KSambaOptions::slotCustomWriteAccessChanged( int index )
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+ KComboBox *custom_rw = static_cast<KComboBox *>( child( "CustomWriteAccess", "KComboBox", true ) );
+
+ if ( view && view->selectedItem() && custom_rw )
+ {
+ if ( QString::compare( "-", custom_rw->text( index ) ) != 0 )
+ {
+ // Set the new value:
+ view->selectedItem()->setText( WriteAccess, custom_rw->text( index ) );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Reset the combo box:
+ custom_rw->setCurrentText( view->selectedItem()->text( WriteAccess ) );
+ }
+ }
+ else
+ {
+ // Nothing to do.
+ }
+#else
+void Smb4KSambaOptions::slotCustomWriteAccessChanged( int )
+{
+#endif
+}
+
+
+void Smb4KSambaOptions::slotCustomKerberosChanged( int index )
+{
+ // FIXME: Do we need to adjust something here with respect to
+ // FreeBSD? It does not know Kerberos for mounting!
+
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+ KComboBox *custom_kerberos = static_cast<KComboBox *>( child( "CustomWriteAccess", "KComboBox", true ) );
+
+ if ( view && view->selectedItem() && custom_kerberos )
+ {
+ if ( QString::compare( "-", custom_kerberos->text( index ) ) != 0 )
+ {
+ // Set the new value:
+ view->selectedItem()->setText( Kerberos, custom_kerberos->text( index ) );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Reset the combo box:
+ custom_kerberos->setCurrentText( view->selectedItem()->text( Kerberos ) );
+ }
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+
+void Smb4KSambaOptions::slotCustomUIDChanged( const QString &uid )
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( view && view->selectedItem() )
+ {
+ // Set the new value:
+ view->selectedItem()->setText( UID, uid );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+
+void Smb4KSambaOptions::slotCustomGIDChanged( const QString &gid )
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( view && view->selectedItem() )
+ {
+ // Set the new value:
+ view->selectedItem()->setText( GID, gid );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+
+void Smb4KSambaOptions::slotCustomPortChanged( int port )
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( view && view->selectedItem() )
+ {
+ view->selectedItem()->setText( Port, QString( "%1" ).arg( port ) );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+
+void Smb4KSambaOptions::slotRemoveCustomOption()
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( view && view->selectedItem() )
+ {
+ delete view->currentItem();
+
+ slotCustomItemClicked( NULL );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+
+void Smb4KSambaOptions::slotRemoveAllCustomOptions()
+{
+ KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) );
+
+ if ( view )
+ {
+ while ( view->firstChild() )
+ {
+ delete view->firstChild();
+ }
+
+ slotCustomItemClicked( NULL );
+
+ emit customSettingsChanged();
+ }
+ else
+ {
+ // Nothing to do.
+ }
+}
+
+#include "smb4ksambaoptions.moc"
diff --git a/smb4k/configdlg/smb4ksambaoptions.h b/smb4k/configdlg/smb4ksambaoptions.h
new file mode 100644
index 0000000..9a994b0
--- /dev/null
+++ b/smb4k/configdlg/smb4ksambaoptions.h
@@ -0,0 +1,168 @@
+/***************************************************************************
+ smb4ksambaoptions.cpp - This is the configuration page for the
+ Samba settings of Smb4K
+ -------------------
+ begin : Mo Jan 26 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSAMBAOPTIONS_H
+#define SMB4KSAMBAOPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qtabwidget.h>
+
+
+/**
+ * This class manages the configuration dialog of the options
+ * that can be passed to smbmount and other programs of the
+ * Samba software suite.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+
+class Smb4KSambaOptions : public QTabWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent widget
+ *
+ * @param name This widget's name
+ */
+ Smb4KSambaOptions( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSambaOptions();
+
+ /**
+ * This enumeration is used for the list view in the "Custom" tab.
+ */
+#ifndef __FreeBSD__
+ enum Columns{ ItemName = 0, Protocol = 1, FileSystem = 2, WriteAccess = 3, Kerberos = 4, UID = 5, GID = 6, Port = 7 };
+#else
+ enum Columns{ ItemName = 0, Protocol = 1, Kerberos = 2, UID = 3, GID = 4, Port = 5 };
+#endif
+
+ /**
+ * Reset the 'Custom' options tab.
+ */
+ void resetCustomTab();
+
+ signals:
+ /**
+ * This signal is emitted everytime the custom settings were changed by the
+ * user. That may mean, that only one setting has has been altered but also
+ * that all custom entries have been deleted. You have to figure out what
+ * happened in the slot that's connected to this signal.
+ */
+ void customSettingsChanged();
+
+ protected slots:
+ /**
+ * Enables/disables widgets according to the choice of the filesystem (SMBFS/CIFS).
+ *
+ * This slot is connected to the combo box that stores the file systems.
+ *
+ * @param item_index The index of the item in the combo box.
+ */
+ void slotSambaFileSystem( int item_index );
+
+ /**
+ * This slot is invoked if an item in the list of custom options has been
+ * clicked. It will put the values that are carried by the list view item
+ * into the editor combo boxes, num inputs, etc.
+ *
+ * @param item The item that has been clicked/highlighted.
+ */
+ void slotCustomItemClicked( QListViewItem *item );
+
+ /**
+ * Commit the new custom protocol to the list view item.
+ *
+ * @param index The index number of the new protocol
+ */
+ void slotCustomProtocolChanged( int index );
+
+ /**
+ * Commit the new custom file system to the list view item.
+ *
+ * @param index The index number of the new file system
+ */
+ void slotCustomFileSystemChanged( int index );
+
+ /**
+ * Commit the new custom write access setting to the list view item.
+ *
+ * @param index The index number of the new setting
+ */
+ void slotCustomWriteAccessChanged( int index );
+
+ /**
+ * Commit the new custom Kerberos setting to the list view item.
+ *
+ * @param index The index number of the new setting
+ */
+ void slotCustomKerberosChanged( int index );
+
+ /**
+ * Commit the new custom UID to the list view item.
+ *
+ * @param uid The new UID in text form
+ */
+ void slotCustomUIDChanged( const QString &uid );
+
+ /**
+ * This slot is invoked if the value for the custom GID setting changed.
+ *
+ * @param gid The new GID in text form
+ */
+ void slotCustomGIDChanged( const QString &gid );
+
+ /**
+ * Commit the new custom port number to the list view item.
+ *
+ * @param port The port number
+ */
+ void slotCustomPortChanged( int port );
+
+ /**
+ * Remove the highlighted item from the custom options list.
+ */
+ void slotRemoveCustomOption();
+
+ /**
+ * Remove all items from the custom options list.
+ */
+ void slotRemoveAllCustomOptions();
+};
+
+#endif
diff --git a/smb4k/configdlg/smb4kshareoptions.cpp b/smb4k/configdlg/smb4kshareoptions.cpp
new file mode 100644
index 0000000..aebd505
--- /dev/null
+++ b/smb4k/configdlg/smb4kshareoptions.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ smb4kshareoptions - The configuration page for the settings of
+ Smb4K regarding share management
+ -------------------
+ begin : Sa Nov 15 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kbuttonbox.h>
+#include <kurlrequester.h>
+#include <knuminput.h>
+
+// system includes
+#include <sys/types.h>
+#include <pwd.h>
+
+// applications specific includes
+#include "smb4kshareoptions.h"
+
+
+Smb4KShareOptions::Smb4KShareOptions( QWidget *parent, const char *name ) : QWidget( parent, name )
+{
+ QGridLayout *grid = new QGridLayout( this );
+ grid->setSpacing( 10 );
+
+ QGroupBox *dir_box = new QGroupBox( 1, Qt::Horizontal, i18n( "Directories" ), this );
+
+ QWidget *prefix_container = new QWidget( dir_box );
+ QGridLayout *prefix_layout = new QGridLayout( prefix_container );
+ prefix_layout->setSpacing( 10 );
+
+ QLabel *prefix = new QLabel( i18n( "Mount prefix:" ), prefix_container );
+ KURLRequester *mount_prefix = new KURLRequester( QString::null, prefix_container,
+ "kcfg_MountPrefix" );
+ mount_prefix->setMode( KFile::Directory );
+ prefix_layout->addWidget( prefix, 0, 0, 0 );
+ prefix_layout->addWidget( mount_prefix, 0, 1, 0 );
+
+ (void) new QCheckBox( i18n( "Force generated subdirectories to be lower case" ),
+ dir_box, "kcfg_ForceLowerCaseSubdirs" );
+
+ QButtonGroup *mount_box = new QButtonGroup( 1, QButtonGroup::Horizontal, i18n( "Mounting and Unmounting" ), this );
+ (void) new QCheckBox( i18n( "Unmount all shares of user %1 on exit" ).arg( getpwuid( getuid() )->pw_name ),
+ mount_box, "kcfg_UnmountSharesOnExit" );
+ (void) new QCheckBox( i18n( "Remount recently used shares on program start" ),
+ mount_box, "kcfg_RemountShares" );
+ (void) new QCheckBox( i18n( "Allow the unmounting of shares that are owned by other users" ),
+ mount_box, "kcfg_UnmountForeignShares" );
+
+ QGroupBox *checks_box = new QGroupBox( 2, QGroupBox::Horizontal, i18n( "Checks" ), this );
+
+ (void) new QLabel( i18n( "Interval between checks:" ), checks_box );
+ KIntNumInput *check_interval = new KIntNumInput( 2500, checks_box, 10,
+ "kcfg_CheckInterval" );
+ check_interval->setSuffix( " ms" );
+ check_interval->setRange( 500, 300000, 1, false );
+
+ QSpacerItem *spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ grid->addWidget( dir_box, 0, 0, 0 );
+ grid->addWidget( mount_box, 1, 0, 0 );
+ grid->addWidget( checks_box, 2, 0, 0 );
+ grid->addItem( spacer2, 3, 0 );
+}
+
+Smb4KShareOptions::~Smb4KShareOptions()
+{
+}
+
+
+#include "smb4kshareoptions.moc"
diff --git a/smb4k/configdlg/smb4kshareoptions.h b/smb4k/configdlg/smb4kshareoptions.h
new file mode 100644
index 0000000..cf45aa7
--- /dev/null
+++ b/smb4k/configdlg/smb4kshareoptions.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ smb4kshareoptions - The configuration page for the settings of
+ Smb4K regarding share management
+ -------------------
+ begin : Sa Nov 15 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHAREOPTIONS_H
+#define SMB4KSHAREOPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qwidget.h>
+
+/**
+ * This is the configuration tab for the settings that are
+ * used to manage the mounted shares.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KShareOptions : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent of this widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KShareOptions( QWidget *parent = 0, const char *name = 0 );
+ /**
+ * The destructor.
+ */
+ ~Smb4KShareOptions();
+};
+#endif
diff --git a/smb4k/configdlg/smb4ksuperuseroptions.cpp b/smb4k/configdlg/smb4ksuperuseroptions.cpp
new file mode 100644
index 0000000..d23b624
--- /dev/null
+++ b/smb4k/configdlg/smb4ksuperuseroptions.cpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ smb4ksuperuseroptions - The configuration page for the super user
+ settings of Smb4K
+ -------------------
+ begin : Sa Okt 30 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kguiitem.h>
+
+// application specific includes
+#include "smb4ksuperuseroptions.h"
+#include "../core/smb4ksettings.h"
+
+
+Smb4KSuperUserOptions::Smb4KSuperUserOptions( QWidget *parent, const char *name )
+: QWidget( parent, name )
+{
+ QGridLayout *grid = new QGridLayout( this );
+ grid->setSpacing( 10 );
+
+ QButtonGroup *suid_progs = new QButtonGroup( 1, QButtonGroup::Horizontal,
+ i18n( "Programs" ), this, "kcfg_SuperUserProgram" );
+ suid_progs->setInsideSpacing( 5 );
+
+ new QLabel( i18n( "Use the following program to gain super user privileges:" ), suid_progs );
+ suid_progs->insert( new QRadioButton( "sudo", suid_progs, "SudoButton" ), Smb4KSettings::EnumSuperUserProgram::Sudo );
+ suid_progs->insert( new QRadioButton( "super", suid_progs, "SuperButton" ), Smb4KSettings::EnumSuperUserProgram::Super );
+
+ QButtonGroup *suid_actions = new QButtonGroup( 1, QButtonGroup::Horizontal, i18n( "Actions" ), this, "SUIDActions" );
+ suid_actions->setInsideSpacing( 5 );
+#ifdef __linux__
+ (void) new QCheckBox( i18n( "Use super user privileges to force the unmounting of (inaccessible) shares" ), suid_actions, "kcfg_UseForceUnmount" );
+#endif
+ (void) new QCheckBox( i18n( "Use super user privileges to mount and unmount shares" ), suid_actions, "kcfg_AlwaysUseSuperUser" );
+
+ QSpacerItem *spacer1 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred );
+ KGuiItem remove_item = KGuiItem( i18n( "Remove Entries" ), "editdelete",
+ i18n( "Remove entries from the configuration file" ),
+ i18n( "Depending on your choice under \"Programs\", all entries that were written by Smb4K will be removed either from /etc/super.tab or /etc/sudoers. Additionally, all your choices under \"Actions\" will be cleared." ) );
+ KPushButton *remove = new KPushButton( remove_item, this, "RemoveButton" );
+
+ QSpacerItem *spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ grid->addMultiCellWidget( suid_progs, 0, 0, 0, 3, 0 );
+ grid->addMultiCellWidget( suid_actions, 1, 1, 0, 3, 0 );
+ grid->addMultiCell( spacer1, 2, 2, 0, 2, 0 );
+ grid->addWidget( remove, 2, 3, 0 );
+ grid->addMultiCell( spacer2, 3, 3, 0, 3, 0 );
+
+ connect( remove, SIGNAL( clicked() ),
+ this, SLOT( slotRemoveClicked() ) );
+}
+
+
+Smb4KSuperUserOptions::~Smb4KSuperUserOptions()
+{
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSuperUserOptions::slotRemoveClicked()
+{
+ // Emit the signal that the removal of the super user
+ // entries has been requested.
+ emit removeEntries();
+}
+
+#include "smb4ksuperuseroptions.moc"
diff --git a/smb4k/configdlg/smb4ksuperuseroptions.h b/smb4k/configdlg/smb4ksuperuseroptions.h
new file mode 100644
index 0000000..86c705e
--- /dev/null
+++ b/smb4k/configdlg/smb4ksuperuseroptions.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ smb4ksuperuseroptions - The configuration page for the super user
+ settings of Smb4K
+ -------------------
+ begin : Sa Okt 30 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSUPERUSEROPTIONS_H
+#define SMB4KSUPERUSEROPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qwidget.h>
+
+/**
+ * This is the configuration tab where the user can determine
+ * whether he/she wants to use the program super or sudo to
+ * gain super user privileges.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSuperUserOptions : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KSuperUserOptions( QWidget *parent = 0, const char *name = 0 );
+ /**
+ * The destructor
+ */
+ ~Smb4KSuperUserOptions();
+
+ signals:
+ /**
+ * This signal is emitted when the "Remove Entries" button has been
+ * clicked. It is provided for convenience. You could also connect
+ * to the clicked() signal.
+ */
+ void removeEntries();
+
+ protected slots:
+ /**
+ * This slot is activated when the "Remove Entries" button has been
+ * clicked.
+ */
+ void slotRemoveClicked();
+};
+
+#endif
diff --git a/smb4k/configdlg/smb4kuserinterfaceoptions.cpp b/smb4k/configdlg/smb4kuserinterfaceoptions.cpp
new file mode 100644
index 0000000..c4310fe
--- /dev/null
+++ b/smb4k/configdlg/smb4kuserinterfaceoptions.cpp
@@ -0,0 +1,207 @@
+/***************************************************************************
+ smb4kuserinterfaceoptions - This configuration page takes care
+ of all settings concerning the user interface of Smb4K
+ -------------------
+ begin : Mi Aug 30 2006
+ copyright : (C) 2006-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+
+// KDE includes
+#include <klocale.h>
+
+// application specific includes
+#include "smb4kuserinterfaceoptions.h"
+#include "../core/smb4ksettings.h"
+
+Smb4KUserInterfaceOptions::Smb4KUserInterfaceOptions( QWidget *parent, const char *name )
+: QTabWidget( parent, name )
+{
+ setMargin( 10 );
+
+ //
+ // Configuration for the main window:
+ //
+ QWidget *main_wd_widget = new QWidget( this );
+ QGridLayout *main_wd_layout = new QGridLayout( main_wd_widget );
+ main_wd_layout->setSpacing( 10 );
+
+ QButtonGroup *shares_view = new QButtonGroup( 1, Qt::Horizontal, i18n( "Shares View" ),
+ main_wd_widget, "kcfg_SharesView" );
+
+ shares_view->insert( new QRadioButton( i18n( "Show mounted shares in an icon view" ), shares_view ), Smb4KSettings::EnumSharesView::IconView );
+
+ shares_view->insert( new QRadioButton( i18n( "Show mounted shares in a list view" ), shares_view ), Smb4KSettings::EnumSharesView::ListView );
+
+ QButtonGroup *bookmarks_grp = new QButtonGroup( 1, Qt::Horizontal, i18n( "Bookmarks" ),
+ main_wd_widget, "BookmarksBox" );
+
+ (void) new QCheckBox( i18n( "Show custom bookmark label if available" ), bookmarks_grp, "kcfg_ShowCustomBookmarkLabel" );
+
+ QButtonGroup *tray_group = new QButtonGroup( 1, Qt::Horizontal, i18n( "System Tray" ),
+ main_wd_widget, "SystemTrayBox" );
+
+ (void) new QCheckBox( i18n( "Embed application into the system tray" ), tray_group, "kcfg_EmbedIntoSystemTray" );
+
+ QSpacerItem *spacer1 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ main_wd_layout->addWidget( shares_view, 0, 0, 0 );
+ main_wd_layout->addWidget( bookmarks_grp, 1, 0, 0 );
+ main_wd_layout->addWidget( tray_group, 2, 0, 0 );
+ main_wd_layout->addItem( spacer1, 3, 0 );
+
+ //
+ // Configuration for the network browser:
+ //
+ QWidget *browser_widget = new QWidget( this );
+ QGridLayout *browser_layout = new QGridLayout( browser_widget );
+ browser_layout->setSpacing( 10 );
+
+ QButtonGroup *remoteGroup = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "Remote Shares" ),
+ browser_widget, "BrowserRemoteSharesBox" );
+ (void) new QCheckBox( i18n( "Show printer shares" ), remoteGroup, "kcfg_ShowPrinterShares" );
+ QCheckBox *hidden = new QCheckBox( i18n( "Show hidden shares" ), remoteGroup, "kcfg_ShowHiddenShares" );
+ (void) new QCheckBox( i18n( "Show IPC$ shares" ), remoteGroup, "kcfg_ShowHiddenIPCShares" );
+ (void) new QCheckBox( i18n( "Show ADMIN$ shares" ), remoteGroup, "kcfg_ShowHiddenADMINShares" );
+
+ QButtonGroup *columnsGroup = new QButtonGroup( 2, QButtonGroup::Horizontal, i18n( "Columns" ),
+ browser_widget, "BrowserColumnsBox" );
+ (void) new QCheckBox( i18n( "Show type" ), columnsGroup, "kcfg_ShowType" );
+ (void) new QCheckBox( i18n( "Show IP address" ), columnsGroup, "kcfg_ShowIPAddress" );
+ (void) new QCheckBox( i18n( "Show comment" ), columnsGroup, "kcfg_ShowComment" );
+
+ QButtonGroup *netTooltipsGroup = new QButtonGroup( 1, QButtonGroup::Horizontal, i18n( "Tooltips" ),
+ browser_widget, "BrowserTooltipsBox" );
+ (void) new QCheckBox( i18n( "Show tooltip with information about a network item" ), netTooltipsGroup, "kcfg_ShowNetworkItemToolTip" );
+
+ QSpacerItem *spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ browser_layout->addWidget( remoteGroup, 0, 0, 0 );
+ browser_layout->addWidget( columnsGroup, 1, 0, 0 );
+ browser_layout->addWidget( netTooltipsGroup, 2, 0, 0 );
+ browser_layout->addItem( spacer2, 3, 0 );
+
+ //
+ // Configuration for the shares view
+ //
+ QWidget *shares_widget = new QWidget( this );
+ QGridLayout *shares_layout = new QGridLayout( shares_widget );
+ shares_layout->setSpacing( 10 );
+
+ QButtonGroup *shares_group = new QButtonGroup( 1, Qt::Horizontal, i18n( "Mounted Shares" ),
+ shares_widget, "SharesIconGroupBox" );
+ (void) new QCheckBox( i18n( "Show mount point instead of share name" ), shares_group, "kcfg_ShowMountPoint" );
+ (void) new QCheckBox( i18n( "Show all shares that are mounted on the system" ), shares_group, "kcfg_ShowAllShares" );
+
+ QButtonGroup *dnd_group = new QButtonGroup( 1, Qt::Horizontal, i18n( "Drag and Drop" ),
+ shares_widget, "DragnDropBox" );
+ (void) new QCheckBox( i18n( "Allow dropping of files and directories onto shares" ), dnd_group, "kcfg_EnableDropSupport" );
+ (void) new QCheckBox( i18n( "Allow dragging of shares" ), dnd_group, "kcfg_EnableDragSupport" );
+
+ QButtonGroup *sharesTooltipGroup = new QButtonGroup( 1, Qt::Horizontal, i18n( "Tooltips" ),
+ shares_widget, "SharesTooltipsBox" );
+ (void) new QCheckBox( i18n( "Show tooltip with information about a share" ), sharesTooltipGroup, "kcfg_ShowShareToolTip" );
+
+ QButtonGroup *list_view_group = new QButtonGroup( 2, Qt::Horizontal, i18n( "List View" ),
+ shares_widget, "SharesListViewBox" );
+
+#ifndef __FreeBSD__
+ (void) new QCheckBox( i18n( "Show owner and group (SMBFS only)" ), list_view_group, "kcfg_ShowOwner" );
+ (void) new QCheckBox( i18n( "Show login (CIFS only)" ), list_view_group, "kcfg_ShowLogin" );
+#else
+ (void) new QCheckBox( i18n( "Show owner and group" ), list_view_group, "kcfg_ShowOwner" );
+#endif
+ (void) new QCheckBox( i18n( "Show file system" ), list_view_group, "kcfg_ShowFileSystem" );
+ (void) new QCheckBox( i18n( "Show free disk space" ), list_view_group, "kcfg_ShowFreeDiskSpace" );
+ (void) new QCheckBox( i18n( "Show used disk space" ), list_view_group, "kcfg_ShowUsedDiskSpace" );
+ (void) new QCheckBox( i18n( "Show total disk space" ), list_view_group, "kcfg_ShowTotalDiskSpace" );
+ (void) new QCheckBox( i18n( "Show disk usage" ), list_view_group, "kcfg_ShowDiskUsage" );
+
+ QSpacerItem *spacer3 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ shares_layout->addWidget( shares_group, 0, 0, 0 );
+ shares_layout->addWidget( dnd_group, 1, 0, 0 );
+ shares_layout->addWidget( sharesTooltipGroup, 2, 0, 0 );
+ shares_layout->addWidget( list_view_group, 3, 0, 0 );
+ shares_layout->addItem( spacer3, 4, 0 );
+
+ //
+ // Configuration for the preview dialog
+ //
+ QWidget *preview_widget = new QWidget( this );
+ QGridLayout *preview_layout = new QGridLayout( preview_widget );
+ preview_layout->setSpacing( 10 );
+
+ QButtonGroup *previewFilesGroup = new QButtonGroup( 1, QButtonGroup::Horizontal, i18n( "Hidden Files and Directories" ), preview_widget, "HiddenFilesBox" );
+ (void) new QCheckBox( i18n( "Preview hidden files and directories" ), previewFilesGroup, "kcfg_PreviewHiddenItems" );
+
+ QSpacerItem *spacer4 = new QSpacerItem( 0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding );
+
+ preview_layout->addWidget( previewFilesGroup, 0, 0, 0 );
+ preview_layout->addItem( spacer4, 1, 0 );
+
+ //
+ // Add tabs:
+ //
+ addTab( main_wd_widget, i18n( "Main Window && System Tray" ) );
+ addTab( browser_widget, i18n( "Network Browser" ) );
+ addTab( shares_widget, i18n( "Shares View" ) );
+ addTab( preview_widget, i18n( "Preview Dialog" ) );
+
+ // Add connections:
+ connect( hidden, SIGNAL( stateChanged( int ) ),
+ this, SLOT( slotShowHiddenShares( int ) ) );
+
+ // Do last adjustments:
+ slotShowHiddenShares( hidden->state() );
+}
+
+
+Smb4KUserInterfaceOptions::~Smb4KUserInterfaceOptions()
+{
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+
+void Smb4KUserInterfaceOptions::slotShowHiddenShares( int state )
+{
+ if ( state == QCheckBox::On )
+ {
+ static_cast<QCheckBox *>( child( "kcfg_ShowHiddenIPCShares", "QCheckBox" ) )->setEnabled( true );
+ static_cast<QCheckBox *>( child( "kcfg_ShowHiddenADMINShares", "QCheckBox" ) )->setEnabled( true );
+ }
+ else if ( state == QCheckBox::Off )
+ {
+ static_cast<QCheckBox *>( child( "kcfg_ShowHiddenIPCShares", "QCheckBox" ) )->setEnabled( false );
+ static_cast<QCheckBox *>( child( "kcfg_ShowHiddenADMINShares", "QCheckBox" ) )->setEnabled( false );
+ }
+}
+
+#include "smb4kuserinterfaceoptions.moc"
diff --git a/smb4k/configdlg/smb4kuserinterfaceoptions.h b/smb4k/configdlg/smb4kuserinterfaceoptions.h
new file mode 100644
index 0000000..6fb7e64
--- /dev/null
+++ b/smb4k/configdlg/smb4kuserinterfaceoptions.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ smb4kuserinterfaceoptions - This configuration page takes care
+ of all settings concerning the user interface of Smb4K
+ -------------------
+ begin : Mi Aug 30 2006
+ copyright : (C) 2006-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KUSERINTERFACEOPTIONS_H
+#define SMB4KUSERINTERFACEOPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qtabwidget.h>
+
+
+/**
+ * The configuration page for the user interface of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KUserInterfaceOptions : public QTabWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ */
+ Smb4KUserInterfaceOptions( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KUserInterfaceOptions();
+
+ protected slots:
+ /**
+ * Enables/disables buttons according to the toggle state of the "Show hidden shares" button.
+ *
+ * @param state Describes the toggle state of the "Show hidden shares" checkbox.
+ */
+ void slotShowHiddenShares( int state );
+};
+
+#endif
diff --git a/smb4k/core/Makefile.am b/smb4k/core/Makefile.am
new file mode 100644
index 0000000..955df6d
--- /dev/null
+++ b/smb4k/core/Makefile.am
@@ -0,0 +1,35 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+lib_LTLIBRARIES = libsmb4kcore.la
+libsmb4kcore_la_LDFLAGS = -no-undefined $(all_libraries) -lkwalletclient \
+ -version-info 2:0:0
+include_HEADERS = smb4kauthinfo.h smb4kbookmark.h smb4kbookmarkhandler.h \
+ smb4kcore.h smb4kdefs.h smb4kerror.h smb4kfileio.h smb4kglobal.h \
+ smb4khomesshareshandler.h smb4kmounter.h smb4knetworkitems.h \
+ smb4kpasswordhandler.h smb4kpreviewer.h smb4kpreviewitem.h \
+ smb4kprint.h smb4kprintinfo.h smb4ksambaoptionshandler.h \
+ smb4ksambaoptionsinfo.h smb4kscanner.h smb4kshare.h \
+ smb4ksynchronizationinfo.h smb4ksynchronizer.h
+libsmb4kcore_la_SOURCES = smb4kauthinfo.cpp smb4kbookmark.cpp \
+ smb4kbookmarkhandler.cpp smb4kcore.cpp smb4kerror.cpp smb4kfileio.cpp smb4kglobal.cpp \
+ smb4kglobal_p.cpp smb4khomesshareshandler.cpp smb4kmounter.cpp smb4kmounter_p.cpp \
+ smb4knetworkitems.cpp smb4kpasswordhandler.cpp smb4kpreviewer.cpp smb4kpreviewitem.cpp \
+ smb4kprint.cpp smb4kprintinfo.cpp smb4ksambaoptionshandler.cpp \
+ smb4ksambaoptionsinfo.cpp smb4kscanner.cpp smb4kscanner_p.cpp smb4ksettings.kcfgc smb4kshare.cpp \
+ smb4ksynchronizationinfo.cpp smb4ksynchronizer.cpp
+libsmb4kcore_la_LIBADD = $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) $(LIB_QT)
+
+kde_kcfg_DATA = smb4k.kcfg
+
+# Build rules
+smb4kcore.lo: smb4ksettings.h
+smb4kfileio.lo: smb4ksettings.h
+smb4kmounter.lo: smb4ksettings.h
+smb4kpasswordhandler.lo: smb4ksettings.h
+smb4kprint.lo: smb4ksettings.h
+smb4ksambaoptionshandler.lo: smb4ksettings.h
+smb4kscanner.lo: smb4ksettings.h
+smb4ksynchronizer.lo: smb4ksettings.h
+
+noinst_HEADERS = smb4kglobal_p.h smb4kmounter_p.h smb4kscanner_p.h
diff --git a/smb4k/core/smb4k.kcfg b/smb4k/core/smb4k.kcfg
new file mode 100644
index 0000000..45a2ead
--- /dev/null
+++ b/smb4k/core/smb4k.kcfg
@@ -0,0 +1,998 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
+<kcfg>
+ <include>unistd.h</include>
+ <include>sys/types.h</include>
+ <include>qstring.h</include>
+ <kcfgfile name="smb4krc" />
+
+<!-- Programs -->
+
+ <group name="Programs">
+ <entry name="grep" type="Path">
+ <label>The path to the program "grep"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="awk" type="Path">
+ <label>The path to the program "awk"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="sed" type="Path">
+ <label>The path to the program "sed"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="xargs" type="Path">
+ <label>The path to the program "xargs"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="rmdir" type="Path">
+ <label>The path to the program "rmdir"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="nmblookup" type="Path">
+ <label>The path to the program "nmblookup"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smbclient" type="Path">
+ <label>The path to the program "smbclient"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smbspool" type="Path">
+ <label>The path to the program "smbspool"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="net" type="Path">
+ <label>The path to the program "net"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="mount_cifs" type="Path">
+ <label>The path to the program "mount.cifs"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="umount_cifs" type="Path">
+ <label>The path to the program "umount.cifs"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smbmount" type="Path">
+ <label>The path to the program "smbmount"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smbumount" type="Path">
+ <label>The path to the program "smbumount"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="mount" type="Path">
+ <label>The path to the program "mount"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="mount_smbfs" type="Path">
+ <label>The path to the program "mount_smbfs" (FreeBSD only)</label>
+ <whatsthis></whatsthis>
+ </entry>
+ <entry name="smbutil" type="Path">
+ <label>The path to the program "smbutil" (FreeBSD only)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="umount" type="Path">
+ <label>The path to the program "umount"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smb4k_mount" type="Path">
+ <label>The path to the program "smb4k_mount"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smb4k_umount" type="Path">
+ <label>The path to the program "smb4k_umount"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smb4k_kill" type="Path">
+ <label>The path to the program "smb4k_kill"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smb4k_cat" type="Path">
+ <label>The path to the program "smb4k_cat"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="smb4k_mv" type="Path">
+ <label>The path to the program "smb4k_mv"</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="super" type="Path">
+ <label>The path to the program "super" (optional)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="sudo" type="Path">
+ <label>The path to the program "sudo" (optional)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="dvips" type="Path">
+ <label>The path to the program "dvips" (optional)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="enscript" type="Path">
+ <label>The path to the program "enscript" (optional)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="rsync" type="Path">
+ <label>The path to the program "rsync" (optional)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ <entry name="konsole" type="Path">
+ <label>The path to the program "konsole" (optional)</label>
+ <whatsthis></whatsthis>
+ <!-- Default will be set by Smb4KCore::searchPrograms() -->
+ </entry>
+ </group>
+
+<!-- User Interface -->
+
+ <group name="UserInterface">
+ <entry name="ShowCustomBookmarkLabel" type="Bool">
+ <label>Show custom bookmark label if available</label>
+ <whatsthis>Do not show the name of the share that is represented by the bookmark but the custom label that was defined in the bookmark editor.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="EmbedIntoSystemTray" type="Bool">
+ <label>Embed application into system tray</label>
+ <whatsthis>Embed the application into the system tray. The system tray widget provides a popup menu with several commonly used tasks so that you do not need to bring up the main window everytime. If this setting is chosen you have to use "Quit" from the "File" menu or the system tray widget to exit the application.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="StartMainWindowDocked" type="Bool">
+ <label>Start docked</label>
+ <whatsthis>Start the application docked to the system tray, i.e. only the system tray widget is shown and the main window is hidden. You can bring the main window up by clicking on the system tray widget or by choosing "Restore" from its popup menu.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="SharesView" type="Enum">
+ <label>How the shares should be displayed</label>
+ <whatsthis>Choose the kind of view you prefer for displaying the mounted shares. There is an icon view or a list view available.</whatsthis>
+ <choices>
+ <choice name="IconView"/>
+ <choice name="ListView"/>
+ </choices>
+ <default>IconView</default>
+ </entry>
+ <entry name="ShowPrinterShares" type="Bool">
+ <label>Show printer shares</label>
+ <whatsthis>Printer shares will be displayed in the network browser.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowHiddenShares" type="Bool">
+ <label>Show hidden shares</label>
+ <whatsthis>Hidden shares will be displayed in the network browser. Hidden shares are ending with a $ sign, e.g. Musik$ or IPC$.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowHiddenIPCShares" type="Bool">
+ <label>Show hidden IPC$ shares</label>
+ <whatsthis>Hidden IPC$ shares will be displayed in the network browser.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowHiddenADMINShares" type="Bool">
+ <label>Show hidden ADMIN$ shares</label>
+ <whatsthis>Hidden ADMIN$ shares will be displayed in the network browser.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowType" type="Bool">
+ <label>Show the type of a share</label>
+ <whatsthis>The type of a share will be displayed in a separate column in the network browser. It can either be Disk, Print or IPC.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowIPAddress" type="Bool">
+ <label>Show the IP address of a server</label>
+ <whatsthis>The IP address of the server will be displayed in a separate column in the network browser.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowComment" type="Bool">
+ <label>Show the comment of a share</label>
+ <whatsthis>The comment describing the server or share will be displayed in a separate column in the network browser.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowNetworkItemToolTip" type="Bool">
+ <label>Show a tooltip with information about the network item</label>
+ <whatsthis>The tooltip shows various information about the current network item.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowMountPoint" type="Bool">
+ <label>Show the mount point of a share instead of its name</label>
+ <whatsthis>A share is normally displayed with its name in the shares view. Choosing this feature will cause the exchange of the share name by the mount point.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowAllShares" type="Bool">
+ <label>Show all shares that are mounted on the system</label>
+ <whatsthis>You will not only see the shares that were mounted and are owned by you, but also all other mounts using the SMBFS and CIFS file system that are present on the system.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="EnableDropSupport" type="Bool">
+ <label>Allow the dropping of files and directories onto share icons</label>
+ <whatsthis>This setting allows you to drop files or whole directories onto the share icons, which will cause them to be copied.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="EnableDragSupport" type="Bool">
+ <label>Allow the dragging of share icons</label>
+ <whatsthis>This setting allows you to drag a share item out of Smb4K and onto the desktop or into a file manager. Only enable it if you think you absolutely need it and read the handbook before you mark this checkbox.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowShareToolTip" type="Bool">
+ <label>Show a tooltip with information about the share</label>
+ <whatsthis>The tooltip shows various information about the current share.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="PreviewHiddenItems" type="Bool">
+ <label>Show hidden files and directories when previewing a share</label>
+ <whatsthis>Display hidden files and directories in the preview dialog. The names of hidden files and directories are beginning with a period and are usually needed for very specific purposes (configuration file of an application, etc.). Since they are not of any importance for your regular work, you normally do not need to enable this feature.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowOwner" type="Bool">
+ <label>Show owner and group (SMBFS only)</label>
+ <whatsthis>Show the UID and GID that own all files on the mounted file system. At the moment the column will only contain an entry if the share was mounted with the SMBFS file system.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowLogin" type="Bool">
+ <label>Show login (CIFS only)</label>
+ <whatsthis>Show the login that was used to authenticate to the server. The column will only contain an entry if the share was mounted with the CIFS file system.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowFileSystem" type="Bool">
+ <label>Show file system</label>
+ <whatsthis>Show the file system that was used for mounting the share.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ShowFreeDiskSpace" type="Bool">
+ <label>Show free disk space</label>
+ <whatsthis>Show the free disk space that is left on the share.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowUsedDiskSpace" type="Bool">
+ <label>Show used disk space</label>
+ <whatsthis>Show the disk space that is already used on the share.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowTotalDiskSpace" type="Bool">
+ <label>Show total disk space</label>
+ <whatsthis>Show the total disk space of the share.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ShowDiskUsage" type="Bool">
+ <label>Show disk usage</label>
+ <whatsthis>Show the space that is used on the share in percent.</whatsthis>
+ <default>true</default>
+ </entry>
+ </group>
+
+<!-- Network -->
+
+ <group name="Network">
+ <entry name="BrowseList" type="Enum">
+ <label>Method how to retrieve the browse list</label>
+ <whatsthis>Choose the method how to compile the initial browse list. There are four options available: The first one is the default one and employs "nmblookup -M -- -" to discover all workgroups, domains, and their master browsers on your network neighborhood. The second one instructs Smb4K to query the current master browser of your workgroup or domain to retrieve the browse list. The third is similar to the second one except that you can define the master browser that should be queried. If you choose the last option, the provided list of broadcast areas will be scanned using "nmblookup -B x.x.x.x -- '*'".</whatsthis>
+ <choices>
+ <choice name="LookupDomains"/>
+ <choice name="QueryCurrentMaster"/>
+ <choice name="QueryCustomMaster"/>
+ <choice name="ScanBroadcastAreas"/>
+ </choices>
+ <default>LookupDomains</default>
+ </entry>
+ <entry name="CustomMasterBrowser" type="String">
+ <label>A custom master browser that is to be queried</label>
+ <whatsthis>Enter the name or IP address of a master browser here that should be queried to compile the initial browse list.</whatsthis>
+ </entry>
+ <entry name="BroadcastAreas" type="String">
+ <label>A custom list of broadcast addresses</label>
+ <whatsthis>Enter a comma-separated list of broadcast addresses here (e.g. 192.168.0.255, 192.168.1.255). It is used to scan for all known hosts in the respective broadcast areas.</whatsthis>
+ </entry>
+ <entry name="SearchMethod" type="Enum">
+ <label>Method for searching for remote hosts</label>
+ <whatsthis>Smb4K is able to search for remote hosts either using nmblookup or smbclient. The nmblookup method is very reliable and works well. However, if your network is configured uncommonly and you experience problems when searching, you should try the smbclient method. But please note that you lose the ability to search for IP addresses in that case.</whatsthis>
+ <choices>
+ <choice name="Nmblookup"/>
+ <choice name="Smbclient"/>
+ </choices>
+ <default>Nmblookup</default>
+ </entry>
+ </group>
+
+<!-- Shares -->
+
+ <group name="Shares">
+ <entry name="MountPrefix" type="Path">
+ <label>The mount prefix</label>
+ <whatsthis>This is the prefix where Smb4K will create the mount points and mount the remote shares.</whatsthis>
+ <default>${HOME}/smb4k/</default>
+ </entry>
+ <entry name="ForceLowerCaseSubdirs" type="Bool">
+ <label>Force the subdirectories created by Smb4K to be lowercase</label>
+ <whatsthis>All names of the subdirectories created by Smb4K below the mount prefix will be lowercase.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UnmountSharesOnExit" type="Bool">
+ <label>Unmount the shares owned by the user on exit</label>
+ <whatsthis>Unmount all shares that belong to you when the program exits.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="RemountShares" type="Bool">
+ <label>Remount shares</label>
+ <whatsthis>Remount all your shares that were still mounted when you exited the program. Shares that were mounted by other users are ignored.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UnmountForeignShares" type="Bool">
+ <label>Allow the unmounting of shares owned by other users</label>
+ <whatsthis>Allow the unmounting of shares that were mounted by other users. In most cases you need super user privileges for this. Please think before you enable this option!</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="CheckInterval" type="Int">
+ <label>Interval between checks for new and inaccessible shares</label>
+ <whatsthis>This is the time that elapses until Smb4K checks again for new mounts and unmounts. The lower limit is 500 ms, the upper one 300000 ms. Please note that the smaller the interval gets the higher is your system load.</whatsthis>
+ <min>500</min>
+ <max>300000</max>
+ <default>2500</default>
+ </entry>
+ </group>
+
+<!-- Authentication -->
+
+ <group name="Authentication">
+ <entry name="UseWallet" type="Bool">
+ <label>Use a wallet to store authentication data</label>
+ <whatsthis>Use a wallet to store the authentication data. The login name and the password name are stored encrypted on your hard drive. If this setting is disabled, the authentication data is not stored permanently but only temporarily.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="RememberPasswords" type="Bool">
+ <label>Remember passwords if no wallet is used</label>
+ <whatsthis>If you decided to store the login names and passwords only temporarily, Smb4K will remember them until the program exits. If you disable this setting, you will have to provide the authentication data everytime it is needed.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="UseDefaultLogin" type="Bool">
+ <label>Use a default login</label>
+ <whatsthis>Enable the usage of a default login name and password. The authentication data provided below is then used by default to authenticate to a remote server. This is very useful e.g. if you are working in an Active Directory environment or an NT domain.</whatsthis>
+ <default>false</default>
+ </entry>
+<!-- <entry name="DefaultUserName" type="String">
+ <label>The default user name for authentication</label>
+ <whatsthis>This login name is used by default to authenticate to a remote server.</whatsthis>
+ </entry>
+ <entry name="DefaultPassword" type="String">
+ <label>The default password for authentication</label>
+ <whatsthis>This password is used by default to authenticate to a remote server. It may be empty.</whatsthis>
+ </entry>-->
+ </group>
+
+<!-- Samba -->
+
+ <group name="Samba">
+ <entry name="NetBIOSName" type="String">
+ <label>The NetBIOS name of this computer</label>
+ <whatsthis>This is the NetBIOS name of this computer that is used by Smb4K. By default, it is either the NetBIOS name that is defined in the smb.conf file or the host name.</whatsthis>
+ <!-- Will be filled by Smb4KCore::setDefaultConfigValues() -->
+ </entry>
+ <entry name="DomainName" type="String">
+ <label>The name of the workgroup/domain this computer is in</label>
+ <whatsthis>This is the workgroup or domain this computer is or should be in. By default, it is the workgroup that is defined in the smb.conf file.</whatsthis>
+ <!-- Will be filled by Smb4KCore::setDefaultConfigValues() -->
+ </entry>
+ <entry name="SocketOptions" type="String">
+ <label>The socket options</label>
+ <whatsthis>These are the TCP socket options that are used by nmblookup, smbmount and smbclient. Socket options are controls on the networking layer of the operating systems which allow the connection to be tuned. See the manual page of smb.conf for more information.</whatsthis>
+ <!-- Will be filled by Smb4KCore::setDefaultConfigValues() -->
+ </entry>
+ <entry name="NetBIOSScope" type="String">
+ <label>The NetBIOS scope</label>
+ <whatsthis>This sets the NetBIOS scope that nmblookup, smbmount and smbclient will operate under. It should not be set unless every machine on your network neighborhood sets this value.</whatsthis>
+ <!-- Will be filled by Smb4KCore::setDefaultConfigValues() -->
+ </entry>
+ <entry name="RemotePort" type="Int">
+ <label>The remote SMB port</label>
+ <whatsthis>This is the port that is to be used for connecting to remote servers. Please note that this is independent of the settings in the smb.conf file.</whatsthis>
+ <min>1</min>
+ <max>65535</max>
+ <default>139</default>
+ </entry>
+ <entry name="UseKerberos" type="Bool">
+ <label>Use Kerberos for authentication</label>
+ <whatsthis>Try to authenticate with Kerberos. This is only useful in an Active Directory environment. The setting affects the smbmount and smbclient command.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="MachineAccount" type="Bool">
+ <label>Use machine account for login</label>
+ <whatsthis>Make queries to the remote server using the machine account of the local server. The setting affects the net and the smbclient command.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="Filesystem" type="Enum">
+ <label>The file system that is used for mounting remote shares</label>
+ <whatsthis>This is the file system that will be used to mount the remote shares. The Common Internet File System (CIFS) is supported by Windows 2000 and above as well as by Samba. It offers many improvements and advancements compared to the Server Message Block File System (SMBFS) which is used by Windows 9x and below.</whatsthis>
+ <choices>
+ <choice name="CIFS"/>
+ <choice name="SMBFS"/>
+ </choices>
+ <default>CIFS</default>
+ </entry>
+ <entry name="ClientCharset" type="Enum">
+ <label>The charset used by the client</label>
+ <whatsthis>This is the charset that is used by the client side (i.e. your side) either to convert local path names to and from Unicode in case of the CIFS file system or for codepage to charset translations (NLS) in case of the SMBFS file system. If you keep the default setting, Smb4K will try to automatically determine the charset by looking up the "unix charset" option in the smb.conf.</whatsthis>
+ <choices>
+ <choice name="default_charset"/>
+ <choice name="iso8859_1"/>
+ <choice name="iso8859_2"/>
+ <choice name="iso8859_3"/>
+ <choice name="iso8859_4"/>
+ <choice name="iso8859_5"/>
+ <choice name="iso8859_6"/>
+ <choice name="iso8859_7"/>
+ <choice name="iso8859_8"/>
+ <choice name="iso8859_9"/>
+ <choice name="iso8859_13"/>
+ <choice name="iso8859_14"/>
+ <choice name="iso8859_15"/>
+ <choice name="utf8"/>
+ <choice name="koi8_r"/>
+ <choice name="koi8_u"/>
+ <choice name="koi8_ru"/>
+ <choice name="cp1251"/>
+ <choice name="gb2312"/>
+ <choice name="big5"/>
+ <choice name="euc_jp"/>
+ <choice name="euc_kr"/>
+ <choice name="tis_620"/>
+ </choices>
+ <default>default_charset</default>
+ </entry>
+ <entry name="ServerCodepage" type="Enum">
+ <label>The codepage used by the server</label>
+ <whatsthis>This is the codepage that is used by the server. The setting is only available with the SMBFS file system. If you keep the default setting, Smb4K will try to automatically determine the codepage by looking up the "dos charset" option in the smb.conf.</whatsthis>
+ <choices>
+ <choice name="default_codepage"/>
+ <choice name="cp437"/>
+ <choice name="cp720"/>
+ <choice name="cp737"/>
+ <choice name="cp775"/>
+ <choice name="cp850"/>
+ <choice name="cp852"/>
+ <choice name="cp855"/>
+ <choice name="cp857"/>
+ <choice name="cp858"/>
+ <choice name="cp860"/>
+ <choice name="cp861"/>
+ <choice name="cp862"/>
+ <choice name="cp863"/>
+ <choice name="cp864"/>
+ <choice name="cp865"/>
+ <choice name="cp866"/>
+ <choice name="cp869"/>
+ <choice name="cp874"/>
+ <choice name="cp932"/>
+ <choice name="cp936"/>
+ <choice name="cp949"/>
+ <choice name="cp950"/>
+ <choice name="cp1250"/>
+ <choice name="cp1251"/>
+ <choice name="cp1252"/>
+ <choice name="cp1253"/>
+ <choice name="cp1254"/>
+ <choice name="cp1255"/>
+ <choice name="cp1256"/>
+ <choice name="cp1257"/>
+ <choice name="cp1258"/>
+ <choice name="unicode"/>
+ </choices>
+ <default>default_codepage</default>
+ </entry>
+ <entry name="UserID" type="String">
+ <label>The user ID that is to be used for mounting</label>
+ <whatsthis>Here you can enter the user ID (a number) that the files and directories of the mounted share will have. If you are using the CIFS file system and the remote server supports the CIFS Unix Extentions, this setting will be ignored.</whatsthis>
+ <default code="true">QString( "%1" ).arg( (int)getuid() )</default>
+ </entry>
+ <entry name="GroupID" type="String">
+ <label>The group ID that is to be used for mounting</label>
+ <whatsthis>Here you can enter the group ID (a number) that the files and directories of the mounted share will have. If you are using the CIFS file system and the remote server supports the CIFS Unix Extentions, this setting will be ignored.</whatsthis>
+ <default code="true">QString( "%1" ).arg( (int)getgid() )</default>
+ </entry>
+ <entry name="FileMask" type="String">
+ <label>The file mask for a share</label>
+ <whatsthis>This is the mask that will be used for creating files. It must be defined in octal. In case the CIFS file system is used, this setting only takes effect if the server does not support the CIFS Unix Extensions.</whatsthis>
+ <default>0755</default>
+ </entry>
+ <entry name="DirectoryMask" type="String">
+ <label>The directory mask for a share</label>
+ <whatsthis>This is the mask that will be used for creating directories. It must be defined in octal. In case the CIFS file system is used, this setting only takes effect if the server does not support the CIFS Unix Extensions.</whatsthis>
+ <default>0755</default>
+ </entry>
+ <entry name="WriteAccess" type="Enum">
+ <label>The write access granted for the share</label>
+ <whatsthis>Here you can choose if the shares should be mounted in read and write mode or only read-only.</whatsthis>
+ <choices>
+ <choice name="ReadWrite"/>
+ <choice name="ReadOnly"/>
+ </choices>
+ <default>ReadWrite</default>
+ </entry>
+ <entry name="PermissionChecks" type="Bool">
+ <label>Do permission checks</label>
+ <whatsthis>The client side (i.e. your side) will check if you have the right UID/GID to manipulate a file or directory. You might want to switch this feature off if the server(s) support the CIFS Unix Extensions and you are not allowed to access the files and directories. This setting does not affect the normal ACL check.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="ClientControlsIDs" type="Bool">
+ <label>Set UID and GID</label>
+ <whatsthis>In case the server supports the CIFS Unix Extensions, the client side (i.e. your side) attempts to set the effective UID and GID of the current process on newly created files, directories and devices. If this feature is turned off, the default UID and GID defined for the share will be used. It is recommended that you read the manual page of mount.cifs before you change this setting.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ServerInodeNumbers" type="Bool">
+ <label>Use server inode numbers</label>
+ <whatsthis>Use inode numbers (unique persistent file identifiers) returned by the server instead of automatically generating temporary inode numbers on the client side.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="InodeDataCaching" type="Bool">
+ <label>Do not cache inode data</label>
+ <whatsthis>Directly read from and write to files opened on the share. In some cases this can provide better performance than the default behavior which caches reads and writes.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="TranslateReservedChars" type="Bool">
+ <label>Translate reserved characters</label>
+ <whatsthis>Translate six of the seven reserved characters (including the colon, question mark, pipe, asterisk, greater than and less than characters but not the backslash) to remap range (above 0xF000). This allows you to open files that were created with such characters. This has no effect if the server does not support Unicode.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="NoLocking" type="Bool">
+ <label>Do not use locking</label>
+ <whatsthis>Do not use locking. Do not start lockd.</whatsthis>
+ <default>false</default>A
+ </entry>
+ <entry name="CustomCIFSOptions" type="String">
+ <label>Advanced custom options for the CIFS file system</label>
+ <whatsthis>Here you can enter advanced options for the CIFS file system in a comma-separated list (refer to the manual page of mount.cifs to learn more). The list will be added AS IS to the "-o" argument of mount.cifs. Please do not enter options that have already been defined in the configuration dialog.</whatsthis>
+ <default></default>
+ </entry>
+ <entry name="CachingTime" type="Int">
+ <label>Determines how long directory listings are cached</label>
+ <whatsthis>This setting determines how long a directory listing is cached in milliseconds. A high value means it takes longer until changes on the server are noticed on the client side (i.e. your side), but it can also give you an increase in performance on large directories, especially on long distances. You need Linux kernel 2.4.2 or later to take advantage of this setting.</whatsthis>
+ <default>1000</default>
+ </entry>
+ <entry name="UnicodeSupport" type="Bool">
+ <label>Unicode support</label>
+ <whatsthis>Use Unicode when communicating with the server. This will give you better support for non-ASCII character sets with the SMBFS file system.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="LargeFileSystemSupport" type="Bool">
+ <label>Long file support</label>
+ <whatsthis>Large file support (LFS) enables you to read and write
+files bigger than 2 GB on shares that were mounted with the SMBFS file system.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ProtocolHint" type="Enum">
+ <label>The protocol that is used with the net command</label>
+ <whatsthis>Here you can choose the protocol that will be used by the net command for the communication with remote servers if appropriate. In most cases the automatic detection will work fine and you should not need to change the default setting. However, if you experience problems, use the RPC protocol for newer operating systems (Windows NT4 and above) and the RAP protocol for older ones (Windows 98/NT3 and below). Functions that need the ADS protocol (for Active Directory environments) have not been implemented yet, so you can ignore that one for now.</whatsthis>
+ <choices>
+ <choice name="Automatic"/>
+ <choice name="RPC"/>
+ <choice name="RAP"/>
+ <choice name="ADS"/>
+ </choices>
+ <default>Automatic</default>
+ </entry>
+ <entry name="NameResolveOrder" type="String">
+ <label>Name resolve order used by smbclient</label>
+ <whatsthis>This option is used to determine what naming services and in what order are used to resolve host names and IP addresses. It takes a space-separated list of up to four different name resolution options. Those are: lmhost, host, wins, bcast. See the manual page of smbclient for further information.</whatsthis>
+ <!-- Will be filled by Smb4KCore::setDefaultConfigValues() -->
+ </entry>
+ <entry name="BufferSize" type="Int">
+ <label>Transmit/send buffer size used by smbclient</label>
+ <whatsthis>This option changes the transmit/send buffer size when getting or putting a file from/to the server. The default is 65520 bytes. Setting this value smaller has been observed to speed up file transfers to and from Windows 9x servers.</whatsthis>
+ <min>0</min>
+ <default>65520</default>
+ </entry>
+ <entry name="SigningState" type="Enum">
+ <label>Signing state</label>
+ <whatsthis>Set the signing state for smbclient.</whatsthis>
+ <choices>
+ <choice name="None"/>
+ <choice name="On"/>
+ <choice name="Off"/>
+ <choice name="Required"/>
+ </choices>
+ <default>None</default>
+ </entry>
+ <entry name="BroadcastAddress" type="String">
+ <label>The broadcast address used by nmblookup</label>
+ <whatsthis>Queries performed with nmblookup will be send to the given broadcast address. Without this option the default behavior is to send the queries to the broadcast address of the network interface that was either auto-detected or defined in the "interfaces" parameter of the smb.conf file.</whatsthis>
+ <!-- Will be filled by Smb4KCore::setDefaultConfigValues() -->
+ </entry>
+ <entry name="UsePort137" type="Bool">
+ <label>Use UDP port 137 with nmblookup</label>
+ <whatsthis>Try and bind to UDP port 137 to send and receive UDP datagrams. The reason for this option is a bug in Windows 95 where it ignores the source port of the requesting packet and only replies to UDP port 137. Unfortunately, on most Unix systems super user privileges are needed to bind to this port. Please read the manual page of nmblookup for more information.</whatsthis>
+ <default>false</default>
+ </entry>
+ <!-- The custom tab is filled by the core -->
+ </group>
+
+<!-- Synchronization -->
+
+ <!-- Many <whatsthis></whatsthis> entries contain excerpts from the rsync
+ manual page (version 2.6.9). -->
+
+ <group name="Synchronization">
+ <entry name="RsyncPrefix" type="Path">
+ <label>Prefix for synchronization</label>
+ <whatsthis>This is the path where Smb4K will store the files and directories during synchronization. If you plan to synchronize only with one remote share, then you can put the data directly in this directory. If you want to synchronize with several remote shares, then you should create a subdirectory for each share and choose the appropriate one in the synchronization dialog.</whatsthis>
+ <default>$HOME/smb4k_sync/</default>
+ </entry>
+ <entry name="ArchiveMode" type="Bool">
+ <label>Use archive mode</label>
+ <whatsthis>Use archive mode (-a, --archive). This is a short form of -rlptgoD.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="RecurseIntoDirectories" type="Bool">
+ <label>Recurse into subdirectories</label>
+ <whatsthis>Recurse into directories (-r, --recursive).</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="UpdateTarget" type="Bool">
+ <label>Skip files that are newer in the target directory</label>
+ <whatsthis>Update files in the destination directory that are older than in the source directory (-u, --update).</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="UpdateInPlace" type="Bool">
+ <label>Update destination files in place</label>
+ <whatsthis>Update destination files in-place (--inplace). By default, rsync first creates a new copy of a file and moves it into place after its transfer finished. If you enable this feature, no copy will be created but the destination file will immediately be overwritten instead. An exception to this is if you combine this option with --backup.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="RelativePathNames" type="Bool">
+ <label>Use relative path names</label>
+ <whatsthis>Use relative paths (-R, --relative). This means that the full path names specified on the command line are sent to the server rather than just the last parts of the file names.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="NoImpliedDirectories" type="Bool">
+ <label>Don't send implied directories with --relative</label>
+ <whatsthis>Don't send implied directories with --relative (--no-implied-dirs). This means that the corresponding path elements on the destination system are left unchanged if they exist, and any missing implied directories are created with default attributes. This even allows these implied path elements to have big differences, such as being a symlink to a directory on one side of the transfer, and a real directory on the other side.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="TransferDirectories" type="Bool">
+ <label>Transfer directories without recursing</label>
+ <whatsthis>Transfer directories without recursing (-d, --dirs). This means that all top-level subdirectories are transferred but without their contents.</whatsthis>
+ <!-- This description is only correct for Smb4K. See manual page for further information. -->
+ <default>false</default>
+ </entry>
+ <entry name="CompressData" type="Bool">
+ <label>Compress data during transfer</label>
+ <whatsthis>Compress data during transfer (-z, --compress). This significantly reduces the amount of data that is being transferred. You may want to use this option, if you have a slow connection.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="PreserveSymlinks" type="Bool">
+ <label>Preserve symlinks</label>
+ <whatsthis>Copy symlinks as symlinks (-l, --links).</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="TransformSymlinks" type="Bool">
+ <label>Transform symlinks</label>
+ <whatsthis>Transform symlinks into the items they are pointing to (-L, --copy-links).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="TransformUnsafeSymlinks" type="Bool">
+ <label>Only transform unsafe symlinks</label>
+ <whatsthis>Transform unsafe symlinks into the items they are pointing to (--copy-unsafe-links). This means that only those symlinks are transformed that point to items that are outside the copied tree. Absolute symlinks are treated the same way. This option has no additional effect if --copy-links has also been specified.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="IgnoreUnsafeSymlinks" type="Bool">
+ <label>Ignore unsafe symlinks</label>
+ <whatsthis>Ignore symlinks that point outside the copied tree (--safe-links). All absolute symlinks are also ignored. If you use this option in conjunction with --relative you might get unexpected results.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="PreserveHardLinks" type="Bool">
+ <label>Preserve hard links</label>
+ <whatsthis>Preserve hard links (-H, --hard-links). This options causes rsync to preserve the hard links that are found during the transfer. Without it, hard links are treated as though they were separate files.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="KeepDirectorySymlinks" type="Bool">
+ <label>Keep directory symlinks</label>
+ <whatsthis>Treat symlinked directories on the receiving side as though they were real ones (-K, --keep-dirlinks). This only works if the symlink matches a real directory from the sending side. Without this option, the receiver's symlink will be deleted and replaced with a real directory.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="PreservePermissions" type="Bool">
+ <label>Preserve permissions</label>
+ <whatsthis>Preserve permissions (-p, --perms). The permissions of the destination file will be same as the source file. For what happens if this option is switched off, please read rsync's manual page.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="PreserveGroup" type="Bool">
+ <label>Preserve group</label>
+ <whatsthis>Preserve the group (-g, --group). The group of the destination file will be set to the same value as the source file.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="PreserveOwner" type="Bool">
+ <label>Preserve owner (super user only)</label>
+ <whatsthis>Preserve the owner (-o, --owner). The owner of the destination file will be set to the same value as the source file, but only if the receiving rsync is run as the super user. Without this option, the owner is set to the invoking user on the receiving side.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="PreserveDevicesAndSpecials" type="Bool">
+ <label>Preserve device and special files</label>
+ <whatsthis>Preserve device and special files (-D, --devices --specials). This option causes rsync to transfer character and block devices as well as special files such as named sockets and fifos. It works only partially if rsync is not run as super user and the --super option is not specified.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="PreserveTimes" type="Bool">
+ <label>Preserve times</label>
+ <whatsthis>Preserve times (-t, --times). The modification times are transferred along with the files. For what happens if this option is switched off, please read rsync's manual page.</whatsthis>
+ <default>true</default>
+ </entry>
+ <entry name="OmitDirectoryTimes" type="Bool">
+ <label>Omit directories when preserving times</label>
+ <whatsthis>Omit directories when preserving times (-O, --omit-dir-times). This means that directories are omitted when modification times are being preserved. Thus, this feature only works in conjunction with --times.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="RemoveSourceFiles" type="Bool">
+ <label>Remove synchronized source files</label>
+ <whatsthis>Remove all synchronized source files (--remove-source-files). This tells rsync to remove from the sending side the non-directory items that are a part of the transfer and have been successfully duplicated on the receiving side.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="DeleteExtraneous" type="Bool">
+ <label>Delete extraneous files</label>
+ <whatsthis>Delete extraneous files from destination (--delete). This tells rsync to delete all files from the receiving side that are not present on the sending side, but only for the directories that are being synchronized.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="DeleteBefore" type="Bool">
+ <label>Delete files before transfer</label>
+ <whatsthis>Delete files on the receiving side before the transfer starts (--delete-before). This is the default behavior if --delete or --delete-excluded is specified without one of the --delete-WHEN options.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="DeleteAfter" type="Bool">
+ <label>Delete files after transfer</label>
+ <whatsthis>Delete files on the receiving side after the transfer has completed (--delete-after, --del).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="DeleteDuring" type="Bool">
+ <label>Delete files during transfer</label>
+ <whatsthis>Delete files on the receiving side during the transfer (--delete-during). This method is faster than --delete-before or --delete-after, but it is only supported with rsync 2.6.4 or later.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="DeleteExcluded" type="Bool">
+ <label>Also delete excluded files from destination directory</label>
+ <whatsthis>Also delete excluded files from destination directory (--delete-excluded). In addition to deleting the files on the receiving side that are not on the sending side, this tells rsync to also delete any files on the receiving side that are excluded. Refer to rsync's manual page for further information.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="IgnoreErrors" type="Bool">
+ <label>Delete even if I/O errors occur</label>
+ <whatsthis>Delete even if I/O errors occur (--ignore-errors). This option has to be specified in conjunction with --delete to take effect.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ForceDirectoryDeletion" type="Bool">
+ <label>Force deletion of non-void directories</label>
+ <whatsthis>Force deletion of directories even if they are not empty (--force). This option tells rsync to delete a non-empty directory when it is to be replaced by a non-directory. This is only relevant if deletions are not active.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UseMaximumDelete" type="Bool">
+ <label>Only delete a maximum number of files</label>
+ <whatsthis>Only delete as many files as defined here (--max-delete=NUM). This tells rsync not to delete more than NUM files or directories (NUM must be non-zero). This is useful when mirroring very large trees to prevent disasters.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="MaximumDeleteValue" type="Int">
+ <label>Value for DeleteMaximum config entry</label>
+ <whatsthis></whatsthis>
+ <min>0</min>
+ <default>0</default>
+ </entry>
+ <entry name="UseMinimalTransferSize" type="Bool">
+ <label>Don't transfer any file smaller than SIZE</label>
+ <whatsthis>This option causes rsync to not transfer any file that is smaller than the specified size (--min-size=SIZE).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="MinimalTransferSize" type="Int">
+ <label>Value for MinimalTransferSize config entry</label>
+ <whatsthis></whatsthis>
+ <min>0</min>
+ <default>0</default>
+ </entry>
+ <entry name="UseMaximalTransferSize" type="Bool">
+ <label>Don't transfer any file smaller than SIZE</label>
+ <whatsthis>This option causes rsync to not transfer any file that is larger than the specified size (--max-size=SIZE).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="MaximalTransferSize" type="Int">
+ <label>Value for MamximalTransferSize config entry</label>
+ <whatsthis></whatsthis>
+ <min>0</min>
+ <default>0</default>
+ </entry>
+ <entry name="KeepPartial" type="Bool">
+ <label>Keep partially transferred files</label>
+ <whatsthis>Keep partially transferred files (--partial). The default behavor is that any partially transferred file is deleted if the transfer is interrupted.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UsePartialDirectory" type="Bool">
+ <label>The directory where to put a partially transferred file into.</label>
+ <whatsthis>Put a partially transferred file into this directory (--partial-dir=DIR). This is a better way than the --partial option to keep partial files, because the partially transferred file is kept in a different directory and the destination file is not overwritten.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="PartialDirectory" type="Path">
+ <label>The data for the UsePartialDirectory option</label>
+ <whatsthis></whatsthis>
+ <default>$HOME</default>
+ </entry>
+ <entry name="UseCVSExclude" type="Bool">
+ <label>Auto-ignore files in the same way CVS does</label>
+ <whatsthis>Auto-ignore files in the same way CVS does (-C, --cvs-exclude). This is a useful shorthand for excluding a broad range of files that you often do not want to transfer between systems. This option uses the same algorithm that CVS uses to determine if a file should be ignored.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UseExcludePattern" type="Bool">
+ <label>Exclude files that match a certain pattern</label>
+ <whatsthis>Exclude files that match a certain pattern (--exclude=PATTERN). This is a special filter rule. For further information on filter rules see rsync's manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ExcludePattern" type="String">
+ <label>Pattern that is used for file exclusion</label>
+ <whatsthis></whatsthis>
+ <default></default>
+ </entry>
+ <entry name="UseExcludeFrom" type="Bool">
+ <label>Read exclude patterns from a file</label>
+ <whatsthis>Read exclude patterns from a file (--exclude-from=FILE). This option is similar to the --exclude=PATTERN option except that the exclude patterns are read from a file. This is a special filter rule. For further information on filter rules see rsync's manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ExcludeFrom" type="Path">
+ <label>The file from which the exclude patterns are read</label>
+ <whatsthis></whatsthis>
+ <default>$HOME/exclude.txt</default>
+ </entry>
+ <entry name="UseIncludePattern" type="Bool">
+ <label>Do not exclude files matching a certain pattern</label>
+ <whatsthis>Do not exclude files matching a certain pattern (--include=PATTERN). This is a special filter rule. For further information on filter rules see rsync's manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="IncludePattern" type="String">
+ <label>Pattern that is used for file inclusion</label>
+ <whatsthis></whatsthis>
+ <default></default>
+ </entry>
+ <entry name="UseIncludeFrom" type="Bool">
+ <label>Read include patterns from a file</label>
+ <whatsthis>Read include patterns from a file (--include-from=FILE). This option is similar to the --include=PATTERN option except that the include patterns are read from a file. This is a special filter rule. For further information on filter rules see rsync's manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="IncludeFrom" type="Path">
+ <label>The file from which the include patterns are read</label>
+ <whatsthis></whatsthis>
+ <default>$HOME/include.txt</default>
+ </entry>
+ <entry name="CustomFilteringRules" type="String">
+ <label>Add custom file-filtering rules</label>
+ <whatsthis>Add custom file-filtering rules (-f, --filter=RULE). This option allows you to add rules to selectively exclude certain files from the list of files to be transferred.</whatsthis>
+ <default></default>
+ </entry>
+ <entry name="UseFFilterRule" type="Bool">
+ <label>Use -F filter rule</label>
+ <whatsthis>This filter rule tells rsync to look for per-directory .rsync-filter files that have been sprinkled through the hierarchy and use their rules to filter the files in the transfer. It has no effect, if you also choose to use the --filter='exclude .rsync-filter' rule.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UseFFFilterRule" type="Bool">
+ <label>Use -FF filter rule</label>
+ <whatsthis>This rule filters out the .rsync-filter files from the transfer. These files normally contain filter rules that can be activated by choosing the --filter='dir-merge /.rsync-filter' rule and deselecting this one.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="EfficientSparseFileHandling" type="Bool">
+ <label>Handle sparse files efficiently</label>
+ <whatsthis>Handle sparse files efficiently (-S, --sparse) so that they take up less space on the destination. This option conflicts with --inplace. For further information read rsync's manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="CopyFilesWhole" type="Bool">
+ <label>Copy files whole (no rsync algorithm)</label>
+ <whatsthis>Copy files whole (-W, --whole-file). With this option the incremental rsync algorithm is not used and the whole file is sent as-is instead.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="OneFileSystem" type="Bool">
+ <label>Do not cross file system boundaries</label>
+ <whatsthis>Do not cross file system boundaries (-x, --one-file-system). This tells rsync to avoid crossing a filesystem boundary when recursing. For further information on this option, read the manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UpdateExisting" type="Bool">
+ <label>Skip creating new files on the receiving side</label>
+ <whatsthis>Skip creating new files on the receiving side (--existing). This tells rsync to skip creating files (including directories) that do not exist yet on the destination. If this option is combined with the --ignore-existing option, no files will be updated (which can be useful if all you want to do is to delete extraneous files).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="IgnoreExisting" type="Bool">
+ <label>Skip updating files that exist on the receiving side</label>
+ <whatsthis>Skip updating files that already exist on the receiving side (--ignore-existing). Existing directories are not ignored.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="DelayUpdates" type="Bool">
+ <label>Delay updates until the end of the transfer</label>
+ <whatsthis>Delay updates until the end of the transfer (--delay-updates). This option puts the temporary file from each updated file into a holding directory until the end of the transfer, at which time all the files are renamed and copied into place in rapid succession.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="MakeBackups" type="Bool">
+ <label>Make backups</label>
+ <whatsthis>Make backups (-b, --backup). With this option, preexisting destination files are renamed as each file is transferred or deleted. You can control where the backup file goes and what (if any) suffix gets appended using the --backup-dir=DIR and --suffix=SUFFIX options.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="UseBackupSuffix" type="Bool">
+ <label>Use a suffix for backups</label>
+ <whatsthis>Use this suffix for backups (--suffix=SUFFIX).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="BackupSuffix" type="String">
+ <label>Backup suffix</label>
+ <whatsthis></whatsthis>
+ <default>~</default>
+ </entry>
+ <entry name="UseBackupDirectory" type="Bool">
+ <label>Put backups into a certain directory</label>
+ <whatsthis>Store backups in this directory (--backup-dir=DIR).</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="BackupDirectory" type="Path">
+ <label>Backup directory</label>
+ <whatsthis></whatsthis>
+ <default>$HOME</default>
+ </entry>
+ <entry name="UseBlockSize" type="Bool">
+ <label>Force a fixed checksum block-size</label>
+ <whatsthis>Force a fixed checksum block-size (-B, --block-size=SIZE). This forces the block size used in the rsync algorithm to a fixed value.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="BlockSize" type="Int">
+ <label>The block size</label>
+ <whatsthis></whatsthis>
+ <min>0</min>
+ <default>0</default>
+ </entry>
+ <entry name="UseChecksumSeed" type="Bool">
+ <label>Set block/file checksum seed</label>
+ <whatsthis>Set block/file checksum seed (--checksum-seed=NUM). Set the MD4 checksum seed to this integer. This 4 byte checksum seed is included in each block and file MD4 checksum calculation. By default the checksum seed is generated by the server and defaults to the current time.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="ChecksumSeed" type="Int">
+ <label>The checksum seed</label>
+ <whatsthis></whatsthis>
+ <min>0</min>
+ <default>0</default>
+ </entry>
+ <entry name="UseChecksum" type="Bool">
+ <label>Skip files based on a checksum</label>
+ <whatsthis>Skip files based on a checksum and not based on modification time and size (-c, --checksum). For further information on how this feature works read rsync's manual page.</whatsthis>
+ <default>false</default>
+ </entry>
+ </group>
+
+
+<!-- Super User -->
+
+ <group name="SuperUser">
+ <entry name="SuperUserProgram" type="Enum">
+ <label>The program that should be used to gain super user privileges</label>
+ <whatsthis>Choose the program that will grant you limited super user privileges for mounting and unmounting remote shares. You can either select sudo, the standard tool for this purpose on most distributions, or super.</whatsthis>
+ <choices>
+ <choice name="Sudo"/>
+ <choice name="Super"/>
+ </choices>
+ <default>Sudo</default>
+ </entry>
+ <entry name="UseForceUnmount" type="Bool">
+ <label>Use super user privileges to unmount inaccessible shares</label>
+ <whatsthis>Unmount a share under Linux by force. This even works if the file system is "busy", because it is immediately detached from the file system hierarchy and all references to it are cleaned up later when it is not busy anymore. Linux kernel 2.4.11 or later is needed to take advantage of this feature. Use with case! Note, that you will need the root password to write the necessary changes to the configuration file.</whatsthis>
+ <default>false</default>
+ </entry>
+ <entry name="AlwaysUseSuperUser" type="Bool">
+ <label>Use super user privileges to mount and unmount shares</label>
+ <whatsthis>Use super user privileges for mounting and unmounting remote shares. This feature is only needed, if you are not allowed to use smbmount, smbumount, mount.cifs and umount.cifs as normal user. Note, that you will need the root password to write the necessary changes to the configuration file.</whatsthis>
+ <default>false</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/smb4k/core/smb4kauthinfo.cpp b/smb4k/core/smb4kauthinfo.cpp
new file mode 100644
index 0000000..d47eeb0
--- /dev/null
+++ b/smb4k/core/smb4kauthinfo.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ smb4kauthinfo.cpp - This class provides a container for the
+ authentication data.
+ -------------------
+ begin : Sa Feb 28 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// application specific includes
+#include "smb4kauthinfo.h"
+
+
+Smb4KAuthInfo::Smb4KAuthInfo( const QString &wg, const QString &h, const QString &s, const QString &u, const QString &p ) : m_workgroup(wg), m_host(h), m_share(s), m_user(u.local8Bit()), m_password(p.local8Bit())
+{
+}
+
+
+Smb4KAuthInfo::Smb4KAuthInfo( Smb4KAuthInfo &i ) : m_workgroup( i.workgroup() ), m_host( i.host() ), m_share( i.share() ), m_user( i.user() ), m_password( i.password() )
+{
+}
+
+
+Smb4KAuthInfo::~Smb4KAuthInfo()
+{
+}
+
+
+void Smb4KAuthInfo::setUser( const QString &user )
+{
+ m_user = user.local8Bit();
+}
+
+
+void Smb4KAuthInfo::setPassword( const QString &passwd )
+{
+ m_password = passwd.local8Bit();
+}
+
+
+void Smb4KAuthInfo::setShare( const QString &share )
+{
+ m_share = share;
+}
+
+
diff --git a/smb4k/core/smb4kauthinfo.h b/smb4k/core/smb4kauthinfo.h
new file mode 100644
index 0000000..9c4798e
--- /dev/null
+++ b/smb4k/core/smb4kauthinfo.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ smb4kauthinfo.h - This class provides a container for the
+ authentication data.
+ -------------------
+ begin : Sa Feb 28 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KAUTHINFO_H
+#define SMB4KAUTHINFO_H
+
+// Qt includes
+#include <qstring.h>
+#include <qcstring.h>
+
+/**
+ * This class provides a container for the authentication data.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+
+class Smb4KAuthInfo
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param workgroup The workgroup of the share the auth info is for.
+ *
+ * @param hosts The host's name
+ *
+ * @param share The share's name
+ *
+ * @param user The username that's used for authentication. Default is QString::null.
+ *
+ * @param password The password that's used for authentication. Default is QString::null.
+ */
+ Smb4KAuthInfo( const QString &workgroup,
+ const QString &host,
+ const QString &share,
+ const QString &user = QString::null,
+ const QString &password = QString::null );
+ /**
+ * The empty constructor.
+ */
+ Smb4KAuthInfo() {}
+ /**
+ * The copy constructor.
+ *
+ * @param info The Smb4KAuthInfo object that will be copied.
+ */
+ Smb4KAuthInfo( Smb4KAuthInfo &info );
+ /**
+ * The destructor
+ */
+ ~Smb4KAuthInfo();
+ /**
+ * Returns the name of the workgroup.
+ *
+ * @returns The workgroup of the server/share for which this
+ * authentication data is for.
+ */
+ const QString &workgroup() const { return m_workgroup; }
+ /**
+ * Returns the name of the server (host).
+ *
+ * @returns The server name
+ */
+ const QString &host() const { return m_host; }
+ /**
+ * Returns the name of the share.
+ *
+ * @returns The share name
+ */
+ const QString &share() const { return m_share; }
+ /**
+ * Returns the user's name.
+ *
+ * @returns The user name
+ */
+ const QCString &user() const { return m_user; }
+ /**
+ * Returns the (unescaped) password.
+ */
+ const QCString &password() const { return m_password; }
+ /**
+ * Sets the user name.
+ *
+ * @param user The user name for the server/share
+ */
+ void setUser( const QString &user );
+ /**
+ * Sets the password.
+ *
+ * @param passwd The password for the server/share
+ */
+ void setPassword( const QString &passwd );
+ /**
+ * Sets the share name.
+ *
+ * @param share The name of the share
+ */
+ void setShare( const QString &share );
+
+ private:
+ /**
+ * The workgroup object.
+ */
+ QString m_workgroup;
+ /**
+ * The host object.
+ */
+ QString m_host;
+ /**
+ * The share object.
+ */
+ QString m_share;
+ /**
+ * The user name for this share.
+ */
+ QCString m_user;
+ /**
+ * The password object for this share.
+ */
+ QCString m_password;
+
+};
+
+#endif
diff --git a/smb4k/core/smb4kbookmark.cpp b/smb4k/core/smb4kbookmark.cpp
new file mode 100644
index 0000000..20b3a90
--- /dev/null
+++ b/smb4k/core/smb4kbookmark.cpp
@@ -0,0 +1,97 @@
+/***************************************************************************
+ smb4kbookmark.cpp - A bookmark container.
+ -------------------
+ begin : Feb 04 2004
+ copyright : (C) 2004 by Franck Babin
+ (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <ksocketaddress.h>
+
+// application specific includes
+#include "smb4kbookmark.h"
+#include "smb4knetworkitems.h"
+
+
+Smb4KBookmark::Smb4KBookmark( const QString &host, const QString &share, const QString &workgroup, const QString &ip, const QString &type, const QString &label )
+: m_host( host ), m_share( share ), m_workgroup( workgroup ), m_type( type ), m_label( label )
+{
+ //FIXME should throw an exception if one of the param is empty
+
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+ m_bookmark = QString( "//%1/%2" ).arg( m_host, m_share );
+}
+
+
+Smb4KBookmark::Smb4KBookmark( Smb4KShareItem *item, const QString &ip, const QString &label )
+: m_host( item->host() ), m_share( item->name() ), m_workgroup( item->workgroup() ),
+ m_type( item->plainType() ), m_label( label )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+ m_bookmark = QString( "//%1/%2" ).arg( m_host, m_share );
+}
+
+
+Smb4KBookmark::~Smb4KBookmark()
+{
+}
+
+
+void Smb4KBookmark::setShareName( const QString &name )
+{
+ m_share = name;
+
+ m_bookmark = QString( "//%1/%2" ).arg( m_host, m_share );
+}
+
+
+void Smb4KBookmark::setIP( const QString &ip )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+}
+
+
+void Smb4KBookmark::setLabel( const QString &text )
+{
+ m_label = text;
+}
+
+
+bool Smb4KBookmark::ipIsValid( const QString &ip )
+{
+ if ( !ip.isEmpty() )
+ {
+ KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( ip );
+
+ if ( !ip_address.isIPv4Addr() && !ip_address.isIPv6Addr() )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
diff --git a/smb4k/core/smb4kbookmark.h b/smb4k/core/smb4kbookmark.h
new file mode 100644
index 0000000..c4e8b25
--- /dev/null
+++ b/smb4k/core/smb4kbookmark.h
@@ -0,0 +1,212 @@
+/***************************************************************************
+ smb4kbookmark.h - A bookmark container.
+ -------------------
+ begin : Feb 04 2004
+ copyright : (C) 2004 by Franck Babin
+ (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KBOOKMARK_H
+#define SMB4KBOOKMARK_H
+
+// Qt includes
+#include <qstring.h>
+
+// forward declarations
+class Smb4KShareItem;
+
+/**
+ * This class is a container for a set bookmark on a samba share
+ */
+
+class Smb4KBookmark
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param hostname The host name.
+ *
+ * @param sharename The share name.
+ *
+ * @param workgroup The workgroup/domain where the share is located.
+ *
+ * @param ip The IP address of the host
+ *
+ * @param type The type of the share, i.e. "disk" or "printer".
+ *
+ * @param label An alternative label to the share name.
+ */
+ Smb4KBookmark( const QString &hostname,
+ const QString &sharename,
+ const QString &workgroup,
+ const QString &ip,
+ const QString &type,
+ const QString &label = QString::null );
+
+ /**
+ * An alternative constructor.
+ *
+ * @param item The Smb4KShareItem for which a bookmark should be
+ * created.
+ *
+ * @param ip The IP address of the host
+ *
+ * @param label An alternative label to the share name.
+ */
+ Smb4KBookmark( Smb4KShareItem *item,
+ const QString &ip,
+ const QString &label = QString::null );
+
+ /**
+ * The empty constructor.
+ */
+ Smb4KBookmark() {}
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KBookmark();
+
+ /**
+ * This function returns the share name.
+ *
+ * @returns The share name
+ */
+ const QString &share() const { return m_share; };
+
+ /**
+ * This function returns the workgroup/domain the share is located in.
+ *
+ * @returns The workgroup
+ */
+ const QString &workgroup() const { return m_workgroup; }
+
+ /**
+ * This function returns the IP address of the host that carries the
+ * share.
+ *
+ * @returns The IP address
+ */
+ const QString &ip() const { return m_ip; }
+
+ /**
+ * This function returns the type of the share, i.e. either "Disk" or
+ * "Printer"/"Print" and "IPC".
+ *
+ * @returns The type of the share
+ */
+ const QString &type() const { return m_type; }
+
+ /**
+ * This function sets the share name of the bookmark. It is normally not
+ * necessary to use it, because all data should be passed to the constructor.
+ * In case of homes shares, however, this function is useful.
+ *
+ * @param name The share name
+ */
+ void setShareName( const QString &name );
+
+ /**
+ * This function returns the bookmark name.
+ *
+ * @returns The name of the bookmark
+ */
+ const QString &bookmark() const { return m_bookmark; }
+
+ /**
+ * This function returns the host name.
+ *
+ * @returns The name of the host
+ */
+ const QString &host() const { return m_host; }
+
+ /**
+ * This function sets the IP address.
+ *
+ * @param ip The IP address
+ */
+ void setIP( const QString &ip );
+
+ /**
+ * Return the alternative bookmark label.
+ *
+ * @returns the label.
+ */
+ const QString &label() const { return m_label; }
+
+ /**
+ * Sets the alternative bookmark label.
+ *
+ * @param text The new text for the label
+ */
+ void setLabel( const QString &text );
+
+ private:
+ /**
+ * The host name.
+ */
+ QString m_host;
+
+ /**
+ * The share name.
+ */
+ QString m_share;
+
+ /**
+ * The workgroup
+ */
+ QString m_workgroup;
+
+ /**
+ * The IP address
+ */
+ QString m_ip;
+
+ /**
+ * The type of the share;
+ */
+ QString m_type;
+
+ /**
+ * The bookmark string.
+ */
+ QString m_bookmark;
+
+ /**
+ * The alternative label
+ */
+ QString m_label;
+
+ /**
+ * This function checks if the IP address is valid, i.e. the
+ * IP address is either IP v4 or IP v6. It returns either TRUE
+ * or FALSE.
+ *
+ * @param ip The IP address that's going to be checked.
+ *
+ * @returns TRUE if the IP address is valid and FALSE otherwise.
+ */
+ bool ipIsValid( const QString &ip );
+};
+
+#endif
diff --git a/smb4k/core/smb4kbookmarkhandler.cpp b/smb4k/core/smb4kbookmarkhandler.cpp
new file mode 100644
index 0000000..113d601
--- /dev/null
+++ b/smb4k/core/smb4kbookmarkhandler.cpp
@@ -0,0 +1,342 @@
+/***************************************************************************
+ smb4kbookmarkhandler - This class handles the bookmarks.
+ -------------------
+ begin : Fr Jan 9 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qdir.h>
+#include <qfile.h>
+
+// KDE includes
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+// system specific includes
+#include <stdlib.h>
+#include <math.h>
+
+// application specific includes
+#include "smb4kbookmarkhandler.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4knetworkitems.h"
+#include "smb4kbookmark.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KBookmarkHandler::Smb4KBookmarkHandler( QValueList<Smb4KHostItem *> *hosts,
+QObject *parent, const char *name )
+: QObject( parent, name ), m_hosts( hosts )
+{
+ // First we need the directory.
+ KStandardDirs *stddir = new KStandardDirs();
+ QString dir = locateLocal( "data", "smb4k", KGlobal::instance() );
+
+ if ( !stddir->exists( dir ) )
+ {
+ stddir->makeDir( dir );
+ }
+
+ delete stddir;
+
+ loadBookmarks();
+}
+
+
+Smb4KBookmarkHandler::~Smb4KBookmarkHandler()
+{
+ for ( QValueList<Smb4KBookmark *>::Iterator it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_bookmarks.clear();
+
+ // Do not delete m_hosts here, because it is either NULL
+ // or it is handled outside of this class.
+}
+
+
+
+void Smb4KBookmarkHandler::addBookmark( Smb4KBookmark *bookmark )
+{
+ if ( !bookmark )
+ {
+ return;
+ }
+
+ if ( QString::compare( bookmark->type(), "Printer" ) == 0 )
+ {
+ Smb4KError::error( ERROR_BOOKMARK_PRINTER );
+ return;
+ }
+
+ if ( QString::compare( bookmark->share(), "homes" ) == 0 )
+ {
+ QString share = specifyUser( bookmark->host(), kapp->mainWidget() ? kapp->mainWidget() : 0, "SpecifyUser" );
+
+ bookmark->setShareName( share );
+ }
+
+ // Search for the bookmark:
+ Smb4KBookmark *result = findBookmarkByName( bookmark->bookmark() );
+
+ if ( result )
+ {
+ if ( QString::compare( result->workgroup().upper(), bookmark->workgroup().upper() ) == 0 )
+ {
+ // It's the same bookmark. We'll update it in a very
+ // brutal but efficient way:
+ m_bookmarks.remove( result );
+
+ if ( result )
+ {
+ delete result;
+ }
+ }
+
+ m_bookmarks.append( bookmark );
+ }
+ else
+ {
+ // The bookmark is new. Append it to the list:
+ m_bookmarks.append( bookmark );
+ }
+
+ writeBookmarkList( m_bookmarks );
+}
+
+
+void Smb4KBookmarkHandler::writeBookmarkList( const QValueList<Smb4KBookmark *> &list )
+{
+ if ( list != m_bookmarks )
+ {
+ for ( QValueListIterator<Smb4KBookmark *> it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_bookmarks.clear();
+
+ m_bookmarks = list;
+ }
+
+ QFile file( locateLocal( "data", "smb4k/bookmarks", KGlobal::instance() ) );
+
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ int serial_number = 0;
+
+ for ( QValueListConstIterator<Smb4KBookmark *> it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
+ {
+ if ( !(*it)->label().isEmpty() )
+ {
+ Smb4KBookmark *result = findBookmarkByLabel( (*it)->label() );
+
+ if ( result &&
+ (QString::compare( result->bookmark().upper(), (*it)->bookmark().upper() ) != 0 ||
+ QString::compare( result->workgroup().upper(), (*it)->workgroup().upper() ) != 0) )
+ {
+ Smb4KError::information( INFO_BOOKMARK_LABEL_IN_USE, (*it)->label(), (*it)->bookmark() );
+
+ (*it)->setLabel( QString( "%1 (%2)" ).arg( (*it)->label() ).arg( serial_number++ ) );
+ }
+ }
+
+ ts << (*it)->host() << ","
+ << (*it)->share() << ","
+ << (*it)->workgroup() << ","
+ << (*it)->ip() << ","
+ << (*it)->label() << endl;
+ }
+
+ file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, QDir::currentDirPath()+"/"+file.name() );
+ return;
+ }
+
+ emit bookmarksUpdated();
+}
+
+
+void Smb4KBookmarkHandler::loadBookmarks()
+{
+ QFile file( locateLocal( "data", "smb4k/bookmarks", KGlobal::instance() ) );
+
+ QStringList contents;
+
+ if ( file.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( '\n', ts.read(), false );
+
+ file.close();
+
+ for ( QStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
+ {
+ if ( (*it).startsWith( "#" ) || (*it).startsWith( "[" ) ||
+ QString::compare( (*it).stripWhiteSpace(), QString::null ) == 0 )
+ {
+ continue;
+ }
+ else
+ {
+ // Load old bookmark entries (prior to version 0.7.0)
+ if ( ((*it).stripWhiteSpace())[0].isDigit() )
+ {
+ QString bookmark = (*it).section( "=", 1, -1 ).stripWhiteSpace();
+ m_bookmarks.append( new Smb4KBookmark( bookmark.section( "/", 2, 2 ).stripWhiteSpace(), bookmark.section( "/", 3, 3 ).stripWhiteSpace(), QString::null, QString::null, "Disk" ) );
+ }
+ else
+ {
+ QString host = (*it).section( ",", 0, 0 ).stripWhiteSpace();
+ QString share = (*it).section( ",", 1, 1 ).stripWhiteSpace();
+ QString workgroup = (*it).section( ",", 2, 2 ).stripWhiteSpace();
+ QString ip = (*it).section( ",", 3, 3 ).stripWhiteSpace();
+ QString label = (*it).section( ",", 4, 4 ).stripWhiteSpace();
+
+ m_bookmarks.append( new Smb4KBookmark( host, share, workgroup, ip, "Disk", label ) );
+ }
+ }
+ }
+
+ emit bookmarksUpdated();
+ }
+ else
+ {
+ if ( file.exists() )
+ {
+ Smb4KError::error( ERROR_READING_FILE, file.name() );
+ }
+ else
+ {
+ // Do nothing if the file does not exist.
+ }
+ }
+}
+
+
+Smb4KBookmark *Smb4KBookmarkHandler::findBookmarkByName( const QString &bookmark )
+{
+ // Update the bookmarks:
+ update();
+
+ // Find the bookmark:
+ QValueListConstIterator<Smb4KBookmark *> it;
+
+ for ( it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
+ {
+ if ( QString::compare( (*it)->bookmark().upper(), bookmark.upper() ) == 0 )
+ {
+ break;
+ }
+ }
+
+ return it != m_bookmarks.end() ? *it : NULL;
+}
+
+
+Smb4KBookmark *Smb4KBookmarkHandler::findBookmarkByLabel( const QString &label )
+{
+ // Update the bookmarks:
+ update();
+
+ // Find the bookmark:
+ QValueListConstIterator<Smb4KBookmark *> it;
+
+ for ( it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
+ {
+ if ( QString::compare( (*it)->label().upper(), label.upper() ) == 0 )
+ {
+ break;
+ }
+ }
+
+ return it != m_bookmarks.end() ? *it : NULL;
+}
+
+
+const QValueList<Smb4KBookmark *> &Smb4KBookmarkHandler::getBookmarks()
+{
+ // Update the bookmarks:
+ update();
+
+ // Return the list of bookmarks:
+ return m_bookmarks;
+}
+
+
+void Smb4KBookmarkHandler::update()
+{
+ // If the user didn't pass the global Smb4KHostItem list, we are not able
+ // to update the bookmarks:
+ if ( !m_hosts )
+ {
+ return;
+ }
+
+ // Search the list of hosts for new IP addresses:
+ for ( QValueList<Smb4KBookmark *>::Iterator it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
+ {
+ for ( QValueList<Smb4KHostItem *>::ConstIterator i = m_hosts->begin(); i != m_hosts->end(); ++i )
+ {
+ if ( QString::compare( (*it)->workgroup().lower(), (*i)->workgroup().lower() ) != 0 )
+ {
+ // Continue, if the workgroup is not the same:
+ continue;
+ }
+ else
+ {
+ if ( QString::compare( (*it)->host().lower(), (*i)->name().lower() ) != 0 )
+ {
+ // Continue if the host name is not the same:
+ continue;
+ }
+ else
+ {
+ // Set the IP address if it changed:
+ if ( !(*i)->ip().stripWhiteSpace().isEmpty() &&
+ QString::compare( (*it)->ip(), (*i)->ip() ) != 0 )
+ {
+ (*it)->setIP( (*i)->ip() );
+ }
+
+ break;
+ }
+ }
+ }
+ }
+}
+
+#include "smb4kbookmarkhandler.moc"
diff --git a/smb4k/core/smb4kbookmarkhandler.h b/smb4k/core/smb4kbookmarkhandler.h
new file mode 100644
index 0000000..56e7302
--- /dev/null
+++ b/smb4k/core/smb4kbookmarkhandler.h
@@ -0,0 +1,162 @@
+/***************************************************************************
+ smb4kbookmarkhandler - This class handles the bookmarks.
+ -------------------
+ begin : Fr Jan 9 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KBOOKMARKHANDLER_H
+#define SMB4KBOOKMARKHANDLER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qvaluelist.h>
+
+// forward declarations
+class Smb4KHostItem;
+class Smb4KBookmark;
+
+
+/**
+ * This class belongs the to core classes of Smb4K and manages the
+ * bookmarks.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KBookmarkHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param hosts A list of Smb4KHostItem items. This should be used
+ * to give the bookmark handler the list of known hosts,
+ * so it is able to update the bookmarks if necessary.
+ * In case a NULL pointer is passed, the bookmarks won't
+ * be updated.
+ *
+ * @param parent The parent of this object
+ *
+ * @param name This object's name
+ */
+ Smb4KBookmarkHandler( QValueList<Smb4KHostItem *> *hosts = 0,
+ QObject *parent = 0,
+ const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KBookmarkHandler();
+
+ /**
+ * This function writes a bookmark to the bookmark file.
+ *
+ * NOTE: This function is more or less a wrapper around the
+ * writeBookmarList() function.
+ *
+ * @param bookmark A bookmark that is to be written to
+ * the bookmark file
+ */
+ void addBookmark( Smb4KBookmark *bookmark );
+
+ /**
+ * This function writes a new list of bookmarks. The old list will be
+ * deleted. It should be used, if you manipulated the list of bookmarks
+ * i. e. by a bookmark editor. When this function finishes, the
+ * bookmarksUpdated() signal will be emitted.
+ *
+ * @param list The (new) list of bookmarks that is to be written
+ * to the bookmark file
+ */
+ void writeBookmarkList( const QValueList<Smb4KBookmark *> &list );
+
+ /**
+ * Get the list of bookmarks.
+ *
+ * @returns The current list of bookmarks stored in the
+ * bookmark file.
+ */
+ const QValueList<Smb4KBookmark *> &getBookmarks();
+
+ /**
+ * This function searches for a bookmark using its name (//HOST/SHARE) and
+ * returns a pointer to it if it is present or NULL.
+ *
+ * @param bookmark The bookmark that is searched. The string you enter
+ * must consist of the host and the share: //HOST/SHARE.
+ *
+ * @returns The bookmark object that was searched for or NULL if it
+ * wasn't found.
+ */
+ Smb4KBookmark *findBookmarkByName( const QString &bookmark );
+
+ /**
+ * This function searches for a bookmark using its label and returns a pointer
+ * to it if it is present or NULL.
+ *
+ * @param label The label that is searched.
+ *
+ * @returns The bookmark object that was searched for or NULL if it
+ * wasn't found.
+ */
+ Smb4KBookmark *findBookmarkByLabel( const QString &label );
+
+ signals:
+ /**
+ * Signal emitted when the list of bookmarks has been updated.
+ */
+ void bookmarksUpdated();
+
+ private:
+ /**
+ * The list of bookmarks.
+ */
+ QValueList<Smb4KBookmark *> m_bookmarks;
+
+ /**
+ * This function loads the list of bookmarks from the bookmarks file.
+ * When it finishes, the bookmarksUpdated() signal is emitted. So, if you
+ * want to access the list of bookmarks immediately after they were read,
+ * connect a slot to that signal.
+ */
+ void loadBookmarks();
+
+ /**
+ * This lis is a pointer to a global list of all known hosts. It
+ * is used to update the bookmarks.
+ */
+ QValueList<Smb4KHostItem *> *m_hosts;
+
+ /**
+ * This function updates the data of the bookmarks, i.e. is searches for
+ * the host provided by m_hosts and sets the appropriate data, if
+ * necessary.
+ */
+ void update();
+};
+#endif
diff --git a/smb4k/core/smb4kcore.cpp b/smb4k/core/smb4kcore.cpp
new file mode 100644
index 0000000..4bf835f
--- /dev/null
+++ b/smb4k/core/smb4kcore.cpp
@@ -0,0 +1,955 @@
+/***************************************************************************
+ smb4kcore - The main core class of Smb4K.
+ -------------------
+ begin : Do Apr 8 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qdir.h>
+#include <qmap.h>
+#include <qstringlist.h>
+
+// KDE includes
+#include <kdeversion.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurl.h>
+#include <krun.h>
+#include <kapplication.h>
+#include <kpassivepopup.h>
+#include <kdebug.h>
+#include <kstaticdeleter.h>
+#include <dcopclient.h>
+
+// system includes
+#include <stdlib.h>
+
+// application specific includes
+#include "smb4kcore.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4knetworkitems.h"
+#include "smb4kshare.h"
+#include "smb4ksambaoptionshandler.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+Smb4KCore *Smb4KCore::m_self = 0;
+static KStaticDeleter<Smb4KCore> staticSmb4KCoreDeleter;
+
+
+Smb4KCore::Smb4KCore() : QObject()
+{
+ // Set default values for settings that depend on the system
+ // Smb4K is running on:
+ setDefaultSettings();
+
+ // Search for the programs that are needed by Smb4K:
+ searchPrograms();
+
+ m_fileIO = new Smb4KFileIO( this, "CoreFileIO" );
+ m_scanner = new Smb4KScanner( &m_workgroups, &m_hosts, this, "CoreScanner" );
+ m_mounter = new Smb4KMounter( this, "CoreMounter" );
+ m_bookmarkHandler = new Smb4KBookmarkHandler( &m_hosts, this, "CoreBookmarkHandler" );
+ m_print = new Smb4KPrint( this, "CorePrinterHandler" );
+ m_synchronizer = new Smb4KSynchronizer( this, "CoreSynchronizer" );
+ m_previewer = new Smb4KPreviewer( this, "CorePreviewer" );
+
+ m_scanner_state = SCANNER_STOP;
+ m_mounter_state = MOUNTER_STOP;
+ m_print_state = PRINT_STOP;
+ m_syncer_state = SYNCHRONIZER_STOP;
+ m_previewer_state = PREVIEWER_STOP;
+
+ // Connections:
+ connect( m_scanner, SIGNAL( state( int ) ),
+ this, SLOT( slotSetScannerState( int ) ) );
+
+ connect( m_mounter, SIGNAL( state( int ) ),
+ this, SLOT( slotSetMounterState( int ) ) );
+
+ connect( m_print, SIGNAL( state( int ) ),
+ this, SLOT( slotSetPrinterHandlerState( int ) ) );
+
+ connect( m_synchronizer, SIGNAL( state( int ) ),
+ this, SLOT( slotSetSynchronizerState( int ) ) );
+
+ connect( m_previewer, SIGNAL( state( int ) ),
+ this, SLOT( slotSetSynchronizerState( int ) ) );
+
+ connect( kapp, SIGNAL( shutDown() ),
+ this, SLOT( slotShutdown() ) );
+}
+
+
+Smb4KCore::~Smb4KCore()
+{
+ // Do not call abort() here. This will most likely lead
+ // to crashes.
+
+ // Clear the list of workgroups.
+ for ( QValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups.begin(); it != m_workgroups.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_workgroups.clear();
+
+ // Clear the list of hosts.
+ for ( QValueList<Smb4KHostItem *>::Iterator it = m_hosts.begin(); it != m_hosts.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_hosts.clear();
+
+ if ( m_self == this )
+ {
+ staticSmb4KCoreDeleter.setObject( m_self, 0, false );
+ }
+}
+
+
+Smb4KCore *Smb4KCore::self()
+{
+ if ( !m_self )
+ {
+ staticSmb4KCoreDeleter.setObject( m_self, new Smb4KCore() );
+ }
+
+ return m_self;
+}
+
+
+void Smb4KCore::init()
+{
+ // Start the core.
+ m_scanner->init();
+ m_mounter->init();
+}
+
+
+/****************************************************************************
+ Returns a bool that tells the program whether a core process is running.
+****************************************************************************/
+
+bool Smb4KCore::isRunning()
+{
+ if ( self()->m_scanner->isRunning() || self()->m_mounter->isRunning() ||
+ self()->m_print->isRunning() || self()->m_synchronizer->isRunning() ||
+ self()->m_previewer->isRunning() )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+/****************************************************************************
+ Sets the current state of the core.
+****************************************************************************/
+
+void Smb4KCore::setCurrentState( int state )
+{
+ if ( state != SCANNER_STOP && state != MOUNTER_STOP &&
+ state != PRINT_STOP && state != SYNCHRONIZER_STOP &&
+ state != PREVIEWER_STOP )
+ {
+ m_current_state = state;
+ }
+ else
+ {
+ if ( !m_scanner->isRunning() && !m_mounter->isRunning() &&
+ !m_print->isRunning() && !m_synchronizer->isRunning() &&
+ !m_previewer->isRunning() )
+ {
+ m_current_state = CORE_STOP;
+ }
+ else
+ {
+ if ( m_scanner->isRunning() )
+ {
+ m_current_state = m_scanner_state;
+ }
+ else if ( m_print->isRunning() )
+ {
+ m_current_state = m_print_state;
+ }
+ else if ( m_mounter->isRunning() )
+ {
+ m_current_state = m_mounter_state;
+ }
+ else if ( m_synchronizer->isRunning() )
+ {
+ m_current_state = m_syncer_state;
+ }
+ else if ( m_previewer->isRunning() )
+ {
+ m_current_state = m_previewer_state;
+ }
+ }
+ }
+}
+
+
+/****************************************************************************
+ Aborts any process of the core.
+****************************************************************************/
+
+void Smb4KCore::abort()
+{
+ self()->m_scanner->abort();
+ self()->m_mounter->abort();
+ self()->m_print->abort();
+ self()->m_synchronizer->abort();
+ self()->m_previewer->abort();
+}
+
+
+/****************************************************************************
+ Opens the given URL.
+****************************************************************************/
+
+void Smb4KCore::open( Smb4KShare *share, int openWith )
+{
+ if ( !share || share->isBroken() )
+ {
+ return;
+ }
+
+#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR <= 3 && KDE_VERSION_RELEASE <= 92
+
+ if ( QString::compare( share->filesystem(), "cifs" ) == 0 )
+ {
+ if( KMessageBox::warningContinueCancel( (QWidget *)this, i18n( "Up to KDE 3.3.x, KIO and Konqueror cannot handle CIFS shares. Konqueror will hang if you try to access it.\nDo you want to continue?" ) ) == KMessageBox::Cancel )
+ {
+ return;
+ }
+ }
+
+#endif
+
+ switch ( openWith )
+ {
+ case Konqueror:
+ {
+ KURL url;
+ url.setPath( share->canonicalPath() );
+
+ (void) new KRun( url, 0, true, true );
+
+ break;
+ }
+ case Konsole:
+ {
+ if ( Smb4KSettings::konsole().isEmpty() )
+ {
+ Smb4KError::error( ERROR_COMMAND_NOT_FOUND, "konsole" );
+ }
+ else
+ {
+ KRun::runCommand( "konsole --workdir "+share->canonicalPath() );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ Searches for the programs needed by Smb4K
+****************************************************************************/
+
+void Smb4KCore::searchPrograms()
+{
+ // Remove the group "Programs" and reread the
+ // configuration:
+ Smb4KSettings::self()->config()->deleteGroup( "Programs" );
+ Smb4KSettings::self()->readConfig();
+
+ // List of paths that should be searched.
+ QStringList path_list = QStringList::split( ":", QString( "%1" ).arg( getenv( "PATH" ) ), false );
+
+ if ( path_list.find( "/sbin" ) == path_list.end() )
+ {
+ path_list << "/sbin";
+ }
+
+ if ( path_list.find( "/usr/sbin" ) == path_list.end() )
+ {
+ path_list << "/usr/sbin";
+ }
+
+ if ( path_list.find( "/usr/local/sbin" ) == path_list.end() )
+ {
+ path_list << "/usr/local/sbin";
+ }
+
+ // Put all programs that are needed by Smb4K
+ // into the map below:
+
+ QMap<QString /*name*/, bool /*located*/> program_list;
+ QMap<QString /*name*/, QString /*absolute path*/> program_paths;
+
+ // Mandatory programs:
+ program_list.insert( "grep", false );
+ program_list.insert( "awk", false );
+ program_list.insert( "sed", false );
+ program_list.insert( "xargs", false );
+ program_list.insert( "rmdir", false );
+ program_list.insert( "nmblookup", false );
+ program_list.insert( "smbclient", false );
+ program_list.insert( "smbspool", false );
+ program_list.insert( "net", false );
+#ifndef __FreeBSD__
+ program_list.insert( "mount.cifs", false );
+ program_list.insert( "umount.cifs", false );
+ program_list.insert( "smbmount", false );
+ program_list.insert( "smbumount", false );
+ program_list.insert( "mount", false );
+#else
+ program_list.insert( "mount_smbfs", false );
+ program_list.insert( "smbutil", false );
+#endif
+ program_list.insert( "umount", false );
+ program_list.insert( "smb4k_mount", false );
+ program_list.insert( "smb4k_umount", false );
+ program_list.insert( "smb4k_kill", false );
+ program_list.insert( "smb4k_cat", false );
+ program_list.insert( "smb4k_mv", false );
+
+ // Optional programs
+ program_list.insert( "super", false );
+ program_list.insert( "sudo", false );
+ program_list.insert( "dvips", false );
+ program_list.insert( "enscript", false );
+ program_list.insert( "rsync", false );
+ program_list.insert( "konsole", false );
+
+
+ for ( QStringList::ConstIterator it = path_list.begin(); it != path_list.end(); ++it )
+ {
+ QDir::setCurrent( *it );
+
+ for ( QMap<QString, bool>::Iterator p = program_list.begin(); p != program_list.end(); ++p )
+ {
+ if ( p.data() == false ) // not located yet
+ {
+ if ( QFile::exists( p.key() ) )
+ {
+ program_paths.insert( p.key(), QDir::currentDirPath()+QDir::separator()+p.key() );
+ program_list[ p.key() ] = true;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ // Find out if Smb4K is to be starting up at all:
+ QStringList missing;
+
+ if ( !program_list["grep"] )
+ {
+ missing.append( "grep" );
+ }
+ else
+ {
+ Smb4KSettings::self()->grepItem()->setDefaultValue( program_paths["grep"] );
+
+ if ( Smb4KSettings::grep().isEmpty() )
+ {
+ Smb4KSettings::self()->grepItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["awk"] )
+ {
+ missing.append( "awk" );
+ }
+ else
+ {
+ Smb4KSettings::self()->awkItem()->setDefaultValue( program_paths["awk"] );
+
+ if ( Smb4KSettings::awk().isEmpty() )
+ {
+ Smb4KSettings::self()->awkItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["sed"] )
+ {
+ missing.append( "sed" );
+ }
+ else
+ {
+ Smb4KSettings::self()->sedItem()->setDefaultValue( program_paths["sed"] );
+
+ if ( Smb4KSettings::sed().isEmpty() )
+ {
+ Smb4KSettings::self()->sedItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["xargs"] )
+ {
+ missing.append( "xargs" );
+ }
+ else
+ {
+ Smb4KSettings::self()->xargsItem()->setDefaultValue( program_paths["xargs"] );
+
+ if ( Smb4KSettings::xargs().isEmpty() )
+ {
+ Smb4KSettings::self()->xargsItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["rmdir"] )
+ {
+ missing.append( "rmdir" );
+ }
+ else
+ {
+ Smb4KSettings::self()->rmdirItem()->setDefaultValue( program_paths["rmdir"] );
+
+ if ( Smb4KSettings::rmdir().isEmpty() )
+ {
+ Smb4KSettings::self()->rmdirItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["nmblookup"] )
+ {
+ missing.append( "nmblookup" );
+ }
+ else
+ {
+ Smb4KSettings::self()->nmblookupItem()->setDefaultValue( program_paths["nmblookup"] );
+
+ if ( Smb4KSettings::nmblookup().isEmpty() )
+ {
+ Smb4KSettings::self()->nmblookupItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smbclient"] )
+ {
+ missing.append( "smbclient" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smbclientItem()->setDefaultValue( program_paths["smbclient"] );
+
+ if ( Smb4KSettings::smbclient().isEmpty() )
+ {
+ Smb4KSettings::self()->smbclientItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smbspool"] )
+ {
+ missing.append( "smbspool" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smbspoolItem()->setDefaultValue( program_paths["smbspool"] );
+
+ if ( Smb4KSettings::smbspool().isEmpty() )
+ {
+ Smb4KSettings::self()->smbspoolItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["net"] )
+ {
+ missing.append( "net" );
+ }
+ else
+ {
+ Smb4KSettings::self()->netItem()->setDefaultValue( program_paths["net"] );
+
+ if ( Smb4KSettings::net().isEmpty() )
+ {
+ Smb4KSettings::self()->netItem()->setDefault();
+ }
+ }
+
+#ifndef __FreeBSD__
+
+ if ( !program_list["mount.cifs"] && !program_list["smbmount"] )
+ {
+ missing.append( "mount.cifs & smbmount" );
+ }
+ else
+ {
+ // One of the two programs is at least present, so we can do
+ // it like this:
+
+ QString filesystem;
+
+ if ( program_list["mount.cifs"] )
+ {
+ Smb4KSettings::self()->mount_cifsItem()->setDefaultValue( program_paths["mount.cifs"] );
+
+ if ( Smb4KSettings::mount_cifs().isEmpty() )
+ {
+ Smb4KSettings::self()->mount_cifsItem()->setDefault();
+ }
+ }
+ else
+ {
+ Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::SMBFS );
+ }
+
+ if ( program_list["smbmount"] )
+ {
+ Smb4KSettings::self()->smbmountItem()->setDefaultValue( program_paths["smbmount"] );
+
+ if ( Smb4KSettings::smbmount().isEmpty() )
+ {
+ Smb4KSettings::self()->smbmountItem()->setDefault();
+ }
+ }
+ else
+ {
+ Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::CIFS );
+ }
+ }
+
+ if ( !program_list["umount.cifs"] && !program_list["smbumount"] )
+ {
+ missing.append( "umount.cifs & smbumount" );
+ }
+ else
+ {
+ // One of the two programs is at least present, so we can do
+ // it like this:
+
+ QString filesystem;
+
+ if ( program_list["umount.cifs"] )
+ {
+ Smb4KSettings::self()->umount_cifsItem()->setDefaultValue( program_paths["umount.cifs"] );
+
+ if ( Smb4KSettings::umount_cifs().isEmpty() )
+ {
+ Smb4KSettings::self()->umount_cifsItem()->setDefault();
+ }
+ }
+ else
+ {
+ Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::SMBFS );
+ }
+
+ if ( program_list["smbumount"] )
+ {
+ Smb4KSettings::self()->smbumountItem()->setDefaultValue( program_paths["smbumount"] );
+
+ if ( Smb4KSettings::smbumount().isEmpty() )
+ {
+ Smb4KSettings::self()->smbumountItem()->setDefault();
+ }
+ }
+ else
+ {
+ Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::CIFS );
+ }
+ }
+
+ if ( !program_list["mount"] )
+ {
+ missing.append( "mount" );
+ }
+ else
+ {
+ Smb4KSettings::self()->mountItem()->setDefaultValue( program_paths["mount"] );
+
+ if ( Smb4KSettings::mount().isEmpty() )
+ {
+ Smb4KSettings::self()->mountItem()->setDefault();
+ }
+ }
+
+#else
+
+ if ( !program_list["mount_smbfs"] )
+ {
+ missing.append( "mount_smbfs" );
+ }
+ else
+ {
+ Smb4KSettings::self()->mount_smbfsItem()->setDefaultValue( program_paths["mount_smbfs"] );
+
+ if ( Smb4KSettings::mount_smbfs().isEmpty() )
+ {
+ Smb4KSettings::self()->mount_smbfsItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smbutil"] )
+ {
+ missing.append( "smbutil" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smbutilItem()->setDefaultValue( program_paths["smbutil"] );
+
+ if ( Smb4KSettings::smbutil().isEmpty() )
+ {
+ Smb4KSettings::self()->smbutilItem()->setDefault();
+ }
+ }
+
+#endif
+
+ if ( !program_list["umount"] )
+ {
+ missing.append( "umount" );
+ }
+ else
+ {
+ Smb4KSettings::self()->umountItem()->setDefaultValue( program_paths["umount"] );
+
+ if ( Smb4KSettings::umount().isEmpty() )
+ {
+ Smb4KSettings::self()->umountItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smb4k_mount"] )
+ {
+ missing.append( "smb4k_mount" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smb4k_mountItem()->setDefaultValue( program_paths["smb4k_mount"] );
+
+ if ( Smb4KSettings::smb4k_mount().isEmpty() )
+ {
+ Smb4KSettings::self()->smb4k_mountItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smb4k_umount"] )
+ {
+ missing.append( "smb4k_umount" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smb4k_umountItem()->setDefaultValue( program_paths["smb4k_umount"] );
+
+ if ( Smb4KSettings::smb4k_umount().isEmpty() )
+ {
+ Smb4KSettings::self()->smb4k_umountItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smb4k_kill"] )
+ {
+ missing.append( "smb4k_kill" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smb4k_killItem()->setDefaultValue( program_paths["smb4k_kill"] );
+
+ if ( Smb4KSettings::smb4k_kill().isEmpty() )
+ {
+ Smb4KSettings::self()->smb4k_killItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smb4k_cat"] )
+ {
+ missing.append( "smb4k_cat" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smb4k_catItem()->setDefaultValue( program_paths["smb4k_cat"] );
+
+ if ( Smb4KSettings::smb4k_cat().isEmpty() )
+ {
+ Smb4KSettings::self()->smb4k_catItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["smb4k_mv"] )
+ {
+ missing.append( "smb4k_mv" );
+ }
+ else
+ {
+ Smb4KSettings::self()->smb4k_mvItem()->setDefaultValue( program_paths["smb4k_mv"] );
+
+ if ( Smb4KSettings::smb4k_mv().isEmpty() )
+ {
+ Smb4KSettings::self()->smb4k_mvItem()->setDefault();
+ }
+ }
+
+ if ( !missing.isEmpty() )
+ {
+ // Error out if one of the mandatory programs is
+ // missing:
+
+ Smb4KError::error( ERROR_MISSING_PROGRAMS, missing.join( ", " ) );
+ exit( EXIT_FAILURE );
+ }
+ else
+ {
+ // Check for the optional programs:
+
+ if ( !program_list["super"] )
+ {
+ if ( (Smb4KSettings::useForceUnmount() ||
+ Smb4KSettings::alwaysUseSuperUser()) &&
+ Smb4KSettings::superUserProgram() ==
+ Smb4KSettings::EnumSuperUserProgram::Super )
+ {
+ Smb4KError::information( INFO_DISABLE_SUID_FEATURE, "super" );
+
+ // Reset the super user settings:
+ Smb4KSettings::self()->useForceUnmountItem()->setDefault();
+ Smb4KSettings::self()->alwaysUseSuperUserItem()->setDefault();
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ Smb4KSettings::self()->superItem()->setDefaultValue( program_paths["super"] );
+
+ if ( Smb4KSettings::super().isEmpty() )
+ {
+ Smb4KSettings::self()->superItem()->setDefault();
+ }
+ }
+
+ if ( !program_list["sudo"] )
+ {
+ if ( (Smb4KSettings::useForceUnmount() ||
+ Smb4KSettings::alwaysUseSuperUser()) &&
+ Smb4KSettings::superUserProgram() ==
+ Smb4KSettings::EnumSuperUserProgram::Super )
+ {
+ Smb4KError::information( INFO_DISABLE_SUID_FEATURE, "sudo" );
+
+ // Reset the super user settings:
+ Smb4KSettings::self()->useForceUnmountItem()->setDefault();
+ Smb4KSettings::self()->alwaysUseSuperUserItem()->setDefault();
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ Smb4KSettings::self()->sudoItem()->setDefaultValue( program_paths["sudo"] );
+
+ if ( Smb4KSettings::sudo().isEmpty() )
+ {
+ Smb4KSettings::self()->sudoItem()->setDefault();
+ }
+ }
+
+ if ( program_list["dvips"] )
+ {
+ Smb4KSettings::self()->dvipsItem()->setDefaultValue( program_paths["dvips"] );
+
+ if ( Smb4KSettings::dvips().isEmpty() )
+ {
+ Smb4KSettings::self()->dvipsItem()->setDefault();
+ }
+ }
+
+ if ( program_list["enscript"] )
+ {
+ Smb4KSettings::self()->enscriptItem()->setDefaultValue( program_paths["enscript"] );
+
+ if ( Smb4KSettings::enscript().isEmpty() )
+ {
+ Smb4KSettings::self()->enscriptItem()->setDefault();
+ }
+ }
+
+ if ( program_list["rsync"] )
+ {
+ Smb4KSettings::self()->rsyncItem()->setDefaultValue( program_paths["rsync"] );
+
+ if ( Smb4KSettings::rsync().isEmpty() )
+ {
+ Smb4KSettings::self()->rsyncItem()->setDefault();
+ }
+ }
+
+ if ( program_list["konsole"] )
+ {
+ Smb4KSettings::self()->konsoleItem()->setDefaultValue( program_paths["konsole"] );
+
+ if ( Smb4KSettings::konsole().isEmpty() )
+ {
+ Smb4KSettings::self()->konsoleItem()->setDefault();
+ }
+ }
+
+ // Write the configuration to disk:
+ Smb4KSettings::writeConfig();
+ }
+}
+
+
+void Smb4KCore::setDefaultSettings()
+{
+ // Samba options that have to be dynamically imported from smb.conf:
+ QMap<QString, QString> opts = optionsHandler()->globalSambaOptions();
+
+ if ( !opts["netbios name"].isEmpty() )
+ {
+ Smb4KSettings::self()->netBIOSNameItem()->setDefaultValue( opts["netbios name"] );
+
+ if ( Smb4KSettings::netBIOSName().isEmpty() )
+ {
+ Smb4KSettings::self()->netBIOSNameItem()->setDefault();
+ }
+ }
+
+ if ( !opts["workgroup"].isEmpty() )
+ {
+ Smb4KSettings::self()->domainNameItem()->setDefaultValue( opts["workgroup"] );
+
+ if ( Smb4KSettings::domainName().isEmpty() )
+ {
+ Smb4KSettings::self()->domainNameItem()->setDefault();
+ }
+ }
+
+ if ( !opts["socket options"].isEmpty() )
+ {
+ Smb4KSettings::self()->socketOptionsItem()->setDefaultValue( opts["socket options"] );
+
+ if ( Smb4KSettings::socketOptions().isEmpty() )
+ {
+ Smb4KSettings::self()->socketOptionsItem()->setDefault();
+ }
+ }
+
+ if ( !opts["netbios scope"].isEmpty() )
+ {
+ Smb4KSettings::self()->netBIOSScopeItem()->setDefaultValue( opts["netbios scope"] );
+
+ if ( Smb4KSettings::netBIOSScope().isEmpty() )
+ {
+ Smb4KSettings::self()->netBIOSScopeItem()->setDefault();
+ }
+ }
+
+ if ( !opts["name resolve order"].isEmpty() )
+ {
+ Smb4KSettings::self()->nameResolveOrderItem()->setDefaultValue( opts["name resolve order"] );
+
+ if ( Smb4KSettings::nameResolveOrder().isEmpty() )
+ {
+ Smb4KSettings::self()->nameResolveOrderItem()->setDefault();
+ }
+ }
+
+ if ( !opts["interfaces"].isEmpty() )
+ {
+ Smb4KSettings::self()->broadcastAddressItem()->setDefaultValue( opts["interfaces"] );
+
+ if ( Smb4KSettings::broadcastAddress().isEmpty() )
+ {
+ Smb4KSettings::self()->broadcastAddressItem()->setDefault();
+ }
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KCore::slotSetScannerState( int state )
+{
+ m_scanner_state = state;
+ setCurrentState( state );
+ emit runStateChanged();
+}
+
+
+void Smb4KCore::slotSetMounterState( int state )
+{
+ m_mounter_state = state;
+ setCurrentState( state );
+ emit runStateChanged();
+}
+
+
+void Smb4KCore::slotSetPrinterHandlerState( int state )
+{
+ m_print_state = state;
+ setCurrentState( state );
+ emit runStateChanged();
+}
+
+
+void Smb4KCore::slotSetSynchronizerState( int state )
+{
+ m_syncer_state = state;
+ setCurrentState( state );
+ emit runStateChanged();
+}
+
+
+void Smb4KCore::slotSetPreviewerState( int state )
+{
+ m_previewer_state = state;
+ setCurrentState( state );
+ emit runStateChanged();
+}
+
+
+void Smb4KCore::slotShutdown()
+{
+ Smb4KSettings::writeConfig();
+}
+
+#include "smb4kcore.moc"
diff --git a/smb4k/core/smb4kcore.h b/smb4k/core/smb4kcore.h
new file mode 100644
index 0000000..fbaa539
--- /dev/null
+++ b/smb4k/core/smb4kcore.h
@@ -0,0 +1,354 @@
+/***************************************************************************
+ smb4kcore - The main core class of Smb4K.
+ -------------------
+ begin : Do Apr 8 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KCORE_H
+#define SMB4KCORE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qmap.h>
+#include <qtimer.h>
+#include <qvaluelist.h>
+
+// application specific includes
+#include "smb4kscanner.h"
+#include "smb4kmounter.h"
+#include "smb4kfileio.h"
+#include "smb4kbookmarkhandler.h"
+#include "smb4kprint.h"
+#include "smb4ksynchronizer.h"
+#include "smb4kpreviewer.h"
+
+// forward declarations
+class Smb4KWorkgroupItem;
+class Smb4KHostItem;
+class Smb4KShare;
+
+
+/**
+ * This is the top-level core class. It inherits most of the core classes.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KCore : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Returns a static pointer to this class.
+ */
+ static Smb4KCore *self();
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KCore();
+
+ /**
+ * This function registers with the DCOP server and starts the core.
+ * It initializes the scanning of the network, the remounting of
+ * recently used shares, etc. Use this, if you want to take advantage
+ * of the automatic features of Smb4K's core.
+ */
+ void init();
+
+ /**
+ * Returns the state the scanner is in.
+ */
+ static int scannerState() { return self()->m_scanner_state; }
+
+ /**
+ * Returns TRUE, if the scanner is running, otherwise FALSE.
+ */
+ static bool scannerIsRunning() { return self()->m_scanner->isRunning(); }
+
+ /**
+ * Returns the state the mounter is in.
+ */
+ static int mounterState() { return self()->m_mounter_state; }
+
+ /**
+ * Returns TRUE, if the mounter is running, otherwise FALSE.
+ */
+ static bool mounterIsRunning() { return self()->m_mounter->isRunning(); }
+
+ /**
+ * Returns the state the print object is in.
+ */
+ static int printState() { return self()->m_print_state; }
+
+ /**
+ * Returns TRUE, if the print object is running, otherwise FALSE.
+ */
+ static bool printIsRunning() { return self()->m_print->isRunning(); }
+
+ /**
+ * Returns the state the synchronizer is in.
+ */
+ static int synchronizerState() { return self()->m_syncer_state; }
+
+ /**
+ * Returns TRUE, if the synchronizer is running, otherwise FALSE.
+ */
+ static bool synchronizerIsRunning() { return self()->m_synchronizer->isRunning(); }
+
+ /**
+ * Returns TRUE if one of the core classes is doing something.
+ */
+ static bool isRunning();
+
+ /**
+ * Returns the current state the core is in.
+ */
+ static int currentState() { return self()->m_current_state; }
+
+ /**
+ * Returns a pointer to the scanner object.
+ */
+ static Smb4KScanner *scanner() { return self()->m_scanner; }
+
+ /**
+ * Returns a pointer to the mounter object.
+ */
+ static Smb4KMounter *mounter() { return self()->m_mounter; }
+
+ /**
+ * Returns a pointer to the bookmark handler object.
+ */
+ static Smb4KBookmarkHandler *bookmarkHandler() { return self()->m_bookmarkHandler; }
+
+ /**
+ * Returns a pointer to the file IO object.
+ */
+ static Smb4KFileIO *fileIO() { return self()->m_fileIO; }
+
+ /**
+ * Returns a pointer to the printer handler object.
+ */
+ static Smb4KPrint *print() { return self()->m_print; }
+
+ /**
+ * Returns a pointer to the synchronizer object.
+ */
+ static Smb4KSynchronizer *synchronizer() { return self()->m_synchronizer; }
+
+ /**
+ * Returns a pointer to the previewer object.
+ */
+ static Smb4KPreviewer *previewer() { return self()->m_previewer; }
+
+ /**
+ * Aborts any action of the core.
+ */
+ static void abort();
+
+ /**
+ * This enumeration determines with which application the mount point
+ * of the current mounted share is to be opened.
+ */
+ enum OpenWith { Konqueror, Konsole };
+
+ /**
+ * Opens the mount point of a share. This function is used to run the file manager.
+ *
+ * @param share The share to be opened.
+ *
+ * @param openWith Integer of type Smb4KCore::OpenWith. Determines with which
+ * application the share should be opened.
+ */
+ static void open( Smb4KShare *share, int openWith = Konqueror );
+
+ signals:
+ /**
+ * This signal is emitted, if one of the core objects
+ * starts or stops running.
+ */
+ void runStateChanged();
+
+ protected:
+ /**
+ * The constructor
+ */
+ Smb4KCore();
+
+ /**
+ * A static pointer to this class
+ */
+ static Smb4KCore *m_self;
+
+ protected slots:
+ /**
+ * This slot sets the run state of the scanner.
+ *
+ * @param state The run state the scanner is in. For definition of the
+ * run states see smb4kdefs.h header file.
+ */
+ void slotSetScannerState( int state );
+
+ /**
+ * This slot sets the run state of the mounter.
+ *
+ * @param state The run state the mounter is in. For definition of the
+ * run states see smb4kdefs.h header file.
+ */
+ void slotSetMounterState( int state );
+
+ /**
+ * This slot sets the run state of the synchronizer.
+ *
+ * @param state The run state the synchronizer is in. For definition of the
+ * run states see smb4kdefs.h header file.
+ */
+ void slotSetSynchronizerState( int state );
+
+ /**
+ * This slot sets the run state of the print handler.
+ *
+ * @param state The run state the print handler is in. For definition of the
+ * run states see smb4kdefs.h header file.
+ */
+ void slotSetPrinterHandlerState( int state );
+
+ /**
+ * This slot sets the run state for the previewer.
+ *
+ * @param state The state the previewer is in. For definition of the
+ * run states see smb4kdefs.h header file.
+ */
+ void slotSetPreviewerState( int state );
+
+ /**
+ * This slot is connected to the KApplication::shutDown() signal. It is invoked
+ * when the application is shut down by the KDE logout or by pressing CTRL+Q, etc.
+ */
+ void slotShutdown();
+
+ private:
+ /**
+ * The scanner object.
+ */
+ Smb4KScanner *m_scanner;
+
+ /**
+ * The mounter object.
+ */
+ Smb4KMounter *m_mounter;
+
+ /**
+ * The bookmark handler object.
+ */
+ Smb4KBookmarkHandler *m_bookmarkHandler;
+
+ /**
+ * The FileIO object.
+ */
+ Smb4KFileIO *m_fileIO;
+
+ /**
+ * The printer handler object.
+ */
+ Smb4KPrint *m_print;
+
+ /**
+ * The synchronizer object.
+ */
+ Smb4KSynchronizer *m_synchronizer;
+
+ /**
+ * The previewer object.
+ */
+ Smb4KPreviewer *m_previewer;
+
+ /**
+ * The state the sanner is in.
+ */
+ int m_scanner_state;
+
+ /**
+ * The state the mounter is in.
+ */
+ int m_mounter_state;
+
+ /**
+ * Holds the current state.
+ */
+ int m_current_state;
+
+ /**
+ * The state the printer handler is in.
+ */
+ int m_print_state;
+
+ /**
+ * The state the synchronizer is in.
+ */
+ int m_syncer_state;
+
+ /**
+ * The state of the previewer is in.
+ */
+ int m_previewer_state;
+
+ /**
+ * This function is used to set the current state of the core.
+ *
+ * @param state One of the states defined in smb4kdefs.h
+ */
+ void setCurrentState( int state );
+
+ /**
+ * Searches for the needed programs and emits an error
+ * if mandatory ones are missing.
+ */
+ void searchPrograms();
+
+ /**
+ * This is the list of workgroups known to Smb4K. It is filled by
+ * the scanner and may be used by all other classes that are invoked
+ * by Smb4KCore.
+ */
+ QValueList<Smb4KWorkgroupItem *> m_workgroups;
+
+ /**
+ * This is the list of remote hosts known to Smb4K. It is filled by
+ * the scanner and may be used by all other classes that are invoked
+ * by Smb4KCore.
+ */
+ QValueList<Smb4KHostItem *> m_hosts;
+
+ /**
+ * Set default values for settings that depend on the system Smb4K is
+ * running on and that have to be set dynamically.
+ */
+ void setDefaultSettings();
+};
+
+#endif
diff --git a/smb4k/core/smb4kdefs.h b/smb4k/core/smb4kdefs.h
new file mode 100644
index 0000000..b9ce07f
--- /dev/null
+++ b/smb4k/core/smb4kdefs.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+ smb4kdefs.h - Definitions for Smb4K
+ -------------------
+ begin : Mo Mär 15 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+#ifndef SMB4KDEFS_H
+#define SMB4KDEFS_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//
+// Run states
+//
+
+#define SCANNER_INIT 0
+#define SCANNER_OPENING_WORKGROUP 1
+#define SCANNER_OPENING_HOST 2
+#define SCANNER_RETRIEVING_INFO 3
+#define SCANNER_SEARCHING 4
+#define SCANNER_RETRYING_OPENING_HOST 5
+#define SCANNER_STOP 6
+#define MOUNTER_MOUNTING 7
+#define MOUNTER_UNMOUNTING 8
+#define MOUNTER_STOP 9
+#define PRINT_START 10
+#define PRINT_STOP 11
+#define SYNCHRONIZER_START 12
+#define SYNCHRONIZER_STOP 13
+#define PREVIEWER_START 14
+#define PREVIEWER_STOP 15
+#define CORE_STOP 16
+
+//
+// Error codes:
+//
+
+// (1) Network related errors.
+#define ERROR_GETTING_BROWSELIST 100
+#define ERROR_GETTING_MEMBERS 101
+#define ERROR_GETTING_SHARES 102
+#define ERROR_GETTING_PREVIEW 103
+#define ERROR_NET_COMMAND 104
+#define ERROR_IP_CANNOT_BE_USED 105
+
+// (2) Errors involving mounting, unmounting
+// and importing shares.
+#define ERROR_MOUNTING_SHARE 106
+#define ERROR_UNMOUNTING_SHARE 107
+#define ERROR_UNMOUNTING_NOT_ALLOWED 108
+#define ERROR_MOUNTPOINT_EMPTY 109
+#define ERROR_IMPORTING_SHARES 110
+
+// (3) Errors that are connected to printing
+#define ERROR_PRINTING 111
+
+// (4) Errors that are connected to
+// synchronization
+#define ERROR_SYNCHRONIZING 112
+
+// (5) Errors that occur when handling
+// bookmarks
+#define ERROR_BOOKMARK_PRINTER 113
+
+// (6) Errors that occur when handling
+// authentication data
+#define ERROR_OPENING_WALLET_FAILED 114
+
+// (7) Errors that occur when handling files
+// and directories.
+#define ERROR_FILE_NOT_FOUND 115
+#define ERROR_OPENING_FILE 116
+#define ERROR_READING_FILE 117
+#define ERROR_WRITING_FILE 118
+#define ERROR_CLOSING_FILE 119
+#define ERROR_GETTING_PERMISSIONS 120
+#define ERROR_DIRECTORY_NOT_FOUND 121
+#define ERROR_CREATING_TEMP_DIR 122
+#define ERROR_CREATING_TEMP_FILE 123
+#define ERROR_FILE_IS_IRREGULAR 124
+#define ERROR_MKDIR_FAILED 125
+
+// (8) Errors that occur when handling programs
+#define ERROR_MISSING_PROGRAMS 126
+#define ERROR_COMMAND_NOT_FOUND 127
+
+// (9) Other errors
+#define ERROR_UNKNOWN 128
+#define ERROR_GETTING_HOSTNAME 129
+#define ERROR_LOCKED 130
+#define ERROR_FEATURE_NOT_ENABLED 131
+#define ERROR_GETTING_GIDS 132
+
+//
+// Warning codes:
+//
+
+/* None defined yet. use 200 ff. for that */
+
+//
+// Information codes:
+//
+
+#define INFO_MIMETYPE_NOT_SUPPORTED 300
+#define INFO_DISABLE_SUID_FEATURE 301
+#define INFO_BOOKMARK_LABEL_IN_USE 302
+
+//
+// Event types
+//
+
+#define EVENT_LOAD_SETTINGS 100000
+#define EVENT_SET_FOCUS 100001
+#define EVENT_SCAN_NETWORK 100002
+
+//
+// Other definitions
+//
+
+#define TIMER_INTERVAL 25
+#define THREAD_WAITING_TIME 100
+#define TEMPPATHLEN 18
+
+#endif
diff --git a/smb4k/core/smb4kerror.cpp b/smb4k/core/smb4kerror.cpp
new file mode 100644
index 0000000..66a3089
--- /dev/null
+++ b/smb4k/core/smb4kerror.cpp
@@ -0,0 +1,408 @@
+/***************************************************************************
+ smb4kerror - This is the class that manages the error messages.
+ -------------------
+ begin : Fr Sep 22 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <kmessagebox.h>
+#include <klocale.h>
+
+// application specific includes
+#include "smb4kerror.h"
+#include "smb4kdefs.h"
+
+void Smb4KError::error( int code, const QString &text, const QString &details )
+{
+ switch ( code )
+ {
+ case ERROR_GETTING_BROWSELIST:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The browse list could not be retrieved.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The browse list could not be retrieved.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_GETTING_MEMBERS:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The list of servers could not be retrieved.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The list of servers could not be retrieved.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_GETTING_SHARES:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The list of shares could not be retrieved.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The list of shares could not be retrieved.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_GETTING_PREVIEW:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The preview could not be compiled.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The preview could not be compiled.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_OPENING_WALLET_FAILED:
+ {
+ KMessageBox::error( 0, i18n( "The wallet \"%1\" could not be opened. KWallet support will be disabled for this session." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_GETTING_PERMISSIONS:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "Some file permissions could not be determined.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "Some file permissions could not be determined.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_UNMOUNTING_NOT_ALLOWED:
+ {
+ KMessageBox::error( 0, i18n( "You are not allowed to unmount this share, because it is owned by another user." ) );
+
+ break;
+ }
+ case ERROR_MOUNTING_SHARE:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The share \"%1\" could not be mounted.\nDetailed information cannot be provided because there was no error message." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The share \"%1\" could not be mounted.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_UNMOUNTING_SHARE:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The share \"%1\" could not be unmounted.\nDetailed information cannot be provided because there was no error message." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The share \"%1\" could not be unmounted.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_FILE_NOT_FOUND:
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" could not be found." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_READING_FILE:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" could not be read." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The file \"%1\" could not be read.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_GETTING_HOSTNAME:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The name of your computer could not be determined by using the gethostname() system call.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The name of your computer could not be determined by using the gethostname() system call.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_MISSING_PROGRAMS:
+ {
+ KMessageBox::error( 0, i18n( "Either your PATH environment variable is not set properly or there are the following programs missing on your system:\n%1\nPlease correct this and restart Smb4K." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_LOCKED:
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" is currently being edited by user %2. To avoid any problems, access to this file is denied at the moment. Please try again later." ).arg( text.section( ":", 1, 1 ), text.section( ":", 0, 0 ) ) );
+
+ break;
+ }
+ case ERROR_MKDIR_FAILED:
+ {
+ KMessageBox::error( 0, i18n( "The directory \"%1\" could not be created." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_WRITING_FILE:
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" could not be written." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_MOUNTPOINT_EMPTY:
+ {
+ KMessageBox::error( 0, i18n( "The share could not be unmounted, because the mount point string was empty." ) );
+
+ break;
+ }
+ case ERROR_FEATURE_NOT_ENABLED:
+ {
+ KMessageBox::error( 0, i18n( "This feature has not been enabled." ) );
+
+ break;
+ }
+ case ERROR_BOOKMARK_PRINTER:
+ {
+ KMessageBox::error( 0, i18n( "Printers cannot be bookmarked." ) );
+
+ break;
+ }
+ case ERROR_IP_CANNOT_BE_USED:
+ {
+ KMessageBox::sorry( 0, i18n( "IP addresses are not supported with this search method. Please choose \"Use nmblookup\" in the configuration dialog and try again." ) );
+
+ break;
+ }
+ case ERROR_IMPORTING_SHARES:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The list of mounted SMBFS and CIFS shares could not be imported.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The list of mounted SMBFS and CIFS shares could not be imported.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_COMMAND_NOT_FOUND:
+ {
+ KMessageBox::error( 0, i18n( "The command \"%1\" could not be found." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_PRINTING:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" could not be printed.\nDetailed information cannot be provided because there was no error message." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The file \"%1\" could not be printed.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_CREATING_TEMP_DIR:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The temporary directory \"%1\" could not be created.\nDetailed information cannot be provided because there was no error message." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The temporary directory \"%1\" could not be created.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_CREATING_TEMP_FILE:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The temporary file \"%1\" could not be created.\nDetailed information cannot be provided because there was no error message." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The temporary file \"%1\" could not be created.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_DIRECTORY_NOT_FOUND:
+ {
+ KMessageBox::error( 0, i18n( "The directory \"%1\" could not be found." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_FILE_IS_IRREGULAR:
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" is irregular. That means it is either a symlink, a fifo, or something similar. This could indicate that someone is trying to exploit your system. Please inform your system administrator." ).arg( text ) );
+
+ break;
+ }
+ case ERROR_SYNCHRONIZING:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The synchronization could not the accomplished successfully.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The synchronization could not the accomplished successfully.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_OPENING_FILE:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" could not be opened." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The file \"%1\" could not be opened.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_CLOSING_FILE:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The file \"%1\" could not be closed." ).arg( text ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The file \"%1\" could not be closed.\nRead the error message under \"Details\" to find out more." ).arg( text ), details );
+ }
+
+ break;
+ }
+ case ERROR_NET_COMMAND:
+ {
+ KMessageBox::error( 0, i18n( "The list of arguments for the \"net\" command could not be assembled.\nAt the moment it reads: %1" ).arg( text ) );
+
+ break;
+ }
+ case ERROR_GETTING_GIDS:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "The list of supplementary group IDs could not be determined." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "The list of supplementary group IDs could not be determined.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ case ERROR_UNKNOWN:
+ default:
+ {
+ if ( details.stripWhiteSpace().isEmpty() )
+ {
+ KMessageBox::error( 0, i18n( "An unknown error occurred.\nDetailed information cannot be provided because there was no error message." ) );
+ }
+ else
+ {
+ KMessageBox::detailedError( 0, i18n( "An unknown error occurred.\nRead the error message under \"Details\" to find out more." ), details );
+ }
+
+ break;
+ }
+ }
+}
+
+
+int Smb4KError::warning( int code, const QString &, const QString & )
+{
+ switch ( code )
+ {
+ default:
+ {
+ return 0;
+ }
+ }
+}
+
+
+void Smb4KError::information( int code, const QString &text, const QString &details )
+{
+ switch ( code )
+ {
+ case INFO_MIMETYPE_NOT_SUPPORTED:
+ {
+ KMessageBox::information( 0, i18n( "The mimetype \"%1\" is not supported. Please convert the file to PostScript or PDF." ).arg( text ) );
+
+ break;
+ }
+ case INFO_DISABLE_SUID_FEATURE:
+ {
+ KMessageBox::information( 0, i18n( "You previously chose to use \"%1\", but now it is missing on your system. Smb4K will disable this feature." ).arg( text ) );
+
+ break;
+ }
+ case INFO_BOOKMARK_LABEL_IN_USE:
+ {
+ KMessageBox::information( 0, i18n( "The label \"%1\" is used more than once. It will automatically be renamed for bookmark \"%2\" to avoid confusion." ).arg( text, details ) );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+// No moc file needs to be included
diff --git a/smb4k/core/smb4kerror.h b/smb4k/core/smb4kerror.h
new file mode 100644
index 0000000..fb5f980
--- /dev/null
+++ b/smb4k/core/smb4kerror.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ smb4kerror - This is the class that manages the error messages.
+ -------------------
+ begin : Fr Sep 22 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KERROR_H
+#define SMB4KERROR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+class Smb4KError
+{
+ public:
+ /**
+ * Show an error that occurred in the core.
+ *
+ * @param code The error code as defined in smb4kdefs.h
+ *
+ * @param text Short text which will be included in the message that's shown
+ * to the user. Normally, a file name or similar is entered here.
+ * May be left blank if you do not need to fill text into the error
+ * message. Please note, that this text is not used to show details.
+ *
+ * @param details The text passed here is used to show details. Please note, that
+ * it depends on the kind of error if it is indeed shown.
+ */
+ static void error( int code,
+ const QString &text = QString::null,
+ const QString &details = QString::null );
+
+ /**
+ * Show a warning.
+ *
+ * @param code The code as defined in smb4kdefs.h
+ *
+ * @param text Short text which will be included in the message that's shown
+ * to the user. Normally, a file name or similar is entered here.
+ * May be left blank if you do not need to fill text into the error
+ * message. Please note, that this text is not used to show details.
+ *
+ * @param details The text passed here is used to show details. Please note, that
+ * it depends on the kind of error if it is indeed shown.
+ *
+ * @returns an integer value according to KMessageBox::ButtonCode or 0 if the warning code
+ * is unknown.
+ */
+ static int warning( int code,
+ const QString &text = QString::null,
+ const QString &details = QString::null );
+
+ /**
+ * Show an information.
+ *
+ * @param code The code as defined in smb4kdefs.h
+ *
+ * @param text Short text which will be included in the message that's shown
+ * to the user. Normally, a file name or similar is entered here.
+ * May be left blank if you do not need to fill text into the error
+ * message. Please note, that this text is not used to show details.
+ *
+ * @param details The text passed here is used to show details. Please note, that
+ * it depends on the kind of error if it is indeed shown.
+ */
+ static void information( int code,
+ const QString &text = QString::null,
+ const QString &details = QString::null );
+};
+
+#endif
diff --git a/smb4k/core/smb4kfileio.cpp b/smb4k/core/smb4kfileio.cpp
new file mode 100644
index 0000000..2b77cf5
--- /dev/null
+++ b/smb4k/core/smb4kfileio.cpp
@@ -0,0 +1,1795 @@
+/***************************************************************************
+ smb4kfileio - Does file IO operations for Smb4K
+ -------------------
+ begin : Do Jan 1 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+// KDE includes
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+// system specific includes
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <grp.h>
+#include <pwd.h>
+
+// application specific includes
+#include "smb4kfileio.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+
+Smb4KFileIO::Smb4KFileIO( QObject *parent, const char *name ) : QObject( parent, name )
+{
+ m_operation = NoOperation;
+ m_state = Idle;
+ m_error_occurred = false;
+
+ m_proc = new KProcess( this, "FileIOProcess" );
+ m_proc->setUseShell( true );
+
+ connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( processExited( KProcess * ) ),
+ this, SLOT( slotProcessExited( KProcess * ) ) );
+
+ connect( kapp, SIGNAL( shutDown() ),
+ this, SLOT( slotShutdown() ) );
+}
+
+
+Smb4KFileIO::~Smb4KFileIO()
+{
+}
+
+
+bool Smb4KFileIO::writeSudoers( Smb4KFileIO::Operation operation )
+{
+ m_operation = operation;
+ bool ok = false;
+
+ // Stop here if nothing has changed:
+ if ( m_operation == NoOperation )
+ {
+ emit finished();
+
+ ok = true;
+
+ return ok;
+ }
+
+ QString file = "sudoers";
+
+ if ( createLockFile( file ) )
+ {
+ // Find the file first:
+ QCString canonical_path = findFile( file );
+
+ if ( !canonical_path.isEmpty() )
+ {
+ // Stat the file, so that we know that it is safe to
+ // read from and write to it and whether we need to
+ // ask for the super user's password:
+ struct stat buf;
+
+ if ( lstat( canonical_path, &buf ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, canonical_path, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Look for the groups the user is in:
+ long ngroups_max;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+
+ gid_t list[ngroups_max];
+
+ if ( getgroups( ngroups_max, list ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_GIDS, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ return ok; // false
+ }
+
+ gid_t sup_gid = 65534; // set this to gid 'nobody' for initialization
+ bool found_gid = false;
+ int i = 0;
+
+ while ( list[i] )
+ {
+ if ( list[i] == buf.st_gid )
+ {
+ sup_gid = list[i];
+ found_gid = true;
+ }
+
+ i++;
+ }
+
+ // Error out if the file is irregular.
+ // Yes, yes, I know that this is normally done in a different
+ // way and that there might be a race here, but, hey, right here
+ // I don't care!
+ if ( !S_ISREG( buf.st_mode ) || S_ISFIFO( buf.st_mode ) || S_ISLNK( buf.st_mode ) )
+ {
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, canonical_path, QString::null );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Check access rights:
+ if ( (buf.st_uid == getuid() && (buf.st_mode & 00600) == (S_IWUSR | S_IRUSR)) /* user */ ||
+ (found_gid && buf.st_gid == sup_gid && (buf.st_mode & 00060) == (S_IWGRP | S_IRGRP)) /* group */ ||
+ ((buf.st_mode & 00006) == (S_IWOTH | S_IROTH)) /* others */ )
+ {
+ // The user has read and write access.
+
+ QFile file ( canonical_path );
+ QStringList contents;
+
+ if ( file.open( IO_ReadWrite ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( "\n", ts.read(), true );
+
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ QString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( "User_Alias\tSMB4KUSERS = "+QString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+ contents.append( "Defaults:SMB4KUSERS\tenv_keep += \"PASSWD USER\"" );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_kill() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_umount() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_mount() );
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+QString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) )
+ {
+ QString users = (*it).section( "=", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( QString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ QStringList list = QStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ file.close();
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ };
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ QStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Now write the contents to the file. The permissions
+ // will be preserved by this action.
+ ts << contents.join( "\n" ) << endl;
+
+ file.close();
+ }
+ else
+ {
+ // The entries are already in the file.
+ }
+
+ ok = true;
+
+ emit finished();
+
+ removeLockFile();
+
+ return ok;
+ }
+ else
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, canonical_path, file.errorString() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The user does not have enough access rights to perform
+ // the modification of the sudoers file. So, we need to use
+ // kdesu to get the contents of the file.
+
+ // Compose the command:
+ QString command;
+ command.append( "kdesu -t -c \"smb4k_cat " );
+ command.append( canonical_path+"\"" );
+ command.append( " ; sleep 2" );
+
+ m_state = ReadSudoers;
+
+ ok = true;
+
+ *m_proc << command;
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+
+ // The process is not finished, so finished() will be emitted
+ // later and the lock file will also be removed at the end.
+
+ return ok;
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_FILE_NOT_FOUND, canonical_path );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The error message has already been shown by
+ // Smb4KFileIO::createLockFile()
+ emit failed();
+ emit finished();
+
+ // We need not remove the lock file here.
+
+ return ok; // false
+ }
+
+ return ok;
+}
+
+
+bool Smb4KFileIO::writeSuperTab( Smb4KFileIO::Operation operation )
+{
+ m_operation = operation;
+ bool ok = false;
+
+ // Stop here if nothing has changed:
+ if ( m_operation == NoOperation )
+ {
+ emit finished();
+
+ ok = true;
+
+ return ok;
+ }
+
+ QString file = "super.tab";
+
+ if ( createLockFile( file ) )
+ {
+ // Find the file first:
+ QCString canonical_path = findFile( file );
+
+ if ( !canonical_path.isEmpty() )
+ {
+ // Stat the file, so that we know that it is safe to
+ // read from and write to it and whether we need to
+ // ask for the super user's password:
+ struct stat buf;
+
+ if ( lstat( canonical_path, &buf ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, canonical_path, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Look for the groups the user is in:
+ long ngroups_max;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+
+ gid_t list[ngroups_max];
+
+ if ( getgroups( ngroups_max, list ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_GIDS, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ return ok; // false
+ }
+
+ gid_t sup_gid = 65534; // set this to gid 'nobody' for initialization
+ bool found_gid = false;
+ int i = 0;
+
+ while ( list[i] )
+ {
+ if ( list[i] == buf.st_gid )
+ {
+ sup_gid = list[i];
+ found_gid = true;
+ }
+
+ i++;
+ }
+
+ // Error out if the file is irregular.
+ // Yes, yes, I know that this is normally done in a different
+ // way and that there might be a race here, but, hey, right here
+ // I don't care!
+ if ( !S_ISREG( buf.st_mode ) || S_ISFIFO( buf.st_mode ) || S_ISLNK( buf.st_mode ) )
+ {
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, canonical_path, QString::null );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Check access rights:
+ if ( (buf.st_uid == getuid() && (buf.st_mode & 00600) == (S_IWUSR | S_IRUSR)) /* user */ ||
+ (found_gid && buf.st_gid == sup_gid && (buf.st_mode & 00060) == (S_IWGRP | S_IRGRP)) /* group */ ||
+ ((buf.st_mode & 00006) == (S_IWOTH | S_IROTH)) /* others */ )
+ {
+ // The user has read and write access.
+
+ QFile file ( canonical_path );
+ QStringList contents;
+
+ if ( file.open( IO_ReadWrite ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( "\n", ts.read(), true );
+
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ QString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( ":define Smb4KUsers "+QString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+#ifndef __FreeBSD__
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root\tenv=PASSWD,USER" );
+#else
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel\tsetenv=HOME=$CALLER_HOME\tenv=PASSWD,USER" );
+#endif
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+QString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) )
+ {
+ QString users = (*it).section( "Smb4KUsers", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( QString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ QStringList list = QStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ file.close();
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ };
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ QStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Now write the contents to the file. The permissions
+ // will be preserved by this action.
+ ts << contents.join( "\n" ) << endl;
+
+ file.close();
+ }
+ else
+ {
+ // The entries are already in the file.
+ }
+
+ ok = true;
+
+ emit finished();
+
+ removeLockFile();
+
+ return ok;
+ }
+ else
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, canonical_path, file.errorString() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The user does not have enough access rights to perform
+ // the modification of the sudoers file. So, we need to use
+ // kdesu to get the contents of the file.
+
+ // Compose the command:
+ QString command;
+ command.append( "kdesu -t -c \"smb4k_cat " );
+ command.append( canonical_path+"\"" );
+ command.append( " ; sleep 2" );
+
+ m_state = ReadSuperTab;
+
+ ok = true;
+
+ *m_proc << command;
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+
+ // The process is not finished, so finished() will be emitted
+ // later and the lock file will also be removed at the end.
+
+ return ok;
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_FILE_NOT_FOUND, canonical_path );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The error message has already been shown by
+ // Smb4KFileIO::createLockFile()
+ emit failed();
+ emit finished();
+
+ // We need not remove the lock file here.
+
+ return ok; // false
+ }
+
+ return ok;
+}
+
+
+bool Smb4KFileIO::createLockFile( const QString &filename )
+{
+ bool ok = false;
+
+ // Determine the directory where to write the lock file. First, try
+ // /var/lock and than /var/tmp. If that does not work either, fall
+ // back to /tmp.
+ if ( m_lock_file.isEmpty() )
+ {
+ QValueList<QCString> dirs;
+ dirs << "/var/lock" << "/var/tmp" << "/tmp";
+
+ struct stat buf;
+
+ for ( QValueList<QCString>::ConstIterator it = dirs.begin(); it != dirs.end(); ++it )
+ {
+ // First check if the directory is available and writable
+ if ( lstat( *it, &buf ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_number != EACCES && error_number != ENOENT )
+ {
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, *it, strerror( error_number ) );
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // Look for the groups the user is in:
+ long ngroups_max;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+
+ gid_t list[ngroups_max];
+
+ if ( getgroups( ngroups_max, list ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_GIDS, QString::null, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ gid_t sup_gid = 65534; // set this to gid 'nobody' for initialization
+ bool found_gid = false;
+ int i = 0;
+
+ while ( list[i] )
+ {
+ if ( list[i] == buf.st_gid )
+ {
+ sup_gid = list[i];
+ found_gid = true;
+ }
+
+ i++;
+ }
+
+ // Check whether we are stat'ing a directory and that the
+ // user has read/write permissions.
+ if ( S_ISDIR( buf.st_mode ) /* is directory */ &&
+ (buf.st_uid == getuid() && (buf.st_mode & 00600) == (S_IWUSR | S_IRUSR)) /* user */ ||
+ (found_gid && buf.st_gid == sup_gid && (buf.st_mode & 00060) == (S_IWGRP | S_IRGRP)) /* group */ ||
+ ((buf.st_mode & 00006) == (S_IWOTH | S_IROTH)) /* others */ )
+ {
+ m_lock_file = *it+"/smb4k.lock";
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+
+ int file_descriptor;
+
+ // Create the lock file if necessary and open it:
+ if ( (file_descriptor = open( m_lock_file, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH )) == -1 )
+ {
+ // Error out if the opening failed:
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_OPENING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+ else
+ {
+ // Check what we actually opened:
+
+ struct stat file_stat;
+
+ if ( fstat( file_descriptor, &file_stat ) == -1 )
+ {
+ // Error out if we could not get the information about the file:
+ int error_number = errno;
+
+ // FIXME for >= 0.8.x: Change error code to ERROR_GETTING_STAT
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, QString::null, strerror( error_number ) );
+
+ return ok;
+ }
+
+ if ( !S_ISREG( file_stat.st_mode ) || S_ISFIFO( file_stat.st_mode ) || S_ISLNK( file_stat.st_mode ) )
+ {
+ // Close the file and error out, if we have opened an
+ // "irregular" file (i.e. a symlink, a fifo, etc.).
+
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, m_lock_file );
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+ else
+ {
+ // Continue if the file is regular.
+
+ char buffer[1000];
+ ssize_t size;
+
+ if ( (size = read( file_descriptor, buffer, 1000 )) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_READING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ if ( size >= 1000 )
+ {
+ // FIXME for >= 0.8.x: Change error code to ERROR_BUFFER_EXCEEDED
+ Smb4KError::error( ERROR_UNKNOWN, QString::null, i18n( "Buffer size exceeded" ) );
+
+ return ok; // false
+ }
+
+ QStringList contents = QStringList::split( '\n', QString::fromLocal8Bit( buffer, size ), false );
+ QString test_string = ":"+filename;
+ QString entry = contents.grep( test_string, true ).join( "\n" ).stripWhiteSpace();
+
+ if ( !entry.isEmpty() )
+ {
+ Smb4KError::error( ERROR_LOCKED, entry );
+
+ return ok; // false
+ }
+ else
+ {
+ contents << QString( "%1:%2" ).arg( getpwuid( getuid() )->pw_name ).arg( filename );
+ QCString out = contents.join( "\n" ).local8Bit();
+
+ if ( write( file_descriptor, out, out.length() ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_WRITING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ ok = true;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+bool Smb4KFileIO::removeLockFile( const bool error_message )
+{
+ // We already have the name and location of the lock
+ // file, so we do not need to define it here.
+
+ int file_descriptor;
+ bool ok = false;
+
+ // Open the lock file:
+ if ( (file_descriptor = open( m_lock_file, O_RDWR )) == -1 )
+ {
+ // Error out if the opening failed:
+ int error_number = errno;
+
+ if ( error_message && error_number != ENOENT )
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+ else
+ {
+ // Check what we actually opened:
+
+ struct stat file_stat;
+
+ if ( fstat( file_descriptor, &file_stat ) == -1 )
+ {
+ // Error out if we could not get the information about the file:
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ // FIXME for >= 0.8.x: Change error code to ERROR_GETTING_STAT
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, QString::null, strerror( error_number ) );
+ }
+
+ return ok;
+ }
+
+ if ( !S_ISREG( file_stat.st_mode ) || S_ISFIFO( file_stat.st_mode ) || S_ISLNK( file_stat.st_mode ) )
+ {
+ // Close the file and error out, if we have opened an
+ // "irregular" file (i.e. a symlink, a fifo, etc.).
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, m_lock_file );
+ }
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+ }
+
+ return ok; // false
+ }
+ else
+ {
+ // Continue if the file is regular.
+
+ char buffer[1000];
+ ssize_t size;
+
+ if ( (size = read( file_descriptor, buffer, 1000 )) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_READING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ if ( size >= 1000 )
+ {
+ if ( error_message )
+ {
+ // FIXME for >= 0.8.x: Change error code to ERROR_BUFFER_EXCEEDED
+ Smb4KError::error( ERROR_UNKNOWN, QString::null, i18n( "Buffer size exceeded" ) );
+ }
+
+ return ok; // false
+ }
+
+ QStringList contents = QStringList::split( '\n', QString::fromLocal8Bit( buffer, size ), false );
+
+ // Prepare the contents of the file and write it to the disk.
+ // It it should be empty, remove the lock file.
+ for ( QStringList::Iterator it = contents.begin(); it != contents.end(); it++ )
+ {
+ if ( (*it).startsWith( QString( getpwuid( getuid() )->pw_name )+":" ) )
+ {
+ *it = QString::null;
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ contents.remove( QString::null );
+
+ if ( !contents.isEmpty() )
+ {
+ // Write the remaining contents to the lock file:
+
+ QCString out = contents.join( "\n" ).local8Bit();
+
+ if ( write( file_descriptor, out, out.length() ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ ok = true;
+ }
+ else
+ {
+ // Close and remove the lock file:
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ if ( unlink( m_lock_file ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ // FIXME for > 0.8.x: Replace error code with ERROR_REMOVING_FILE
+ Smb4KError::error( ERROR_UNKNOWN, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ ok = true;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+const QCString Smb4KFileIO::findFile( const QString &filename )
+{
+ QStringList paths;
+ paths << "/etc";
+ paths << "/etc/samba";
+ paths << "/usr/local/etc";
+ paths << "/usr/local/etc/samba";
+
+ QString canonical_path = QString::null;
+
+ for ( QStringList::ConstIterator it = paths.begin(); it != paths.end(); it++ )
+ {
+ QDir::setCurrent( *it );
+
+ if ( QFile::exists( filename ) )
+ {
+ canonical_path = QDir::current().canonicalPath()+"/"+filename;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return canonical_path.local8Bit();
+}
+
+
+void Smb4KFileIO::processSudoers()
+{
+ // If the output buffer is empty, we stop, because
+ // that most likely means, the user cancelled the
+ // kdesu dialog.
+ if ( m_buffer.stripWhiteSpace().isEmpty() )
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ QStringList contents = QStringList::split( "\n", m_buffer, true );
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+
+ QString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( "User_Alias\tSMB4KUSERS = "+QString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+ contents.append( "Defaults:SMB4KUSERS\tenv_keep += \"PASSWD USER\"" );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_kill() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_umount() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_mount() );
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+QString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) )
+ {
+ QString users = (*it).section( "=", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( QString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ QStringList list = QStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+ }
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ QStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Create a temporary file and write the data to it:
+ QCString template_string = tempDir().local8Bit()+"/XXXXXX";
+ char tmp[template_string.length()+1];
+ (void) qstrncpy( tmp, template_string, template_string.length()+1 );
+
+ QFile temp_file;
+ int file_descriptor;
+
+ if ( (file_descriptor = mkstemp( tmp )) == -1 )
+ {
+ int err = errno;
+
+ Smb4KError::error( ERROR_CREATING_TEMP_FILE, tmp, strerror( err ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ if ( temp_file.open( IO_WriteOnly, file_descriptor ) )
+ {
+ QTextStream ts( &temp_file );
+ ts.setEncoding( QTextStream::Locale );
+
+ ts << contents.join( "\n" ) << endl;
+
+ temp_file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, temp_file.name() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ // Now move the file to the right location. Preserve the permissions
+ // and the owner:
+ QString canonical_path = findFile( "sudoers" );
+ struct stat file_stat;
+
+ if ( stat( canonical_path.local8Bit(), &file_stat ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ QString perms = QString( "%1" ).arg( (int)file_stat.st_mode, 0, 8 );
+ perms = perms.right( 4 );
+ QString owner = QString( "%1" ).arg( (int)file_stat.st_uid );
+ QString group = QString( "%1" ).arg( (int)file_stat.st_gid );
+ QString temp_file_name = QString( tmp );
+
+ // Assemble the command.
+ QString command;
+ command.append( "kdesu -n -c \"smb4k_mv "+owner+":"+group+" "+perms+" " );
+ command.append( temp_file_name+" " );
+ command.append( canonical_path+"\" ; " );
+ command.append( "rm -f "+temp_file_name );
+
+ m_state = WriteSudoers;
+
+ *m_proc << command;
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+ }
+ else
+ {
+ // Everything OK.
+ emit finished();
+
+ removeLockFile();
+ }
+}
+
+
+void Smb4KFileIO::processSuperTab()
+{
+ // If the output buffer is empty, we stop, because
+ // that most likely means, the user cancelled the
+ // kdesu dialog.
+ if ( m_buffer.stripWhiteSpace().isEmpty() )
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ QStringList contents = QStringList::split( "\n", m_buffer, true );
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+
+ QString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( ":define Smb4KUsers "+QString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+#ifndef __FreeBSD__
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root\tenv=PASSWD,USER" );
+#else
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel\tsetenv=HOME=$CALLER_HOME\tenv=PASSWD,USER" );
+#endif
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+QString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ QStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ QStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( QStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) )
+ {
+ QString users = (*it).section( "Smb4KUsers", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( QString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ QStringList list = QStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+ }
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ QStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Create a temporary file and write the data to it:
+ QCString template_string = tempDir().local8Bit()+"/XXXXXX";
+ char tmp[template_string.length()+1];
+ (void) qstrncpy( tmp, template_string, template_string.length()+1 );
+
+ QFile temp_file;
+ int file_descriptor;
+
+ if ( (file_descriptor = mkstemp( tmp )) == -1 )
+ {
+ int err = errno;
+
+ Smb4KError::error( ERROR_CREATING_TEMP_FILE, tmp, strerror( err ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ if ( temp_file.open( IO_WriteOnly, file_descriptor ) )
+ {
+ QTextStream ts( &temp_file );
+ ts.setEncoding( QTextStream::Locale );
+
+ ts << contents.join( "\n" ) << endl;
+
+ temp_file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, temp_file.name() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ // Now move the file to the right location. Preserve the permissions
+ // and the owner:
+ QString canonical_path = findFile( "super.tab" );
+ struct stat file_stat;
+
+ if ( stat( canonical_path.local8Bit(), &file_stat ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, QString::null, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ QString perms = QString( "%1" ).arg( (int)file_stat.st_mode, 0, 8 );
+ perms = perms.right( 4 );
+ QString owner = QString( "%1" ).arg( (int)file_stat.st_uid );
+ QString group = QString( "%1" ).arg( (int)file_stat.st_gid );
+ QString temp_file_name = QString( tmp );
+
+ // Assemble the command.
+ QString command;
+ command.append( "kdesu -n -c \"smb4k_mv "+owner+":"+group+" "+perms+" " );
+ command.append( temp_file_name+" " );
+ command.append( canonical_path+"\" ; " );
+ command.append( "rm -f "+temp_file_name );
+
+ m_state = WriteSuperTab;
+
+ *m_proc << command;
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+ }
+ else
+ {
+ // Everything OK.
+ emit finished();
+
+ removeLockFile();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KFileIO::slotShutdown()
+{
+ removeLockFile( false );
+}
+
+
+void Smb4KFileIO::slotReceivedStderr( KProcess *, char *buf, int len )
+{
+ QString error_output = QString::fromLocal8Bit( buf, len );
+
+ if ( error_output.contains( "smb4k_mv" ) != 0 )
+ {
+ m_error_occurred = true;
+
+ QString canonical_path = findFile( (m_state == WriteSudoers ? "sudoers" : "super.tab") );
+
+ Smb4KError::error( ERROR_WRITING_FILE, canonical_path, m_buffer );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+ else if ( error_output.contains( "smb4k_cat" ) != 0 )
+ {
+ m_error_occurred = true;
+
+ QString canonical_path = findFile( (m_state == ReadSudoers ? "sudoers" : "super.tab") );
+
+ Smb4KError::error( ERROR_READING_FILE, canonical_path, m_buffer );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+}
+
+
+void Smb4KFileIO::slotReceivedStdout( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KFileIO::slotProcessExited( KProcess * )
+{
+ m_proc->clearArguments();
+
+ if ( !m_error_occurred )
+ {
+ switch ( m_state )
+ {
+ case ReadSudoers:
+ {
+ processSudoers();
+
+ break;
+ }
+ case WriteSudoers:
+ {
+ emit finished();
+
+ removeLockFile();
+
+ break;
+ }
+ case ReadSuperTab:
+ {
+ processSuperTab();
+
+ break;
+ }
+ default:
+ {
+ emit finished();
+
+ removeLockFile();
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Smb4KFileIO::slotReceivedStderr() has already done the
+ // necessary things.
+ }
+
+ m_buffer = QString::null;
+ m_state = Idle;
+ m_error_occurred = false;
+}
+
+#include "smb4kfileio.moc"
diff --git a/smb4k/core/smb4kfileio.h b/smb4k/core/smb4kfileio.h
new file mode 100644
index 0000000..bbfbbe0
--- /dev/null
+++ b/smb4k/core/smb4kfileio.h
@@ -0,0 +1,246 @@
+/***************************************************************************
+ smb4kfileio - Does file IO operations for Smb4K
+ -------------------
+ begin : Do Jan 1 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KFILEIO_H
+#define SMB4KFILEIO_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qstring.h>
+#include <qcstring.h>
+
+// KDE include
+#include <kprocess.h>
+
+
+/**
+ * This class belongs to the core classes of Smb4K. It handles IO
+ * operations that are performed on system configuration files.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KFileIO : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent object of this class
+ *
+ * @param name The name of this class
+ */
+ Smb4KFileIO( QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KFileIO();
+
+ /**
+ * Enumeration that determines for which super user program we perform
+ * the current action.
+ */
+ enum Operation { Insert, Remove, NoOperation };
+
+ /**
+ * This function writes changes to the sudoers configuration file.
+ *
+ * @param operation Defines whether entries should be inserted or if
+ * they should be removed. With Smb4KFileIO::NoOperation
+ * the function exits immediately and returns TRUE.
+ *
+ * @returns TRUE if the write process was successfully initiate and FALSE
+ * otherwise.
+ *
+ * @note You need to connect to the finished() and failed() signals to find
+ * out if the the write process finished successfully.
+ *
+ */
+ bool writeSudoers( Smb4KFileIO::Operation operation );
+
+ /**
+ * This function writes changes to the super.tab configuration file.
+ *
+ * @param operation Defines whether entries should be inserted or if
+ * they should be removed. With Smb4KFileIO::NoOperation
+ * the function exits immediately and returns TRUE.
+ *
+ * @returns TRUE if the write process was successfully initiate and FALSE
+ * otherwise.
+ *
+ * @note You need to connect to the finished() and failed() signals to find
+ * out if the the write process finished successfully.
+ *
+ */
+ bool writeSuperTab( Smb4KFileIO::Operation operation );
+
+ signals:
+ /**
+ * This signal is emitted when somthing went wrong with the writing to
+ * the system configuration files.
+ */
+ void failed();
+
+ /**
+ * This signal is emitted when the writing to the system configuration
+ * files has finished. It is emitted in case the writing was successful
+ * as well as in case it wasn't.
+ */
+ void finished();
+
+ protected slots:
+ /**
+ * This slot is invokes when the application is closed. It is connected
+ * to KApplication::shutDown().
+ */
+ void slotShutdown();
+
+ /**
+ * This slot receives shell program output from Stderr.
+ *
+ * @param proc The KProcess object
+ *
+ * @param buf The buffer that holds the error output
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStderr( KProcess *proc, char *buf, int len );
+
+ /**
+ * This slot receives shell program output from Stdout.
+ *
+ * @param proc The KProcess object
+ *
+ * @param buf The buffer that holds the output
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStdout( KProcess *proc, char *buf, int len );
+
+ /**
+ * This slot is called, when the process exited.
+ *
+ * @param proc The KProcess object
+ */
+ void slotProcessExited( KProcess *proc );
+
+ private:
+ /**
+ * This function creates a lock file in /tmp if it does not
+ * exist already. If the user is not allowed to write to the
+ * desired file a the moment, the user will be shown an error
+ * dialog and the function will return FALSE.
+ *
+ * Checks are performed to make sure it is save to write to an
+ * existing lock file using the system call lstat().
+ *
+ * @param filename The name of the file that is to be modified.
+ *
+ * @returns TRUE if the creation was successful and FALSE if
+ * something went wrong.
+ */
+ bool createLockFile( const QString &filename );
+
+ /**
+ * This function removes the lock file or at least the
+ * entry within it.
+ *
+ * Checks are performed to make sure it is save to write to an
+ * existing lock file using the system call lstat().
+ *
+ * @param shutdown Should be set to FALSE if you do not want to have
+ * any error message shown. Otherwise you should set it
+ * to TRUE.
+ *
+ * @returns TRUE if the removal was successful and FALSE if
+ * something went wrong.
+ */
+ bool removeLockFile( const bool error_message = true );
+
+ /**
+ * This function finds a file.
+ *
+ * @param filename The name of the file
+ *
+ * @returns the canonical path of the file or an empty string if it could not be
+ * found.
+ */
+ const QCString findFile( const QString &filename );
+
+ /**
+ * Enumeration that is used to tell the process what has to be done.
+ */
+ enum State { ReadSudoers, ReadSuperTab, WriteSudoers, WriteSuperTab, Idle };
+
+ /**
+ * This integer holds one of the entries of the enumeration above.
+ */
+ State m_state;
+
+ /**
+ * This buffer holds the output that was received at Stdout.
+ */
+ QString m_buffer;
+
+ /**
+ * Process the sudoers file.
+ */
+ void processSudoers();
+
+ /**
+ * Process the sudoers file.
+ */
+ void processSuperTab();
+
+ /**
+ * This is the absolute path of the lock file.
+ */
+ QCString m_lock_file;
+
+ /**
+ * Which operation should be performed
+ */
+ Operation m_operation;
+
+ /**
+ * The KProcess object
+ */
+ KProcess *m_proc;
+
+ /**
+ * Tell if an error occurred.
+ */
+ bool m_error_occurred;
+};
+
+
+#endif
diff --git a/smb4k/core/smb4kglobal.cpp b/smb4k/core/smb4kglobal.cpp
new file mode 100644
index 0000000..c1fe706
--- /dev/null
+++ b/smb4k/core/smb4kglobal.cpp
@@ -0,0 +1,78 @@
+/***************************************************************************
+ smb4kglobal - This is the global namespace for Smb4K.
+ -------------------
+ begin : Sa Apr 2 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <kconfig.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kglobal.h"
+#include "smb4kglobal_p.h"
+#include "smb4kdefs.h"
+
+
+static Smb4KGlobalPrivate p;
+
+
+QTimer *Smb4KGlobal::timer()
+{
+ return p.timer();
+}
+
+
+const int Smb4KGlobal::timerInterval()
+{
+ return TIMER_INTERVAL;
+}
+
+
+const QString Smb4KGlobal::specifyUser( const QString &host, QWidget *parent, const char *name )
+{
+ return p.homesHandler()->specifyUser( host, parent, name );
+}
+
+
+Smb4KPasswordHandler *Smb4KGlobal::passwordHandler()
+{
+ return p.passwordHandler();
+}
+
+
+Smb4KSambaOptionsHandler *Smb4KGlobal::optionsHandler()
+{
+ return p.optionsHandler();
+}
+
+
+const QString &Smb4KGlobal::tempDir()
+{
+ return p.tempDir();
+}
+
+
+const QStringList Smb4KGlobal::homesUsers( const QString &host )
+{
+ return p.homesUsers( host );
+}
diff --git a/smb4k/core/smb4kglobal.h b/smb4k/core/smb4kglobal.h
new file mode 100644
index 0000000..815938f
--- /dev/null
+++ b/smb4k/core/smb4kglobal.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ smb4kglobal - This is the global namespace for Smb4K.
+ -------------------
+ begin : Sa Apr 2 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KGLOBAL_H
+#define SMB4KGLOBAL_H
+
+#include <qstring.h>
+#include <qtimer.h>
+
+#include <kconfig.h>
+
+// forward declarations:
+class Smb4KPasswordHandler;
+class Smb4KSambaOptionsHandler;
+class Smb4KHomesSharesHandler;
+
+/**
+ * This is the global namespace for the core classes of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+namespace Smb4KGlobal
+{
+ /**
+ * This returns the pointer to the global timer for the application.
+ * WARNING: Du *NOT* stop this timer anywhere in the program or all
+ * actions that need a timer are stopped all over the application!
+ *
+ * @returns A pointer to the global timer.
+ */
+ QTimer *timer() KDE_DEPRECATED;
+
+ /**
+ * This function returns the interval of the timer.
+ *
+ * @returns The interval of the timer in msec.
+ */
+ const int timerInterval();
+
+ /**
+ * This function will open a dialog where the user has to define a
+ * user name to access a 'homes' share. Besides returning this name,
+ * this function will also store the name in the configuration file.
+ *
+ * @param host The host where the homes share is located
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this dialog
+ *
+ * @returns A user name
+ */
+ const QString specifyUser( const QString &host, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * This function returns the password handler.
+ *
+ * @returns a pointer to the global password handler object.
+ */
+ Smb4KPasswordHandler *passwordHandler();
+
+ /**
+ * This function returns a pointer to the global Smb4KOptionsHandler object.
+ * You need to use it if you want to retrieve (a) the custom options defined for
+ * a share, (b) the argument strings for the 'net', 'smbclient', or 'nmblookup'
+ * command, or (c) the options in the global section of the smb.conf configuration
+ * file.
+ *
+ * @returns a pointer to the global options handler object.
+ */
+ Smb4KSambaOptionsHandler *optionsHandler();
+
+ /**
+ * This function creates a temporary directory and returns its name. If it already
+ * exists, only the name will be returned. If an failure occurrs, an error message
+ * will be shown and an empty string is returned.
+ *
+ * @returns the name of the temporary directory.
+ */
+ const QString &tempDir();
+
+ /**
+ * Get the user names that are defined for a homes share.
+ *
+ * @param host The name of the host where the 'homes' share is located.
+ *
+ * @returns the list of user names for this homes share.
+ */
+ const QStringList homesUsers( const QString &host );
+};
+
+#endif
diff --git a/smb4k/core/smb4kglobal_p.cpp b/smb4k/core/smb4kglobal_p.cpp
new file mode 100644
index 0000000..f5da58f
--- /dev/null
+++ b/smb4k/core/smb4kglobal_p.cpp
@@ -0,0 +1,123 @@
+/***************************************************************************
+ smb4kglobal_p - This is the private helper class of the Smb4KGlobal
+ namespace.
+ -------------------
+ begin : Di Jul 24 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// system includes
+#include <errno.h>
+#include <stdlib.h>
+
+// application specific includes
+#include "smb4kglobal_p.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+
+
+Smb4KGlobalPrivate::Smb4KGlobalPrivate()
+{
+ m_timer = new QTimer();
+ m_timer->start( TIMER_INTERVAL, false );
+
+ // Do NOT initialize these classes here; you'll
+ // get crashes.
+ m_passwd_handler = NULL;
+ m_options_handler = NULL;
+ m_homes_handler = NULL;
+
+ m_temp_dir = QString::null;
+}
+
+
+Smb4KGlobalPrivate::~Smb4KGlobalPrivate()
+{
+ rmdir( m_temp_dir.local8Bit() );
+
+ delete m_timer;
+ delete m_passwd_handler;
+ delete m_options_handler;
+ delete m_homes_handler;
+}
+
+
+QTimer *Smb4KGlobalPrivate::timer()
+{
+ return m_timer;
+}
+
+
+Smb4KHomesSharesHandler *Smb4KGlobalPrivate::homesHandler()
+{
+ return m_homes_handler ? m_homes_handler :
+ (m_homes_handler = new Smb4KHomesSharesHandler());
+}
+
+
+Smb4KPasswordHandler *Smb4KGlobalPrivate::passwordHandler()
+{
+#ifndef __FreeBSD__
+ return m_passwd_handler ? m_passwd_handler :
+ (m_passwd_handler = new Smb4KPasswordHandler( homesHandler() ));
+#else
+ return m_passwd_handler ? m_passwd_handler :
+ (m_passwd_handler = new Smb4KPasswordHandler( homesHandler(), optionsHandler() ));
+#endif
+}
+
+
+Smb4KSambaOptionsHandler *Smb4KGlobalPrivate::optionsHandler()
+{
+ return m_options_handler ? m_options_handler :
+ (m_options_handler = new Smb4KSambaOptionsHandler());
+}
+
+
+const QString &Smb4KGlobalPrivate::tempDir()
+{
+ if ( m_temp_dir.isEmpty() )
+ {
+ char tmpd_name[] = "/tmp/smb4k.XXXXXX";
+
+ if ( mkdtemp( tmpd_name ) == NULL )
+ {
+ Smb4KError::error( ERROR_CREATING_TEMP_DIR, tmpd_name, strerror( errno ) );
+
+ return QString::null;
+ }
+
+ m_temp_dir = QString( tmpd_name );
+ }
+
+ return m_temp_dir;
+}
+
+
+const QStringList Smb4KGlobalPrivate::homesUsers( const QString &host )
+{
+ if ( !m_homes_handler )
+ {
+ m_homes_handler = new Smb4KHomesSharesHandler();
+ }
+
+ return m_homes_handler->homesUsers( host );
+}
diff --git a/smb4k/core/smb4kglobal_p.h b/smb4k/core/smb4kglobal_p.h
new file mode 100644
index 0000000..e1bad0a
--- /dev/null
+++ b/smb4k/core/smb4kglobal_p.h
@@ -0,0 +1,102 @@
+/***************************************************************************
+ smb4kglobal_p - This is the private helper class of the Smb4KGlobal
+ namespace.
+ -------------------
+ begin : Di Jul 24 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KGLOBAL_P_H
+#define SMB4KGLOBAL_P_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qtimer.h>
+
+// KDE includes
+#include <kconfig.h>
+
+// application specific includes
+#include "smb4kpasswordhandler.h"
+#include "smb4ksambaoptionshandler.h"
+#include "smb4khomesshareshandler.h"
+
+/**
+ * This class is a private helper for the Smb4KGlobal namespace.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KGlobalPrivate
+{
+ public:
+ /**
+ * Constructor
+ */
+ Smb4KGlobalPrivate();
+
+ /**
+ * Destructor
+ */
+ ~Smb4KGlobalPrivate();
+
+ /**
+ * Returns a pointer to the global timer
+ */
+ QTimer *timer();
+
+ /**
+ * Returns the handler for homes shares
+ */
+ Smb4KHomesSharesHandler *homesHandler();
+
+ /**
+ * Returns a pointer to the global password handler object
+ */
+ Smb4KPasswordHandler *passwordHandler();
+
+ /**
+ * Returns a pointer to the global Samba options handler
+ */
+ Smb4KSambaOptionsHandler *optionsHandler();
+
+ /**
+ * Returns the name of the temporary directory.
+ */
+ const QString &tempDir();
+
+ /**
+ * Return the user names defined for a certain homes share
+ */
+ const QStringList homesUsers( const QString &host );
+
+ private:
+ QTimer *m_timer;
+ Smb4KPasswordHandler *m_passwd_handler;
+ Smb4KSambaOptionsHandler *m_options_handler;
+ Smb4KHomesSharesHandler *m_homes_handler;
+ QString m_temp_dir;
+};
+
+#endif
diff --git a/smb4k/core/smb4khomesshareshandler.cpp b/smb4k/core/smb4khomesshareshandler.cpp
new file mode 100644
index 0000000..a81a6e7
--- /dev/null
+++ b/smb4k/core/smb4khomesshareshandler.cpp
@@ -0,0 +1,361 @@
+/***************************************************************************
+ smb4khomesshareshandler - This class handles the homes shares.
+ -------------------
+ begin : Do Aug 10 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qmap.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qfile.h>
+
+// KDE includes
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kcombobox.h>
+
+// application specific includes
+#include "smb4khomesshareshandler.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+
+
+Smb4KHomesSharesHandler::Smb4KHomesSharesHandler( QObject *parent, const char *name )
+: QObject( parent, name )
+{
+ // First we need the directory.
+ KStandardDirs *stddir = new KStandardDirs();
+ QString dir = locateLocal( "data", "smb4k", KGlobal::instance() );
+
+ if ( !stddir->exists( dir ) )
+ {
+ stddir->makeDir( dir );
+ }
+
+ delete stddir;
+
+ m_dlg = NULL;
+}
+
+
+Smb4KHomesSharesHandler::~Smb4KHomesSharesHandler()
+{
+ delete m_dlg;
+}
+
+
+const QString Smb4KHomesSharesHandler::specifyUser( const QString &host, QWidget *parent, const char *name )
+{
+ QString username = QString::null;
+
+ m_dlg = new KDialogBase( KDialogBase::Plain, i18n( "Specify User" ), KDialogBase::User1|KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, parent, name, true, true );
+ m_dlg->setButtonGuiItem( KDialogBase::User1, KGuiItem( i18n( "Clear List" ), "editdelete", 0, 0 ) );
+ m_dlg->enableButton( KDialogBase::Ok, false );
+ m_dlg->enableButton( KDialogBase::User1, false );
+
+ // Set up the ask pass dialog.
+ QFrame *frame = m_dlg->plainPage();
+ QGridLayout *layout = new QGridLayout( frame );
+ layout->setSpacing( 5 );
+
+ QLabel *pic = new QLabel( frame );
+ pic->setPixmap( DesktopIcon( "personal" ) );
+ pic->setMargin( 10 );
+
+ QLabel *text = new QLabel( i18n( "Please specify a user name." ), frame );
+
+ QLabel *userLabel = new QLabel( i18n( "User:" ), frame );
+ KComboBox *userCombo = new KComboBox( true, frame, "UserComboBox" );
+ userCombo->setDuplicatesEnabled( false );
+
+ QSpacerItem *spacer1 = new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Preferred );
+
+ layout->addWidget( pic, 0, 0, 0 );
+ layout->addMultiCellWidget( text, 0, 0, 1, 3, 0 );
+ layout->addWidget( userLabel, 1, 0, 0 );
+ layout->addMultiCellWidget( userCombo, 1, 1, 1, 4, 0 );
+ layout->addItem( spacer1, 0, 2 );
+
+ connect( userCombo, SIGNAL( textChanged( const QString &) ),
+ this, SLOT( slotTextChanged( const QString & ) ) );
+ connect( m_dlg, SIGNAL( user1Clicked() ),
+ this, SLOT( slotClearClicked() ) );
+
+ // Read the list of logins, that are already defined
+ // for this 'homes' share.
+ QStringList list = read_names( host );
+
+ if ( !list.isEmpty() )
+ {
+ userCombo->insertStringList( list, -1 );
+ m_dlg->enableButton( KDialogBase::User1, true );
+ }
+
+ userCombo->setCurrentText( QString::null );
+
+ // Do the last things before showing.
+ userCombo->setFocus();
+ m_dlg->setFixedSize( m_dlg->sizeHint() );
+
+ if ( m_dlg->exec() == KDialogBase::Accepted )
+ {
+ // First make sure, the list is cleared:
+ list.clear();
+
+ // Write the new list of logins to the config file.
+ if ( !userCombo->lineEdit()->text().isEmpty() )
+ {
+ list.append( userCombo->lineEdit()->text() );
+ }
+
+ int index = 0;
+
+ while ( index < userCombo->count() )
+ {
+ if ( list.find( userCombo->text( index ) ) == list.end() )
+ {
+ list.append( userCombo->text( index ) );
+ }
+
+ index++;
+ }
+
+ list.sort();
+
+ write_names( host, list );
+
+ username = userCombo->currentText();
+ }
+
+ delete m_dlg;
+ m_dlg = NULL;
+
+ return username;
+}
+
+
+const QStringList &Smb4KHomesSharesHandler::read_names( const QString &host )
+{
+ // Clear the old contents of this list:
+ m_names.clear();
+
+ QFile file( locateLocal( "data", "smb4k/homes_shares", KGlobal::instance() ) );
+
+ if ( file.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ QString line;
+ bool get_names = false;
+
+ while ( !ts.atEnd() )
+ {
+ line = ts.readLine();
+
+ if ( !get_names )
+ {
+ if ( QString::compare( line.stripWhiteSpace(), "["+host.upper()+"]" ) == 0 )
+ {
+ // Found the host:
+ get_names = true;
+
+ continue;
+ }
+ else
+ {
+ // No match yet...
+ continue;
+ }
+ }
+ else
+ {
+ if ( !line.stripWhiteSpace().isEmpty() )
+ {
+ // Write the names to the list:
+ m_names = QStringList::split( ",", line, false );
+
+ // This is not needed, but let's do it anyway:
+ get_names = false;
+
+ break;
+ }
+ }
+ }
+
+ file.close();
+ }
+ else
+ {
+ if ( file.exists() )
+ {
+ Smb4KError::error( ERROR_READING_FILE, file.name() );
+
+ // The list is empty:
+ return m_names;
+ }
+ }
+
+ return m_names;
+}
+
+
+void Smb4KHomesSharesHandler::write_names( const QString &host, const QStringList &names )
+{
+ // First get the whole contents of the file, so that
+ // we can easily modify it:
+ QStringList contents;
+
+ QFile file( locateLocal( "data", "smb4k/homes_shares", KGlobal::instance() ) );
+
+ if ( file.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( '\n', ts.read(), true );
+
+ file.close();
+ }
+ else
+ {
+ if ( file.exists() )
+ {
+ Smb4KError::error( ERROR_READING_FILE, file.name() );
+
+ return;
+ }
+ }
+
+ // Now search for the host:
+ QStringList::Iterator it;
+
+ for ( it = contents.begin(); it != contents.end(); ++it )
+ {
+ if ( QString::compare( (*it).stripWhiteSpace().upper(), "["+host.upper()+"]" ) == 0 )
+ {
+ if ( !names.isEmpty() )
+ {
+ // Move to the line with the names:
+ it++;
+ // Change the line:
+ *it = names.join( "," );
+ }
+ else
+ {
+ // Remove the host entry:
+ it = contents.remove( it );
+ // Remove the user names:
+ it = contents.remove( it );
+
+ // Remove the blank line following the entry:
+ if ( it != contents.end() && (*it).stripWhiteSpace().isEmpty() )
+ {
+ contents.remove( it );
+ }
+ }
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ // If we haven't found the host, append it to the end:
+ if ( it == contents.end() )
+ {
+ if ( !contents.isEmpty() )
+ {
+ contents.append( "" );
+ }
+
+ contents.append( "["+host.upper()+"]");
+ contents.append( names.join( "," ) );
+ }
+
+
+ // Now write or remove the file:
+ if ( !contents.isEmpty() )
+ {
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ ts << contents.join( "\n" );
+
+ file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, file.name() );
+
+ return;
+ }
+ }
+ else
+ {
+ file.remove();
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KHomesSharesHandler::slotTextChanged( const QString &text )
+{
+ if ( !text.isEmpty() )
+ {
+ m_dlg->enableButtonOK( true );
+ }
+ else
+ {
+ m_dlg->enableButtonOK( false );
+ }
+}
+
+
+void Smb4KHomesSharesHandler::slotClearClicked()
+{
+ if ( m_dlg )
+ {
+ KComboBox *cb = (KComboBox *)m_dlg->child( "UserComboBox", "KComboBox", true );
+
+ if ( cb )
+ {
+ cb->clearEdit();
+ cb->clear();
+
+ m_dlg->enableButton( KDialogBase::User1, false );
+ }
+ }
+}
+
+#include "smb4khomesshareshandler.moc"
+
diff --git a/smb4k/core/smb4khomesshareshandler.h b/smb4k/core/smb4khomesshareshandler.h
new file mode 100644
index 0000000..cf501e2
--- /dev/null
+++ b/smb4k/core/smb4khomesshareshandler.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+ smb4khomesshareshandler - This class handles the homes shares.
+ -------------------
+ begin : Do Aug 10 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KHOMESSHARESHANDLER_H
+#define SMB4KHOMESSHARESHANDLER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+
+// KDE includes
+#include <kdialogbase.h>
+#include <kconfig.h>
+
+
+/**
+ * This class belongs to the core of Smb4K and takes care of the
+ * user names that are/were defined for a certain 'homes' share.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KHomesSharesHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent object of this class
+ *
+ * @param name The name of this class
+ */
+ Smb4KHomesSharesHandler( QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KHomesSharesHandler();
+
+ /**
+ * This function will open a dialog where the user has to define a
+ * user name to access a 'homes' share. Besides returning this name,
+ * this function will also store the name in the configuration file.
+ *
+ * @param host The host where the homes share is located
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this dialog
+ *
+ * @returns A user name
+ */
+ const QString specifyUser( const QString &host, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * Read and return the user names that are defined for a homes share.
+ *
+ * @param host The name of the host where the 'homes' share is located.
+ *
+ * @returns the list of user names for this homes share.
+ */
+ const QStringList &homesUsers( const QString &host ) { return read_names( host ); }
+
+ protected slots:
+ /**
+ * Is connected to the textChanged() signal of the combo box
+ * in the "Specify User" dialog.
+ *
+ * @param text The text in the combo box
+ */
+ void slotTextChanged( const QString &text );
+
+ /**
+ * This slot is called if the User1 button, i.e. the "Clear" button
+ * in the "Specify User" dialog has been clicked. It removes all
+ * entries from the combo box.
+ */
+ void slotClearClicked();
+
+ private:
+ /**
+ * Read the user names for a homes share.
+ *
+ * @param host The host where the homes share is located.
+ */
+ const QStringList &read_names( const QString &host );
+
+ /**
+ * Write the user names for a certain homes share to the config
+ * file.
+ *
+ * @param host The host where the homes share is located
+ *
+ * @param names The list of user names that are defined for
+ * the homes share and should be written to the
+ * config file.
+ */
+ void write_names( const QString &host, const QStringList &names );
+
+ /**
+ * This is the dialog that's shown the user when he/she has to
+ * provide a user name.
+ */
+ KDialogBase *m_dlg;
+
+ /**
+ * This is a buffer for the list of names defined for a 'homes' share.
+ */
+ QStringList m_names;
+};
+
+#endif
diff --git a/smb4k/core/smb4kmounter.cpp b/smb4k/core/smb4kmounter.cpp
new file mode 100644
index 0000000..45ccc9c
--- /dev/null
+++ b/smb4k/core/smb4kmounter.cpp
@@ -0,0 +1,1718 @@
+/***************************************************************************
+ smb4kmounter.cpp - The core class that mounts the shares.
+ -------------------
+ begin : Die Jun 10 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qapplication.h>
+#include <qdir.h>
+#include <qtextstream.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+// KDE includes
+#include <kapplication.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+// system includes
+#if !defined(__FreeBSD__) && !defined(__solaris__) && !defined(USE_SOLARIS)
+#include <sys/statfs.h>
+#elif defined(__solaris__) || defined(USE_SOLARIS)
+#include <sys/statvfs.h>
+#elif defined(__FreeBSD__)
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif
+#include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dirent.h>
+
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <qfileinfo.h>
+#endif
+
+// Application specific includes
+#include "smb4kmounter.h"
+#include "smb4kmounter_p.h"
+#include "smb4kauthinfo.h"
+#include "smb4ksambaoptionsinfo.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4ksambaoptionshandler.h"
+#include "smb4kpasswordhandler.h"
+#include "smb4kshare.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KMounter::Smb4KMounter( QObject *parent, const char *name ) : QObject( parent, name )
+{
+ m_priv = new Smb4KMounterPrivate;
+
+ m_proc = new KProcess( this, "MounterProcess" );
+ m_proc->setUseShell( true );
+
+ m_working = false;
+
+ m_queue.setAutoDelete( true );
+
+ connect( m_proc, SIGNAL( processExited( KProcess * ) ),
+ this, SLOT( slotProcessExited( KProcess * ) ) );
+
+ connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
+
+ connect( kapp, SIGNAL( shutDown() ),
+ this, SLOT( slotShutdown() ) );
+}
+
+
+Smb4KMounter::~Smb4KMounter()
+{
+ abort();
+
+ for ( QValueList<Smb4KShare *>::Iterator it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_mounted_shares.clear();
+
+ delete m_priv;
+}
+
+
+void Smb4KMounter::init()
+{
+ m_queue.enqueue( new QString( QString( "%1:" ).arg( Import ) ) );
+ m_queue.enqueue( new QString( QString( "%1:" ).arg( Remount ) ) );
+
+ startTimer( TIMER_INTERVAL );
+}
+
+
+/***************************************************************************
+ Aborts any action of the mounter.
+***************************************************************************/
+
+
+void Smb4KMounter::abort()
+{
+ m_queue.clear();
+
+ if ( m_proc->isRunning() )
+ {
+ if ( Smb4KSettings::alwaysUseSuperUser() )
+ {
+ QString suid_program;
+
+ switch( Smb4KSettings::superUserProgram() )
+ {
+ case Smb4KSettings::EnumSuperUserProgram::Sudo:
+ {
+ suid_program = Smb4KSettings::sudo();
+
+ break;
+ }
+ case Smb4KSettings::EnumSuperUserProgram::Super:
+ {
+ suid_program = Smb4KSettings::super();
+
+ break;
+ }
+ default:
+ {
+ // FIXME: Throw an error?
+ return;
+ }
+ }
+
+ KProcess proc;
+ proc.setUseShell( true );
+ proc << QString( "%1 smb4k_kill %2" ).arg( suid_program ).arg( m_proc->pid() );
+ proc.start( KProcess::DontCare, KProcess::NoCommunication );
+ }
+ else
+ {
+ m_proc->kill();
+ }
+ }
+}
+
+
+/***************************************************************************
+ Mounts recently used shares.
+***************************************************************************/
+
+
+void Smb4KMounter::remount()
+{
+ if ( Smb4KSettings::remountShares() )
+ {
+ const QValueList<Smb4KSambaOptionsInfo *> *list = &(optionsHandler()->customOptionsList());
+
+ for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = list->begin();
+ it != list->end(); ++it )
+ {
+ if ( (*it)->remount() )
+ {
+ QValueList<Smb4KShare> list = findShareByName( (*it)->itemName() );
+
+ bool mount = true;
+
+ if ( !list.isEmpty() )
+ {
+ for ( QValueList<Smb4KShare>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it).isForeign() )
+ {
+ mount = false;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ if ( mount )
+ {
+#ifndef __FreeBSD__
+ mountShare( QString::null, (*it)->itemName().section( "/", 2, 2 ), QString::null, (*it)->itemName().section( "/", 3, 3 ) );
+#else
+ mountShare( QString::null, (*it)->itemName().section( "/", 2, 2 ).section( "@", 1, 1 ), QString::null, (*it)->itemName().section( "/", 3, 3 ) );
+#endif
+ }
+
+ // If the share is to be remounted the next time,
+ // slotShutdown() will tell the options handler.
+ (*it)->setRemount( false );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ m_working = false;
+ emit state( MOUNTER_STOP );
+ }
+ else
+ {
+ m_working = false;
+ emit state( MOUNTER_STOP );
+ }
+}
+
+
+/***************************************************************************
+ Imports all shares, that are mounted externally.
+***************************************************************************/
+
+void Smb4KMounter::import()
+{
+ QValueList<Smb4KShare *> shares;
+
+#ifndef __FreeBSD__
+
+ if ( m_proc_mounts.name().isEmpty() )
+ {
+ m_proc_mounts.setName( "/proc/mounts" );
+ }
+
+ if ( !QFile::exists( m_proc_mounts.name() ) )
+ {
+ if ( !m_proc_error )
+ {
+ m_proc_error = true;
+ Smb4KError::error( ERROR_FILE_NOT_FOUND, m_proc_mounts.name() );
+ }
+ else
+ {
+ // No need to do anything here
+ }
+ }
+ else
+ {
+ QStringList contents, list;
+
+ // Read /proc/mounts:
+
+ if ( m_proc_mounts.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &m_proc_mounts );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( "\n", ts.read(), false );
+
+ m_proc_mounts.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, m_proc_mounts.name() );
+
+ return;
+ }
+
+ // Process the SMBFS and CIFS entries:
+
+ list += contents.grep( " smbfs ", true );
+ list += contents.grep( " cifs ", true );
+
+ if ( !list.isEmpty() )
+ {
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); it++ )
+ {
+ Smb4KShare *new_share = NULL;
+
+ if ( (*it).contains( " smbfs ", false ) != 0 )
+ {
+ QString share_and_path = (*it).section( " smbfs ", 0, 0 ).stripWhiteSpace();
+ QString name = share_and_path.section( " ", 0, 0 ).stripWhiteSpace().replace( "\\040", "\040" );
+ QString path = share_and_path.section( " ", 1, 1 ).stripWhiteSpace();
+
+ if ( path.contains( "\\040" ) != 0 || path.contains( "\040" ) != 0 )
+ {
+ name.replace( "_", "\040" );
+ path.replace( "\\040", "\040" );
+ }
+
+ int uid = (*it).section( "uid=", 1, 1 ).section( ",", 0, 0 ).stripWhiteSpace().toInt();
+ int gid = (*it).section( "gid=", 1, 1 ).section( ",", 0, 0 ).stripWhiteSpace().toInt();
+
+ new_share = new Smb4KShare( name, path, "smbfs", uid, gid );
+ }
+ else if ( (*it).contains( " cifs ", false ) != 0 )
+ {
+ QString share_and_path = (*it).section( " cifs ", 0, 0 ).stripWhiteSpace();
+ QString name = share_and_path.section( " ", 0, 0 ).stripWhiteSpace().replace( "\\040", "\040" );
+ QString path = share_and_path.section( " ", 1, 1 ).stripWhiteSpace();
+
+ if ( path.contains( "\\040" ) != 0 || path.contains( "\040" ) != 0 )
+ {
+ name.replace( "_", "\040" );
+ path.replace( "\\040", "\040" );
+ }
+
+ QString login = (*it).section( "username=", 1, 1 ).section( ",", 0, 0 ).stripWhiteSpace();
+
+ new_share = new Smb4KShare( name, path, "cifs", login );
+ }
+ else
+ {
+ continue;
+ }
+
+ if ( new_share )
+ {
+ // If the a representative of the new share is already in the list of
+ // mounted shares, replace the new with the old one.
+
+ Smb4KShare *existing_share = findShareByPath( new_share->path() );
+
+ if ( existing_share )
+ {
+ delete new_share;
+ new_share = new Smb4KShare( *existing_share );
+ }
+
+ // Check if the share is broken and/or foreign.
+
+ if ( (existing_share && !existing_share->isBroken()) || !existing_share )
+ {
+ checkAccessibility( new_share );
+ }
+ else
+ {
+ // Since new_share is a copy of existing_share, we do not need to do
+ // anything here.
+ }
+
+ if ( !existing_share && QString::compare( new_share->filesystem(), "cifs" ) == 0 )
+ {
+ bool foreign = true;
+
+ if ( (!new_share->isBroken() &&
+ (qstrncmp( new_share->canonicalPath(),
+ QDir( Smb4KSettings::mountPrefix() ).canonicalPath(),
+ QDir( Smb4KSettings::mountPrefix() ).canonicalPath().length() ) == 0 ||
+ qstrncmp( new_share->canonicalPath(),
+ QDir::home().canonicalPath(),
+ QDir::home().canonicalPath().length() ) == 0)) ||
+ (new_share->isBroken() &&
+ (qstrncmp( new_share->path(),
+ QDir::homeDirPath(),
+ QDir::homeDirPath().length() ) == 0 ||
+ qstrncmp( new_share->path(),
+ Smb4KSettings::mountPrefix(),
+ Smb4KSettings::mountPrefix().length() ) == 0)) )
+ {
+ foreign = false;
+ }
+
+ new_share->setForeign( foreign );
+ }
+
+ shares.append( new_share );
+ }
+ }
+ }
+ }
+
+#else
+
+ struct statfs *buf;
+ int count = getmntinfo( &buf, 0 );
+
+ if ( count == 0 )
+ {
+ int err_code = errno;
+
+ Smb4KError::error( ERROR_IMPORTING_SHARES, QString::null, strerror( err_code ) );
+
+ m_working = false;
+ return;
+ }
+
+ for ( int i = 0; i < count; ++i )
+ {
+ if ( !strcmp( buf[i].f_fstypename, "smbfs" ) )
+ {
+ QString share_name( buf[i].f_mntfromname );
+ QString path( buf[i].f_mntonname );
+ QString fs( buf[i].f_fstypename );
+
+ QFileInfo info( QString( buf[i].f_mntonname )+"/." );
+
+ int uid = (int)info.ownerId();
+ int gid = (int)info.groupId();
+
+ Smb4KShare *existing_share = findShareByPath( path );
+ Smb4KShare *new_share = NULL;
+
+ if ( existing_share )
+ {
+ new_share = new Smb4KShare( *existing_share );
+ }
+ else
+ {
+ new_share = new Smb4KShare( share_name, path, fs, uid, gid );
+ }
+
+ // Test if share is broken
+ if ( (existing_share && !existing_share->isBroken()) || !existing_share )
+ {
+ checkAccessibility( new_share );
+ }
+ else
+ {
+ // Since new_share is a copy of existing_share, we do not need to do
+ // anything here.
+ }
+
+ shares.append( new_share );
+ }
+ }
+
+ // Apparently, under FreeBSD we do not need to delete
+ // the pointer (see manual page).
+
+#endif
+
+ // Delete all entries of m_mounted_shares.
+ for ( QValueList<Smb4KShare *>::Iterator it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_mounted_shares.clear();
+
+ m_mounted_shares = shares;
+
+ emit updated();
+
+ m_working = false;
+}
+
+
+/***************************************************************************
+ Mounts a share. (Public part)
+***************************************************************************/
+
+void Smb4KMounter::mountShare( const QString &workgroup, const QString &host, const QString &ip, const QString &share )
+{
+ QString share_name = QString::null;
+
+ if ( QString::compare( share, "homes" ) == 0 )
+ {
+ share_name = specifyUser( host, kapp->mainWidget() ? kapp->mainWidget() : 0, "SpecifyUser" );
+ }
+ else
+ {
+ share_name = share;
+ }
+
+ if ( !share_name.stripWhiteSpace().isEmpty() )
+ {
+ // Before doing anything else let's check that the
+ // share has not been mounted by the user already:
+ QValueList<Smb4KShare> list = findShareByName( QString( "//%1/%2" ).arg( host, share_name ) );
+
+ for ( QValueList<Smb4KShare>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it).isForeign() )
+ {
+ emit mountedShare( (*it).canonicalPath() );
+
+ return;
+ }
+ }
+
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4:%5" ).arg( Mount )
+ .arg( workgroup, host )
+ .arg( ip, share_name ) ) );
+ }
+}
+
+
+
+/***************************************************************************
+ Mounts a share. (Private part)
+***************************************************************************/
+
+void Smb4KMounter::mount( const QString &workgroup, const QString &host, const QString &ip, const QString &share )
+{
+ m_priv->setWorkgroup( workgroup );
+ m_priv->setHost( host );
+ m_priv->setShare( share );
+ m_priv->setIP( ip );
+
+ // Create the mount point:
+ QDir *dir = new QDir( Smb4KSettings::mountPrefix() );
+
+ if ( !dir->exists() )
+ {
+ if ( !dir->mkdir( dir->canonicalPath() ) )
+ {
+ Smb4KError::error( ERROR_MKDIR_FAILED, dir->path() );
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+
+ dir->setPath( dir->path() + "/" +
+ (Smb4KSettings::forceLowerCaseSubdirs() ?
+ m_priv->host().lower() :
+ m_priv->host()) );
+
+ if ( !dir->exists() )
+ {
+ if ( !dir->mkdir( dir->canonicalPath() ) )
+ {
+ Smb4KError::error( ERROR_MKDIR_FAILED, dir->path() );
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+
+ dir->setPath( dir->path() + "/" +
+ (Smb4KSettings::forceLowerCaseSubdirs() ?
+ m_priv->share().lower() :
+ m_priv->share()) );
+
+ if ( !dir->exists() )
+ {
+ if ( !dir->mkdir( dir->canonicalPath() ) )
+ {
+ Smb4KError::error( ERROR_MKDIR_FAILED, dir->path() );
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+
+ m_priv->setPath( QDir::cleanDirPath( dir->path() ) );
+
+ delete dir;
+
+ // Now we are prepared to mount the share:
+ QString command, suid_program;
+
+ switch ( Smb4KSettings::superUserProgram() )
+ {
+ case Smb4KSettings::EnumSuperUserProgram::Sudo:
+ {
+ suid_program = "sudo";
+
+ break;
+ }
+ case Smb4KSettings::EnumSuperUserProgram::Super:
+ {
+ suid_program = "super";
+
+ break;
+ }
+ default:
+ {
+ return;
+ }
+ }
+
+ Smb4KAuthInfo authInfo( m_priv->workgroup(), m_priv->host(), m_priv->share() );
+ (void) passwordHandler()->readAuth( &authInfo );
+
+#ifndef __FreeBSD__
+
+ // Let's see if the options handler knows the share:
+ Smb4KSambaOptionsInfo *info = optionsHandler()->findItem( QString( "//%1/%2" ).arg( m_priv->host(), m_priv->share() ), true );
+
+ // Determine the file system we have to use:
+ int filesystem;
+
+ if ( info )
+ {
+ filesystem = QString::compare( info->filesystem().lower(), "cifs" ) == 0 ?
+ Smb4KSettings::EnumFilesystem::CIFS :
+ Smb4KSettings::EnumFilesystem::SMBFS;
+ }
+ else
+ {
+ filesystem = Smb4KSettings::filesystem();
+ }
+
+ // Compile the mount command:
+ switch ( filesystem )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ command.append( Smb4KSettings::alwaysUseSuperUser() ? // FIXME: Check if suid program is installed
+ QString( "%1 smb4k_mount -s -t cifs " ).arg( suid_program ) :
+ "smb4k_mount -n -t cifs " );
+
+ command.append( "-o " );
+
+ command.append( optionsHandler()->mountOptions( QString( "//%1/%2" ).arg( m_priv->host(), m_priv->share() ) ) );
+
+ command.append( !m_priv->workgroup().stripWhiteSpace().isEmpty() ?
+ QString( "domain='%1'," ).arg( m_priv->workgroup() ) :
+ "" );
+
+ command.append( !m_priv->ip().stripWhiteSpace().isEmpty() ?
+ QString( "ip=%1," ).arg( m_priv->ip() ) :
+ "" );
+
+ command.append( !authInfo.user().isEmpty() ?
+ QString( "user=%1" ).arg( authInfo.user() ) :
+ "guest" );
+
+ command.append( " -- " );
+
+ command.append( QString( "//'%1'/'%2' '%3'" ).arg( m_priv->host(), m_priv->share(), m_priv->path() ) );
+
+ m_priv->setCIFSLogin( !authInfo.user().isEmpty() ?
+ authInfo.user() :
+ "guest" );
+
+ m_priv->setFileSystem( "cifs" );
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ command.append( Smb4KSettings::alwaysUseSuperUser() ? // FIXME: Check if suid program is installed
+ QString( "%1 smb4k_mount -s -t smbfs " ).arg( suid_program ) :
+ "smb4k_mount -n -t smbfs " );
+
+ command.append( "-o " );
+
+ command.append( optionsHandler()->mountOptions( QString( "//%1/%2" ).arg( m_priv->host(), m_priv->share() ) ) );
+
+ command.append( !m_priv->workgroup().stripWhiteSpace().isEmpty() ?
+ QString( "workgroup='%1'," ).arg( m_priv->workgroup() ) :
+ "" );
+
+ command.append( !m_priv->ip().stripWhiteSpace().isEmpty() ?
+ QString( "ip=%1," ).arg( m_priv->ip() ) :
+ "" );
+
+ command.append( !authInfo.user().isEmpty() ?
+ QString( "username=%1" ).arg( authInfo.user() ) :
+ "guest" );
+
+ command.append( " -- " );
+
+ command.append( QString( "//'%1'/'%2' '%3'" ).arg( m_priv->host(), m_priv->share(), m_priv->path() ) );
+
+ m_priv->setFileSystem( "smbfs" );
+
+ break;
+ }
+ default:
+ {
+ return;
+ }
+ }
+
+ m_proc->setEnvironment( "PASSWD", !authInfo.password().isEmpty() ? authInfo.password() : "" );
+
+#else
+
+ Smb4KSambaOptionsInfo *info = optionsHandler()->findItem( "//"+m_priv->host()+"/"+m_priv->share() );
+
+ int port = info && info->port() != -1 ?
+ info->port() :
+ Smb4KSettings::remotePort();
+
+ command.append( Smb4KSettings::alwaysUseSuperUser() ? // FIXME: Check if suid program is installed
+ QString( "%1 smb4k_mount " ).arg( suid_program ) :
+ "smb4k_mount " );
+
+ command.append( optionsHandler()->mountOptions( QString( "//%1/%2" ).arg( m_priv->host(), m_priv->share() ) ) );
+
+ command.append( !m_priv->workgroup().stripWhiteSpace().isEmpty() ?
+ QString( " -W '%1'" ).arg( m_priv->workgroup() ) :
+ "" );
+
+ command.append( !m_priv->ip().stripWhiteSpace().isEmpty() ?
+ QString( " -I %1" ).arg( m_priv->ip() ) :
+ "" );
+
+ command.append( " -N" );
+
+ command.append( " -- " );
+
+ command.append( QString( "//%1@'%2':%3/'%4' '%5'" ).arg( !authInfo.user().isEmpty() ? authInfo.user() : "guest" )
+ .arg( m_priv->host() )
+ .arg( port )
+ .arg( m_priv->share(), m_priv->path() ) );
+
+#endif
+
+ // Start the mount process:
+ *m_proc << command;
+
+ startProcess( Mount );
+}
+
+
+/****************************************************************************
+ Unmount a share. (Public part)
+****************************************************************************/
+
+void Smb4KMounter::unmountShare( Smb4KShare *share, bool force, bool noMessage )
+{
+ // Do *not* change share->canonicalPath(). It is necessary for the
+ // checks below to work.
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4" ).arg( Unmount )
+ .arg( share->canonicalPath() )
+ .arg( force, noMessage ) ) );
+}
+
+
+/***************************************************************************
+ Unmount a share. (Private part)
+***************************************************************************/
+
+void Smb4KMounter::unmount( const QString &mountpoint, bool force, bool noMessage )
+{
+ // First let's see if all requirements are fullfilled:
+
+ if ( force )
+ {
+ // Check that the user enabled the "Force Unmounting" ability:
+ if ( !Smb4KSettings::useForceUnmount() )
+ {
+ Smb4KError::error( ERROR_FEATURE_NOT_ENABLED );
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+
+ // Compose the unmount command:
+ if ( !mountpoint.stripWhiteSpace().isEmpty() )
+ {
+ bool execute = false;
+
+ QString path = mountpoint;
+ m_priv->setPath( path.replace( '\044', "\044" ) );
+
+ QString suid_program, command;
+
+ if ( Smb4KSettings::useForceUnmount() || Smb4KSettings::alwaysUseSuperUser() )
+ {
+ switch ( Smb4KSettings::superUserProgram() )
+ {
+ case Smb4KSettings::EnumSuperUserProgram::Sudo:
+ {
+ suid_program = Smb4KSettings::sudo();
+
+ break;
+ }
+ case Smb4KSettings::EnumSuperUserProgram::Super:
+ {
+ suid_program = Smb4KSettings::super();
+
+ break;
+ }
+ default:
+ {
+ // FIXME: Throw an error?
+ return;
+ }
+ }
+ }
+
+ Smb4KShare *share = findShareByPath( mountpoint );
+
+ if ( share )
+ {
+ if ( !share->isForeign() )
+ {
+ if ( force )
+ {
+ if ( KMessageBox::questionYesNo( 0, i18n( "Do you really want to force the unmounting of this share?" ), QString::null, KStdGuiItem::yes(), KStdGuiItem::no(), "Dont Ask Forced", KMessageBox::Notify ) == KMessageBox::Yes )
+ {
+#ifdef __linux__
+ command.append( QString( "%1 smb4k_umount -s -l " ).arg( suid_program ) );
+#else
+#ifdef __FreeBSD__
+ command.append( QString( "%1 smb4k_umount " ).arg( suid_program ) );
+#else
+ command.append( QString( "%1 smb4k_umount -s " ).arg( suid_program ) );
+#endif
+#endif
+ execute = true;
+ }
+ else
+ {
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+ else
+ {
+ if ( !Smb4KSettings::alwaysUseSuperUser() )
+ {
+#ifndef __FreeBSD__
+ command.append( "smb4k_umount -n " );
+#else
+ command.append( "smb4k_umount " );
+#endif
+ }
+ else
+ {
+#ifndef __FreeBSD__
+ command.append( QString( "%1 smb4k_umount -s " ).arg( suid_program ) );
+#else
+ command.append( QString( "%1 smb4k_umount " ).arg( suid_program ) );
+#endif
+ }
+ }
+ }
+ else
+ {
+ if ( Smb4KSettings::unmountForeignShares() )
+ {
+ if ( force )
+ {
+ if ( KMessageBox::questionYesNo( 0, i18n( "Do you really want to force the unmounting of this share?" ), QString::null, KStdGuiItem::yes(), KStdGuiItem::no(), "Dont Ask Forced", KMessageBox::Notify ) == KMessageBox::Yes )
+ {
+#ifdef __linux__
+ command.append( QString( "%1 smb4k_umount -s -l " ).arg( suid_program ) );
+#else
+#ifdef __FreeBSD__
+ command.append( QString( "%1 smb4k_umount " ).arg( suid_program ) );
+#else
+ command.append( QString( "%1 smb4k_umount -s " ).arg( suid_program ) );
+#endif
+#endif
+ execute = true;
+ }
+ else
+ {
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+ else
+ {
+ if ( !Smb4KSettings::alwaysUseSuperUser() )
+ {
+#ifndef __FreeBSD__
+ command.append( "smb4k_umount -n " );
+#else
+ command.append( "smb4k_umount " );
+#endif
+ }
+ else
+ {
+#ifndef __FreeBSD__
+ command.append( QString( "%1 smb4k_umount -s " ).arg( suid_program ) );
+#else
+ command.append( QString( "%1 smb4k_umount " ).arg( suid_program ) );
+#endif
+ }
+ }
+ }
+ else
+ {
+ if ( !noMessage )
+ {
+ Smb4KError::error( ERROR_UNMOUNTING_NOT_ALLOWED );
+ }
+
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+ }
+
+#ifndef __FreeBSD__
+ command.append( QString( "-t %1 " ).arg( share->filesystem() ) );
+#endif
+ command.append( QString( "'%1'" ).arg( m_priv->path() ) );
+
+ if ( force && !execute )
+ {
+ return;
+ }
+
+ emit aboutToUnmount( mountpoint );
+
+ *m_proc << command;
+ startProcess( Unmount );
+ }
+ else
+ {
+ // FIXME: Throw an error?
+ return;
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_MOUNTPOINT_EMPTY );
+ m_working = false;
+ emit state( MOUNTER_STOP );
+
+ return;
+ }
+}
+
+
+/***************************************************************************
+ Unmounts all shares at once. (Public part)
+***************************************************************************/
+
+void Smb4KMounter::unmountAllShares()
+{
+ m_queue.enqueue( new QString( QString( "%1" ).arg( UnmountAll ) ) );
+}
+
+
+/***************************************************************************
+ Unmounts all shares at once.
+***************************************************************************/
+
+void Smb4KMounter::unmountAll()
+{
+ for ( QValueListIterator<Smb4KShare *> it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ unmountShare( *it, false, true );
+ }
+
+ m_working = false;
+}
+
+
+/***************************************************************************
+ Starts any process.
+***************************************************************************/
+
+void Smb4KMounter::startProcess( int state )
+{
+ m_buffer = QString::null;
+ m_state = state;
+
+ if ( m_state != Import )
+ {
+ QApplication::setOverrideCursor( waitCursor );
+ }
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+
+/***************************************************************************
+ Ends any process. This functions tells the mounter what to do
+ afterwards.
+***************************************************************************/
+
+void Smb4KMounter::endProcess()
+{
+ switch ( m_state )
+ {
+ case Mount:
+ processMount();
+ break;
+ case Unmount:
+ processUnmount();
+ break;
+ default:
+ break;
+ }
+
+ m_state = Idle;
+
+ m_priv->clearData();
+
+ QApplication::restoreOverrideCursor();
+ m_proc->clearArguments();
+
+ m_working = false;
+ emit state( MOUNTER_STOP );
+}
+
+
+/***************************************************************************
+ Process mounts.
+***************************************************************************/
+
+void Smb4KMounter::processMount()
+{
+ Smb4KShare *share = NULL;
+
+#ifndef __FreeBSD__
+
+ if ( m_proc->normalExit() )
+ {
+ if ( m_buffer.contains( "smb4k_mount:", true ) == 0 &&
+ m_buffer.contains( "failed", true ) == 0 &&
+ m_buffer.contains( "ERR", true ) == 0 &&
+ m_buffer.contains( "/bin/sh:" ) == 0 &&
+ m_buffer.contains( "mount:", true ) == 0 &&
+ m_buffer.contains( "smbmnt" ) == 0 &&
+ m_buffer.contains( m_priv->path() ) == 0 &&
+ m_buffer.contains( "mount error" ) == 0 &&
+ m_buffer.contains( "bad user name" ) == 0 &&
+ m_buffer.contains( "bad group name" ) == 0 )
+ {
+ QString name = QString( "//%1/%2" ).arg( m_priv->host() ).arg( m_priv->share() );
+
+ // Check file system
+#if !defined(__solaris__)
+ struct statfs filesystem;
+#else
+ struct statvfs filesystem;
+#endif
+
+#if !defined(__solaris__) && !defined(__irix__)
+ if ( statfs( m_priv->path(), &filesystem ) == -1 )
+#elif defined(__irix__)
+ if ( statfs( m_priv->path(), &filesystem, sizeof( filesystem ), 0 ) == -1 )
+#else
+ if ( statvfs( m_priv->path(), &filesystem ) == -1 )
+#endif
+ {
+ // The query failed. Go with the file system already defined in m_priv.
+ if ( QString::compare( m_priv->filesystem(), "smbfs" ) == 0 )
+ {
+ share = new Smb4KShare( name, m_priv->path(), m_priv->filesystem(), (int)getuid(), (int)getgid() );
+ m_mounted_shares.append( share );
+ }
+ else if ( QString::compare( m_priv->filesystem(), "cifs" ) == 0 )
+ {
+ // The user name will be send if no login was specified.
+ QString cifs_login = !m_priv->cifsLogin().isEmpty() ?
+ m_priv->cifsLogin() :
+ getpwuid( getuid() )->pw_name;
+
+ share = new Smb4KShare( name, m_priv->path(), m_priv->filesystem(), cifs_login, false );
+ m_mounted_shares.append( share );
+ }
+ }
+ else
+ {
+#if !defined(__FreeBSD__) && !defined(__solaris__) && !defined(__irix__)
+ if ( (uint)filesystem.f_type == 0xFF534D42 /* CIFS */)
+ {
+ // The user name will be send if no login was specified.
+ QString cifs_login = !m_priv->cifsLogin().isEmpty() ?
+ m_priv->cifsLogin() :
+ getpwuid( getuid() )->pw_name;
+
+ share = new Smb4KShare( name, m_priv->path(), "cifs", cifs_login, false );
+ m_mounted_shares.append( share );
+ }
+ else if ( (uint)filesystem.f_type == 0x517B /* SMBFS */)
+ {
+ share = new Smb4KShare( name, m_priv->path(), "smbfs", (int)getuid(), (int)getgid() );
+ m_mounted_shares.append( share );
+ }
+#elif defined(__solaris__)
+ if ( (uint)filesystem.f_basetype == 0xFF534D42 /* CIFS */)
+ {
+ // The user name will be send if no login was specified.
+ QString cifs_login = !m_priv->cifsLogin().isEmpty() ?
+ m_priv->cifsLogin() :
+ getpwuid( getuid() )->pw_name;
+
+ share = new Smb4KShare( name, m_priv->path(), "cifs", cifs_login, false );
+ m_mounted_shares.append( share );
+ }
+ else if ( (uint)filesystem.f_basetype == 0x517B /* SMBFS */)
+ {
+ share = new Smb4KShare( name, m_priv->path(), "smbfs", (int)getuid(), (int)getgid() );
+ m_mounted_shares.append( share );
+ }
+#elif defined(__irix__)
+ if ( (uint)filesystem.f_fstyp == 0xFF534D42 /* CIFS */)
+ {
+ // The user name will be send if no login was specified.
+ QString cifs_login = !m_priv->cifsLogin().isEmpty() ?
+ m_priv->cifsLogin() :
+ getpwuid( getuid() )->pw_name;
+
+ share = new Smb4KShare( name, m_priv->path(), "cifs", cifs_login, false );
+ m_mounted_shares.append( share );
+ }
+ else if ( (uint)filesystem.f_basetype == 0x517B && !strncmp( fs, "smbfs", strlen( fs )+1 ) )
+ {
+ share = new Smb4KShare( name, m_priv->path(), "smbfs", (int)getuid(), (int)getgid() );
+ m_mounted_shares.append( share );
+ }
+#endif
+ else
+ {
+ // Error... We don't create a share.
+ }
+ }
+
+ if ( share )
+ {
+ // Check that the share is accessible:
+ checkAccessibility( share );
+
+ emit mountedShare( m_priv->path() );
+ }
+ }
+ else
+ {
+ if ( m_buffer.contains( "ERRbadpw" ) != 0 ||
+ m_buffer.contains( "ERRnoaccess" ) != 0 ||
+ m_buffer.contains( "mount error 13 = Permission denied" ) != 0 )
+ {
+ int state = Smb4KPasswordHandler::None;
+
+ if ( m_buffer.contains( "ERRbadpw" ) != 0 )
+ {
+ state = Smb4KPasswordHandler::BadPassword;
+ }
+ else if ( m_buffer.contains( "ERRnoaccess" ) != 0 )
+ {
+ state = Smb4KPasswordHandler::AccessDenied;
+ }
+ else if ( m_buffer.contains( "mount error 13 = Permission denied" ) != 0 )
+ {
+ state = Smb4KPasswordHandler::PermDenied;
+ }
+
+ // If the user supplied auth information, we will retry mounting.
+ if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(), m_priv->share(), state ) )
+ {
+ mountShare( m_priv->workgroup(), m_priv->host(), m_priv->ip(), m_priv->share() );
+ }
+ }
+ else if ( m_buffer.contains( "ERRnosuchshare" ) != 0 && m_priv->share().contains( "_" ) != 0 )
+ {
+ QString share_string = static_cast<QString>( m_priv->share() ).replace( "_", " " );
+ mountShare( m_priv->workgroup(), m_priv->host(), m_priv->ip(), share_string );
+ }
+ else
+ {
+ QString name = QString( "//%1/%2" ).arg( m_priv->host() ).arg( m_priv->share() );
+
+ Smb4KError::error( ERROR_MOUNTING_SHARE, name, m_buffer );
+ }
+ }
+ }
+
+#else
+
+ if ( m_proc->normalExit() )
+ {
+ if ( m_buffer.contains( "smb4k_mount:", true ) == 0 &&
+ m_buffer.contains( "syserr =", true ) == 0 &&
+ /* To make sure we catch all errors, also check for the following
+ strings. Maybe we can remove them?? */
+ m_buffer.contains( "Authentication error", true ) == 0 &&
+ m_buffer.contains( "Connection refused", true ) == 0 &&
+ m_buffer.contains( "Operation not permitted", true ) == 0 )
+ {
+ import(); // FIXME: *cough* What is this for???
+
+ Smb4KAuthInfo authInfo( m_priv->workgroup(), m_priv->host(), m_priv->share() );
+ (void) passwordHandler()->readAuth( &authInfo );
+
+ QString name = QString( "//%1@%2/%3" ).arg( authInfo.user().upper(), m_priv->host().upper(), m_priv->share().upper() );
+
+ share = new Smb4KShare( name, m_priv->path(), m_priv->filesystem(), (int)getuid(), (int)getgid() );
+ m_mounted_shares.append( share );
+
+ // Check that the share is accessible:
+ checkAccessibility( share );
+
+ emit mountedShare( m_priv->path() );
+ }
+ else
+ {
+ if ( m_buffer.contains( "Authentication error" ) != 0 )
+ {
+ // If the user supplied auth information, we will retry mounting.
+ if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(), m_priv->share(), Smb4KPasswordHandler::AuthError ) )
+ {
+ mountShare( m_priv->workgroup(), m_priv->host(), m_priv->ip() , m_priv->share() );
+ }
+ }
+ else
+ {
+ Smb4KAuthInfo authInfo( m_priv->workgroup(), m_priv->host(), m_priv->share() );
+ (void) passwordHandler()->readAuth( &authInfo );
+
+ QString name = QString( "//%1@%2/%3" ).arg( authInfo.user().upper(), m_priv->host().upper(), m_priv->share().upper() );
+
+ Smb4KError::error( ERROR_MOUNTING_SHARE, name, m_buffer );
+ }
+ }
+ }
+
+#endif
+
+ emit updated();
+}
+
+
+/***************************************************************************
+ Process unmounts.
+***************************************************************************/
+
+void Smb4KMounter::processUnmount()
+{
+ // Get the share:
+ Smb4KShare *share = findShareByPath( m_priv->path() );
+
+ if ( m_proc->normalExit() )
+ {
+ if ( m_buffer.isEmpty() )
+ {
+ if ( qstrncmp( share->canonicalPath(),
+ QDir( Smb4KSettings::mountPrefix() ).canonicalPath().local8Bit(),
+ QDir( Smb4KSettings::mountPrefix() ).canonicalPath().local8Bit().length() ) == 0 )
+ {
+ QDir dir( share->canonicalPath() );
+
+ if ( dir.rmdir( dir.canonicalPath(), true ) )
+ {
+ dir.cdUp();
+ dir.rmdir( dir.canonicalPath(), true );
+ }
+ }
+
+ m_mounted_shares.remove(share);
+ }
+ else
+ {
+ // If the user's computer is configured by a DHCP server, under
+ // rare circumstances it might occur that sudo reports an error,
+ // because it is not able to resolve the host. This error message
+ // will be removed, because it does not affect the unmounting:
+ if ( m_buffer.contains( "sudo: unable to resolve host", true ) != 0 )
+ {
+ size_t hostnamelen = 255;
+ char *hostname = new char[hostnamelen];
+
+ if ( gethostname( hostname, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, QString::null, strerror( error_number ) );
+ }
+ else
+ {
+ QString str = QString( "sudo: unable to resolve host %1\n" ).arg( hostname );
+
+ m_buffer.remove( str, false /* case insensitive */ );
+
+ if ( !m_buffer.isEmpty() )
+ {
+ Smb4KError::error( ERROR_UNMOUNTING_SHARE, share->name(), m_buffer );
+ }
+ else
+ {
+ if ( qstrncmp( share->canonicalPath(),
+ QDir( Smb4KSettings::mountPrefix() ).canonicalPath().local8Bit(),
+ QDir( Smb4KSettings::mountPrefix() ).canonicalPath().local8Bit().length() ) == 0 )
+ {
+ QDir dir( share->canonicalPath() );
+
+ if ( dir.rmdir( dir.canonicalPath(), true ) )
+ {
+ dir.cdUp();
+ dir.rmdir( dir.canonicalPath(), true );
+ }
+ }
+
+ m_mounted_shares.remove(share);
+ }
+ }
+
+ delete [] hostname;
+ }
+ else
+ {
+ Smb4KError::error( ERROR_UNMOUNTING_SHARE, share->name(), m_buffer );
+ }
+ }
+ }
+
+ emit updated();
+}
+
+
+/***************************************************************************
+ Check if a share is already mounted
+***************************************************************************/
+
+bool Smb4KMounter::isMounted( const QString &name, bool userOnly )
+{
+ QValueList<Smb4KShare> list = findShareByName( name );
+
+ bool mounted = false;
+
+ if ( !list.isEmpty() && userOnly )
+ {
+ for ( QValueList<Smb4KShare>::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it).isForeign() )
+ {
+ mounted = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ else
+ {
+ mounted = !list.isEmpty();
+ }
+
+ return mounted;
+}
+
+
+/***************************************************************************
+ Find a share in the list with its path
+***************************************************************************/
+
+Smb4KShare* Smb4KMounter::findShareByPath( const QString &path )
+{
+ if ( path.isEmpty() || m_mounted_shares.isEmpty() )
+ {
+ return NULL;
+ }
+
+ Smb4KShare *share = NULL;
+
+ for ( QValueListIterator<Smb4KShare *> it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ if( QString::compare( path.upper(), QString::fromLocal8Bit( (*it)->path(), -1 ).upper() ) == 0 ||
+ QString::compare( path.upper(), QString::fromLocal8Bit( (*it)->canonicalPath(), -1 ).upper() ) == 0 )
+ {
+ share = *it;
+
+ break;
+ }
+ }
+
+ return share;
+}
+
+
+/***************************************************************************
+ Find the list of mounts of a share
+***************************************************************************/
+
+QValueList<Smb4KShare> Smb4KMounter::findShareByName( const QString &name )
+{
+ QValueList<Smb4KShare> list;
+
+ if ( name.isEmpty() || m_mounted_shares.isEmpty() )
+ {
+ return list; // is empty
+ }
+
+ QString n = name;
+
+ for ( QValueListIterator<Smb4KShare *> it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ if( QString::compare( (*it)->name().upper(), name.upper() ) == 0 ||
+ QString::compare( (*it)->name().upper(), n.replace( " ", "_" ).upper() ) == 0 )
+ {
+ list.append( *(*it) );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return list;
+}
+
+
+/***************************************************************************
+ Returns a list of mount points that belong to broken shares
+***************************************************************************/
+
+const QValueList<Smb4KShare *> Smb4KMounter::getBrokenShares()
+{
+ QValueList<Smb4KShare *> broken_shares;
+
+ for ( QValueListIterator<Smb4KShare *> it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ if ( (*it)->isBroken() )
+ {
+ broken_shares.append( *it );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return broken_shares;
+}
+
+
+void Smb4KMounter::prepareForShutdown()
+{
+ slotShutdown();
+}
+
+
+void Smb4KMounter::checkAccessibility( Smb4KShare *share )
+{
+ if ( share )
+ {
+ m_priv->thread.setMountpoint( share->path() );
+ m_priv->thread.start();
+ m_priv->thread.wait( THREAD_WAITING_TIME );
+ m_priv->thread.terminate();
+ m_priv->thread.wait();
+
+ share->setBroken( m_priv->thread.isBroken() );
+ share->setTotalDiskSpace( m_priv->thread.totalDiskSpace() );
+ share->setFreeDiskSpace( m_priv->thread.freeDiskSpace() );
+ }
+ else
+ {
+ // FIXME: Should we throw an error here?
+ }
+}
+
+
+void Smb4KMounter::timerEvent( QTimerEvent * )
+{
+ if ( !m_working && !m_queue.isEmpty() )
+ {
+ // Tell the mounter, that it is busy.
+ m_working = true;
+
+ QString *item = m_queue.dequeue();
+ int todo = item->section( ":", 0, 0 ).toInt();
+
+ switch ( todo )
+ {
+ case Remount:
+ {
+ remount();
+ break;
+ }
+ case Import:
+ {
+ import();
+ break;
+ }
+ case Mount:
+ {
+ emit state( MOUNTER_MOUNTING );
+ mount( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ), item->section( ":", 4, 4 ) );
+ break;
+ }
+ case Unmount:
+ {
+ emit state( MOUNTER_UNMOUNTING );
+ unmount( item->section( ":", 1, 1 ), (bool)item->section( ":", 2, 2 ).toInt() /* force */, (bool)item->section( ":", 3, 3 ).toInt() /* noMessage */);
+ break;
+ }
+ case UnmountAll:
+ {
+ unmountAll();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ delete item;
+ }
+
+ m_priv->timerTicks++;
+
+ if ( m_priv->timerTicks * timerInterval() >= Smb4KSettings::checkInterval() /* msec */ &&
+ (!m_working || m_queue.isEmpty()) )
+ {
+ m_queue.enqueue( new QString( QString( "%1:" ).arg( Import ) ) );
+ m_priv->timerTicks = 0;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+
+void Smb4KMounter::slotProcessExited( KProcess * )
+{
+ endProcess();
+}
+
+
+void Smb4KMounter::slotReceivedStdout( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KMounter::slotReceivedStderr( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KMounter::slotShutdown()
+{
+ // Abort any action:
+ abort();
+
+ // Prepare for shutdown:
+ if ( Smb4KSettings::remountShares() && !m_mounted_shares.isEmpty() )
+ {
+ for ( QValueList<Smb4KShare *>::ConstIterator it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ optionsHandler()->remount( *it, !(*it)->isForeign() );
+ }
+ }
+
+ optionsHandler()->sync();
+
+ QDir dir;
+
+ dir.cd( Smb4KSettings::mountPrefix() );
+
+ QStringList dirs = dir.entryList( QDir::Dirs, QDir::DefaultSort );
+
+ QValueList<Smb4KShare *> broken_shares = getBrokenShares();
+
+ for ( QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it )
+ {
+ if ( QString::compare( *it, "." ) != 0 && QString::compare( *it, ".." ) != 0 )
+ {
+ bool broken = false;
+
+ for ( QValueListIterator<Smb4KShare *> bs = broken_shares.begin(); bs != broken_shares.end(); ++bs )
+ {
+ if ( qstrncmp( (*bs)->path(),
+ Smb4KSettings::mountPrefix()+*it,
+ (Smb4KSettings::mountPrefix()+*it).length() ) == 0 ||
+ qstrncmp( (*bs)->canonicalPath(),
+ Smb4KSettings::mountPrefix()+*it,
+ (Smb4KSettings::mountPrefix()+*it).length() ) == 0 )
+ {
+ broken = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !broken )
+ {
+ dir.cd( *it );
+
+ QStringList subdirs = dir.entryList( QDir::Dirs, QDir::DefaultSort );
+
+ for ( QStringList::ConstIterator i = subdirs.begin(); i != subdirs.end(); ++i )
+ {
+ if ( QString::compare( *i, "." ) != 0 && QString::compare( *i, ".." ) != 0 )
+ {
+ dir.rmdir( *i );
+ }
+ }
+
+ dir.cdUp();
+ dir.rmdir( *it );
+ }
+ }
+ }
+
+ broken_shares.clear();
+
+ if ( Smb4KSettings::unmountSharesOnExit() )
+ {
+ QString suid_program, command;
+
+ switch( Smb4KSettings::superUserProgram() )
+ {
+ case Smb4KSettings::EnumSuperUserProgram::Sudo:
+ {
+ suid_program = Smb4KSettings::sudo();
+
+ break;
+ }
+ case Smb4KSettings::EnumSuperUserProgram::Super:
+ {
+ suid_program = Smb4KSettings::super();
+
+ break;
+ }
+ default:
+ {
+ // FIXME: Throw an error?
+ return;
+ }
+ }
+
+ KProcess proc;
+ proc.setUseShell( true );
+ proc.detach();
+
+ for ( QValueListIterator<Smb4KShare *> it = m_mounted_shares.begin(); it != m_mounted_shares.end(); ++it )
+ {
+ if ( !(*it)->isForeign() )
+ {
+ if ( Smb4KSettings::alwaysUseSuperUser() )
+ {
+#ifndef __FreeBSD__
+ command.append( QString( "%1 smb4k_umount -s -t %2 " ).arg( suid_program ).arg( (*it)->filesystem() ) );
+#else
+ command.append( QString( "%1 smb4k_umount " ).arg( suid_program ) );
+#endif
+ command.append( KProcess::quote( (*it)->path() ) );
+ command.append( " ; " );
+ }
+ else
+ {
+#ifndef __FreeBSD__
+ command.append( QString( "smb4k_umount -n -t %1 " ).arg( (*it)->filesystem() ) );
+#else
+ command.append( "smb4k_umount " );
+#endif
+ command.append( KProcess::quote( (*it)->path() ) );
+ command.append( " ; " );
+ }
+
+ dir.setPath( (*it)->canonicalPath() );
+
+#ifndef __FreeBSD__
+ command.append( "rmdir --ignore-fail-on-non-empty " );
+ command.append( KProcess::quote( dir.canonicalPath() ) );
+ command.append( " ; " );
+ command.append( "rmdir --ignore-fail-on-non-empty " );
+ dir.cdUp();
+ command.append( KProcess::quote( dir.canonicalPath() ) );
+ command.append( " ; " );
+#else
+ command.append( "rmdir " );
+ command.append( KProcess::quote( dir.canonicalPath() ) );
+ command.append( " ; " );
+ command.append( "rmdir " );
+ dir.cdUp();
+ command.append( KProcess::quote( dir.canonicalPath() ) );
+ command.append( " ; " );
+#endif
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ command.truncate( command.length() - 2 );
+
+ proc << command;
+ proc.start( KProcess::DontCare, KProcess::NoCommunication );
+ }
+}
+
+
+#include "smb4kmounter.moc"
diff --git a/smb4k/core/smb4kmounter.h b/smb4k/core/smb4kmounter.h
new file mode 100644
index 0000000..a5f51db
--- /dev/null
+++ b/smb4k/core/smb4kmounter.h
@@ -0,0 +1,343 @@
+/***************************************************************************
+ smb4kmounter.h - The core class that mounts the shares.
+ -------------------
+ begin : Die Jun 10 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KMOUNTER_H
+#define SMB4KMOUNTER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qptrqueue.h>
+#include <qfile.h>
+
+// KDE includes
+#include <kprocess.h>
+
+// application specific includes
+#include "smb4kdefs.h"
+
+// forward declarations
+class Smb4KMounterPrivate;
+class Smb4KShare;
+
+
+/**
+ * This is one of the core classes of Smb4K. It manages the mounting
+ * and unmounting of remote Samba/Windows shares. Additionally it maintains a
+ * list of all mounts with SMBFS and CIFS file system that are present
+ * on the system.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KMounter : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ */
+ Smb4KMounter( QObject *parent = 0, const char *name = 0 );
+ /**
+ * The destructor.
+ */
+ ~Smb4KMounter();
+
+ /**
+ * Aborts a running process.
+ */
+ void abort();
+
+ /**
+ * Enumeration for the state of the process. The members are also
+ * used in the results() signal as return values.
+ */
+ enum State{ Remount, Import, Mount, Unmount, UnmountAll, Idle };
+
+ /**
+ * Unmounts a share. This can either be done the "normal" way, or you may
+ * force it. If you decide the force the unmounting by setting @p force to TRUE,
+ * a lazy unmount will be initiated. With the parameter @p noMessage you can
+ * suppress any error messages.
+ *
+ * @param share The share object that should be unmounted.
+ *
+ * @param force Force the unmounting of the share.
+ *
+ * @param noMessage Determines whether this function should emit an error code in case of an error.
+ * The default value is FALSE.
+ */
+ void unmountShare( Smb4KShare *share, bool force = false, bool noMessage = false );
+
+ /**
+ * Unmounts all shares at once.
+ */
+ void unmountAllShares();
+
+ /**
+ * Mounts a share.
+ *
+ * @param workgroup The workgroup of the share.
+ *
+ * @param host The server where the share is located.
+ *
+ * @param ip The IP address of the host.
+ *
+ * @param share The name of the share.
+ */
+ void mountShare( const QString &workgroup, const QString &host, const QString &ip, const QString &share );
+
+ /**
+ * Returns the unsorted list of mounted shares.
+ */
+ const QValueList<Smb4KShare *> &getShares() { return m_mounted_shares; };
+
+ /**
+ * Find a share in the list with its path.
+ */
+ Smb4KShare* findShareByPath( const QString &path );
+
+ /**
+ * Find all mounts of the particular share @p share on the system.
+ *
+ * @param name The name of the share
+ *
+ * @returns the complete list of mounts of @p share.
+ */
+ QValueList<Smb4KShare> findShareByName( const QString &name );
+
+ /**
+ * This function returns TRUE if a share is mounted and FALSE otherwise.
+ *
+ * @param name The name of the share. It has to look like this:
+ * //HOST/SHARE.
+ *
+ * @param userOnly Specifies whether this function should only consider
+ * shares mounted by the user or all shares that are
+ * available on the system. The default is TRUE.
+ *
+ * @return TRUE if the share is mounted and FALSE otherwise.
+ */
+ bool isMounted( const QString &name, bool userOnly = true );
+
+ /**
+ * This function reports if the mounter is running or not.
+ *
+ * @returns TRUE if the scanner is running and FALSE otherwise.
+ */
+ bool isRunning() { return m_working; }
+
+ /**
+ * This function returns the list of broken shares.
+ *
+ * @returns The list of broken shares.
+ */
+ const QValueList<Smb4KShare *> getBrokenShares();
+
+ /**
+ * This function executes Smb4KMounter::slotShutdown(). Under normal circumstances,
+ * there is no need to use this function, because everything that is done here is
+ * also done when KApplication::shutDown() is emitted. However, it comes in handy
+ * when you need to perform last actions in a plugin.
+ */
+ void prepareForShutdown();
+
+ /**
+ * This function initializes import of mounted shares and the remounting of recently
+ * used shares.
+ */
+ void init();
+
+ signals:
+ /**
+ * This signal emits the run state.
+ *
+ * @param state The so-called run state. There are several defined
+ * in the smb4kdefs.h header file.
+ */
+ void state( int state );
+
+ /**
+ * Tells the program, that the shares list has been updated.
+ */
+ void updated();
+
+ /**
+ * This signal is emitted when a share has successfully been mounted or
+ * if it has already been mounted.
+ *
+ * @param mountpoint The mount point of the share.
+ */
+ void mountedShare( const QString &mountpoint );
+
+ /**
+ * This signal is emitted just before a share is unmounted.
+ *
+ * @param mountpoint The mount point of the share that is going to
+ * be unmounted.
+ */
+ void aboutToUnmount( const QString &mountpoint );
+
+ protected:
+ /**
+ * Starts a process. It takes an interger, that determines,
+ * which process has to be started.
+ */
+ void startProcess( int state );
+
+ /**
+ * Is called, when the process ended.
+ */
+ void endProcess();
+
+ /**
+ * Finishes the mounting of shares.
+ */
+ void processMount();
+
+ /**
+ * Finishes the unmounting of a single share.
+ */
+ void processUnmount();
+
+ /**
+ * Reimplemented from QObject
+ */
+ void timerEvent( QTimerEvent *e );
+
+ protected slots:
+ /**
+ * Is called, when the process exits.
+ */
+ void slotProcessExited( KProcess * );
+
+ /**
+ * Is called, if output is received on Stdout.
+ */
+ void slotReceivedStdout( KProcess *, char *buf, int len );
+
+ /**
+ * Is called, if output is received on Stderr.
+ */
+ void slotReceivedStderr( KProcess *, char *buf, int len );
+
+ /**
+ * This slot is called by the KApplication::shutDown() signal.
+ * Is does everything that has to be done before the program
+ * really exits.
+ */
+ void slotShutdown();
+
+ private:
+ /**
+ * Remount shares that were used in the last session.
+ */
+ void remount();
+
+ /**
+ * Imports mounted shares.
+ */
+ void import();
+
+ /**
+ * Mounts a selected share.
+ */
+ void mount( const QString &workgroup, const QString &host, const QString &ip, const QString &share );
+
+ /**
+ * Unmounts the selected item.
+ */
+ void unmount( const QString &mountpoint, bool noMessage, bool force = false );
+
+ /**
+ * Unmounts all shares at once.
+ */
+ void unmountAll();
+
+ /**
+ * Checks if the share @p share is accessible or not and sets Smb4KShare::isBroken()
+ * accordingly. Additionally, Smb4KShare::totalDiskSpace() and Smb4KShare::freeDiskSpace()
+ * are set to the current values.
+ *
+ * @param share The share that should be checked.
+ */
+ void checkAccessibility( Smb4KShare *share );
+
+ /**
+ * The KProcess object.
+ */
+ KProcess *m_proc;
+
+ /**
+ * The buffer.
+ */
+ QString m_buffer;
+
+ /**
+ * The queue, where the incoming requests are stored.
+ */
+ QPtrQueue<QString> m_queue;
+
+ /**
+ * Determines, whether the mounter is running or not.
+ */
+ bool m_working;
+
+ /**
+ * Holds the list of currently mounted shares as a pointer list.
+ */
+ QValueList<Smb4KShare *> m_mounted_shares;
+
+ /**
+ * Makes sure that the error message concerning the missing of
+ * the file /proc/mounts is only shown once.
+ */
+ bool m_proc_error;
+
+ /**
+ * The internal state of the process. Do not mix this up with
+ * the state that's emitted to notify the application about changes.
+ */
+ int m_state;
+
+#ifndef __FreeBSD__
+ /**
+ * This file object points to /proc/mounts.
+ */
+ QFile m_proc_mounts;
+#endif
+
+ /**
+ * This is the pointer to the private helper class.
+ */
+ Smb4KMounterPrivate *m_priv;
+};
+
+#endif
diff --git a/smb4k/core/smb4kmounter_p.cpp b/smb4k/core/smb4kmounter_p.cpp
new file mode 100644
index 0000000..96d1149
--- /dev/null
+++ b/smb4k/core/smb4kmounter_p.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ smb4kmounter_p - This is a private helper class for Smb4KMounter.
+ -------------------
+ begin : Do Jul 19 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+// application specific includes
+#include "smb4kmounter_p.h"
+
+Smb4KMounterPrivate::Smb4KMounterPrivate()
+{
+ timerTicks = 0;
+ clearData();
+}
+
+
+Smb4KMounterPrivate::~Smb4KMounterPrivate()
+{
+}
+
+
+void Smb4KMounterPrivate::clearData()
+{
+ m_workgroup = QString::null;
+ m_host = QString::null;
+ m_share = QString::null;
+ m_ip = QString::null;
+ m_path = QString::null;
+ m_filesystem = QString::null;
+ m_cifsLogin = QString::null;
+}
+
+
+const QString &Smb4KMounterPrivate::workgroup()
+{
+ return m_workgroup;
+}
+
+
+const QString &Smb4KMounterPrivate::host()
+{
+ return m_host;
+}
+
+
+const QString &Smb4KMounterPrivate::share()
+{
+ return m_share;
+}
+
+
+const QString &Smb4KMounterPrivate::ip()
+{
+ return m_ip;
+}
+
+
+const QString &Smb4KMounterPrivate::path()
+{
+ return m_path;
+}
+
+
+const QString &Smb4KMounterPrivate::filesystem()
+{
+ return m_filesystem;
+}
+
+
+const QString &Smb4KMounterPrivate::cifsLogin()
+{
+ return m_cifsLogin;
+}
+
+
+void Smb4KMounterPrivate::setWorkgroup( const QString &wg )
+{
+ m_workgroup = wg;
+}
+
+
+void Smb4KMounterPrivate::setHost( const QString &h )
+{
+ m_host = h;
+}
+
+
+void Smb4KMounterPrivate::setShare( const QString &s )
+{
+ m_share = s;
+}
+
+
+void Smb4KMounterPrivate::setIP( const QString &i )
+{
+ m_ip = i;
+}
+
+
+void Smb4KMounterPrivate::setPath( const QString &p )
+{
+ m_path = p;
+}
+
+
+void Smb4KMounterPrivate::setFileSystem( const QString &f )
+{
+ m_filesystem = f;
+}
+
+
+void Smb4KMounterPrivate::setCIFSLogin( const QString &l )
+{
+ m_cifsLogin = l;
+}
diff --git a/smb4k/core/smb4kmounter_p.h b/smb4k/core/smb4kmounter_p.h
new file mode 100644
index 0000000..334ffa3
--- /dev/null
+++ b/smb4k/core/smb4kmounter_p.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ smb4kmounter_p - This is a private helper class for Smb4KMounter.
+ -------------------
+ begin : Do Jul 19 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KMOUNTER_P_H
+#define SMB4KMOUNTER_P_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qthread.h>
+#include <qstring.h>
+
+// KDE includes
+#include <kdebug.h>
+
+// system includes
+#include <sys/statvfs.h>
+
+class Smb4KMounterPrivate
+{
+ public:
+ Smb4KMounterPrivate();
+ ~Smb4KMounterPrivate();
+ int timerTicks;
+
+ class Thread : public QThread
+ {
+ public:
+ Thread() : QThread(), m_mountpoint( QString::null ), m_broken( true ) {}
+ ~Thread() {}
+
+ void setMountpoint( const QString &mp ) { m_mountpoint = mp; }
+
+ virtual void run()
+ {
+ if ( m_mountpoint.isEmpty() )
+ {
+ kdFatal() << "Smb4KMounterPrivate::Thread: No mountpoint specified" << endl;
+ }
+
+ struct statvfs fs;
+
+ if ( statvfs( m_mountpoint.local8Bit(), &fs ) == -1 )
+ {
+ m_broken = true;
+ m_total = -1;
+ m_free = -1;
+ }
+ else
+ {
+ m_broken = false;
+
+ double kB_block = (double)(fs.f_bsize / 1024);
+ double total = (double)(fs.f_blocks*kB_block);
+ double free = (double)(fs.f_bfree*kB_block);
+
+ m_total = total;
+ m_free = free;
+ }
+
+ m_mountpoint = QString::null;
+ }
+
+ bool isBroken() { return m_broken; }
+ double totalDiskSpace() { return m_total; }
+ double freeDiskSpace() { return m_free; }
+
+ private:
+ QString m_mountpoint;
+ bool m_broken;
+ double m_total;
+ double m_free;
+ };
+
+ Thread thread;
+ void clearData();
+ const QString &workgroup();
+ const QString &host();
+ const QString &share();
+ const QString &ip();
+ const QString &path();
+ const QString &filesystem();
+ const QString &cifsLogin();
+ void setWorkgroup ( const QString &wg );
+ void setHost( const QString &h );
+ void setShare( const QString &s );
+ void setIP( const QString &i );
+ void setPath( const QString &p );
+ void setFileSystem( const QString &f );
+ void setCIFSLogin( const QString &l );
+
+ private:
+ QString m_workgroup;
+ QString m_host;
+ QString m_share;
+ QString m_ip;
+ QString m_path;
+ QString m_filesystem;
+ QString m_cifsLogin;
+};
+
+#endif
diff --git a/smb4k/core/smb4knetworkitems.cpp b/smb4k/core/smb4knetworkitems.cpp
new file mode 100644
index 0000000..b278640
--- /dev/null
+++ b/smb4k/core/smb4knetworkitems.cpp
@@ -0,0 +1,239 @@
+/***************************************************************************
+ smb4knetworkitems - Network items used by the Smb4KScanner class
+ to pass and store data.
+ -------------------
+ begin : Mi Jun 2 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <klocale.h>
+#include <ksocketaddress.h>
+
+// application specific includes
+#include "smb4knetworkitems.h"
+
+
+/****************************************************************************
+ Smb4KWorkgroupItem class
+****************************************************************************/
+
+Smb4KWorkgroupItem::Smb4KWorkgroupItem( const QString &name, const QString &master, const QString &masterIP )
+: m_name( name ), m_master( master ), m_pseudo( false )
+{
+ m_ip = ipIsValid( masterIP ) ? masterIP : QString::null;
+}
+
+
+Smb4KWorkgroupItem::~Smb4KWorkgroupItem()
+{
+}
+
+
+void Smb4KWorkgroupItem::setPseudoMaster()
+{
+ m_pseudo = true;
+}
+
+
+void Smb4KWorkgroupItem::setMasterIP( const QString &ip )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+}
+
+
+void Smb4KWorkgroupItem::setMaster( const QString &name, const QString &ip, bool pseudo )
+{
+ m_master = name;
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+ m_pseudo = pseudo;
+}
+
+
+bool Smb4KWorkgroupItem::ipIsValid( const QString &ip )
+{
+ if ( !ip.isEmpty() )
+ {
+ KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( ip );
+
+ if ( !ip_address.isIPv4Addr() && !ip_address.isIPv6Addr() )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/****************************************************************************
+ Smb4KHostItem class
+****************************************************************************/
+
+Smb4KHostItem::Smb4KHostItem( const QString &workgroup, const QString &name, const QString &comment, const QString &ip )
+: m_workgroup( workgroup ), m_name( name ), m_comment( comment ), m_server_string( QString::null ),
+ m_os_string( QString::null ), m_master( false ), m_ip_checked( m_ip.stripWhiteSpace().isEmpty() ? false : true ),
+ m_info_checked( false )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+}
+
+
+Smb4KHostItem::Smb4KHostItem( const Smb4KHostItem &host )
+: m_workgroup( host.workgroup() ), m_name( host.name() ), m_comment( host.comment() ), m_ip( host.ip() ),
+ m_server_string( host.serverString() ), m_os_string( host.osString() ), m_master( host.isMaster() ),
+ m_ip_checked( host.ipAddressChecked() ), m_info_checked( host.infoChecked() )
+{
+ // NOTE: We do not check the IP address here, because that has
+ // already been done by the copied Smb4KHostItem object.
+}
+
+
+Smb4KHostItem::~Smb4KHostItem()
+{
+}
+
+
+void Smb4KHostItem::setServerString( const QString &server )
+{
+ m_server_string = server;
+}
+
+
+void Smb4KHostItem::setOSString( const QString &os )
+{
+ m_os_string = os;
+}
+
+
+void Smb4KHostItem::setMaster( bool master )
+{
+ m_master = master;
+}
+
+
+void Smb4KHostItem::setIPAddress( const QString &ip )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+}
+
+
+void Smb4KHostItem::setComment( const QString &comment )
+{
+ m_comment = comment;
+}
+
+
+void Smb4KHostItem::setIPAddressChecked( bool yes )
+{
+ m_ip_checked = yes;
+}
+
+
+void Smb4KHostItem::setInfoChecked( bool yes )
+{
+ m_info_checked = yes;
+}
+
+
+bool Smb4KHostItem::ipIsValid( const QString &ip )
+{
+ if ( !ip.isEmpty() )
+ {
+ KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( ip );
+
+ if ( !ip_address.isIPv4Addr() && !ip_address.isIPv6Addr() )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/****************************************************************************
+ Smb4KShareItem class
+****************************************************************************/
+
+Smb4KShareItem::Smb4KShareItem( const QString &workgroup, const QString &host, const QString &name, const QString &type, const QString &comment )
+: m_workgroup( workgroup ), m_host( host ), m_name( name ), m_type( type ), m_comment( comment )
+{
+}
+
+
+Smb4KShareItem::~Smb4KShareItem()
+{
+}
+
+
+const QString Smb4KShareItem::translatedType() const
+{
+ QString return_string;
+
+ if ( QString::compare( m_type, "Disk" ) == 0 )
+ {
+ return_string = i18n( "Disk" );
+ }
+ else if ( QString::compare( m_type, "Print" ) == 0 || QString::compare( m_type, "Printer" ) == 0 )
+ {
+ return_string = i18n( "Printer" );
+ }
+ else
+ {
+ return_string = m_type;
+ }
+
+ return return_string;
+}
+
+
+bool Smb4KShareItem::isHidden() const
+{
+ return m_name.stripWhiteSpace().endsWith( "$" );
+}
+
+
+bool Smb4KShareItem::isPrinter() const
+{
+ return (QString::compare( m_type, "Print" ) == 0 || QString::compare( m_type, "Printer" ) == 0);
+}
+
+
+bool Smb4KShareItem::isIPC() const
+{
+ return (QString::compare( m_name.stripWhiteSpace(), "IPC$" ) == 0);
+}
+
+
+bool Smb4KShareItem::isADMIN() const
+{
+ return (QString::compare( m_name.stripWhiteSpace(), "ADMIN$" ) == 0);
+}
+
diff --git a/smb4k/core/smb4knetworkitems.h b/smb4k/core/smb4knetworkitems.h
new file mode 100644
index 0000000..abfff2a
--- /dev/null
+++ b/smb4k/core/smb4knetworkitems.h
@@ -0,0 +1,487 @@
+/***************************************************************************
+ smb4knetworkitems - Network items used by the Smb4KScanner class
+ to pass and store data.
+ -------------------
+ begin : Mi Jun 2 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KNETWORKITEMS_H
+#define SMB4KNETWORKITEMS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qstring.h>
+
+/**
+ * This class provides a container for a workgroup/domain found in the network
+ * neighborhood.
+ */
+
+class Smb4KWorkgroupItem
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param name The name of the workgroup/domain.
+ *
+ * @param master The master browser of the workgroup.
+ *
+ * @param masterIP The IP address of the workgroup master browser.
+ */
+ Smb4KWorkgroupItem( const QString &name,
+ const QString &master,
+ const QString &masterIP = QString::null );
+
+ /**
+ * Empty constructor.
+ */
+ Smb4KWorkgroupItem() {}
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KWorkgroupItem();
+
+ /**
+ * Returns the workgroup name.
+ */
+ const QString &name() const { return m_name; }
+
+ /**
+ * Returns the name of the master browser.
+ */
+ const QString &master() const { return m_master; }
+
+ /**
+ * Returns the IP address of the master browser. If it is not a valid
+ * IPv4 or IPv6 address, QString::null is returned.
+ *
+ * @returns the valid IP v4 or v6 address of the workgroup master browser
+ * or QString::null.
+ */
+ const QString &masterIP() const { return m_ip; }
+
+ /**
+ * You can mark the master as 'pseudo' with this function. That means that
+ * this master was not reported as being the master browser of this
+ * workgroup, but it's the only one found (e.g. by a custom search).
+ */
+ void setPseudoMaster();
+
+ /**
+ * Returns TRUE, if the master is a 'pseudo' master. @see setPseudoMaster()
+ * for further information.
+ */
+ bool hasPseudoMaster() const { return m_pseudo; }
+
+ /**
+ * This function sets the IP address of the master browser.
+ *
+ * @param ip The IP address of the master browser
+ */
+ void setMasterIP( const QString &ip );
+
+ /**
+ * This function sets the master browser.
+ *
+ * @param name The name of the master browser
+ *
+ * @param ip The IP address of the master browser
+ *
+ * @param pseudo Determines if this is a real master browser or if
+ * it is a faked one, i.e. a pseudo master.
+ */
+ void setMaster( const QString &name,
+ const QString &ip,
+ bool pseudo = false );
+
+ private:
+ /**
+ * The name of the workgroup.
+ */
+ QString m_name;
+
+ /**
+ * The name of the workgroup master.
+ */
+ QString m_master;
+
+ /**
+ * The IP address of the master.
+ */
+ QString m_ip;
+
+ /**
+ * Determines whether the master is a 'pseudo'-master.
+ */
+ bool m_pseudo;
+
+ /**
+ * This function checks if the IP address is valid, i.e. the
+ * IP address is either IP v4 or IP v6. It returns either TRUE
+ * or FALSE.
+ *
+ * @param ip The IP address that's going to be checked.
+ *
+ * @returns TRUE if the IP address is valid and FALSE otherwise.
+ */
+ bool ipIsValid( const QString &ip );
+};
+
+
+/**
+ * This class provides a container for a host found in the network
+ * neighborhood.
+ */
+
+class Smb4KHostItem
+{
+ public:
+ /**
+ * The default constructor.
+ *
+ * @param workgroup The workgroup/domain of the host
+ *
+ * @param name The name of the host
+ *
+ * @param comment The comment that describes the host. May be empty.
+ *
+ * @param ip The IP address of the host
+ */
+ Smb4KHostItem( const QString &workgroup,
+ const QString &name,
+ const QString &comment = QString::null,
+ const QString &ip = QString::null );
+
+ /**
+ * The copy constructor.
+ *
+ * @param host A Smb4KHostItem representing a host.
+ */
+ Smb4KHostItem( const Smb4KHostItem &host );
+
+ /**
+ * The empty constructor.
+ */
+ Smb4KHostItem() {}
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KHostItem();
+
+ /**
+ * Returns the workgroup the host is in.
+ */
+ const QString &workgroup() const { return m_workgroup; }
+
+ /**
+ * Returns the name of the host.
+ */
+ const QString &name() const { return m_name; }
+
+ /**
+ * Returns the IP address of the host.
+ */
+ const QString &ip() const { return m_ip; }
+
+ /**
+ * Returns the comment for this host.
+ */
+ const QString &comment() const { return m_comment; }
+
+ /**
+ * Sets the Server string that is reported by the host.
+ */
+ void setServerString( const QString &server );
+
+ /**
+ * Returns the Server string.
+ */
+ const QString &serverString() const { return m_server_string; }
+
+ /**
+ * Sets the OS string that is reported by the host.
+ */
+ void setOSString( const QString &os );
+
+ /**
+ * Returns the OS string.
+ */
+ const QString &osString() const { return m_os_string; }
+
+ /**
+ * This functions determines whether this host should be
+ * registered as a master browser.
+ *
+ * @param master Set this to TRUE if the host is a master browser.
+ */
+ void setMaster( bool master );
+
+ /**
+ * This function tells you if the host is a master or not.
+ *
+ * @returns TRUE if the host is a master browser.
+ */
+ const bool isMaster() const { return m_master; }
+
+ /**
+ * This function sets the IP address of a host.
+ *
+ * @param ip The IP address of a host
+ */
+ void setIPAddress( const QString &ip );
+
+ /**
+ * This function sets the command for a host.
+ *
+ * @param comment The comment
+ */
+ void setComment( const QString &comment );
+
+ /**
+ * This function is used to tell the host item, if a
+ * check for the IP address has already been performed.
+ *
+ * @param yes Should be set to TRUE if a check was performed.
+ */
+ void setIPAddressChecked( bool yes );
+
+ /**
+ * Tells if a check for the IP address has already been performed.
+ *
+ * @returns TRUE if a check was performed, and FALSE otherwise.
+ */
+ const bool ipAddressChecked() const { return m_ip_checked; }
+
+ /**
+ * This function is used to tell the host item, if a
+ * check for the information (OS and Server string ) has already been performed.
+ *
+ * @param yes Should be set to TRUE if a check was performed.
+ */
+ void setInfoChecked( bool yes );
+
+ /**
+ * Tells if a check for the information (OS and Server string) has already
+ * been performed.
+ *
+ * @returns TRUE is the check was performed previously.
+ */
+ const bool infoChecked() const { return m_info_checked; }
+
+ private:
+ /**
+ * The name of the workgroup.
+ */
+ QString m_workgroup;
+
+ /**
+ * The name of the host.
+ */
+ QString m_name;
+
+ /**
+ * The comment for this host.
+ */
+ QString m_comment;
+
+ /**
+ * The IP address of the host.
+ */
+ QString m_ip;
+
+ /**
+ * The Server string as reported by the host.
+ */
+ QString m_server_string;
+
+ /**
+ * The operating system string as reported by the host.
+ */
+ QString m_os_string;
+
+ /**
+ * This boolian determines if the host is a master browser
+ * or not.
+ */
+ bool m_master;
+
+ /**
+ * This boolean tells if a check for the IP address was already
+ * performed.
+ */
+ bool m_ip_checked;
+
+ /**
+ * This boolean tells if a check for the information (OS and server string)
+ * was already performed.
+ */
+ bool m_info_checked;
+
+ /**
+ * This function checks if the IP address is valid, i.e. the
+ * IP address is either IP v4 or IP v6. It returns either TRUE
+ * or FALSE.
+ *
+ * @param ip The IP address that's going to be checked.
+ *
+ * @returns TRUE if the IP address is valid and FALSE otherwise.
+ */
+ bool ipIsValid( const QString &ip );
+};
+
+
+/**
+ * This class provides a container for a share found in the
+ * network neighborhood.
+ */
+
+class Smb4KShareItem
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param workgroup The workgroup/domain name.
+ *
+ * @param host The name of the host where the share is located.
+ *
+ * @param name The name of the share.
+ *
+ * @param type The type of the share as returned by the Samba programs, i.e.
+ * "Disk", "Printer", "IPC$" or "ADMIN$".
+ *
+ * @param comment The comment of the share.
+ */
+ Smb4KShareItem( const QString &workgroup,
+ const QString &host,
+ const QString &name,
+ const QString &type,
+ const QString &comment );
+
+ /**
+ * Empty constructor.
+ */
+ Smb4KShareItem() {}
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KShareItem();
+
+ /**
+ * Returns the workgroup of the host where the share is located.
+ */
+ const QString &workgroup() const { return m_workgroup; }
+
+ /**
+ * Returns the name of the host where the share is located.
+ */
+ const QString &host() const { return m_host; }
+
+ /**
+ * Returns the name of the share.
+ */
+ const QString &name() const { return m_name; }
+
+ /**
+ * Returns the type of the share.
+ */
+ const QString &plainType() const { return m_type; }
+
+ /**
+ * Returns a translated version of the type of the share.
+ *
+ * @returns The translated share type
+ */
+ const QString translatedType() const;
+
+ /**
+ * Returns the comment for this share.
+ */
+ const QString &comment() const { return m_comment; }
+
+ /**
+ * This function tells if the share is a hidden one.
+ *
+ * @returns TRUE is the share is a hidden one and FALSE otherwise.
+ */
+ bool isHidden() const;
+
+ /**
+ * This function is TRUE if the share is a printer and
+ * FALSE otherwise.
+ *
+ * @returns TRUE if the share is a printer
+ */
+ bool isPrinter() const;
+
+ /**
+ * This function returns TRUE if the share is an IPC$
+ * share and FALSE otherwise.
+ *
+ * @returns TRUE if the share is an IPC$ share
+ */
+ bool isIPC() const;
+
+ /**
+ * This function returns TRUE if the share is an ADMIN$
+ * share and FALSE otherwise.
+ *
+ * @returns TRUE if the share is an ADMIN$ share
+ */
+ bool isADMIN() const;
+
+ private:
+ /**
+ * The workgroup object.
+ */
+ QString m_workgroup;
+
+ /**
+ * The host name.
+ */
+ QString m_host;
+
+ /**
+ * The name of the share.
+ */
+ QString m_name;
+
+ /**
+ * The type of the share.
+ */
+ QString m_type;
+
+ /**
+ * The comment for this share.
+ */
+ QString m_comment;
+};
+
+#endif
diff --git a/smb4k/core/smb4kpasswordhandler.cpp b/smb4k/core/smb4kpasswordhandler.cpp
new file mode 100644
index 0000000..0eb896b
--- /dev/null
+++ b/smb4k/core/smb4kpasswordhandler.cpp
@@ -0,0 +1,1001 @@
+/***************************************************************************
+ smb4kpasswordhandler - This class handles the passwords for Smb4K.
+ -------------------
+ begin : So Jan 16 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+// Qt includes
+#include <qframe.h>
+#include <qlayout.h>
+#include <qstring.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qstringlist.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#endif
+
+// application specific includes
+#include "smb4kpasswordhandler.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kauthinfo.h"
+#include "smb4ksettings.h"
+
+
+#ifndef __FreeBSD__
+Smb4KPasswordHandler::Smb4KPasswordHandler( Smb4KHomesSharesHandler *handler, QObject *parent, const char *name )
+: QObject( parent, name ), m_handler( handler ), m_wallet_support_disabled( false )
+#else
+Smb4KPasswordHandler::Smb4KPasswordHandler( Smb4KHomesSharesHandler *s_handler, Smb4KSambaOptionsHandler *o_handler, QObject *parent, const char *name )
+: QObject( parent, name ), m_handler( s_handler ), m_options_handler( o_handler ),
+ m_wallet_support_disabled( false )
+#endif
+{
+ if ( !m_handler )
+ {
+ kdFatal() << "Smb4KPasswordHandler: No Smb4KHomesSharesHandler object" << endl;
+ }
+
+#ifdef __FreeBSD__
+ if ( !m_options_handler )
+ {
+ kdFatal() << "Smb4KPasswordHandler: No Smb4KSambaOptionsHandler object" << endl;
+ }
+#endif
+
+ m_auth = NULL;
+ m_dlg = NULL;
+ m_wallet = NULL;
+ m_temp_auth = NULL;
+}
+
+
+Smb4KPasswordHandler::~Smb4KPasswordHandler()
+{
+ for ( QValueList<Smb4KAuthInfo *>::Iterator it = m_auth_list.begin(); it != m_auth_list.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_auth_list.clear();
+
+ delete m_wallet;
+}
+
+
+void Smb4KPasswordHandler::open_close_wallet()
+{
+ if ( Smb4KSettings::useWallet() && !walletSupportIsDisabled() )
+ {
+ if ( !walletIsOpen() )
+ {
+ // Start the wallet manager before accessing the wallet. We
+ // do not care about the return value, because we do not do
+ // error handling here.
+ if ( kapp )
+ {
+ (void) kapp->kdeinitExec( "kwalletmanager" );
+ }
+ else
+ {
+ // Do nothing. --- Good luck!
+ }
+
+ m_wallet = KWallet::Wallet::openWallet( KWallet::Wallet::NetworkWallet(), 0, KWallet::Wallet::Synchronous );
+
+ if ( m_wallet )
+ {
+ if ( !m_wallet->hasFolder( "Smb4K" ) )
+ {
+ m_wallet->createFolder( "Smb4K" );
+ m_wallet->setFolder( "Smb4K" );
+ }
+ else
+ {
+ m_wallet->setFolder( "Smb4K" );
+
+ convert_old_entries();
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_OPENING_WALLET_FAILED, KWallet::Wallet::NetworkWallet(), QString::null );
+
+ delete m_wallet;
+ m_wallet = NULL;
+
+ m_wallet_support_disabled = true;
+ }
+ }
+ else
+ {
+ convert_old_entries();
+ }
+ }
+ else
+ {
+ if ( m_wallet )
+ {
+ delete m_wallet;
+ m_wallet = NULL;
+ }
+ }
+}
+
+
+void Smb4KPasswordHandler::convert_old_entries()
+{
+ // Convert old entries (Smb4K 0.9.2 and earlier) to the
+ // new map based format.
+ if ( !m_wallet->entryList().isEmpty() )
+ {
+ QStringList entries = m_wallet->entryList();
+
+ // Since in the old format the keys contained a string like
+ // this: HOST:USER, we only need to test whether the first
+ // key contains a ":". If that's the case, we need to convert
+ // the entries, otherwise we don't.
+ if ( entries.first().contains( ":" ) != 0 )
+ {
+ for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it )
+ {
+ // Get the password.
+ QString pass;
+ m_wallet->readPassword( *it, pass );
+
+ if ( (*it).startsWith( "DEFAULT:" ) )
+ {
+ // Convert the data to the new format.
+ QMap<QString,QString> map;
+ map["Login"] = (*it).section( ":", 1, 1 );
+ map["Password"] = pass;
+
+ m_wallet->writeMap( "DEFAULT_LOGIN", map );
+ }
+ else
+ {
+ // Convert the data to the new format.
+ QMap<QString,QString> map;
+ map["Login"] = (*it).section( ":", 3, 3 );
+ map["Password"] = pass;
+
+ if ( QString::compare( (*it).section( ":", 0, 0 ), "*" ) != 0 )
+ {
+ map["Workgroup"] = (*it).section( ":", 0, 0 ).upper();
+ }
+
+ if ( QString::compare( (*it).section( ":", 2, 2 ), "*" ) == 0 )
+ {
+ m_wallet->writeMap( (*it).section( ":", 1, 1 ).upper(), map );
+ }
+ else
+ {
+ m_wallet->writeMap( "//"+(*it).section( ":", 1, 1 ).upper()+
+ "/"+(*it).section( ":", 2, 2 ).upper(), map );
+ }
+ }
+
+ // Delete the old entry.
+ m_wallet->removeEntry( *it );
+ }
+ }
+ else
+ {
+ // Do nothing.
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+bool Smb4KPasswordHandler::askpass( const QString &workgroup, const QString &host, const QString &share, int desc, QWidget *parent, const char *name )
+{
+ // m_auth is NULL:
+ m_auth = readAuth( new Smb4KAuthInfo( workgroup, host, share ) );
+
+ // Set up the askpass dialog:
+ m_dlg = new KDialogBase( KDialogBase::Plain, i18n( "Authentication" ), KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok, parent, name, true, true );
+
+ QFrame *frame = m_dlg->plainPage();
+ QGridLayout *layout = new QGridLayout( frame );
+ layout->setSpacing( 5 );
+ layout->setMargin( 0 );
+
+ QLabel *pixmap_label = new QLabel( frame );
+ pixmap_label->setPixmap( DesktopIcon( "identity" ) );
+ pixmap_label->adjustSize();
+
+ layout->addWidget( pixmap_label, 0, 0, Qt::AlignCenter );
+
+ QString message;
+
+ switch ( desc )
+ {
+ case NewData:
+ break;
+ case AccessDenied:
+ message = i18n( "The access was denied. " );
+ break;
+ case BadPassword:
+ message = i18n( "The password is not correct. " );
+ break;
+ case PermDenied:
+ message = i18n( "The permission was denied. " );
+ break;
+ case AuthError:
+ message = i18n( "An authentication error occurred. " );
+ break;
+ case LogonFailure:
+ message = i18n( "The logon failed. " );
+ break;
+ default:
+ break;
+ }
+
+ if ( m_auth->share().stripWhiteSpace().isEmpty() )
+ {
+ message.append( i18n( "Please enter authentication data for server %1." ).arg( m_auth->host() ) );
+ }
+ else
+ {
+ message.append( i18n( "Please enter authentication data for share %1." ).arg( "//"+m_auth->host()+"/"+m_auth->share() ) );
+ }
+
+ QLabel *message_label = new QLabel( frame );
+ message_label->setText( message.stripWhiteSpace() );
+ message_label->setTextFormat( Qt::RichText );
+
+ layout->addWidget( message_label, 0, 1, 0 );
+
+ QLabel *user_label = new QLabel( i18n( "User:" ), frame );
+ layout->addWidget( user_label, 1, 0, 0 );
+
+ KLineEdit *user_edit = NULL;
+ KComboBox *user_combo = NULL;
+
+ if ( QString::compare( m_auth->share(), "homes" ) != 0 )
+ {
+ user_edit = new KLineEdit( frame, "AskPassUserEdit" );
+ user_edit->setMinimumWidth( 200 );
+ layout->addWidget( user_edit, 1, 1, 0 );
+ }
+ else
+ {
+ user_combo = new KComboBox( frame, "AskPassUserCombo" );
+ user_combo->setEditable( true );
+ user_combo->setMinimumWidth( 200 );
+ layout->addWidget( user_combo, 1, 1, 0 );
+ }
+
+ QLabel *password_label = new QLabel( i18n( "Password:" ), frame );
+ layout->addWidget( password_label, 2, 0, 0 );
+
+ KLineEdit *pass_edit = new KLineEdit( frame, "AskPassPasswordEdit" );
+ pass_edit->setEchoMode( KLineEdit::Password );
+ layout->addWidget( pass_edit, 2, 1, 0 );
+
+ m_dlg->setMainWidget( frame );
+ m_dlg->setFixedSize( 350, m_dlg->sizeHint().height() );
+ m_dlg->enableButtonOK( false );
+
+ // Since we have to allow empty passwords, we will only connect
+ // the edit line for the user to enable/disable the OK button.
+ if ( user_edit )
+ {
+ connect( user_edit, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotEnableOKButton( const QString& ) ) );
+ }
+ else
+ {
+ connect( user_combo, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotEnableOKButton( const QString& ) ) );
+ }
+
+ // Process the authentication data:
+
+ if ( QString::compare( share, "homes" ) != 0 )
+ {
+ user_edit->setText( m_auth->user() );
+ pass_edit->setText( m_auth->password() );
+
+ if ( m_auth->user().isEmpty() )
+ {
+ user_edit->setFocus();
+ }
+ else
+ {
+ pass_edit->setFocus();
+ }
+ }
+ else
+ {
+ QStringList list = m_handler->homesUsers( host );
+
+ user_combo->insertStringList( list );
+ user_combo->setCurrentText( QString::null );
+
+ connect( user_combo, SIGNAL( activated( const QString & ) ),
+ this, SLOT( slotGetPassword( const QString & ) ) );
+
+ user_combo->setFocus();
+ }
+
+ bool ok = false;
+
+ if ( m_dlg->exec() == KDialogBase::Accepted )
+ {
+ if ( QString::compare( share, "homes" ) != 0 )
+ {
+ QString user = user_edit->text();
+ QString pass = pass_edit->text();
+
+ m_auth->setUser( user );
+ m_auth->setPassword( pass );
+
+ writeAuth( m_auth );
+ }
+ else
+ {
+ QString user = user_combo->currentText();
+ QString pass = pass_edit->text();
+
+ m_auth->setUser( user );
+ m_auth->setPassword( pass );
+
+ writeAuth( m_auth );
+ }
+
+ ok = true;
+ }
+
+ // Clean up:
+
+ delete m_dlg;
+ m_dlg = NULL;
+
+ delete m_auth;
+ m_auth = NULL;
+
+ return ok;
+}
+
+
+Smb4KAuthInfo *Smb4KPasswordHandler::readAuth( Smb4KAuthInfo *authInfo )
+{
+ // Do nothing, if authInfo is NULL:
+ if ( !authInfo )
+ {
+ return authInfo;
+ }
+
+ open_close_wallet();
+
+ if ( walletIsOpen() )
+ {
+ // Get the authentication information from the wallet.
+ // Always prefer either the exact match or the information
+ // that was provided for the host.
+ QMap<QString,QString> map;
+
+ if ( !authInfo->share().isEmpty() )
+ {
+ m_wallet->readMap( "//"+authInfo->host().upper()+"/"+authInfo->share().upper(), map );
+
+ if ( map.isEmpty() )
+ {
+ m_wallet->readMap( authInfo->host().upper(), map );
+
+ if ( map.isEmpty() )
+ {
+ if ( Smb4KSettings::useDefaultLogin() )
+ {
+ m_wallet->readMap( "DEFAULT_LOGIN", map );
+
+ if ( map.isEmpty() )
+ {
+ return authInfo;
+ }
+ else
+ {
+ // We have authentication information.
+ // So, do nothing here.
+ }
+ }
+ else
+ {
+ return authInfo;
+ }
+ }
+ else
+ {
+ // Check that the workgroup is correct.
+ if ( map.contains( "Workgroup" ) && !authInfo->workgroup().isEmpty() )
+ {
+ if ( QString::compare( map["Workgroup"].upper(), authInfo->workgroup().upper() ) != 0 )
+ {
+ return authInfo;
+ }
+ else
+ {
+ // Everything is OK. Do nothing.
+ }
+ }
+ else
+ {
+ // We cannot check if the workgroup is OK. So, just return
+ // the authentication information we just collected. If it
+ // should be wrong, the user will be asked to provide the
+ // correct data anyway.
+ }
+ }
+ }
+ else
+ {
+ // Check that the workgroup is correct.
+ if ( map.contains( "Workgroup" ) && !authInfo->workgroup().isEmpty() )
+ {
+ if ( QString::compare( map["Workgroup"].upper(), authInfo->workgroup().upper() ) != 0 )
+ {
+ return authInfo;
+ }
+ else
+ {
+ // Everything is OK. Do nothing.
+ }
+ }
+ else
+ {
+ // We cannot check if the workgroup is OK. So, just process
+ // the authentication information we just collected. If it
+ // should be wrong, the user will be asked to provide the
+ // correct data anyway.
+ }
+ }
+ }
+ else
+ {
+ m_wallet->readMap( authInfo->host().upper(), map );
+
+ if ( map.isEmpty() )
+ {
+ if ( Smb4KSettings::useDefaultLogin() )
+ {
+ m_wallet->readMap( "DEFAULT_LOGIN", map );
+
+ if ( map.isEmpty() )
+ {
+ return authInfo;
+ }
+ }
+ else
+ {
+ return authInfo;
+ }
+ }
+ else
+ {
+ // Check that the workgroup is correct.
+ if ( map.contains( "Workgroup" ) && !authInfo->workgroup().isEmpty() )
+ {
+ if ( QString::compare( map["Workgroup"].upper(), authInfo->workgroup().upper() ) != 0 )
+ {
+ return authInfo;
+ }
+ else
+ {
+ // Everything is OK. Do nothing.
+ }
+ }
+ else
+ {
+ // We cannot check if the workgroup is OK. So, just process
+ // the authentication information we just collected. If it
+ // should be wrong, the user will be asked to provide the
+ // correct data anyway.
+ }
+ }
+ }
+
+ // We have authentication information. Put the data into the
+ // Smb4KAuthInfo object.
+ authInfo->setUser( map["Login"] );
+ authInfo->setPassword( map["Password"] );
+ }
+ else
+ {
+ // Either the opening of the wallet failed or the user does
+ // not want to use a wallet.
+ // Let's see if we can get the authentication information from
+ // the temporary list.
+ if ( Smb4KSettings::rememberPasswords() )
+ {
+ if ( !m_auth_list.isEmpty() )
+ {
+ for ( QValueList<Smb4KAuthInfo *>::Iterator it = m_auth_list.begin(); it != m_auth_list.end(); ++it )
+ {
+ if ( !authInfo->share().isEmpty() )
+ {
+ if ( QString::compare( authInfo->host().upper(), (*it)->host().upper() ) == 0 &&
+ QString::compare( authInfo->share().upper(), (*it)->share().upper() ) == 0 )
+ {
+ if ( QString::compare( authInfo->workgroup().upper(), (*it)->workgroup().upper() ) == 0 ||
+ (*it)->workgroup().isEmpty() )
+ {
+ // Either the workgroup is OK, or we cannot check if it is OK.
+ // In both cases we process the data at hand.
+ authInfo->setUser( (*it)->user() );
+ authInfo->setPassword( (*it)->password() );
+
+ // Exact match. Stop here.
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else if ( QString::compare( authInfo->host().upper(), (*it)->host().upper() ) == 0 )
+ {
+ if ( QString::compare( authInfo->workgroup().upper(), (*it)->workgroup().upper() ) == 0 ||
+ (*it)->workgroup().isEmpty() )
+ {
+ // Either the workgroup is OK, or we cannot check if it is OK.
+ // In both cases we process the data at hand.
+ authInfo->setUser( (*it)->user() );
+ authInfo->setPassword( (*it)->password() );
+
+ // Because we always prefer the exact match, we keep
+ // on searching.
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ if ( QString::compare( authInfo->host().upper(), (*it)->host().upper() ) == 0 )
+ {
+ if ( QString::compare( authInfo->workgroup().upper(), (*it)->workgroup().upper() ) == 0 ||
+ (*it)->workgroup().isEmpty() )
+ {
+ // Either the workgroup is OK, or we cannot check if it is OK.
+ // In both cases we process the data at hand.
+ authInfo->setUser( (*it)->user() );
+ authInfo->setPassword( (*it)->password() );
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ if ( m_temp_auth )
+ {
+ authInfo->setUser( m_temp_auth->user() );
+ authInfo->setPassword( m_temp_auth->password() );
+
+ delete m_temp_auth;
+ m_temp_auth = NULL;
+ }
+ }
+ }
+
+#ifdef __FreeBSD__
+
+ writeToSMBConfFile( authInfo );
+
+#endif
+
+ return authInfo;
+}
+
+
+void Smb4KPasswordHandler::writeAuth( Smb4KAuthInfo *authInfo )
+{
+ open_close_wallet();
+
+ if ( walletIsOpen() )
+ {
+ QMap<QString,QString> map;
+ map["Login"] = authInfo->user();
+ map["Password"] = authInfo->password();
+
+ if ( !authInfo->workgroup().isEmpty() )
+ {
+ map["Workgroup"] = authInfo->workgroup().upper();
+ }
+
+ if ( !authInfo->share().isEmpty() )
+ {
+ m_wallet->writeMap( "//"+authInfo->host().upper()+"/"+authInfo->share().upper(), map );
+ }
+ else
+ {
+ m_wallet->writeMap( authInfo->host().upper(), map );
+ }
+
+ m_wallet->sync();
+ }
+ else
+ {
+ if ( Smb4KSettings::rememberPasswords() )
+ {
+ Smb4KAuthInfo *tmp = NULL;
+
+ for ( QValueList<Smb4KAuthInfo *>::Iterator it = m_auth_list.begin(); it != m_auth_list.end(); ++it )
+ {
+ if ( ((*it)->workgroup().isEmpty() ||
+ QString::compare( (*it)->workgroup().upper(), authInfo->workgroup().upper() ) == 0) &&
+ QString::compare( (*it)->host().upper(), authInfo->host().upper() ) == 0 &&
+ QString::compare( (*it)->host().upper(), authInfo->share().upper() ) == 0 )
+ {
+ tmp = *it;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( tmp )
+ {
+ delete tmp;
+ }
+
+ m_auth_list.append( new Smb4KAuthInfo( *authInfo ) );
+ }
+ else
+ {
+ if ( !m_temp_auth )
+ {
+ m_temp_auth = new Smb4KAuthInfo( *authInfo );
+ }
+ }
+ }
+
+#ifdef __FreeBSD__
+
+ writeToSMBConfFile( authInfo );
+
+#endif
+}
+
+
+Smb4KAuthInfo *Smb4KPasswordHandler::readDefaultAuth( Smb4KAuthInfo *authInfo )
+{
+ if ( !authInfo )
+ {
+ return authInfo;
+ }
+
+ open_close_wallet();
+
+ if ( walletIsOpen() )
+ {
+ // Read the default authentication information.
+ QMap<QString,QString> map;
+
+ m_wallet->readMap( "DEFAULT_LOGIN", map );
+
+ if ( !map.isEmpty() )
+ {
+ authInfo->setUser( map["Login"] );
+ authInfo->setPassword( map["Password"] );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ // Nothing to do.
+ }
+
+ return authInfo;
+}
+
+
+void Smb4KPasswordHandler::writeDefaultAuth( Smb4KAuthInfo *authInfo )
+{
+ open_close_wallet();
+
+ if ( walletIsOpen() )
+ {
+ QMap<QString,QString> map;
+ map["Login"] = authInfo->user();
+ map["Password"] = authInfo->password();
+
+ m_wallet->writeMap( "DEFAULT_LOGIN", map );
+ m_wallet->sync();
+ }
+}
+
+
+#ifdef __FreeBSD__
+
+void Smb4KPasswordHandler::writeToSMBConfFile( Smb4KAuthInfo *authInfo )
+{
+ m_nsmbrc_auth = *authInfo;
+
+ KProcess *p = new KProcess();
+ p->setUseShell( true );
+
+ connect( p, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivePassword( KProcess *, char *, int ) ) );
+ connect( p, SIGNAL( processExited( KProcess * ) ),
+ this, SLOT( slotWritePassword( KProcess * ) ) );
+
+ *p << QString( "smbutil crypt %1" ).arg( m_nsmbrc_auth.password() );
+
+ p->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+
+void Smb4KPasswordHandler::slotGetPassword( const QString &username )
+{
+ if ( m_dlg && m_auth )
+ {
+ // We need to re-read the auth data here, because
+ // of the homes shares:
+ Smb4KAuthInfo *auth = readAuth( new Smb4KAuthInfo( m_auth->workgroup().upper(), m_auth->host().upper(), username ) );
+
+ KLineEdit *lineEdit = static_cast<KLineEdit *>( m_dlg->child( "AskPassPasswordEdit", "KLineEdit", true ) );
+ lineEdit->setText( auth->password() );
+
+ delete auth;
+
+ m_auth->setShare( username );
+ }
+}
+
+
+void Smb4KPasswordHandler::slotEnableOKButton( const QString &text )
+{
+ if ( m_dlg )
+ {
+ m_dlg->enableButtonOK( !text.isEmpty() );
+ }
+}
+
+#ifdef __FreeBSD__
+void Smb4KPasswordHandler::slotReceivePassword( KProcess *, char *buffer, int buflen )
+{
+ m_buffer.append( QString::fromLocal8Bit( buffer, buflen ) );
+#else
+void Smb4KPasswordHandler::slotReceivePassword( KProcess *, char *, int )
+{
+#endif
+}
+
+
+void Smb4KPasswordHandler::slotWritePassword( KProcess *proc )
+{
+
+ delete proc;
+
+#ifdef __FreeBSD__
+
+ QString pass = m_buffer.remove( "\n" ).stripWhiteSpace();
+ m_buffer = QString::null;
+
+ QDir::setCurrent( QDir::homeDirPath() );
+
+ QFile file( ".nsmbrc" );
+
+ QStringList contents;
+
+ if ( file.exists() )
+ {
+ if ( file.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ while ( !ts.atEnd() )
+ {
+ contents.append( ts.readLine().stripWhiteSpace() );
+ }
+
+ file.close();
+ }
+ }
+
+ // Check if the [default] section is present.
+ if ( contents.find( "[default]" ) == contents.end() &&
+ contents.find( "[DEFAULT]" ) == contents.end() )
+ {
+ QMap<QString,QString> map = m_options_handler->globalSambaOptions();
+ QString workgroup = map["workgroup"];
+ QString wins = m_options_handler->winsServer();
+
+ QStringList::Iterator it = contents.prepend( "[default]" );
+ it++;
+
+ if ( !workgroup.isEmpty() )
+ {
+ it = contents.insert( it, "workgroup="+workgroup );
+ }
+
+ if ( !wins.isEmpty() )
+ {
+ it = contents.insert( it, "nbns="+wins );
+ }
+
+ // FIXME: Should we write the charsets here, too??
+ }
+
+ QString section;
+
+ if ( m_nsmbrc_auth.share().isEmpty() )
+ {
+ section.append( QString( "[%1:%2]" ).arg( m_nsmbrc_auth.host().upper(), m_nsmbrc_auth.user().isEmpty() ? "GUEST" : m_nsmbrc_auth.user().upper() ) );
+ }
+ else
+ {
+ section.append( QString( "[%1:%2:%3]" ).arg( m_nsmbrc_auth.host().upper(), m_nsmbrc_auth.user().isEmpty() ? "GUEST" : m_nsmbrc_auth.user().upper(), m_nsmbrc_auth.share().upper() ) );
+ }
+
+ QStringList::Iterator it = contents.find( section );
+
+ if ( it == contents.end() )
+ {
+ if ( contents.last() != QString::null )
+ {
+ contents.append( QString::null );
+ }
+
+ contents.append( section );
+ contents.append( "password="+pass );
+
+ if ( !m_nsmbrc_auth.workgroup().isEmpty() )
+ {
+ contents.append( "workgroup="+m_nsmbrc_auth.workgroup() );
+ }
+ }
+ else
+ {
+ for ( QStringList::Iterator i = ++it; i != contents.end(); ++i )
+ {
+ if ( (*i).contains( "password=" ) )
+ {
+ QString old_pass = (*i).section( "password=", 1, 1 ).stripWhiteSpace();
+
+ if ( QString::compare( pass, old_pass ) == 0 )
+ {
+ // The passwords are identical, so stop here.
+ return;
+ }
+ else
+ {
+ *i = "password="+pass;
+ break;
+ }
+ }
+ else if ( (*i).startsWith( "[" ) )
+ {
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ QDir::setCurrent( QDir::homeDirPath() );
+
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ for ( QStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
+ {
+ ts << *it << endl;
+ }
+
+ file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, "~/.nsmbrc", QString::null );
+
+ return;
+ }
+
+ // Get minimal security: Fix permissions.
+ QString path = QDir::homeDirPath()+"/"+file.name();
+
+ int fd;
+
+ if ( (fd = open( path.ascii(), O_WRONLY )) == -1 )
+ {
+ int err_no = errno;
+ Smb4KError::error( ERROR_OPENING_FILE, path, strerror( err_no ) );
+
+ return;
+ }
+ else
+ {
+ if ( fchmod( fd, 00600 ) == -1 )
+ {
+ // FIXME: Do we need to emit an error here at all?
+ }
+ }
+#endif
+}
+
+#include "smb4kpasswordhandler.moc"
diff --git a/smb4k/core/smb4kpasswordhandler.h b/smb4k/core/smb4kpasswordhandler.h
new file mode 100644
index 0000000..513f399
--- /dev/null
+++ b/smb4k/core/smb4kpasswordhandler.h
@@ -0,0 +1,305 @@
+/***************************************************************************
+ smb4kpasswordhandler - This class handles the passwords for Smb4K.
+ -------------------
+ begin : So Jan 16 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPASSWORDHANDLER_H
+#define SMB4KPASSWORDHANDLER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qcheckbox.h>
+
+// KDE includes
+#include <kwallet.h>
+#include <kdialogbase.h>
+#include <kprocess.h>
+
+// forward declarations
+#ifndef __FreeBSD__
+class Smb4KAuthInfo;
+#endif
+
+// application specific includes
+#include "smb4khomesshareshandler.h"
+#ifdef __FreeBSD__
+#include "smb4ksambaoptionshandler.h"
+#include "smb4kauthinfo.h"
+#endif
+
+
+
+/**
+ * This class handles the passwords used by Smb4K to authenticate to
+ * the network shares.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KPasswordHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+#ifndef __FreeBSD__
+ /**
+ * The constructor.
+ *
+ * @param config The KConfig object that should be used
+ *
+ * @param handler The Smb4KHomesSharesHandler object that is needed to retrieve
+ * infos in case we need to look up authentication information for
+ * 'homes' shares.
+ *
+ * @param parent The parent object.
+ *
+ * @param name The name this class should carry.
+ */
+ Smb4KPasswordHandler( Smb4KHomesSharesHandler *handler,
+ QObject *parent = 0,
+ const char *name = 0 );
+#else
+ /**
+ * The constructor (FreeBSD).
+ *
+ * @param s_handler The Smb4KHomesSharesHandler object that is needed to retrieve
+ * infos in case we need to look up authentication information for
+ * 'homes' shares.
+ *
+ * @param o_handler The Smb4KSambaOptionsHandler object. It is needed to write the
+ * ~/.nsmbrc file correctly.
+ *
+ * @param parent The parent object.
+ *
+ * @param name The name this class should carry.
+ */
+ Smb4KPasswordHandler( Smb4KHomesSharesHandler *s_handler,
+ Smb4KSambaOptionsHandler *o_handler,
+ QObject *parent = 0,
+ const char *name = 0 );
+#endif
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KPasswordHandler();
+
+ /**
+ * Opens the askpass dialog.
+ *
+ * @param workgroup The workgroup where the share is located in (may be empty).
+ *
+ * @param host The host the share belongs to.
+ *
+ * @param name The name of the share.
+ *
+ * @param desc Determines which descriptive label the askpass dialog should carry.
+ * Values are taken from the Smb4KPasswordHandler::AskPass::Description
+ * enumeration.
+ *
+ * @param parent The parent of this dialog.
+ *
+ * @param name The name of this dialog.
+ *
+ * @returns TRUE if a new password has been supplied and FALSE otherwise.
+ */
+ bool askpass( const QString &workgroup, const QString &host, const QString &share, int desc, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * Returns the authentication data that was found for the defined share. You need to
+ * provide the workgroup, host name, and share name with @p authInfo.
+ *
+ * @param authInfo The authentication information object.
+ *
+ * @returns a pointer to @p authInfo. This may be NULL if @p authInfo was
+ * also NULL.
+ */
+ Smb4KAuthInfo *readAuth( Smb4KAuthInfo *authInfo );
+
+ /**
+ * Write the provided authentication data to the wallet.
+ *
+ * @param authInfo The Smb4KAuthInfo object that holds the authentication information.
+ */
+ void writeAuth( Smb4KAuthInfo *authInfo );
+
+ /**
+ * Read the default authentication from the wallet.
+ *
+ * @param authInfo The authentication information object.
+ *
+ * @returns pointer to the authentication data object if a wallet is used or NULL otherwise
+ */
+ Smb4KAuthInfo *readDefaultAuth( Smb4KAuthInfo *authInfo );
+
+ /**
+ * Writes the default authentication data to the wallet. This function seems only to
+ * be useful for the configuration dialog.
+ *
+ * @param authInfo The authentication data for the default login if a wallet is
+ * used or NULL otherwise.
+ */
+ void writeDefaultAuth( Smb4KAuthInfo *authInfo );
+
+ /**
+ * This enumeration destermines which destriptive label the askpass
+ * dialog should carry.
+ */
+ enum Description{ NewData, AccessDenied, BadPassword, PermDenied, AuthError, LogonFailure, None };
+
+ /**
+ * This function returns TRUE if the wallet it open at the moment and FALSE
+ * if it is closed or not used.
+ *
+ * @returns TRUE if the wallet is open.
+ */
+ bool walletIsOpen() { return (m_wallet && m_wallet->isOpen()); }
+
+ /**
+ * This function returns TRUE if the digital wallet support has been
+ * disabled. This happens when the wallet could not be opened.
+ *
+ * @returns TRUE if the digital wallet support has been disabled.
+ */
+ bool walletSupportIsDisabled() { return m_wallet_support_disabled; }
+
+ protected slots:
+ /**
+ * Get the password for a specific share and user name.
+ */
+ void slotGetPassword( const QString &username );
+
+ /**
+ * This slot is used to enable the OK button of the askpass
+ * dialog when text has been entered in the text boxes and/or the
+ * combo box.
+ *
+ * @param text The text that has been entered.
+ */
+ void slotEnableOKButton( const QString &text );
+
+ /**
+ * FreeBSD specific: This slot receives output from the process that encrypts
+ * the passwords.
+ *
+ * @param proc The process that sends the output
+ *
+ * @param buffer The buffer that contains the output
+ *
+ * @param buflen The length of the buffer
+ */
+ void slotReceivePassword( KProcess *proc, char *buffer, int buflen );
+
+ /**
+ * FreeBSD specific: This slot is invoked if the process exited.
+ *
+ * @param proc The process that exited
+ */
+ void slotWritePassword( KProcess *proc );
+
+ private:
+ /**
+ * This function opens the wallet in which the passwords should be
+ * stored.
+ */
+ void open_close_wallet();
+
+ /**
+ * This function is used to convert old wallet entries to the new
+ * map based ones.
+ */
+ void convert_old_entries();
+
+ /**
+ * The KWallet object.
+ */
+ KWallet::Wallet *m_wallet;
+
+ /**
+ * The Smb4KAuthInfo object. For use with the askpass dialog.
+ */
+ Smb4KAuthInfo *m_auth;
+
+ /**
+ * The askpass dialog.
+ */
+ KDialogBase *m_dlg;
+
+ /**
+ * This list holds the authentication data the user supplied if he/she
+ * does not want to use KWallet.
+ */
+ QValueList<Smb4KAuthInfo *> m_auth_list;
+
+ /**
+ * If the user neither wants to store the passwords in a wallet nor in a
+ * temporary list, the authentication data received from the askpass dialog
+ * will the stored in this object.
+ */
+ Smb4KAuthInfo *m_temp_auth;
+
+ /**
+ * The Smb4KHomesSharesHandler object
+ */
+ Smb4KHomesSharesHandler *m_handler;
+
+ /**
+ * Is the wallet support disabled?
+ */
+ bool m_wallet_support_disabled;
+
+#ifdef __FreeBSD__
+
+ /**
+ * FreeBSD specific: This function writes authentication information
+ * to the ~/.nsmbrc file, which is used by mount_smbfs.
+ *
+ * @param authInfo The authentication information that should be written
+ * to ~/.nsmbrc file.
+ */
+ void writeToSMBConfFile( Smb4KAuthInfo *authInfo );
+
+ /**
+ * FreeBSD specific: Holds the authentication information that should
+ * be written to ~/.nsmbrc.
+ */
+ Smb4KAuthInfo m_nsmbrc_auth;
+
+ /**
+ * The buffer for the process that encrypts the password.
+ */
+ QString m_buffer;
+
+ /**
+ * The Smb4KSambaOptionsHandler object.
+ */
+ Smb4KSambaOptionsHandler *m_options_handler;
+
+#endif
+};
+
+#endif
diff --git a/smb4k/core/smb4kpreviewer.cpp b/smb4k/core/smb4kpreviewer.cpp
new file mode 100644
index 0000000..2d3c850
--- /dev/null
+++ b/smb4k/core/smb4kpreviewer.cpp
@@ -0,0 +1,361 @@
+/***************************************************************************
+ smb4kpreviewer - This class queries a remote share for a preview
+ -------------------
+ begin : Mo Mai 28 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qapplication.h>
+
+// KDE includes
+#include <kapplication.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kpreviewer.h"
+#include "smb4kpreviewitem.h"
+#include "smb4kdefs.h"
+#include "smb4kglobal.h"
+#include "smb4kpasswordhandler.h"
+#include "smb4kauthinfo.h"
+#include "smb4ksambaoptionshandler.h"
+#include "smb4kerror.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KPreviewer::Smb4KPreviewer( QObject *parent, const char *name )
+: QObject( parent, name )
+{
+ m_item = NULL;
+
+ m_buffer = QString::null;
+
+ m_working = false;
+
+ m_proc = new KProcess( this, "PreviewProcess" );
+ m_proc->setUseShell( true );
+
+ connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( slotProcessExited( KProcess * ) ) );
+
+ connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
+}
+
+
+Smb4KPreviewer::~Smb4KPreviewer()
+{
+ // Do not delete m_item here, because it belongs to an
+ // outside class.
+}
+
+
+bool Smb4KPreviewer::preview( Smb4KPreviewItem *item )
+{
+ // If there is no item, stop right here.
+ if ( !item )
+ {
+ return false;
+ }
+
+ if ( QString::compare( item->share(), "homes" ) == 0 )
+ {
+ QString share_name = specifyUser( item->host(), kapp->mainWidget() ? kapp->mainWidget() : 0, "SpecifyUser" );
+
+ if ( !share_name.isEmpty() )
+ {
+ // The Smb4KPreviewItem::setShare() function will take care
+ // that no share name is overwritten, that is *not* named
+ // 'homes'.
+ item->setShare( share_name );
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ m_timer_id = startTimer( TIMER_INTERVAL );
+
+ m_queue.enqueue( item );
+
+ return true;
+}
+
+
+void Smb4KPreviewer::abort()
+{
+ m_queue.clear();
+
+ if ( m_proc->isRunning() )
+ {
+ m_proc->kill();
+ }
+}
+
+
+void Smb4KPreviewer::timerEvent( QTimerEvent * )
+{
+ if ( m_working )
+ {
+ return;
+ }
+
+ // Declare the previewer working:
+ emit state( PREVIEWER_START );
+
+ m_working = true;
+
+ m_item = m_queue.dequeue();
+
+ // Assemble the command.
+ //
+ // Here are some things to remember:
+ // (a) Do not convert the path to local 8 bit. It won't work with umlauts or other
+ // special characters.
+ // (b) Do not pass the path unquoted, or you'll get a NT_STATUS_OBJECT_NAME_NOT_FOUND
+ // error message in the case the path is empty.
+ QString command;
+ command.append( QString( "smbclient //%1/%2 " ).arg( KProcess::quote( m_item->host() ), KProcess::quote( m_item->share() ) ) );
+ command.append( QString( " -d1 -W %1 -D %2 " ).arg( KProcess::quote( m_item->workgroup() ), KProcess::quote( m_item->path() ) ) );
+ command.append( " -c \"ls\" " );
+
+ if ( !m_item->ip().isEmpty() )
+ {
+ command.append( QString( " -I %1 " ).arg( m_item->ip() ) );
+ }
+
+ command.append( optionsHandler()->smbclientOptions( "//"+m_item->host()+"/"+m_item->share() ) );
+
+ Smb4KAuthInfo *auth = passwordHandler()->readAuth( new Smb4KAuthInfo( m_item->workgroup(), m_item->host(), m_item->share() ) );
+
+ if ( !auth->user().isEmpty() )
+ {
+ command.append( QString( " -U %1" ).arg( KProcess::quote( auth->user() ) ) );
+
+ if ( !auth->password().isEmpty() )
+ {
+ m_proc->setEnvironment( "PASSWD", auth->password() );
+ }
+ }
+ else
+ {
+ command.append( " -U guest%" );
+ }
+
+ delete auth;
+
+ *m_proc << command;
+
+ QApplication::setOverrideCursor( waitCursor );
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KPreviewer::slotReceivedStdout( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KPreviewer::slotReceivedStderr( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KPreviewer::slotProcessExited( KProcess * )
+{
+ // Disconnect the timer:
+ if ( m_queue.isEmpty() )
+ {
+ killTimer( m_timer_id );
+ }
+
+ m_proc->clearArguments();
+
+ QStringList list = QStringList::split( "\n", m_buffer, false );
+
+ m_buffer = QString::null;
+
+ // Check whether an error occurred:
+ if ( list.grep( "NT_STATUS" ).count() != 0 )
+ {
+ // Something went wrong. Let's check if this "only" an
+ // authentication issue or if we have to error out:
+
+ QString error_code = list.grep( "NT_STATUS" ).first().stripWhiteSpace().section( " ", 0, 0 );
+
+ // The error output of smbclient is a little bit inconsistent:
+ if ( error_code.contains( "NT_STATUS" ) == 0 )
+ {
+ error_code = list.grep( "NT_STATUS" ).first().stripWhiteSpace().section( " ", -1, -1 );
+ }
+
+ // Authentication issue?
+ if ( QString::compare( error_code, "NT_STATUS_ACCESS_DENIED" ) == 0 ||
+ QString::compare( error_code, "NT_STATUS_LOGON_FAILURE" ) == 0 )
+ {
+ int state = Smb4KPasswordHandler::None;
+
+ if ( QString::compare( error_code, "NT_STATUS_ACCESS_DENIED" ) == 0 )
+ {
+ state = Smb4KPasswordHandler::AccessDenied;
+ }
+ else if ( QString::compare( error_code, "NT_STATUS_LOGON_FAILURE" ) == 0 )
+ {
+ state = Smb4KPasswordHandler::LogonFailure;
+ }
+
+ if ( passwordHandler()->askpass( m_item->workgroup(), m_item->host(),
+ m_item->share(), state,
+ kapp->mainWidget() ? kapp->mainWidget() : 0,
+ "AskPass" ) )
+ {
+ // Now we have a password. Retry.
+ // NOTE: Since the item is appended to the queue, there might
+ // be the case, that another preview is generated before the
+ // retry is executed. I think, we can live with that.
+ preview( m_item );
+ }
+ else
+ {
+ // The user cancelled the askpass dialog. We won't show an
+ // error dialog here, but will only clear the contents of
+ // the preview item and emit the failed() signal.
+ m_item->clearContents();
+
+ emit failed();
+ }
+ }
+ else
+ {
+ // OK, error out. We cannot recover from it:
+ Smb4KError::error( ERROR_GETTING_PREVIEW, QString::null, m_buffer );
+
+ m_item->clearContents();
+
+ emit failed();
+ }
+ }
+ else if ( list.grep( "Connection to" ).count() != 0 ||
+ (list.grep( "Error returning browse list:" ).count() != 0 &&
+ list.grep( "NT_STATUS" ).count() == 0) )
+ {
+ // These are errors that we cannot work around. Error out.
+ Smb4KError::error( ERROR_GETTING_PREVIEW, QString::null, m_buffer );
+
+ m_item->clearContents();
+
+ emit failed();
+ }
+ else
+ {
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( (*it).stripWhiteSpace().startsWith( "Domain" ) ||
+ (*it).stripWhiteSpace().startsWith( "OS" ) ||
+ (*it).stripWhiteSpace().startsWith( "Anonymous" ) )
+ {
+ continue;
+ }
+ else if ( (*it).contains( "blocks of size" ) != 0 )
+ {
+ continue;
+ }
+ else
+ {
+ QString tmp = (*it).stripWhiteSpace().section( " ", 0, -9 ).stripWhiteSpace();
+
+ QString item = tmp.section( " ", 0, -2 ).stripWhiteSpace();
+
+ if ( !item.isEmpty() && tmp.section( " ", -1, -1 ).contains( "D" ) != 0 )
+ {
+ // We have a directory here.
+ if ( item.startsWith( "." ) &&
+ (QString::compare( item.stripWhiteSpace(), "." ) != 0 &&
+ QString::compare( item.stripWhiteSpace(), ".." ) != 0) )
+ {
+ m_item->addContents( ContentsItem( Smb4KPreviewItem::HiddenDirectory, item ) );
+ }
+ else
+ {
+ m_item->addContents( ContentsItem( Smb4KPreviewItem::Directory, item ) );
+ }
+
+ continue;
+ }
+ else if ( item.isEmpty() || tmp.section( " ", -1, -1 ).contains( "D" ) == 0 )
+ {
+ // We have a file
+ if ( item.isEmpty() )
+ {
+ if ( tmp.startsWith( "." ) )
+ {
+ m_item->addContents( ContentsItem( Smb4KPreviewItem::HiddenFile, tmp ) );
+ }
+ else
+ {
+ m_item->addContents( ContentsItem( Smb4KPreviewItem::File, tmp ) );
+ }
+ }
+ else
+ {
+ if ( item.startsWith( "." ) )
+ {
+ m_item->addContents( ContentsItem( Smb4KPreviewItem::HiddenFile, item ) );
+ }
+ else
+ {
+ m_item->addContents( ContentsItem( Smb4KPreviewItem::File, item ) );
+ }
+ }
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+
+ emit result( m_item );
+
+ QApplication::restoreOverrideCursor();
+
+ m_working = false;
+
+ emit state( PREVIEWER_STOP );
+}
+
+#include "smb4kpreviewer.moc"
diff --git a/smb4k/core/smb4kpreviewer.h b/smb4k/core/smb4kpreviewer.h
new file mode 100644
index 0000000..f946f9f
--- /dev/null
+++ b/smb4k/core/smb4kpreviewer.h
@@ -0,0 +1,190 @@
+/***************************************************************************
+ smb4kpreviewer - This class queries a remote share for a preview
+ -------------------
+ begin : Mo Mai 28 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPREVIEWER_H
+#define SMB4KPREVIEWER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qstring.h>
+#include <qptrqueue.h>
+
+// KDE includes
+#include <kprocess.h>
+
+// forward declarations
+class Smb4KPreviewItem;
+
+/**
+ * This class is part of the core of Smb4K. It queries a remote SMB share for
+ * a preview and returns the result.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KPreviewer : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent object
+ *
+ * @param name The name of this object
+ */
+ Smb4KPreviewer( QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KPreviewer();
+
+ /**
+ * Get a preview of the contents of @p item.
+ *
+ * In the case that @p item represents a 'homes' share, the user will be
+ * prompted for the user name with which he wants to log in and the share
+ * name of @p item will be set to the result.
+ *
+ * @param item The item for which a preview should be
+ * requested.
+ *
+ * @returns TRUE if einter the share name is not 'homes' or if it could
+ * successfully be set to a user name. Otherwise it returns FALSE.
+ */
+ bool preview( Smb4KPreviewItem *item );
+
+ /**
+ * Using this function, you can find out whether the previewer is running
+ * at the moment.
+ *
+ * @returns TRUE if the previewer is running or FALSE otherwise.
+ */
+ bool isRunning() { return m_working; }
+
+ /**
+ * Abort any action the previewer is performing at the moment and clear
+ * the queue.
+ */
+ void abort();
+
+ signals:
+ /**
+ * Emits the state the previewer is in
+ *
+ * @param state The state
+ */
+ void state( int state );
+
+ /**
+ * Emits the preview after the process exited successfully. Get the contents
+ * of the remote share by looping through the Smb4KPreviewItem::contents() list.
+ *
+ * @param item The item for which the preview was received.
+ */
+ void result( Smb4KPreviewItem *item );
+
+ /**
+ * This signal is emitted if an error occurred.
+ */
+ void failed();
+
+ protected:
+ /**
+ * Reimplemented from QObject
+ */
+ void timerEvent( QTimerEvent *e );
+
+ protected slots:
+ /**
+ * This slot receives output from stdout.
+ *
+ * @param proc The process
+ *
+ * @param buf The buffer
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStdout( KProcess *proc, char *buf, int len );
+
+ /**
+ * This slot receives output from stderr.
+ *
+ * @param proc The process
+ *
+ * @param buf The buffer
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStderr( KProcess *proc, char *buf, int len );
+
+ /**
+ * Is called, when the KProcess exited.
+ *
+ * @param proc The process that exited
+ */
+ void slotProcessExited( KProcess *proc );
+
+ private:
+ /**
+ * The KProcess object
+ */
+ KProcess *m_proc;
+
+ /**
+ * The output buffer
+ */
+ QString m_buffer;
+
+ /**
+ * This is the pointer to the Smb4KPreviewItem that's
+ * processed.
+ */
+ Smb4KPreviewItem *m_item;
+
+ /**
+ * Indicates whether the previewer is running or not.
+ */
+ bool m_working;
+
+ /**
+ * This pointer queue holds the pointers to the Smb4KPreviewItem
+ * objects that are to be processed.
+ */
+ QPtrQueue<Smb4KPreviewItem> m_queue;
+
+ /**
+ * The timer id
+ */
+ int m_timer_id;
+};
+
+#endif
diff --git a/smb4k/core/smb4kpreviewitem.cpp b/smb4k/core/smb4kpreviewitem.cpp
new file mode 100644
index 0000000..c712a48
--- /dev/null
+++ b/smb4k/core/smb4kpreviewitem.cpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ smb4kpreviewitem - A container for previews of a remote share
+ -------------------
+ begin : Mo Mai 28 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <ksocketaddress.h>
+
+// application specific includes
+#include "smb4kpreviewitem.h"
+
+Smb4KPreviewItem::Smb4KPreviewItem( Smb4KShareItem *item, const QString &ip, const QString &path )
+: m_workgroup( item->workgroup() ), m_host( item->host() ), m_share( item->name() ), m_path( path )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+ m_location = "//"+m_host+"/"+m_share+"/"+m_path;
+}
+
+
+Smb4KPreviewItem::~Smb4KPreviewItem()
+{
+}
+
+
+void Smb4KPreviewItem::setShare( const QString &share )
+{
+ if ( QString::compare( m_share, "homes" ) == 0 )
+ {
+ m_share = share;
+ }
+}
+
+
+void Smb4KPreviewItem::setIP( const QString &ip )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+}
+
+
+void Smb4KPreviewItem::setPath( const QString &path )
+{
+ m_path = path;
+ m_location = "//"+m_host+"/"+m_share+"/"+m_path;
+
+ clearContents();
+}
+
+
+void Smb4KPreviewItem::addContents( const ContentsItem &item )
+{
+ // Do not set the last argument to TRUE, because then
+ // we would be in overwrite mode.
+ m_contents.append( item );
+}
+
+
+void Smb4KPreviewItem::clearContents()
+{
+ m_contents.clear();
+}
+
+
+bool Smb4KPreviewItem::ipIsValid( const QString &ip )
+{
+ if ( !ip.isEmpty() )
+ {
+ KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( ip );
+
+ if ( !ip_address.isIPv4Addr() && !ip_address.isIPv6Addr() )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/smb4k/core/smb4kpreviewitem.h b/smb4k/core/smb4kpreviewitem.h
new file mode 100644
index 0000000..d3663d5
--- /dev/null
+++ b/smb4k/core/smb4kpreviewitem.h
@@ -0,0 +1,216 @@
+/***************************************************************************
+ smb4kpreviewitem - A container for previews of a remote share
+ -------------------
+ begin : Mo Mai 28 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPREVIEWITEM_H
+#define SMB4KPREVIEWITEM_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qstring.h>
+#include <qmap.h>
+#include <qpair.h>
+
+// application specific includes
+#include "smb4knetworkitems.h"
+
+typedef QPair<int, QString> ContentsItem;
+
+/**
+ * This class provides a container for the preview of the contents of a remote
+ * SMB share.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KPreviewItem
+{
+ public:
+ /**
+ * The default constructor.
+ *
+ * @param item The share for that a preview should be collected.
+ *
+ * @param ip The IP address of the host where the share
+ * is located.
+ *
+ * @param path The path for that the preview should be collected.
+ */
+ Smb4KPreviewItem( Smb4KShareItem *item, const QString &ip = QString::null, const QString &path = QString::null );
+
+ /**
+ * The empty constructor.
+ */
+ Smb4KPreviewItem() {}
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KPreviewItem();
+
+ /**
+ * Returns the workgroup where the host is located
+ */
+ const QString &workgroup() const { return m_workgroup; }
+
+ /**
+ * Return the name of the host where the share is located.
+ */
+ const QString &host() const { return m_host; }
+
+ /**
+ * Return the name of the share that is to be previewed.
+ */
+ const QString &share() const { return m_share; }
+
+ /**
+ * With this function you can set the share name if this item
+ * represents a homes share. In all other cases it will do just
+ * nothing.
+ *
+ * @param share The new share name
+ */
+ void setShare( const QString &share );
+
+ /**
+ * Return the path that is to be previewed.
+ */
+ const QString &path() const { return m_path; }
+
+ /**
+ * Returns the IP address of the host where the share
+ * is located.
+ */
+ const QString &ip() const { return m_ip; }
+
+ /**
+ * Set the IP address of the host.
+ *
+ * @param ip The IP address of the host.
+ */
+ void setIP( const QString &ip );
+
+ /**
+ * Set the path for which the preview.
+ *
+ * @param path The path
+ *
+ * @note As soon as this function is used, the list of files and directories
+ * will be cleared.
+ */
+ void setPath( const QString &path );
+
+ /**
+ * Returns the current location in the form //HOST/SHARE/PATH.
+ * It can be used for displaying in a preview dialog or for checks.
+ *
+ * @returns The current location
+ */
+ const QString &location() const { return m_location; }
+
+ /**
+ * This enumeration is used for the contents. It determines if
+ * an item is a file, a hidden file, a directory, or a hidden
+ * directory.
+ */
+ enum Contents { File, HiddenFile, Directory, HiddenDirectory };
+
+ /**
+ * Returns the contents of the location.
+ *
+ * @returns a map of (hidden) files and (hidden) directories.
+ */
+ const QValueList<ContentsItem> &contents() const { return m_contents; }
+
+ /**
+ * Add a file or directory to the contents.
+ *
+ * @param item A ContentsItem object. This is a QPair<int,QString>
+ * with the integer being a value from the Contents
+ * enumeration and the string being the full path of
+ * the file or directory.
+ *
+ * @see Smb4KPreviewItem::setPath() or Smb4KPreviewItem::clearContents() for how
+ * the list of files and directories is cleared.
+ */
+ void addContents( const ContentsItem &item );
+
+ /**
+ * Clears the contents.
+ */
+ void clearContents();
+
+ private:
+ /**
+ * The workgroup of the host
+ */
+ QString m_workgroup;
+
+ /**
+ * The host's name
+ */
+ QString m_host;
+
+ /**
+ * The share name
+ */
+ QString m_share;
+
+ /**
+ * The IP address of the host
+ */
+ QString m_ip;
+
+ /**
+ * The path that has to be previewed.
+ */
+ QString m_path;
+
+ /**
+ * The current location
+ */
+ QString m_location;
+
+ /**
+ * This map stores the contents of the current
+ * location.
+ */
+ QValueList<ContentsItem> m_contents;
+
+ /**
+ * This function checks if the IP address is valid, i.e. the
+ * IP address is either IP v4 or IP v6. It returns either TRUE
+ * or FALSE.
+ *
+ * @param ip The IP address that's going to be checked.
+ *
+ * @returns TRUE if the IP address is valid and FALSE otherwise.
+ */
+ bool ipIsValid( const QString &ip );
+};
+
+#endif
diff --git a/smb4k/core/smb4kprint.cpp b/smb4k/core/smb4kprint.cpp
new file mode 100644
index 0000000..9567926
--- /dev/null
+++ b/smb4k/core/smb4kprint.cpp
@@ -0,0 +1,372 @@
+/***************************************************************************
+ smb4kprint - The printing core class.
+ -------------------
+ begin : Tue Mar 30 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qtimer.h>
+#include <qfile.h>
+
+// KDE includes
+#include <kurl.h>
+#include <kfileitem.h>
+#include <kdebug.h>
+
+// system includes
+#include <sys/types.h>
+#include <pwd.h>
+
+// application specific includes
+#include "smb4kprint.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4kauthinfo.h"
+#include "smb4kpasswordhandler.h"
+#include "smb4kprintinfo.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+
+Smb4KPrint::Smb4KPrint( QObject *parent, const char *name ) : QObject( parent, name )
+{
+ m_proc = new KProcess( this, "PrintProcess" );
+ m_proc->setUseShell( true );
+
+ m_info = NULL;
+
+ m_working = false;
+
+ connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( processExited( KProcess * ) ),
+ this, SLOT( slotProcessExited( KProcess * ) ) );
+}
+
+
+Smb4KPrint::~Smb4KPrint()
+{
+ abort();
+}
+
+
+/****************************************************************************
+ Aborts the current process.
+****************************************************************************/
+
+void Smb4KPrint::abort()
+{
+ if ( m_proc->isRunning() )
+ {
+ m_proc->kill();
+ }
+}
+
+
+/****************************************************************************
+ Start the printing.
+****************************************************************************/
+
+bool Smb4KPrint::print( Smb4KPrintInfo *info )
+{
+ // Do nothing if we receive a NULL pointer:
+ if ( !info )
+ {
+ return false;
+ }
+
+ m_working = true;
+ m_info = info;
+
+ // Start processing the file:
+ if ( QFile::exists( m_info->path() ) )
+ {
+ // Determine the mimetype of the file:
+ KURL url;
+ url.setPath( m_info->path() );
+
+ KFileItem file_item = KFileItem( KFileItem::Unknown, KFileItem::Unknown, url, false );
+
+ if ( QString::compare( file_item.mimetype(), "application/postscript" ) == 0 ||
+ QString::compare( file_item.mimetype(), "application/pdf" ) == 0 ||
+ file_item.mimetype().startsWith( "image" ) )
+ {
+ setDeviceURI();
+ printNormal();
+ }
+ else if ( QString::compare( file_item.mimetype(), "application/x-dvi" ) == 0 &&
+ !Smb4KSettings::dvips().isEmpty() )
+ {
+ setDeviceURI();
+ printDVI();
+ }
+ else if ( (file_item.mimetype().startsWith( "text" ) ||
+ file_item.mimetype().startsWith( "message" ) ||
+ QString::compare( file_item.mimetype(), "application/x-shellscript" ) == 0) &&
+ !Smb4KSettings::enscript().isEmpty() )
+ {
+ setDeviceURI();
+ printText();
+ }
+ else
+ {
+ Smb4KError::information( INFO_MIMETYPE_NOT_SUPPORTED, file_item.mimetype() );
+
+ delete m_info;
+ m_info = NULL;
+
+ m_working = false;
+ emit state( PRINT_STOP );
+ return false;
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_FILE_NOT_FOUND, m_info->path() );
+
+ delete m_info;
+ m_info = NULL;
+
+ m_working = false;
+ emit state( PRINT_STOP );
+ return false;
+ }
+
+ return true;
+}
+
+
+/****************************************************************************
+ Sets the device URI
+****************************************************************************/
+
+void Smb4KPrint::setDeviceURI()
+{
+ Smb4KAuthInfo *auth = passwordHandler()->readAuth( new Smb4KAuthInfo( m_info->workgroup(),
+ m_info->host(), m_info->printer() ) );
+
+ QString uri;
+
+ // It seems that we must not quote the entries for the DEVICE_URI
+ // environment variable. Printing will fail if you do it.
+
+ if ( !m_info->workgroup().isEmpty() )
+ {
+ if ( !auth->user().isEmpty() )
+ {
+ uri = QString( "smb://%1:%2@%3/%4/%5" ).arg( auth->user(), auth->password() ).arg( m_info->workgroup(), m_info->host(), m_info->printer() );
+ }
+ else
+ {
+ uri = QString( "smb://%1/%2/%3" ).arg( m_info->workgroup(), m_info->host(), m_info->printer() );
+ }
+ }
+ else
+ {
+ if ( !auth->user().isEmpty() )
+ {
+ uri = QString( "smb://%1:%2@%3/%4" ).arg( auth->user(), auth->password() ).arg( m_info->host(), m_info->printer() );
+ }
+ else
+ {
+ uri = QString( "smb://%1/%2" ).arg( m_info->host(), m_info->printer() );
+ }
+ }
+
+ m_proc->setEnvironment( "DEVICE_URI", uri );
+
+ delete auth;
+}
+
+
+/****************************************************************************
+ Do normal printing.
+****************************************************************************/
+
+void Smb4KPrint::printNormal()
+{
+ QString command;
+
+ command.append( "smbspool 111 "+QString( getpwuid( getuid() )->pw_name ) );
+ command.append( " \"Smb4K print job\" "+QString( "%1" ).arg( m_info->copies() ) );
+ command.append( " \"\" "+KProcess::quote( m_info->path() ) );
+
+ *m_proc << command;
+
+ emit state( PRINT_START );
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+
+/****************************************************************************
+ Print DVI files.
+****************************************************************************/
+
+void Smb4KPrint::printDVI()
+{
+ // The temporary file.
+ QString temp_file = tempDir()+"/smb4k_print.ps";
+
+ QString command;
+
+ // First we need the conversion:
+ command.append( "cd "+KProcess::quote( m_info->path().section( "/", 0, -2 ) )+" && " );
+ command.append( "dvips -P pdf -o "+temp_file+" "+KProcess::quote( m_info->path().section( "/", -1, -1 ) )+" && " );
+
+ // The actual print command:
+ command.append( "smbspool 111 "+QString( getpwuid( getuid() )->pw_name ) );
+ command.append( " \"Smb4K print job\" "+QString( "%1" ).arg( m_info->copies() ) );
+ command.append( " \"\" "+KProcess::quote( temp_file )+" && " );
+
+ // Clean up:
+ command.append( "rm -f "+temp_file );
+
+ *m_proc << command;
+
+ emit state( PRINT_START );
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+
+/****************************************************************************
+ Print text files.
+****************************************************************************/
+
+void Smb4KPrint::printText()
+{
+ // The temporary file.
+ QString temp_file = tempDir()+"/smb4k_print.ps";
+
+ QString command;
+
+ // Conversion:
+ command.append( "enscript --columns=1 --no-header --ps-level=2 " );
+ command.append( "-o "+KProcess::quote( temp_file )+" " );
+ command.append( KProcess::quote( m_info->path() )+ " && " );
+
+ // The actual print command:
+ command.append( "smbspool 111 "+QString( getpwuid( getuid() )->pw_name ) );
+ command.append( " \"Smb4K print job\" "+QString( "%1" ).arg( m_info->copies() ) );
+ command.append( " \"\" "+KProcess::quote( temp_file )+" && " );
+
+ // Clean up:
+ command.append( "rm -f "+temp_file );
+
+ *m_proc << command;
+
+ emit state( PRINT_START );
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KPrint::slotReceivedStdout( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KPrint::slotReceivedStderr( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+
+ if ( m_buffer.contains( "NT_STATUS" ) != 0 )
+ {
+ abort();
+ }
+}
+
+
+void Smb4KPrint::slotProcessExited( KProcess * )
+{
+ bool retry = false;
+
+ if ( m_buffer.contains( "NT_STATUS", true ) != 0 ||
+ m_buffer.contains( "enscript", true ) != 0 ||
+ m_buffer.contains( "dvips", true ) != 0 )
+ {
+ if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 || m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 )
+ {
+ int state = Smb4KPasswordHandler::None;
+
+ if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 )
+ {
+ state = Smb4KPasswordHandler::AccessDenied;
+ }
+ else if (m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 )
+ {
+ state = Smb4KPasswordHandler::LogonFailure;
+ }
+
+ if ( passwordHandler()->askpass( m_info->workgroup(), m_info->host(), m_info->printer(), state ) )
+ {
+ retry = true;
+ QTimer::singleShot( 50, this, SLOT( slotRetry() ) );
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_PRINTING, m_info->path(), m_buffer );
+
+ // Clean up:
+ QFile::remove( QString( "%1/smb4k_print.ps" ).arg( tempDir() ) );
+ }
+ }
+ else
+ {
+ // Clean up:
+ QFile::remove( QString( "%1/smb4k_print.ps" ).arg( tempDir() ) );
+ }
+
+ m_proc->clearArguments();
+
+ if ( !retry )
+ {
+ delete m_info;
+ m_info = NULL;
+ }
+
+ m_working = false;
+ emit state( PRINT_STOP );
+}
+
+
+void Smb4KPrint::slotRetry()
+{
+ print( m_info );
+}
+
+
+#include "smb4kprint.moc"
diff --git a/smb4k/core/smb4kprint.h b/smb4k/core/smb4kprint.h
new file mode 100644
index 0000000..8a9a5cd
--- /dev/null
+++ b/smb4k/core/smb4kprint.h
@@ -0,0 +1,170 @@
+/***************************************************************************
+ smb4kprint - The printing core class.
+ -------------------
+ begin : Tue Mar 30 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPRINT_H
+#define SMB4KPRINT_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qstring.h>
+#include <qwidget.h>
+
+// KDE includes
+#include <kprocess.h>
+#include <kdialogbase.h>
+
+// forward declarations
+class Smb4KPrintInfo;
+
+
+/**
+ * This is a core class. It provides the interface for printing documents over
+ * the network neighborhood.
+ *
+ * You shouldn't use this class directly but access it through Smb4KCore.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KPrint : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ */
+ Smb4KPrint( QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KPrint();
+
+ /**
+ * This function starts the printing of a file. It takes a Smb4KPrintInfo object
+ * and constructs the print dialog from it. The information entered there will be
+ * used to print the file.
+ *
+ * Note that @p info will be deleted. So do not try to use the pointer later in your
+ * code!
+ *
+ * @param info The Smb4KShareItem object
+ */
+ bool print( Smb4KPrintInfo *info );
+
+ /**
+ * Aborts the print process.
+ */
+ void abort();
+
+ /**
+ * This function returns TRUE if the printer handler is running and
+ * FALSE otherwise.
+ *
+ * @returns TRUE is the printer handler is running and FALSE otherwise.
+ */
+ bool isRunning() { return m_working; }
+
+ signals:
+ /**
+ * This signal emits the run state.
+ *
+ * @param state The so-called run state. There are several defined
+ * in the smb4kdefs.h header file.
+ */
+ void state( int state );
+
+ protected slots:
+ /**
+ * This slot receives output at stdout.
+ */
+ void slotReceivedStdout( KProcess *, char *buf, int len );
+
+ /**
+ * This slot receives output at stderr.
+ */
+ void slotReceivedStderr( KProcess *, char *buf, int len );
+
+ /**
+ * This slot is called when the process exited.
+ */
+ void slotProcessExited( KProcess * );
+
+ /**
+ * This slot is invoked if the print process should be restarted
+ * (i.e. because authentication data was missing, etc.).
+ */
+ void slotRetry();
+
+ private:
+
+ /**
+ * The KProcess object.
+ */
+ KProcess *m_proc;
+
+ /**
+ * The buffer
+ */
+ QString m_buffer;
+
+ /**
+ * This boolean is TRUE if the printer handler is running and
+ * FALSE otherwise.
+ */
+ bool m_working;
+
+ /**
+ * The print info object
+ */
+ Smb4KPrintInfo *m_info;
+
+ /**
+ * Sets the device URI
+ */
+ void setDeviceURI();
+
+ /**
+ * Do normal printing.
+ */
+ void printNormal();
+
+ /**
+ * Print DVI files.
+ */
+ void printDVI();
+
+ /**
+ * Print text files
+ */
+ void printText();
+};
+
+#endif
diff --git a/smb4k/core/smb4kprintinfo.cpp b/smb4k/core/smb4kprintinfo.cpp
new file mode 100644
index 0000000..7f546c7
--- /dev/null
+++ b/smb4k/core/smb4kprintinfo.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ smb4kprintinfo - description
+ -------------------
+ begin : Mo Apr 19 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <ksocketaddress.h>
+
+// application specific includes
+#include "smb4kprintinfo.h"
+
+
+Smb4KPrintInfo::Smb4KPrintInfo( Smb4KShareItem *item, const QString &ip, const QString &path, int copies )
+: m_workgroup( item->workgroup() ), m_host( item->host() ), m_printer( item->name() ), m_path( path ),
+ m_copies( copies ), m_comment( item->comment() )
+{
+ m_ip = ipIsValid( ip ) ? ip : QString::null;
+}
+
+
+Smb4KPrintInfo::~Smb4KPrintInfo()
+{
+}
+
+
+void Smb4KPrintInfo::setPath( const QString &path )
+{
+ m_path = path;
+}
+
+
+void Smb4KPrintInfo::setCopies( int num )
+{
+ m_copies = num;
+}
+
+
+bool Smb4KPrintInfo::ipIsValid( const QString &ip )
+{
+ if ( !ip.isEmpty() )
+ {
+ KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( ip );
+
+ if ( !ip_address.isIPv4Addr() && !ip_address.isIPv6Addr() )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/smb4k/core/smb4kprintinfo.h b/smb4k/core/smb4kprintinfo.h
new file mode 100644
index 0000000..9b25c9e
--- /dev/null
+++ b/smb4k/core/smb4kprintinfo.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+ smb4kprintinfo - description
+ -------------------
+ begin : Mo Apr 19 2004
+ copyright : (C) 2004 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPRINTINFO_H
+#define SMB4KPRINTINFO_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qstring.h>
+
+// application specific includes
+#include "smb4knetworkitems.h"
+
+/**
+ * This class provides a container that holds all the info
+ * that is needed to print a file.
+ */
+
+class Smb4KPrintInfo
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param item The Smb4KShareItem that represents the printer
+ *
+ * @param ip The IP address of the host
+ *
+ * @param filepath The path of the file to print
+ *
+ * @param copies The number of copies
+ */
+ Smb4KPrintInfo( Smb4KShareItem *item, const QString &ip, const QString &filepath = QString::null, int copies = 1 );
+ /**
+ * Empty constructor.
+ */
+ Smb4KPrintInfo() {}
+ /**
+ * The destructor.
+ */
+ ~Smb4KPrintInfo();
+ /**
+ * Returns the path of the file.
+ */
+ const QString &path() const { return m_path; }
+ /**
+ * Returns the host where the printer is located.
+ */
+ const QString &host() const { return m_host; }
+ /**
+ * Returns the workgroup in which the host located.
+ */
+ const QString &workgroup() const { return m_workgroup; }
+ /**
+ * Returns the name of the printer.
+ */
+ const QString &printer() const { return m_printer; }
+ /**
+ * Returns the IP address of the host.
+ */
+ const QString &ip() const { return m_ip; }
+ /**
+ * Sets the path to the file to print.
+ */
+ void setPath( const QString &path );
+ /**
+ * Returns the number of copies the user wants to have.
+ */
+ int copies() const { return m_copies; }
+ /**
+ * Sets the number of copies.
+ */
+ void setCopies( int num );
+ /**
+ * Returns the comment.
+ */
+ const QString &comment() const { return m_comment; }
+
+ private:
+ /**
+ * The workgroup.
+ */
+ QString m_workgroup;
+ /**
+ * The host.
+ */
+ QString m_host;
+ /**
+ * The IP address.
+ */
+ QString m_ip;
+ /**
+ * The printer name.
+ */
+ QString m_printer;
+ /**
+ * The path to the file to print.
+ */
+ QString m_path;
+ /**
+ * Holds the number of copies the user wants to have.
+ */
+ int m_copies;
+ /**
+ * The comment
+ */
+ QString m_comment;
+
+ /**
+ * This function checks if the IP address is valid, i.e. the
+ * IP address is either IP v4 or IP v6. It returns either TRUE
+ * or FALSE.
+ *
+ * @param ip The IP address that's going to be checked.
+ *
+ * @returns TRUE if the IP address is valid and FALSE otherwise.
+ */
+ bool ipIsValid( const QString &ip );
+};
+
+#endif
+
diff --git a/smb4k/core/smb4ksambaoptionshandler.cpp b/smb4k/core/smb4ksambaoptionshandler.cpp
new file mode 100644
index 0000000..e31648d
--- /dev/null
+++ b/smb4k/core/smb4ksambaoptionshandler.cpp
@@ -0,0 +1,1559 @@
+/***************************************************************************
+ smb4ksambaoptionshandler - This class handles the Samba options.
+ -------------------
+ begin : So Mai 14 2006
+ copyright : (C) 2006-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qdir.h>
+
+// KDE includes
+#include <kstandarddirs.h>
+#include <kprocess.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+// system specific includes
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+
+// application specific includes
+#include "smb4ksambaoptionshandler.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4ksambaoptionsinfo.h"
+#include "smb4kshare.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KSambaOptionsHandler::Smb4KSambaOptionsHandler( QObject *parent, const char *name )
+: QObject( parent, name )
+{
+ // We need the directory.
+ KStandardDirs *stddir = new KStandardDirs();
+ QString dir = locateLocal( "data", "smb4k", KGlobal::instance() );
+
+ if ( !stddir->exists( dir ) )
+ {
+ stddir->makeDir( dir );
+ }
+
+ delete stddir;
+
+ m_wins_server = QString::null;
+}
+
+
+Smb4KSambaOptionsHandler::~Smb4KSambaOptionsHandler()
+{
+ for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = m_list.begin();
+ it != m_list.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_list.clear();
+}
+
+
+const QValueList<Smb4KSambaOptionsInfo *> &Smb4KSambaOptionsHandler::customOptionsList()
+{
+ if ( m_list.isEmpty() )
+ {
+ read_options();
+ }
+
+ return m_list;
+}
+
+
+void Smb4KSambaOptionsHandler::read_options()
+{
+ // Clear the list before filling it (again)
+ if ( !m_list.isEmpty() )
+ {
+ for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = m_list.begin();
+ it != m_list.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_list.clear();
+ }
+
+ QFile file( locateLocal( "data", "smb4k/custom_options", KGlobal::instance() ) );
+
+ QStringList contents;
+
+ if ( file.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( '\n', ts.read(), true );
+
+ file.close();
+ }
+ else
+ {
+ if ( file.exists() )
+ {
+ Smb4KError::error( ERROR_READING_FILE, file.name() );
+ }
+
+ return;
+ }
+
+ if ( !contents.isEmpty() )
+ {
+ for ( QStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
+ {
+ if ( (*it).startsWith( "[" ) )
+ {
+ Smb4KSambaOptionsInfo *info = new Smb4KSambaOptionsInfo( (*it).section( "[", 1, -1 ).section( "]", -2, 0 ) );
+
+ for ( QStringList::ConstIterator i = ++it; i != contents.end(); ++i )
+ {
+ if ( (*i).startsWith( "remount=" ) )
+ {
+ bool remount = QString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 ? true : false;
+
+ info->setRemount( remount );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "port=" ) )
+ {
+ int port = (*i).section( "=", 1, 1 ).stripWhiteSpace().toInt();
+
+ info->setPort( port );
+
+ continue;
+ }
+#ifndef __FreeBSD__
+ else if ( (*i).startsWith( "filesystem=" ) )
+ {
+ info->setFilesystem( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "read-write=" ) ) // Deprecated since version 0.9.0
+ {
+ info->setWriteAccess( QString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "write access=" ) )
+ {
+ info->setWriteAccess( QString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
+
+ continue;
+ }
+#endif
+ else if ( (*i).startsWith( "protocol=" ) )
+ {
+ info->setProtocol( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "kerberos=" ) )
+ {
+ info->setKerberos( QString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "uid=" ) )
+ {
+ info->setUID( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "gid=" ) )
+ {
+ info->setGID( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
+
+ continue;
+ }
+ else if ( (*i).isEmpty() || (*i).stripWhiteSpace().startsWith( "[" ) )
+ {
+ it = i;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ m_list.append( info );
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+}
+
+
+void Smb4KSambaOptionsHandler::write_options()
+{
+ QString protocol_hint;
+
+ // Determine the protocol hint specified by the user:
+ switch ( Smb4KSettings::protocolHint() )
+ {
+ case Smb4KSettings::EnumProtocolHint::Automatic:
+ {
+ // In this case the user leaves it to the net
+ // command to determine the right protocol.
+ protocol_hint = QString::null;
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RPC:
+ {
+ protocol_hint = "rpc";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RAP:
+ {
+ protocol_hint = "rap";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::ADS:
+ {
+ protocol_hint = "ads";
+
+ break;
+ }
+ default:
+ {
+ protocol_hint = QString::null;
+
+ break;
+ }
+ }
+
+#ifndef __FreeBSD__
+
+ QString default_filesystem;
+
+ switch( Smb4KSettings::filesystem() )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ default_filesystem = "cifs";
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ default_filesystem = "smbfs";
+
+ break;
+ }
+ default:
+ {
+ // FIXME: Set default_filesystem to "cifs"?
+ break;
+ }
+ }
+
+ bool write_access = true;
+
+ switch( Smb4KSettings::writeAccess() )
+ {
+ case Smb4KSettings::EnumWriteAccess::ReadWrite:
+ {
+ write_access = true;
+
+ break;
+ }
+ case Smb4KSettings::EnumWriteAccess::ReadOnly:
+ {
+ write_access = false;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+#endif
+
+ QFile file( locateLocal( "data", "smb4k/custom_options", KGlobal::instance() ) );
+
+ if ( !m_list.isEmpty() )
+ {
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = m_list.begin(); it != m_list.end(); ++it )
+ {
+ switch ( (*it)->type() )
+ {
+ case Smb4KSambaOptionsInfo::Host:
+ {
+ // Check if we need to write anything:
+ if ( (*it)->port() != -1 ||
+ !(*it)->protocol().stripWhiteSpace().isEmpty() ||
+ ((*it)->kerberos() != Smb4KSettings::useKerberos()) )
+ {
+ ts << "[" << (*it)->itemName() << "]" << endl;
+
+ ts << "port=" << ((*it)->port() != -1 ? (*it)->port() :
+ Smb4KSettings::remotePort()) << endl;
+
+ ts << "kerberos=" << ((*it)->kerberos() ? "true" : "false") << endl;
+
+ ts << "protocol=" << (!(*it)->protocol().stripWhiteSpace().isEmpty() ?
+ (*it)->protocol() : protocol_hint) << endl;
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ break;
+ }
+ case Smb4KSambaOptionsInfo::Share:
+ {
+ if ( (*it)->port() != -1 ||
+ (*it)->remount() ||
+#ifndef __FreeBSD__
+ (*it)->kerberos() != Smb4KSettings::useKerberos() ||
+ !(*it)->filesystem().isEmpty() ||
+ (*it)->writeAccess() != write_access ||
+#endif
+ !(*it)->uid().isEmpty() ||
+ !(*it)->gid().isEmpty() )
+ {
+ ts << "[" << (*it)->itemName() << "]" << endl;
+
+ ts << "port=" << ((*it)->port() != -1 ? (*it)->port() :
+ Smb4KSettings::remotePort()) << endl;
+
+ ts << "remount=" << ((*it)->remount() ? "true" : "false") << endl;
+#ifndef __FreeBSD__
+ // FreeBSD does not know Kerberos for mounting:
+ ts << "kerberos=" << ((*it)->kerberos() ? "true" : "false") << endl;
+
+ ts << "filesystem=" << (!(*it)->filesystem().stripWhiteSpace().isEmpty() ?
+ (*it)->filesystem() : default_filesystem) << endl;
+
+ ts << "write access=" << ((*it)->writeAccess() ? "true" : "false") << endl;
+#endif
+ ts << "uid=" << (!(*it)->uid().stripWhiteSpace().isEmpty() ?
+ (*it)->uid() : Smb4KSettings::userID()) << endl;
+
+ ts << "gid=" << (!(*it)->gid().stripWhiteSpace().isEmpty() ?
+ (*it)->gid() : Smb4KSettings::groupID()) << endl;
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ ts << endl;
+ }
+
+ file.close();
+ }
+ }
+ else
+ {
+ file.remove();
+ }
+}
+
+
+void Smb4KSambaOptionsHandler::remount( Smb4KShare *share, bool yes )
+{
+ if ( share )
+ {
+ Smb4KSambaOptionsInfo *info = NULL;
+
+ if ( (info = find_item( share->name() )) )
+ {
+ info->setRemount( yes );
+ }
+ else if ( !info && yes )
+ {
+ info = new Smb4KSambaOptionsInfo( share );
+ info->setRemount( yes );
+
+ m_list.append( info );
+ }
+ }
+}
+
+
+void Smb4KSambaOptionsHandler::sync()
+{
+ write_options();
+}
+
+
+Smb4KSambaOptionsInfo *Smb4KSambaOptionsHandler::find_item( const QString &item, bool exactMatch )
+{
+ // If the list is empty, we'll read the file.
+ if ( m_list.isEmpty() )
+ {
+ read_options();
+ }
+
+ QString host = item.section( "/", 2, 2 ).stripWhiteSpace();
+
+ Smb4KSambaOptionsInfo *info = NULL;
+
+ if ( !item.stripWhiteSpace().isEmpty() )
+ {
+ for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = m_list.begin();
+ it != m_list.end(); ++it )
+ {
+ if ( QString::compare( item.lower(), (*it)->itemName().lower() ) == 0 )
+ {
+ info = *it;
+
+ break;
+ }
+ else if ( QString::compare( host.lower(), (*it)->itemName().lower() ) == 0 )
+ {
+ if ( !info && !exactMatch )
+ {
+ info = *it;
+ }
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ return info;
+}
+
+
+const QString Smb4KSambaOptionsHandler::smbclientOptions( const QString &share )
+{
+ // Get the global Samba options
+ (void) globalSambaOptions();
+
+ Smb4KSambaOptionsInfo *info = find_item( share );
+ QString args = QString::null;
+
+ // Get the strings that are needed to put the
+ // argument list together:
+ QString resolve_order = (!Smb4KSettings::nameResolveOrder().isEmpty() &&
+ QString::compare( Smb4KSettings::nameResolveOrder(),
+ m_samba_options["name resolve order"] ) != 0) ?
+ Smb4KSettings::nameResolveOrder() :
+ QString::null;
+
+ QString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSName(),
+ m_samba_options["netbios name"] ) != 0) ?
+ Smb4KSettings::netBIOSName() :
+ QString::null;
+
+ QString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSScope(),
+ m_samba_options["netbios scope"] ) != 0) ?
+ Smb4KSettings::netBIOSScope() :
+ QString::null;
+
+ QString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
+ QString::compare( Smb4KSettings::socketOptions(),
+ m_samba_options["socket options"] ) != 0) ?
+ Smb4KSettings::socketOptions() :
+ QString::null;
+
+ bool kerberos = info ?
+ info->kerberos() :
+ Smb4KSettings::useKerberos();
+
+ int port = info && info->port() != -1 ?
+ info->port() :
+ Smb4KSettings::remotePort();
+
+ // Options that are not customizable:
+ args.append( !resolve_order.isEmpty() ?
+ QString( " -R '%1'" ).arg( resolve_order ) :
+ QString::null );
+
+ args.append( !netbios_name.isEmpty() ?
+ QString( " -n '%1'" ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( !netbios_scope.isEmpty() ?
+ QString( " -i '%1'" ).arg( netbios_scope ) :
+ QString::null );
+
+ args.append( !socket_options.isEmpty() ?
+ QString( " -O '%1'" ).arg( socket_options ) :
+ QString::null );
+
+ args.append( Smb4KSettings::bufferSize() != 65520 ?
+ QString( " -b %1" ).arg( Smb4KSettings::bufferSize() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::machineAccount() ? " -P" : QString::null );
+
+ switch ( Smb4KSettings::signingState() )
+ {
+ case Smb4KSettings::EnumSigningState::None:
+ {
+ // The user does not want this setting
+ // to be used.
+ break;
+ }
+ case Smb4KSettings::EnumSigningState::On:
+ {
+ args.append( " -S on" );
+
+ break;
+ }
+ case Smb4KSettings::EnumSigningState::Off:
+ {
+ args.append( " -S off" );
+
+ break;
+ }
+ case Smb4KSettings::EnumSigningState::Required:
+ {
+ args.append( " -S required" );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ args.append( kerberos ? " -k" : QString::null );
+
+ args.append( QString( " -p %1" ).arg( port ) );
+
+ return args;
+}
+
+
+const QString Smb4KSambaOptionsHandler::nmblookupOptions( bool with_broadcast )
+{
+ // Get the global Samba options
+ (void) globalSambaOptions();
+
+ QString args = QString::null;
+
+ QString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSName(),
+ m_samba_options["netbios name"] ) != 0) ?
+ Smb4KSettings::netBIOSName() :
+ QString::null;
+
+ QString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSScope(),
+ m_samba_options["netbios scope"] ) != 0) ?
+ Smb4KSettings::netBIOSScope() :
+ QString::null;
+
+ QString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
+ QString::compare( Smb4KSettings::socketOptions(),
+ m_samba_options["socket options"] ) != 0) ?
+ Smb4KSettings::socketOptions() :
+ QString::null;
+
+ QString domain = (!Smb4KSettings::domainName().isEmpty() &&
+ QString::compare( Smb4KSettings::domainName(),
+ m_samba_options["workgroup"] ) != 0) ?
+ Smb4KSettings::domainName() :
+ QString::null;
+
+ args.append( !netbios_name.isEmpty() ?
+ QString( " -n '%1'" ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( !netbios_scope.isEmpty() ?
+ QString( " -i '%1'" ).arg( netbios_scope ) :
+ QString::null );
+
+ args.append( !socket_options.isEmpty() ?
+ QString( " -O '%1'" ).arg( socket_options ) :
+ QString::null );
+
+ args.append( !domain.isEmpty() ?
+ QString( " -W '%1'" ).arg( domain ) :
+ QString::null );
+
+ args.append( (!Smb4KSettings::broadcastAddress().isEmpty() &&
+ with_broadcast) ?
+ QString( " -B %1" ).arg( Smb4KSettings::broadcastAddress() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::usePort137() ?
+ " -r" :
+ QString::null );
+
+ return args;
+}
+
+
+const QString Smb4KSambaOptionsHandler::netOptions( int command, const QString &networkItem, const QString &protocol )
+{
+ QString args = QString::null;
+
+ Smb4KSambaOptionsInfo *info = find_item( networkItem );
+
+ QString protocol_hint;
+
+ // Determine the protocol hint specified by the user:
+ switch ( Smb4KSettings::protocolHint() )
+ {
+ case Smb4KSettings::EnumProtocolHint::Automatic:
+ {
+ // In this case the user leaves it to the net
+ // command to determine the right protocol.
+ protocol_hint = QString::null;
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RPC:
+ {
+ protocol_hint = "rpc";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RAP:
+ {
+ protocol_hint = "rap";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::ADS:
+ {
+ protocol_hint = "ads";
+
+ break;
+ }
+ default:
+ {
+ protocol_hint = QString::null;
+
+ break;
+ }
+ }
+
+ QString default_protocol = (info && !info->protocol().isEmpty()) ?
+ info->protocol() :
+ protocol_hint;
+
+ QString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSName(),
+ m_samba_options["netbios name"] ) != 0) ?
+ Smb4KSettings::netBIOSName() :
+ QString::null;
+
+ QString domain = (!Smb4KSettings::domainName().isEmpty() &&
+ QString::compare( Smb4KSettings::domainName(),
+ m_samba_options["workgroup"] ) != 0) ?
+ Smb4KSettings::domainName() :
+ QString::null;
+
+ int port = (info && info->port() != -1) ?
+ info->port() :
+ Smb4KSettings::remotePort();
+
+ // Add command specific arguments:
+ switch ( command )
+ {
+ case Share:
+ {
+ // We can only use the RAP or RPC protocol here.
+ if ( !protocol.stripWhiteSpace().isEmpty() )
+ {
+ // Protocol can only be defined by us developers,
+ // and we should know what we are doing. So, no
+ // checks for the right protocol here:
+ args.append( QString( " %1" ).arg( protocol ) );
+ }
+ else
+ {
+ args.append( QString( " %1" ).arg( QString::compare( default_protocol, "ads" ) != 0 ?
+ default_protocol :
+ QString::null /* FIXME: Is that the best way how to do it? */) );
+ }
+
+ args.append( " share -l" );
+
+ break;
+ }
+ case ServerDomain:
+ {
+ // NOTE: Since version 3.0.25, the command 'net rap server domain ...'
+ // will through an error. We have to use 'net rap server ...'. This is
+ // also compatible with earlier version.
+
+ // This only works with the rap protocol:
+ args.append( " rap server" );
+
+ break;
+ }
+ case LookupHost:
+ {
+ // Check that the server name is present:
+ if ( networkItem.stripWhiteSpace().isEmpty() )
+ {
+ Smb4KError::error( ERROR_NET_COMMAND, args.stripWhiteSpace() );
+
+ return args; // still empty
+ }
+
+ // This lookup command takes no protocol:
+ args.append( QString( " lookup host %1" ).arg( networkItem ) );
+
+ break;
+ }
+ case LookupMaster:
+ {
+ // Check that the domain name is present:
+ if ( networkItem.stripWhiteSpace().isEmpty() )
+ {
+ Smb4KError::error( ERROR_NET_COMMAND, args.stripWhiteSpace() );
+
+ return args; // still empty
+ }
+
+ // This lookup command takes no protocol:
+ args.append( QString( " lookup master '%1'" ).arg( networkItem ) );
+
+ break;
+ }
+ case Domain:
+ {
+ // This only works with the rap protocol:
+ args.append( " rap domain" );
+
+ break;
+ }
+ default:
+ {
+ // Bypass the rest and return an
+ // empty string:
+ return args;
+ }
+ }
+
+ args.append( !domain.isEmpty() ?
+ QString( " -W '%1'" ).arg( domain ) :
+ QString::null );
+
+ args.append( !netbios_name.isEmpty() ?
+ QString( " -n '%1'" ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( Smb4KSettings::machineAccount() ?
+ " -P" :
+ QString::null );
+
+ args.append( QString( " -p %1" ).arg( port ) );
+
+ return args;
+}
+
+
+const QString Smb4KSambaOptionsHandler::mountOptions( const QString &share )
+{
+ Smb4KSambaOptionsInfo *info = find_item( share );
+ QString args;
+
+ // Read the global Samba options from smb.conf:
+ (void) globalSambaOptions();
+
+ // Get the strings needed to put the argument list together:
+ QString uid = (info && !info->uid().isEmpty()) ?
+ info->uid() :
+ Smb4KSettings::userID();
+
+ QString gid = (info && !info->gid().isEmpty()) ?
+ info->gid() :
+ Smb4KSettings::groupID();
+
+ QString charset, codepage;
+
+ switch ( Smb4KSettings::clientCharset() )
+ {
+ case Smb4KSettings::EnumClientCharset::default_charset:
+ {
+ charset = m_samba_options["unix charset"].lower(); // maybe empty
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_1:
+ {
+ charset = "iso8859-1";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_2:
+ {
+ charset = "iso8859-2";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_3:
+ {
+ charset = "iso8859-3";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_4:
+ {
+ charset = "iso8859-4";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_5:
+ {
+ charset = "iso8859-5";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_6:
+ {
+ charset = "iso8859-6";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_7:
+ {
+ charset = "iso8859-7";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_8:
+ {
+ charset = "iso8859-8";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_9:
+ {
+ charset = "iso8859-9";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_13:
+ {
+ charset = "iso8859-13";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_14:
+ {
+ charset = "iso8859-14";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::iso8859_15:
+ {
+ charset = "iso8859-15";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::utf8:
+ {
+ charset = "utf8";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::koi8_r:
+ {
+ charset = "koi8-r";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::koi8_u:
+ {
+ charset = "koi8-u";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::koi8_ru:
+ {
+ charset = "koi8-ru";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::cp1251:
+ {
+ charset = "cp1251";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::gb2312:
+ {
+ charset = "gb2312";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::big5:
+ {
+ charset = "big5";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::euc_jp:
+ {
+ charset = "euc-jp";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::euc_kr:
+ {
+ charset = "euc-kr";
+
+ break;
+ }
+ case Smb4KSettings::EnumClientCharset::tis_620:
+ {
+ charset = "tis-620";
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ switch ( Smb4KSettings::serverCodepage() )
+ {
+ case Smb4KSettings::EnumServerCodepage::default_codepage:
+ {
+ codepage = m_samba_options["dos charset"].lower(); // maybe empty
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp437:
+ {
+ codepage = "cp437";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp720:
+ {
+ codepage = "cp720";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp737:
+ {
+ codepage = "cp737";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp775:
+ {
+ codepage = "cp775";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp850:
+ {
+ codepage = "cp850";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp852:
+ {
+ codepage = "cp852";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp855:
+ {
+ codepage = "cp855";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp857:
+ {
+ codepage = "cp857";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp858:
+ {
+ codepage = "cp858";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp860:
+ {
+ codepage = "cp860";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp861:
+ {
+ codepage = "cp861";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp862:
+ {
+ codepage = "cp862";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp863:
+ {
+ codepage = "cp863";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp864:
+ {
+ codepage = "cp864";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp865:
+ {
+ codepage = "cp865";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp866:
+ {
+ codepage = "cp866";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp869:
+ {
+ codepage = "cp869";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp874:
+ {
+ codepage = "cp874";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp932:
+ {
+ codepage = "cp932";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp936:
+ {
+ codepage = "cp936";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp949:
+ {
+ codepage = "cp949";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp950:
+ {
+ codepage = "cp950";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1250:
+ {
+ codepage = "cp1250";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1251:
+ {
+ codepage = "cp1251";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1252:
+ {
+ codepage = "cp1252";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1253:
+ {
+ codepage = "cp1253";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1254:
+ {
+ codepage = "cp1254";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1255:
+ {
+ codepage = "cp1255";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1256:
+ {
+ codepage = "cp1256";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1257:
+ {
+ codepage = "cp1257";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::cp1258:
+ {
+ codepage = "cp1258";
+
+ break;
+ }
+ case Smb4KSettings::EnumServerCodepage::unicode:
+ {
+ codepage = "unicode";
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+#ifndef __FreeBSD__
+
+ QString netbios_name = !Smb4KSettings::netBIOSName().isEmpty() ?
+ Smb4KSettings::netBIOSName() :
+ m_samba_options["netbios name"];
+
+ QString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
+ QString::compare( Smb4KSettings::socketOptions(),
+ m_samba_options["socket options"] ) != 0) ?
+ Smb4KSettings::socketOptions() :
+ QString::null;
+
+ QString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSScope(),
+ m_samba_options["netbios scope"] ) != 0) ?
+ Smb4KSettings::netBIOSScope() :
+ QString::null;
+
+ int port = info && info->port() != -1 ?
+ info->port() :
+ Smb4KSettings::remotePort();
+
+ bool kerberos = info ?
+ info->kerberos() :
+ Smb4KSettings::useKerberos();
+
+ bool read_write = info ?
+ info->writeAccess() :
+ (Smb4KSettings::writeAccess() == Smb4KSettings::EnumWriteAccess::ReadWrite);
+
+ // Compile the arguments list:
+ args.append( !netbios_name.isEmpty() ?
+ QString( "netbiosname='%1'," ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( !uid.isEmpty() ?
+ QString( "uid=%1," ).arg( uid ) :
+ QString::null );
+
+ args.append( !gid.isEmpty() ?
+ QString( "gid=%1," ).arg( gid ) :
+ QString::null );
+
+ args.append( QString( "port=%1," ).arg( port ) );
+
+ args.append( !charset.isEmpty() ?
+ QString( "iocharset=%1," ).arg( charset ) :
+ QString::null );
+
+ args.append( read_write ? "rw," : "ro," );
+
+ switch ( Smb4KSettings::filesystem() )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ args.append( !Smb4KSettings::fileMask().isEmpty() ?
+ QString( "file_mode=%1," ).arg( Smb4KSettings::fileMask() ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::directoryMask().isEmpty() ?
+ QString( "dir_mode=%1," ).arg( Smb4KSettings::directoryMask() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::permissionChecks() ?
+ "perm," :
+ "noperm," );
+
+ args.append( Smb4KSettings::clientControlsIDs() ?
+ "setuids," :
+ "nosetuids," );
+
+ args.append( Smb4KSettings::serverInodeNumbers() ?
+ "serverino," :
+ "noserverino," );
+
+ args.append( Smb4KSettings::inodeDataCaching() ?
+ "directio," :
+ QString::null ); // FIXME: Does 'nodirectio' exist?
+
+ args.append( Smb4KSettings::translateReservedChars() ?
+ "mapchars," :
+ "nomapchars," );
+
+ args.append( Smb4KSettings::noLocking() ?
+ "nolock," :
+ QString::null ); // FIXME: Does 'lock' exist?
+
+ args.append( !Smb4KSettings::customCIFSOptions().isEmpty() ?
+ Smb4KSettings::customCIFSOptions() :
+ QString::null );
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ args.append( !socket_options.isEmpty() ?
+ QString( "sockopt='%1'," ).arg( socket_options ) :
+ QString::null );
+
+ args.append( !netbios_scope.isEmpty() ?
+ QString( "scope=%1," ).arg( netbios_scope ) :
+ QString::null );
+
+ args.append( !codepage.isEmpty() ?
+ QString( "codepage=%1," ).arg( codepage ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::fileMask().isEmpty() ?
+ QString( "fmask=%1," ).arg( Smb4KSettings::fileMask() ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::directoryMask().isEmpty() ?
+ QString( "dmask=%1," ).arg( Smb4KSettings::directoryMask() ) :
+ QString::null );
+
+ args.append( kerberos ? "krb," : QString::null );
+
+ args.append( Smb4KSettings::cachingTime() != 1000 ?
+ QString( "ttl=%1," ).arg( Smb4KSettings::cachingTime() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::unicodeSupport() ?
+ "unicode," :
+ QString::null );
+
+ args.append( Smb4KSettings::largeFileSystemSupport() ?
+ "lfs," :
+ QString::null );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+#else
+
+ // Compile the arguments list:
+ args.append( !uid.isEmpty() ?
+ QString( " -u %1" ).arg( uid ) :
+ QString::null );
+
+ args.append( !gid.isEmpty() ?
+ QString( " -g %1" ).arg( gid ) :
+ QString::null );
+
+ args.append( !charset.isEmpty() && !codepage.isEmpty() ?
+ QString( " -E %1:%2" ).arg( charset, codepage ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::fileMask().isEmpty() ?
+ QString( " -f %1" ).arg( Smb4KSettings::fileMask() ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::directoryMask().isEmpty() ?
+ QString( " -d %1" ).arg( Smb4KSettings::directoryMask() ) :
+ QString::null );
+
+ // NOTE: Under FreeBSD the port must be managed by the mounter.
+
+ // FIXME: If the manual page was of more use, we could probably implement
+ // more of the arguments that are available for mount_smbfs.
+
+#endif
+
+ return args;
+}
+
+
+void Smb4KSambaOptionsHandler::read_smb_conf()
+{
+ // Clear the options list before reading.
+ m_samba_options.clear();
+
+ QStringList paths;
+ paths << "/etc";
+ paths << "/etc/samba";
+ paths << "/usr/local/etc";
+ paths << "/usr/local/etc/samba";
+
+ QFile f( "smb.conf" );
+
+ QStringList contents;
+
+ // Locate the file and read its contents:
+ for ( QStringList::Iterator it = paths.begin(); it != paths.end(); ++it )
+ {
+ QDir::setCurrent( *it );
+
+ if ( f.exists() )
+ {
+ if ( f.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &f );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( '\n', ts.read(), false );
+ }
+
+ f.close();
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ // Process the file contents.
+ for ( QStringList::Iterator it = contents.erase( contents.begin(), ++(contents.find( "[global]" )) ); it != contents.end(); ++it )
+ {
+ if ( (*it).stripWhiteSpace().startsWith( "#" ) || (*it).stripWhiteSpace().startsWith( ";" ) )
+ {
+ *it = QString::null;
+ }
+ else if ( (*it).stripWhiteSpace().startsWith( "include" ) )
+ {
+ // Put the contents of the included at this position.
+ QString file = (*it).section( "=", 1, 1 ).stripWhiteSpace();
+ *it = QString::null;
+ f.setName( file );
+
+ QStringList include;
+
+ if ( f.exists() )
+ {
+ if ( f.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &f );
+ ts.setEncoding( QTextStream::Locale );
+
+ include = QStringList::split( '\n', ts.read(), false );
+ }
+
+ f.close();
+ }
+
+ for ( QStringList::Iterator i = include.begin(); i != include.end(); ++i )
+ {
+ if ( !(*i).stripWhiteSpace().isEmpty() )
+ {
+ contents.insert( it, *i );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ continue;
+ }
+ else if ( (*it).startsWith( "[" ) )
+ {
+ contents.erase( it, contents.end() );
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ contents.remove( QString::null );
+
+ // Write all options into the map:
+ for ( QStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
+ {
+ QString key = (*it).section( "=", 0, 0 ).stripWhiteSpace().lower();
+ m_samba_options[key] = QString( (*it).section( "=", 1, 1 ).stripWhiteSpace().upper() );
+ }
+
+ // Post-processing. Some values should be entered with their defaults, if they are
+ // not already present.
+ if ( !m_samba_options.contains( "netbios name" ) )
+ {
+ size_t hostnamelen = 255;
+ char *hostname = new char[hostnamelen];
+
+ if ( gethostname( hostname, hostnamelen ) == -1 )
+ {
+ int error = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, QString::null, strerror( error ) );
+ }
+ else
+ {
+ m_samba_options["netbios name"] = ( QString( "%1" ).arg( hostname ) ).upper();
+ }
+
+ delete [] hostname;
+ }
+}
+
+
+const QMap<QString,QString> &Smb4KSambaOptionsHandler::globalSambaOptions()
+{
+ if ( m_samba_options.isEmpty() )
+ {
+ read_smb_conf();
+ }
+
+ return m_samba_options;
+}
+
+
+const QString &Smb4KSambaOptionsHandler::winsServer()
+{
+ if ( m_wins_server.isEmpty() )
+ {
+ (void) globalSambaOptions();
+
+ if ( !m_samba_options["wins server"].isEmpty() )
+ {
+ m_wins_server = m_samba_options["wins server"];
+ }
+ else if ( !m_samba_options["wins support"].isEmpty() &&
+ (QString::compare( m_samba_options["wins support"].lower(), "yes" ) == 0 ||
+ QString::compare( m_samba_options["wins support"].lower(), "true" ) == 0) )
+ {
+ m_wins_server = "127.0.0.1";
+ }
+ }
+
+ return m_wins_server;
+}
+
+
+void Smb4KSambaOptionsHandler::addItem( Smb4KSambaOptionsInfo *info, bool s )
+{
+ Smb4KSambaOptionsInfo *item = find_item( info->itemName() );
+
+ if ( item && QString::compare( item->itemName().lower(), info->itemName().lower() ) == 0 )
+ {
+ item->setPort( info->port() );
+#ifndef __FreeBSD__
+ item->setFilesystem( info->filesystem() );
+ item->setWriteAccess( info->writeAccess() );
+#endif
+ item->setRemount( info->remount() );
+ item->setProtocol( info->protocol() );
+ item->setKerberos( info->kerberos() );
+ item->setUID( info->uid() );
+ item->setGID( info->gid() );
+
+ delete info;
+ }
+ else
+ {
+ m_list.append( info );
+ }
+
+ if ( s )
+ {
+ sync();
+ }
+}
+
+
+void Smb4KSambaOptionsHandler::removeItem( const QString &name, bool s )
+{
+ Smb4KSambaOptionsInfo *item = find_item( name );
+
+ if ( item && QString::compare( item->itemName().lower(), name.lower() ) == 0 )
+ {
+ m_list.remove( item );
+ delete item;
+ }
+
+ if ( s )
+ {
+ sync();
+ }
+}
+
+#include "smb4ksambaoptionshandler.moc"
diff --git a/smb4k/core/smb4ksambaoptionshandler.h b/smb4k/core/smb4ksambaoptionshandler.h
new file mode 100644
index 0000000..6bb5565
--- /dev/null
+++ b/smb4k/core/smb4ksambaoptionshandler.h
@@ -0,0 +1,253 @@
+/***************************************************************************
+ smb4ksambaoptionshandler - This class handles the Samba options.
+ -------------------
+ begin : So Mai 14 2006
+ copyright : (C) 2006-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSAMBAOPTIONSHANDLER_H
+#define SMB4KSAMBAOPTIONSHANDLER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qmap.h>
+
+// KDE includes
+#include <kconfig.h>
+
+// forward declarations
+class Smb4KSambaOptionsInfo;
+class Smb4KShare;
+
+
+/**
+ * This class belongs to the core classes of Smb4K and handles the global
+ * and the custom Samba options.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSambaOptionsHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent object
+ *
+ * @param name The name of this object
+ */
+ Smb4KSambaOptionsHandler( QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSambaOptionsHandler();
+
+ /**
+ * Retrieve the list of shares that have custom options defined.
+ * You will not only get those options that have different ports etc.
+ * defined but also all shares that are to be remounted.
+ *
+ * @returns the list of all shares that have custom options defined.
+ */
+ const QValueList<Smb4KSambaOptionsInfo *> &customOptionsList();
+
+ /**
+ * This functions sets the remount flag of the share @p share to TRUE or FALSE.
+ * In case the share is not yet in the list of shares that are to be remounted,
+ * it will be added. If you set the remount flag to FALSE on an existing entry,
+ * it will stay in the list even if no other custom options were defined.
+ *
+ * @param share The Smb4KShare object that represents the share
+ *
+ * @param yes TRUE if you want the share to be remounted and FALSE
+ * otherwise
+ */
+ void remount( Smb4KShare *share, bool yes );
+
+ /**
+ * Commit the whole list of shares with custom options to the configuration
+ * file. You should call this if you exit the application.
+ */
+ void sync();
+
+ /**
+ * This function returns the line of arguments for the 'smbclient' program.
+ * The arguments are spcific to the share that is defined by @p share. You have
+ * to provide the name of the shares - as always - in the form //HOST/SHARE.
+ *
+ * @param share The name of the share.
+ *
+ * @returns a list of arguments for use with the 'smbclient' program.
+ */
+ const QString smbclientOptions( const QString &share = QString::null );
+
+ /**
+ * This function returns the "global" options for nmblookup, i.e. the domain
+ * the client is in, if Kerberos should be used, etc.
+ *
+ * @param with_broadcast Return the global broadcast address if defined.
+ *
+ * @returns a string with the "global" options for nmblookup
+ */
+ const QString nmblookupOptions( bool with_broadcast = true );
+
+ /**
+ * This function returns the options defined in the global section of the smb.conf
+ * file. All option names have been converted to lower case and you can find each
+ * entry by providing the option name in lowercase (!) as key.
+ *
+ * @returns a list of the options defined in smb.conf.
+ */
+ const QMap<QString,QString> &globalSambaOptions();
+
+ /**
+ * This function returns the WINS server the system is using.
+ *
+ * @returns the name or IP of the WINS server
+ */
+ const QString &winsServer();
+
+ /**
+ * This enumeration is for use with the netOptions() function. It tells which
+ * command to use.
+ */
+ enum NetCommand { Share, ServerDomain, LookupHost, LookupMaster, Domain };
+
+ /**
+ * This function returns the options for the net command.
+ *
+ * @param command One of the entries of the NetCommand enumeration.
+ *
+ * @param networkItem The name of the network Item. May be empty.
+ *
+ * @param protocol Force a certain protocol (rap/rpc/ads) to be used.
+ *
+ * @returns the list of arguments for the net command or QString::null if an error occurred.
+ */
+ const QString netOptions( int command, const QString &networkItem, const QString &protocol = QString::null );
+
+ /**
+ * This function returns the options for smbmount/mount.cifs under Linux
+ * and similar operating systems or for mount_smbfs under FreeBSD.
+ *
+ * Note: Under Linux etc. this is a comma-separated list which ends with
+ * a comma, so remember this when you build up the command line.
+ *
+ * @param share The share that is to be mounted.
+ */
+ const QString mountOptions( const QString &share );
+
+ /**
+ * Find a network item in the list.
+ *
+ * Please note that if the host where a share you are probing for
+ * is located, a pointer to this *host* item will be returned unless
+ * you set @p exactMatch to TRUE in which case NULL is returned! If
+ * neither the host nor the share is found, NULL is returned.
+ *
+ * @param item The name of the network item to find.
+ *
+ * @param exactMatch The name has to match exactly the result that's returned.
+ *
+ * @returns the network item.
+ */
+ Smb4KSambaOptionsInfo *findItem( const QString &item, bool exactMatch = false ) { return find_item( item, exactMatch ); }
+
+ /**
+ * Add a new Smb4KSambaOptionsInfo object to the list of custom options. If the item already exists,
+ * the old options will be replaced by the new ones.
+ *
+ * @param info The Smb4KSambaOptionsInfo object
+ *
+ * @param sync If TRUE, the list is sync'ed with the config file.
+ */
+ void addItem( Smb4KSambaOptionsInfo *info, bool sync );
+
+ /**
+ * Remove an item from the list.
+ *
+ * @param name The name of the item.
+ *
+ * @param sync If TRUE, the list is sync'ed with the config file.
+ */
+ void removeItem( const QString &name, bool sync );
+
+ private:
+ /**
+ * The list of network items that have custom options defined.
+ */
+ QValueList<Smb4KSambaOptionsInfo *> m_list;
+
+ /**
+ * This function reads the options from the config file.
+ */
+ void read_options();
+
+ /**
+ * Write the list of custom shares to the file.
+ */
+ void write_options();
+
+ /**
+ * This function searches a particular network item in the list. If this item is a share
+ * and it is not found, @p exactMatch determines if NULL is returned or if the values of
+ * the item that matches @p item closest (i.e. the host, or another share that's located
+ * on the host). In most cases you want @p exactMatch to be FALSE.
+ * Please note: Do not delete the pointer that's returned by this function or you will
+ * remove an item from the list!
+ *
+ * @param item The name of the network item.
+ *
+ * @param exactMatch The name has to match exactly the result that's returned.
+ *
+ * @returns The Smb4KSambaOptionsInfo object associated with the network item.
+ */
+ Smb4KSambaOptionsInfo *find_item( const QString &item, bool exactMatch = false );
+
+ /**
+ * This function reads the entries of the global section of Samba's configuration
+ * file smb.conf and puts them into a map.
+ */
+ void read_smb_conf();
+
+ /**
+ * This map carries the options defined in the [global] section of Samba's configuration
+ * file smb.conf. You can access a certain value by providing the lower case option name
+ * as key.
+ */
+ QMap<QString,QString> m_samba_options;
+
+ /**
+ * The WINS server
+ */
+ QString m_wins_server;
+};
+
+
+#endif
diff --git a/smb4k/core/smb4ksambaoptionsinfo.cpp b/smb4k/core/smb4ksambaoptionsinfo.cpp
new file mode 100644
index 0000000..5ea5b51
--- /dev/null
+++ b/smb4k/core/smb4ksambaoptionsinfo.cpp
@@ -0,0 +1,137 @@
+/***************************************************************************
+ smb4ksambaoptionsinfo - This is a container class that carries
+ various information of extra options for a specific host.
+ -------------------
+ begin : Mi Okt 18 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+// application specific includes
+#include "smb4ksambaoptionsinfo.h"
+#include "smb4kshare.h"
+
+
+Smb4KSambaOptionsInfo::Smb4KSambaOptionsInfo( const QString &name )
+: m_name( name ), m_remount( false ), m_port( -1 ),
+#ifndef __FreeBSD__
+m_filesystem( QString::null ), m_write_access( true ),
+#endif
+m_protocol( QString::null ), m_kerberos( false ),
+m_uid( QString::null ), m_gid( QString::null )
+{
+}
+
+
+Smb4KSambaOptionsInfo::Smb4KSambaOptionsInfo( Smb4KShare *share )
+: m_name( share->name() ), m_remount( false ), m_port( -1 ),
+#ifndef __FreeBSD__
+m_filesystem( share->filesystem() ), m_write_access( true ),
+#endif
+m_protocol( QString::null ), m_kerberos( false ),
+m_uid( QString( "%1" ).arg( share->uid() ) ), m_gid( QString( "%1" ).arg( share->gid() ) )
+{
+}
+
+
+
+Smb4KSambaOptionsInfo::Smb4KSambaOptionsInfo( const Smb4KSambaOptionsInfo &info )
+: m_name( info.itemName() ), m_remount( info.remount() ), m_port( info.port() ),
+#ifndef __FreeBSD__
+m_filesystem( info.filesystem() ), m_write_access( info.writeAccess() ),
+#endif
+m_protocol( info.protocol() ), m_kerberos( info.kerberos() ),
+m_uid( info.uid() ), m_gid( info.gid() )
+{
+}
+
+
+Smb4KSambaOptionsInfo::~Smb4KSambaOptionsInfo()
+{
+}
+
+
+void Smb4KSambaOptionsInfo::setRemount( bool rm )
+{
+ m_remount = rm;
+}
+
+
+void Smb4KSambaOptionsInfo::setItemName( const QString &name )
+{
+ m_name = name;
+}
+
+
+void Smb4KSambaOptionsInfo::setPort( int port )
+{
+ m_port = port;
+}
+
+void Smb4KSambaOptionsInfo::setProtocol( const QString &p )
+{
+ if ( QString::compare( p, "auto" ) != 0 )
+ {
+ m_protocol = p;
+ }
+ else
+ {
+ m_protocol = QString::null;
+ }
+}
+
+
+void Smb4KSambaOptionsInfo::setKerberos( bool krb )
+{
+ m_kerberos = krb;
+}
+
+
+int Smb4KSambaOptionsInfo::type()
+{
+ return m_name.contains( "/" ) == 3 ? Share : Host;
+}
+
+
+void Smb4KSambaOptionsInfo::setUID( const QString &uid )
+{
+ m_uid = uid;
+}
+
+
+void Smb4KSambaOptionsInfo::setGID( const QString &gid )
+{
+ m_gid = gid;
+}
+
+#ifndef __FreeBSD__
+void Smb4KSambaOptionsInfo::setFilesystem( const QString &fs )
+{
+ m_filesystem = fs;
+}
+
+
+void Smb4KSambaOptionsInfo::setWriteAccess( bool rw )
+{
+ m_write_access = rw;
+}
+#endif
+
diff --git a/smb4k/core/smb4ksambaoptionsinfo.h b/smb4k/core/smb4ksambaoptionsinfo.h
new file mode 100644
index 0000000..706aa66
--- /dev/null
+++ b/smb4k/core/smb4ksambaoptionsinfo.h
@@ -0,0 +1,291 @@
+/***************************************************************************
+ smb4ksambaoptionsinfo - This is a container class that carries
+ various information of extra options for a specific host.
+ -------------------
+ begin : Mi Okt 18 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSAMBAOPTIONSINFO_H
+#define SMB4KSAMBAOPTIONSINFO_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qstring.h>
+
+// forward declarations
+class Smb4KShare;
+
+
+/**
+ * This class provides a container for all extra options that the user defined
+ * for a certain share.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSambaOptionsInfo
+{
+ public:
+ /**
+ * Constructor. It takes the name of the network item in the form
+ * HOST or //HOST/SHARE as only argument. If you use this constructor, you
+ * need to use the set* functions to add information.
+ *
+ * @param name The network item's name.
+ */
+ Smb4KSambaOptionsInfo( const QString &name );
+
+ /**
+ * Constructor. It takes a Smb4KShare object and extracts the name and the
+ * filesystem from it. All other information has to be set with the set*
+ * functions.
+ *
+ * @param share A Smb4KShare object representing a share.
+ */
+ Smb4KSambaOptionsInfo( Smb4KShare *share );
+
+ /**
+ * The copy constructor.
+ *
+ * @param info A Smb4KShareOptionsInfo object
+ */
+ Smb4KSambaOptionsInfo( const Smb4KSambaOptionsInfo &info );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSambaOptionsInfo();
+
+ /**
+ * Sets the "should be remounted" flag.
+ *
+ * @param rm TRUE if the share is to be remounted and
+ * FALSE otherwise.
+ */
+ void setRemount( bool rm );
+
+ /**
+ * Returns TRUE if the share is to be remounted and FALSE otherwise.
+ *
+ * @returns TRUE if the share is to be remounted and FALSE otherwise
+ */
+ bool remount() const { return m_remount; }
+
+ /**
+ * This function sets the item name.
+ *
+ * @param name The name of the network item
+ */
+ void setItemName( const QString &name );
+
+ /**
+ * This function returns the name of the network item, i.e. the server or
+ * share.
+ *
+ * @returns the name of the network item.
+ */
+ const QString &itemName() const { return m_name; }
+
+ /**
+ * This function sets the port that should be used when querying this share.
+ *
+ * @param port The port number
+ */
+ void setPort( int port );
+
+ /**
+ * This function returns the port that should be used when working with this
+ * share. Please note, that it will be returned as an integer. If no port has been
+ * defined, -1 will be returned.
+ *
+ * @returns the port number
+ */
+ int port() const { return m_port; }
+
+ /**
+ * This function sets the protocol to use with the net command. If @p protocol
+ * is equal to "auto", the protocol will automatically be set to "" internally,
+ * so that Smb4KSambaOptionsInfo::protocol() returns an empty string.
+ *
+ * @param protocol the protocol
+ */
+ void setProtocol( const QString &protocol );
+
+ /**
+ * This function returns the protocol to use with the net command.
+ *
+ * @retuns the protocol
+ */
+ const QString &protocol() const { return m_protocol; }
+
+ /**
+ * Set the 'Use Kerberos' flag.
+ *
+ * @param krb TRUE if the user wants to use Kerberos
+ * and FALSE otherwise.
+ */
+ void setKerberos( bool krb );
+
+ /**
+ * This functions returns TRUE if the user wants to use Kerberos and
+ * otherwise it returns FALSE.
+ *
+ * @returns TRUE if Kerberos should be used and FALSE
+ * otherwise.
+ */
+ bool kerberos() const { return m_kerberos; }
+
+ /**
+ * With this function you can set the UID you want to use for this item.
+ * However, it makes only sense with shares.
+ *
+ * @param uid The UID
+ */
+ void setUID( const QString &uid );
+
+ /**
+ * This functions returns the UID defined for this item.
+ *
+ * @returns the UID.
+ */
+ const QString &uid() const { return m_uid; }
+
+ /**
+ * With this function you can set the GID you want to use for this item.
+ * However, it makes only sense with shares.
+ *
+ * @param gid The GID
+ */
+ void setGID( const QString &gid );
+
+ /**
+ * This functions returns the GID defined for this item.
+ *
+ * @returns the GID.
+ */
+ const QString &gid() const { return m_gid; }
+
+ /**
+ * This function returns the type of the network item for which the options
+ * have been defined.
+ *
+ * @returns the type according to the Type enumeration.
+ */
+ int type();
+
+ /**
+ * The Type enumeration.
+ */
+ enum Type { Share, Host };
+
+#ifndef __FreeBSD__
+ /**
+ * This function sets the file system that is to be used when mounting the share.
+ *
+ * Note: This function is not available und FreeBSD.
+ *
+ * @param fs the file system name
+ */
+ void setFilesystem( const QString &fs );
+
+ /**
+ * This function returns the file system that is to be used.
+ *
+ * Note: This function is not available und FreeBSD.
+ *
+ * @returns the file system name
+ */
+ const QString &filesystem() const { return m_filesystem; }
+
+ /**
+ * Set if the share is to be mounted read-write or read-only.
+ *
+ * Note: This function is not available und FreeBSD.
+ *
+ * @param rw TRUE if read-write and FALSE otherwise.
+ */
+ void setWriteAccess( bool rw );
+
+ /**
+ * This functions returns TRUE if the user wants to mount a share read-write
+ * otherwise it returns FALSE.
+ *
+ * Note: This function is not available und FreeBSD.
+ *
+ * @returns TRUE if read-write and FALSE otherwise.
+ */
+ bool writeAccess() const { return m_write_access; }
+#endif
+
+ private:
+ /**
+ * The share name.
+ */
+ QString m_name;
+
+ /**
+ * Should be remounted?
+ */
+ bool m_remount;
+
+ /**
+ * The port number
+ */
+ int m_port;
+
+#ifndef __FreeBSD__
+ /**
+ * The file system
+ */
+ QString m_filesystem;
+
+ /**
+ * Mount read-write or read-only?
+ */
+ bool m_write_access;
+#endif
+
+ /**
+ * The protocol
+ */
+ QString m_protocol;
+
+ /**
+ * Use Kerberos or not
+ */
+ bool m_kerberos;
+
+ /**
+ * The UID
+ */
+ QString m_uid;
+
+ /**
+ * The GID
+ */
+ QString m_gid;
+};
+
+#endif
diff --git a/smb4k/core/smb4kscanner.cpp b/smb4k/core/smb4kscanner.cpp
new file mode 100644
index 0000000..737bf55
--- /dev/null
+++ b/smb4k/core/smb4kscanner.cpp
@@ -0,0 +1,1720 @@
+/***************************************************************************
+ smb4kscanner.cpp - The network scan core class of Smb4K.
+ -------------------
+ begin : Sam Mai 31 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qapplication.h>
+#include <qmap.h>
+#include <qdeepcopy.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <ksocketaddress.h>
+
+// system includes
+#include <stdlib.h>
+
+// Application specific includes.
+#include "smb4kscanner.h"
+#include "smb4kscanner_p.h"
+#include "smb4kauthinfo.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4ksambaoptionshandler.h"
+#include "smb4kpasswordhandler.h"
+#include "smb4knetworkitems.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+static bool created_workgroups_list = false;
+static bool created_hosts_list = false;
+
+
+
+Smb4KScanner::Smb4KScanner( QValueList<Smb4KWorkgroupItem *> *workgroups, QValueList<Smb4KHostItem *> *hosts,
+QObject *parent, const char *name )
+: QObject( parent, name ), m_workgroups_list( workgroups ), m_hosts_list( hosts )
+{
+ m_priv = new Smb4KScannerPrivate;
+
+ if ( !m_workgroups_list )
+ {
+ created_workgroups_list = true;
+ m_workgroups_list = new QValueList<Smb4KWorkgroupItem *>;
+ }
+ else
+ {
+ // The list was passed to the constructor from outside.
+ }
+
+ if ( !m_hosts_list )
+ {
+ created_hosts_list = true;
+ m_hosts_list = new QValueList<Smb4KHostItem *>;
+ }
+ else
+ {
+ // The list was passed to the constructor from outside.
+ }
+
+ m_proc = new KProcess( this, "ScannerMainProcess" );
+ m_proc->setUseShell( true );
+
+ m_working = false;
+
+ m_queue.setAutoDelete( true );
+
+ connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( slotProcessExited( KProcess * ) ) );
+
+ connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
+}
+
+
+Smb4KScanner::~Smb4KScanner()
+{
+ abort();
+
+ // Delete the list of workgroups, if necessary:
+ if ( created_workgroups_list )
+ {
+ for ( QValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_workgroups_list->clear();
+
+ delete m_workgroups_list;
+ }
+ else
+ {
+ // The list of workgroups is handled outside of this class.
+ }
+
+ // Delete the list of hosts, if necessary:
+ if ( created_hosts_list )
+ {
+ for ( QValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_hosts_list->clear();
+
+ delete m_hosts_list;
+ }
+ else
+ {
+ // The list of hosts is handled outside of this class.
+ }
+
+ delete m_priv;
+}
+
+
+void Smb4KScanner::init()
+{
+ m_timer_id = startTimer( TIMER_INTERVAL );
+ rescan();
+}
+
+
+void Smb4KScanner::rescan()
+{
+ m_queue.enqueue( new QString( QString( "%1:" ).arg( Init ) ) );
+}
+
+
+/****************************************************************************
+ Scans for workgroup members. (public part)
+****************************************************************************/
+
+void Smb4KScanner::getWorkgroupMembers( const QString &workgroup, const QString &master, const QString &ip )
+{
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4" ).arg( Hosts ).arg( workgroup, master, ip ) ) );
+}
+
+
+/****************************************************************************
+ Scans for shares on a selected host. (public part)
+****************************************************************************/
+
+void Smb4KScanner::getShares( const QString &workgroup, const QString &host, const QString &ip, const QString &protocol )
+{
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4:%5" ).arg( Shares ).arg( workgroup, host, ip ).arg( protocol ) ) );
+}
+
+
+/****************************************************************************
+ Gets more info on a selected host. (public part)
+****************************************************************************/
+
+void Smb4KScanner::getInfo( const QString &workgroup, const QString &host, const QString &ip )
+{
+ Smb4KHostItem *item = getHost( host, workgroup );
+
+ if ( item && item->infoChecked() )
+ {
+ emit info( item );
+
+ return;
+ }
+ else
+ {
+ // Avoid several queueing up:
+ item->setInfoChecked( true );
+ }
+
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4" ).arg( Info ).arg( workgroup, host, ip ) ) );
+}
+
+
+/****************************************************************************
+ Searches for a host. (public part)
+****************************************************************************/
+
+void Smb4KScanner::search( const QString &host )
+{
+ // Check whether we already have this host in
+ // the list:
+ Smb4KHostItem *item = getHost( host );
+
+ if ( item )
+ {
+ emit searchResult( item );
+
+ return;
+ }
+
+ m_queue.enqueue( new QString( QString( "%1:%2" ).arg( Search ).arg( host ) ) );
+}
+
+
+/****************************************************************************
+ Aborts any process that is running.
+****************************************************************************/
+
+void Smb4KScanner::abort()
+{
+ m_queue.clear();
+
+ if ( m_proc->isRunning() )
+ {
+ m_proc->kill();
+ }
+}
+
+
+/****************************************************************************
+ This function retrieves the initial browse list
+****************************************************************************/
+
+void Smb4KScanner::scanNetwork()
+{
+ abort();
+
+ QString command;
+
+ // Look up the workgroups/domains and their master browsers.
+ // At the moment we have three methods:
+ // (1) Smb4KSettings::EnumBrowseList::LookupDomains: This method is
+ // the most reliable one. It uses nmblookup and will only find
+ // *active* workgroup master browsers and thus active domains.
+ // (2) Smb4KSettings::EnumBrowseList::QueryCurrentMaster: This
+ // method will query the current master browser of the local
+ // workgroup/domain. This method is not as reliable as the first
+ // one, because you might get wrong (i. e. outdated) master
+ // browsers for the workgroups or even empty workgroups.
+ // (3) Smb4KSettings::EnumBrowseList::QueryCustomMaster: This method
+ // is similar to the second one, but the user has defined a fixed
+ // host name or IP address.
+ // (4) Smb4KSettings::EnumBrowseList::ScanBroadcastAreas: Scan the
+ // user given broadcast addresses for active hosts (IP scan)
+
+ switch ( Smb4KSettings::browseList() )
+ {
+ case Smb4KSettings::EnumBrowseList::LookupDomains:
+ {
+ command.append( "nmblookup -M " );
+ command.append( optionsHandler()->nmblookupOptions() );
+ command.append( " -- - | grep '<01>' | awk '{print $1}'" );
+ command.append( !optionsHandler()->winsServer().isEmpty() ?
+ QString( " | xargs nmblookup -R -U %1 -A " ).arg( optionsHandler()->winsServer() ) :
+ " | xargs nmblookup -A " );
+ command.append( optionsHandler()->nmblookupOptions() );
+
+ *m_proc << command;
+
+ startProcess( Workgroups );
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::QueryCurrentMaster:
+ {
+ command.append( "net " );
+ command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::LookupMaster,
+ Smb4KSettings::domainName() ) );
+ command.append( " -U % | xargs net " );
+ command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::Domain,
+ QString::null ) );
+ command.append( " -U % -S" );
+
+ *m_proc << command;
+
+ startProcess( QueryHost );
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::QueryCustomMaster:
+ {
+ command.append( "net " );
+ command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::LookupHost,
+ Smb4KSettings::customMasterBrowser() ) );
+ command.append( " -U % -S "+KProcess::quote( Smb4KSettings::customMasterBrowser() ) );
+ command.append( " | xargs net " );
+ command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::Domain,
+ QString::null ) );
+ command.append( " -U % -S "+KProcess::quote( Smb4KSettings::customMasterBrowser() )+" -I " );
+
+ *m_proc << command;
+
+ startProcess( QueryHost );
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::ScanBroadcastAreas:
+ {
+ // Get the broadcast addresses that are to be scanned:
+ QStringList addresses = QStringList::split( ",", Smb4KSettings::broadcastAreas(), false );
+
+ // Build the command:
+ for ( QStringList::ConstIterator it = addresses.begin(); it != addresses.end(); ++it )
+ {
+ if ( !(*it).isEmpty() )
+ {
+ command.append( "nmblookup " );
+ // We want all globally defined options for nmblookup, except
+ // the broadcast address, because that is needed for the IP
+ // scan:
+ command.append( optionsHandler()->nmblookupOptions( false ) );
+ command.append( " -B "+*it+" -- '*' " );
+ command.append( "| sed -e /querying/d | awk '{print $1}' " );
+ command.append( "| xargs nmblookup " );
+ // This time we want to have the globally defined broadcast
+ // address:
+ command.append( optionsHandler()->nmblookupOptions() );
+ // Include the WINS server:
+ command.append( !optionsHandler()->winsServer().isEmpty() ?
+ " -R -U "+optionsHandler()->winsServer()+" " : "" );
+ command.append( " -A" );
+ command.append( " ; " );
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ // Get rid of the last 3 characters (" ; "):
+ command.truncate( command.length() - 3 );
+
+ *m_proc << command;
+
+ startProcess( IPScan );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ Scans for workgroup members. (private part)
+****************************************************************************/
+
+void Smb4KScanner::scanForWorkgroupMembers( const QString &workgroup, const QString &master, const QString &ip )
+{
+ m_priv->setWorkgroup( workgroup );
+ m_priv->setHost( master );
+ m_priv->setIP( ip );
+
+ QString command;
+
+ if ( !ip.isEmpty() )
+ {
+ command.append( "net "+optionsHandler()->netOptions( Smb4KSambaOptionsHandler::ServerDomain, QString::null ) );
+ command.append( " -I "+ip );
+ command.append( " -w "+KProcess::quote( workgroup ) );
+ command.append( " -S "+KProcess::quote( master ) );
+
+ Smb4KAuthInfo authInfo( workgroup, master, QString::null );
+ (void) passwordHandler()->readAuth( &authInfo );
+
+ if ( !authInfo.user().isEmpty() )
+ {
+ command.append( QString( " -U %1" ).arg( KProcess::quote( authInfo.user() ) ) );
+
+ if ( !authInfo.password().isEmpty() )
+ {
+ m_proc->setEnvironment( "PASSWD", authInfo.password() );
+ }
+ }
+ else
+ {
+ command.append( " -U %" );
+ }
+ }
+ else
+ {
+ command.append( "net "+optionsHandler()->netOptions( Smb4KSambaOptionsHandler::LookupHost, KProcess::quote( master ) ) );
+ command.append( " -S "+KProcess::quote( master )+" -w "+KProcess::quote( workgroup )+" -U % " );
+ // FIXME: Maybe we need to know the shell if the user does not use a
+ // sh-compatible one...?
+ command.append( "| xargs -IIPADDR " );
+ command.append( getenv( "SHELL" ) );
+ command.append( " -c 'echo \"*** "+master+": IPADDR ***\" && " );
+ command.append( "net "+optionsHandler()->netOptions( Smb4KSambaOptionsHandler::ServerDomain, QString::null ) );
+ command.append( " -I IPADDR" );
+ command.append( " -w "+KProcess::quote( workgroup ) );
+ command.append( " -S "+KProcess::quote( master ) );
+
+ Smb4KAuthInfo authInfo( workgroup, master, QString::null );
+ (void) passwordHandler()->readAuth( &authInfo );
+
+ if ( !authInfo.user().isEmpty() )
+ {
+ command.append( QString( " -U %1'" ).arg( KProcess::quote( authInfo.user() ) ) );
+
+ if ( !authInfo.password().isEmpty() )
+ {
+ m_proc->setEnvironment( "PASSWD", authInfo.password() );
+ }
+ }
+ else
+ {
+ command.append( " -U %'" );
+ }
+ }
+
+ *m_proc << command;
+
+ startProcess( Hosts );
+}
+
+
+/****************************************************************************
+ Scans for shares on a selected host. (private part)
+****************************************************************************/
+
+void Smb4KScanner::scanForShares( const QString &workgroup, const QString &host, const QString &ip, const QString &protocol )
+{
+ m_priv->setWorkgroup( workgroup );
+ m_priv->setHost( host );
+ m_priv->setIP( ip );
+
+ Smb4KAuthInfo *auth = passwordHandler()->readAuth( new Smb4KAuthInfo( workgroup, host, QString::null ) );
+
+ QString command;
+
+ command = QString( "net %1 -w %2 -S %3" ).arg( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::Share, host, protocol ) ).arg( KProcess::quote( workgroup ), KProcess::quote( host ) );
+
+ if ( !ip.isEmpty() )
+ {
+ command.append( QString( " -I %1" ).arg( KProcess::quote( ip ) ) );
+ }
+
+ if ( !auth->user().isEmpty() )
+ {
+ command.append( QString( " -U %1" ).arg( KProcess::quote( auth->user() ) ) );
+
+ if ( !auth->password().isEmpty() )
+ {
+ m_proc->setEnvironment( "PASSWD", auth->password() );
+ }
+ }
+ else
+ {
+ command.append( " -U guest%" );
+ }
+
+ delete auth;
+
+ *m_proc << command;
+
+ startProcess( Shares );
+}
+
+
+/****************************************************************************
+ Gets more info on a selected host. (private part)
+****************************************************************************/
+
+void Smb4KScanner::scanForInfo( const QString &workgroup, const QString &host, const QString &ip )
+{
+ m_priv->setWorkgroup( workgroup );
+ m_priv->setHost( host );
+ m_priv->setIP( ip );
+
+ QString smbclient_options = optionsHandler()->smbclientOptions();
+
+ QString command = QString( "smbclient -d1 -U guest% -W %1 -L %2" ).arg( KProcess::quote( workgroup ) ).arg( KProcess::quote( host ) );
+
+ if ( !ip.isEmpty() )
+ {
+ command.append( QString( " -I %1" ).arg( KProcess::quote( ip ) ) );
+ }
+
+ if ( !smbclient_options.stripWhiteSpace().isEmpty() )
+ {
+ command.append( smbclient_options );
+ }
+
+ *m_proc << command;
+
+ startProcess( Info );
+}
+
+
+/****************************************************************************
+ Searches for a host. (private part)
+****************************************************************************/
+
+void Smb4KScanner::searchForHost( const QString &host )
+{
+ // We need this because smbclient won't return the host name.
+ KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( host );
+
+ if ( Smb4KSettings::searchMethod() == Smb4KSettings::EnumSearchMethod::Smbclient &&
+ (ip_address.isIPv4Addr() || ip_address.isIPv6Addr()) )
+ {
+ Smb4KError::error( ERROR_IP_CANNOT_BE_USED );
+ m_working = false;
+ emit state( SCANNER_STOP );
+ return;
+ }
+
+ m_priv->setHost( host );
+
+ QString wins = optionsHandler()->winsServer();
+ QString nmblookup_options = optionsHandler()->nmblookupOptions();
+ QString smbclient_options = optionsHandler()->smbclientOptions();
+
+ QString command;
+
+ switch ( Smb4KSettings::searchMethod() )
+ {
+ case Smb4KSettings::EnumSearchMethod::Nmblookup:
+ {
+ command = QString( "nmblookup" );
+
+ if ( !nmblookup_options.stripWhiteSpace().isEmpty() )
+ {
+ command.append( nmblookup_options );
+ }
+
+ if ( host.contains( '.', true ) != 3 )
+ {
+ if ( !wins.isEmpty() )
+ {
+ command.append( QString( " -R -U %1 %2 -S | grep '<00>' | sed -e 's/<00>.*//'" ).arg( wins ).arg( m_priv->host() ) );
+ }
+ else
+ {
+ command.append( QString( " %1 -S | grep '<00>' | sed -e 's/<00>.*//'" ).arg( m_priv->host() ) );
+ }
+ }
+ else
+ {
+ if ( !wins.isEmpty() )
+ {
+ command.append( QString( " -R -U %1 %2 -A | grep '<00>' | sed -e 's/<00>.*//'" ).arg( wins ).arg( m_priv->host() ) );
+ }
+ else
+ {
+ command.append( QString( " %1 -A | grep '<00>' | sed -e 's/<00>.*//'" ).arg( m_priv->host() ) );
+ }
+ }
+
+ break;
+ }
+ case Smb4KSettings::EnumSearchMethod::Smbclient:
+ {
+ command = QString( "smbclient -d2 -U % -L %1" ).arg( m_priv->host() );
+
+ if ( !smbclient_options.stripWhiteSpace().isEmpty() )
+ {
+ command.append( smbclient_options );
+ }
+
+ break;
+ }
+ default:
+ {
+ // Something went wrong. Stop here.
+ return;
+ }
+ }
+
+ *m_proc << command;
+
+ startProcess( Search );
+}
+
+
+/****************************************************************************
+ Starts the process of the scanner.
+****************************************************************************/
+
+void Smb4KScanner::startProcess( int state )
+{
+ m_state = state;
+ m_buffer = QString::null;
+
+ if ( state != Info )
+ {
+ QApplication::setOverrideCursor( waitCursor );
+ }
+
+ m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+}
+
+
+/****************************************************************************
+ End the process and tell, what to do with the data.
+****************************************************************************/
+
+void Smb4KScanner::endProcess()
+{
+ switch ( m_state )
+ {
+ case Workgroups:
+ case QueryHost:
+ processWorkgroups();
+ break;
+ case IPScan:
+ processIPScan();
+ break;
+ case Hosts:
+ processWorkgroupMembers();
+ break;
+ case Shares:
+ processShares();
+ break;
+ case Info:
+ processInfo();
+ break;
+ case Search:
+ processSearch();
+ break;
+ default:
+ break;
+ }
+
+ m_state = Idle;
+
+ m_priv->clearData();
+
+ QApplication::restoreOverrideCursor();
+
+ m_proc->clearArguments();
+
+ m_working = false;
+
+ emit state( SCANNER_STOP );
+}
+
+
+/****************************************************************************
+ Process the list of workgroups.
+****************************************************************************/
+
+void Smb4KScanner::processWorkgroups()
+{
+ QStringList list = QStringList::split( '\n', m_buffer, false );
+
+ for ( QValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
+ {
+ delete *it;
+ }
+
+ for ( QValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_workgroups_list->clear();
+ m_hosts_list->clear();
+
+ if ( m_state == Workgroups )
+ {
+ QString workgroup, master, ip;
+
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( (*it).stripWhiteSpace().startsWith( "Looking" ) )
+ {
+ ip = (*it).section( "of", 1, 1 ).stripWhiteSpace();
+
+ continue;
+ }
+ else if ( (*it).contains( "<00>" ) != 0 && (*it).contains( "<GROUP>" ) == 0 )
+ {
+ if ( workgroup.isEmpty() && master.isEmpty() && !ip.isEmpty() )
+ {
+ master = (*it).section( "<00>", 0, 0 ).stripWhiteSpace();
+ }
+
+ continue;
+ }
+ else if ( (*it).contains( "<00>" ) != 0 && (*it).contains( "<GROUP>" ) != 0 )
+ {
+ if ( workgroup.isEmpty() && !master.isEmpty() && !ip.isEmpty() )
+ {
+ workgroup = (*it).left( (*it).find( "<00>" ) ).stripWhiteSpace();
+
+ m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, master, ip ) );
+
+ Smb4KHostItem *master_item = new Smb4KHostItem( workgroup, master, QString::null, ip );
+ master_item->setMaster( true );
+
+ m_hosts_list->append( master_item );
+
+ workgroup = QString::null;
+ master = QString::null;
+ ip = QString::null;
+ }
+
+ continue;
+ }
+ }
+ }
+ else if ( m_state == QueryHost )
+ {
+ bool process = false;
+
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ QString line = (*it).stripWhiteSpace();
+
+ if ( line.startsWith( "-------------" ) )
+ {
+ process = true;
+
+ continue;
+ }
+
+ if ( process && !line.isEmpty() )
+ {
+ QString workgroup = line.section( " ", 0, 0 ).stripWhiteSpace();
+ QString master = line.section( " ", 1, -1 ).stripWhiteSpace();
+
+ m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, master, QString::null ) );
+
+ Smb4KHostItem *master_item = new Smb4KHostItem( workgroup, master );
+ master_item->setMaster( true );
+
+ m_hosts_list->append( master_item );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ lookupIPAddresses();
+
+ emit workgroups( *m_workgroups_list );
+ emit hostListChanged();
+}
+
+
+/****************************************************************************
+ Process the data from the IP range scan
+****************************************************************************/
+
+void Smb4KScanner::processIPScan()
+{
+ QStringList list = QStringList::split( '\n', m_buffer, true );
+
+ for ( QValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
+ {
+ delete *it;
+ }
+
+ for ( QValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_workgroups_list->clear();
+ m_hosts_list->clear();
+
+ // Process the data:
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( (*it).startsWith( "Looking up status of" ) )
+ {
+ QString workgroup, host, ip;
+ bool master = false;
+
+ // Get the IP address of this host.
+ ip = (*it).section( "of", 1, 1 ).stripWhiteSpace();
+
+ // Loop through the data:
+ for ( QStringList::ConstIterator i = it; i != list.end(); ++i )
+ {
+ if ( (*i).contains( " <00> " ) != 0 )
+ {
+ if ( (*i).contains( " <GROUP> " ) != 0 )
+ {
+ workgroup = (*i).section( "<00>", 0, 0 ).stripWhiteSpace();
+ }
+ else
+ {
+ host = (*i).section( "<00>", 0, 0 ).stripWhiteSpace();
+ }
+
+ continue;
+ }
+ else if ( (*i).contains( "__MSBROWSE__" ) != 0 && (*i).contains( " <01> " ) != 0 )
+ {
+ master = true;
+
+ continue;
+ }
+ else if ( (*i).contains( "MAC Address" ) != 0 || (*i).stripWhiteSpace().isEmpty() )
+ {
+ it = i;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !workgroup.isEmpty() )
+ {
+ Smb4KWorkgroupItem *workgroup_item = getWorkgroup( workgroup );
+
+ if ( workgroup_item )
+ {
+ if ( master )
+ {
+ workgroup_item->setMaster( host, ip );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ if ( master )
+ {
+ m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, host, ip ) );
+ }
+ else
+ {
+ m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, QString::null, QString::null ) );
+ }
+ }
+
+ Smb4KHostItem *host_item = new Smb4KHostItem( workgroup, host, QString::null, ip );
+ host_item->setMaster( master );
+
+ m_hosts_list->append( host_item );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ // No extra lookup of IP addresses is needed since
+ // we searched for IP addresses. :)
+
+ emit workgroups( *m_workgroups_list );
+ emit members( m_priv->workgroup(), *m_hosts_list );
+ emit hostListChanged();
+}
+
+
+/****************************************************************************
+ Process the member list of a workgroup.
+****************************************************************************/
+
+void Smb4KScanner::processWorkgroupMembers()
+{
+ QStringList list = QStringList::split( '\n', m_buffer, false );
+
+ switch ( Smb4KSettings::browseList() )
+ {
+ case Smb4KSettings::EnumBrowseList::LookupDomains:
+ case Smb4KSettings::EnumBrowseList::QueryCurrentMaster:
+ case Smb4KSettings::EnumBrowseList::QueryCustomMaster:
+ {
+ if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 ||
+ m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 ||
+ m_buffer.contains( "The username or password was not correct" ) != 0 )
+ {
+ // Authentication failed:
+ emit failed();
+
+ if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(),
+ QString::null, Smb4KPasswordHandler::AccessDenied,
+ kapp->mainWidget() ? kapp->mainWidget() : 0, "AskPass" ) )
+ {
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4" ).arg( Hosts ).arg( m_priv->workgroup(), m_priv->host(), m_priv->ip() ) ) );
+ }
+
+ return;
+ }
+ else if ( m_buffer.contains( "Could not connect to server" ) != 0 ||
+ m_buffer.contains( "Unable to find a suitable server" ) != 0 ||
+ m_buffer.contains( "Invalid ip address specified" ) != 0 )
+ {
+ // If the IP address is empty, the shell output contains
+ // the IP address. Remove it, because it will confuse
+ // the user:
+ if ( m_priv->ip().isEmpty() )
+ {
+ list.remove( list.first() );
+ }
+
+ // Notify the rest of the program, that something went wrong.
+ emit failed();
+
+ // Notify the user:
+ Smb4KError::error( ERROR_GETTING_MEMBERS, QString::null, list.join( "\n" ) );
+
+ return;
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ QValueList<Smb4KHostItem *> hosts;
+
+ bool process = false;
+
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ QString line = (*it).stripWhiteSpace();
+
+ if ( !process )
+ {
+ // Find the IP address in case we did not know it at the beginning
+ // of the scan process and put it into m_priv.ip():
+ if ( m_priv->ip().isEmpty() && line.startsWith( "***" ) && line.endsWith( "***" ) )
+ {
+ m_priv->setIP( line.section( ":", 1, 1 ).section( "***", 0, 0 ).stripWhiteSpace() );
+
+ continue;
+ }
+
+ // Find the line after that we will have to process the output
+ // to get the servers belonging to this workgroup:
+ if ( line.startsWith( "-------------" ) )
+ {
+ process = true;
+
+ continue;
+ }
+
+ continue;
+ }
+ else
+ {
+ if ( !line.isEmpty() )
+ {
+ QString host, comment;
+
+ if ( line.contains( " " ) == 0 )
+ {
+ host = line;
+ }
+ else
+ {
+ host = line.section( " ", 0, 0 ).stripWhiteSpace();
+ comment = line.section( " ", 1, -1 ).stripWhiteSpace();
+ }
+
+ Smb4KHostItem *item = new Smb4KHostItem( m_priv->workgroup(), host, comment );
+
+ if ( QString::compare( item->name(), m_priv->host() ) == 0 )
+ {
+ // The item is identical to the master browser! Give the
+ // respective workgroup item the IP address of the master
+ // if it is not already present.
+ Smb4KWorkgroupItem *workgroupItem = getWorkgroup( m_priv->workgroup() );
+
+ if ( workgroupItem && workgroupItem->masterIP().isEmpty() )
+ {
+ workgroupItem->setMasterIP( m_priv->ip() );
+ }
+
+ // Set the IP address for new item (we only know it at this point,
+ // because this is the workgroup master):
+ item->setIPAddress( m_priv->ip() );
+ // Set it to be the master:
+ item->setMaster( true );
+ }
+
+ hosts.append( item );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ // If the list is empty, put the master in.
+ if ( hosts.isEmpty() )
+ {
+ Smb4KHostItem *item = new Smb4KHostItem( m_priv->workgroup(), m_priv->host() );
+ item->setMaster( true );
+
+ hosts.append( item );
+ }
+
+ emit members( m_priv->workgroup(), hosts );
+
+ // Now put the hosts in m_hosts_list:
+ for ( QValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
+ {
+ if ( QString::compare( (*it)->workgroup(), m_priv->workgroup() ) == 0 )
+ {
+ bool found = false;
+
+ for ( QValueList<Smb4KHostItem *>::Iterator i = hosts.begin(); i != hosts.end(); ++i )
+ {
+ if ( *i && QString::compare( (*i)->name(), (*it)->name() ) == 0 )
+ {
+ found = true;
+
+ // The only thing that might be missing is the comment.
+ (*it)->setComment( (*i)->comment() );
+
+ delete *i;
+ *i = NULL;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !found )
+ {
+ delete *it;
+ *it = NULL;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ m_hosts_list->remove( NULL );
+ hosts.remove( NULL );
+
+ // Append the list:
+ *m_hosts_list += hosts;
+
+ // Lookup IP addresses.
+ lookupIPAddresses();
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::ScanBroadcastAreas:
+ {
+ if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 ||
+ m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 ||
+ m_buffer.contains( "The username or password was not correct" ) != 0 )
+ {
+ // Authentication failed:
+ emit failed();
+
+ if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(),
+ QString::null, Smb4KPasswordHandler::AccessDenied,
+ kapp->mainWidget() ? kapp->mainWidget() : 0, "AskPass" ) )
+ {
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4" ).arg( Hosts ).arg( m_priv->workgroup(), m_priv->host(), m_priv->ip() ) ) );
+ }
+
+ return;
+ }
+ else if ( m_buffer.contains( "Could not connect to server" ) != 0 ||
+ m_buffer.contains( "Unable to find a suitable server" ) != 0 ||
+ m_buffer.contains( "Invalid ip address specified" ) != 0 )
+ {
+ // We are in IP scan mode, so we can ignore the error and emit
+ // what we already have:
+ emit members( m_priv->workgroup(), *m_hosts_list );
+ emit hostListChanged();
+
+ return;
+ }
+
+ // We will not remove any host from the list in IP scan mode,
+ // but we will add additional infomation, if available.
+
+ bool process = false;
+
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( (*it).stripWhiteSpace().startsWith( "-------------" ) )
+ {
+ process = true;
+
+ continue;
+ }
+
+ if ( process && !(*it).stripWhiteSpace().isEmpty() )
+ {
+ QString line = (*it).stripWhiteSpace();
+
+ // Extract host name and comment:
+ QString host, comment;
+
+ if ( line.contains( " " ) == 0 )
+ {
+ host = line;
+ }
+ else
+ {
+ host = line.section( " ", 0, 0 ).stripWhiteSpace();
+ comment = line.section( " ", 1, -1 ).stripWhiteSpace();
+ }
+
+ // Now add the comment to the host item or do nothing if
+ // no comment was found:
+ if ( !comment.isEmpty() )
+ {
+ Smb4KHostItem *item = getHost( host, m_priv->workgroup() );
+
+ if ( item )
+ {
+ item->setComment( comment );
+ }
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ emit members( m_priv->workgroup(), *m_hosts_list );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ emit hostListChanged();
+}
+
+
+/****************************************************************************
+ Process the share list of a host.
+****************************************************************************/
+
+void Smb4KScanner::processShares()
+{
+ // Error handling
+ if ( m_buffer.contains( "The username or password was not correct.", true ) != 0 ||
+ m_buffer.contains( "NT_STATUS_ACCOUNT_DISABLED" ) != 0 /* Active Directory error */ )
+ {
+ // Authentication failed:
+ emit failed();
+
+ if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(), QString::null, Smb4KPasswordHandler::AccessDenied, kapp->mainWidget() ? kapp->mainWidget() : 0, "AskPass" ) )
+ {
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4:%5" ).arg( Shares ).arg( m_priv->workgroup(), m_priv->host(), m_priv->ip(), QString::null ) ) );
+ }
+
+ return;
+ }
+ else if ( m_buffer.contains( "could not obtain sid for domain", true ) != 0 )
+ {
+ // FIXME: Does this error only occur when we scan a server that is
+ // only capable of the RAP protocol or also under other conditions?
+ m_queue.enqueue( new QString( QString( "%1:%2:%3:%4:%5" ).arg( Shares ).arg( m_priv->workgroup(), m_priv->host(), m_priv->ip(), "rap" ) ) );
+
+ m_priv->retry = true;
+
+ return;
+ }
+ else if ( (m_buffer.contains( "Could not connect to server", true ) != 0 &&
+ m_buffer.contains( "The username or password was not correct.", true ) == 0) ||
+ m_buffer.contains( "Unable to find a suitable server" ) != 0 )
+ {
+ // We could not get the list of shares:
+ emit failed();
+
+ // Notify the user:
+ Smb4KError::error( ERROR_GETTING_SHARES, QString::null, m_buffer );
+
+ return;
+ }
+
+ QStringList list = QStringList::split( '\n', m_buffer, false );
+
+ QValueList<Smb4KShareItem *> share_list;
+
+ bool process = false;
+
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( (*it).startsWith( "---" ) )
+ {
+ process = true;
+ }
+
+ if ( process )
+ {
+ QString name, type, comment;
+
+ if ( (*it).contains( " Disk ", true ) != 0 )
+ {
+ name = (*it).section( " Disk ", 0, 0 ).stripWhiteSpace();
+ type = "Disk";
+ comment = (*it).section( " Disk ", 1, 1 ).stripWhiteSpace();
+ }
+ else if ( (*it).contains( " Print ", true ) != 0 )
+ {
+ name = (*it).section( " Print ", 0, 0 ).stripWhiteSpace();
+ type = "Printer";
+ comment = (*it).section( " Print ", 1, 1 ).stripWhiteSpace();
+ }
+ else if ( (*it).contains( " IPC ", true ) != 0 )
+ {
+ name = (*it).section( " IPC ", 0, 0 ).stripWhiteSpace();
+ type = "IPC";
+ comment = (*it).section( " IPC ", 1, 1 ).stripWhiteSpace();
+ }
+ else
+ {
+ continue;
+ }
+
+ share_list.append( new Smb4KShareItem( m_priv->workgroup(), m_priv->host(), name, type, comment ) );
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ emit shares( m_priv->host(), share_list );
+}
+
+
+/****************************************************************************
+ Process the search data.
+****************************************************************************/
+
+void Smb4KScanner::processSearch()
+{
+ // NOTE: We do not emit Smb4KScanner::failed() here, because
+ // errors are handled in a different way by the search dialog.
+
+ // Stop right here if the user searched for illegal
+ // strings like #, ', () etc.
+ if ( m_buffer.contains( "Usage:", true ) != 0 ||
+ m_buffer.contains( "/bin/sh:", true ) != 0 )
+ {
+ emit searchResult( new Smb4KHostItem() );
+
+ return;
+ }
+
+ QStringList data = QStringList::split( '\n', m_buffer.stripWhiteSpace(), false );
+
+ switch ( Smb4KSettings::searchMethod() )
+ {
+ case Smb4KSettings::EnumSearchMethod::Nmblookup:
+ {
+ if ( !data.isEmpty() )
+ {
+ // The last entry in the list is the workgroup:
+ QString workgroup = data.last().stripWhiteSpace();
+ QString host, ip;
+
+ if ( m_priv->host().contains( ".", true ) != 3 )
+ {
+ // The IP address is in the first entry:
+ ip = data.first().stripWhiteSpace().section( " ", 0, 0 );
+ // The host.
+ host = m_priv->host().upper();
+ }
+ else
+ {
+ ip = m_priv->host();
+ host = data[0].stripWhiteSpace();
+ }
+
+ emit searchResult( new Smb4KHostItem( workgroup, host, QString::null, ip ) );
+ }
+ else
+ {
+ emit searchResult( new Smb4KHostItem() );
+ }
+
+ break;
+ }
+ case Smb4KSettings::EnumSearchMethod::Smbclient:
+ {
+ if ( data.count() > 1 && !data[1].isEmpty() )
+ {
+ if ( m_buffer.contains( QString( "Connection to %1 failed" ).arg( m_priv->host() ) ) != 0 )
+ {
+ emit searchResult( new Smb4KHostItem() );
+ }
+ else
+ {
+ QString workgroup = data.grep( "Domain" ).first().section( "Domain=[", 1, 1 ).section( "]", 0, 0 );
+ QString ip = data.grep( "Got a positive name query" ).first().section( "(", 1, 1 ).section( ")", 0, 0 ).stripWhiteSpace();
+
+ emit searchResult( new Smb4KHostItem( workgroup, m_priv->host().upper(), QString::null, ip ) );
+ }
+ }
+ else
+ {
+ emit searchResult( new Smb4KHostItem() );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ Process the information about a host.
+****************************************************************************/
+
+void Smb4KScanner::processInfo()
+{
+ if ( m_proc->normalExit() )
+ {
+ QStringList list = QStringList::split( '\n', m_buffer, false );
+
+ Smb4KHostItem *host = getHost( m_priv->host(), m_priv->workgroup() );
+
+ if ( host )
+ {
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( (*it).stripWhiteSpace().startsWith( "Domain" ) || (*it).stripWhiteSpace().startsWith( "OS" ) )
+ {
+ // The OS string.
+ host->setOSString( (*it).section( "OS=[", 1, 1 ).section( "]", 0, 0 ).stripWhiteSpace() );
+
+ // The Server string.
+ host->setServerString( (*it).section( "Server=[", 1, 1 ).section( "]", 0, 0 ).stripWhiteSpace() );
+
+ break;
+ }
+ else if ( (*it).contains( "Connection to", true ) != 0 )
+ {
+ // The lookup of the info failed:
+ emit failed();
+
+ break;
+ }
+ }
+
+ emit info( host );
+ }
+ }
+ else
+ {
+ // In case the process was aborted, we need to enable checking
+ // again:
+ Smb4KHostItem *host = getHost( m_priv->host(), m_priv->workgroup() );
+
+ if ( host )
+ {
+ host->setInfoChecked( false );
+ }
+ }
+}
+
+
+/****************************************************************************
+ Get a workgroup item out of the workgroup list.
+****************************************************************************/
+
+Smb4KWorkgroupItem *Smb4KScanner::getWorkgroup( const QString &workgroup )
+{
+ QValueListIterator<Smb4KWorkgroupItem *> it;
+
+ for ( it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
+ {
+ if ( QString::compare( (*it)->name(), workgroup ) == 0 )
+ {
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return it == m_workgroups_list->end() ? NULL : *it;
+}
+
+
+/****************************************************************************
+ Get a workgroup item out of the workgroup list.
+****************************************************************************/
+
+Smb4KHostItem *Smb4KScanner::getHost( const QString &name, const QString &workgroup )
+{
+ QValueListIterator<Smb4KHostItem *> it;
+
+ for ( it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
+ {
+ if ( !workgroup.stripWhiteSpace().isEmpty() &&
+ QString::compare( (*it)->workgroup().upper(), workgroup.upper() ) != 0 )
+ {
+ continue;
+ }
+
+ if ( QString::compare( (*it)->name().upper(), name.upper() ) == 0 )
+ {
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return it == m_hosts_list->end() ? NULL : *it;
+}
+
+
+/****************************************************************************
+ Add a host to the host list
+****************************************************************************/
+
+void Smb4KScanner::insertHost( Smb4KHostItem *host )
+{
+ if ( host && !getHost( host->name(), host->workgroup() ) )
+ {
+ // Use the copy constructor here, so that we do not run into
+ // trouble when/if host is deleted.
+ Smb4KHostItem *host_item = new Smb4KHostItem( *host );
+
+ m_hosts_list->append( host_item );
+
+ // Check if the workgroup is already known. If not, create a new Smb4KWorkgroupItem,
+ // declare the host a pseudo master and add the workgroup to the list.
+ if ( !getWorkgroup( host_item->workgroup() ) )
+ {
+ Smb4KWorkgroupItem *workgroup_item = new Smb4KWorkgroupItem( host_item->workgroup(),
+ host_item->name(), host_item->ip() );
+ workgroup_item->setPseudoMaster();
+ host_item->setMaster( true ); // pseudo master
+
+ appendWorkgroup( workgroup_item );
+ }
+
+ // Lookup at least the IP address of this host, if necessary:
+ if ( host_item->ip().isEmpty() )
+ {
+ lookupIPAddresses();
+ }
+
+ emit hostAdded( host_item );
+
+ emit hostListChanged();
+ }
+}
+
+
+/****************************************************************************
+ Appends an item to the list of workgroups.
+****************************************************************************/
+
+void Smb4KScanner::appendWorkgroup( Smb4KWorkgroupItem *item )
+{
+ if ( !getWorkgroup( item->name() ) )
+ {
+ m_workgroups_list->append( item );
+
+ emit workgroups( *m_workgroups_list );
+ }
+}
+
+
+void Smb4KScanner::timerEvent( QTimerEvent * )
+{
+ // Look for the thing to do (next).
+ // At this point, the topmost item will not be
+ // dequeued. This will be done below.
+ int todo = Idle;
+ QString *head = NULL;
+
+ if ( (head = m_queue.head()) != 0 )
+ {
+ todo = head->section( ":", 0, 0 ).toInt();
+ }
+
+ if ( !m_working && !m_queue.isEmpty() )
+ {
+ // Start processing with dequeueing the item:
+ QString *item = m_queue.dequeue();
+
+ // Tell the program, that the scanner is running.
+ m_working = true;
+
+ switch ( todo )
+ {
+ case Init:
+ {
+ emit state( SCANNER_INIT );
+ scanNetwork();
+ break;
+ }
+ case Hosts:
+ {
+ emit state( SCANNER_OPENING_WORKGROUP );
+ scanForWorkgroupMembers( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ) );
+ break;
+ }
+ case Shares:
+ {
+ if ( !m_priv->retry )
+ {
+ emit state( SCANNER_OPENING_HOST );
+ }
+ else
+ {
+ emit state( SCANNER_RETRYING_OPENING_HOST );
+ m_priv->retry = false;
+ }
+ scanForShares( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ), item->section( ":", 4, 4 ) );
+ break;
+ }
+ case Info:
+ {
+ emit state( SCANNER_RETRIEVING_INFO );
+ scanForInfo( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ) );
+ break;
+ }
+ case Search:
+ {
+ emit state( SCANNER_SEARCHING );
+ searchForHost( item->section( ":", 1, 1 ) );
+ break;
+ }
+ default:
+ break;
+ }
+
+ delete item;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+ Internal slots.
+****************************************************************************/
+
+void Smb4KScanner::slotReceivedStdout( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KScanner::slotProcessExited( KProcess * )
+{
+ endProcess();
+}
+
+
+void Smb4KScanner::slotReceivedStderr( KProcess *, char *buf, int len )
+{
+ m_buffer.append( QString::fromLocal8Bit( buf, len ) );
+}
+
+
+
+/***************************************************************************
+ * *
+ * Lookup for IP addresses *
+ * *
+ ***************************************************************************/
+
+/****************************************************************************
+ Start the scanning for IP addresses
+****************************************************************************/
+
+void Smb4KScanner::lookupIPAddresses()
+{
+ bool start = false;
+ QString command = QString::null;
+
+ for ( QValueList<Smb4KHostItem *>::ConstIterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
+ {
+ if ( (*it)->ip().stripWhiteSpace().isEmpty() && !(*it)->ipAddressChecked() )
+ {
+ if ( !start )
+ {
+ start = true;
+ }
+
+ (*it)->setIPAddressChecked( true );
+
+ command.append( "nmblookup" );
+ command.append( optionsHandler()->nmblookupOptions() );
+ command.append( optionsHandler()->winsServer().isEmpty() ? "" : " -R -U "+KProcess::quote( optionsHandler()->winsServer() ) );
+ command.append( " -- "+KProcess::quote( (*it)->name() )+" | grep '<00>'" );
+ command.append( " ; " );
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ command.truncate( command.length() - 3 );
+
+ if ( start )
+ {
+ KProcess *proc = new KProcess( this );
+ proc->setUseShell( true );
+
+ connect( proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedIPAddresses( KProcess *, char *, int ) ) );
+ connect( proc, SIGNAL( processExited( KProcess * ) ),
+ this, SLOT( slotIPAddressProcessExited( KProcess * ) ) );
+
+ *proc << command;
+ proc->start( KProcess::NotifyOnExit, KProcess::Stdout );
+ }
+}
+
+
+/****************************************************************************
+ Processes IP addresses if data occurrs on stdout.
+****************************************************************************/
+
+void Smb4KScanner::slotReceivedIPAddresses( KProcess *, char *buf, int len )
+{
+ // WARNING: Do not implement error handling here!!!
+
+ QString buffer = QString::fromLocal8Bit( buf, len );
+
+ if ( !buffer.stripWhiteSpace().isEmpty() )
+ {
+ QString ip = buffer.stripWhiteSpace().section( " ", 0, 0 ).stripWhiteSpace();
+ QString host = buffer.stripWhiteSpace().section( " ", 1, 1 ).section( "<00>", 0, 0 ).stripWhiteSpace();
+
+ if ( !host.isEmpty() && !ip.isEmpty() )
+ {
+ Smb4KHostItem *item = getHost( host );
+
+ if ( item )
+ {
+ item->setIPAddress( ip );
+
+ if ( item->isMaster() )
+ {
+ Smb4KWorkgroupItem *workgroup = getWorkgroup( item->workgroup() );
+
+ if ( workgroup )
+ {
+ workgroup->setMasterIP( ip );
+ }
+ }
+
+ emit ipAddress( item );
+ }
+ }
+ }
+}
+
+
+/****************************************************************************
+ End IP address scan.
+****************************************************************************/
+
+void Smb4KScanner::slotIPAddressProcessExited( KProcess *p )
+{
+ delete p;
+}
+
+
+#include "smb4kscanner.moc"
diff --git a/smb4k/core/smb4kscanner.h b/smb4k/core/smb4kscanner.h
new file mode 100644
index 0000000..3930d5e
--- /dev/null
+++ b/smb4k/core/smb4kscanner.h
@@ -0,0 +1,485 @@
+/***************************************************************************
+ smb4kscanner.h - The network scan core class of Smb4K.
+ -------------------
+ begin : Sam Mai 31 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSCANNER_H
+#define SMB4KSCANNER_H
+
+#ifndef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qptrqueue.h>
+
+// KDE includes
+#include <kprocess.h>
+
+// application specific includes
+#include "smb4kdefs.h"
+
+// forward declarations
+class Smb4KScannerPrivate;
+class Smb4KWorkgroupItem;
+class Smb4KHostItem;
+class Smb4KShareItem;
+
+
+/**
+ * This is the core class, that communicates with the network. All look-up
+ * stuff is done here.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KScanner : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param workgroups A list of Smb4KWorkgroupItem items which will be filled by the scanner
+ * with the list of available workgroups. If a NULL pointer is passed, a
+ * private list will be created which cannot be accessed from outside.
+ *
+ * @param hosts A list of Smb4KHostItem items which will be filled by the scanner.
+ * with the list of available hosts. If a NULL pointer is passed, a
+ * private list will be created which cannot be accessed from outside.
+ *
+ * @param parent The parent of this class.
+ *
+ * @param name The name of this class.
+ */
+ Smb4KScanner( QValueList<Smb4KWorkgroupItem *> *workgroups = 0,
+ QValueList<Smb4KHostItem *> *hosts = 0,
+ QObject *parent = 0,
+ const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KScanner();
+
+ /**
+ * Initiates a network scan.
+ *
+ * Please not that after having invoked this function, the list of workgroups
+ * as well as the list of known hosts will be cleared and refilled. Thus, all
+ * known hosts except the current workgroup master browsers will have been
+ * vanished.
+ */
+ void rescan();
+
+ /**
+ * Aborts the network scan.
+ */
+ void abort();
+
+ /**
+ * Reads the options.
+ */
+ void readOptions();
+
+ /**
+ * Scan for the shares on a selected host.
+ *
+ * @param workgroup The workgroup of the host you want to scan.
+ *
+ * @param host The host you want to scan.
+ *
+ * @param ip The IP address of the host.
+ *
+ * @param protocol With this argument you can force a special protocol
+ * the net command has to use. Normally, you do not have
+ * to set here anything.
+ */
+ void getShares( const QString &workgroup,
+ const QString &host,
+ const QString &ip,
+ const QString &protocol = QString::null );
+
+ /**
+ * Scans for workgroup members.
+ *
+ * @param workgroup The workgroup of the master browser that should be scanned.
+ *
+ * @param master The name of the master browser.
+ *
+ * @param ip The IP address of the master browser.
+ */
+ void getWorkgroupMembers( const QString &workgroup,
+ const QString &master,
+ const QString &ip );
+
+ /**
+ * Get more info about a share (i.e. server and OS string, etc.).
+ *
+ * @param workgroup The workgroup of the host
+ *
+ * @param host The host's name
+ *
+ * @param ip The host's IP address
+ */
+ void getInfo( const QString &workgroup,
+ const QString &host,
+ const QString &ip );
+
+ /**
+ * Starts the search for a host that matches @p string. If the host is already
+ * in the list of known hosts, this function immediately emits the searchResult()
+ * signal with the Smb4KHostItem representing the host. If this is not the case,
+ * a search process is started.
+ *
+ * @param string The user supplied search string.
+ */
+ void search( const QString &string );
+
+ /**
+ * This function returns an Smb4KWorkgroupItem, if the the workgroup
+ * exists in the list, or NULL, if it does not.
+ *
+ * @param workgroup The name of the workgroup
+ */
+ Smb4KWorkgroupItem *getWorkgroup( const QString &workgroup );
+
+ /**
+ * This function reports if the scanner is running or not.
+ *
+ * @returns TRUE if the scanner is running and FALSE otherwise.
+ */
+ bool isRunning() { return m_working; }
+
+ /**
+ * This function returns the specified host item, or NULL, if this host was not found.
+ * The name of the host is mandatory. The workgroup may be empty, but should be given,
+ * because this will speed up the search process.
+ *
+ * @param name The name of the host
+ *
+ * @param workgroup The workgroup of the host item
+ *
+ * @returns A host item
+ */
+ Smb4KHostItem *getHost( const QString &name,
+ const QString &workgroup = QString::null );
+
+ /**
+ * This function inserts a @p host into the list of known servers. If it belongs to
+ * a workgroup that was not known until now, a new Smb4KWorkgroupItem item is also
+ * created and added to the list of known workgroups. @p host is then marked as
+ * pseudo master browser. On success, the this function emits the hostAdded() and
+ * hostListChanged() signals. If the host is already in the known, nothing is done.
+ *
+ * @param host The host that should be inserted
+ */
+ void insertHost( Smb4KHostItem *host );
+
+ /**
+ * This function initializes the network scan It just executes the rescan() function,
+ * so you can also use that instead.
+ */
+ void init();
+
+ signals:
+ /**
+ * This signal emits the run state.
+ *
+ * @param state The so-called run state. There are several defined
+ * in the smb4kdefs.h header file.
+ */
+ void state( int state );
+
+ /**
+ * This signal is emitted, when the workgroup list has been updated.
+ *
+ * @param list The list of workgroups in the network neighborhood.
+ */
+ void workgroups( const QValueList<Smb4KWorkgroupItem *> &list );
+
+ /**
+ * Emits the list of workgroup members.
+ *
+ * @param workgroup The workgroup in which the members are located
+ *
+ * @param list The list of workgroup members.
+ */
+ void members( const QString &workgroup, const QValueList<Smb4KHostItem *> &list );
+
+ /**
+ * Emits the list of shares.
+ *
+ * @param host The host that carries the shares
+ *
+ * @param list The list of shares
+ */
+ void shares( const QString &host, const QValueList<Smb4KShareItem *> &list );
+
+ /**
+ * This signal provides info about a certain host. It passes the server
+ * and the OS string.
+ */
+ void info( Smb4KHostItem *host );
+
+ /**
+ * Is emitted, when the results of a network search are to be passed.
+ */
+ void searchResult( Smb4KHostItem *host );
+
+ /**
+ * This signal emits the host item for which an IP address has
+ * been found.
+ *
+ * @param host The host item with the new IP address
+ */
+ void ipAddress( Smb4KHostItem *host );
+
+ /**
+ * This signal is emitted when the list of hosts is changed.
+ */
+ void hostListChanged();
+
+ /**
+ * This signal is emitted if a request could not be processed
+ * successfully.
+ */
+ void failed();
+
+ /**
+ * This signal is emitted when a host has been added to the list of known
+ * hosts via the addHost() function.
+ *
+ * @param host The Smb4KHostItem that represents the host that
+ * was added.
+ */
+ void hostAdded( Smb4KHostItem *host );
+
+ protected:
+ /**
+ * Starts the process.
+ *
+ * @param state The state
+ */
+ void startProcess( int state );
+
+ /**
+ * Is called, when the main process ends.
+ */
+ void endProcess();
+
+ /**
+ * Processes the output of the network group scan.
+ */
+ void processWorkgroups();
+
+ /**
+ * Processes the list of workgroup members retrieved by
+ * scanning the workgroup master browser.
+ */
+ void processWorkgroupMembers();
+
+ /**
+ * Processes the output of the host scan.
+ */
+ void processShares();
+
+ /**
+ * Processes the output of the scan for the OS and Server
+ * string.
+ */
+ void processInfo();
+
+ /**
+ * Processes the output of a search request.
+ */
+ void processSearch();
+
+ /**
+ * Process the data from the IP range scan.
+ */
+ void processIPScan();
+
+ /**
+ * Reimplemented from QObject
+ */
+ void timerEvent( QTimerEvent *e );
+
+ protected slots:
+ /**
+ * Is called, if something is received on stdout from the main process.
+ *
+ * @param proc The process
+ *
+ * @param buf The buffer
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStdout( KProcess *proc,
+ char *buf,
+ int len );
+
+ /**
+ * Is called, when the KProcess exited.
+ *
+ * @param proc The process that exited
+ */
+ void slotProcessExited( KProcess *proc );
+
+ /**
+ * Is called, if something is received on stderr from the main process.
+ *
+ * @param proc The process
+ *
+ * @param buf The buffer
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStderr( KProcess *proc,
+ char *buf,
+ int len );
+
+ /**
+ * Is called when the scan for IP addresses produced output on stdout.
+ *
+ * @param proc The process
+ *
+ * @param buf The buffer
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedIPAddresses( KProcess *proc,
+ char *buf,
+ int len );
+
+ /**
+ * Is called, when the KProcess exited.
+ *
+ * @param proc The process that exited
+ */
+ void slotIPAddressProcessExited( KProcess *proc );
+
+
+ private:
+ /**
+ * Initiates the (re-)scan of the network to retrieve the initial
+ * browse list.
+ */
+ void scanNetwork();
+
+ /**
+ * Scans the group master for the group members.
+ */
+ void scanForWorkgroupMembers( const QString &workgroup,
+ const QString &master,
+ const QString &ip );
+
+ /**
+ * Scans the chosen host for its shares. This is the private part
+ * of @see Smb4KScanner::getShares().
+ */
+ void scanForShares( const QString &workgroup,
+ const QString &host,
+ const QString &ip,
+ const QString &protocol );
+
+ /**
+ * Scans a given host for its OS and Server string.
+ */
+ void scanForInfo( const QString &workgroup,
+ const QString &host,
+ const QString &ip );
+
+ /**
+ * Searches for a given host.
+ */
+ void searchForHost( const QString &host );
+
+ /**
+ * This function initializes the lookup of IP addresses.
+ */
+ void lookupIPAddresses();
+
+ /**
+ * This function takes an Smb4KWorkgroupItem and appends it to the list,
+ * if the represented workgroup isn't already in it.
+ */
+ void appendWorkgroup( Smb4KWorkgroupItem *item );
+
+ /**
+ * Internal enumeration.
+ */
+ enum TODO{ Workgroups, QueryHost, IPScan, Hosts, Shares, Info, Search, Init, Idle };
+
+ /**
+ * The main KProcess object.
+ */
+ KProcess *m_proc;
+
+ /**
+ * The buffer for the main process.
+ */
+ QString m_buffer;
+
+ /**
+ * This queue stores the incoming requests until they are processed.
+ */
+ QPtrQueue<QString> m_queue;
+
+ /**
+ * Is set to true, if the scanner is running.
+ */
+ bool m_working;
+
+ /**
+ * The list of workgroups including the master browser and their
+ * IP addresses.
+ */
+ QValueList<Smb4KWorkgroupItem *> *m_workgroups_list;
+
+ /**
+ * This list contains all hosts, that are found by the scanner and
+ * that are currently active.
+ */
+ QValueList<Smb4KHostItem *> *m_hosts_list;
+
+ /**
+ * The internal state of the main process. Do not mix this up with
+ * the state that's emitted to notify the application about changes.
+ */
+ int m_state;
+
+ /**
+ * This is the pointer to the private helper class.
+ */
+ Smb4KScannerPrivate *m_priv;
+
+ /**
+ * The timer id
+ */
+ int m_timer_id;
+};
+#endif
diff --git a/smb4k/core/smb4kscanner_p.cpp b/smb4k/core/smb4kscanner_p.cpp
new file mode 100644
index 0000000..a4e03c3
--- /dev/null
+++ b/smb4k/core/smb4kscanner_p.cpp
@@ -0,0 +1,96 @@
+/***************************************************************************
+ smb4kscanner_p - This is a private helper class for Smb4KScanner.
+ -------------------
+ begin : Do Jul 19 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// application specific includes
+#include "smb4kscanner_p.h"
+
+
+Smb4KScannerPrivate::Smb4KScannerPrivate()
+{
+ retry = false;
+ clearData();
+}
+
+
+Smb4KScannerPrivate::~Smb4KScannerPrivate()
+{
+}
+
+
+void Smb4KScannerPrivate::clearData()
+{
+ m_workgroup = QString::null;
+ m_host = QString::null;
+ m_ip = QString::null;
+ m_share = QString::null;
+}
+
+
+void Smb4KScannerPrivate::setWorkgroup( const QString &w )
+{
+ m_workgroup = w;
+}
+
+
+void Smb4KScannerPrivate::setHost( const QString &h )
+{
+ m_host = h;
+}
+
+
+void Smb4KScannerPrivate::setIP( const QString &i )
+{
+ m_ip = i;
+}
+
+
+void Smb4KScannerPrivate::setShare( const QString &s )
+{
+ m_share = s;
+}
+
+
+const QString &Smb4KScannerPrivate::workgroup()
+{
+ return m_workgroup;
+}
+
+
+const QString &Smb4KScannerPrivate::host()
+{
+ return m_host;
+}
+
+
+const QString &Smb4KScannerPrivate::ip()
+{
+ return m_ip;
+}
+
+
+const QString &Smb4KScannerPrivate::share()
+{
+ return m_share;
+}
diff --git a/smb4k/core/smb4kscanner_p.h b/smb4k/core/smb4kscanner_p.h
new file mode 100644
index 0000000..be0a364
--- /dev/null
+++ b/smb4k/core/smb4kscanner_p.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ smb4kscanner_p - This is a private helper class for Smb4KScanner.
+ -------------------
+ begin : Do Jul 19 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSCANNER_P_H
+#define SMB4KSCANNER_P_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qstring.h>
+
+class Smb4KScannerPrivate
+{
+ public:
+ Smb4KScannerPrivate();
+ ~Smb4KScannerPrivate();
+ bool retry;
+ void clearData();
+ void setWorkgroup( const QString &w );
+ void setHost( const QString &h );
+ void setIP( const QString &i );
+ void setShare( const QString &s );
+ const QString &workgroup();
+ const QString &host();
+ const QString &ip();
+ const QString &share();
+
+ private:
+ QString m_workgroup;
+ QString m_host;
+ QString m_ip;
+ QString m_share;
+};
+
+#endif
diff --git a/smb4k/core/smb4ksettings.cpp b/smb4k/core/smb4ksettings.cpp
new file mode 100644
index 0000000..3a88f66
--- /dev/null
+++ b/smb4k/core/smb4ksettings.cpp
@@ -0,0 +1,1092 @@
+// This file is generated by kconfig_compiler from smb4k.kcfg.
+// All changes you do to this file will be lost.
+
+#include "smb4ksettings.h"
+
+#include <klocale.h>
+
+#include <kstaticdeleter.h>
+
+Smb4KSettings *Smb4KSettings::mSelf = 0;
+static KStaticDeleter<Smb4KSettings> staticSmb4KSettingsDeleter;
+
+Smb4KSettings *Smb4KSettings::self()
+{
+ if ( !mSelf ) {
+ staticSmb4KSettingsDeleter.setObject( mSelf, new Smb4KSettings() );
+ mSelf->readConfig();
+ }
+
+ return mSelf;
+}
+
+Smb4KSettings::Smb4KSettings( )
+ : KConfigSkeleton( QString::fromLatin1( "smb4krc" ) )
+{
+ mSelf = this;
+ setCurrentGroup( QString::fromLatin1( "Programs" ) );
+
+ mGrepItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "grep" ), mGrep );
+ mGrepItem->setLabel( i18n("The path to the program \"grep\"") );
+ addItem( mGrepItem, QString::fromLatin1( "grep" ) );
+ mAwkItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "awk" ), mAwk );
+ mAwkItem->setLabel( i18n("The path to the program \"awk\"") );
+ addItem( mAwkItem, QString::fromLatin1( "awk" ) );
+ mSedItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "sed" ), mSed );
+ mSedItem->setLabel( i18n("The path to the program \"sed\"") );
+ addItem( mSedItem, QString::fromLatin1( "sed" ) );
+ mXargsItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "xargs" ), mXargs );
+ mXargsItem->setLabel( i18n("The path to the program \"xargs\"") );
+ addItem( mXargsItem, QString::fromLatin1( "xargs" ) );
+ mRmdirItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "rmdir" ), mRmdir );
+ mRmdirItem->setLabel( i18n("The path to the program \"rmdir\"") );
+ addItem( mRmdirItem, QString::fromLatin1( "rmdir" ) );
+ mNmblookupItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "nmblookup" ), mNmblookup );
+ mNmblookupItem->setLabel( i18n("The path to the program \"nmblookup\"") );
+ addItem( mNmblookupItem, QString::fromLatin1( "nmblookup" ) );
+ mSmbclientItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smbclient" ), mSmbclient );
+ mSmbclientItem->setLabel( i18n("The path to the program \"smbclient\"") );
+ addItem( mSmbclientItem, QString::fromLatin1( "smbclient" ) );
+ mSmbspoolItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smbspool" ), mSmbspool );
+ mSmbspoolItem->setLabel( i18n("The path to the program \"smbspool\"") );
+ addItem( mSmbspoolItem, QString::fromLatin1( "smbspool" ) );
+ mNetItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "net" ), mNet );
+ mNetItem->setLabel( i18n("The path to the program \"net\"") );
+ addItem( mNetItem, QString::fromLatin1( "net" ) );
+ mMount_cifsItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "mount_cifs" ), mMount_cifs );
+ mMount_cifsItem->setLabel( i18n("The path to the program \"mount.cifs\"") );
+ addItem( mMount_cifsItem, QString::fromLatin1( "mount_cifs" ) );
+ mUmount_cifsItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "umount_cifs" ), mUmount_cifs );
+ mUmount_cifsItem->setLabel( i18n("The path to the program \"umount.cifs\"") );
+ addItem( mUmount_cifsItem, QString::fromLatin1( "umount_cifs" ) );
+ mSmbmountItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smbmount" ), mSmbmount );
+ mSmbmountItem->setLabel( i18n("The path to the program \"smbmount\"") );
+ addItem( mSmbmountItem, QString::fromLatin1( "smbmount" ) );
+ mSmbumountItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smbumount" ), mSmbumount );
+ mSmbumountItem->setLabel( i18n("The path to the program \"smbumount\"") );
+ addItem( mSmbumountItem, QString::fromLatin1( "smbumount" ) );
+ mMountItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "mount" ), mMount );
+ mMountItem->setLabel( i18n("The path to the program \"mount\"") );
+ addItem( mMountItem, QString::fromLatin1( "mount" ) );
+ mMount_smbfsItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "mount_smbfs" ), mMount_smbfs );
+ mMount_smbfsItem->setLabel( i18n("The path to the program \"mount_smbfs\" (FreeBSD only)") );
+ addItem( mMount_smbfsItem, QString::fromLatin1( "mount_smbfs" ) );
+ mSmbutilItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smbutil" ), mSmbutil );
+ mSmbutilItem->setLabel( i18n("The path to the program \"smbutil\" (FreeBSD only)") );
+ addItem( mSmbutilItem, QString::fromLatin1( "smbutil" ) );
+ mUmountItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "umount" ), mUmount );
+ mUmountItem->setLabel( i18n("The path to the program \"umount\"") );
+ addItem( mUmountItem, QString::fromLatin1( "umount" ) );
+ mSmb4k_mountItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smb4k_mount" ), mSmb4k_mount );
+ mSmb4k_mountItem->setLabel( i18n("The path to the program \"smb4k_mount\"") );
+ addItem( mSmb4k_mountItem, QString::fromLatin1( "smb4k_mount" ) );
+ mSmb4k_umountItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smb4k_umount" ), mSmb4k_umount );
+ mSmb4k_umountItem->setLabel( i18n("The path to the program \"smb4k_umount\"") );
+ addItem( mSmb4k_umountItem, QString::fromLatin1( "smb4k_umount" ) );
+ mSmb4k_killItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smb4k_kill" ), mSmb4k_kill );
+ mSmb4k_killItem->setLabel( i18n("The path to the program \"smb4k_kill\"") );
+ addItem( mSmb4k_killItem, QString::fromLatin1( "smb4k_kill" ) );
+ mSmb4k_catItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smb4k_cat" ), mSmb4k_cat );
+ mSmb4k_catItem->setLabel( i18n("The path to the program \"smb4k_cat\"") );
+ addItem( mSmb4k_catItem, QString::fromLatin1( "smb4k_cat" ) );
+ mSmb4k_mvItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "smb4k_mv" ), mSmb4k_mv );
+ mSmb4k_mvItem->setLabel( i18n("The path to the program \"smb4k_mv\"") );
+ addItem( mSmb4k_mvItem, QString::fromLatin1( "smb4k_mv" ) );
+ mSuperItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "super" ), mSuper );
+ mSuperItem->setLabel( i18n("The path to the program \"super\" (optional)") );
+ addItem( mSuperItem, QString::fromLatin1( "super" ) );
+ mSudoItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "sudo" ), mSudo );
+ mSudoItem->setLabel( i18n("The path to the program \"sudo\" (optional)") );
+ addItem( mSudoItem, QString::fromLatin1( "sudo" ) );
+ mDvipsItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "dvips" ), mDvips );
+ mDvipsItem->setLabel( i18n("The path to the program \"dvips\" (optional)") );
+ addItem( mDvipsItem, QString::fromLatin1( "dvips" ) );
+ mEnscriptItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "enscript" ), mEnscript );
+ mEnscriptItem->setLabel( i18n("The path to the program \"enscript\" (optional)") );
+ addItem( mEnscriptItem, QString::fromLatin1( "enscript" ) );
+ mRsyncItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "rsync" ), mRsync );
+ mRsyncItem->setLabel( i18n("The path to the program \"rsync\" (optional)") );
+ addItem( mRsyncItem, QString::fromLatin1( "rsync" ) );
+ mKonsoleItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "konsole" ), mKonsole );
+ mKonsoleItem->setLabel( i18n("The path to the program \"konsole\" (optional)") );
+ addItem( mKonsoleItem, QString::fromLatin1( "konsole" ) );
+
+ setCurrentGroup( QString::fromLatin1( "UserInterface" ) );
+
+ mShowCustomBookmarkLabelItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowCustomBookmarkLabel" ), mShowCustomBookmarkLabel, true );
+ mShowCustomBookmarkLabelItem->setLabel( i18n("Show custom bookmark label if available") );
+ mShowCustomBookmarkLabelItem->setWhatsThis( i18n("Do not show the name of the share that is represented by the bookmark but the custom label that was defined in the bookmark editor.") );
+ addItem( mShowCustomBookmarkLabelItem, QString::fromLatin1( "ShowCustomBookmarkLabel" ) );
+ mEmbedIntoSystemTrayItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "EmbedIntoSystemTray" ), mEmbedIntoSystemTray, true );
+ mEmbedIntoSystemTrayItem->setLabel( i18n("Embed application into system tray") );
+ mEmbedIntoSystemTrayItem->setWhatsThis( i18n("Embed the application into the system tray. The system tray widget provides a popup menu with several commonly used tasks so that you do not need to bring up the main window everytime. If this setting is chosen you have to use \"Quit\" from the \"File\" menu or the system tray widget to exit the application.") );
+ addItem( mEmbedIntoSystemTrayItem, QString::fromLatin1( "EmbedIntoSystemTray" ) );
+ mStartMainWindowDockedItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "StartMainWindowDocked" ), mStartMainWindowDocked, false );
+ mStartMainWindowDockedItem->setLabel( i18n("Start docked") );
+ mStartMainWindowDockedItem->setWhatsThis( i18n("Start the application docked to the system tray, i.e. only the system tray widget is shown and the main window is hidden. You can bring the main window up by clicking on the system tray widget or by choosing \"Restore\" from its popup menu.") );
+ addItem( mStartMainWindowDockedItem, QString::fromLatin1( "StartMainWindowDocked" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesSharesView;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "IconView" );
+ valuesSharesView.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ListView" );
+ valuesSharesView.append( choice );
+ }
+ mSharesViewItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "SharesView" ), mSharesView, valuesSharesView, EnumSharesView::IconView );
+ mSharesViewItem->setLabel( i18n("How the shares should be displayed") );
+ mSharesViewItem->setWhatsThis( i18n("Choose the kind of view you prefer for displaying the mounted shares. There is an icon view or a list view available.") );
+ addItem( mSharesViewItem, QString::fromLatin1( "SharesView" ) );
+ mShowPrinterSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowPrinterShares" ), mShowPrinterShares, true );
+ mShowPrinterSharesItem->setLabel( i18n("Show printer shares") );
+ mShowPrinterSharesItem->setWhatsThis( i18n("Printer shares will be displayed in the network browser.") );
+ addItem( mShowPrinterSharesItem, QString::fromLatin1( "ShowPrinterShares" ) );
+ mShowHiddenSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowHiddenShares" ), mShowHiddenShares, true );
+ mShowHiddenSharesItem->setLabel( i18n("Show hidden shares") );
+ mShowHiddenSharesItem->setWhatsThis( i18n("Hidden shares will be displayed in the network browser. Hidden shares are ending with a $ sign, e.g. Musik$ or IPC$.") );
+ addItem( mShowHiddenSharesItem, QString::fromLatin1( "ShowHiddenShares" ) );
+ mShowHiddenIPCSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowHiddenIPCShares" ), mShowHiddenIPCShares, true );
+ mShowHiddenIPCSharesItem->setLabel( i18n("Show hidden IPC$ shares") );
+ mShowHiddenIPCSharesItem->setWhatsThis( i18n("Hidden IPC$ shares will be displayed in the network browser.") );
+ addItem( mShowHiddenIPCSharesItem, QString::fromLatin1( "ShowHiddenIPCShares" ) );
+ mShowHiddenADMINSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowHiddenADMINShares" ), mShowHiddenADMINShares, true );
+ mShowHiddenADMINSharesItem->setLabel( i18n("Show hidden ADMIN$ shares") );
+ mShowHiddenADMINSharesItem->setWhatsThis( i18n("Hidden ADMIN$ shares will be displayed in the network browser.") );
+ addItem( mShowHiddenADMINSharesItem, QString::fromLatin1( "ShowHiddenADMINShares" ) );
+ mShowTypeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowType" ), mShowType, true );
+ mShowTypeItem->setLabel( i18n("Show the type of a share") );
+ mShowTypeItem->setWhatsThis( i18n("The type of a share will be displayed in a separate column in the network browser. It can either be Disk, Print or IPC.") );
+ addItem( mShowTypeItem, QString::fromLatin1( "ShowType" ) );
+ mShowIPAddressItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowIPAddress" ), mShowIPAddress, true );
+ mShowIPAddressItem->setLabel( i18n("Show the IP address of a server") );
+ mShowIPAddressItem->setWhatsThis( i18n("The IP address of the server will be displayed in a separate column in the network browser.") );
+ addItem( mShowIPAddressItem, QString::fromLatin1( "ShowIPAddress" ) );
+ mShowCommentItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowComment" ), mShowComment, true );
+ mShowCommentItem->setLabel( i18n("Show the comment of a share") );
+ mShowCommentItem->setWhatsThis( i18n("The comment describing the server or share will be displayed in a separate column in the network browser.") );
+ addItem( mShowCommentItem, QString::fromLatin1( "ShowComment" ) );
+ mShowNetworkItemToolTipItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowNetworkItemToolTip" ), mShowNetworkItemToolTip, true );
+ mShowNetworkItemToolTipItem->setLabel( i18n("Show a tooltip with information about the network item") );
+ mShowNetworkItemToolTipItem->setWhatsThis( i18n("The tooltip shows various information about the current network item.") );
+ addItem( mShowNetworkItemToolTipItem, QString::fromLatin1( "ShowNetworkItemToolTip" ) );
+ mShowMountPointItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowMountPoint" ), mShowMountPoint, false );
+ mShowMountPointItem->setLabel( i18n("Show the mount point of a share instead of its name") );
+ mShowMountPointItem->setWhatsThis( i18n("A share is normally displayed with its name in the shares view. Choosing this feature will cause the exchange of the share name by the mount point.") );
+ addItem( mShowMountPointItem, QString::fromLatin1( "ShowMountPoint" ) );
+ mShowAllSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowAllShares" ), mShowAllShares, false );
+ mShowAllSharesItem->setLabel( i18n("Show all shares that are mounted on the system") );
+ mShowAllSharesItem->setWhatsThis( i18n("You will not only see the shares that were mounted and are owned by you, but also all other mounts using the SMBFS and CIFS file system that are present on the system.") );
+ addItem( mShowAllSharesItem, QString::fromLatin1( "ShowAllShares" ) );
+ mEnableDropSupportItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "EnableDropSupport" ), mEnableDropSupport, false );
+ mEnableDropSupportItem->setLabel( i18n("Allow the dropping of files and directories onto share icons") );
+ mEnableDropSupportItem->setWhatsThis( i18n("This setting allows you to drop files or whole directories onto the share icons, which will cause them to be copied.") );
+ addItem( mEnableDropSupportItem, QString::fromLatin1( "EnableDropSupport" ) );
+ mEnableDragSupportItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "EnableDragSupport" ), mEnableDragSupport, false );
+ mEnableDragSupportItem->setLabel( i18n("Allow the dragging of share icons") );
+ mEnableDragSupportItem->setWhatsThis( i18n("This setting allows you to drag a share item out of Smb4K and onto the desktop or into a file manager. Only enable it if you think you absolutely need it and read the handbook before you mark this checkbox.") );
+ addItem( mEnableDragSupportItem, QString::fromLatin1( "EnableDragSupport" ) );
+ mShowShareToolTipItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowShareToolTip" ), mShowShareToolTip, true );
+ mShowShareToolTipItem->setLabel( i18n("Show a tooltip with information about the share") );
+ mShowShareToolTipItem->setWhatsThis( i18n("The tooltip shows various information about the current share.") );
+ addItem( mShowShareToolTipItem, QString::fromLatin1( "ShowShareToolTip" ) );
+ mPreviewHiddenItemsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreviewHiddenItems" ), mPreviewHiddenItems, false );
+ mPreviewHiddenItemsItem->setLabel( i18n("Show hidden files and directories when previewing a share") );
+ mPreviewHiddenItemsItem->setWhatsThis( i18n("Display hidden files and directories in the preview dialog. The names of hidden files and directories are beginning with a period and are usually needed for very specific purposes (configuration file of an application, etc.). Since they are not of any importance for your regular work, you normally do not need to enable this feature.") );
+ addItem( mPreviewHiddenItemsItem, QString::fromLatin1( "PreviewHiddenItems" ) );
+ mShowOwnerItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowOwner" ), mShowOwner, false );
+ mShowOwnerItem->setLabel( i18n("Show owner and group (SMBFS only)") );
+ mShowOwnerItem->setWhatsThis( i18n("Show the UID and GID that own all files on the mounted file system. At the moment the column will only contain an entry if the share was mounted with the SMBFS file system.") );
+ addItem( mShowOwnerItem, QString::fromLatin1( "ShowOwner" ) );
+ mShowLoginItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowLogin" ), mShowLogin, false );
+ mShowLoginItem->setLabel( i18n("Show login (CIFS only)") );
+ mShowLoginItem->setWhatsThis( i18n("Show the login that was used to authenticate to the server. The column will only contain an entry if the share was mounted with the CIFS file system.") );
+ addItem( mShowLoginItem, QString::fromLatin1( "ShowLogin" ) );
+ mShowFileSystemItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowFileSystem" ), mShowFileSystem, true );
+ mShowFileSystemItem->setLabel( i18n("Show file system") );
+ mShowFileSystemItem->setWhatsThis( i18n("Show the file system that was used for mounting the share.") );
+ addItem( mShowFileSystemItem, QString::fromLatin1( "ShowFileSystem" ) );
+ mShowFreeDiskSpaceItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowFreeDiskSpace" ), mShowFreeDiskSpace, false );
+ mShowFreeDiskSpaceItem->setLabel( i18n("Show free disk space") );
+ mShowFreeDiskSpaceItem->setWhatsThis( i18n("Show the free disk space that is left on the share.") );
+ addItem( mShowFreeDiskSpaceItem, QString::fromLatin1( "ShowFreeDiskSpace" ) );
+ mShowUsedDiskSpaceItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowUsedDiskSpace" ), mShowUsedDiskSpace, false );
+ mShowUsedDiskSpaceItem->setLabel( i18n("Show used disk space") );
+ mShowUsedDiskSpaceItem->setWhatsThis( i18n("Show the disk space that is already used on the share.") );
+ addItem( mShowUsedDiskSpaceItem, QString::fromLatin1( "ShowUsedDiskSpace" ) );
+ mShowTotalDiskSpaceItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowTotalDiskSpace" ), mShowTotalDiskSpace, false );
+ mShowTotalDiskSpaceItem->setLabel( i18n("Show total disk space") );
+ mShowTotalDiskSpaceItem->setWhatsThis( i18n("Show the total disk space of the share.") );
+ addItem( mShowTotalDiskSpaceItem, QString::fromLatin1( "ShowTotalDiskSpace" ) );
+ mShowDiskUsageItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ShowDiskUsage" ), mShowDiskUsage, true );
+ mShowDiskUsageItem->setLabel( i18n("Show disk usage") );
+ mShowDiskUsageItem->setWhatsThis( i18n("Show the space that is used on the share in percent.") );
+ addItem( mShowDiskUsageItem, QString::fromLatin1( "ShowDiskUsage" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Network" ) );
+
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesBrowseList;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "LookupDomains" );
+ valuesBrowseList.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "QueryCurrentMaster" );
+ valuesBrowseList.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "QueryCustomMaster" );
+ valuesBrowseList.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ScanBroadcastAreas" );
+ valuesBrowseList.append( choice );
+ }
+ mBrowseListItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "BrowseList" ), mBrowseList, valuesBrowseList, EnumBrowseList::LookupDomains );
+ mBrowseListItem->setLabel( i18n("Method how to retrieve the browse list") );
+ mBrowseListItem->setWhatsThis( i18n("Choose the method how to compile the initial browse list. There are four options available: The first one is the default one and employs \"nmblookup -M -- -\" to discover all workgroups, domains, and their master browsers on your network neighborhood. The second one instructs Smb4K to query the current master browser of your workgroup or domain to retrieve the browse list. The third is similar to the second one except that you can define the master browser that should be queried. If you choose the last option, the provided list of broadcast areas will be scanned using \"nmblookup -B x.x.x.x -- '*'\".") );
+ addItem( mBrowseListItem, QString::fromLatin1( "BrowseList" ) );
+ mCustomMasterBrowserItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "CustomMasterBrowser" ), mCustomMasterBrowser );
+ mCustomMasterBrowserItem->setLabel( i18n("A custom master browser that is to be queried") );
+ mCustomMasterBrowserItem->setWhatsThis( i18n("Enter the name or IP address of a master browser here that should be queried to compile the initial browse list.") );
+ addItem( mCustomMasterBrowserItem, QString::fromLatin1( "CustomMasterBrowser" ) );
+ mBroadcastAreasItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "BroadcastAreas" ), mBroadcastAreas );
+ mBroadcastAreasItem->setLabel( i18n("A custom list of broadcast addresses") );
+ mBroadcastAreasItem->setWhatsThis( i18n("Enter a comma-separated list of broadcast addresses here (e.g. 192.168.0.255, 192.168.1.255). It is used to scan for all known hosts in the respective broadcast areas.") );
+ addItem( mBroadcastAreasItem, QString::fromLatin1( "BroadcastAreas" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesSearchMethod;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Nmblookup" );
+ valuesSearchMethod.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Smbclient" );
+ valuesSearchMethod.append( choice );
+ }
+ mSearchMethodItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "SearchMethod" ), mSearchMethod, valuesSearchMethod, EnumSearchMethod::Nmblookup );
+ mSearchMethodItem->setLabel( i18n("Method for searching for remote hosts") );
+ mSearchMethodItem->setWhatsThis( i18n("Smb4K is able to search for remote hosts either using nmblookup or smbclient. The nmblookup method is very reliable and works well. However, if your network is configured uncommonly and you experience problems when searching, you should try the smbclient method. But please note that you lose the ability to search for IP addresses in that case.") );
+ addItem( mSearchMethodItem, QString::fromLatin1( "SearchMethod" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Shares" ) );
+
+ mMountPrefixItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "MountPrefix" ), mMountPrefix, QString::fromLatin1( "${HOME}/smb4k/" ) );
+ mMountPrefixItem->setLabel( i18n("The mount prefix") );
+ mMountPrefixItem->setWhatsThis( i18n("This is the prefix where Smb4K will create the mount points and mount the remote shares.") );
+ addItem( mMountPrefixItem, QString::fromLatin1( "MountPrefix" ) );
+ mForceLowerCaseSubdirsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ForceLowerCaseSubdirs" ), mForceLowerCaseSubdirs, false );
+ mForceLowerCaseSubdirsItem->setLabel( i18n("Force the subdirectories created by Smb4K to be lowercase") );
+ mForceLowerCaseSubdirsItem->setWhatsThis( i18n("All names of the subdirectories created by Smb4K below the mount prefix will be lowercase.") );
+ addItem( mForceLowerCaseSubdirsItem, QString::fromLatin1( "ForceLowerCaseSubdirs" ) );
+ mUnmountSharesOnExitItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UnmountSharesOnExit" ), mUnmountSharesOnExit, false );
+ mUnmountSharesOnExitItem->setLabel( i18n("Unmount the shares owned by the user on exit") );
+ mUnmountSharesOnExitItem->setWhatsThis( i18n("Unmount all shares that belong to you when the program exits.") );
+ addItem( mUnmountSharesOnExitItem, QString::fromLatin1( "UnmountSharesOnExit" ) );
+ mRemountSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "RemountShares" ), mRemountShares, false );
+ mRemountSharesItem->setLabel( i18n("Remount shares") );
+ mRemountSharesItem->setWhatsThis( i18n("Remount all your shares that were still mounted when you exited the program. Shares that were mounted by other users are ignored.") );
+ addItem( mRemountSharesItem, QString::fromLatin1( "RemountShares" ) );
+ mUnmountForeignSharesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UnmountForeignShares" ), mUnmountForeignShares, false );
+ mUnmountForeignSharesItem->setLabel( i18n("Allow the unmounting of shares owned by other users") );
+ mUnmountForeignSharesItem->setWhatsThis( i18n("Allow the unmounting of shares that were mounted by other users. In most cases you need super user privileges for this. Please think before you enable this option!") );
+ addItem( mUnmountForeignSharesItem, QString::fromLatin1( "UnmountForeignShares" ) );
+ mCheckIntervalItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "CheckInterval" ), mCheckInterval, 2500 );
+ mCheckIntervalItem->setMinValue(500);
+ mCheckIntervalItem->setMaxValue(300000);
+ mCheckIntervalItem->setLabel( i18n("Interval between checks for new and inaccessible shares") );
+ mCheckIntervalItem->setWhatsThis( i18n("This is the time that elapses until Smb4K checks again for new mounts and unmounts. The lower limit is 500 ms, the upper one 300000 ms. Please note that the smaller the interval gets the higher is your system load.") );
+ addItem( mCheckIntervalItem, QString::fromLatin1( "CheckInterval" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Authentication" ) );
+
+ mUseWalletItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseWallet" ), mUseWallet, true );
+ mUseWalletItem->setLabel( i18n("Use a wallet to store authentication data") );
+ mUseWalletItem->setWhatsThis( i18n("Use a wallet to store the authentication data. The login name and the password name are stored encrypted on your hard drive. If this setting is disabled, the authentication data is not stored permanently but only temporarily.") );
+ addItem( mUseWalletItem, QString::fromLatin1( "UseWallet" ) );
+ mRememberPasswordsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "RememberPasswords" ), mRememberPasswords, true );
+ mRememberPasswordsItem->setLabel( i18n("Remember passwords if no wallet is used") );
+ mRememberPasswordsItem->setWhatsThis( i18n("If you decided to store the login names and passwords only temporarily, Smb4K will remember them until the program exits. If you disable this setting, you will have to provide the authentication data everytime it is needed.") );
+ addItem( mRememberPasswordsItem, QString::fromLatin1( "RememberPasswords" ) );
+ mUseDefaultLoginItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseDefaultLogin" ), mUseDefaultLogin, false );
+ mUseDefaultLoginItem->setLabel( i18n("Use a default login") );
+ mUseDefaultLoginItem->setWhatsThis( i18n("Enable the usage of a default login name and password. The authentication data provided below is then used by default to authenticate to a remote server. This is very useful e.g. if you are working in an Active Directory environment or an NT domain.") );
+ addItem( mUseDefaultLoginItem, QString::fromLatin1( "UseDefaultLogin" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Samba" ) );
+
+ mNetBIOSNameItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "NetBIOSName" ), mNetBIOSName );
+ mNetBIOSNameItem->setLabel( i18n("The NetBIOS name of this computer") );
+ mNetBIOSNameItem->setWhatsThis( i18n("This is the NetBIOS name of this computer that is used by Smb4K. By default, it is either the NetBIOS name that is defined in the smb.conf file or the host name.") );
+ addItem( mNetBIOSNameItem, QString::fromLatin1( "NetBIOSName" ) );
+ mDomainNameItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "DomainName" ), mDomainName );
+ mDomainNameItem->setLabel( i18n("The name of the workgroup/domain this computer is in") );
+ mDomainNameItem->setWhatsThis( i18n("This is the workgroup or domain this computer is or should be in. By default, it is the workgroup that is defined in the smb.conf file.") );
+ addItem( mDomainNameItem, QString::fromLatin1( "DomainName" ) );
+ mSocketOptionsItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "SocketOptions" ), mSocketOptions );
+ mSocketOptionsItem->setLabel( i18n("The socket options") );
+ mSocketOptionsItem->setWhatsThis( i18n("These are the TCP socket options that are used by nmblookup, smbmount and smbclient. Socket options are controls on the networking layer of the operating systems which allow the connection to be tuned. See the manual page of smb.conf for more information.") );
+ addItem( mSocketOptionsItem, QString::fromLatin1( "SocketOptions" ) );
+ mNetBIOSScopeItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "NetBIOSScope" ), mNetBIOSScope );
+ mNetBIOSScopeItem->setLabel( i18n("The NetBIOS scope") );
+ mNetBIOSScopeItem->setWhatsThis( i18n("This sets the NetBIOS scope that nmblookup, smbmount and smbclient will operate under. It should not be set unless every machine on your network neighborhood sets this value.") );
+ addItem( mNetBIOSScopeItem, QString::fromLatin1( "NetBIOSScope" ) );
+ mRemotePortItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "RemotePort" ), mRemotePort, 139 );
+ mRemotePortItem->setMinValue(1);
+ mRemotePortItem->setMaxValue(65535);
+ mRemotePortItem->setLabel( i18n("The remote SMB port") );
+ mRemotePortItem->setWhatsThis( i18n("This is the port that is to be used for connecting to remote servers. Please note that this is independent of the settings in the smb.conf file.") );
+ addItem( mRemotePortItem, QString::fromLatin1( "RemotePort" ) );
+ mUseKerberosItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseKerberos" ), mUseKerberos, false );
+ mUseKerberosItem->setLabel( i18n("Use Kerberos for authentication") );
+ mUseKerberosItem->setWhatsThis( i18n("Try to authenticate with Kerberos. This is only useful in an Active Directory environment. The setting affects the smbmount and smbclient command.") );
+ addItem( mUseKerberosItem, QString::fromLatin1( "UseKerberos" ) );
+ mMachineAccountItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "MachineAccount" ), mMachineAccount, false );
+ mMachineAccountItem->setLabel( i18n("Use machine account for login") );
+ mMachineAccountItem->setWhatsThis( i18n("Make queries to the remote server using the machine account of the local server. The setting affects the net and the smbclient command.") );
+ addItem( mMachineAccountItem, QString::fromLatin1( "MachineAccount" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesFilesystem;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "CIFS" );
+ valuesFilesystem.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "SMBFS" );
+ valuesFilesystem.append( choice );
+ }
+ mFilesystemItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "Filesystem" ), mFilesystem, valuesFilesystem, EnumFilesystem::CIFS );
+ mFilesystemItem->setLabel( i18n("The file system that is used for mounting remote shares") );
+ mFilesystemItem->setWhatsThis( i18n("This is the file system that will be used to mount the remote shares. The Common Internet File System (CIFS) is supported by Windows 2000 and above as well as by Samba. It offers many improvements and advancements compared to the Server Message Block File System (SMBFS) which is used by Windows 9x and below.") );
+ addItem( mFilesystemItem, QString::fromLatin1( "Filesystem" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesClientCharset;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "default_charset" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_1" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_2" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_3" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_4" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_5" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_6" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_7" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_8" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_9" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_13" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_14" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "iso8859_15" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "utf8" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "koi8_r" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "koi8_u" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "koi8_ru" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1251" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "gb2312" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "big5" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "euc_jp" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "euc_kr" );
+ valuesClientCharset.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "tis_620" );
+ valuesClientCharset.append( choice );
+ }
+ mClientCharsetItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "ClientCharset" ), mClientCharset, valuesClientCharset, EnumClientCharset::default_charset );
+ mClientCharsetItem->setLabel( i18n("The charset used by the client") );
+ mClientCharsetItem->setWhatsThis( i18n("This is the charset that is used by the client side (i.e. your side) either to convert local path names to and from Unicode in case of the CIFS file system or for codepage to charset translations (NLS) in case of the SMBFS file system. If you keep the default setting, Smb4K will try to automatically determine the charset by looking up the \"unix charset\" option in the smb.conf.") );
+ addItem( mClientCharsetItem, QString::fromLatin1( "ClientCharset" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesServerCodepage;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "default_codepage" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp437" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp720" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp737" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp775" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp850" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp852" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp855" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp857" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp858" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp860" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp861" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp862" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp863" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp864" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp865" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp866" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp869" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp874" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp932" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp936" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp949" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp950" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1250" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1251" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1252" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1253" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1254" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1255" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1256" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1257" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "cp1258" );
+ valuesServerCodepage.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "unicode" );
+ valuesServerCodepage.append( choice );
+ }
+ mServerCodepageItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "ServerCodepage" ), mServerCodepage, valuesServerCodepage, EnumServerCodepage::default_codepage );
+ mServerCodepageItem->setLabel( i18n("The codepage used by the server") );
+ mServerCodepageItem->setWhatsThis( i18n("This is the codepage that is used by the server. The setting is only available with the SMBFS file system. If you keep the default setting, Smb4K will try to automatically determine the codepage by looking up the \"dos charset\" option in the smb.conf.") );
+ addItem( mServerCodepageItem, QString::fromLatin1( "ServerCodepage" ) );
+ mUserIDItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "UserID" ), mUserID, QString( "%1" ).arg( (int)getuid() ) );
+ mUserIDItem->setLabel( i18n("The user ID that is to be used for mounting") );
+ mUserIDItem->setWhatsThis( i18n("Here you can enter the user ID (a number) that the files and directories of the mounted share will have. If you are using the CIFS file system and the remote server supports the CIFS Unix Extentions, this setting will be ignored.") );
+ addItem( mUserIDItem, QString::fromLatin1( "UserID" ) );
+ mGroupIDItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "GroupID" ), mGroupID, QString( "%1" ).arg( (int)getgid() ) );
+ mGroupIDItem->setLabel( i18n("The group ID that is to be used for mounting") );
+ mGroupIDItem->setWhatsThis( i18n("Here you can enter the group ID (a number) that the files and directories of the mounted share will have. If you are using the CIFS file system and the remote server supports the CIFS Unix Extentions, this setting will be ignored.") );
+ addItem( mGroupIDItem, QString::fromLatin1( "GroupID" ) );
+ mFileMaskItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "FileMask" ), mFileMask, QString::fromLatin1( "0755" ) );
+ mFileMaskItem->setLabel( i18n("The file mask for a share") );
+ mFileMaskItem->setWhatsThis( i18n("This is the mask that will be used for creating files. It must be defined in octal. In case the CIFS file system is used, this setting only takes effect if the server does not support the CIFS Unix Extensions.") );
+ addItem( mFileMaskItem, QString::fromLatin1( "FileMask" ) );
+ mDirectoryMaskItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "DirectoryMask" ), mDirectoryMask, QString::fromLatin1( "0755" ) );
+ mDirectoryMaskItem->setLabel( i18n("The directory mask for a share") );
+ mDirectoryMaskItem->setWhatsThis( i18n("This is the mask that will be used for creating directories. It must be defined in octal. In case the CIFS file system is used, this setting only takes effect if the server does not support the CIFS Unix Extensions.") );
+ addItem( mDirectoryMaskItem, QString::fromLatin1( "DirectoryMask" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesWriteAccess;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ReadWrite" );
+ valuesWriteAccess.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ReadOnly" );
+ valuesWriteAccess.append( choice );
+ }
+ mWriteAccessItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "WriteAccess" ), mWriteAccess, valuesWriteAccess, EnumWriteAccess::ReadWrite );
+ mWriteAccessItem->setLabel( i18n("The write access granted for the share") );
+ mWriteAccessItem->setWhatsThis( i18n("Here you can choose if the shares should be mounted in read and write mode or only read-only.") );
+ addItem( mWriteAccessItem, QString::fromLatin1( "WriteAccess" ) );
+ mPermissionChecksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PermissionChecks" ), mPermissionChecks, true );
+ mPermissionChecksItem->setLabel( i18n("Do permission checks") );
+ mPermissionChecksItem->setWhatsThis( i18n("The client side (i.e. your side) will check if you have the right UID/GID to manipulate a file or directory. You might want to switch this feature off if the server(s) support the CIFS Unix Extensions and you are not allowed to access the files and directories. This setting does not affect the normal ACL check.") );
+ addItem( mPermissionChecksItem, QString::fromLatin1( "PermissionChecks" ) );
+ mClientControlsIDsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ClientControlsIDs" ), mClientControlsIDs, false );
+ mClientControlsIDsItem->setLabel( i18n("Set UID and GID") );
+ mClientControlsIDsItem->setWhatsThis( i18n("In case the server supports the CIFS Unix Extensions, the client side (i.e. your side) attempts to set the effective UID and GID of the current process on newly created files, directories and devices. If this feature is turned off, the default UID and GID defined for the share will be used. It is recommended that you read the manual page of mount.cifs before you change this setting.") );
+ addItem( mClientControlsIDsItem, QString::fromLatin1( "ClientControlsIDs" ) );
+ mServerInodeNumbersItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ServerInodeNumbers" ), mServerInodeNumbers, false );
+ mServerInodeNumbersItem->setLabel( i18n("Use server inode numbers") );
+ mServerInodeNumbersItem->setWhatsThis( i18n("Use inode numbers (unique persistent file identifiers) returned by the server instead of automatically generating temporary inode numbers on the client side.") );
+ addItem( mServerInodeNumbersItem, QString::fromLatin1( "ServerInodeNumbers" ) );
+ mInodeDataCachingItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "InodeDataCaching" ), mInodeDataCaching, false );
+ mInodeDataCachingItem->setLabel( i18n("Do not cache inode data") );
+ mInodeDataCachingItem->setWhatsThis( i18n("Directly read from and write to files opened on the share. In some cases this can provide better performance than the default behavior which caches reads and writes.") );
+ addItem( mInodeDataCachingItem, QString::fromLatin1( "InodeDataCaching" ) );
+ mTranslateReservedCharsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "TranslateReservedChars" ), mTranslateReservedChars, false );
+ mTranslateReservedCharsItem->setLabel( i18n("Translate reserved characters") );
+ mTranslateReservedCharsItem->setWhatsThis( i18n("Translate six of the seven reserved characters (including the colon, question mark, pipe, asterisk, greater than and less than characters but not the backslash) to remap range (above 0xF000). This allows you to open files that were created with such characters. This has no effect if the server does not support Unicode.") );
+ addItem( mTranslateReservedCharsItem, QString::fromLatin1( "TranslateReservedChars" ) );
+ mNoLockingItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "NoLocking" ), mNoLocking, false );
+ mNoLockingItem->setLabel( i18n("Do not use locking") );
+ mNoLockingItem->setWhatsThis( i18n("Do not use locking. Do not start lockd.") );
+ addItem( mNoLockingItem, QString::fromLatin1( "NoLocking" ) );
+ mCustomCIFSOptionsItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "CustomCIFSOptions" ), mCustomCIFSOptions );
+ mCustomCIFSOptionsItem->setLabel( i18n("Advanced custom options for the CIFS file system") );
+ mCustomCIFSOptionsItem->setWhatsThis( i18n("Here you can enter advanced options for the CIFS file system in a comma-separated list (refer to the manual page of mount.cifs to learn more). The list will be added AS IS to the \"-o\" argument of mount.cifs. Please do not enter options that have already been defined in the configuration dialog.") );
+ addItem( mCustomCIFSOptionsItem, QString::fromLatin1( "CustomCIFSOptions" ) );
+ mCachingTimeItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "CachingTime" ), mCachingTime, 1000 );
+ mCachingTimeItem->setLabel( i18n("Determines how long directory listings are cached") );
+ mCachingTimeItem->setWhatsThis( i18n("This setting determines how long a directory listing is cached in milliseconds. A high value means it takes longer until changes on the server are noticed on the client side (i.e. your side), but it can also give you an increase in performance on large directories, especially on long distances. You need Linux kernel 2.4.2 or later to take advantage of this setting.") );
+ addItem( mCachingTimeItem, QString::fromLatin1( "CachingTime" ) );
+ mUnicodeSupportItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UnicodeSupport" ), mUnicodeSupport, false );
+ mUnicodeSupportItem->setLabel( i18n("Unicode support") );
+ mUnicodeSupportItem->setWhatsThis( i18n("Use Unicode when communicating with the server. This will give you better support for non-ASCII character sets with the SMBFS file system.") );
+ addItem( mUnicodeSupportItem, QString::fromLatin1( "UnicodeSupport" ) );
+ mLargeFileSystemSupportItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "LargeFileSystemSupport" ), mLargeFileSystemSupport, false );
+ mLargeFileSystemSupportItem->setLabel( i18n("Long file support") );
+ mLargeFileSystemSupportItem->setWhatsThis( i18n("Large file support (LFS) enables you to read and write \n"
+"files bigger than 2 GB on shares that were mounted with the SMBFS file system.") );
+ addItem( mLargeFileSystemSupportItem, QString::fromLatin1( "LargeFileSystemSupport" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesProtocolHint;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Automatic" );
+ valuesProtocolHint.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "RPC" );
+ valuesProtocolHint.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "RAP" );
+ valuesProtocolHint.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ADS" );
+ valuesProtocolHint.append( choice );
+ }
+ mProtocolHintItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "ProtocolHint" ), mProtocolHint, valuesProtocolHint, EnumProtocolHint::Automatic );
+ mProtocolHintItem->setLabel( i18n("The protocol that is used with the net command") );
+ mProtocolHintItem->setWhatsThis( i18n("Here you can choose the protocol that will be used by the net command for the communication with remote servers if appropriate. In most cases the automatic detection will work fine and you should not need to change the default setting. However, if you experience problems, use the RPC protocol for newer operating systems (Windows NT4 and above) and the RAP protocol for older ones (Windows 98/NT3 and below). Functions that need the ADS protocol (for Active Directory environments) have not been implemented yet, so you can ignore that one for now.") );
+ addItem( mProtocolHintItem, QString::fromLatin1( "ProtocolHint" ) );
+ mNameResolveOrderItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "NameResolveOrder" ), mNameResolveOrder );
+ mNameResolveOrderItem->setLabel( i18n("Name resolve order used by smbclient") );
+ mNameResolveOrderItem->setWhatsThis( i18n("This option is used to determine what naming services and in what order are used to resolve host names and IP addresses. It takes a space-separated list of up to four different name resolution options. Those are: lmhost, host, wins, bcast. See the manual page of smbclient for further information.") );
+ addItem( mNameResolveOrderItem, QString::fromLatin1( "NameResolveOrder" ) );
+ mBufferSizeItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "BufferSize" ), mBufferSize, 65520 );
+ mBufferSizeItem->setMinValue(0);
+ mBufferSizeItem->setLabel( i18n("Transmit/send buffer size used by smbclient") );
+ mBufferSizeItem->setWhatsThis( i18n("This option changes the transmit/send buffer size when getting or putting a file from/to the server. The default is 65520 bytes. Setting this value smaller has been observed to speed up file transfers to and from Windows 9x servers.") );
+ addItem( mBufferSizeItem, QString::fromLatin1( "BufferSize" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesSigningState;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "None" );
+ valuesSigningState.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "On" );
+ valuesSigningState.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Off" );
+ valuesSigningState.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Required" );
+ valuesSigningState.append( choice );
+ }
+ mSigningStateItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "SigningState" ), mSigningState, valuesSigningState, EnumSigningState::None );
+ mSigningStateItem->setLabel( i18n("Signing state") );
+ mSigningStateItem->setWhatsThis( i18n("Set the signing state for smbclient.") );
+ addItem( mSigningStateItem, QString::fromLatin1( "SigningState" ) );
+ mBroadcastAddressItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "BroadcastAddress" ), mBroadcastAddress );
+ mBroadcastAddressItem->setLabel( i18n("The broadcast address used by nmblookup") );
+ mBroadcastAddressItem->setWhatsThis( i18n("Queries performed with nmblookup will be send to the given broadcast address. Without this option the default behavior is to send the queries to the broadcast address of the network interface that was either auto-detected or defined in the \"interfaces\" parameter of the smb.conf file.") );
+ addItem( mBroadcastAddressItem, QString::fromLatin1( "BroadcastAddress" ) );
+ mUsePort137Item = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UsePort137" ), mUsePort137, false );
+ mUsePort137Item->setLabel( i18n("Use UDP port 137 with nmblookup") );
+ mUsePort137Item->setWhatsThis( i18n("Try and bind to UDP port 137 to send and receive UDP datagrams. The reason for this option is a bug in Windows 95 where it ignores the source port of the requesting packet and only replies to UDP port 137. Unfortunately, on most Unix systems super user privileges are needed to bind to this port. Please read the manual page of nmblookup for more information.") );
+ addItem( mUsePort137Item, QString::fromLatin1( "UsePort137" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Synchronization" ) );
+
+ mRsyncPrefixItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "RsyncPrefix" ), mRsyncPrefix, QString::fromLatin1( "$HOME/smb4k_sync/" ) );
+ mRsyncPrefixItem->setLabel( i18n("Prefix for synchronization") );
+ mRsyncPrefixItem->setWhatsThis( i18n("This is the path where Smb4K will store the files and directories during synchronization. If you plan to synchronize only with one remote share, then you can put the data directly in this directory. If you want to synchronize with several remote shares, then you should create a subdirectory for each share and choose the appropriate one in the synchronization dialog.") );
+ addItem( mRsyncPrefixItem, QString::fromLatin1( "RsyncPrefix" ) );
+ mArchiveModeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ArchiveMode" ), mArchiveMode, true );
+ mArchiveModeItem->setLabel( i18n("Use archive mode") );
+ mArchiveModeItem->setWhatsThis( i18n("Use archive mode (-a, --archive). This is a short form of -rlptgoD.") );
+ addItem( mArchiveModeItem, QString::fromLatin1( "ArchiveMode" ) );
+ mRecurseIntoDirectoriesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "RecurseIntoDirectories" ), mRecurseIntoDirectories, true );
+ mRecurseIntoDirectoriesItem->setLabel( i18n("Recurse into subdirectories") );
+ mRecurseIntoDirectoriesItem->setWhatsThis( i18n("Recurse into directories (-r, --recursive).") );
+ addItem( mRecurseIntoDirectoriesItem, QString::fromLatin1( "RecurseIntoDirectories" ) );
+ mUpdateTargetItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UpdateTarget" ), mUpdateTarget, true );
+ mUpdateTargetItem->setLabel( i18n("Skip files that are newer in the target directory") );
+ mUpdateTargetItem->setWhatsThis( i18n("Update files in the destination directory that are older than in the source directory (-u, --update).") );
+ addItem( mUpdateTargetItem, QString::fromLatin1( "UpdateTarget" ) );
+ mUpdateInPlaceItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UpdateInPlace" ), mUpdateInPlace, false );
+ mUpdateInPlaceItem->setLabel( i18n("Update destination files in place") );
+ mUpdateInPlaceItem->setWhatsThis( i18n("Update destination files in-place (--inplace). By default, rsync first creates a new copy of a file and moves it into place after its transfer finished. If you enable this feature, no copy will be created but the destination file will immediately be overwritten instead. An exception to this is if you combine this option with --backup.") );
+ addItem( mUpdateInPlaceItem, QString::fromLatin1( "UpdateInPlace" ) );
+ mRelativePathNamesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "RelativePathNames" ), mRelativePathNames, false );
+ mRelativePathNamesItem->setLabel( i18n("Use relative path names") );
+ mRelativePathNamesItem->setWhatsThis( i18n("Use relative paths (-R, --relative). This means that the full path names specified on the command line are sent to the server rather than just the last parts of the file names.") );
+ addItem( mRelativePathNamesItem, QString::fromLatin1( "RelativePathNames" ) );
+ mNoImpliedDirectoriesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "NoImpliedDirectories" ), mNoImpliedDirectories, false );
+ mNoImpliedDirectoriesItem->setLabel( i18n("Don't send implied directories with --relative") );
+ mNoImpliedDirectoriesItem->setWhatsThis( i18n("Don't send implied directories with --relative (--no-implied-dirs). This means that the corresponding path elements on the destination system are left unchanged if they exist, and any missing implied directories are created with default attributes. This even allows these implied path elements to have big differences, such as being a symlink to a directory on one side of the transfer, and a real directory on the other side.") );
+ addItem( mNoImpliedDirectoriesItem, QString::fromLatin1( "NoImpliedDirectories" ) );
+ mTransferDirectoriesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "TransferDirectories" ), mTransferDirectories, false );
+ mTransferDirectoriesItem->setLabel( i18n("Transfer directories without recursing") );
+ mTransferDirectoriesItem->setWhatsThis( i18n("Transfer directories without recursing (-d, --dirs). This means that all top-level subdirectories are transferred but without their contents.") );
+ addItem( mTransferDirectoriesItem, QString::fromLatin1( "TransferDirectories" ) );
+ mCompressDataItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "CompressData" ), mCompressData, false );
+ mCompressDataItem->setLabel( i18n("Compress data during transfer") );
+ mCompressDataItem->setWhatsThis( i18n("Compress data during transfer (-z, --compress). This significantly reduces the amount of data that is being transferred. You may want to use this option, if you have a slow connection.") );
+ addItem( mCompressDataItem, QString::fromLatin1( "CompressData" ) );
+ mPreserveSymlinksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreserveSymlinks" ), mPreserveSymlinks, true );
+ mPreserveSymlinksItem->setLabel( i18n("Preserve symlinks") );
+ mPreserveSymlinksItem->setWhatsThis( i18n("Copy symlinks as symlinks (-l, --links).") );
+ addItem( mPreserveSymlinksItem, QString::fromLatin1( "PreserveSymlinks" ) );
+ mTransformSymlinksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "TransformSymlinks" ), mTransformSymlinks, false );
+ mTransformSymlinksItem->setLabel( i18n("Transform symlinks") );
+ mTransformSymlinksItem->setWhatsThis( i18n("Transform symlinks into the items they are pointing to (-L, --copy-links).") );
+ addItem( mTransformSymlinksItem, QString::fromLatin1( "TransformSymlinks" ) );
+ mTransformUnsafeSymlinksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "TransformUnsafeSymlinks" ), mTransformUnsafeSymlinks, false );
+ mTransformUnsafeSymlinksItem->setLabel( i18n("Only transform unsafe symlinks") );
+ mTransformUnsafeSymlinksItem->setWhatsThis( i18n("Transform unsafe symlinks into the items they are pointing to (--copy-unsafe-links). This means that only those symlinks are transformed that point to items that are outside the copied tree. Absolute symlinks are treated the same way. This option has no additional effect if --copy-links has also been specified.") );
+ addItem( mTransformUnsafeSymlinksItem, QString::fromLatin1( "TransformUnsafeSymlinks" ) );
+ mIgnoreUnsafeSymlinksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "IgnoreUnsafeSymlinks" ), mIgnoreUnsafeSymlinks, false );
+ mIgnoreUnsafeSymlinksItem->setLabel( i18n("Ignore unsafe symlinks") );
+ mIgnoreUnsafeSymlinksItem->setWhatsThis( i18n("Ignore symlinks that point outside the copied tree (--safe-links). All absolute symlinks are also ignored. If you use this option in conjunction with --relative you might get unexpected results.") );
+ addItem( mIgnoreUnsafeSymlinksItem, QString::fromLatin1( "IgnoreUnsafeSymlinks" ) );
+ mPreserveHardLinksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreserveHardLinks" ), mPreserveHardLinks, false );
+ mPreserveHardLinksItem->setLabel( i18n("Preserve hard links") );
+ mPreserveHardLinksItem->setWhatsThis( i18n("Preserve hard links (-H, --hard-links). This options causes rsync to preserve the hard links that are found during the transfer. Without it, hard links are treated as though they were separate files.") );
+ addItem( mPreserveHardLinksItem, QString::fromLatin1( "PreserveHardLinks" ) );
+ mKeepDirectorySymlinksItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "KeepDirectorySymlinks" ), mKeepDirectorySymlinks, false );
+ mKeepDirectorySymlinksItem->setLabel( i18n("Keep directory symlinks") );
+ mKeepDirectorySymlinksItem->setWhatsThis( i18n("Treat symlinked directories on the receiving side as though they were real ones (-K, --keep-dirlinks). This only works if the symlink matches a real directory from the sending side. Without this option, the receiver's symlink will be deleted and replaced with a real directory.") );
+ addItem( mKeepDirectorySymlinksItem, QString::fromLatin1( "KeepDirectorySymlinks" ) );
+ mPreservePermissionsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreservePermissions" ), mPreservePermissions, true );
+ mPreservePermissionsItem->setLabel( i18n("Preserve permissions") );
+ mPreservePermissionsItem->setWhatsThis( i18n("Preserve permissions (-p, --perms). The permissions of the destination file will be same as the source file. For what happens if this option is switched off, please read rsync's manual page.") );
+ addItem( mPreservePermissionsItem, QString::fromLatin1( "PreservePermissions" ) );
+ mPreserveGroupItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreserveGroup" ), mPreserveGroup, true );
+ mPreserveGroupItem->setLabel( i18n("Preserve group") );
+ mPreserveGroupItem->setWhatsThis( i18n("Preserve the group (-g, --group). The group of the destination file will be set to the same value as the source file.") );
+ addItem( mPreserveGroupItem, QString::fromLatin1( "PreserveGroup" ) );
+ mPreserveOwnerItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreserveOwner" ), mPreserveOwner, true );
+ mPreserveOwnerItem->setLabel( i18n("Preserve owner (super user only)") );
+ mPreserveOwnerItem->setWhatsThis( i18n("Preserve the owner (-o, --owner). The owner of the destination file will be set to the same value as the source file, but only if the receiving rsync is run as the super user. Without this option, the owner is set to the invoking user on the receiving side.") );
+ addItem( mPreserveOwnerItem, QString::fromLatin1( "PreserveOwner" ) );
+ mPreserveDevicesAndSpecialsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreserveDevicesAndSpecials" ), mPreserveDevicesAndSpecials, true );
+ mPreserveDevicesAndSpecialsItem->setLabel( i18n("Preserve device and special files") );
+ mPreserveDevicesAndSpecialsItem->setWhatsThis( i18n("Preserve device and special files (-D, --devices --specials). This option causes rsync to transfer character and block devices as well as special files such as named sockets and fifos. It works only partially if rsync is not run as super user and the --super option is not specified.") );
+ addItem( mPreserveDevicesAndSpecialsItem, QString::fromLatin1( "PreserveDevicesAndSpecials" ) );
+ mPreserveTimesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "PreserveTimes" ), mPreserveTimes, true );
+ mPreserveTimesItem->setLabel( i18n("Preserve times") );
+ mPreserveTimesItem->setWhatsThis( i18n("Preserve times (-t, --times). The modification times are transferred along with the files. For what happens if this option is switched off, please read rsync's manual page.") );
+ addItem( mPreserveTimesItem, QString::fromLatin1( "PreserveTimes" ) );
+ mOmitDirectoryTimesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "OmitDirectoryTimes" ), mOmitDirectoryTimes, false );
+ mOmitDirectoryTimesItem->setLabel( i18n("Omit directories when preserving times") );
+ mOmitDirectoryTimesItem->setWhatsThis( i18n("Omit directories when preserving times (-O, --omit-dir-times). This means that directories are omitted when modification times are being preserved. Thus, this feature only works in conjunction with --times.") );
+ addItem( mOmitDirectoryTimesItem, QString::fromLatin1( "OmitDirectoryTimes" ) );
+ mRemoveSourceFilesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "RemoveSourceFiles" ), mRemoveSourceFiles, false );
+ mRemoveSourceFilesItem->setLabel( i18n("Remove synchronized source files") );
+ mRemoveSourceFilesItem->setWhatsThis( i18n("Remove all synchronized source files (--remove-source-files). This tells rsync to remove from the sending side the non-directory items that are a part of the transfer and have been successfully duplicated on the receiving side.") );
+ addItem( mRemoveSourceFilesItem, QString::fromLatin1( "RemoveSourceFiles" ) );
+ mDeleteExtraneousItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "DeleteExtraneous" ), mDeleteExtraneous, false );
+ mDeleteExtraneousItem->setLabel( i18n("Delete extraneous files") );
+ mDeleteExtraneousItem->setWhatsThis( i18n("Delete extraneous files from destination (--delete). This tells rsync to delete all files from the receiving side that are not present on the sending side, but only for the directories that are being synchronized.") );
+ addItem( mDeleteExtraneousItem, QString::fromLatin1( "DeleteExtraneous" ) );
+ mDeleteBeforeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "DeleteBefore" ), mDeleteBefore, false );
+ mDeleteBeforeItem->setLabel( i18n("Delete files before transfer") );
+ mDeleteBeforeItem->setWhatsThis( i18n("Delete files on the receiving side before the transfer starts (--delete-before). This is the default behavior if --delete or --delete-excluded is specified without one of the --delete-WHEN options.") );
+ addItem( mDeleteBeforeItem, QString::fromLatin1( "DeleteBefore" ) );
+ mDeleteAfterItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "DeleteAfter" ), mDeleteAfter, false );
+ mDeleteAfterItem->setLabel( i18n("Delete files after transfer") );
+ mDeleteAfterItem->setWhatsThis( i18n("Delete files on the receiving side after the transfer has completed (--delete-after, --del).") );
+ addItem( mDeleteAfterItem, QString::fromLatin1( "DeleteAfter" ) );
+ mDeleteDuringItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "DeleteDuring" ), mDeleteDuring, false );
+ mDeleteDuringItem->setLabel( i18n("Delete files during transfer") );
+ mDeleteDuringItem->setWhatsThis( i18n("Delete files on the receiving side during the transfer (--delete-during). This method is faster than --delete-before or --delete-after, but it is only supported with rsync 2.6.4 or later.") );
+ addItem( mDeleteDuringItem, QString::fromLatin1( "DeleteDuring" ) );
+ mDeleteExcludedItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "DeleteExcluded" ), mDeleteExcluded, false );
+ mDeleteExcludedItem->setLabel( i18n("Also delete excluded files from destination directory") );
+ mDeleteExcludedItem->setWhatsThis( i18n("Also delete excluded files from destination directory (--delete-excluded). In addition to deleting the files on the receiving side that are not on the sending side, this tells rsync to also delete any files on the receiving side that are excluded. Refer to rsync's manual page for further information.") );
+ addItem( mDeleteExcludedItem, QString::fromLatin1( "DeleteExcluded" ) );
+ mIgnoreErrorsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "IgnoreErrors" ), mIgnoreErrors, false );
+ mIgnoreErrorsItem->setLabel( i18n("Delete even if I/O errors occur") );
+ mIgnoreErrorsItem->setWhatsThis( i18n("Delete even if I/O errors occur (--ignore-errors). This option has to be specified in conjunction with --delete to take effect.") );
+ addItem( mIgnoreErrorsItem, QString::fromLatin1( "IgnoreErrors" ) );
+ mForceDirectoryDeletionItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "ForceDirectoryDeletion" ), mForceDirectoryDeletion, false );
+ mForceDirectoryDeletionItem->setLabel( i18n("Force deletion of non-void directories") );
+ mForceDirectoryDeletionItem->setWhatsThis( i18n("Force deletion of directories even if they are not empty (--force). This option tells rsync to delete a non-empty directory when it is to be replaced by a non-directory. This is only relevant if deletions are not active.") );
+ addItem( mForceDirectoryDeletionItem, QString::fromLatin1( "ForceDirectoryDeletion" ) );
+ mUseMaximumDeleteItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseMaximumDelete" ), mUseMaximumDelete, false );
+ mUseMaximumDeleteItem->setLabel( i18n("Only delete a maximum number of files") );
+ mUseMaximumDeleteItem->setWhatsThis( i18n("Only delete as many files as defined here (--max-delete=NUM). This tells rsync not to delete more than NUM files or directories (NUM must be non-zero). This is useful when mirroring very large trees to prevent disasters.") );
+ addItem( mUseMaximumDeleteItem, QString::fromLatin1( "UseMaximumDelete" ) );
+ mMaximumDeleteValueItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "MaximumDeleteValue" ), mMaximumDeleteValue, 0 );
+ mMaximumDeleteValueItem->setMinValue(0);
+ mMaximumDeleteValueItem->setLabel( i18n("Value for DeleteMaximum config entry") );
+ addItem( mMaximumDeleteValueItem, QString::fromLatin1( "MaximumDeleteValue" ) );
+ mUseMinimalTransferSizeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseMinimalTransferSize" ), mUseMinimalTransferSize, false );
+ mUseMinimalTransferSizeItem->setLabel( i18n("Don't transfer any file smaller than SIZE") );
+ mUseMinimalTransferSizeItem->setWhatsThis( i18n("This option causes rsync to not transfer any file that is smaller than the specified size (--min-size=SIZE).") );
+ addItem( mUseMinimalTransferSizeItem, QString::fromLatin1( "UseMinimalTransferSize" ) );
+ mMinimalTransferSizeItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "MinimalTransferSize" ), mMinimalTransferSize, 0 );
+ mMinimalTransferSizeItem->setMinValue(0);
+ mMinimalTransferSizeItem->setLabel( i18n("Value for MinimalTransferSize config entry") );
+ addItem( mMinimalTransferSizeItem, QString::fromLatin1( "MinimalTransferSize" ) );
+ mUseMaximalTransferSizeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseMaximalTransferSize" ), mUseMaximalTransferSize, false );
+ mUseMaximalTransferSizeItem->setLabel( i18n("Don't transfer any file smaller than SIZE") );
+ mUseMaximalTransferSizeItem->setWhatsThis( i18n("This option causes rsync to not transfer any file that is larger than the specified size (--max-size=SIZE).") );
+ addItem( mUseMaximalTransferSizeItem, QString::fromLatin1( "UseMaximalTransferSize" ) );
+ mMaximalTransferSizeItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "MaximalTransferSize" ), mMaximalTransferSize, 0 );
+ mMaximalTransferSizeItem->setMinValue(0);
+ mMaximalTransferSizeItem->setLabel( i18n("Value for MamximalTransferSize config entry") );
+ addItem( mMaximalTransferSizeItem, QString::fromLatin1( "MaximalTransferSize" ) );
+ mKeepPartialItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "KeepPartial" ), mKeepPartial, false );
+ mKeepPartialItem->setLabel( i18n("Keep partially transferred files") );
+ mKeepPartialItem->setWhatsThis( i18n("Keep partially transferred files (--partial). The default behavor is that any partially transferred file is deleted if the transfer is interrupted.") );
+ addItem( mKeepPartialItem, QString::fromLatin1( "KeepPartial" ) );
+ mUsePartialDirectoryItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UsePartialDirectory" ), mUsePartialDirectory, false );
+ mUsePartialDirectoryItem->setLabel( i18n("The directory where to put a partially transferred file into.") );
+ mUsePartialDirectoryItem->setWhatsThis( i18n("Put a partially transferred file into this directory (--partial-dir=DIR). This is a better way than the --partial option to keep partial files, because the partially transferred file is kept in a different directory and the destination file is not overwritten.") );
+ addItem( mUsePartialDirectoryItem, QString::fromLatin1( "UsePartialDirectory" ) );
+ mPartialDirectoryItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "PartialDirectory" ), mPartialDirectory, QString::fromLatin1( "$HOME" ) );
+ mPartialDirectoryItem->setLabel( i18n("The data for the UsePartialDirectory option") );
+ addItem( mPartialDirectoryItem, QString::fromLatin1( "PartialDirectory" ) );
+ mUseCVSExcludeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseCVSExclude" ), mUseCVSExclude, false );
+ mUseCVSExcludeItem->setLabel( i18n("Auto-ignore files in the same way CVS does") );
+ mUseCVSExcludeItem->setWhatsThis( i18n("Auto-ignore files in the same way CVS does (-C, --cvs-exclude). This is a useful shorthand for excluding a broad range of files that you often do not want to transfer between systems. This option uses the same algorithm that CVS uses to determine if a file should be ignored.") );
+ addItem( mUseCVSExcludeItem, QString::fromLatin1( "UseCVSExclude" ) );
+ mUseExcludePatternItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseExcludePattern" ), mUseExcludePattern, false );
+ mUseExcludePatternItem->setLabel( i18n("Exclude files that match a certain pattern") );
+ mUseExcludePatternItem->setWhatsThis( i18n("Exclude files that match a certain pattern (--exclude=PATTERN). This is a special filter rule. For further information on filter rules see rsync's manual page.") );
+ addItem( mUseExcludePatternItem, QString::fromLatin1( "UseExcludePattern" ) );
+ mExcludePatternItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "ExcludePattern" ), mExcludePattern );
+ mExcludePatternItem->setLabel( i18n("Pattern that is used for file exclusion") );
+ addItem( mExcludePatternItem, QString::fromLatin1( "ExcludePattern" ) );
+ mUseExcludeFromItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseExcludeFrom" ), mUseExcludeFrom, false );
+ mUseExcludeFromItem->setLabel( i18n("Read exclude patterns from a file") );
+ mUseExcludeFromItem->setWhatsThis( i18n("Read exclude patterns from a file (--exclude-from=FILE). This option is similar to the --exclude=PATTERN option except that the exclude patterns are read from a file. This is a special filter rule. For further information on filter rules see rsync's manual page.") );
+ addItem( mUseExcludeFromItem, QString::fromLatin1( "UseExcludeFrom" ) );
+ mExcludeFromItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "ExcludeFrom" ), mExcludeFrom, QString::fromLatin1( "$HOME/exclude.txt" ) );
+ mExcludeFromItem->setLabel( i18n("The file from which the exclude patterns are read") );
+ addItem( mExcludeFromItem, QString::fromLatin1( "ExcludeFrom" ) );
+ mUseIncludePatternItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseIncludePattern" ), mUseIncludePattern, false );
+ mUseIncludePatternItem->setLabel( i18n("Do not exclude files matching a certain pattern") );
+ mUseIncludePatternItem->setWhatsThis( i18n("Do not exclude files matching a certain pattern (--include=PATTERN). This is a special filter rule. For further information on filter rules see rsync's manual page.") );
+ addItem( mUseIncludePatternItem, QString::fromLatin1( "UseIncludePattern" ) );
+ mIncludePatternItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "IncludePattern" ), mIncludePattern );
+ mIncludePatternItem->setLabel( i18n("Pattern that is used for file inclusion") );
+ addItem( mIncludePatternItem, QString::fromLatin1( "IncludePattern" ) );
+ mUseIncludeFromItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseIncludeFrom" ), mUseIncludeFrom, false );
+ mUseIncludeFromItem->setLabel( i18n("Read include patterns from a file") );
+ mUseIncludeFromItem->setWhatsThis( i18n("Read include patterns from a file (--include-from=FILE). This option is similar to the --include=PATTERN option except that the include patterns are read from a file. This is a special filter rule. For further information on filter rules see rsync's manual page.") );
+ addItem( mUseIncludeFromItem, QString::fromLatin1( "UseIncludeFrom" ) );
+ mIncludeFromItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "IncludeFrom" ), mIncludeFrom, QString::fromLatin1( "$HOME/include.txt" ) );
+ mIncludeFromItem->setLabel( i18n("The file from which the include patterns are read") );
+ addItem( mIncludeFromItem, QString::fromLatin1( "IncludeFrom" ) );
+ mCustomFilteringRulesItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "CustomFilteringRules" ), mCustomFilteringRules );
+ mCustomFilteringRulesItem->setLabel( i18n("Add custom file-filtering rules") );
+ mCustomFilteringRulesItem->setWhatsThis( i18n("Add custom file-filtering rules (-f, --filter=RULE). This option allows you to add rules to selectively exclude certain files from the list of files to be transferred.") );
+ addItem( mCustomFilteringRulesItem, QString::fromLatin1( "CustomFilteringRules" ) );
+ mUseFFilterRuleItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseFFilterRule" ), mUseFFilterRule, false );
+ mUseFFilterRuleItem->setLabel( i18n("Use -F filter rule") );
+ mUseFFilterRuleItem->setWhatsThis( i18n("This filter rule tells rsync to look for per-directory .rsync-filter files that have been sprinkled through the hierarchy and use their rules to filter the files in the transfer. It has no effect, if you also choose to use the --filter='exclude .rsync-filter' rule.") );
+ addItem( mUseFFilterRuleItem, QString::fromLatin1( "UseFFilterRule" ) );
+ mUseFFFilterRuleItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseFFFilterRule" ), mUseFFFilterRule, false );
+ mUseFFFilterRuleItem->setLabel( i18n("Use -FF filter rule") );
+ mUseFFFilterRuleItem->setWhatsThis( i18n("This rule filters out the .rsync-filter files from the transfer. These files normally contain filter rules that can be activated by choosing the --filter='dir-merge /.rsync-filter' rule and deselecting this one.") );
+ addItem( mUseFFFilterRuleItem, QString::fromLatin1( "UseFFFilterRule" ) );
+ mEfficientSparseFileHandlingItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "EfficientSparseFileHandling" ), mEfficientSparseFileHandling, false );
+ mEfficientSparseFileHandlingItem->setLabel( i18n("Handle sparse files efficiently") );
+ mEfficientSparseFileHandlingItem->setWhatsThis( i18n("Handle sparse files efficiently (-S, --sparse) so that they take up less space on the destination. This option conflicts with --inplace. For further information read rsync's manual page.") );
+ addItem( mEfficientSparseFileHandlingItem, QString::fromLatin1( "EfficientSparseFileHandling" ) );
+ mCopyFilesWholeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "CopyFilesWhole" ), mCopyFilesWhole, false );
+ mCopyFilesWholeItem->setLabel( i18n("Copy files whole (no rsync algorithm)") );
+ mCopyFilesWholeItem->setWhatsThis( i18n("Copy files whole (-W, --whole-file). With this option the incremental rsync algorithm is not used and the whole file is sent as-is instead.") );
+ addItem( mCopyFilesWholeItem, QString::fromLatin1( "CopyFilesWhole" ) );
+ mOneFileSystemItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "OneFileSystem" ), mOneFileSystem, false );
+ mOneFileSystemItem->setLabel( i18n("Do not cross file system boundaries") );
+ mOneFileSystemItem->setWhatsThis( i18n("Do not cross file system boundaries (-x, --one-file-system). This tells rsync to avoid crossing a filesystem boundary when recursing. For further information on this option, read the manual page.") );
+ addItem( mOneFileSystemItem, QString::fromLatin1( "OneFileSystem" ) );
+ mUpdateExistingItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UpdateExisting" ), mUpdateExisting, false );
+ mUpdateExistingItem->setLabel( i18n("Skip creating new files on the receiving side") );
+ mUpdateExistingItem->setWhatsThis( i18n("Skip creating new files on the receiving side (--existing). This tells rsync to skip creating files (including directories) that do not exist yet on the destination. If this option is combined with the --ignore-existing option, no files will be updated (which can be useful if all you want to do is to delete extraneous files).") );
+ addItem( mUpdateExistingItem, QString::fromLatin1( "UpdateExisting" ) );
+ mIgnoreExistingItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "IgnoreExisting" ), mIgnoreExisting, false );
+ mIgnoreExistingItem->setLabel( i18n("Skip updating files that exist on the receiving side") );
+ mIgnoreExistingItem->setWhatsThis( i18n("Skip updating files that already exist on the receiving side (--ignore-existing). Existing directories are not ignored.") );
+ addItem( mIgnoreExistingItem, QString::fromLatin1( "IgnoreExisting" ) );
+ mDelayUpdatesItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "DelayUpdates" ), mDelayUpdates, false );
+ mDelayUpdatesItem->setLabel( i18n("Delay updates until the end of the transfer") );
+ mDelayUpdatesItem->setWhatsThis( i18n("Delay updates until the end of the transfer (--delay-updates). This option puts the temporary file from each updated file into a holding directory until the end of the transfer, at which time all the files are renamed and copied into place in rapid succession.") );
+ addItem( mDelayUpdatesItem, QString::fromLatin1( "DelayUpdates" ) );
+ mMakeBackupsItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "MakeBackups" ), mMakeBackups, false );
+ mMakeBackupsItem->setLabel( i18n("Make backups") );
+ mMakeBackupsItem->setWhatsThis( i18n("Make backups (-b, --backup). With this option, preexisting destination files are renamed as each file is transferred or deleted. You can control where the backup file goes and what (if any) suffix gets appended using the --backup-dir=DIR and --suffix=SUFFIX options.") );
+ addItem( mMakeBackupsItem, QString::fromLatin1( "MakeBackups" ) );
+ mUseBackupSuffixItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseBackupSuffix" ), mUseBackupSuffix, false );
+ mUseBackupSuffixItem->setLabel( i18n("Use a suffix for backups") );
+ mUseBackupSuffixItem->setWhatsThis( i18n("Use this suffix for backups (--suffix=SUFFIX).") );
+ addItem( mUseBackupSuffixItem, QString::fromLatin1( "UseBackupSuffix" ) );
+ mBackupSuffixItem = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "BackupSuffix" ), mBackupSuffix, QString::fromLatin1( "~" ) );
+ mBackupSuffixItem->setLabel( i18n("Backup suffix") );
+ addItem( mBackupSuffixItem, QString::fromLatin1( "BackupSuffix" ) );
+ mUseBackupDirectoryItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseBackupDirectory" ), mUseBackupDirectory, false );
+ mUseBackupDirectoryItem->setLabel( i18n("Put backups into a certain directory") );
+ mUseBackupDirectoryItem->setWhatsThis( i18n("Store backups in this directory (--backup-dir=DIR).") );
+ addItem( mUseBackupDirectoryItem, QString::fromLatin1( "UseBackupDirectory" ) );
+ mBackupDirectoryItem = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "BackupDirectory" ), mBackupDirectory, QString::fromLatin1( "$HOME" ) );
+ mBackupDirectoryItem->setLabel( i18n("Backup directory") );
+ addItem( mBackupDirectoryItem, QString::fromLatin1( "BackupDirectory" ) );
+ mUseBlockSizeItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseBlockSize" ), mUseBlockSize, false );
+ mUseBlockSizeItem->setLabel( i18n("Force a fixed checksum block-size") );
+ mUseBlockSizeItem->setWhatsThis( i18n("Force a fixed checksum block-size (-B, --block-size=SIZE). This forces the block size used in the rsync algorithm to a fixed value.") );
+ addItem( mUseBlockSizeItem, QString::fromLatin1( "UseBlockSize" ) );
+ mBlockSizeItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "BlockSize" ), mBlockSize, 0 );
+ mBlockSizeItem->setMinValue(0);
+ mBlockSizeItem->setLabel( i18n("The block size") );
+ addItem( mBlockSizeItem, QString::fromLatin1( "BlockSize" ) );
+ mUseChecksumSeedItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseChecksumSeed" ), mUseChecksumSeed, false );
+ mUseChecksumSeedItem->setLabel( i18n("Set block/file checksum seed") );
+ mUseChecksumSeedItem->setWhatsThis( i18n("Set block/file checksum seed (--checksum-seed=NUM). Set the MD4 checksum seed to this integer. This 4 byte checksum seed is included in each block and file MD4 checksum calculation. By default the checksum seed is generated by the server and defaults to the current time.") );
+ addItem( mUseChecksumSeedItem, QString::fromLatin1( "UseChecksumSeed" ) );
+ mChecksumSeedItem = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "ChecksumSeed" ), mChecksumSeed, 0 );
+ mChecksumSeedItem->setMinValue(0);
+ mChecksumSeedItem->setLabel( i18n("The checksum seed") );
+ addItem( mChecksumSeedItem, QString::fromLatin1( "ChecksumSeed" ) );
+ mUseChecksumItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseChecksum" ), mUseChecksum, false );
+ mUseChecksumItem->setLabel( i18n("Skip files based on a checksum") );
+ mUseChecksumItem->setWhatsThis( i18n("Skip files based on a checksum and not based on modification time and size (-c, --checksum). For further information on how this feature works read rsync's manual page.") );
+ addItem( mUseChecksumItem, QString::fromLatin1( "UseChecksum" ) );
+
+ setCurrentGroup( QString::fromLatin1( "SuperUser" ) );
+
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesSuperUserProgram;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Sudo" );
+ valuesSuperUserProgram.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "Super" );
+ valuesSuperUserProgram.append( choice );
+ }
+ mSuperUserProgramItem = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "SuperUserProgram" ), mSuperUserProgram, valuesSuperUserProgram, EnumSuperUserProgram::Sudo );
+ mSuperUserProgramItem->setLabel( i18n("The program that should be used to gain super user privileges") );
+ mSuperUserProgramItem->setWhatsThis( i18n("Choose the program that will grant you limited super user privileges for mounting and unmounting remote shares. You can either select sudo, the standard tool for this purpose on most distributions, or super.") );
+ addItem( mSuperUserProgramItem, QString::fromLatin1( "SuperUserProgram" ) );
+ mUseForceUnmountItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "UseForceUnmount" ), mUseForceUnmount, false );
+ mUseForceUnmountItem->setLabel( i18n("Use super user privileges to unmount inaccessible shares") );
+ mUseForceUnmountItem->setWhatsThis( i18n("Unmount a share under Linux by force. This even works if the file system is \"busy\", because it is immediately detached from the file system hierarchy and all references to it are cleaned up later when it is not busy anymore. Linux kernel 2.4.11 or later is needed to take advantage of this feature. Use with case! Note, that you will need the root password to write the necessary changes to the configuration file.") );
+ addItem( mUseForceUnmountItem, QString::fromLatin1( "UseForceUnmount" ) );
+ mAlwaysUseSuperUserItem = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "AlwaysUseSuperUser" ), mAlwaysUseSuperUser, false );
+ mAlwaysUseSuperUserItem->setLabel( i18n("Use super user privileges to mount and unmount shares") );
+ mAlwaysUseSuperUserItem->setWhatsThis( i18n("Use super user privileges for mounting and unmounting remote shares. This feature is only needed, if you are not allowed to use smbmount, smbumount, mount.cifs and umount.cifs as normal user. Note, that you will need the root password to write the necessary changes to the configuration file.") );
+ addItem( mAlwaysUseSuperUserItem, QString::fromLatin1( "AlwaysUseSuperUser" ) );
+}
+
+Smb4KSettings::~Smb4KSettings()
+{
+ if ( mSelf == this )
+ staticSmb4KSettingsDeleter.setObject( mSelf, 0, false );
+}
+
diff --git a/smb4k/core/smb4ksettings.kcfgc b/smb4k/core/smb4ksettings.kcfgc
new file mode 100644
index 0000000..c103aec
--- /dev/null
+++ b/smb4k/core/smb4ksettings.kcfgc
@@ -0,0 +1,6 @@
+File=smb4k.kcfg
+ClassName=Smb4KSettings
+Singleton=true
+Mutators=true
+ItemAccessors=true
+SetUserTexts=true
diff --git a/smb4k/core/smb4kshare.cpp b/smb4k/core/smb4kshare.cpp
new file mode 100644
index 0000000..7877171
--- /dev/null
+++ b/smb4k/core/smb4kshare.cpp
@@ -0,0 +1,216 @@
+/***************************************************************************
+ smb4kshare - This is a container that holds information about
+ a mounted remote share.
+ -------------------
+ begin : Do Mär 4 2004
+ copyright : (C) 2004 by Franck Babin
+ (C) 2005 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qdir.h>
+
+// KDE includes
+#include <kdebug.h>
+
+// system includes
+#include <unistd.h>
+#include <sys/types.h>
+
+// application specific includes
+#include "smb4kshare.h"
+
+
+Smb4KShare::Smb4KShare( const QString &name, const QString &path, const QString &filesystem, const int uid, const int gid, bool broken ) :
+m_name(name), m_path( path.local8Bit() ), m_filesystem( filesystem ), m_user( uid ), m_group( gid ), m_cifs_login( QString::null ), m_broken( broken ), m_total( 0 ), m_free( 0 )
+{
+ //FIXME should throw an exception if one of the param is empty
+
+ if ( uid != (int)getuid() && gid != (int)getgid() )
+ {
+ m_foreign_mount = true;
+ }
+ else
+ {
+ m_foreign_mount = false;
+ }
+}
+
+
+Smb4KShare::Smb4KShare( const QString &name, const QString &path, const QString &filesystem, const QString &username, bool foreign, bool broken ) :
+m_name( name ), m_path( path.local8Bit() ), m_filesystem( filesystem ), m_user( (int)getuid() ), m_group( (int)getgid() ), m_cifs_login( username ), m_foreign_mount( foreign ), m_broken( broken ), m_total( 0 ), m_free( 0 )
+{
+}
+
+
+Smb4KShare::Smb4KShare( const Smb4KShare &s ) :
+m_name( s.name() ), m_path( s.path() ), m_filesystem( s.filesystem() ), m_user( s.uid() ), m_group( s.gid() ), m_cifs_login( s.cifsLogin() ), m_foreign_mount( s.isForeign() ), m_broken( s.isBroken() ), m_total( s.totalDiskSpace() ), m_free( s.freeDiskSpace() )
+{
+}
+
+
+Smb4KShare::~Smb4KShare()
+{
+}
+
+
+
+const QString &Smb4KShare::name() const
+{
+ return m_name;
+}
+
+
+const QCString &Smb4KShare::path() const
+{
+ return m_path;
+}
+
+
+const QCString Smb4KShare::canonicalPath() const
+{
+ return m_broken ? m_path : QDir( m_path ).canonicalPath().local8Bit();
+}
+
+
+int Smb4KShare::uid() const
+{
+ return (int)m_user.uid();
+}
+
+
+void Smb4KShare::setUID( int uid )
+{
+ m_user = KUser( uid );
+}
+
+
+int Smb4KShare::gid() const
+{
+ return (int)m_group.gid();
+}
+
+
+void Smb4KShare::setGID( int gid )
+{
+ m_group = KUserGroup( gid );
+}
+
+
+const QString Smb4KShare::user() const
+{
+ return m_user.loginName();
+}
+
+
+const QString Smb4KShare::group() const
+{
+ return m_group.name();
+}
+
+
+const QString &Smb4KShare::filesystem() const
+{
+ return m_filesystem;
+}
+
+
+const QString &Smb4KShare::cifsLogin() const
+{
+ return m_cifs_login;
+}
+
+
+bool Smb4KShare::isForeign() const
+{
+ return m_foreign_mount;
+}
+
+
+void Smb4KShare::setForeign( bool foreign )
+{
+ m_foreign_mount = foreign;
+}
+
+
+bool Smb4KShare::isBroken() const
+{
+ return m_broken;
+}
+
+
+void Smb4KShare::setBroken( bool broken )
+{
+ m_broken = broken;
+}
+
+
+void Smb4KShare::setTotalDiskSpace( double total )
+{
+ m_total = total;
+}
+
+
+void Smb4KShare::setFreeDiskSpace( double free )
+{
+ m_free = free;
+}
+
+
+double Smb4KShare::totalDiskSpace() const
+{
+ return m_total;
+}
+
+
+double Smb4KShare::freeDiskSpace() const
+{
+ return m_free;
+}
+
+
+double Smb4KShare::percentage() const
+{
+ return (m_total - m_free) / m_total * 100;
+}
+
+
+bool Smb4KShare::equals( const Smb4KShare &share )
+{
+ bool equal = false;
+
+ if ( QString::compare( m_name, share.name() ) == 0 &&
+ QString::compare( m_path, share.path() ) == 0 &&
+ QString::compare( m_filesystem, share.filesystem() ) == 0 &&
+ QString::compare( m_cifs_login, share.cifsLogin() ) == 0 &&
+ (int)m_user.uid() == share.uid() &&
+ (int)m_group.gid() == share.gid() &&
+ m_broken == share.isBroken() &&
+ m_foreign_mount == share.isForeign() &&
+ m_total == share.totalDiskSpace() &&
+ m_free == share.freeDiskSpace() )
+ {
+ equal = true;
+ }
+
+ return equal;
+}
diff --git a/smb4k/core/smb4kshare.h b/smb4k/core/smb4kshare.h
new file mode 100644
index 0000000..40c8c47
--- /dev/null
+++ b/smb4k/core/smb4kshare.h
@@ -0,0 +1,291 @@
+/***************************************************************************
+ smb4kshare - This is a container that holds information about
+ a mounted remote share.
+ -------------------
+ begin : Do M� 4 2004
+ copyright : (C) 2004 by Franck Babin
+ (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARE_H
+#define SMB4KSHARE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qstring.h>
+#include <qcstring.h>
+
+// KDE includes
+#include <kuser.h>
+
+
+/**
+ * This class is a container that holds information about a remote share
+ * that was mounted on the system. It belongs to the core classes of
+ * Smb4K.
+ *
+ * @author Franck Babin,
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KShare
+{
+ public:
+ /**
+ * The default constructor.
+ *
+ * @param name The name of the share: //HOST/SHARE or //USER\@HOST/SHARE (FreeBSD).
+ *
+ * @param path The path where the share is mounted to.
+ *
+ * @param filesystem The filesystem that was used. If you use this constructor it should be "smbfs".
+ *
+ * @param uid The UID of the user.
+ *
+ * @param gid The GID of the user.
+ *
+ * @param broken Determines whether the share is broken. "Broken" means that the share is unaccessible.
+ */
+ Smb4KShare( const QString &name, const QString &path, const QString &filesystem, const int uid = 0, const int gid = 0, bool broken = false );
+
+ /**
+ * The constructor for CIFS shares. It does not take the UID and GID, but the
+ * user name with which the login was done.
+ *
+ * @param name The name of the share: //HOST/SHARE or //USER@HOST/SHARE (FreeBSD).
+ *
+ * @param path The path where the share is mounted to.
+ *
+ * @param filesystem The filesystem that was used. If you use this constructor it should be "cifs".
+ *
+ * @param username The the user name that had to be used for authentication. It can be different from the local user name.
+ *
+ * @param foreign Determines whether the share was mounted by another user (i.e. is a foreign share).
+ *
+ * @param broken Determines whether the share is broken. "Broken" means that the share is unaccessible.
+ */
+ Smb4KShare( const QString &name, const QString &path, const QString &filesystem, const QString &username, bool foreign = false, bool broken = false );
+
+ /**
+ * Empty constructor.
+ */
+ Smb4KShare() {}
+
+ /**
+ * Copy constructor.
+ *
+ * @param share The share that is to be copied.
+ */
+ Smb4KShare( const Smb4KShare &share );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KShare();
+
+ /**
+ * Returns the name of the share as it has been gathered by the mounter.
+ *
+ * @returns The name of the share.
+ */
+ const QString &name() const;
+
+ /**
+ * Returns the mount point aka path of the share as it has been gathered
+ * by the mounter. This is a C-type string.
+ *
+ * @returns The path of the share.
+ */
+ const QCString &path() const;
+
+ /**
+ * This function returns the canonical path of the share. In contrast to
+ * Smb4KShare::path(), it will return the absolute path without symlinks. However,
+ * should the share be broken (i.e. Smb4KShare::isBroken() returns TRUE),
+ * only Smb4KShare::path() is returned.
+ *
+ * @returns Returns the canonical path of the share.
+ */
+ const QCString canonicalPath() const;
+
+ /**
+ * Returns the UID of the mounted share.
+ */
+ int uid() const;
+
+ /**
+ * Set the UID of the mounted share.
+ *
+ * @param uid The UID of the share
+ */
+ void setUID( int uid );
+
+ /**
+ * Returns the GID of the mounted share.
+ */
+ int gid() const;
+
+ /**
+ * Set the GID of the mounted share.
+ *
+ * @param gid The GID of the share
+ */
+ void setGID( int gid );
+
+ /**
+ * Returns the name of the user of the share.
+ */
+ const QString user() const;
+
+ /**
+ * Returns the name of the group of the share.
+ */
+ const QString group() const;
+
+ /**
+ * Returns the file system of the share.
+ */
+ const QString &filesystem() const;
+
+ /**
+ * Returns the CIFS login (user name).
+ */
+ const QString &cifsLogin() const;
+
+ /**
+ * Is TRUE if the share is/seems to be mounted by another
+ * user.
+ *
+ * @returns TRUE if another user mounted the share and FALSE otherwise.
+ */
+ bool isForeign() const;
+
+ /**
+ * This function sets the share to be foreign.
+ *
+ * @param foreign TRUE if share is foreign and FALSE otherwise.
+ */
+ void setForeign( bool foreign );
+
+ /**
+ * Returns TRUE if the share is broken and FALSE otherwise.
+ */
+ bool isBroken() const;
+
+ /**
+ * Sets the share to be broken.
+ *
+ * @param broken TRUE if the share is broken and FALSE otherwise.
+ */
+ void setBroken( bool broken );
+
+ /**
+ * This function sets the value of the total disk usage. The value has to
+ * be provided in kilobytes. If the disk usage could not be determined,
+ * total has to be set to -1.
+ *
+ * @param total The total disk usage in kB.
+ */
+ void setTotalDiskSpace( double total );
+
+ /**
+ * This function sets the value of the free space on the share. The value
+ * has to be provided in kilobytes. If the free space could not be determined,
+ * free has to be set to -1.
+ *
+ * @param free The free disk space in kB.
+ */
+ void setFreeDiskSpace( double free );
+
+ /**
+ * This function returns the total disk space of the share.
+ *
+ * @returns The total disk space in kB.
+ */
+ double totalDiskSpace() const;
+
+ /**
+ * This function returns the free disk space available on the share in kB.
+ *
+ * @returns the free disk space in kB.
+ */
+ double freeDiskSpace() const;
+
+ /**
+ * This function returns the percentage of used disk space on the
+ * share.
+ *
+ * @returns the percentage of disk space used on the share.
+ */
+ double percentage() const;
+
+ /**
+ * Compare another Smb4KShare object with this one and return TRUE if both
+ * carry the same data.
+ *
+ * @param share The Smb4KShare object that is compared to this one
+ *
+ * @returns TRUE if the values match.
+ */
+ bool equals( const Smb4KShare &share );
+
+
+ private:
+ /**
+ * The name of the share.
+ */
+ QString m_name;
+
+ /**
+ * The mount point / path of the share
+ */
+ QCString m_path;
+
+ /**
+ * The filesystem string
+ */
+ QString m_filesystem;
+
+ /**
+ * The user ID of the share.
+ */
+ KUser m_user;
+
+ /**
+ * The group ID of the share.
+ */
+ KUserGroup m_group;
+
+ /**
+ * The CIFS login name
+ */
+ QString m_cifs_login;
+ bool m_foreign_mount;
+ bool m_broken;
+ double m_total;
+ double m_free;
+};
+
+#endif
diff --git a/smb4k/core/smb4ksynchronizationinfo.cpp b/smb4k/core/smb4ksynchronizationinfo.cpp
new file mode 100644
index 0000000..072014f
--- /dev/null
+++ b/smb4k/core/smb4ksynchronizationinfo.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ smb4ksynchronizationinfo - This is a container that holds
+ information about progress of the synchronization
+ -------------------
+ begin : So Mai 20 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// application specific includes
+#include "smb4ksynchronizationinfo.h"
+
+
+Smb4KSynchronizationInfo::Smb4KSynchronizationInfo() : m_text( QString::null ),
+m_individual_progress( -1 ), m_total_progress( -1 ), m_total_files( -1 ),
+m_processed_files( -1 ), m_rate( QString::null )
+{
+}
+
+
+Smb4KSynchronizationInfo::~Smb4KSynchronizationInfo()
+{
+}
+
+
+void Smb4KSynchronizationInfo::setText( const QString &text )
+{
+ m_text = text;
+}
+
+
+void Smb4KSynchronizationInfo::setIndividualProgress( int percent )
+{
+ m_individual_progress = percent;
+}
+
+
+void Smb4KSynchronizationInfo::setTotalProgress( int percent )
+{
+ m_total_progress = percent;
+}
+
+
+void Smb4KSynchronizationInfo::setTotalFileNumber( int total )
+{
+ m_total_files = total;
+}
+
+
+void Smb4KSynchronizationInfo::setProcessedFileNumber( int processed )
+{
+ m_processed_files = processed;
+}
+
+
+void Smb4KSynchronizationInfo::setTransferRate( const QString &rate )
+{
+ m_rate = rate;
+}
diff --git a/smb4k/core/smb4ksynchronizationinfo.h b/smb4k/core/smb4ksynchronizationinfo.h
new file mode 100644
index 0000000..f254dd1
--- /dev/null
+++ b/smb4k/core/smb4ksynchronizationinfo.h
@@ -0,0 +1,176 @@
+/***************************************************************************
+ smb4ksynchronizationinfo - This is a container that holds
+ information about progress of the synchronization
+ -------------------
+ begin : So Mai 20 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSYNCHRONIZATIONINFO_H
+#define SMB4KSYNCHRONIZATIONINFO_H
+
+// Qt includes
+#include <qstring.h>
+
+class Smb4KSynchronizationInfo
+{
+ public:
+ /**
+ * The constructor. It takes no arguments and you should use the
+ * setXYZ() functions to set the necessary values.
+ */
+ Smb4KSynchronizationInfo();
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSynchronizationInfo();
+
+ /**
+ * Set the text that's provided in rsync's output. This may either be a
+ * file name or some information about the progress
+ *
+ * @param text The text
+ */
+ void setText( const QString &text );
+
+ /**
+ * Return the name of the file that is currently processed. This may
+ * be empty if no information about the file name is available.
+ *
+ * @returns the name of the file that is currently processed or an empty
+ * string
+ */
+ const QString &text () const { return m_text; }
+
+ /**
+ * Set the progress of the file that's currently processed.
+ *
+ * @param percent The progress in percent
+ */
+ void setIndividualProgress( int percent );
+
+ /**
+ * Return the progress of the current file transfer. If no
+ * information is available, -1 is returned.
+ *
+ * @returns the progress of the current file transfer or -1.
+ */
+ const int individualProgress() const { return m_individual_progress; }
+
+ /**
+ * Set the total progress of synchronization process.
+ *
+ * @param percent The progress in percent
+ */
+ void setTotalProgress( int percent );
+
+ /**
+ * Return the total progress of synchronization process. If no
+ * information is available, -1 is returned.
+ *
+ * @returns the total progress of the synchronization or -1.
+ */
+ const int totalProgress() const { return m_total_progress; }
+
+ /**
+ * Set the total number of files that have been considered for the
+ * synchronization.
+ *
+ * @param total The total number of files
+ */
+ void setTotalFileNumber( int total );
+
+ /**
+ * Return the total number of files that were considered for synchronization.
+ * If no information is available, -1 is returned.
+ *
+ * @returns the total number of files or -1.
+ */
+ const int totalFileNumber() const { return m_total_files; }
+
+ /**
+ * Set the number of files that have already been processed during the
+ * synchronization.
+ *
+ * @param processed The number of files that have been processed
+ */
+ void setProcessedFileNumber( int processed );
+
+ /**
+ * Return the number of files that have already been processed during the
+ * synchronization. If no information is available, -1 is returned.
+ *
+ * @returns the number of processed files or -1.
+ */
+ const int processedFileNumber() const { return m_processed_files; }
+
+ /**
+ * Set the transfer rate. This should be a string that already contains
+ * all information, i.e. the string should look like this: 100 kB/s.
+ *
+ * @param rate The rate string (e.g. 100 kB/s)
+ */
+ void setTransferRate( const QString &rate );
+
+ /**
+ * Return the transfer rate. This is a string that already contains all
+ * information, so that you can just put it into your widget without any
+ * modification. It may also be empty if no information about the rate is
+ * available.
+ *
+ * @returns The rate or an empty string.
+ */
+ const QString &transferRate() const { return m_rate; }
+
+ private:
+ /**
+ * The text
+ */
+ QString m_text;
+
+ /**
+ * The individual progress
+ */
+ int m_individual_progress;
+
+ /**
+ * The total progress
+ */
+ int m_total_progress;
+
+ /**
+ * The total file number
+ */
+ int m_total_files;
+
+ /**
+ * The number of processed files
+ */
+ int m_processed_files;
+
+ /**
+ * The rate string
+ */
+ QString m_rate;
+};
+
+#endif
diff --git a/smb4k/core/smb4ksynchronizer.cpp b/smb4k/core/smb4ksynchronizer.cpp
new file mode 100644
index 0000000..21ac788
--- /dev/null
+++ b/smb4k/core/smb4ksynchronizer.cpp
@@ -0,0 +1,503 @@
+/***************************************************************************
+ smb4ksynchronizer - This is the synchronizer of Smb4K.
+ -------------------
+ begin : Mo Jul 4 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qdir.h>
+#include <qlabel.h>
+#include <qregexp.h>
+
+// KDE includes
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kprogress.h>
+#include <kurlrequester.h>
+#include <kguiitem.h>
+#include <kapplication.h>
+
+// application specific includes
+#include "smb4ksynchronizer.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4kshare.h"
+#include "smb4ksynchronizationinfo.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+bool cancel = false;
+
+
+Smb4KSynchronizer::Smb4KSynchronizer( QObject *parent, const char *name )
+: QObject( parent, name )
+{
+ m_proc = new KProcess( this, "SynchronizerProcess" );
+
+ m_proc->setUseShell( true );
+
+ m_working = false;
+
+ connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
+
+ connect( m_proc, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( slotProcessExited( KProcess * ) ) );
+
+ connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
+
+ connect( kapp, SIGNAL( shutDown() ),
+ this, SLOT( slotShutdown() ) );
+}
+
+
+Smb4KSynchronizer::~Smb4KSynchronizer()
+{
+}
+
+
+/****************************************************************************
+ Synchronizes a share with a local copy or vice versa.
+****************************************************************************/
+
+void Smb4KSynchronizer::synchronize( const QString &source, const QString &destination )
+{
+ if ( Smb4KSettings::rsync().isEmpty() )
+ {
+ Smb4KError::error( ERROR_COMMAND_NOT_FOUND, "rsync" );
+ return;
+ }
+
+ // FIXME: Do not stop here but buffer the requests and
+ // process them if the previous process finished.
+ if ( isRunning() )
+ {
+ return;
+ }
+
+ m_working = true;
+ emit state( SYNCHRONIZER_START );
+ emit start();
+
+ // We will only define the stuff we urgently need
+ // here. The options that actually influence rsync's
+ // behavior will be retrieved by readRsyncOptions().
+ QString command = "rsync --progress ";
+
+ command.append( readRsyncOptions() );
+ command.append( " " );
+ command.append( KProcess::quote( source ) );
+ command.append( " " );
+ command.append( KProcess::quote( destination ) );
+
+ *m_proc << command;
+
+ // Use KProcess::OwnGroup instead of KProcess::NotifyOnExit here, because
+ // this garantees that the process is indeed killed when using abort().
+ // See KProcess docs for further information.
+ m_proc->start( KProcess::OwnGroup, KProcess::AllOutput );
+}
+
+
+/****************************************************************************
+ Reads the options that should be used with rsync
+****************************************************************************/
+
+const QString Smb4KSynchronizer::readRsyncOptions()
+{
+ QString options;
+
+ if ( Smb4KSettings::archiveMode() )
+ {
+ options.append( " --archive" );
+ }
+ else
+ {
+ options.append( Smb4KSettings::recurseIntoDirectories() ?
+ " --recursive" :
+ "" );
+
+ options.append( Smb4KSettings::preserveSymlinks() ?
+ " --links" :
+ "" );
+
+ options.append( Smb4KSettings::preservePermissions() ?
+ " --perms" :
+ "" );
+
+ options.append( Smb4KSettings::preserveTimes() ?
+ " --times" :
+ "" );
+
+ options.append( Smb4KSettings::preserveGroup() ?
+ " --group" :
+ "" );
+
+ options.append( Smb4KSettings::preserveOwner() ?
+ " --owner" :
+ "" );
+
+ options.append( Smb4KSettings::preserveDevicesAndSpecials() ?
+ " --devices --specials" : // alias: -D
+ "" );
+ }
+
+ options.append( Smb4KSettings::relativePathNames() ?
+ " --relative" :
+ "" );
+
+ options.append( Smb4KSettings::omitDirectoryTimes() ?
+ " --omit-dir-times" :
+ "" );
+
+ options.append( Smb4KSettings::noImpliedDirectories() ?
+ " --no-implied-dirs" :
+ "" );
+
+ options.append( Smb4KSettings::updateTarget() ?
+ " --update" :
+ "" );
+
+ options.append( Smb4KSettings::updateInPlace() ?
+ " --inplace" :
+ "" );
+
+ options.append( Smb4KSettings::transferDirectories() ?
+ " --dirs" :
+ "" );
+
+ options.append( Smb4KSettings::transformSymlinks() ?
+ " --copy-links" :
+ "" );
+
+ options.append( Smb4KSettings::transformUnsafeSymlinks() ?
+ " --copy-unsafe-links" :
+ "" );
+
+ options.append( Smb4KSettings::ignoreUnsafeSymlinks() ?
+ " --safe-links" :
+ "" );
+
+ options.append( Smb4KSettings::preserveHardLinks() ?
+ " --hard-links" :
+ "" );
+
+ options.append( Smb4KSettings::keepDirectorySymlinks() ?
+ " --keep-dirlinks" :
+ "" );
+
+ options.append( Smb4KSettings::deleteExtraneous() ?
+ " --delete" :
+ "" );
+
+ options.append( Smb4KSettings::removeSourceFiles() ?
+ " --remove-source-files" :
+ "" );
+
+ options.append( Smb4KSettings::deleteBefore() ?
+ " --delete-before" :
+ "" );
+
+ options.append( Smb4KSettings::deleteDuring() ?
+ " --delete-during" :
+ "" );
+
+ options.append( Smb4KSettings::deleteAfter() ?
+ " --delete-after" :
+ "" );
+
+ options.append( Smb4KSettings::deleteExcluded() ?
+ " --delete-excluded" :
+ "" );
+
+ options.append( Smb4KSettings::ignoreErrors() ?
+ " --ignore-errors" :
+ "" );
+
+ options.append( Smb4KSettings::forceDirectoryDeletion() ?
+ " --force" :
+ "" );
+
+ options.append( Smb4KSettings::copyFilesWhole() ?
+ " --whole-file" :
+ "" );
+
+ options.append( Smb4KSettings::efficientSparseFileHandling() ?
+ " --sparse" :
+ "" );
+
+ options.append( Smb4KSettings::oneFileSystem() ?
+ " --one-file-system" :
+ "" );
+
+ options.append( Smb4KSettings::updateExisting() ?
+ " --existing" :
+ "" );
+
+ options.append( Smb4KSettings::ignoreExisting() ?
+ " --ignore-existing" :
+ "" );
+
+ options.append( Smb4KSettings::delayUpdates() ?
+ " --delay-updates" :
+ "" );
+
+ options.append( Smb4KSettings::compressData() ?
+ " --compress" :
+ "" );
+
+ if ( Smb4KSettings::makeBackups() )
+ {
+ options.append( " --backup" );
+
+ options.append( Smb4KSettings::useBackupDirectory() ?
+ " --backup-dir="+Smb4KSettings::backupDirectory() :
+ "" );
+
+ options.append( Smb4KSettings::useBackupSuffix() ?
+ " --suffix="+Smb4KSettings::backupSuffix() :
+ "" );
+ }
+
+ options.append( Smb4KSettings::useMaximumDelete() ?
+ " --max-delete="+QString( "%1" ).arg( Smb4KSettings::maximumDeleteValue() ) :
+ "" );
+
+ options.append( Smb4KSettings::useChecksum() ?
+ " --checksum" :
+ "" );
+
+ options.append( Smb4KSettings::useBlockSize() ?
+ " --block-size="+QString( "%1" ).arg( Smb4KSettings::blockSize() ) :
+ "" );
+
+ options.append( Smb4KSettings::useChecksumSeed() ?
+ " --checksum-seed="+QString( "%1" ).arg( Smb4KSettings::checksumSeed() ) :
+ "" );
+
+ if ( !Smb4KSettings::customFilteringRules().isEmpty() )
+ {
+ options.append( " "+Smb4KSettings::customFilteringRules() );
+ }
+
+ options.append( Smb4KSettings::useMinimalTransferSize() ?
+ " --min-size="+QString( "%1" ).arg( Smb4KSettings::minimalTransferSize() )+"K" :
+ "" );
+
+ options.append( Smb4KSettings::useMaximalTransferSize() ?
+ " --max-size="+QString( "%1" ).arg( Smb4KSettings::maximalTransferSize() )+"K" :
+ "" );
+
+ if ( Smb4KSettings::keepPartial() )
+ {
+ options.append( " --partial" );
+
+ options.append( Smb4KSettings::usePartialDirectory() ?
+ " --partial-dir="+Smb4KSettings::partialDirectory() :
+ "" );
+ }
+
+ options.append( Smb4KSettings::useCVSExclude() ?
+ " --cvs-exclude" :
+ "" );
+
+ options.append( Smb4KSettings::useFFilterRule() ?
+ " -F" :
+ "" );
+
+ options.append( Smb4KSettings::useFFFilterRule() ?
+ " -F -F" :
+ "" );
+
+ options.append( Smb4KSettings::useExcludePattern() ?
+ " --exclude="+Smb4KSettings::excludePattern() :
+ "" );
+
+ options.append( Smb4KSettings::useExcludeFrom() ?
+ " --exclude-from="+Smb4KSettings::excludeFrom() :
+ "" );
+
+ options.append( Smb4KSettings::useIncludePattern() ?
+ " --include="+Smb4KSettings::includePattern() :
+ "" );
+
+ options.append( Smb4KSettings::useIncludeFrom() ?
+ " --include-from="+Smb4KSettings::includeFrom() :
+ "" );
+
+ return options;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSynchronizer::abort()
+{
+ cancel = true;
+
+ if ( m_proc->isRunning() )
+ {
+ m_proc->kill();
+ }
+}
+
+
+void Smb4KSynchronizer::slotProcessExited( KProcess * )
+{
+ m_proc->clearArguments();
+
+ m_working = false;
+
+ emit finished();
+ emit state( SYNCHRONIZER_STOP );
+}
+
+
+void Smb4KSynchronizer::slotReceivedStdout( KProcess *, char *buf, int len )
+{
+ m_buffer = QString::fromLocal8Bit( buf, len );
+
+ Smb4KSynchronizationInfo sync_info;
+
+ QString partial, total, files, rate;
+
+ if ( m_buffer[0].isSpace() && m_buffer.contains( "/s ", true ) > 0 )
+ {
+ partial = m_buffer.section( "%", 0, 0 ).section( " ", -1, -1 ).stripWhiteSpace();
+
+ if ( !partial.isEmpty() )
+ {
+ sync_info.setIndividualProgress( partial.toInt() );
+ }
+
+ if ( m_buffer.contains( "to-check=" ) > 0 )
+ {
+ // Newer versions of rsync:
+ QString tmp = m_buffer.section( "to-check=", 1, 1 ).section( ")", 0, 0 ).stripWhiteSpace();
+
+ if ( !tmp.isEmpty() )
+ {
+ double tmp_total = tmp.section( "/", 1, 1 ).stripWhiteSpace().toInt();
+ double tmp_done = tmp.section( "/", 0, 0 ).stripWhiteSpace().toInt();
+ double tmp_percent = ((tmp_total-tmp_done)/tmp_total)*100;
+
+ total = QString( "%1" ).arg( tmp_percent ).section( ".", 0, 0 ).stripWhiteSpace();
+ }
+ }
+ else
+ {
+ // Older versions of rsync:
+ total = m_buffer.section( " (", 1, 1 ).section( ",", 1, 1 ).section( "%", 0, 0 ).section( ".", 0, 0 ).stripWhiteSpace();
+ }
+
+ if ( !total.isEmpty() )
+ {
+ sync_info.setTotalProgress( total.toInt() );
+ }
+
+ if ( m_buffer.contains( "xfer#" ) > 0 )
+ {
+ // Newer versions of rsync:
+ files = m_buffer.section( "xfer#", 1, 1 ).section( ",", 0, 0 ).stripWhiteSpace();
+ }
+ else
+ {
+ // Older versions of rsync:
+ files = m_buffer.section( " (", 1, 1 ).section( ",", 0, 0 ).stripWhiteSpace();
+ }
+
+ if ( !files.isEmpty() )
+ {
+ sync_info.setProcessedFileNumber( files.toInt() );
+ sync_info.setTotalFileNumber( m_total_files.toInt() );
+ }
+
+ rate = m_buffer.section( "/s ", 0, 0 ).section( " ", -1, -1 ).stripWhiteSpace();
+
+ if ( !rate.isEmpty() )
+ {
+ rate.append( "/s" );
+ rate.insert( rate.length() - 4, " " );
+
+ sync_info.setTransferRate( rate );
+ }
+
+ m_buffer = QString::null;
+ }
+ else if ( !m_buffer[0].isSpace() && m_buffer.endsWith( "\n" ) && m_buffer.contains( "/s ", true ) == 0 )
+ {
+ sync_info.setText( m_buffer.stripWhiteSpace() );
+
+ if ( m_buffer.contains( "files to consider" ) != 0 )
+ {
+ m_total_files = m_buffer.section( " files to consider", 0, 0 ).section( " ", -1, -1 ).stripWhiteSpace();
+
+ sync_info.setTotalFileNumber( m_total_files.toInt() );
+ }
+
+ m_buffer = QString::null;
+ }
+
+ emit progress( sync_info );
+}
+
+
+
+void Smb4KSynchronizer::slotReceivedStderr( KProcess *, char *buf, int len )
+{
+ QString error_message = QString::fromLocal8Bit( buf, len );
+
+ // At least under Debian unstable (20051216), rsync emits an error
+ // when you kill the process (using SIGTERM). Pressing the cancel
+ // button will exactly do this. Thus, we need to exclude this occasion
+ // from here.
+ if ( !cancel && error_message.contains( "rsync error:", true ) != 0 )
+ {
+ // Cancel the whole synchronization in case an error occurred.
+ // If we don't do it, the user might be flooded with error messages
+ // especially if you try to synchronize a local copy with a remote
+ // share that is mounted read-only.
+ abort();
+ Smb4KError::error( ERROR_SYNCHRONIZING, QString::null, error_message );
+ }
+ else
+ {
+ cancel = false;
+ }
+}
+
+
+void Smb4KSynchronizer::slotShutdown()
+{
+ abort();
+}
+
+#include "smb4ksynchronizer.moc"
diff --git a/smb4k/core/smb4ksynchronizer.h b/smb4k/core/smb4ksynchronizer.h
new file mode 100644
index 0000000..ecc279f
--- /dev/null
+++ b/smb4k/core/smb4ksynchronizer.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+ smb4ksynchronizer - This is the synchronizer of Smb4K.
+ -------------------
+ begin : Mo Jul 4 2005
+ copyright : (C) 2005-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSYNCHRONIZER_H
+#define SMB4KSYNCHRONIZER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kprocess.h>
+#include <kdialogbase.h>
+
+// Qt includes
+#include <qobject.h>
+#include <qstring.h>
+
+// forward declarations
+class Smb4KShare;
+class Smb4KSynchronizationInfo;
+
+
+/**
+ * This is a core class of Smb4K. It manages the synchronization of remote
+ * shares with a local copy (and vice versa).
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+
+class Smb4KSynchronizer : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor of the synchronizer.
+ *
+ * @param parent The parent of this object
+ *
+ * @param name The name of this object
+ */
+ Smb4KSynchronizer( QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSynchronizer();
+
+ /**
+ * This function synchronizes a destination with the source.
+ *
+ * @param source The source location
+ *
+ * @param destination The destination
+ */
+ void synchronize( const QString &source, const QString &destination );
+
+ /**
+ * This function reports if the synchronizer is running or not.
+ *
+ * @returns TRUE if the synchronizer is running an FALSE otherwise.
+ */
+ bool isRunning() { return m_working; }
+
+ public slots:
+ /**
+ * This function aborts the synchronization, i.e. the sync process is killed.
+ */
+ void abort();
+
+ signals:
+ /**
+ * This signal emits the run state.
+ *
+ * @param state The so-called run state. There are several defined
+ * in the smb4kdefs.h header file.
+ */
+ void state( int state );
+
+ /**
+ * This signal is emitted just before the synchronization process is
+ * started.
+ */
+ void start();
+
+ /**
+ * This signal is emitted when the synchronization process finished.
+ */
+ void finished();
+
+ /**
+ * Emit information about the progress of current synchronization process.
+ * The information that's available may only be partial, i.e. that maybe
+ * the file name or the rate or somthing else is missing. That's because
+ * of the way the output of rsync is processed.
+ *
+ * @param info Information about progress of the synchronization
+ * process
+ */
+ void progress( const Smb4KSynchronizationInfo &info );
+
+ protected slots:
+ /**
+ * Reimplemented from KProcess.
+ *
+ * @param proc The process that exited
+ */
+ void slotProcessExited( KProcess *proc );
+
+ /**
+ * Reimplemented from KProcess.
+ *
+ * @param proc The process from which output was received on stdout
+ *
+ * @param buf The buffer that contains the output
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStdout( KProcess *proc, char *buf, int len );
+
+ /**
+ * Reimplemented from KProcess.
+ *
+ * @param proc The process from which output was received on stderr
+ *
+ * @param buf The buffer that contains the output
+ *
+ * @param len The length of the buffer
+ */
+ void slotReceivedStderr( KProcess *proc, char *buf, int len );
+
+ /**
+ * This slot is connected to KApplication::shutDown() signal.
+ * It aborts the running KProcess if necessary.
+ */
+ void slotShutdown();
+
+ private:
+ /**
+ * The process object for this class.
+ */
+ KProcess *m_proc;
+
+ /**
+ * This booian is TRUE if the synchronizer is working and FALSE otherwise.
+ */
+ bool m_working;
+
+ /**
+ * This function reads the options, that the user chose to use with rsync.
+ *
+ * @returns an option string
+ */
+ const QString readRsyncOptions();
+
+ /**
+ * The buffer for the output.
+ *
+ * NOTE: The buffer is not to contain error messages, that are received
+ * via slotReceivedStderr()!
+ */
+ QString m_buffer;
+
+ /**
+ * Total number of files to transfer
+ */
+ QString m_total_files;
+};
+
+#endif
diff --git a/smb4k/dialogs/Makefile.am b/smb4k/dialogs/Makefile.am
new file mode 100644
index 0000000..28a1b47
--- /dev/null
+++ b/smb4k/dialogs/Makefile.am
@@ -0,0 +1,11 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+lib_LTLIBRARIES = libsmb4kdialogs.la
+libsmb4kdialogs_la_LDFLAGS = -avoid-version -no-undefined $(all_libraries)
+libsmb4kdialogs_la_SOURCES = smb4kbookmarkeditor.cpp \
+ smb4kcustomoptionsdialog.cpp smb4kmountdialog.cpp smb4kpreviewdialog.cpp smb4kprintdialog.cpp \
+ smb4ksynchronizationdialog.cpp
+libsmb4kdialogs_la_LIBADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_QT)
+noinst_HEADERS = smb4kbookmarkeditor.h smb4kmountdialog.h smb4kpreviewdialog.h \
+ smb4kprintdialog.h smb4ksynchronizationdialog.h
diff --git a/smb4k/dialogs/smb4kbookmarkeditor.cpp b/smb4k/dialogs/smb4kbookmarkeditor.cpp
new file mode 100644
index 0000000..b348e80
--- /dev/null
+++ b/smb4k/dialogs/smb4kbookmarkeditor.cpp
@@ -0,0 +1,258 @@
+/***************************************************************************
+ smb4kbookmarkeditor - This is the bookmark editor of Smb4K.
+ -------------------
+ begin : Di Okt 5 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qvaluelist.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kaction.h>
+#include <kactionclasses.h>
+#include <kaccel.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kpopupmenu.h>
+
+// application specific includes
+#include "smb4kbookmarkeditor.h"
+#include "../core/smb4kbookmark.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4kglobal.h"
+#include "../core/smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KBookmarkEditor::Smb4KBookmarkEditor( QWidget *parent, const char *name )
+: KDialogBase( Plain, i18n( "Bookmark Editor" ), Ok|Cancel, Ok, parent, name, true, true )
+{
+ setWFlags( Qt::WDestructiveClose );
+
+ QFrame *frame = plainPage();
+ QGridLayout *layout = new QGridLayout( frame );
+ layout->setSpacing( 5 );
+
+ m_view = new KListView( frame );
+ m_view->addColumn( i18n( "Bookmark" ), Bookmark );
+ m_view->addColumn( i18n( "Workgroup" ), Workgroup );
+ m_view->addColumn( i18n( "IP Address" ), IPAddress );
+ m_view->addColumn( i18n( "Label" ), Label );
+// m_view->setAllColumnsShowFocus( true );
+ m_view->setItemsRenameable( true );
+ m_view->setRenameable( Bookmark, false );
+ m_view->setRenameable( Workgroup, false );
+ m_view->setRenameable( IPAddress, true );
+ m_view->setRenameable( Label, true );
+
+ m_collection = new KActionCollection( this, "BookmarkEditor_ActionCollection", KGlobal::instance() );
+
+ (void) new KAction( i18n( "&Remove" ), "remove", Key_Delete, this, SLOT( slotRemoveClicked() ), m_collection, "remove_bookmark" );
+
+ (void) new KAction( i18n( "Remove &All" ), "editdelete", CTRL+Key_X, this, SLOT( slotDeleteAllClicked() ), m_collection, "remove_all_bookmarks" );
+
+ slotLoadBookmarks();
+
+ layout->addWidget( m_view, 0, 0, 0 );
+
+ setInitialSize( configDialogSize( *(Smb4KSettings::self()->config()), "BookmarkEditor" ) );
+ setMinimumSize( (sizeHint().width() > 350 ? sizeHint().width() : 350), sizeHint().height() );
+
+ connect( m_view, SIGNAL( rightButtonPressed( QListViewItem *, const QPoint &, int ) ),
+ this, SLOT( slotRightButtonPressed( QListViewItem *, const QPoint &, int ) ) );
+
+ connect( m_view, SIGNAL( itemRenamed( QListViewItem * ) ),
+ this, SLOT( slotItemRenamed( QListViewItem * ) ) );
+
+ connect( this, SIGNAL( okClicked() ),
+ this, SLOT( slotOkClicked() ) );
+
+ connect( this, SIGNAL( cancelClicked() ),
+ this, SLOT( slotCancelClicked() ) );
+
+ connect( Smb4KCore::bookmarkHandler(), SIGNAL( bookmarksUpdated() ),
+ this, SLOT( slotLoadBookmarks() ) );
+}
+
+
+Smb4KBookmarkEditor::~Smb4KBookmarkEditor()
+{
+ uint index = 0;
+
+ while ( index < m_collection->count() )
+ {
+ delete m_collection->action( index++ );
+ }
+
+ m_collection->clear();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KBookmarkEditor::slotRightButtonPressed( QListViewItem *item, const QPoint &pos, int )
+{
+ if ( !item )
+ {
+ m_collection->action( "remove_bookmark" )->setEnabled( false );
+ }
+ else
+ {
+ m_collection->action( "remove_bookmark" )->setEnabled( true );
+ }
+
+ if ( m_view->childCount() == 0 )
+ {
+ m_collection->action( "remove_all_bookmarks" )->setEnabled( false );
+ }
+ else
+ {
+ m_collection->action( "remove_all_bookmarks" )->setEnabled( true );
+ }
+
+ KActionMenu *menu = static_cast<KActionMenu *>( child( "BookmarkEditorPopupMenu", "KActionMenu", true ) );
+
+ if ( !menu )
+ {
+ menu = new KActionMenu( this, "BookmarkEditorPopupMenu" );
+ menu->insert( m_collection->action( "remove_bookmark" ) );
+ menu->insert( m_collection->action( "remove_all_bookmarks" ) );
+ }
+
+ menu->popup( pos );
+}
+
+
+void Smb4KBookmarkEditor::slotRemoveClicked()
+{
+ if ( m_view->currentItem() )
+ {
+ delete m_view->currentItem();
+ }
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_view->columns(); col++ )
+ {
+ m_view->adjustColumn( col );
+ }
+}
+
+
+void Smb4KBookmarkEditor::slotDeleteAllClicked()
+{
+ m_view->clear();
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_view->columns(); col++ )
+ {
+ m_view->adjustColumn( col );
+ }
+}
+
+
+void Smb4KBookmarkEditor::slotOkClicked()
+{
+ KActionPtrList list = m_collection->actions( "BookmarkEditor" );
+
+ for ( KActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ delete *it;
+ }
+
+ QValueList<Smb4KBookmark *> bookmarks;
+
+ if ( m_view->childCount() != 0 )
+ {
+ QListViewItemIterator it( m_view );
+
+ while( it.current() )
+ {
+ bookmarks.append( new Smb4KBookmark(
+ it.current()->text( Bookmark ).section( "/", 2, 2 ).stripWhiteSpace(),
+ it.current()->text( Bookmark ).section( "/", 3, 3 ).stripWhiteSpace(),
+ it.current()->text( Workgroup ).stripWhiteSpace(),
+ it.current()->text( IPAddress ).stripWhiteSpace(),
+ "Disk",
+ it.current()->text( Label ).stripWhiteSpace() ) );
+ ++it;
+ }
+ }
+
+ Smb4KCore::bookmarkHandler()->writeBookmarkList( bookmarks );
+
+ saveDialogSize( *(Smb4KSettings::self()->config()), "BookmarkEditor" );
+}
+
+
+void Smb4KBookmarkEditor::slotCancelClicked()
+{
+ KActionPtrList list = m_collection->actions( "BookmarkEditor" );
+
+ for ( KActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ m_collection->kaccel()->remove( (*it)->name() );
+ m_collection->remove( *it );
+ }
+}
+
+
+void Smb4KBookmarkEditor::slotLoadBookmarks()
+{
+ m_view->clear();
+
+ QValueList<Smb4KBookmark *> bookmarks = Smb4KCore::bookmarkHandler()->getBookmarks();
+
+ for ( QValueList<Smb4KBookmark *>::ConstIterator it = bookmarks.begin(); it != bookmarks.end(); ++it )
+ {
+ KListViewItem *item = new KListViewItem( m_view );
+ item->setText( Bookmark, (*it)->bookmark() );
+ item->setText( Workgroup, (*it)->workgroup() );
+ item->setText( IPAddress, (*it)->ip() );
+ item->setText( Label, (*it)->label() );
+ item->setPixmap( Bookmark, SmallIcon( "folder" ) );
+ }
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_view->columns(); col++ )
+ {
+ m_view->adjustColumn( col );
+ }
+}
+
+
+void Smb4KBookmarkEditor::slotItemRenamed( QListViewItem * )
+{
+ // Adjust the columns:
+ for ( int col = 0; col < m_view->columns(); col++ )
+ {
+ m_view->adjustColumn( col );
+ }
+}
+
+#include "smb4kbookmarkeditor.moc"
diff --git a/smb4k/dialogs/smb4kbookmarkeditor.h b/smb4k/dialogs/smb4kbookmarkeditor.h
new file mode 100644
index 0000000..8184c0c
--- /dev/null
+++ b/smb4k/dialogs/smb4kbookmarkeditor.h
@@ -0,0 +1,137 @@
+/***************************************************************************
+ smb4kbookmarkeditor - description
+ -------------------
+ begin : Di Okt 5 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KBOOKMARKEDITOR_H
+#define SMB4KBOOKMARKEDITOR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kdialogbase.h>
+#include <klistview.h>
+#include <kactioncollection.h>
+
+/**
+ * This is the bookmark editor of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KBookmarkEditor : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent of this dialog.
+ *
+ * @param name The name of this dialog.
+ */
+ Smb4KBookmarkEditor( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KBookmarkEditor();
+
+ /**
+ * This function returns a pointer to the action collection of this class.
+ * You should use it to include the action into the action collection of the
+ * main action collection (e.g. KMainWindow::actionCollection()).
+ *
+ * The entries in this action collection are members of the group "BookmarkEditor".
+ *
+ * @returns a pointer to the action collection of this class
+ */
+ KActionCollection *action_collection() { return m_collection; }
+
+ protected slots:
+ /**
+ * This slot is activated whenever the right mouse button
+ * has been pressed.
+ *
+ * @param item The item over which the mouse pointer is (maybe NULL).
+ *
+ * @param pos The position where the mouse is.
+ *
+ * @param col The column of the list view item.
+ */
+ void slotRightButtonPressed ( QListViewItem *item, const QPoint &pos, int col );
+
+ /**
+ * This slot is activated whenever the remove button of the
+ * menu is clicked.
+ */
+ void slotRemoveClicked();
+
+ /**
+ * This slot is activated whenever the 'Remove All' button of
+ * the menu has been clicked.
+ */
+ void slotDeleteAllClicked();
+
+ /**
+ * This slot is activated if the OK button has been clicked.
+ */
+ void slotOkClicked();
+
+ /**
+ * This slot is activated if the Cancel button has been clicked.
+ */
+ void slotCancelClicked();
+
+ /**
+ * This slot is invoked, if the bookmark handler updated the bookmarks.
+ */
+ void slotLoadBookmarks();
+
+ /**
+ * This slot is invoked when an item was renamed. It will adjust the columns.
+ *
+ * @param item The item that was renamed.
+ */
+ void slotItemRenamed( QListViewItem *item );
+
+ private:
+ /**
+ * Enumeration for the columns in the list view.
+ */
+ enum Columns { Bookmark = 0, Workgroup = 1, IPAddress = 2, Label = 3 };
+ /**
+ * The listview.
+ */
+ KListView *m_view;
+
+ /**
+ * The action collection of this class.
+ */
+ KActionCollection *m_collection;
+};
+
+#endif
diff --git a/smb4k/dialogs/smb4kcustomoptionsdialog.cpp b/smb4k/dialogs/smb4kcustomoptionsdialog.cpp
new file mode 100644
index 0000000..6d8609b
--- /dev/null
+++ b/smb4k/dialogs/smb4kcustomoptionsdialog.cpp
@@ -0,0 +1,1027 @@
+/***************************************************************************
+ smb4kcustomoptionsdialog - With this dialog the user can define
+ custom Samba options for hosts or shares.
+ -------------------
+ begin : So Jun 25 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qframe.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kapplication.h>
+#include <klineedit.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kcustomoptionsdialog.h"
+#include "../core/smb4kglobal.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4ksambaoptionsinfo.h"
+#include "../core/smb4ksambaoptionshandler.h"
+#include "../core/smb4knetworkitems.h"
+#include "../core/smb4ksettings.h"
+
+using namespace Smb4KGlobal;
+
+
+// FIXME: Maybe introduce a private class here?
+static int default_port = -1;
+static QString default_protocol = QString::null;
+static bool default_kerberos = false;
+static QString default_uid = QString::null;
+static QString default_gid = QString::null;
+#ifndef __FreeBSD__
+static QString default_filesystem = QString::null;
+static bool default_readwrite = true;
+#endif
+
+static int port_value = -1;
+static QString protocol_value = QString::null;
+static bool kerberos_value = false;
+static QString uid_value = QString::null;
+static QString gid_value = QString::null;
+#ifndef __FreeBSD__
+static QString filesystem_value = QString::null;
+static bool readwrite_value = true;
+#endif
+
+static bool port_changed_ok = false;
+static bool protocol_changed_ok = false;
+static bool kerberos_changed_ok = false;
+static bool uid_changed_ok = false;
+static bool gid_changed_ok = false;
+#ifndef __FreeBSD__
+static bool filesystem_changed_ok = false;
+static bool readwrite_changed_ok = false;
+#endif
+
+static bool port_changed_default = false;
+static bool protocol_changed_default = false;
+static bool kerberos_changed_default = false;
+static bool uid_changed_default = false;
+static bool gid_changed_default = false;
+#ifndef __FreeBSD__
+static bool filesystem_changed_default = false;
+static bool readwrite_changed_default = false;
+#endif
+
+
+Smb4KCustomOptionsDialog::Smb4KCustomOptionsDialog( Smb4KHostItem *host, QWidget *parent, const char *name )
+: KDialogBase( Plain, i18n( "Custom Options" ), User1|Ok|Cancel, Ok, parent, name, true, true ), m_type( Host ), m_host_item( host ), m_share_item( NULL ), m_homes_user( QString::null )
+{
+ m_initialized = true;
+
+ setButtonGuiItem( User1, KStdGuiItem::defaults() );
+
+ setWFlags( Qt::WDestructiveClose );
+
+ setupDialog();
+}
+
+
+Smb4KCustomOptionsDialog::Smb4KCustomOptionsDialog( Smb4KShareItem *share, QWidget *parent, const char *name )
+: KDialogBase( Plain, i18n( "Custom Options" ), User1|Ok|Cancel, Ok, parent, name, true, true ), m_type( Share ), m_host_item( NULL ), m_share_item( share ), m_homes_user( QString::null )
+{
+ if ( QString::compare( share->name(), "homes" ) != 0 )
+ {
+ m_initialized = true;
+ }
+ else
+ {
+ m_homes_user = specifyUser( share->host(), kapp->mainWidget() ? kapp->mainWidget() : 0, "SpecifyUser" );
+ m_initialized = m_homes_user.isEmpty() ? false : true;
+ }
+
+ setButtonGuiItem( User1, KStdGuiItem::defaults() );
+
+ setWFlags( Qt::WDestructiveClose );
+
+ setupDialog();
+}
+
+
+Smb4KCustomOptionsDialog::~Smb4KCustomOptionsDialog()
+{
+}
+
+
+void Smb4KCustomOptionsDialog::setupDialog()
+{
+ // The Smb4KSambaOptionsInfo object:
+ Smb4KSambaOptionsInfo *info = NULL;
+
+ // We need this later to decide if the "Default"
+ // button needs to be enabled:
+ bool enable_default_button = false;
+
+ // These are the input widgets we need below:
+ m_port_input = NULL;
+ m_kerberos = NULL;
+ m_proto_input = NULL;
+ m_uid_input = NULL;
+ m_gid_input = NULL;
+#ifndef __FreeBSD__
+ m_fs_input = NULL;
+ m_rw_input = NULL;
+#endif
+
+ // Set-up the widget:
+ QFrame *frame = plainPage();
+
+ QGridLayout *grid = new QGridLayout( frame );
+ grid->setSpacing( 5 );
+ grid->setMargin( 0 );
+
+ // The following widgets are independent of the type of
+ // the network item:
+ QLabel *location_label = new QLabel( m_type == Host ? i18n( "Host:" ) : i18n( "Share:" ), frame );
+ KLineEdit *location = new KLineEdit( m_type == Host ? m_host_item->name() : "//"+m_share_item->host()+"/"+(QString::compare( m_share_item->name(), "homes" ) != 0 ? m_share_item->name() : m_homes_user), frame );
+ location->setReadOnly( true );
+
+ QLabel *port_label = new QLabel( i18n( "Port:" ), frame );
+ m_port_input = new KIntNumInput( -1, frame );
+ m_port_input->setMinimumWidth( 200 );
+ m_port_input->setMinValue( -1 );
+ m_port_input->setMaxValue( 65535 );
+
+ // The widgets will be put into the layout below.
+
+ // Here comes the item-dependent stuff:
+ switch ( m_type )
+ {
+ case Host:
+ {
+ QLabel *protocol_label = new QLabel( i18n( "Protocol:" ), frame );
+ m_proto_input = new KComboBox( false, frame );
+ m_proto_input->setMinimumWidth( 200 );
+ m_proto_input->insertItem( i18n( "auto" ), -1 );
+ m_proto_input->insertItem( "RPC", -1 );
+ m_proto_input->insertItem( "RAP", -1 );
+ m_proto_input->insertItem( "ADS", -1 );
+
+ m_kerberos = new QCheckBox( i18n( "Try to authenticate with Kerberos (Active Directory)" ), frame );
+
+ grid->addWidget( location_label, 0, 0, 0 );
+ grid->addWidget( location, 0, 1, 0 );
+ grid->addWidget( port_label, 1, 0, 0 );
+ grid->addWidget( m_port_input, 1, 1, 0 );
+ grid->addWidget( protocol_label, 2, 0, 0 );
+ grid->addWidget( m_proto_input, 2, 1, 0 );
+ grid->addMultiCellWidget( m_kerberos, 3, 3, 0, 1, 0 );
+
+ info = optionsHandler()->findItem( m_host_item->name() );
+
+ // Get the default values from the config file:
+ default_port = Smb4KSettings::remotePort();
+
+ default_kerberos = Smb4KSettings::useKerberos();
+
+ switch ( Smb4KSettings::protocolHint() )
+ {
+ case Smb4KSettings::EnumProtocolHint::Automatic:
+ {
+ // In this case the user leaves it to the net
+ // command to determine the right protocol.
+ default_protocol = "auto";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RPC:
+ {
+ default_protocol = "rpc";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::RAP:
+ {
+ default_protocol = "rap";
+
+ break;
+ }
+ case Smb4KSettings::EnumProtocolHint::ADS:
+ {
+ default_protocol = "ads";
+
+ break;
+ }
+ default:
+ {
+ default_protocol = QString::null;
+
+ break;
+ }
+ }
+
+ // Define the values that have to be put into the widgets:
+ port_value = (info && info->port() != -1) ?
+ info->port() :
+ default_port;
+
+ protocol_value = (info && !info->protocol().isEmpty()) ?
+ info->protocol() :
+ default_protocol;
+
+ kerberos_value = (info && info->kerberos() != default_kerberos) ?
+ info->kerberos() :
+ default_kerberos;
+
+ // Put the values in the widgets:
+ m_port_input->setValue( port_value );
+ m_proto_input->setCurrentText( (QString::compare( protocol_value, "auto" ) == 0 ? i18n( "auto" ) : protocol_value.upper()) );
+ m_kerberos->setChecked( kerberos_value );
+
+ // Does the 'Default' button need to be enabled?
+ if ( default_port != port_value ||
+ QString::compare( default_protocol, protocol_value ) != 0 ||
+ default_kerberos != kerberos_value )
+ {
+ enable_default_button = true;
+ }
+
+ // Connections:
+ connect( m_port_input, SIGNAL( valueChanged( int ) ),
+ this, SLOT( slotPortChanged( int ) ) );
+
+ connect( m_kerberos, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotKerberosToggled( bool ) ) );
+
+ connect( m_proto_input, SIGNAL( activated( const QString & ) ),
+ this, SLOT( slotProtocolChanged( const QString & ) ) );
+
+ break;
+ }
+ case Share:
+ {
+#ifndef __FreeBSD__
+ QLabel *filesystem_label = new QLabel( i18n( "File system:" ), frame );
+ m_fs_input = new KComboBox( false, frame );
+ m_fs_input->setMinimumWidth( 200 );
+ m_fs_input->insertItem( "SMBFS", -1 );
+ m_fs_input->insertItem( "CIFS", -1 );
+ m_fs_input->setCurrentItem( 0 );
+
+ QLabel *permission_label = new QLabel( i18n( "Write access:" ), frame );
+ m_rw_input = new KComboBox( false, frame );
+ m_rw_input->setMinimumWidth( 200 );
+ m_rw_input->insertItem( i18n( "read-write" ) );
+ m_rw_input->insertItem( i18n( "read-only" ) );
+
+ QLabel *uid_label = new QLabel( i18n( "User ID:" ), frame );
+ m_uid_input = new KLineEdit( frame );
+ m_uid_input->setMinimumWidth( 200 );
+ m_uid_input->setAlignment( Qt::AlignRight );
+ QLabel *gid_label = new QLabel( i18n( "Group ID:" ), frame );
+ m_gid_input = new KLineEdit( frame );
+ m_gid_input->setMinimumWidth( 200 );
+ m_gid_input->setAlignment( Qt::AlignRight );
+
+ m_kerberos = new QCheckBox( i18n( "Try to authenticate with Kerberos (Active Directory)" ), frame );
+
+ grid->addWidget( location_label, 0, 0, 0 );
+ grid->addWidget( location, 0, 1, 0 );
+ grid->addWidget( port_label, 1, 0, 0 );
+ grid->addWidget( m_port_input, 1, 1, 0 );
+ grid->addWidget( filesystem_label, 2, 0, 0 );
+ grid->addWidget( m_fs_input, 2, 1, 0 );
+ grid->addWidget( uid_label, 3, 0, 0 );
+ grid->addWidget( m_uid_input, 3, 1, 0 );
+ grid->addWidget( gid_label, 4, 0, 0 );
+ grid->addWidget( m_gid_input, 4, 1, 0 );
+ grid->addWidget( permission_label, 5, 0, 0 );
+ grid->addWidget( m_rw_input, 5, 1, 0 );
+ grid->addMultiCellWidget( m_kerberos, 6, 6, 0, 1, 0 );
+#else
+ QLabel *uid_label = new QLabel( i18n( "User ID:" ), frame );
+ m_uid_input = new KLineEdit( frame );
+ m_uid_input->setMinimumWidth( 200 );
+ m_uid_input->setAlignment( Qt::AlignRight );
+ QLabel *gid_label = new QLabel( i18n( "Group ID:" ), frame );
+ m_gid_input = new KLineEdit( frame );
+ m_gid_input->setMinimumWidth( 200 );
+ m_gid_input->setAlignment( Qt::AlignRight );
+
+ grid->addWidget( location_label, 0, 0, 0 );
+ grid->addWidget( location, 0, 1, 0 );
+ grid->addWidget( port_label, 1, 0, 0 );
+ grid->addWidget( m_port_input, 1, 1, 0 );
+ grid->addWidget( uid_label, 2, 0, 0 );
+ grid->addWidget( m_uid_input, 2, 1, 0 );
+ grid->addWidget( gid_label, 3, 0, 0 );
+ grid->addWidget( m_gid_input, 3, 1, 0 );
+#endif
+
+ info = optionsHandler()->findItem( QString( "//%1/%2" ).arg( m_share_item->host(), m_share_item->name() ) );
+
+ // Get the default values from the config file:
+ default_port = Smb4KSettings::remotePort();
+ default_uid = Smb4KSettings::userID();
+ default_gid = Smb4KSettings::groupID();
+#ifndef __FreeBSD__
+ default_kerberos = Smb4KSettings::useKerberos();
+
+ switch ( Smb4KSettings::writeAccess() )
+ {
+ case Smb4KSettings::EnumWriteAccess::ReadWrite:
+ {
+ default_readwrite = true;
+
+ break;
+ }
+ case Smb4KSettings::EnumWriteAccess::ReadOnly:
+ {
+ default_readwrite = false;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+
+ switch( Smb4KSettings::filesystem() )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ default_filesystem = "cifs";
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ default_filesystem = "smbfs";
+
+ break;
+ }
+ default:
+ {
+ // FIXME: Set default_filesystem to "cifs"?
+ break;
+ }
+ }
+#endif
+
+ // Define the values that have to be put into the widgets:
+ port_value = (info && info->port() != -1) ?
+ info->port() :
+ default_port;
+
+ uid_value = (info && !info->uid().isEmpty()) ?
+ info->uid() :
+ default_uid;
+
+ gid_value = (info && !info->gid().isEmpty()) ?
+ info->gid() :
+ default_gid;
+#ifndef __FreeBSD__
+ kerberos_value = (info && info->kerberos() != default_kerberos) ?
+ info->kerberos() :
+ default_kerberos;
+
+ readwrite_value = (info && info->writeAccess() != default_readwrite) ?
+ info->writeAccess() :
+ default_readwrite;
+
+ filesystem_value = (info && !info->filesystem().isEmpty()) ?
+ info->filesystem() :
+ default_filesystem;
+#endif
+
+ // Put the values in the widgets:
+ m_port_input->setValue( port_value );
+ m_uid_input->setText( uid_value );
+ m_gid_input->setText( gid_value );
+#ifndef __FreeBSD__
+ m_kerberos->setChecked( kerberos_value );
+ m_fs_input->setCurrentText( filesystem_value.upper() );
+ m_rw_input->setCurrentText( (readwrite_value ?
+ i18n( "read-write" ) :
+ i18n( "read-only" )) );
+
+ // Because we do not have Kerberos with CIFS, disable this button
+ // in that case:
+ m_kerberos->setEnabled( !(QString::compare( filesystem_value, "cifs" ) == 0) );
+#endif
+
+ // Does the 'Default' button need to be enabled?
+#ifndef __FreeBSD__
+ if ( default_port != port_value ||
+ QString::compare( default_filesystem, filesystem_value ) != 0 ||
+ default_kerberos != kerberos_value ||
+ default_readwrite != readwrite_value ||
+ QString::compare( default_uid, uid_value ) != 0 ||
+ QString::compare( default_gid, gid_value ) != 0 )
+ {
+ enable_default_button = true;
+ }
+#else
+ if ( default_port != port_value ||
+ QString::compare( default_uid, uid_value ) != 0 ||
+ QString::compare( default_gid, gid_value ) != 0 )
+ {
+ enable_default_button = true;
+ }
+#endif
+
+ // Connections:
+ connect( m_port_input, SIGNAL( valueChanged( int ) ),
+ this, SLOT( slotPortChanged( int ) ) );
+
+ connect( m_uid_input, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotUIDChanged( const QString & ) ) );
+
+ connect( m_gid_input, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotGIDChanged( const QString & ) ) );
+
+#ifndef __FreeBSD__
+ connect( m_kerberos, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotKerberosToggled( bool ) ) );
+
+ connect( m_rw_input, SIGNAL( activated( const QString & ) ),
+ this, SLOT( slotWriteAccessChanged( const QString & ) ) );
+
+ connect( m_fs_input, SIGNAL( activated( const QString & ) ),
+ this, SLOT( slotFilesystemChanged( const QString & ) ) );
+#endif
+
+ break;
+ }
+ default:
+ {
+ // This should not happen...
+ break;
+ }
+ }
+
+ // Enable the buttons:
+ enableButton( Ok, false );
+ enableButton( User1, enable_default_button );
+
+ // Connect the buttons:
+ connect( this, SIGNAL( okClicked() ),
+ this, SLOT( slotOKButtonClicked() ) );
+
+ connect( this, SIGNAL( user1Clicked() ),
+ this, SLOT( slotDefaultButtonClicked() ) );
+
+ setFixedSize( (sizeHint().width() > 350 ? sizeHint().width() : 350), sizeHint().height() );
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KCustomOptionsDialog::slotPortChanged( int val )
+{
+ port_changed_ok = (port_value != val);
+ port_changed_default = (default_port != val);
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+#ifndef __FreeBSD__
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+#endif
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+#ifndef __FreeBSD__
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+#endif
+ uid_changed_default ||
+ gid_changed_default );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KCustomOptionsDialog::slotFilesystemChanged( const QString &text )
+{
+#ifndef __FreeBSD__
+ filesystem_changed_ok = (QString::compare( filesystem_value, text.lower() ) != 0);
+ filesystem_changed_default = (QString::compare( default_filesystem, text.lower() ) != 0);
+
+ // Authentication with Kerberos does not exist with mount.cifs:
+ if ( QString::compare( text, "CIFS" ) == 0 )
+ {
+ m_kerberos->setEnabled( false );
+ }
+ else
+ {
+ m_kerberos->setEnabled( true );
+ }
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+ uid_changed_default ||
+ gid_changed_default );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+#endif
+}
+
+
+void Smb4KCustomOptionsDialog::slotProtocolChanged( const QString &protocol )
+{
+ protocol_changed_ok = (QString::compare( protocol_value, protocol.lower() ) != 0);
+ protocol_changed_default = (QString::compare( default_protocol, protocol.lower() ) != 0);
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+#ifndef __FreeBSD__
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+#endif
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+#ifndef __FreeBSD__
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+#endif
+ uid_changed_default ||
+ gid_changed_default );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KCustomOptionsDialog::slotKerberosToggled( bool on )
+{
+ kerberos_changed_ok = (kerberos_value != on);
+ kerberos_changed_default = (default_kerberos != on);
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+#ifndef __FreeBSD__
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+#endif
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+#ifndef __FreeBSD__
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+#endif
+ uid_changed_default ||
+ gid_changed_default );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KCustomOptionsDialog::slotWriteAccessChanged( const QString &rw )
+{
+#ifndef __FreeBSD__
+ bool readwrite = (QString::compare( rw, i18n( "read-write" ) ) == 0);
+ readwrite_changed_ok = (readwrite_value != readwrite);
+ readwrite_changed_default = (default_readwrite != readwrite);
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+ uid_changed_default ||
+ gid_changed_default );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+#endif
+}
+
+
+void Smb4KCustomOptionsDialog::slotUIDChanged( const QString &uid )
+{
+ uid_changed_ok = (QString::compare( uid_value, uid ) != 0);
+ uid_changed_default = (QString::compare( default_uid, uid ) != 0);
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+#ifndef __FreeBSD__
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+#endif
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+#ifndef __FreeBSD__
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+#endif
+ uid_changed_default ||
+ gid_changed_default );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KCustomOptionsDialog::slotGIDChanged( const QString &gid )
+{
+ gid_changed_ok = (QString::compare( gid_value, gid ) != 0);
+ gid_changed_default = (QString::compare( default_gid, gid ) != 0);
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ enableButton( Ok, port_changed_ok ||
+ protocol_changed_ok ||
+ kerberos_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+ protocol_changed_default ||
+ kerberos_changed_default );
+
+ break;
+ }
+ case Share:
+ {
+ enableButton( Ok, port_changed_ok ||
+#ifndef __FreeBSD__
+ filesystem_changed_ok ||
+ kerberos_changed_ok ||
+ readwrite_changed_ok ||
+#endif
+ uid_changed_ok ||
+ gid_changed_ok );
+
+ enableButton( User1, port_changed_default ||
+#ifndef __FreeBSD__
+ filesystem_changed_default ||
+ kerberos_changed_default ||
+ readwrite_changed_default ||
+#endif
+ uid_changed_default ||
+ gid_changed_default );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KCustomOptionsDialog::slotOKButtonClicked()
+{
+ Smb4KSambaOptionsInfo *info = NULL;
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ QString item_name = m_host_item->name();
+
+ // Check if we can remove the item:
+ if ( !port_changed_default && !protocol_changed_default && !kerberos_changed_default )
+ {
+ optionsHandler()->removeItem( item_name, true );
+ }
+ else
+ {
+ // First search for the item in the custom options list
+ // and create a new one only if the info could not be
+ // found:
+ if ( !(info = optionsHandler()->findItem( item_name, true )) )
+ {
+ info = new Smb4KSambaOptionsInfo( item_name );
+ }
+
+ // Put in the needed information:
+ info->setPort( m_port_input->value() );
+
+ info->setProtocol( QString::compare( m_proto_input->currentText(), i18n( "auto" ) ) == 0 ?
+ "auto" :
+ m_proto_input->currentText().lower() );
+
+ info->setKerberos( m_kerberos->isChecked() );
+
+ // Add the new item.
+ optionsHandler()->addItem( info, true );
+ }
+
+ break;
+ }
+ case Share:
+ {
+ QString item_name = QString( "//%1/%2" ).arg( m_share_item->host(),
+ QString::compare( m_share_item->name(), "homes" ) == 0 ?
+ m_homes_user :
+ m_share_item->name() );
+
+#ifndef __FreeBSD__
+ // Check if we can remove the item:
+ if ( !port_changed_default && !filesystem_changed_default && !kerberos_changed_default &&
+ !readwrite_changed_default && !uid_changed_default && !gid_changed_default )
+ {
+ optionsHandler()->removeItem( item_name, true );
+ }
+ else
+ {
+ // First search for the item in the custom options list
+ // and create a new one only if the info could not be
+ // found:
+ if ( !(info = optionsHandler()->findItem( item_name, true )) )
+ {
+ info = new Smb4KSambaOptionsInfo( item_name );
+ }
+
+ // Put in the needed information:
+ info->setPort( m_port_input->value() );
+ info->setKerberos( m_kerberos->isChecked() );
+ info->setWriteAccess( (QString::compare( m_rw_input->currentText(), i18n( "read-write" ) ) == 0) );
+ info->setFilesystem( m_fs_input->currentText().lower() );
+ info->setUID( m_uid_input->text() );
+ info->setGID( m_gid_input->text() );
+
+ // Add the new item.
+ optionsHandler()->addItem( info, true );
+ }
+#else
+ // Check if we can remove the item:
+ if ( !port_changed_default && !kerberos_changed_default && !uid_changed_default &&
+ !gid_changed_default )
+ {
+ optionsHandler()->removeItem( item_name, true );
+ }
+ else
+ {
+ // First search for the item in the custom options list
+ // and create a new one only if the info could not be
+ // found:
+ if ( !(info = optionsHandler()->findItem( item_name, true )) )
+ {
+ info = new Smb4KSambaOptionsInfo( item_name );
+ }
+
+ // Put in the needed information:
+ info->setPort( m_port_input->value() );
+ info->setUID( m_uid_input->text() );
+
+ info->setGID( m_gid_input->text() );
+
+ // Add the new item.
+ optionsHandler()->addItem( info, true );
+ }
+#endif
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KCustomOptionsDialog::slotDefaultButtonClicked()
+{
+ // Here, we only reset the dialog and enable the OK button
+ // if necessary.
+
+ switch ( m_type )
+ {
+ case Host:
+ {
+ m_port_input->setValue( default_port );
+ m_kerberos->setChecked( default_kerberos );
+ QString protocol = (QString::compare( default_protocol, "auto" ) == 0 ? i18n( "auto" ) : protocol_value.upper());
+ m_proto_input->setCurrentText( protocol );
+
+ // Enable or disable the OK button:
+ enableButton( Ok, default_port != port_value ||
+ default_kerberos != kerberos_value ||
+ QString::compare( default_protocol, protocol_value ) != 0 );
+
+ break;
+ }
+ case Share:
+ {
+ m_port_input->setValue( default_port );
+ m_uid_input->setText( default_uid );
+ m_gid_input->setText( default_gid );
+
+#ifndef __FreeBSD__
+ m_kerberos->setChecked( default_kerberos );
+ QString write_access = (default_readwrite ? i18n( "read-write" ) : i18n( "read-only" ));
+ m_rw_input->setCurrentText( write_access );
+ m_fs_input->setCurrentText( default_filesystem.upper() );
+
+ // Enable or disable the Kerberos check box depending on
+ // the (default) file system:
+ if ( QString::compare( default_filesystem, "cifs" ) == 0 )
+ {
+ m_kerberos->setEnabled( false );
+ }
+ else
+ {
+ m_kerberos->setEnabled( true );
+ }
+#endif
+
+ // Enable or disable the OK button:
+ enableButton( Ok, default_port != port_value ||
+#ifndef __FreeBSD__
+ default_kerberos != kerberos_value ||
+ QString::compare( default_filesystem, filesystem_value ) != 0 ||
+ default_readwrite != readwrite_value ||
+#endif
+ QString::compare( default_uid, uid_value ) != 0 ||
+ QString::compare( default_gid, gid_value ) != 0 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // We just put the default values into the dialog.
+ // Disable the 'Default' button:
+ enableButton( User1, false );
+}
+
+#include "smb4kcustomoptionsdialog.moc"
diff --git a/smb4k/dialogs/smb4kcustomoptionsdialog.h b/smb4k/dialogs/smb4kcustomoptionsdialog.h
new file mode 100644
index 0000000..10594a9
--- /dev/null
+++ b/smb4k/dialogs/smb4kcustomoptionsdialog.h
@@ -0,0 +1,232 @@
+/***************************************************************************
+ smb4kcustomoptionsdialog - With this dialog the user can define
+ custom Samba options for hosts or shares.
+ -------------------
+ begin : So Jun 25 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KCUSTOMOPTIONSDIALOG_H
+#define SMB4KCUSTOMOPTIONSDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qcheckbox.h>
+
+// KDE includes
+#include <kdialogbase.h>
+#include <knuminput.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+
+// forward declarations
+class Smb4KHostItem;
+class Smb4KShareItem;
+
+class Smb4KCustomOptionsDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param host The host (server) for which the custom options should be defined.
+ *
+ * @param parent The parent of this dialog
+ *
+ * @param name The name of this dialog
+ */
+ Smb4KCustomOptionsDialog( Smb4KHostItem *host, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * Another constructor, similar to the one above.
+ *
+ * @param share The share for which the custom options should be defined.
+ *
+ * @param parent The parent of this dialog
+ *
+ * @param name The name of this dialog
+ */
+ Smb4KCustomOptionsDialog( Smb4KShareItem *share, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KCustomOptionsDialog();
+
+ /**
+ * This function returns TRUE if the dialog has been initialized correctly
+ * and may be shown now. It will always return TRUE if you want to set options
+ * for a server or for a share, that is not a 'homes' share. Only in the case
+ * of a homes share it may return FALSE, if you didn't choose a user name.
+ *
+ * @returns TRUE if the dialog has been set up correctly.
+ */
+ bool isInitialized() { return m_initialized; }
+
+ protected slots:
+ /**
+ * Is invoked when the port value changed
+ *
+ * @param int The port number
+ */
+ void slotPortChanged( int value );
+
+ /**
+ * Is invoked when the file system value changed
+ *
+ * @param fs The file system
+ */
+ void slotFilesystemChanged( const QString &fs );
+
+ /**
+ * Is invoked when the protocol value changed
+ *
+ * @param t The protocol
+ */
+ void slotProtocolChanged( const QString &p );
+
+ /**
+ * Is invoked when the user clicked the 'Use Kerberos'
+ * check box.
+ *
+ * @param on TRUE if the check box was
+ * checked and FALSE otherwise
+ */
+ void slotKerberosToggled( bool on );
+
+ /**
+ * Commit the custom options provided for the selected
+ * network item.
+ */
+ void slotOKButtonClicked();
+
+ /**
+ * Is invoked if the "Default" button has been pressed.
+ */
+ void slotDefaultButtonClicked();
+
+ /**
+ * This slot is invoked when the "Write Access" value changed.
+ *
+ * @param rw Either 'read-write' or 'read-only' (localized).
+ */
+ void slotWriteAccessChanged( const QString &rw );
+
+ /**
+ * This slot is invoked when the UID value changed.
+ *
+ * @param uid The UID value
+ */
+ void slotUIDChanged( const QString &uid );
+
+ /**
+ * This slot is invoked when the GID value changed.
+ *
+ * @param gid The UID value
+ */
+ void slotGIDChanged( const QString &gid );
+
+ private:
+ /**
+ * Enumeration
+ */
+ enum ItemType{ Host, Share };
+
+ /**
+ * The item type
+ */
+ int m_type;
+
+ /**
+ * Sets up the dialog
+ */
+ void setupDialog();
+
+ /**
+ * The host item (is NULL if you process a share).
+ */
+ Smb4KHostItem *m_host_item;
+
+ /**
+ * The share item (is NULL if you process a host).
+ */
+ Smb4KShareItem *m_share_item;
+
+ /**
+ * Port input
+ */
+ KIntNumInput *m_port_input;
+
+#ifndef __FreeBSD__
+ /**
+ * The file system
+ */
+ KComboBox *m_fs_input;
+
+ /**
+ * This combo box determines if the user wants to mount a share
+ * readwrite or readonly.
+ */
+ KComboBox *m_rw_input;
+#endif
+
+ /**
+ * The protocol
+ */
+ KComboBox *m_proto_input;
+
+ /**
+ * Boolean that is TRUE if the dialog has been initialized
+ * correctly and my be shown now.
+ */
+ bool m_initialized;
+
+ /**
+ * This will only be set if we are dealing with a 'homes' share.
+ */
+ QString m_homes_user;
+
+ /**
+ * This check box will determine if the user wants to try to
+ * authenticate with Kerberos or not. This is needed for Active
+ * Directory stuff.
+ */
+ QCheckBox *m_kerberos;
+
+ /**
+ * This combo box holds the values of the UID that the user can
+ * chose from.
+ */
+ KLineEdit *m_uid_input;
+
+ /**
+ * This combo box holds the values of the GID that the user can
+ * chose from.
+ */
+ KLineEdit *m_gid_input;
+};
+
+#endif
diff --git a/smb4k/dialogs/smb4kmountdialog.cpp b/smb4k/dialogs/smb4kmountdialog.cpp
new file mode 100644
index 0000000..7cafe35
--- /dev/null
+++ b/smb4k/dialogs/smb4kmountdialog.cpp
@@ -0,0 +1,172 @@
+/***************************************************************************
+ smb4kmountdialog - This class provides a dialog for mounting shares
+ manually.
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kmountdialog.h"
+
+#include "../core/smb4kmounter.h"
+#include "../core/smb4kbookmarkhandler.h"
+#include "../core/smb4kbookmark.h"
+#include "../core/smb4kcore.h"
+#include "../smb4k.h"
+
+Smb4KMountDialog::Smb4KMountDialog( QWidget *parent, const char *name ) :
+KDialogBase( Plain, i18n( "Mount Share" ), Ok|Cancel, Ok, parent, name, true, true )
+{
+ setWFlags( Qt::WDestructiveClose );
+
+ setupView();
+
+ setFixedSize( (sizeHint().width() > 350 ? sizeHint().width() : 350), sizeHint().height() );
+}
+
+
+Smb4KMountDialog::~Smb4KMountDialog()
+{
+}
+
+
+void Smb4KMountDialog::setupView()
+{
+ QFrame *frame = plainPage();
+ QGridLayout *layout = new QGridLayout( frame );
+ layout->setSpacing( 5 );
+ layout->setMargin( 0 );
+
+ QLabel *shareLabel = new QLabel( i18n( "Share:" ), frame );
+ m_share_input = new KLineEdit( frame, "ShareInputLine" );
+ m_share_input->setMinimumWidth( 200 );
+ m_share_input->setFocus();
+
+ QLabel *addressLabel = new QLabel( i18n( "IP Address:" ), frame );
+ m_ip_input = new KLineEdit( frame, "IPInputLine" );
+ m_ip_input->setMinimumWidth( 200 );
+
+ QLabel *workgroupLabel = new QLabel( i18n( "Workgroup:" ), frame );
+ m_workgroup_input = new KLineEdit( frame, "WorkgroupInputLine" );
+ m_workgroup_input->setMinimumWidth( 200 );
+
+ m_bookmark = new QCheckBox( i18n( "Add this share to the bookmarks" ), frame, "BookmarkButton" );
+
+ layout->addWidget( shareLabel, 0, 0, 0 );
+ layout->addWidget( m_share_input, 0, 1, 0 );
+ layout->addWidget( addressLabel, 1, 0, 0 );
+ layout->addWidget( m_ip_input, 1, 1, 0 );
+ layout->addWidget( workgroupLabel, 2, 0, 0 );
+ layout->addWidget( m_workgroup_input, 2, 1, 0 );
+ layout->addMultiCellWidget( m_bookmark, 3, 3, 0, 1, 0 );
+
+ connect( m_share_input, SIGNAL( textChanged ( const QString & ) ) ,
+ this, SLOT( slotChangeInputValue( const QString & ) ) );
+
+ slotChangeInputValue( m_share_input->text() );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KMountDialog::slotChangeInputValue( const QString& _test)
+{
+ enableButtonOK( !_test.isEmpty() );
+}
+
+void Smb4KMountDialog::slotOk()
+{
+ // FIXME: Leave the decision if the share is not formatted
+ // correctly up to the mounter. Just pass the string to
+ // Smb4KCore::mounter()->mountShare().
+
+ if ( !m_share_input->text().stripWhiteSpace().isEmpty() )
+ {
+#ifndef __FreeBSD__
+ if ( m_share_input->text().contains( "/" ) == 3 )
+#else
+ if ( m_share_input->text().contains( "/" ) == 3
+ && m_share_input->text().contains( '@' ) == 0 )
+#endif
+ {
+ QString host = m_share_input->text().stripWhiteSpace().section( "/", 2, 2 );
+ QString share = m_share_input->text().stripWhiteSpace().section( "/", 3, 3 );
+ QString ip = m_ip_input->text().stripWhiteSpace();
+ QString workgroup = m_workgroup_input->text().stripWhiteSpace();
+
+ Smb4KCore::mounter()->mountShare( workgroup, host, ip, share );
+
+ if ( m_bookmark->isChecked() )
+ {
+ Smb4KCore::bookmarkHandler()->addBookmark( new Smb4KBookmark( host, share, workgroup, ip, QString::null ) );
+ }
+
+ connect( Smb4KCore::mounter(), SIGNAL( state( int ) ), this, SLOT( slotMounterStateChanged( int ) ) );
+ }
+ else
+ {
+ KMessageBox::error( this, i18n( "The format of the share you entered is not correct. It must have the form //HOST/SHARE." ) );
+ }
+ }
+}
+
+
+void Smb4KMountDialog::slotCancel()
+{
+ Smb4KCore::mounter()->abort();
+
+ KDialogBase::slotCancel();
+}
+
+
+void Smb4KMountDialog::slotMounterStateChanged( int state )
+{
+ switch ( state )
+ {
+ case MOUNTER_STOP:
+ {
+ accept();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+#include "smb4kmountdialog.moc"
+
diff --git a/smb4k/dialogs/smb4kmountdialog.h b/smb4k/dialogs/smb4kmountdialog.h
new file mode 100644
index 0000000..ff7ff5f
--- /dev/null
+++ b/smb4k/dialogs/smb4kmountdialog.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ smb4kmountdialog - This class provides a dialog for mounting shares
+ manually.
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KMOUNTDIALOG_H
+#define SMB4KMOUNTDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qcheckbox.h>
+
+// KDE includes
+#include <kdialogbase.h>
+#include <klineedit.h>
+
+/**
+ * This class provides a dialog with which you can mount shares "manually".
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KMountDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ */
+ Smb4KMountDialog( QWidget *parent = 0, const char *name = 0 );
+ /**
+ * The destructor.
+ */
+ ~Smb4KMountDialog();
+
+ protected slots:
+ /**
+ * Reimplemented from KDialogBase.
+ */
+ void slotOk();
+
+ /**
+ * Reimplemented from KDoalogBase.
+ */
+ void slotCancel();
+
+ /**
+ * This slot is being enabled if there is input text.
+ *
+ * @param text The input text.
+ */
+ void slotChangeInputValue( const QString &text );
+
+ /**
+ * This slot is connected to the Smb4KCore::mounter()::state() signal.
+ * It is used to close the dialog.
+ *
+ * @param state The state of the mounter.
+ */
+ void slotMounterStateChanged( int state );
+
+ private:
+ /**
+ * This function sets up the view.
+ */
+ void setupView();
+ /**
+ * The line edit where the user has to enter the share.
+ */
+ KLineEdit *m_share_input;
+ /**
+ * The line edit where the user can enter the IP address.
+ */
+ KLineEdit *m_ip_input;
+ /**
+ * The line edit where the user can enter the workgroup.
+ */
+ KLineEdit *m_workgroup_input;
+ /**
+ * This checkbox determines whether the share should be added to the
+ * bookmarks.
+ */
+ QCheckBox *m_bookmark;
+};
+
+#endif
diff --git a/smb4k/dialogs/smb4kpreviewdialog.cpp b/smb4k/dialogs/smb4kpreviewdialog.cpp
new file mode 100644
index 0000000..4a3f7b8
--- /dev/null
+++ b/smb4k/dialogs/smb4kpreviewdialog.cpp
@@ -0,0 +1,399 @@
+/***************************************************************************
+ smb4kpreviewdialog.cpp - The preview dialog of Smb4K
+ -------------------
+ begin : Fre Jul 4 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qiconset.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <ktoolbarbutton.h>
+
+// application specific includes
+#include "smb4kpreviewdialog.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4knetworkitems.h"
+#include "../core/smb4ksettings.h"
+
+
+Smb4KPreviewDialog::Smb4KPreviewDialog( Smb4KShareItem *item, QWidget *parent, const char *name )
+: KDialogBase( Plain, i18n( "Preview" ), Close, Close, parent, name, false, true )
+{
+ setWFlags( Qt::WDestructiveClose );
+
+ m_item = new Smb4KPreviewItem( item );
+
+ if ( m_item )
+ {
+ if ( Smb4KHostItem *host = Smb4KCore::scanner()->getHost( item->host(), item->workgroup() ) )
+ {
+ m_item->setIP( host->ip() );
+ }
+
+ m_button_id = None;
+
+ m_current_item = m_history.end();
+
+ setupView();
+
+ setInitialSize( configDialogSize( *(Smb4KSettings::self()->config()), "PreviewDialog" ) );
+
+ connect( m_view, SIGNAL( executed( QIconViewItem * ) ),
+ this, SLOT( slotItemExecuted( QIconViewItem * ) ) );
+
+ connect( m_toolbar, SIGNAL( clicked( int ) ),
+ this, SLOT( slotButtonClicked( int ) ) );
+
+ connect( m_combo, SIGNAL( activated( const QString & ) ),
+ this, SLOT( slotItemActivated( const QString & ) ) );
+
+ connect( Smb4KCore::previewer(), SIGNAL( result( Smb4KPreviewItem * ) ),
+ this, SLOT( slotReceivedData( Smb4KPreviewItem * ) ) );
+
+ m_initialized = Smb4KCore::previewer()->preview( m_item );
+ }
+
+ setMinimumSize( (sizeHint().width() > 350 ? sizeHint().width() : 350), sizeHint().height() );
+}
+
+
+Smb4KPreviewDialog::~Smb4KPreviewDialog()
+{
+ delete m_item;
+}
+
+
+void Smb4KPreviewDialog::setupView()
+{
+ QFrame *frame = plainPage();
+ QGridLayout *layout = new QGridLayout( frame );
+
+ m_view = new KIconView( frame, 0, 0 );
+ m_view->setItemTextPos( KIconView::Right );
+ m_view->setResizeMode( KIconView::Adjust );
+ m_view->setArrangement( KIconView::TopToBottom );
+ m_view->setSpacing( 1 );
+ m_view->setGridX( 200 );
+ m_view->setWordWrapIconText( false );
+ m_view->setShowToolTips( true );
+ m_view->setAutoArrange( true );
+ m_view->setSorting( true, true );
+
+ m_toolbar = new KToolBar( frame, 0, true, false );
+ m_toolbar->insertButton( "reload", Reload, true, i18n( "Reload" ), 0 );
+ m_toolbar->insertButton( "back", Back, false, i18n( "Back" ), 1 );
+ m_toolbar->insertButton( "forward", Forward, false, i18n( "Forward" ), 2 );
+ m_toolbar->insertButton( "up", Up, false, i18n( "Up" ), 3 );
+
+ m_combo = new KComboBox( false, m_toolbar, 0 );
+ m_combo->listBox()->setHScrollBarMode( QScrollView::Auto );
+ m_combo->listBox()->setVScrollBarMode( QScrollView::Auto );
+ m_combo->listBox()->setMinimumHeight( 100 );
+ m_toolbar->insertWidget( Combo, 10, m_combo, 4 );
+ m_toolbar->setItemAutoSized( Combo, true );
+
+ layout->addWidget( m_view, 0, 0, 0 );
+ layout->addWidget( m_toolbar, 1, 0, 0 );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KPreviewDialog::slotReceivedData( Smb4KPreviewItem *item )
+{
+ // If the item is NULL or not equal to m_item,
+ // stop right here:
+ if ( !item || item != m_item )
+ {
+ return;
+ }
+
+ // Clear the icon view:
+ m_view->clear();
+
+ // The item should be equal to m_item, so we can use either of those
+ // pointers.
+
+ // Process the data:
+ if ( !item->contents().isEmpty() )
+ {
+ // Generate the history.
+ switch ( m_button_id )
+ {
+ case Reload: /* Really? */
+ case Back:
+ case Forward:
+ {
+ // Do not insert anything into the history if
+ // one of these three buttons was clicked.
+
+ break;
+ }
+ default:
+ {
+ m_history.append( item->location() );
+ m_current_item = --m_history.end();
+
+ break;
+ }
+ }
+
+ // Clear the combo box, put the new history there and set the
+ // current item:
+ m_combo->clear();
+
+ for ( QStringList::Iterator it = m_history.begin(); it != m_history.end(); it++ )
+ {
+ if ( !m_combo->listBox()->findItem( *it, Qt::CaseSensitive|Qt::ExactMatch ) )
+ {
+ m_combo->insertItem( *it, -1 );
+ }
+ }
+
+ m_combo->setCurrentText( *m_current_item );
+
+ // Now put the contents in the icon view:
+ for ( QValueList<ContentsItem>::ConstIterator it = item->contents().begin();
+ it != item->contents().end(); ++it )
+ {
+ switch ( (*it).first )
+ {
+ case Smb4KPreviewItem::File:
+ {
+ KIconViewItem *view_item = new KIconViewItem( m_view, (*it).second, SmallIcon( "file" ) );
+ view_item->setKey( QString( "[file]_%1" ).arg( (*it).second ) );
+
+ break;
+ }
+ case Smb4KPreviewItem::Directory:
+ {
+ // We do not want to show the '.' and '..' directories.
+ if ( QString::compare( (*it).second, "." ) != 0 && QString::compare( (*it).second, ".." ) != 0 )
+ {
+ KIconViewItem *view_item = new KIconViewItem( m_view, (*it).second, SmallIcon( "folder" ) );
+ view_item->setKey( QString( "[directory]_%1" ).arg( (*it).second ) );
+ }
+
+ break;
+ }
+ case Smb4KPreviewItem::HiddenFile:
+ {
+ if ( Smb4KSettings::previewHiddenItems() )
+ {
+ KIconViewItem *view_item = new KIconViewItem( m_view, (*it).second, SmallIcon( "file" ) );
+ view_item->setKey( QString( "[file]_%1" ).arg( (*it).second ) );
+ }
+
+ break;
+ }
+ case Smb4KPreviewItem::HiddenDirectory:
+ {
+ if ( Smb4KSettings::previewHiddenItems() &&
+ QString::compare( (*it).second, "." ) != 0 && QString::compare( (*it).second, ".." ) != 0 )
+ {
+ KIconViewItem *view_item = new KIconViewItem( m_view, (*it).second, SmallIcon( "folder" ) );
+ view_item->setKey( QString( "[directory]_%1" ).arg( (*it).second ) );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Now activate or deactivate the buttons:
+
+ // Activate the 'Up' button if the current address is
+ // not equal to the base address.
+ m_toolbar->setItemEnabled( Up, QString::compare( "//"+item->host()+"/"+item->share()+"/", item->location() ) != 0 );
+
+ // Activate/Deactivate 'Back' and 'Forward' buttons.
+ m_toolbar->setItemEnabled( Back, m_current_item != m_history.at( 0 ) );
+ m_toolbar->setItemEnabled( Forward, m_current_item != m_history.at( m_history.count() - 1 ) );
+ }
+ else
+ {
+ return;
+ }
+}
+
+
+void Smb4KPreviewDialog::slotItemExecuted( QIconViewItem *item )
+{
+ if ( !item->key().startsWith( "[file]_" ) )
+ {
+ m_button_id = None;
+
+ m_item->setPath( m_item->path()+item->text()+"/" );
+
+ Smb4KCore::previewer()->preview( m_item );
+ }
+}
+
+
+void Smb4KPreviewDialog::slotButtonClicked( int id )
+{
+ m_button_id = id;
+
+ m_item->clearContents();
+
+ switch ( id )
+ {
+ case Reload:
+ {
+ Smb4KCore::previewer()->preview( m_item );
+
+ break;
+ }
+ case Up:
+ {
+ // Do nothing if the path is empty because
+ // we are already in the root directory.
+ if ( m_item->path().isEmpty() )
+ {
+ return;
+ }
+
+ if ( m_item->path().contains( "/" ) > 1 )
+ {
+ m_item->setPath( m_item->path().section( "/", 0, -3 ).append( "/" ) );
+ }
+ else if ( m_item->path().contains( "/", true ) == 1 )
+ {
+ m_item->setPath( QString::null );
+ }
+
+ Smb4KCore::previewer()->preview( m_item );
+
+ break;
+ }
+ case Back:
+ {
+ // Move one item back in the list:
+ if ( m_current_item != m_history.at( 0 ) )
+ {
+ m_current_item--;
+ }
+ else
+ {
+ return;
+ }
+
+ // Get the path:
+ if ( (*m_current_item).contains( "/", true ) == 3 )
+ {
+ m_item->setPath( QString::null );
+ }
+ else
+ {
+ m_item->setPath( (*m_current_item).section( "/", 4, -1 ) );
+
+ if ( !m_item->path().isEmpty() )
+ {
+ m_item->setPath( m_item->path()+"/" );
+ }
+ else
+ {
+ // Do nothing.
+ }
+ }
+
+ Smb4KCore::previewer()->preview( m_item );
+
+ break;
+ }
+ case Forward:
+ {
+ // Move one item forward in the list:
+ if ( m_current_item != m_history.at( m_history.count() - 1 ) )
+ {
+ m_current_item++;
+ }
+ else
+ {
+ return;
+ }
+
+ // Get the path:
+ if ( (*m_current_item).contains( "/", true ) == 3 )
+ {
+ m_item->setPath( QString::null );
+ }
+ else
+ {
+ m_item->setPath( (*m_current_item).section( "/", 4, -1 ) );
+
+ if ( !m_item->path().isEmpty() )
+ {
+ m_item->setPath( m_item->path()+"/" );
+ }
+ else
+ {
+ // Do nothing.
+ }
+ }
+
+ Smb4KCore::previewer()->preview( m_item );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KPreviewDialog::slotItemActivated( const QString &item )
+{
+ m_button_id = Combo;
+
+ // First we have to strip the address:
+ m_item->setPath( item.section( "//"+m_item->host()+"/"+m_item->share()+"/", 1, 1 ).stripWhiteSpace() );
+
+ Smb4KCore::previewer()->preview( m_item );
+}
+
+
+void Smb4KPreviewDialog::slotClose()
+{
+ saveDialogSize( *(Smb4KSettings::self()->config()), "PreviewDialog" );
+
+ KDialogBase::slotClose();
+}
+
+
+#include "smb4kpreviewdialog.moc"
+
diff --git a/smb4k/dialogs/smb4kpreviewdialog.h b/smb4k/dialogs/smb4kpreviewdialog.h
new file mode 100644
index 0000000..8c8fe15
--- /dev/null
+++ b/smb4k/dialogs/smb4kpreviewdialog.h
@@ -0,0 +1,167 @@
+/***************************************************************************
+ smb4kpreviewdialog.h - The preview dialog of Smb4K
+ -------------------
+ begin : Fre Jul 4 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPREVIEWDIALOG_H
+#define SMB4KPREVIEWDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qvaluelist.h>
+
+// KDE includes
+#include <kdialogbase.h>
+#include <kiconview.h>
+#include <ktoolbar.h>
+#include <kcombobox.h>
+
+// application specific includes
+#include "../core/smb4kpreviewitem.h"
+
+// forward declarations
+class Smb4KShareItem;
+
+/**
+ * This is the preview dialog of Smb4K. You can preview remote
+ * shares with it.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KPreviewDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * This is the constructor of the preview dialog.
+ *
+ * @param item The Smb4KShareItem object.
+ *
+ * @param parent The parent of this widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KPreviewDialog( Smb4KShareItem *item, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KPreviewDialog();
+
+ /**
+ * This function returns TRUE if the preview dialog has been
+ * initialized correctly and FALSE otherwise.
+ *
+ * @returns TRUE if the dialog was initialized correctly.
+ */
+ bool isInitialized() { return m_initialized; }
+
+ protected slots:
+ /**
+ * This slot receives the results of the attempt to generate
+ * a preview.
+ *
+ * @param item The Smb4KPreviewItem for which a preview
+ * was generated.
+ */
+ void slotReceivedData( Smb4KPreviewItem *item );
+
+ /**
+ * Is called, if one icon view item is clicked.
+ */
+ void slotItemExecuted( QIconViewItem *item );
+
+ /**
+ * Is called, if a tool bar button is clicked.
+ */
+ void slotButtonClicked( int id );
+
+ /**
+ * Is called, if an item in the combo box is activated.
+ */
+ void slotItemActivated( const QString &item );
+
+ /**
+ * Reimplemented from KDialogBase. Saves the dialog size and
+ * then executes KDialogBase::slotClose().
+ */
+ void slotClose();
+
+ private:
+ /**
+ * Enumeration for the buttons.
+ */
+ enum ButtonID{ Reload, Up, Back, Forward, Combo, None };
+
+ /**
+ * The current button id
+ */
+ int m_button_id;
+
+ /**
+ * Sets up the file view.
+ */
+ void setupView();
+
+ /**
+ * The icon view.
+ */
+ KIconView *m_view;
+
+ /**
+ * The toolbar.
+ */
+ KToolBar *m_toolbar;
+
+ /**
+ * The combo box.
+ */
+ KComboBox *m_combo;
+
+ /**
+ * The private Smb4KHostItem object
+ */
+ Smb4KPreviewItem *m_item;
+
+ /**
+ * This list holds the history of the session.
+ */
+ QStringList m_history;
+
+ /**
+ * This iterator points to the current item in the history.
+ */
+ QStringList::Iterator m_current_item;
+
+ /**
+ * TRUE if the dialog was successfully initilized and
+ * FALSE otherwise.
+ */
+ bool m_initialized;
+};
+#endif
diff --git a/smb4k/dialogs/smb4kprintdialog.cpp b/smb4k/dialogs/smb4kprintdialog.cpp
new file mode 100644
index 0000000..342d085
--- /dev/null
+++ b/smb4k/dialogs/smb4kprintdialog.cpp
@@ -0,0 +1,196 @@
+/***************************************************************************
+ smb4kprintdialog - The print dialog for Smb4K
+ -------------------
+ begin : So Apr 11 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurlrequester.h>
+#include <knuminput.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kprintdialog.h"
+#include "../core/smb4kprintinfo.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4knetworkitems.h"
+
+
+Smb4KPrintDialog::Smb4KPrintDialog( Smb4KShareItem *item, QWidget *parent, const char *name )
+: KDialogBase( Plain, i18n( "Print File" ), Details|Filler|User1|Cancel, User1, parent, name, true, true ),
+m_item( item ), m_ip( QString::null ) /* will collect it in an instant */
+{
+ setWFlags( Qt::WDestructiveClose );
+
+ if ( !m_item )
+ {
+ close();
+ }
+
+ setButtonGuiItem( User1, KStdGuiItem::print() );
+ setButtonText( Details, i18n( "Options" ) );
+
+ // Get the IP address
+ if ( Smb4KHostItem *host = Smb4KCore::scanner()->getHost( m_item->host(), m_item->workgroup() ) )
+ {
+ m_ip = host->ip();
+ }
+
+ // Bild the view:
+ QFrame *frame = plainPage();
+
+ QGridLayout *layout = new QGridLayout( frame );
+ layout->setSpacing( 10 );
+
+ QGroupBox *p = new QGroupBox( 2, Qt::Horizontal, i18n( "Printer" ), frame );
+ p->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "Name:" ), p );
+ (void) new QLabel( m_item->name()+
+ (!m_item->comment().stripWhiteSpace().isEmpty() ?
+ " ("+m_item->comment()+")" :
+ ""), p );
+
+// (void) new QLabel( i18n( "Comment:" ), p );
+// (void) new QLabel( m_item->comment(), p );
+
+ (void) new QLabel( i18n( "Host:" ), p );
+ (void) new QLabel( m_item->host(), p );
+
+ (void) new QLabel( i18n( "IP address:" ), p );
+ (void) new QLabel( m_ip.stripWhiteSpace().isEmpty() ?
+ i18n( "Unknown" ) :
+ m_ip,
+ p );
+
+ (void) new QLabel( i18n( "Workgroup:" ), p );
+ (void) new QLabel( m_item->workgroup(), p );
+
+ QGroupBox *f = new QGroupBox( 2, Qt::Horizontal, i18n( "File" ), frame );
+ f->setInsideSpacing( 5 );
+
+ (void) new QLabel( i18n( "File:" ), f );
+ KURLRequester *requester = new KURLRequester( QString::null, f, "URL" );
+ requester->setMode( KFile::File | KFile::LocalOnly );
+
+ QGroupBox *s = new QGroupBox( 2, Qt::Horizontal, i18n( "Options" ), frame );
+ s->setInsideSpacing( 5 );
+
+ setDetailsWidget( s );
+
+ (void) new QLabel( i18n( "Copies:" ), s );
+ KIntNumInput *cp = new KIntNumInput( 1, s, 10, "Copies" );
+ cp->setMinValue( 1 );
+
+ layout->addWidget( p, 0, 0, 0 );
+ layout->addWidget( f, 1, 0, 0 );
+
+ setFixedSize( (sizeHint().width() > 350 ? sizeHint().width() : 350), sizeHint().height() );
+
+ enableButton( User1, false );
+
+ connect( requester, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotInputValueChanged( const QString & ) ) );
+}
+
+
+Smb4KPrintDialog::~ Smb4KPrintDialog()
+{
+ // Do not delete the pointer to the Smb4KShareObject here!
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KPrintDialog::slotUser1()
+{
+ KURLRequester *url = static_cast<KURLRequester *>( child( "URL", "KURLRequester", true ) );
+ KIntNumInput *copies = static_cast<KIntNumInput *>( child( "Copies", "KIntNumInput", true ) );
+
+ if ( url && copies )
+ {
+ if ( !url->url().stripWhiteSpace().isEmpty() )
+ {
+ if ( Smb4KCore::print()->print( new Smb4KPrintInfo( m_item, m_ip, url->url().stripWhiteSpace(), copies->value() ) ) )
+ {
+ enableButton( User1, false );
+
+ connect( Smb4KCore::print(), SIGNAL( state( int ) ), this, SLOT( slotPrintStateChanged( int ) ) );
+ }
+ else
+ {
+ // FIXME: Should we report an error here?
+ }
+ }
+ else
+ {
+ KMessageBox::error( this, i18n( "You haven't specified a file." ) );
+ }
+ }
+}
+
+
+void Smb4KPrintDialog::slotCancel()
+{
+ if ( Smb4KCore::printIsRunning() )
+ {
+ Smb4KCore::print()->abort();
+ }
+
+ KDialogBase::slotCancel();
+}
+
+
+void Smb4KPrintDialog::slotPrintStateChanged( int state )
+{
+ switch ( state )
+ {
+ case PRINT_STOP:
+ {
+ accept();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KPrintDialog::slotInputValueChanged( const QString &text )
+{
+ enableButton( User1, !text.isEmpty() );
+}
+
+
+#include "smb4kprintdialog.moc"
diff --git a/smb4k/dialogs/smb4kprintdialog.h b/smb4k/dialogs/smb4kprintdialog.h
new file mode 100644
index 0000000..c7bff79
--- /dev/null
+++ b/smb4k/dialogs/smb4kprintdialog.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ smb4kprintdialog - The print dialog for Smb4K
+ -------------------
+ begin : So Apr 11 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KPRINTDIALOG_H
+#define SMB4KPRINTDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qstring.h>
+
+// KDE includes
+#include <kdialogbase.h>
+
+// forward declarations
+class Smb4KShareItem;
+
+
+/**
+ * This class provides the print dialog for Smb4K. You can choose the
+ * file that is to be printed and you can define the number of copies
+ * you want to have.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KPrintDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param item The Smb4KShareItem of the printer.
+ *
+ * @param parent The parent widget of this dialog.
+ *
+ * @param name The name of this dialog.
+ */
+ Smb4KPrintDialog( Smb4KShareItem *item, QWidget *parent = 0, const char *name = 0 );
+ /**
+ * The destructor
+ */
+ ~Smb4KPrintDialog();
+
+ protected slots:
+ /**
+ * Reimplemented from KDialogBase.
+ */
+ void slotUser1();
+
+ /**
+ * Reimplemented from KDialogBase.
+ */
+ void slotCancel();
+
+ /**
+ * This slot is connected to the Smb4KPrint::state() signal.
+ */
+ void slotPrintStateChanged( int state );
+
+ /**
+ * This slot is being enabled if there is input text.
+ *
+ * @param text The input text.
+ */
+ void slotInputValueChanged( const QString &text );
+
+ private:
+ /**
+ * The Smb4KShareItem object.
+ */
+ Smb4KShareItem *m_item;
+ /**
+ * Holds the IP address.
+ */
+ QString m_ip;
+};
+
+#endif
diff --git a/smb4k/dialogs/smb4ksynchronizationdialog.cpp b/smb4k/dialogs/smb4ksynchronizationdialog.cpp
new file mode 100644
index 0000000..5d72cce
--- /dev/null
+++ b/smb4k/dialogs/smb4ksynchronizationdialog.cpp
@@ -0,0 +1,239 @@
+/***************************************************************************
+ smb4ksynchronizationdialog - The synchronization dialog of Smb4K
+ -------------------
+ begin : Sa Mai 19 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kguiitem.h>
+#include <kdebug.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
+#include <kprogress.h>
+
+// application specific includes
+#include "smb4ksynchronizationdialog.h"
+#include "../core/smb4kshare.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4ksynchronizationinfo.h"
+#include "../core/smb4ksettings.h"
+
+Smb4KSynchronizationDialog::Smb4KSynchronizationDialog( Smb4KShare *share, QWidget *parent, const char *name )
+: KDialogBase( Plain, i18n( "Synchronization" ), User2|User1|Cancel, User1, parent, name, false, true ),
+m_share( share )
+{
+ setWFlags( Qt::WDestructiveClose );
+
+ setButtonGuiItem( User1, KGuiItem( i18n( "Synchronize" ), "bottom", i18n( "Synchronize the destination with the source" ) ) );
+ setButtonGuiItem( User2, KGuiItem( i18n( "Swap Paths" ), QString::null, i18n( "Swap source and destination" ) ) );
+
+ QFrame *frame = plainPage();
+ QGridLayout *layout = new QGridLayout( frame );
+ layout->setSpacing( 5 );
+ layout->setMargin( 0 );
+
+ QLabel *source_label = new QLabel( i18n( "Source:" ), frame, "SourceURLLabel" );
+ KURLRequester *source = new KURLRequester( m_share->path()+"/", frame, "SourceURL" );
+ source->setShowLocalProtocol( false );
+ source->setMode( KFile::Directory | KFile::LocalOnly );
+
+ QLabel *destination_label = new QLabel( i18n( "Destination:" ), frame, "DestinationURLLabel" );
+ KURLRequester *destination = new KURLRequester( Smb4KSettings::rsyncPrefix(), frame, "DestinationURL" );
+ destination->setShowLocalProtocol( false );
+ destination->setMode( KFile::Directory | KFile::LocalOnly );
+
+ KLineEdit *current_file = new KLineEdit( QString::null, frame, "ProgressInfo" );
+ current_file->setEnableSqueezedText( true );
+ current_file->setReadOnly( true );
+
+ KProgress *individual = new KProgress( frame, "IndividualProgress", 0 );
+ individual->setEnabled( false );
+
+ KProgress *total = new KProgress( frame, "TotalProgress", 0 );
+ total->setEnabled( false );
+
+ QWidget *transfer_widget = new QWidget( frame, "TransferInfoWidget" );
+ QGridLayout *trans_layout = new QGridLayout( transfer_widget );
+ trans_layout->setSpacing( 5 );
+ trans_layout->setMargin( 0 );
+
+ QLabel *file_label = new QLabel( i18n( "Files transferred:" ), transfer_widget,
+ "FilesTransferredLabel" );
+ QLabel *file_trans_label = new QLabel( "0 / 0", transfer_widget,
+ "FilesTransferred" );
+
+ QLabel *rate_label = new QLabel( i18n( "Transfer rate:" ), transfer_widget,
+ "TransferRateLabel" );
+ QLabel *trans_rate_label = new QLabel( "0.00 kB/s", transfer_widget,
+ "TransferRate" );
+
+ trans_layout->addWidget( file_label, 0, 0, 0 );
+ trans_layout->addWidget( file_trans_label, 0, 1, Qt::AlignRight );
+ trans_layout->addWidget( rate_label, 1, 0, 0 );
+ trans_layout->addWidget( trans_rate_label, 1, 1, Qt::AlignRight );
+
+ transfer_widget->setEnabled( false );
+
+ layout->addWidget( source_label, 0, 0, 0 );
+ layout->addWidget( source, 0, 1, 0 );
+ layout->addWidget( destination_label, 1, 0, 0 );
+ layout->addWidget( destination, 1, 1, 0 );
+ layout->addMultiCellWidget( current_file, 2, 2, 0, 1, 0 );
+ layout->addMultiCellWidget( individual, 3, 3, 0, 1, 0 );
+ layout->addMultiCellWidget( total, 4, 4, 0, 1, 0 );
+ layout->addMultiCellWidget( transfer_widget, 5, 6, 0, 1, 0 );
+
+ // Connections
+ connect( Smb4KCore::synchronizer(), SIGNAL( progress( const Smb4KSynchronizationInfo & ) ),
+ this, SLOT( slotProgress( const Smb4KSynchronizationInfo & ) ) );
+
+ connect( Smb4KCore::synchronizer(), SIGNAL( finished() ),
+ this, SLOT( slotSynchronizationFinished() ) );
+
+
+ setFixedSize( (sizeHint().width() > 350 ? sizeHint().width() : 350), sizeHint().height() );
+}
+
+
+Smb4KSynchronizationDialog::~Smb4KSynchronizationDialog()
+{
+ // Do *not* delete the share object here.
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+
+void Smb4KSynchronizationDialog::slotUser1()
+{
+ // Synchronize!
+
+ // Disable the URL requesters but in a way, that the information
+ // proviced in them is still readable:
+ KURLRequester *source = static_cast<KURLRequester *>( child( "SourceURL", "KURLRequester", true ) );
+ source->lineEdit()->setReadOnly( true );
+ source->button()->setEnabled( false );
+
+ KURLRequester *destination = static_cast<KURLRequester *>( child( "DestinationURL", "KURLRequester", true ) );
+ destination->lineEdit()->setReadOnly( true );
+ destination->button()->setEnabled( false );
+
+ QWidget *transfer_widget = static_cast<QWidget *>( child( "TransferInfoWidget", "QWidget", true ) );
+ transfer_widget->setEnabled( true );
+
+ enableButton( User1, false );
+ enableButton( User2, false );
+
+ // Enable the progress bars and the information widgets:
+ static_cast<KProgress *>( child( "IndividualProgress", "KProgress", true ) )->setEnabled( true );
+ static_cast<KProgress *>( child( "TotalProgress", "KProgress", true ) )->setEnabled( true );
+
+ Smb4KCore::synchronizer()->synchronize( source->url(), destination->url() );
+}
+
+
+void Smb4KSynchronizationDialog::slotUser2()
+{
+ // Swap URLs.
+
+ KURLRequester *source = static_cast<KURLRequester *>( child( "SourceURL", "KURLRequester", true ) );
+ KURLRequester *destination = static_cast<KURLRequester *>( child( "DestinationURL", "KURLRequester", true ) );
+
+ QString sourceURL = source->url();
+ QString destinationURL = destination->url();
+
+ source->setURL( destinationURL );
+ destination->setURL( sourceURL );
+}
+
+
+void Smb4KSynchronizationDialog::slotCancel()
+{
+ Smb4KCore::synchronizer()->abort();
+
+ KDialogBase::slotCancel();
+}
+
+
+void Smb4KSynchronizationDialog::slotProgress( const Smb4KSynchronizationInfo &info )
+{
+ KLineEdit *progress = static_cast<KLineEdit *>( child( "ProgressInfo", "KLineEdit", true ) );
+ KProgress *individual = static_cast<KProgress *>( child( "IndividualProgress", "KProgress", true ) );
+ KProgress *total = static_cast<KProgress *>( child( "TotalProgress", "KProgress", true ) );
+ QLabel *transferred = static_cast<QLabel *>( child( "FilesTransferred", "QLabel", true ) );
+ QLabel *rate = static_cast<QLabel *>( child( "TransferRate", "QLabel", true ) );
+
+ if ( !info.text().isEmpty() )
+ {
+ progress->setSqueezedText( info.text() );
+ }
+
+ if ( info.individualProgress() != -1 )
+ {
+ individual->setProgress( info.individualProgress() );
+ }
+
+ if ( info.totalProgress() != -1 )
+ {
+ total->setProgress( info.totalProgress() );
+ }
+
+ if ( info.totalFileNumber() != -1 && info.processedFileNumber() != -1 )
+ {
+ transferred->setText( QString( "%1 / %2" ).arg( info.processedFileNumber() ).arg( info.totalFileNumber() ) );
+ }
+
+ if ( !info.transferRate().isEmpty() )
+ {
+ rate->setText( info.transferRate() );
+ }
+}
+
+
+void Smb4KSynchronizationDialog::slotSynchronizationFinished()
+{
+ KProgress *individual = static_cast<KProgress *>( child( "IndividualProgress", "KProgress", true ) );
+ KProgress *total = static_cast<KProgress *>( child( "TotalProgress", "KProgress", true ) );
+
+ if ( individual && individual->progress() != 100 )
+ {
+ individual->setProgress( 100 );
+ }
+
+ if ( total && total->progress() != 100 )
+ {
+ total->setProgress( 100 );
+ }
+
+ // Change the "Cancel" button to a "Close" button.
+ setButtonGuiItem( Cancel, KStdGuiItem::close() );
+}
+
+#include "smb4ksynchronizationdialog.moc"
diff --git a/smb4k/dialogs/smb4ksynchronizationdialog.h b/smb4k/dialogs/smb4ksynchronizationdialog.h
new file mode 100644
index 0000000..c2c0c2d
--- /dev/null
+++ b/smb4k/dialogs/smb4ksynchronizationdialog.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ smb4ksynchronizationdialog - The synchronization dialog of Smb4K
+ -------------------
+ begin : Sa Mai 19 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSYNCHRONIZATIONDIALOG_H
+#define SMB4KSYNCHRONIZATIONDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kdialogbase.h>
+#include <kurlrequester.h>
+
+// forward declarations
+class Smb4KShare;
+class Smb4KSynchronizationInfo;
+
+/**
+ * This class provides a synchronization dialog. It contains URL requesters
+ * for the source and destination as well as widgets to monitor the process
+ * of the synchronization.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSynchronizationDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param share The share item
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this dialog
+ */
+ Smb4KSynchronizationDialog( Smb4KShare *share, QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSynchronizationDialog();
+
+ protected slots:
+ /**
+ * Reimplemented from KDialogBase. This slot starts the
+ * synchronization.
+ */
+ void slotUser1();
+
+ /**
+ * Reimplemented from KDialogBase. This slot swaps the
+ * paths of the source and destination.
+ */
+ void slotUser2();
+
+ /**
+ * Reimplemented from KDialogBase. This slot aborts the
+ * current synchronization and exists the dialog.
+ */
+ void slotCancel();
+
+ /**
+ * This slot receives information about the progress of the
+ * current synchronization and puts it into the dialog.
+ *
+ * @param info Information about the progress of the
+ * current synchronization process.
+ */
+ void slotProgress( const Smb4KSynchronizationInfo &info );
+
+ /**
+ * This slot is invoked when the synchronization has finished.
+ * It is connected to the Smb4KSynchronizer::finished() signal.
+ */
+ void slotSynchronizationFinished();
+
+ private:
+ /**
+ * A pointer to the share object
+ */
+ Smb4KShare *m_share;
+};
+
+#endif
diff --git a/smb4k/icons/Makefile.am b/smb4k/icons/Makefile.am
new file mode 100644
index 0000000..5f3734f
--- /dev/null
+++ b/smb4k/icons/Makefile.am
@@ -0,0 +1,22 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = cr16-app-smb4k.png cr32-app-smb4k.png cr48-app-smb4k.png cr64-app-smb4k.png
+
+install-data-local:
+ $(mkinstalldirs) $(kde_icondir)/crystalsvg/16x16/apps/
+ $(INSTALL_DATA) $(srcdir)/cr16-app-smb4k.png $(kde_icondir)/crystalsvg/16x16/apps/smb4k.png
+ $(mkinstalldirs) $(kde_icondir)/crystalsvg/32x32/apps/
+ $(INSTALL_DATA) $(srcdir)/cr32-app-smb4k.png $(kde_icondir)/crystalsvg/32x32/apps/smb4k.png
+ $(mkinstalldirs) $(kde_icondir)/crystalsvg/48x48/apps/
+ $(INSTALL_DATA) $(srcdir)/cr48-app-smb4k.png $(kde_icondir)/crystalsvg/48x48/apps/smb4k.png
+ $(mkinstalldirs) $(kde_icondir)/crystalsvg/64x64/apps/
+ $(INSTALL_DATA) $(srcdir)/cr64-app-smb4k.png $(kde_icondir)/crystalsvg/64x64/apps/smb4k.png
+
+uninstall-local:
+ -rm -f $(kde_icondir)/crystalsvg/16x16/apps/smb4k.png
+ -rm -f $(kde_icondir)/crystalsvg/32x32/apps/smb4k.png
+ -rm -f $(kde_icondir)/crystalsvg/48x48/apps/smb4k.png
+ -rm -f $(kde_icondir)/crystalsvg/64x64/apps/smb4k.png
+
+####### kdevelop will overwrite this part!!! (end)############
diff --git a/smb4k/icons/cr16-app-smb4k.png b/smb4k/icons/cr16-app-smb4k.png
new file mode 100644
index 0000000..dfd36fb
--- /dev/null
+++ b/smb4k/icons/cr16-app-smb4k.png
Binary files differ
diff --git a/smb4k/icons/cr32-app-smb4k.png b/smb4k/icons/cr32-app-smb4k.png
new file mode 100644
index 0000000..3712c0e
--- /dev/null
+++ b/smb4k/icons/cr32-app-smb4k.png
Binary files differ
diff --git a/smb4k/icons/cr48-app-smb4k.png b/smb4k/icons/cr48-app-smb4k.png
new file mode 100644
index 0000000..789fcb1
--- /dev/null
+++ b/smb4k/icons/cr48-app-smb4k.png
Binary files differ
diff --git a/smb4k/icons/cr64-app-smb4k.png b/smb4k/icons/cr64-app-smb4k.png
new file mode 100644
index 0000000..5a33038
--- /dev/null
+++ b/smb4k/icons/cr64-app-smb4k.png
Binary files differ
diff --git a/smb4k/iconview/Makefile.am b/smb4k/iconview/Makefile.am
new file mode 100644
index 0000000..ec51fb2
--- /dev/null
+++ b/smb4k/iconview/Makefile.am
@@ -0,0 +1,16 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libsmb4ksharesiconview.la
+libsmb4ksharesiconview_la_SOURCES = smb4ksharesiconview.cpp \
+ smb4ksharesiconview_part.cpp smb4ksharesiconviewitem.cpp \
+ smb4ksharesiconviewtooltip.cpp
+libsmb4ksharesiconview_la_LDFLAGS = -module -no-undefined $(all_libraries)
+noinst_HEADERS = smb4ksharesiconview.h smb4ksharesiconview_part.h \
+ smb4ksharesiconviewitem.h smb4ksharesiconviewtooltip.h
+libsmb4ksharesiconview_la_LIBADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(top_builddir)/smb4k/dialogs/libsmb4kdialogs.la $(LIB_KIO) $(LIB_KDECORE) $(LIB_KDEUI) $(KDE_PLUGIN) $(LIB_KPARTS) \
+ $(LIB_QT)
+
+partrcdir = $(kde_datadir)/smb4ksharesiconviewpart
+partrc_DATA = smb4ksharesiconview_part.rc
diff --git a/smb4k/iconview/smb4ksharesiconview.cpp b/smb4k/iconview/smb4ksharesiconview.cpp
new file mode 100644
index 0000000..bb669e1
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconview.cpp
@@ -0,0 +1,271 @@
+/***************************************************************************
+ smb4ksharesiconview - This is the shares icon view of Smb4K.
+ -------------------
+ begin : Mo Dez 4 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <kdebug.h>
+#include <kurl.h>
+#include <kio/job.h>
+#include <kdeversion.h>
+
+// application specific includes
+#include "smb4ksharesiconview.h"
+#include "smb4ksharesiconviewitem.h"
+#include "smb4ksharesiconviewtooltip.h"
+#include "../core/smb4kshare.h"
+#include "../core/smb4ksettings.h"
+#include "../core/smb4kcore.h"
+
+
+Smb4KSharesIconView::Smb4KSharesIconView( QWidget *parent, const char *name )
+: KIconView( parent, name )
+{
+ setSelectionMode( KIconView::Single ); // If this is changed, revise dragObject() function.
+ setResizeMode( KIconView::Adjust );
+ setAutoArrange( true );
+ setSorting( true, true );
+ setItemsMovable( false );
+ setAcceptDrops( true );
+ setItemTextPos( KIconView::Bottom );
+ setMaxItemWidth( 150 );
+ setArrangement( KIconView::LeftToRight );
+ setWordWrapIconText( true );
+
+ m_tooltip = NULL;
+
+ // Connections:
+ connect( this, SIGNAL( pressed( QIconViewItem * ) ),
+ this, SLOT( slotPressed( QIconViewItem * ) ) );
+}
+
+
+Smb4KSharesIconView::~Smb4KSharesIconView()
+{
+ // The tool tip's parent is 0 and not this icon view.
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ }
+}
+
+
+void Smb4KSharesIconView::updateToolTip()
+{
+ if ( !m_tooltip )
+ {
+ return;
+ }
+
+ m_tooltip->update();
+}
+
+
+KURLDrag *Smb4KSharesIconView::dragObject()
+{
+ // Get the KURL of the item that is to be dragged:
+ KURL url = KURL( static_cast<Smb4KSharesIconViewItem *>( currentItem() )->shareObject()->canonicalPath() );
+
+ KURLDrag *drag = new KURLDrag( KURL::List::List( url ), this );
+ drag->setPixmap( DesktopIcon( "folder" ) );
+// drag->dragCopy();
+
+ return drag;
+}
+
+
+void Smb4KSharesIconView::startDrag()
+{
+ // Kill the tooltip, so it is not in the way:
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+
+ if ( !Smb4KSettings::enableDragSupport() )
+ {
+ return;
+ }
+
+ KIconView::startDrag();
+}
+
+
+void Smb4KSharesIconView::contentsDragEnterEvent( QDragEnterEvent *e )
+{
+ e->accept( Smb4KSettings::enableDropSupport() );
+}
+
+
+void Smb4KSharesIconView::contentsDragMoveEvent( QDragMoveEvent *e )
+{
+ QIconViewItem *item = findItem( e->pos() );
+
+ e->accept( Smb4KSettings::enableDropSupport() && item );
+}
+
+
+void Smb4KSharesIconView::contentsDropEvent( QDropEvent *e )
+{
+ QIconViewItem *item = findItem( e->pos() );
+ KURL::List src;
+
+ // Do we have to stop here?
+ if ( !Smb4KSettings::enableDropSupport() ||
+ !item ||
+ !KURLDrag::decode( e, src ) )
+ {
+ e->ignore();
+
+ return;
+ }
+
+ KURL dest;
+ dest.setPath( static_cast<Smb4KSharesIconViewItem *>( item )->shareObject()->canonicalPath() );
+
+ // Deny dropping if we dropped something on itself.
+ // This was inspired by KonqOperations::doDrop() function.
+ for ( KURL::List::Iterator it = src.begin(); it != src.end(); ++it )
+ {
+ if ( dest.equals( *it, true ) )
+ {
+ if ( e->source() == this || e->source()->parent() == this )
+ {
+ e->ignore();
+
+ return;
+ }
+ }
+ }
+
+ // We only allow copying:
+ KIO::CopyJob *job = KIO::copy( src, dest, true );
+ job->setAutoErrorHandlingEnabled( true, NULL );
+#if KDE_VERSION_MAJOR >= 3 && KDE_VERSION_MINOR >= 5
+ job->setAutoWarningHandlingEnabled( true );
+#endif
+}
+
+
+void Smb4KSharesIconView::contentsMouseMoveEvent( QMouseEvent *e )
+{
+ m_pos = e->globalPos();
+
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( findItem( e->pos() ) );
+
+ if ( item )
+ {
+ if ( m_tooltip )
+ {
+ // Check if tool tip is still valid:
+ if ( m_tooltip->item() != item )
+ {
+ delete m_tooltip;
+
+ if ( hasMouse() && Smb4KSettings::showShareToolTip() )
+ {
+ m_tooltip = new Smb4KSharesIconViewToolTip( item );
+
+ QTimer::singleShot( 2000, this, SLOT( slotShowToolTip() ) );
+ }
+ else
+ {
+ m_tooltip = NULL;
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ }
+ else
+ {
+ // Create new tool tip:
+ if ( hasMouse() && Smb4KSettings::showShareToolTip() )
+ {
+ m_tooltip = new Smb4KSharesIconViewToolTip( item );
+
+ QTimer::singleShot( 2000, this, SLOT( slotShowToolTip() ) );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ }
+ else
+ {
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+ }
+
+ KIconView::contentsMouseMoveEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSharesIconView::slotPressed( QIconViewItem *item )
+{
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+
+ if ( !item )
+ {
+ // Clear the selection if the user clicked onto the
+ // viewport:
+ clearSelection();
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KSharesIconView::slotShowToolTip()
+{
+ if ( m_tooltip && hasMouse() && Smb4KSettings::showShareToolTip() &&
+ (m_tooltip->item() == static_cast<Smb4KSharesIconViewItem *>( findItem( viewport()->mapFromGlobal( m_pos ) ) )) )
+ {
+ m_tooltip->showTip( m_pos );
+ }
+ else
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+}
+
+
+#include "smb4ksharesiconview.moc"
diff --git a/smb4k/iconview/smb4ksharesiconview.h b/smb4k/iconview/smb4ksharesiconview.h
new file mode 100644
index 0000000..048e23d
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconview.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+ smb4ksharesiconview - This is the shares icon view of Smb4K.
+ -------------------
+ begin : Mo Dez 4 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESICONVIEW_H
+#define SMB4KSHARESICONVIEW_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qvaluelist.h>
+
+// KDE includes
+#include <kiconview.h>
+#include <kurldrag.h>
+
+// forward declarations
+class Smb4KSharesIconViewItem;
+class Smb4KSharesIconViewToolTip;
+
+
+/**
+ * This widget class provides the shares icon view of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesIconView : public KIconView
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of the widget
+ */
+ Smb4KSharesIconView( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSharesIconView();
+
+ /**
+ * Update the tool tip if it exists. This function just executes
+ * Smb4KSharesListViewToolTip::update().
+ */
+ void updateToolTip();
+
+ protected:
+ /**
+ * Reimplemented (sort of) from QIconView to enable dragging. As QDragObject
+ * a KURLDrag will be returned.
+ *
+ * @returns a KURLDrag object.
+ */
+ KURLDrag *dragObject();
+
+ /**
+ * Reimplemented from QIconView to allow some actions to be carried
+ * out before the drag begins.
+ */
+ void startDrag();
+
+ /**
+ * Reimplemented from QIconView.
+ */
+ void contentsDragEnterEvent( QDragEnterEvent * );
+
+ /**
+ * Reimplemented from QIconView.
+ */
+ void contentsDragMoveEvent( QDragMoveEvent *e );
+
+ /**
+ * Reimplemented from QIconView.
+ */
+ void contentsDropEvent( QDropEvent *e );
+
+ /**
+ * Reimplemented from QIconView. This function is used to
+ * show the tooltips.
+ */
+ void contentsMouseMoveEvent( QMouseEvent *e );
+
+ protected slots:
+ /**
+ * This slot is connected to KIconView::pressed() and clears the selection
+ * if the user clicked on the viewport.
+ *
+ * @param item The QIconViewItem that the user clicked or NULL
+ * if he/she pressed a mouse button on the viewport.
+ */
+ void slotPressed( QIconViewItem *item );
+
+ /**
+ * This slot shows the tool tip for an icon view item.
+ */
+ void slotShowToolTip();
+
+ private:
+ /**
+ * The current global mouse position
+ */
+ QPoint m_pos;
+
+ /**
+ * The tool tip
+ */
+ Smb4KSharesIconViewToolTip *m_tooltip;
+};
+
+#endif
diff --git a/smb4k/iconview/smb4ksharesiconview_part.cpp b/smb4k/iconview/smb4ksharesiconview_part.cpp
new file mode 100644
index 0000000..0f47631
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconview_part.cpp
@@ -0,0 +1,573 @@
+/***************************************************************************
+ smb4ksharesview_part - This Part includes the shares icon view
+ of Smb4K.
+ -------------------
+ begin : Mo Dez 4 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// KDE includes
+#include <kglobal.h>
+#include <kstdaction.h>
+#include <klocale.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kaction.h>
+#include <kshortcut.h>
+#include <kdebug.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kactionclasses.h>
+
+// application specific includes
+#include "smb4ksharesiconview_part.h"
+#include "smb4ksharesiconview.h"
+#include "smb4ksharesiconviewitem.h"
+#include "../dialogs/smb4ksynchronizationdialog.h"
+#include "../core/smb4kshare.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4ksettings.h"
+
+
+KInstance *Smb4KSharesIconViewPartFactory::m_instance = 0L;
+KAboutData *Smb4KSharesIconViewPartFactory::m_about = 0L;
+
+
+Smb4KSharesIconViewPart::Smb4KSharesIconViewPart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name )
+: KParts::Part( parent, name )
+{
+ // First of all We need an instance:
+ setInstance( Smb4KSharesIconViewPartFactory::instance() );
+
+ // Set the XML file:
+ setXMLFile( "smb4ksharesiconview_part.rc" );
+
+ // Set the widget of this part:
+ m_widget = new Smb4KSharesIconView( parentWidget, widgetName );
+ setWidget( m_widget );
+
+ // Set up the actions.
+ // Do not put this before setWidget() or the shortcuts
+ // will not be shown.
+ setupActions();
+
+ // Import the shares:
+ slotMountedShares();
+
+ // Load settings:
+ loadSettings();
+
+ // Add some connections:
+ connect( Smb4KCore::mounter(), SIGNAL( updated() ),
+ this, SLOT( slotMountedShares() ) );
+
+ connect( Smb4KCore::synchronizer(), SIGNAL( state( int ) ),
+ this, SLOT( slotSynchronizationState( int ) ) );
+
+ connect( m_widget, SIGNAL( contextMenuRequested( QIconViewItem *, const QPoint & ) ),
+ this, SLOT( slotContextMenuRequested( QIconViewItem *, const QPoint & ) ) );
+
+ connect( m_widget, SIGNAL( selectionChanged( QIconViewItem * ) ),
+ this, SLOT( slotSelectionChanged( QIconViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( pressed( QIconViewItem * ) ),
+ this, SLOT( slotMouseButtonPressed( QIconViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( executed( QIconViewItem * ) ),
+ this, SLOT( slotFilemanager() ) );
+}
+
+
+Smb4KSharesIconViewPart::~Smb4KSharesIconViewPart()
+{
+}
+
+
+void Smb4KSharesIconViewPart::setupActions()
+{
+ // Create the actions:
+ KAction *unmount = new KAction( i18n( "&Unmount" ), "hdd_unmount", KShortcut( CTRL+Key_U ),
+ this, SLOT( slotUnmountShare() ),
+ actionCollection(), "unmount_action" );
+#ifdef __linux__
+ KAction *force = new KAction( i18n( "&Force Unmounting" ), "hdd_unmount", KShortcut( CTRL+Key_F ),
+ this, SLOT( slotForceUnmountShare() ),
+ actionCollection(), "force_unmount_action" );
+#endif
+ KAction *all = new KAction( i18n( "U&nmount All" ), "gear", KShortcut( CTRL+Key_N ),
+ this, SLOT( slotUnmountAllShares() ),
+ actionCollection(), "unmount_all_action" );
+ KAction *sync = new KAction( i18n( "S&ynchronize" ), "bottom", KShortcut( CTRL+Key_Y ),
+ this, SLOT( slotSynchronize() ),
+ actionCollection(), "synchronize_action" );
+ KAction *konsole = new KAction( i18n( "Open with Konso&le" ), "terminal", KShortcut( CTRL+Key_L ),
+ this, SLOT( slotKonsole() ),
+ actionCollection(), "konsole_action" );
+ KAction *konq = new KAction( i18n( "Open with &Konqueror" ), "kfm_home", KShortcut( CTRL+Key_K ),
+ this, SLOT( slotFilemanager() ),
+ actionCollection(), "filemanager_action" );
+
+ // Disable all actions for now:
+ unmount->setEnabled( false );
+#ifdef __linux__
+ force->setEnabled( false );
+#endif
+ all->setEnabled( false );
+ sync->setEnabled( false );
+ konsole->setEnabled( false );
+ konq->setEnabled( false );
+
+ // Insert the actions into the menu:
+ m_menu = new KActionMenu( this, "SharesIconViewMenu" );
+ m_menu->popupMenu()->insertTitle( SmallIcon( "hdd_mount" ), i18n( "Shares" ), 0 );
+ m_menu->insert( unmount, -1 );
+#ifdef __linux__
+ m_menu->insert( force, -1 );
+#endif
+ m_menu->insert( all, -1 );
+ m_menu->popupMenu()->insertSeparator( -1 );
+ m_menu->insert( sync, -1 );
+ m_menu->popupMenu()->insertSeparator( -1 );
+ m_menu->insert( konsole, -1 );
+ m_menu->insert( konq, -1 );
+}
+
+
+void Smb4KSharesIconViewPart::loadSettings()
+{
+#ifdef __linux__
+ actionCollection()->action( "force_unmount_action" )->setEnabled( Smb4KSettings::useForceUnmount() );
+#endif
+
+ // Change the text of the share:
+ for ( QIconViewItem *it = m_widget->firstItem(); it; it = it->nextItem() )
+ {
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( it );
+
+ if ( item )
+ {
+ item->setText( (Smb4KSettings::showMountPoint() ?
+ item->shareObject()->path() :
+ item->shareObject()->name()) );
+ }
+ }
+
+ // Enable/disable support for dropping:
+ m_widget->setAcceptDrops( Smb4KSettings::enableDropSupport() );
+
+ // Load or remove all foreign shares. The easiest way to do this
+ // is to invoke slotMountedShares():
+ slotMountedShares();
+}
+
+
+void Smb4KSharesIconViewPart::customEvent( QCustomEvent *e )
+{
+ switch ( e->type() )
+ {
+ case EVENT_LOAD_SETTINGS:
+ {
+ loadSettings();
+ slotMountedShares();
+
+ break;
+ }
+ case EVENT_SET_FOCUS:
+ {
+ KIconView *view = static_cast<KIconView *>( m_widget );
+
+ if ( view->count() != 0 )
+ {
+ view->setSelected( !view->currentItem() ?
+ view->firstItem() :
+ view->currentItem(), true, false );
+ }
+
+ view->setFocus();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ KParts::Part::customEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS (Smb4KSharesIconViewPart)
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSharesIconViewPart::slotContextMenuRequested( QIconViewItem *item, const QPoint &pos )
+{
+ if ( item )
+ {
+ m_menu->popupMenu()->changeTitle( 0, SmallIcon( "hdd_mount" ),
+ static_cast<Smb4KSharesIconViewItem *>( item )->shareObject()->name() );
+ }
+ else
+ {
+ m_menu->popupMenu()->changeTitle( 0, SmallIcon( "hdd_mount" ), i18n( "Shares" ) );
+ }
+
+ m_menu->popupMenu()->exec( pos, 0 );
+}
+
+
+void Smb4KSharesIconViewPart::slotSelectionChanged( QIconViewItem *item )
+{
+ // NOTE: Here we only enable or disable the KActions. All other things
+ // are done in the Smb4KSharesIconView class.
+
+ // This slot is used to enable or disable the actions when the user
+ // changes the item in the icon view. This slot won't be called when
+ // the user clicks on the view port!
+ if ( item )
+ {
+ actionCollection()->action( "unmount_action" )->setEnabled( true );
+#ifdef __linux__
+ actionCollection()->action( "force_unmount_action" )->setEnabled( Smb4KSettings::useForceUnmount() );
+#endif
+ actionCollection()->action( "unmount_all_action" )->setEnabled( true );
+
+ Smb4KShare *share = static_cast<Smb4KSharesIconViewItem *>( item )->shareObject();
+
+ if ( !share->isBroken() )
+ {
+ actionCollection()->action( "konsole_action" )->setEnabled( !Smb4KSettings::konsole().isEmpty() );
+ actionCollection()->action( "filemanager_action" )->setEnabled( true );
+ actionCollection()->action( "synchronize_action" )->setEnabled( !Smb4KSettings::rsync().isEmpty() &&
+ !Smb4KCore::synchronizer()->isRunning() );
+ }
+ else
+ {
+ actionCollection()->action( "konsole_action" )->setEnabled( false );
+ actionCollection()->action( "filemanager_action" )->setEnabled( false );
+ actionCollection()->action( "synchronize_action" )->setEnabled( false );
+ }
+ }
+ else
+ {
+ // Smb4KSharesIconViewPart::slotMouseButtonPressed()
+ }
+}
+
+
+void Smb4KSharesIconViewPart::slotMouseButtonPressed( QIconViewItem *item )
+{
+ // NOTE: Here we only enable or disable the KActions. All other things
+ // are done in the Smb4KSharesIconView class.
+
+ // Here we do all the stuff that cannot be done in
+ // Smb4KSharesIconViewPart::slotSelectionChanged()
+ if ( !item )
+ {
+ actionCollection()->action( "unmount_action" )->setEnabled( false );
+#ifdef __linux__
+ actionCollection()->action( "force_unmount_action" )->setEnabled( false );
+#endif
+ actionCollection()->action( "unmount_all_action" )->setEnabled( (m_widget->count() > 0) );
+ actionCollection()->action( "konsole_action" )->setEnabled( false );
+ actionCollection()->action( "filemanager_action" )->setEnabled( false );
+ actionCollection()->action( "synchronize_action" )->setEnabled( false );
+ }
+ else
+ {
+ // See Smb4KSharesIconViewPart::slotSelectionChanged()
+ }
+}
+
+
+void Smb4KSharesIconViewPart::slotMountedShares()
+{
+ // Get the list of shares:
+ QValueList<Smb4KShare *> list = Smb4KCore::mounter()->getShares();
+
+ // Update the view:
+ if ( !list.isEmpty() )
+ {
+ // Remove all obsolete items:
+ Smb4KSharesIconViewItem *test_item = static_cast<Smb4KSharesIconViewItem *>( m_widget->firstItem() );
+ Smb4KSharesIconViewItem *next_item = NULL;
+
+ while ( test_item )
+ {
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( test_item->shareObject()->path() );
+ next_item = static_cast<Smb4KSharesIconViewItem *>( test_item->nextItem() );
+
+ if( !share || (test_item->shareObject()->isForeign() && !Smb4KSettings::showAllShares()) )
+ {
+ delete test_item;
+ test_item = NULL;
+ }
+
+ test_item = next_item;
+ }
+
+ // Now process the entries in the list:
+ bool already_in_view = false;
+
+ for ( QValueListConstIterator<Smb4KShare *> it = list.begin(); it != list.end(); ++it )
+ {
+ // Check, whether the share is already in the list. Look for the
+ // mount point.
+ for ( Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( m_widget->firstItem() );
+ item; item = static_cast<Smb4KSharesIconViewItem *>( item->nextItem() ) )
+ {
+ if ( QString::compare( item->shareObject()->path(), (*it)->path() ) == 0 ||
+ QString::compare( item->shareObject()->canonicalPath(), (*it)->canonicalPath() ) == 0 )
+ {
+ // Replace the share object if something changed:
+ if ( !item->sameShareObject( *it ) )
+ {
+ item->replaceShareObject( *it );
+ }
+
+ already_in_view = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !already_in_view )
+ {
+ if ( !Smb4KSettings::showAllShares() && (*it)->isForeign() )
+ {
+ // If the user does not want to have foreign shares
+ // displayed continue.
+ continue;
+ }
+ else
+ {
+ // Put the new item into the icon view:
+ (void) new Smb4KSharesIconViewItem( *it, Smb4KSettings::showMountPoint(), m_widget );
+
+ continue;
+ }
+ }
+
+ already_in_view = false;
+ }
+
+ m_widget->sort( m_widget->sortDirection() );
+ }
+ else
+ {
+ m_widget->clear();
+ }
+
+ // Update the tool tip, if it exists:
+ if ( m_widget->count() != 0 )
+ {
+ m_widget->updateToolTip();
+ }
+
+ // Enable/disable the actions:
+ QIconViewItem *item = m_widget->currentItem();
+ bool have_selected_item = (item && item->isSelected());
+
+ actionCollection()->action( "unmount_action" )->setEnabled( have_selected_item );
+#ifdef __linux__
+ if ( Smb4KSettings::useForceUnmount() )
+ {
+ actionCollection()->action( "force_unmount_action" )->setEnabled( have_selected_item );
+ }
+ else
+ {
+ actionCollection()->action( "force_unmount_action" )->setEnabled( false );
+ }
+#endif
+ actionCollection()->action( "unmount_all_action" )->setEnabled( (m_widget->count() > 0) );
+ actionCollection()->action( "konsole_action" )->setEnabled( !Smb4KSettings::konsole().isEmpty() &&
+ have_selected_item );
+ actionCollection()->action( "filemanager_action" )->setEnabled( have_selected_item );
+ actionCollection()->action( "synchronize_action" )->setEnabled( !Smb4KSettings::rsync().isEmpty() &&
+ !Smb4KCore::synchronizer()->isRunning() &&
+ have_selected_item );
+}
+
+
+void Smb4KSharesIconViewPart::slotUnmountShare()
+{
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( m_widget->currentItem() );
+
+ if ( item )
+ {
+ Smb4KCore::mounter()->unmountShare( item->shareObject(), false );
+ }
+}
+
+
+void Smb4KSharesIconViewPart::slotForceUnmountShare()
+{
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( m_widget->currentItem() );
+
+ if ( item )
+ {
+ Smb4KCore::mounter()->unmountShare( item->shareObject(), true );
+ }
+}
+
+
+void Smb4KSharesIconViewPart::slotUnmountAllShares()
+{
+ Smb4KCore::mounter()->unmountAllShares();
+}
+
+
+void Smb4KSharesIconViewPart::slotSynchronize()
+{
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( m_widget->currentItem() );
+ Smb4KSynchronizationDialog *dlg = static_cast<Smb4KSynchronizationDialog *>( m_widget->child( "SynchronizationDialog", "Smb4KSynchronizationDialog", true ) );
+
+ if ( item && !item->shareObject()->isBroken() && !dlg )
+ {
+ dlg = new Smb4KSynchronizationDialog( item->shareObject(), m_widget, "SynchronizationDialog" );
+
+ dlg->show();
+ }
+}
+
+void Smb4KSharesIconViewPart::slotKonsole()
+{
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( m_widget->currentItem() );
+
+ if ( item && !item->shareObject()->isBroken() )
+ {
+ Smb4KCore::open( item->shareObject(), Smb4KCore::Konsole );
+ }
+}
+
+
+void Smb4KSharesIconViewPart::slotFilemanager()
+{
+ Smb4KSharesIconViewItem *item = static_cast<Smb4KSharesIconViewItem *>( m_widget->currentItem() );
+
+ if ( item )
+ {
+ // Workaround: The item is not selected if you execute it, so
+ // we have to do it here:
+// item->setSelected( true );
+
+ if ( !item->shareObject()->isBroken() )
+ {
+ Smb4KCore::open( item->shareObject(), Smb4KCore::Konqueror );
+ }
+ }
+}
+
+
+void Smb4KSharesIconViewPart::slotSynchronizationState( int state )
+{
+ switch ( state )
+ {
+ case SYNCHRONIZER_START:
+ {
+ actionCollection()->action( "synchronize_action" )->setEnabled( false );
+
+ break;
+ }
+ case SYNCHRONIZER_STOP:
+ {
+ actionCollection()->action( "synchronize_action" )->setEnabled( true );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// FACTORY STUFF
+/////////////////////////////////////////////////////////////////////////////
+
+Smb4KSharesIconViewPartFactory::Smb4KSharesIconViewPartFactory()
+: KParts::Factory()
+{
+}
+
+
+Smb4KSharesIconViewPartFactory::~Smb4KSharesIconViewPartFactory()
+{
+ delete m_instance;
+ delete m_about;
+
+ m_instance = 0L;
+}
+
+
+KParts::Part *Smb4KSharesIconViewPartFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
+QObject *parent, const char *name, const char *, const QStringList & )
+{
+ Smb4KSharesIconViewPart *obj = new Smb4KSharesIconViewPart( parentWidget, widgetName, parent, name );
+
+ // See if we are to be read-write or not
+// if (QCString(classname) == "KParts::ReadOnlyPart")
+// {
+// obj->setReadWrite(false);
+// }
+
+ return obj;
+}
+
+
+KInstance *Smb4KSharesIconViewPartFactory::instance()
+{
+ if( !m_instance )
+ {
+ m_about = new KAboutData( "smb4ksharesiconviewpart", I18N_NOOP( "Smb4KSharesIconViewPart" ), "1.0" );
+ m_about->addAuthor("Alexander Reinholdt", 0, "[email protected]");
+ m_about->setLicense( KAboutData::License_GPL );
+ m_instance = new KInstance( m_about );
+ }
+
+ return m_instance;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// INIT
+/////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+{
+ void *init_libsmb4ksharesiconview()
+ {
+ KGlobal::locale()->insertCatalogue( "smb4k" );
+ return new Smb4KSharesIconViewPartFactory;
+ }
+}
+
+
+#include "smb4ksharesiconview_part.moc"
diff --git a/smb4k/iconview/smb4ksharesiconview_part.h b/smb4k/iconview/smb4ksharesiconview_part.h
new file mode 100644
index 0000000..f9d482b
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconview_part.h
@@ -0,0 +1,232 @@
+/***************************************************************************
+ smb4ksharesview_part - This Part includes the shares icon view
+ of Smb4K.
+ -------------------
+ begin : Mo Dez 4 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESICONVIEW_PART_H
+#define SMB4KSHARESICONVIEW_PART_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kparts/part.h>
+#include <kparts/factory.h>
+
+// applications specific includes
+#include "smb4ksharesiconview.h"
+
+/**
+ * This is one of the parts of Smb4K. It contains the shares icon
+ * view.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesIconViewPart : public KParts::Part
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parentWidget The parent widget
+ *
+ * @param widgetName The name the widget should have
+ *
+ * @param parent The parent object
+ *
+ * @param name The name this object should have
+ */
+ Smb4KSharesIconViewPart( QWidget *parentWidget = 0, const char *widgetName = 0,
+ QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ virtual ~Smb4KSharesIconViewPart();
+
+ protected:
+ /**
+ * Reimplemented from KParts::Part.
+ */
+ void customEvent( QCustomEvent *e );
+
+ protected slots:
+ /**
+ * Opens a context menu over the icon view item @p item at position
+ * @p pos if requested.
+ *
+ * @param item The icon view item or NULL if the user clicked
+ * somewhere else.
+ *
+ * @param pos The position where the user clicked.
+ */
+ void slotContextMenuRequested( QIconViewItem *item, const QPoint & pos );
+
+ /**
+ * This slot is called when the selection in the icon view changed. It
+ * enables or disables the actions according to known options/states.
+ * Please note that it won't be invoked when the user clicked on the
+ * viewport. Use slotMouseButtonPressed() to also catch that event.
+ *
+ * @param item The icon view item that was selected
+ */
+ void slotSelectionChanged( QIconViewItem *item );
+
+ /**
+ * This slot is called when the user presses any mouse button somewhere
+ * in the icon view. It enables or disables the actions according to known
+ * options/states.
+ *
+ * @param item The icon view item that was clicked or NULL if the
+ * user clicked onto the viewport.
+ */
+ void slotMouseButtonPressed( QIconViewItem *item );
+
+ /**
+ * This slot is called by the Smb4KMounter::updated() signal and updates
+ * the icon view according to the list that is returned by Smb4KMounter::getShares().
+ */
+ void slotMountedShares();
+
+ /**
+ * This slot is connected to the 'Unmount action'. You will be able to
+ * unmount a certain share when activating this slot.
+ */
+ void slotUnmountShare();
+
+ /**
+ * This slot is connected to the 'Force Unmounting' action and is, thus,
+ * only useful under Linux, because only there the possibility for a forced
+ * (i.e. lazy) unmount exists.
+ *
+ * When activating this slot, the selected share will be unmounted, even if
+ * it is not accessible or the server already went offline.
+ */
+ void slotForceUnmountShare();
+
+ /**
+ * This slot is connected to the 'Unmount All' action. All shares - either of
+ * the user or that are present on the system (depending on the settings the
+ * user chose) - will be unmounted. Please note that Smb4KMounter::unmountAllShares()
+ * is invoked directly.
+ */
+ void slotUnmountAllShares();
+
+ /**
+ * This slot is connected to the 'Synchronize' action. The current item will be
+ * synchronized with a local copy (or vice versa) if you activate it.
+ */
+ void slotSynchronize();
+
+ /**
+ * This slot is connected to the 'Konsole' action. The mount point of the current
+ * share item will be opened in Konsole.
+ */
+ void slotKonsole();
+
+ /**
+ * This slot is connected to the 'Konqueror' action. The contents of the current
+ * share item will be opened in the file manager.
+ */
+ void slotFilemanager();
+
+ /**
+ * This slot is called by the synchronizer whenever the state of the synchronization
+ * process changed.
+ *
+ * @param state The state the synchronizer is in.
+ */
+ void slotSynchronizationState( int state );
+
+ private:
+ /**
+ * Set up the actions
+ */
+ void setupActions();
+
+ /**
+ * Load settings for the widget or the actions.
+ */
+ void loadSettings();
+
+ /**
+ * The icon view.
+ */
+ Smb4KSharesIconView *m_widget;
+
+ /**
+ * The action menu.
+ */
+ KActionMenu *m_menu;
+};
+
+
+class KInstance;
+class KAboutData;
+
+class Smb4KSharesIconViewPartFactory : public KParts::Factory
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ */
+ Smb4KSharesIconViewPartFactory();
+
+ /**
+ * The destructor
+ */
+ virtual ~Smb4KSharesIconViewPartFactory();
+
+ /**
+ * Reimplemented from KParts::Factory
+ */
+ virtual KParts::Part *createPartObject( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name,
+ const char *classname, const QStringList &args );
+
+ /**
+ * The instance
+ */
+ static KInstance *instance();
+
+ private:
+ /**
+ * The factory's instance.
+ */
+ static KInstance *m_instance;
+
+ /**
+ * The factory's KAboutData object
+ */
+ static KAboutData *m_about;
+};
+
+
+#endif
diff --git a/smb4k/iconview/smb4ksharesiconview_part.rc b/smb4k/iconview/smb4ksharesiconview_part.rc
new file mode 100644
index 0000000..dd82e5e
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconview_part.rc
@@ -0,0 +1,25 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="smb4ksharesiconview_part" version="1">
+<MenuBar>
+ <Menu name="shares"><text>&amp;Shares</text>
+ <Action name="unmount_action"/>
+ <Action name="force_unmount_action"/>
+ <Action name="unmount_all_action"/>
+ <Separator/>
+ <Action name="synchronize_action"/>
+ <Separator/>
+ <Action name="konsole_action"/>
+ <Action name="filemanager_action"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="sharesViewToolBar">
+ <Action name="unmount_action"/>
+ <Action name="force_unmount_action"/>
+ <Action name="unmount_all_action"/>
+ <Separator/>
+ <Action name="synchronize_action"/>
+ <Separator/>
+ <Action name="konsole_action"/>
+ <Action name="filemanager_action"/>
+</ToolBar>
+</kpartgui>
diff --git a/smb4k/iconview/smb4ksharesiconviewitem.cpp b/smb4k/iconview/smb4ksharesiconviewitem.cpp
new file mode 100644
index 0000000..c54a734
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconviewitem.cpp
@@ -0,0 +1,148 @@
+/***************************************************************************
+ smb4ksharesiconviewitem - The items for Smb4K's shares icon view.
+ -------------------
+ begin : Di Dez 5 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qpixmap.h>
+
+// KDE includes
+#include <kiconeffect.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4ksharesiconviewitem.h"
+#include "smb4ksharesiconview.h"
+
+Smb4KSharesIconViewItem::Smb4KSharesIconViewItem( Smb4KShare *share, bool mountpoint,
+ Smb4KSharesIconView *parent )
+: KIconViewItem( parent, QString::null ), m_share( *share ), m_mountpoint( mountpoint ),
+ m_initial_setup( false )
+{
+ setDropEnabled( true );
+ setDragEnabled( true );
+
+ m_loader = new KIconLoader();
+
+ setupItem( m_share, m_mountpoint );
+}
+
+
+Smb4KSharesIconViewItem::~Smb4KSharesIconViewItem()
+{
+ // Do not touch the Smb4KShare object!
+ delete m_loader;
+}
+
+
+void Smb4KSharesIconViewItem::paintItem( QPainter *p, const QColorGroup &cg )
+{
+ // Set the color of the item text:
+ QColorGroup colorgrp( cg );
+
+ if ( m_share.isForeign() )
+ {
+ colorgrp.setColor( QColorGroup::Text, Qt::gray );
+ }
+
+ QIconViewItem::paintItem( p, colorgrp );
+}
+
+
+bool Smb4KSharesIconViewItem::acceptDrop( const QMimeSource *source ) const
+{
+ if ( source->provides( "text/plain" ) )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+void Smb4KSharesIconViewItem::setupItem( const Smb4KShare &share, bool mountpoint )
+{
+ // Only do something here if either the item hasn't been set up
+ // yet, or share and mountpoint changed, respectively.
+ if ( !m_initial_setup || !m_share.equals( share ) || m_mountpoint != mountpoint )
+ {
+ if ( !m_initial_setup || m_share.isBroken() != share.isBroken() )
+ {
+ int icon_state = m_share.isForeign() ? KIcon::DisabledState : KIcon::DefaultState;
+
+ if ( m_share.isBroken() )
+ {
+ QImage over = m_loader->loadIcon( "button_cancel", KIcon::Desktop,
+ 0, icon_state, 0L, false ).convertToImage();
+ QImage src = m_loader->loadIcon( "hdd_mount", KIcon::Desktop,
+ 0, icon_state, 0L, false ).convertToImage();
+
+ KIconEffect e;
+ e.semiTransparent( over );
+ e.overlay( src, over );
+
+ m_pixmap = QPixmap( src );
+ }
+ else
+ {
+ m_pixmap = m_loader->loadIcon( "hdd_mount", KIcon::Desktop,
+ 0, icon_state, 0L, false );
+ }
+
+ setPixmap( m_pixmap );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ if ( !m_initial_setup || m_mountpoint != mountpoint )
+ {
+ setText( (m_mountpoint ? m_share.path() : m_share.name()) );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ m_initial_setup = true;
+ m_share = share;
+ m_mountpoint = mountpoint;
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+bool Smb4KSharesIconViewItem::sameShareObject( Smb4KShare *share )
+{
+ return m_share.equals( *share );
+}
+
+
+void Smb4KSharesIconViewItem::replaceShareObject( Smb4KShare *share )
+{
+ setupItem( *share, m_mountpoint );
+}
diff --git a/smb4k/iconview/smb4ksharesiconviewitem.h b/smb4k/iconview/smb4ksharesiconviewitem.h
new file mode 100644
index 0000000..c18360f
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconviewitem.h
@@ -0,0 +1,173 @@
+/***************************************************************************
+ smb4ksharesiconviewitem - The items for Smb4K's shares icon view.
+ -------------------
+ begin : Di Dez 5 2006
+ copyright : (C) 2006 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESICONVIEWITEM_H
+#define SMB4KSHARESICONVIEWITEM_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qpainter.h>
+#include <qpalette.h>
+
+// KDE includes
+#include <kiconview.h>
+#include <kiconloader.h>
+
+// application specific includes
+#include "../core/smb4kshare.h"
+
+// forward declarations
+class Smb4KSharesIconView;
+
+/**
+ * This class provides the items for the shares icon view
+ * of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesIconViewItem : public KIconViewItem
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param share The Smb4KShare object that represents the share.
+ *
+ * @param mountpoint Tells the item if the mount point instead of the
+ * share name should be shown. Default is FALSE.
+ *
+ * @param parent The parent widget of this item.
+ */
+ Smb4KSharesIconViewItem( Smb4KShare *share,
+ bool mountpoint = false,
+ Smb4KSharesIconView *parent = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSharesIconViewItem();
+
+ /**
+ * This function compares the encapsulated Smb4KShare object with @p item
+ * and returns TRUE if they contain equal values.
+ *
+ * @param item A Smb4KShare object that should be compared
+ *
+ * @returns TRUE if @p item has the same values stored as the
+ * encapsulated Smb4KShare object.
+ */
+ bool sameShareObject( Smb4KShare *share );
+
+ /**
+ * Replace the encapsulated Smb4KShare object. This function just passes
+ * the share object to setupItem() which does all the work.
+ *
+ * @param share The new Smb4KShare object
+ */
+ void replaceShareObject( Smb4KShare *share );
+
+ /**
+ * Returns a pointer to the share object that's represented by this item.
+ * You have to use it to access its data.
+ *
+ * @returns a pointer to a Smb4KShare object.
+ */
+ Smb4KShare *shareObject() { return &m_share; }
+
+ /**
+ * This function returns the desktop pixmap of this item.
+ *
+ * @returns the destop pixmap of this item.
+ */
+ const QPixmap &desktopPixmap() { return m_pixmap; }
+
+ protected:
+ /**
+ * Reimplemented from QIconViewItem.
+ *
+ * This function paints the icon text and uses Smb4KShare::isForeign() to
+ * determine the color (TRUE: gray, FALSE: the default color).
+ *
+ * @param p The painter
+ *
+ * @param cg The color group
+ */
+ void paintItem( QPainter *p,
+ const QColorGroup &cg );
+
+ /**
+ * Reimplemented from QIconViewItem.
+ *
+ * This function accepts or denies drops according to the contents of @p source.
+ *
+ * @param source The mime source
+ */
+ bool acceptDrop( const QMimeSource *source ) const;
+
+ private:
+ /**
+ * Set up the icon and text of the item with resepect to @p share and @p mountpoint.
+ *
+ * @param share The Smb4KShare object.
+ *
+ * @param mountpoint If TRUE, the mount point will be shown instead of the
+ * share name.
+ */
+ void setupItem( const Smb4KShare &share,
+ bool mountpoint = false );
+
+ /**
+ * The Smb4KShare object representing the share.
+ */
+ Smb4KShare m_share;
+
+ /**
+ * Tells us if the mount point instead of the share
+ * name should be shown.
+ */
+ bool m_mountpoint;
+
+ /**
+ * Tells us that the initial setup already happened.
+ */
+ bool m_initial_setup;
+
+ /**
+ * The icon loader for this item.
+ */
+ KIconLoader *m_loader;
+
+ /**
+ * The desktop pixmap
+ */
+ QPixmap m_pixmap;
+};
+
+#endif
+
diff --git a/smb4k/iconview/smb4ksharesiconviewtooltip.cpp b/smb4k/iconview/smb4ksharesiconviewtooltip.cpp
new file mode 100644
index 0000000..7f33fce
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconviewtooltip.cpp
@@ -0,0 +1,429 @@
+/***************************************************************************
+ smb4ksharesiconviewtooltip - Tool tip for the shares icon view.
+ -------------------
+ begin : Do Jan 4 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qtooltip.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qtimer.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4ksharesiconviewtooltip.h"
+#include "smb4ksharesiconviewitem.h"
+
+
+Smb4KSharesIconViewToolTip::Smb4KSharesIconViewToolTip( Smb4KSharesIconViewItem *item )
+: QLabel( 0, "SharesIconViewToolTip", WStyle_StaysOnTop | WStyle_Customize |
+WStyle_NoBorder | WStyle_Tool | WX11BypassWM | WDestructiveClose ), m_item( item )
+{
+ setPalette( QToolTip::palette() );
+ setLineWidth( 1 );
+ setMidLineWidth( 1 );
+ setFrameShape( Box );
+ setFrameShadow( Plain );
+ setMouseTracking( true );
+
+ m_layout = new QGridLayout( this );
+ m_layout->setMargin( 10 );
+ m_layout->setSpacing( 3 );
+
+ m_is_set_up = false;
+
+ m_free = NULL;
+ m_used = NULL;
+ m_total = NULL;
+ m_usage = NULL;
+ m_pixmap = NULL;
+
+ // We will set up the tip in the showTip() function.
+}
+
+
+Smb4KSharesIconViewToolTip::~Smb4KSharesIconViewToolTip()
+{
+ // Never touch the Smb4KSharesIconViewItem object here!
+}
+
+
+void Smb4KSharesIconViewToolTip::showTip( const QPoint &pos )
+{
+ if ( !m_item || isShown() )
+ {
+ return;
+ }
+
+ setupTip();
+
+ adjustSize();
+
+ QDesktopWidget *d = QApplication::desktop();
+ QPoint p( pos );
+
+ if ( p.x() + width() > d->width() )
+ {
+ p.setX( p.x() - width() - 5 );
+ }
+ else
+ {
+ p.setX( p.x() + 5 );
+ }
+
+ if ( p.y() + height() > d->height() )
+ {
+ p.setY( p.y() - height() - 5 );
+ }
+ else
+ {
+ p.setY( p.y() + 5 );
+ }
+
+ setGeometry( p.x(), p.y(), width(), height() );
+ polish();
+ show();
+ QTimer::singleShot( 10000, this, SLOT( slotHideToolTip() ) );
+}
+
+
+void Smb4KSharesIconViewToolTip::setupTip()
+{
+ if ( !m_item )
+ {
+ return;
+ }
+
+ m_layout->addWidget( new QLabel( i18n( "Share:" ), this ), 0, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->name(), this ), 0, 2, 0 );
+ m_layout->addWidget( new QLabel( i18n( "Mount point:" ), this ), 1, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->path(), this ), 1, 2, 0 );
+
+ if ( QString::compare( m_item->shareObject()->filesystem(), "smbfs" ) == 0 )
+ {
+ m_layout->addWidget( new QLabel( "Owner:", this ), 2, 1, 0 );
+ m_layout->addWidget( new QLabel( QString( "%1 - %2" ).arg( m_item->shareObject()->user(), m_item->shareObject()->group() ), this ), 2, 2, 0 );
+ }
+ else
+ {
+ m_layout->addWidget( new QLabel( "Login:", this ), 2, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->cifsLogin(), this ), 2, 2, 0 );
+ }
+
+ m_layout->addWidget( new QLabel( i18n( "File system:" ), this ), 3, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->filesystem().upper(), this ), 3, 2, 0 );
+
+ QFrame *line = new QFrame( this );
+ line->setLineWidth( 1 );
+ line->setMidLineWidth( 0 );
+ line->setFixedWidth( 100 );
+ line->setFrameShape( QFrame::HLine );
+ line->setFrameShadow( QFrame::Plain );
+
+ m_layout->addMultiCellWidget( line, 4, 4, 1, 2, Qt::AlignCenter );
+
+ // Prepare the disk usage stuff.
+ if ( !m_item->shareObject()->isBroken() )
+ {
+ QString total, free, used, total_dim, free_dim, used_dim;
+
+ if ( m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace() > 1024 )
+ {
+ double tmp_used = (m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace()) / 1024;
+ used_dim = "MB";
+
+ if ( tmp_used >= 1024 )
+ {
+ tmp_used = tmp_used / 1024;
+ used_dim = "GB";
+ }
+
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+ else
+ {
+ used_dim = "kB";
+ double tmp_used = m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace();
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->freeDiskSpace() >= 1024 )
+ {
+ double tmp_free = m_item->shareObject()->freeDiskSpace() / 1024;
+ free_dim = "MB";
+
+ if ( tmp_free >= 1024 )
+ {
+ tmp_free = tmp_free / 1024;
+ free_dim = "GB";
+ }
+
+ free = QString( "%1" ).arg( tmp_free, 0, 'f', 1 );
+ }
+ else
+ {
+ free_dim = "kB";
+ free = QString( "%1" ).arg( m_item->shareObject()->freeDiskSpace(), 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->totalDiskSpace() >= 1024 )
+ {
+ double tmp_total = m_item->shareObject()->totalDiskSpace() / 1024;
+ total_dim = "MB";
+
+ if ( tmp_total >= 1024 )
+ {
+ tmp_total = tmp_total / 1024;
+ total_dim = "GB";
+ }
+
+ total = QString( "%1" ).arg( tmp_total, 0, 'f', 1 );
+ }
+ else
+ {
+ total_dim = "kB";
+ total = QString( "%1" ).arg( m_item->shareObject()->totalDiskSpace(), 0, 'f', 1 );
+ }
+
+ m_layout->addWidget( new QLabel( i18n( "Free:" ), this, "FreeLabel" ), 5, 1, 0 );
+ m_free = new QLabel( QString( "%1 %2" ).arg( free, free_dim ), this );
+ m_layout->addWidget( m_free, 5, 2, 0 );
+
+ m_layout->addWidget( new QLabel( i18n( "Used:" ), this, "UsedLabel" ), 6, 1, 0 );
+ m_used = new QLabel( QString( "%1 %2" ).arg( used, used_dim ), this );
+ m_layout->addWidget( m_used, 6, 2, 0 );
+
+ m_layout->addWidget( new QLabel( i18n( "Total:" ), this, "TotalLabel" ), 7, 1, 0 );
+ m_total = new QLabel( QString( "%1 %2" ).arg( total, total_dim ), this );
+ m_layout->addWidget( m_total, 7, 2, 0 );
+
+ m_layout->addWidget( new QLabel( i18n( "Usage:" ), this, "UsageLabel" ), 8, 1, 0 );
+ m_usage = new QLabel( QString( "%1 %" ).arg( m_item->shareObject()->percentage(), 0, 'f', 1 ), this );
+ m_layout->addWidget( m_usage, 8, 2, 0 );
+ }
+ else
+ {
+ QLabel *error = new QLabel( i18n( "This share is inaccessible." ), this );
+
+ QFont font;
+ font.setItalic( true );
+
+ error->setFont( font );
+
+ m_layout->addMultiCellWidget( error, 5, 5, 1, 2, Qt::AlignCenter );
+ }
+
+ m_pixmap = new QLabel( this );
+ m_pixmap->setPixmap( m_item->desktopPixmap() );
+
+ m_layout->addMultiCellWidget( m_pixmap, 0, m_layout->numRows(), 0, 0, Qt::AlignCenter );
+
+ m_is_set_up = true;
+}
+
+
+void Smb4KSharesIconViewToolTip::update()
+{
+ if ( !m_is_set_up )
+ {
+ return;
+ }
+
+ // Only change the variable entries:
+ if ( !m_item->shareObject()->isBroken() )
+ {
+ QString total, free, used, total_dim, free_dim, used_dim;
+
+ if ( m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace() > 1024 )
+ {
+ double tmp_used = (m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace()) / 1024;
+ used_dim = "MB";
+
+ if ( tmp_used >= 1024 )
+ {
+ tmp_used = tmp_used / 1024;
+ used_dim = "GB";
+ }
+
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+ else
+ {
+ used_dim = "kB";
+ double tmp_used = m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace();
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->freeDiskSpace() >= 1024 )
+ {
+ double tmp_free = m_item->shareObject()->freeDiskSpace() / 1024;
+ free_dim = "MB";
+
+ if ( tmp_free >= 1024 )
+ {
+ tmp_free = tmp_free / 1024;
+ free_dim = "GB";
+ }
+
+ free = QString( "%1" ).arg( tmp_free, 0, 'f', 1 );
+ }
+ else
+ {
+ free_dim = "kB";
+ free = QString( "%1" ).arg( m_item->shareObject()->freeDiskSpace(), 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->totalDiskSpace() >= 1024 )
+ {
+ double tmp_total = m_item->shareObject()->totalDiskSpace() / 1024;
+ total_dim = "MB";
+
+ if ( tmp_total >= 1024 )
+ {
+ tmp_total = tmp_total / 1024;
+ total_dim = "GB";
+ }
+
+ total = QString( "%1" ).arg( tmp_total, 0, 'f', 1 );
+ }
+ else
+ {
+ total_dim = "kB";
+ total = QString( "%1" ).arg( m_item->shareObject()->totalDiskSpace(), 0, 'f', 1 );
+ }
+
+ m_free->setText( QString( "%1 %2" ).arg( free, free_dim ) );
+ m_used->setText( QString( "%1 %2" ).arg( used, used_dim ) );
+ m_total->setText( QString( "%1 %2" ).arg( total, total_dim ) );
+ m_usage->setText( QString( "%1 %" ).arg( m_item->shareObject()->percentage(), 0, 'f', 1 ) );
+ }
+ else
+ {
+ QLabel *free_label = static_cast<QLabel *>( child( "FreeLabel", "QLabel" ) );
+
+ if ( free_label )
+ {
+ m_layout->remove( free_label );
+ delete free_label;
+ }
+
+ if ( m_free )
+ {
+ m_layout->remove( m_free );
+ delete m_free;
+ m_free = NULL;
+ }
+
+ QLabel *used_label = static_cast<QLabel *>( child( "UsedLabel", "QLabel" ) );
+
+ if ( used_label )
+ {
+ m_layout->remove( used_label );
+ delete used_label;
+ }
+
+ if ( m_used )
+ {
+ m_layout->remove( m_used );
+ delete m_used;
+ m_used = NULL;
+ }
+
+ QLabel *total_label = static_cast<QLabel *>( child( "TotalLabel", "QLabel" ) );
+
+ if ( total_label )
+ {
+ m_layout->remove( total_label );
+ delete total_label;
+ }
+
+ if ( m_total )
+ {
+ m_layout->remove( m_total );
+ delete m_total;
+ m_total = NULL;
+ }
+
+ QLabel *usage_label = static_cast<QLabel *>( child( "UsageLabel", "QLabel" ) );
+
+ if ( usage_label )
+ {
+ m_layout->remove( usage_label );
+ delete usage_label;
+ }
+
+ if ( m_usage )
+ {
+ m_layout->remove( m_usage );
+ delete m_usage;
+ m_usage = NULL;
+ }
+
+ QFont font;
+ font.setItalic( true );
+
+ QLabel *error = new QLabel( i18n( "This share is inaccessible." ), this );
+ error->setFont( font );
+ error->show();
+
+ m_layout->remove( m_pixmap );
+ m_pixmap->setPixmap( m_item->desktopPixmap() );
+
+ m_layout->addMultiCellWidget( error, 5, 5, 1, 2, Qt::AlignCenter );
+ m_layout->addMultiCellWidget( m_pixmap, 0, 5, 0, 0, Qt::AlignCenter );
+ }
+
+ adjustSize();
+}
+
+
+void Smb4KSharesIconViewToolTip::mousePressEvent( QMouseEvent *e )
+{
+ hide();
+ QLabel::mousePressEvent( e );
+}
+
+
+void Smb4KSharesIconViewToolTip::leaveEvent( QEvent *e )
+{
+ hide();
+ QLabel::leaveEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSharesIconViewToolTip::slotHideToolTip()
+{
+ if ( isShown() )
+ {
+ hide();
+ }
+}
+
+#include "smb4ksharesiconviewtooltip.moc"
diff --git a/smb4k/iconview/smb4ksharesiconviewtooltip.h b/smb4k/iconview/smb4ksharesiconviewtooltip.h
new file mode 100644
index 0000000..f8b1c99
--- /dev/null
+++ b/smb4k/iconview/smb4ksharesiconviewtooltip.h
@@ -0,0 +1,160 @@
+/***************************************************************************
+ smb4ksharesiconviewtooltip - Tool tip for the shares icon view.
+ -------------------
+ begin : Do Jan 4 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESICONVIEWTOOLTIP_H
+#define SMB4KSHARESICONVIEWTOOLTIP_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qlabel.h>
+#include <qpoint.h>
+#include <qlayout.h>
+
+// Forward declarations:
+class Smb4KSharesIconViewItem;
+
+/**
+ * This class provides the tool tip for the shares icon view
+ * of Smb4K. It shows information about the associated share.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesIconViewToolTip : public QLabel
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * Please note that the parent of the tool tip will be '0' and
+ * not the parent widget of @p item. Thus, you have to delete the
+ * tool tip object in the destructor of the parent widget.
+ *
+ * @param item The item for which the tool tip should be shown.
+ */
+ Smb4KSharesIconViewToolTip( Smb4KSharesIconViewItem *item );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSharesIconViewToolTip();
+
+ /**
+ * Show the tool tip. Please note that the tool tip will not be
+ * shown exactly at position @p pos but with a displacement of 5
+ * pixels in x- and y-direction.
+ *
+ * @param pos The global position of the mouse pointer.
+ */
+ void showTip( const QPoint &pos );
+
+ /**
+ * The shares icon view item for which the tool tip should be shown.
+ *
+ * @returns a pointer to a Smb4KSharesIconViewItem object.
+ */
+ Smb4KSharesIconViewItem *item() { return m_item; }
+
+ /**
+ * Update the tool tip by rereading the contents of the shareObject()
+ * provided by the Smb4KSharesIconViewItem. This function only changes
+ * those entries that might have changed such as the free and used disk
+ * space and the usage.
+ */
+ void update();
+
+ protected:
+ /**
+ * Reimplemented from QLabel.
+ */
+ void mousePressEvent( QMouseEvent *e );
+
+ /**
+ * Reimplemented from QLabel.
+ */
+ void leaveEvent( QEvent *e );
+
+ protected slots:
+ /**
+ * This slot hides the tool tip after 10 sec.
+ */
+ void slotHideToolTip();
+
+ private:
+ /**
+ * The item for which the tool tip should be shown
+ */
+ Smb4KSharesIconViewItem *m_item;
+
+ /**
+ * The layout of the tool tip.
+ */
+ QGridLayout *m_layout;
+
+ /**
+ * This function sets up the tool tip.
+ */
+ void setupTip();
+
+ /**
+ * Tells us if the tool tip has already been set up.
+ */
+ bool m_is_set_up;
+
+ /**
+ * This label holds the variable value of the free
+ * space left on the share.
+ */
+ QLabel *m_free;
+
+ /**
+ * This label holds the variable value of the used
+ * space on the share.
+ */
+ QLabel *m_used;
+
+ /**
+ * This label holds the value of the total space
+ * available on the share.
+ */
+ QLabel *m_total;
+
+ /**
+ * This label holds the variable value of the usage
+ */
+ QLabel *m_usage;
+
+ /**
+ * This label holds the pixmap.
+ */
+ QLabel *m_pixmap;
+};
+
+#endif
diff --git a/smb4k/listview/Makefile.am b/smb4k/listview/Makefile.am
new file mode 100644
index 0000000..385f7ed
--- /dev/null
+++ b/smb4k/listview/Makefile.am
@@ -0,0 +1,14 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libsmb4kshareslistview.la
+libsmb4kshareslistview_la_LIBADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(top_builddir)/smb4k/dialogs/libsmb4kdialogs.la $(LIB_KIO) $(LIB_KDECORE) $(LIB_KDEUI) $(KDE_PLUGIN) $(LIB_KPARTS) \
+ $(LIB_QT)
+
+partrcdir = $(kde_datadir)/smb4kshareslistviewpart
+partrc_DATA = smb4kshareslistview_part.rc
+libsmb4kshareslistview_la_SOURCES = smb4kshareslistview.cpp \
+ smb4kshareslistview_part.cpp smb4kshareslistviewitem.cpp smb4kshareslistviewtooltip.cpp
+noinst_HEADERS = smb4kshareslistview.h smb4kshareslistview_part.h \
+ smb4kshareslistviewitem.h smb4kshareslistviewtooltip.h
diff --git a/smb4k/listview/smb4kshareslistview.cpp b/smb4k/listview/smb4kshareslistview.cpp
new file mode 100644
index 0000000..8efc550
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistview.cpp
@@ -0,0 +1,275 @@
+/***************************************************************************
+ smb4kshareslistview - This is the shares list view of Smb4K.
+ -------------------
+ begin : Sa Jun 30 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qtimer.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kurl.h>
+#include <kio/job.h>
+#include <kdeversion.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kshareslistview.h"
+#include "smb4kshareslistviewitem.h"
+#include "smb4kshareslistviewtooltip.h"
+#include "../core/smb4ksettings.h"
+
+Smb4KSharesListView::Smb4KSharesListView( QWidget *parent, const char *name )
+: KListView( parent, name )
+{
+ setSelectionModeExt( KListView::Single );
+ setAllColumnsShowFocus( false );
+ setItemsMovable( false );
+ setAcceptDrops( true );
+
+ // Set up columns
+ addColumn( i18n( "Item" ) );
+ addColumn( i18n( "Owner" ) );
+#ifndef __FreeBSD__
+ addColumn( i18n( "Login" ) );
+#endif
+ addColumn( i18n( "File System" ) );
+ addColumn( i18n( "Free" ) );
+ addColumn( i18n( "Used" ) );
+ addColumn( i18n( "Total" ) );
+ addColumn( i18n( "Usage" ) );
+
+ // Set alignment
+ setColumnAlignment( Free, Qt::AlignRight );
+ setColumnAlignment( Used, Qt::AlignRight );
+ setColumnAlignment( Total, Qt::AlignRight );
+ setColumnAlignment( Usage, Qt::AlignRight );
+
+ m_tooltip = NULL;
+
+ // Connections:
+ connect( this, SIGNAL( pressed( QListViewItem * ) ),
+ this, SLOT( slotPressed( QListViewItem * ) ) );
+}
+
+
+Smb4KSharesListView::~Smb4KSharesListView()
+{
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ }
+}
+
+
+void Smb4KSharesListView::updateToolTip()
+{
+ if ( !m_tooltip )
+ {
+ return;
+ }
+
+ m_tooltip->update();
+}
+
+
+KURLDrag *Smb4KSharesListView::dragObject()
+{
+ // Get the KURL of the item that is to be dragged:
+ KURL url = KURL( static_cast<Smb4KSharesListViewItem *>( currentItem() )->shareObject()->canonicalPath() );
+
+ KURLDrag *drag = new KURLDrag( KURL::List::List( url ), this );
+ drag->setPixmap( DesktopIcon( "folder" ) );
+// drag->dragCopy();
+
+ return drag;
+}
+
+
+void Smb4KSharesListView::startDrag()
+{
+ if ( !Smb4KSettings::enableDragSupport() )
+ {
+ return;
+ }
+
+ KListView::startDrag();
+}
+
+
+void Smb4KSharesListView::contentsDragEnterEvent( QDragEnterEvent *e )
+{
+ e->accept( Smb4KSettings::enableDropSupport() );
+}
+
+
+void Smb4KSharesListView::contentsDragMoveEvent( QDragMoveEvent *e )
+{
+ QListViewItem *item = itemAt( contentsToViewport( e->pos() ) );
+
+ e->accept( Smb4KSettings::enableDropSupport() && item );
+}
+
+
+void Smb4KSharesListView::contentsDropEvent( QDropEvent *e )
+{
+ QListViewItem *item = itemAt( contentsToViewport( e->pos() ) );
+ KURL::List src;
+
+ // Do we have to stop here?
+ if ( !Smb4KSettings::enableDropSupport() ||
+ !item ||
+ !KURLDrag::decode( e, src ) )
+ {
+ e->ignore();
+
+ return;
+ }
+
+ KURL dest;
+ dest.setPath( static_cast<Smb4KSharesListViewItem *>( item )->shareObject()->canonicalPath() );
+
+ // Deny dropping if we dropped something on itself.
+ // This was inspired by KonqOperations::doDrop() function.
+ for ( KURL::List::Iterator it = src.begin(); it != src.end(); ++it )
+ {
+ if ( dest.equals( *it, true ) )
+ {
+ if ( e->source() == this || e->source()->parent() == this )
+ {
+ e->ignore();
+
+ return;
+ }
+ }
+ }
+
+ // We only allow copying:
+ KIO::CopyJob *job = KIO::copy( src, dest, true );
+ job->setAutoErrorHandlingEnabled( true, NULL );
+#if KDE_VERSION_MAJOR >= 3 && KDE_VERSION_MINOR >= 5
+ job->setAutoWarningHandlingEnabled( true );
+#endif
+}
+
+
+void Smb4KSharesListView::contentsMouseMoveEvent( QMouseEvent *e )
+{
+ m_pos = e->globalPos();
+
+ Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( itemAt( contentsToViewport( e->pos() ) ) );
+
+ if ( item )
+ {
+ if ( m_tooltip )
+ {
+ // Check if tool tip is still valid:
+ if ( m_tooltip->item() != item )
+ {
+ delete m_tooltip;
+
+ if ( hasMouse() && Smb4KSettings::showShareToolTip() )
+ {
+ m_tooltip = new Smb4KSharesListViewToolTip( item );
+
+ QTimer::singleShot( 2000, this, SLOT( slotShowToolTip() ) );
+ }
+ else
+ {
+ m_tooltip = NULL;
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ }
+ else
+ {
+ // Create new tool tip:
+ if ( hasMouse() && Smb4KSettings::showShareToolTip() )
+ {
+ m_tooltip = new Smb4KSharesListViewToolTip( item );
+
+ QTimer::singleShot( 2000, this, SLOT( slotShowToolTip() ) );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ }
+ else
+ {
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+ }
+
+ KListView::contentsMouseMoveEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSharesListView::slotPressed( QListViewItem *item )
+{
+ if ( m_tooltip )
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+
+ if ( !item )
+ {
+ // Clear the selection if the user clicked onto the
+ // viewport:
+ clearSelection();
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KSharesListView::slotShowToolTip()
+{
+ if ( m_tooltip && hasMouse() && Smb4KSettings::showShareToolTip() &&
+ (m_tooltip->item() == static_cast<Smb4KSharesListViewItem *>( itemAt( viewport()->mapFromGlobal( m_pos ) ) )) )
+ {
+ m_tooltip->showTip( m_pos );
+ }
+ else
+ {
+ delete m_tooltip;
+ m_tooltip = NULL;
+ }
+}
+
+#include "smb4kshareslistview.moc"
diff --git a/smb4k/listview/smb4kshareslistview.h b/smb4k/listview/smb4kshareslistview.h
new file mode 100644
index 0000000..df1c265
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistview.h
@@ -0,0 +1,157 @@
+/***************************************************************************
+ smb4kshareslistview - This is the shares list view of Smb4K.
+ -------------------
+ begin : Sa Jun 30 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESLISTVIEW_H
+#define SMB4KSHARESLISTVIEW_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <klistview.h>
+#include <kurldrag.h>
+
+// forward declarations
+class Smb4KSharesListViewToolTip;
+
+/**
+ * This widget class provides the shares list view of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesListView : public KListView
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this object
+ */
+ Smb4KSharesListView( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSharesListView();
+
+ /**
+ * Enumeration for the columns.
+ */
+#ifndef __FreeBSD__
+ enum Columns { Item = 0,
+ Owner = 1,
+ Login = 2,
+ FileSystem = 3,
+ Free = 4,
+ Used = 5,
+ Total = 6,
+ Usage = 7 };
+#else
+ enum Columns { Item = 0,
+ Owner = 1,
+ FileSystem = 2,
+ Free = 3,
+ Used = 4,
+ Total = 5,
+ Usage = 6 };
+#endif
+
+ /**
+ * Update the tool tip if it exists. This function just executes
+ * Smb4KSharesListViewToolTip::update().
+ */
+ void updateToolTip();
+
+ protected:
+ /**
+ * Reimplemented (sort of) from QListView to enable dragging. As QDragObject
+ * a KURLDrag will be returned.
+ *
+ * @returns a KURLDrag object.
+ */
+ KURLDrag *dragObject();
+
+ /**
+ * Reimplemented from QListView to allow some actions to be carried
+ * out before the drag begins.
+ */
+ void startDrag();
+
+ /**
+ * Reimplemented from QListView.
+ */
+ void contentsDragEnterEvent( QDragEnterEvent * );
+
+ /**
+ * Reimplemented from QListView.
+ */
+ void contentsDragMoveEvent( QDragMoveEvent *e );
+
+ /**
+ * Reimplemented from QListView.
+ */
+ void contentsDropEvent( QDropEvent *e );
+
+ /**
+ * Reimplemented from QListView. This function is used to
+ * show the tooltips.
+ */
+ void contentsMouseMoveEvent( QMouseEvent *e );
+
+ protected slots:
+ /**
+ * This slot is connected to KListView::pressed() and clears the selection
+ * if the user clicked on the viewport.
+ *
+ * @param item The QIconViewItem that the user clicked or NULL
+ * if he/she pressed a mouse button on the viewport.
+ */
+ void slotPressed( QListViewItem *item );
+
+ /**
+ * This slot shows the tool tip for an icon view item.
+ */
+ void slotShowToolTip();
+
+ private:
+ /**
+ * The current global mouse position
+ */
+ QPoint m_pos;
+
+ /**
+ * The tool tip
+ */
+ Smb4KSharesListViewToolTip *m_tooltip;
+};
+
+#endif
+
diff --git a/smb4k/listview/smb4kshareslistview_part.cpp b/smb4k/listview/smb4kshareslistview_part.cpp
new file mode 100644
index 0000000..723042a
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistview_part.cpp
@@ -0,0 +1,700 @@
+/***************************************************************************
+ smb4kshareslistview_part - This Part includes the shares list view
+ of Smb4K.
+ -------------------
+ begin : Sa Jun 30 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qheader.h>
+
+// KDE includes
+#include <kglobal.h>
+#include <kstdaction.h>
+#include <klocale.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kaction.h>
+#include <kshortcut.h>
+#include <kdebug.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kactionclasses.h>
+
+// application specific includes
+#include "smb4kshareslistview_part.h"
+#include "smb4kshareslistview.h"
+#include "smb4kshareslistviewitem.h"
+#include "../dialogs/smb4ksynchronizationdialog.h"
+#include "../core/smb4kshare.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4ksettings.h"
+
+
+KInstance *Smb4KSharesListViewPartFactory::m_instance = 0L;
+KAboutData *Smb4KSharesListViewPartFactory::m_about = 0L;
+
+
+Smb4KSharesListViewPart::Smb4KSharesListViewPart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name )
+: KParts::Part( parent, name )
+{
+ // First of all We need an instance:
+ setInstance( Smb4KSharesListViewPartFactory::instance() );
+
+ // Set the XML file:
+ setXMLFile( "smb4kshareslistview_part.rc" );
+
+ // Set the widget of this part:
+ m_widget = new Smb4KSharesListView( parentWidget, widgetName );
+ setWidget( m_widget );
+
+ // Set up the actions.
+ // Do not put this before setWidget() or the shortcuts
+ // will not be shown.
+ setupActions();
+
+ // Import the shares:
+ slotMountedShares();
+
+ // Load settings:
+ loadSettings();
+
+ // Add some connections:
+ connect( Smb4KCore::mounter(), SIGNAL( updated() ),
+ this, SLOT( slotMountedShares() ) );
+
+ connect( Smb4KCore::synchronizer(), SIGNAL( state( int ) ),
+ this, SLOT( slotSynchronizationState( int ) ) );
+
+ connect( m_widget, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint & , int) ),
+ this, SLOT( slotContextMenuRequested( QListViewItem *, const QPoint &, int ) ) );
+
+ connect( m_widget, SIGNAL( selectionChanged( QListViewItem * ) ),
+ this, SLOT( slotSelectionChanged( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( pressed( QListViewItem * ) ),
+ this, SLOT( slotMouseButtonPressed( QListViewItem * ) ) );
+
+ connect( m_widget, SIGNAL( executed( QListViewItem * ) ),
+ this, SLOT( slotFilemanager() ) );
+}
+
+
+Smb4KSharesListViewPart::~Smb4KSharesListViewPart()
+{
+}
+
+
+void Smb4KSharesListViewPart::setupActions()
+{
+ // Create the actions:
+ KAction *unmount = new KAction( i18n( "&Unmount" ), "hdd_unmount", KShortcut( CTRL+Key_U ),
+ this, SLOT( slotUnmountShare() ),
+ actionCollection(), "unmount_action" );
+#ifdef __linux__
+ KAction *force = new KAction( i18n( "&Force Unmounting" ), "hdd_unmount", KShortcut( CTRL+Key_F ),
+ this, SLOT( slotForceUnmountShare() ),
+ actionCollection(), "force_unmount_action" );
+#endif
+ KAction *all = new KAction( i18n( "U&nmount All" ), "gear", KShortcut( CTRL+Key_N ),
+ this, SLOT( slotUnmountAllShares() ),
+ actionCollection(), "unmount_all_action" );
+ KAction *sync = new KAction( i18n( "S&ynchronize" ), "bottom", KShortcut( CTRL+Key_Y ),
+ this, SLOT( slotSynchronize() ),
+ actionCollection(), "synchronize_action" );
+ KAction *konsole = new KAction( i18n( "Open with Konso&le" ), "terminal", KShortcut( CTRL+Key_L ),
+ this, SLOT( slotKonsole() ),
+ actionCollection(), "konsole_action" );
+ KAction *konq = new KAction( i18n( "Open with &Konqueror" ), "kfm_home", KShortcut( CTRL+Key_K ),
+ this, SLOT( slotFilemanager() ),
+ actionCollection(), "filemanager_action" );
+
+ // Disable all actions for now:
+ unmount->setEnabled( false );
+#ifdef __linux__
+ force->setEnabled( false );
+#endif
+ all->setEnabled( false );
+ sync->setEnabled( false );
+ konsole->setEnabled( false );
+ konq->setEnabled( false );
+
+ // Insert the actions into the menu:
+ m_menu = new KActionMenu( this, "SharesListViewMenu" );
+ m_menu->popupMenu()->insertTitle( SmallIcon( "hdd_mount" ), i18n( "Shares" ), 0 );
+ m_menu->insert( unmount, -1 );
+#ifdef __linux__
+ m_menu->insert( force, -1 );
+#endif
+ m_menu->insert( all, -1 );
+ m_menu->popupMenu()->insertSeparator( -1 );
+ m_menu->insert( sync, -1 );
+ m_menu->popupMenu()->insertSeparator( -1 );
+ m_menu->insert( konsole, -1 );
+ m_menu->insert( konq, -1 );
+}
+
+
+void Smb4KSharesListViewPart::loadSettings()
+{
+#ifdef __linux__
+ actionCollection()->action( "force_unmount_action" )->setEnabled( Smb4KSettings::useForceUnmount() );
+#endif
+
+ m_widget->setColumnWidth( Smb4KSharesListView::Item, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Item, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Item );
+
+ if ( Smb4KSettings::showOwner() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Owner, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Owner, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Owner );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Owner, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Owner, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::Owner );
+ }
+
+#ifndef __FreeBSD__
+ if ( Smb4KSettings::showLogin() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Login, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Login, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Login );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Login, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Login, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::Login );
+ }
+#endif
+
+ if ( Smb4KSettings::showFileSystem() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::FileSystem, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::FileSystem, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::FileSystem );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::FileSystem, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::FileSystem, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::FileSystem );
+ }
+
+ if ( Smb4KSettings::showFreeDiskSpace() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Free, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Free, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Free );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Free, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Free, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::Free );
+ }
+
+ if ( Smb4KSettings::showUsedDiskSpace() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Used, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Used, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Used );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Used, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Used, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::Used );
+ }
+
+ if ( Smb4KSettings::showTotalDiskSpace() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Total, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Total, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Total );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Total, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Total, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::Total );
+ }
+
+ if ( Smb4KSettings::showDiskUsage() )
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Usage, 10 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Usage, QListView::Maximum );
+ m_widget->header()->setResizeEnabled( true, Smb4KSharesListView::Usage );
+ }
+ else
+ {
+ m_widget->setColumnWidth( Smb4KSharesListView::Usage, 0 );
+ m_widget->setColumnWidthMode( Smb4KSharesListView::Usage, QListView::Manual );
+ m_widget->header()->setResizeEnabled( false, Smb4KSharesListView::Usage );
+ }
+
+ // Change the text of the share (first column):
+ QListViewItemIterator it( m_widget );
+ Smb4KSharesListViewItem *item = NULL;
+
+ while( it.current() )
+ {
+ item = static_cast<Smb4KSharesListViewItem *>( it.current() );
+
+ if ( item )
+ {
+ item->setText( 0, (Smb4KSettings::showMountPoint() ?
+ item->shareObject()->path() :
+ item->shareObject()->name()) );
+ }
+
+ ++it;
+ }
+
+ // Enable/disable support for dropping:
+ m_widget->setAcceptDrops( Smb4KSettings::enableDropSupport() );
+
+ // Load or remove all foreign shares. The easiest way to do this
+ // is to invoke slotMountedShares():
+ slotMountedShares();
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+}
+
+
+void Smb4KSharesListViewPart::customEvent( QCustomEvent *e )
+{
+ switch ( e->type() )
+ {
+ case EVENT_LOAD_SETTINGS:
+ {
+ loadSettings();
+ slotMountedShares();
+
+ break;
+ }
+ case EVENT_SET_FOCUS:
+ {
+ KListView *view = static_cast<KListView *>( m_widget );
+
+ if ( view->childCount() != 0 )
+ {
+ view->setSelected( !view->currentItem() ?
+ view->firstChild() :
+ view->currentItem(), true );
+ }
+
+ view->setFocus();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ KParts::Part::customEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS (Smb4KSharesListViewPart)
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSharesListViewPart::slotContextMenuRequested( QListViewItem *item, const QPoint &pos, int /*col*/ )
+{
+ if ( item )
+ {
+ m_menu->popupMenu()->changeTitle( 0, SmallIcon( "hdd_mount" ),
+ static_cast<Smb4KSharesListViewItem *>( item )->shareObject()->name() );
+ }
+ else
+ {
+ m_menu->popupMenu()->changeTitle( 0, SmallIcon( "hdd_mount" ), i18n( "Shares" ) );
+ }
+
+ m_menu->popupMenu()->exec( pos, 0 );
+}
+
+
+void Smb4KSharesListViewPart::slotSelectionChanged( QListViewItem *item )
+{
+ // NOTE: Here we only enable or disable the KActions. All other things
+ // are done in the Smb4KSharesListView class.
+
+ // This slot is used to enable or disable the actions when the user
+ // changes the item in the list view. This slot won't be called when
+ // the user clicks on the view port!
+ if ( item )
+ {
+ actionCollection()->action( "unmount_action" )->setEnabled( true );
+#ifdef __linux__
+ actionCollection()->action( "force_unmount_action" )->setEnabled( Smb4KSettings::useForceUnmount() );
+#endif
+ actionCollection()->action( "unmount_all_action" )->setEnabled( true );
+
+ Smb4KShare *share = static_cast<Smb4KSharesListViewItem *>( item )->shareObject();
+
+ if ( !share->isBroken() )
+ {
+ actionCollection()->action( "konsole_action" )->setEnabled( !Smb4KSettings::konsole().isEmpty() );
+ actionCollection()->action( "filemanager_action" )->setEnabled( true );
+ actionCollection()->action( "synchronize_action" )->setEnabled( !Smb4KSettings::rsync().isEmpty() &&
+ !Smb4KCore::synchronizer()->isRunning() );
+ }
+ else
+ {
+ actionCollection()->action( "konsole_action" )->setEnabled( false );
+ actionCollection()->action( "filemanager_action" )->setEnabled( false );
+ actionCollection()->action( "synchronize_action" )->setEnabled( false );
+ }
+ }
+ else
+ {
+ // Smb4KSharesListViewPart::slotMouseButtonPressed()
+ }
+}
+
+
+void Smb4KSharesListViewPart::slotMouseButtonPressed( QListViewItem *item )
+{
+ // NOTE: Here we only enable or disable the KActions. All other things
+ // are done in the Smb4KSharesListView class.
+
+ // Here we do all the stuff that cannot be done in
+ // Smb4KSharesListViewPart::slotSelectionChanged()
+ if ( !item )
+ {
+ actionCollection()->action( "unmount_action" )->setEnabled( false );
+#ifdef __linux__
+ actionCollection()->action( "force_unmount_action" )->setEnabled( false );
+#endif
+ actionCollection()->action( "unmount_all_action" )->setEnabled( (m_widget->childCount() > 0) );
+ actionCollection()->action( "konsole_action" )->setEnabled( false );
+ actionCollection()->action( "filemanager_action" )->setEnabled( false );
+ actionCollection()->action( "synchronize_action" )->setEnabled( false );
+ }
+ else
+ {
+ // See Smb4KSharesListViewPart::slotSelectionChanged()
+ }
+}
+
+
+void Smb4KSharesListViewPart::slotMountedShares()
+{
+ // Get the list of shares:
+ QValueList<Smb4KShare *> list = Smb4KCore::mounter()->getShares();
+
+ // Update the view:
+ if ( !list.isEmpty() )
+ {
+ // Remove all obsolete items:
+ QListViewItemIterator it( m_widget );
+ Smb4KSharesListViewItem *item = NULL;
+
+ while ( it.current() )
+ {
+ item = static_cast<Smb4KSharesListViewItem *>( it.current() );
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( item->shareObject()->path() );
+
+ if( !share || (item->shareObject()->isForeign() && !Smb4KSettings::showAllShares()) )
+ {
+ delete item;
+ item = NULL;
+ }
+
+ ++it;
+ }
+
+ // Now process the entries in the list:
+ bool already_in_view = false;
+
+ for ( QValueListConstIterator<Smb4KShare *> it = list.begin(); it != list.end(); ++it )
+ {
+ // Check, whether the share is already in the list. Look for the
+ // mount point.
+ for ( Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( m_widget->firstChild() );
+ item; item = static_cast<Smb4KSharesListViewItem *>( item->nextSibling() ) )
+ {
+ if ( QString::compare( item->shareObject()->path(), (*it)->path() ) == 0 ||
+ QString::compare( item->shareObject()->canonicalPath(), (*it)->canonicalPath() ) == 0 )
+ {
+ // Replace the share object if something changed:
+ if ( !item->sameShareObject( *it ) )
+ {
+ item->replaceShareObject( *it );
+ }
+
+ already_in_view = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !already_in_view )
+ {
+ if ( !Smb4KSettings::showAllShares() && (*it)->isForeign() )
+ {
+ // If the user does not want to have foreign shares
+ // displayed continue.
+ continue;
+ }
+ else
+ {
+ // Put the new item into the list view:
+ (void) new Smb4KSharesListViewItem( *it, Smb4KSettings::showMountPoint(), m_widget );
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+
+ continue;
+ }
+ }
+
+ already_in_view = false;
+ }
+
+ m_widget->sort();
+ }
+ else
+ {
+ if ( m_widget->childCount() != 0 )
+ {
+ m_widget->clear();
+
+ // Adjust the columns:
+ for ( int col = 0; col < m_widget->columns(); col++ )
+ {
+ if ( m_widget->columnWidth( col ) != 0 )
+ {
+ m_widget->adjustColumn( col );
+ }
+ }
+ }
+ }
+
+ // Update the tool tip, if it exists:
+ if ( m_widget->childCount() != 0 )
+ {
+ m_widget->updateToolTip();
+ }
+
+ // Enable/disable the actions:
+ QListViewItem *item = m_widget->currentItem();
+ bool have_selected_item = (item && item->isSelected());
+
+ actionCollection()->action( "unmount_action" )->setEnabled( have_selected_item );
+#ifdef __linux__
+ if ( Smb4KSettings::useForceUnmount() )
+ {
+ actionCollection()->action( "force_unmount_action" )->setEnabled( have_selected_item );
+ }
+ else
+ {
+ actionCollection()->action( "force_unmount_action" )->setEnabled( false );
+ }
+#endif
+ actionCollection()->action( "unmount_all_action" )->setEnabled( (m_widget->childCount() > 0) );
+ actionCollection()->action( "konsole_action" )->setEnabled( !Smb4KSettings::konsole().isEmpty() && have_selected_item );
+ actionCollection()->action( "filemanager_action" )->setEnabled( have_selected_item );
+ actionCollection()->action( "synchronize_action" )->setEnabled( !Smb4KSettings::rsync().isEmpty() &&
+ !Smb4KCore::synchronizer()->isRunning() &&
+ have_selected_item );
+}
+
+
+void Smb4KSharesListViewPart::slotUnmountShare()
+{
+ Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( m_widget->currentItem() );
+
+ if ( item )
+ {
+ Smb4KCore::mounter()->unmountShare( item->shareObject(), false );
+ }
+}
+
+
+void Smb4KSharesListViewPart::slotForceUnmountShare()
+{
+ Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( m_widget->currentItem() );
+
+ if ( item )
+ {
+ Smb4KCore::mounter()->unmountShare( item->shareObject(), true );
+ }
+}
+
+
+void Smb4KSharesListViewPart::slotUnmountAllShares()
+{
+ Smb4KCore::mounter()->unmountAllShares();
+}
+
+
+void Smb4KSharesListViewPart::slotSynchronize()
+{
+ Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( m_widget->currentItem() );
+ Smb4KSynchronizationDialog *dlg = static_cast<Smb4KSynchronizationDialog *>( m_widget->child( "SynchronizationDialog", "Smb4KSynchronizationDialog", true ) );
+
+ if ( item && !item->shareObject()->isBroken() && !dlg )
+ {
+ dlg = new Smb4KSynchronizationDialog( item->shareObject(), m_widget, "SynchronizationDialog" );
+
+ dlg->show();
+ }
+}
+
+void Smb4KSharesListViewPart::slotKonsole()
+{
+ Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( m_widget->currentItem() );
+
+ if ( item && !item->shareObject()->isBroken() )
+ {
+ Smb4KCore::open( item->shareObject(), Smb4KCore::Konsole );
+ }
+}
+
+
+void Smb4KSharesListViewPart::slotFilemanager()
+{
+ Smb4KSharesListViewItem *item = static_cast<Smb4KSharesListViewItem *>( m_widget->currentItem() );
+
+ if ( item && !item->shareObject()->isBroken() )
+ {
+ Smb4KCore::open( item->shareObject(), Smb4KCore::Konqueror );
+ }
+}
+
+
+void Smb4KSharesListViewPart::slotSynchronizationState( int state )
+{
+ switch ( state )
+ {
+ case SYNCHRONIZER_START:
+ {
+ actionCollection()->action( "synchronize_action" )->setEnabled( false );
+
+ break;
+ }
+ case SYNCHRONIZER_STOP:
+ {
+ actionCollection()->action( "synchronize_action" )->setEnabled( true );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// FACTORY STUFF
+/////////////////////////////////////////////////////////////////////////////
+
+Smb4KSharesListViewPartFactory::Smb4KSharesListViewPartFactory()
+: KParts::Factory()
+{
+}
+
+
+Smb4KSharesListViewPartFactory::~Smb4KSharesListViewPartFactory()
+{
+ delete m_instance;
+ delete m_about;
+
+ m_instance = 0L;
+}
+
+
+KParts::Part *Smb4KSharesListViewPartFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
+QObject *parent, const char *name, const char *, const QStringList & )
+{
+ Smb4KSharesListViewPart *obj = new Smb4KSharesListViewPart( parentWidget, widgetName, parent, name );
+
+ // See if we are to be read-write or not
+// if (QCString(classname) == "KParts::ReadOnlyPart")
+// {
+// obj->setReadWrite(false);
+// }
+
+ return obj;
+}
+
+
+KInstance *Smb4KSharesListViewPartFactory::instance()
+{
+ if( !m_instance )
+ {
+ m_about = new KAboutData( "smb4kshareslistviewpart", I18N_NOOP( "Smb4KSharesListViewPart" ), "1.0" );
+ m_about->addAuthor("Alexander Reinholdt", 0, "[email protected]");
+ m_about->setLicense( KAboutData::License_GPL );
+ m_instance = new KInstance( m_about );
+ }
+
+ return m_instance;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// INIT
+/////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+{
+ void *init_libsmb4kshareslistview()
+ {
+ KGlobal::locale()->insertCatalogue( "smb4k" );
+ return new Smb4KSharesListViewPartFactory;
+ }
+}
+
+
+#include "smb4kshareslistview_part.moc"
diff --git a/smb4k/listview/smb4kshareslistview_part.h b/smb4k/listview/smb4kshareslistview_part.h
new file mode 100644
index 0000000..858193e
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistview_part.h
@@ -0,0 +1,234 @@
+/***************************************************************************
+ smb4kshareslistview_part -This Part includes the shares list view
+ of Smb4K.
+ -------------------
+ begin : Sa Jun 30 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESLISTVIEW_PART_H
+#define SMB4KSHARESLISTVIEW_PART_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kparts/part.h>
+#include <kparts/factory.h>
+
+// applications specific includes
+#include "smb4kshareslistview.h"
+
+/**
+ * This is one of the parts of Smb4K. It contains the shares list
+ * view.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesListViewPart : public KParts::Part
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parentWidget The parent widget
+ *
+ * @param widgetName The name the widget should have
+ *
+ * @param parent The parent object
+ *
+ * @param name The name this object should have
+ */
+ Smb4KSharesListViewPart( QWidget *parentWidget = 0, const char *widgetName = 0,
+ QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ virtual ~Smb4KSharesListViewPart();
+
+ protected:
+ /**
+ * Reimplemented from KParts::Part.
+ */
+ void customEvent( QCustomEvent *e );
+
+ protected slots:
+ /**
+ * Opens a context menu over the list view item @p item at position
+ * @p pos if requested.
+ *
+ * @param item The list view item or NULL if the user clicked
+ * somewhere else.
+ *
+ * @param pos The position where the user clicked.
+ *
+ * @param col The column where the context menu should be show.
+ */
+ void slotContextMenuRequested( QListViewItem *item, const QPoint & pos, int col );
+
+ /**
+ * This slot is called when the selection in the list view changed. It
+ * enables or disables the actions according to known options/states.
+ * Please note that it won't be invoked when the user clicked on the
+ * viewport. Use slotMouseButtonPressed() to also catch that event.
+ *
+ * @param item The list view item that was selected
+ */
+ void slotSelectionChanged( QListViewItem *item );
+
+ /**
+ * This slot is called when the user presses any mouse button somewhere
+ * in the list view. It enables or disables the actions according to known
+ * options/states.
+ *
+ * @param item The icon view item that was clicked or NULL if the
+ * user clicked onto the viewport.
+ */
+ void slotMouseButtonPressed( QListViewItem *item );
+
+ /**
+ * This slot is called by the Smb4KMounter::updated() signal and updates
+ * the list view according to the list that is returned by Smb4KMounter::getShares().
+ */
+ void slotMountedShares();
+
+ /**
+ * This slot is connected to the 'Unmount action'. You will be able to
+ * unmount a certain share when activating this slot.
+ */
+ void slotUnmountShare();
+
+ /**
+ * This slot is connected to the 'Force Unmounting' action and is, thus,
+ * only useful under Linux, because only there the possibility for a forced
+ * (i.e. lazy) unmount exists.
+ *
+ * When activating this slot, the selected share will be unmounted, even if
+ * it is not accessible or the server already went offline.
+ */
+ void slotForceUnmountShare();
+
+ /**
+ * This slot is connected to the 'Unmount All' action. All shares - either of
+ * the user or that are present on the system (depending on the settings the
+ * user chose) - will be unmounted. Please note that Smb4KMounter::unmountAllShares()
+ * is invoked directly.
+ */
+ void slotUnmountAllShares();
+
+ /**
+ * This slot is connected to the 'Synchronize' action. The current item will be
+ * synchronized with a local copy (or vice versa) if you activate it.
+ */
+ void slotSynchronize();
+
+ /**
+ * This slot is connected to the 'Konsole' action. The mount point of the current
+ * share item will be opened in Konsole.
+ */
+ void slotKonsole();
+
+ /**
+ * This slot is connected to the 'Konqueror' action. The contents of the current
+ * share item will be opened in the file manager.
+ */
+ void slotFilemanager();
+
+ /**
+ * This slot is called by the synchronizer whenever the state of the synchronization
+ * process changed.
+ *
+ * @param state The state the synchronizer is in.
+ */
+ void slotSynchronizationState( int state );
+
+ private:
+ /**
+ * Set up the actions
+ */
+ void setupActions();
+
+ /**
+ * Load settings for the widget or the actions.
+ */
+ void loadSettings();
+
+ /**
+ * The icon view.
+ */
+ Smb4KSharesListView *m_widget;
+
+ /**
+ * The action menu.
+ */
+ KActionMenu *m_menu;
+};
+
+
+class KInstance;
+class KAboutData;
+
+class Smb4KSharesListViewPartFactory : public KParts::Factory
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ */
+ Smb4KSharesListViewPartFactory();
+
+ /**
+ * The destructor
+ */
+ virtual ~Smb4KSharesListViewPartFactory();
+
+ /**
+ * Reimplemented from KParts::Factory
+ */
+ virtual KParts::Part *createPartObject( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name,
+ const char *classname, const QStringList &args );
+
+ /**
+ * The instance
+ */
+ static KInstance *instance();
+
+ private:
+ /**
+ * The factory's instance.
+ */
+ static KInstance *m_instance;
+
+ /**
+ * The factory's KAboutData object
+ */
+ static KAboutData *m_about;
+};
+
+
+#endif
diff --git a/smb4k/listview/smb4kshareslistview_part.rc b/smb4k/listview/smb4kshareslistview_part.rc
new file mode 100644
index 0000000..a030146
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistview_part.rc
@@ -0,0 +1,25 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="smb4kshareslistview_part" version="1">
+<MenuBar>
+ <Menu name="shares"><text>&amp;Shares</text>
+ <Action name="unmount_action"/>
+ <Action name="force_unmount_action"/>
+ <Action name="unmount_all_action"/>
+ <Separator/>
+ <Action name="synchronize_action"/>
+ <Separator/>
+ <Action name="konsole_action"/>
+ <Action name="filemanager_action"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="sharesViewToolBar">
+ <Action name="unmount_action"/>
+ <Action name="force_unmount_action"/>
+ <Action name="unmount_all_action"/>
+ <Separator/>
+ <Action name="synchronize_action"/>
+ <Separator/>
+ <Action name="konsole_action"/>
+ <Action name="filemanager_action"/>
+</ToolBar>
+</kpartgui>
diff --git a/smb4k/listview/smb4kshareslistviewitem.cpp b/smb4k/listview/smb4kshareslistviewitem.cpp
new file mode 100644
index 0000000..327f9fb
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistviewitem.cpp
@@ -0,0 +1,353 @@
+/***************************************************************************
+ smb4kshareslistviewitem - The shares list view item class of Smb4K.
+ -------------------
+ begin : Sa Jun 30 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qpixmap.h>
+#include <qcolor.h>
+
+// KDE includes
+#include <kiconeffect.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kshareslistviewitem.h"
+#include "smb4kshareslistview.h"
+
+
+Smb4KSharesListViewItem::Smb4KSharesListViewItem( Smb4KShare *share, bool mountpoint,
+ Smb4KSharesListView *parent )
+: KListViewItem( parent ), m_share( *share ), m_mountpoint( mountpoint ),
+ m_initial_setup( true )
+{
+ setDropEnabled( true );
+ setDragEnabled( true );
+
+ m_loader = new KIconLoader();
+
+ setupItem( m_share, m_mountpoint );
+}
+
+
+Smb4KSharesListViewItem::~Smb4KSharesListViewItem()
+{
+ // Do not touch the Smb4KShare object!
+ delete m_loader;
+}
+
+
+void Smb4KSharesListViewItem::setupItem( const Smb4KShare &share, bool mountpoint )
+{
+ // Only do something here if either the item hasn't been set up
+ // yet, or share and mountpoint changed, respectively.
+ if ( m_initial_setup || !m_share.equals( share ) || m_mountpoint != mountpoint )
+ {
+ if ( m_initial_setup || m_share.isBroken() != share.isBroken() )
+ {
+ QPixmap pix;
+
+ int icon_state = m_share.isForeign() ? KIcon::DisabledState : KIcon::DefaultState;
+
+ if ( m_share.isBroken() )
+ {
+ QImage over = m_loader->loadIcon( "button_cancel", KIcon::Small,
+ 0, icon_state, 0L, false ).convertToImage();
+ QImage src = m_loader->loadIcon( "hdd_mount", KIcon::Small,
+ 0, icon_state, 0L, false ).convertToImage();
+
+ QImage over_desk = m_loader->loadIcon( "button_cancel", KIcon::Desktop,
+ 0, icon_state, 0L, false ).convertToImage();
+ QImage src_desk = m_loader->loadIcon( "hdd_mount", KIcon::Desktop,
+ 0, icon_state, 0L, false ).convertToImage();
+
+ KIconEffect e;
+ e.semiTransparent( over );
+ e.overlay( src, over );
+ e.semiTransparent( over_desk );
+ e.overlay( src_desk, over_desk );
+
+ pix = QPixmap( src );
+ m_desktop_pixmap = QPixmap( src_desk );
+ }
+ else
+ {
+ pix = m_loader->loadIcon( "hdd_mount", KIcon::Small,
+ 0, icon_state, 0L, false );
+
+ m_desktop_pixmap = m_loader->loadIcon( "hdd_mount", KIcon::Desktop,
+ 0, icon_state, 0L, false );
+ }
+
+ setPixmap( Item, pix );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ if ( !m_initial_setup )
+ {
+ if ( m_mountpoint != mountpoint )
+ {
+ setText( Item, (m_mountpoint ? m_share.path() : m_share.name()) );
+ }
+
+ // The file system, owner and login won't change
+
+ QString total, free, used, total_dim, free_dim, used_dim;
+
+ if ( shareObject()->totalDiskSpace() - shareObject()->freeDiskSpace() > 1024 )
+ {
+ double tmp_used = (shareObject()->totalDiskSpace() - shareObject()->freeDiskSpace()) / 1024;
+ used_dim = "MB";
+
+ if ( tmp_used >= 1024 )
+ {
+ tmp_used = tmp_used / 1024;
+ used_dim = "GB";
+ }
+
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+ else
+ {
+ used_dim = "kB";
+ double tmp_used = shareObject()->totalDiskSpace() - shareObject()->freeDiskSpace();
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+
+ if ( shareObject()->freeDiskSpace() >= 1024 )
+ {
+ double tmp_free = shareObject()->freeDiskSpace() / 1024;
+ free_dim = "MB";
+
+ if ( tmp_free >= 1024 )
+ {
+ tmp_free = tmp_free / 1024;
+ free_dim = "GB";
+ }
+
+ free = QString( "%1" ).arg( tmp_free, 0, 'f', 1 );
+ }
+ else
+ {
+ free_dim = "kB";
+ free = QString( "%1" ).arg( shareObject()->freeDiskSpace(), 0, 'f', 1 );
+ }
+
+ if ( shareObject()->totalDiskSpace() >= 1024 )
+ {
+ double tmp_total = shareObject()->totalDiskSpace() / 1024;
+ total_dim = "MB";
+
+ if ( tmp_total >= 1024 )
+ {
+ tmp_total = tmp_total / 1024;
+ total_dim = "GB";
+ }
+
+ total = QString( "%1" ).arg( tmp_total, 0, 'f', 1 );
+ }
+ else
+ {
+ total_dim = "kB";
+ total = QString( "%1" ).arg( shareObject()->totalDiskSpace(), 0, 'f', 1 );
+ }
+
+ setText( Free, QString( "%1 %2" ).arg( free, free_dim ) );
+ setText( Used, QString( "%1 %2" ).arg( used, used_dim ) );
+ setText( Total, QString( "%1 %2" ).arg( total, total_dim ) );
+ }
+ else
+ {
+ setText( Item, (m_mountpoint ? m_share.path() : m_share.name()) );
+
+ setText( Owner, QString::compare( m_share.filesystem(), "smbfs" ) == 0 ?
+ QString( "%1 - %2" ).arg( m_share.user() ).arg( m_share.group() ) :
+ QString::null );
+#ifndef __FreeBSD__
+ setText( Login, QString::compare( m_share.filesystem(), "cifs" ) == 0 ?
+ m_share.cifsLogin() :
+ QString::null );
+#endif
+ setText( FileSystem, m_share.filesystem().upper() );
+
+ QString total, free, used, total_dim, free_dim, used_dim;
+
+ if ( shareObject()->totalDiskSpace() - shareObject()->freeDiskSpace() > 1024 )
+ {
+ double tmp_used = (shareObject()->totalDiskSpace() - shareObject()->freeDiskSpace()) / 1024;
+ used_dim = "MB";
+
+ if ( tmp_used >= 1024 )
+ {
+ tmp_used = tmp_used / 1024;
+ used_dim = "GB";
+ }
+
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+ else
+ {
+ used_dim = "kB";
+ double tmp_used = shareObject()->totalDiskSpace() - shareObject()->freeDiskSpace();
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+
+ if ( shareObject()->freeDiskSpace() >= 1024 )
+ {
+ double tmp_free = shareObject()->freeDiskSpace() / 1024;
+ free_dim = "MB";
+
+ if ( tmp_free >= 1024 )
+ {
+ tmp_free = tmp_free / 1024;
+ free_dim = "GB";
+ }
+
+ free = QString( "%1" ).arg( tmp_free, 0, 'f', 1 );
+ }
+ else
+ {
+ free_dim = "kB";
+ free = QString( "%1" ).arg( shareObject()->freeDiskSpace(), 0, 'f', 1 );
+ }
+
+ if ( shareObject()->totalDiskSpace() >= 1024 )
+ {
+ double tmp_total = shareObject()->totalDiskSpace() / 1024;
+ total_dim = "MB";
+
+ if ( tmp_total >= 1024 )
+ {
+ tmp_total = tmp_total / 1024;
+ total_dim = "GB";
+ }
+
+ total = QString( "%1" ).arg( tmp_total, 0, 'f', 1 );
+ }
+ else
+ {
+ total_dim = "kB";
+ total = QString( "%1" ).arg( shareObject()->totalDiskSpace(), 0, 'f', 1 );
+ }
+
+ setText( Free, QString( "%1 %2" ).arg( free, free_dim ) );
+ setText( Used, QString( "%1 %2" ).arg( used, used_dim ) );
+ setText( Total, QString( "%1 %2" ).arg( total, total_dim ) );
+ }
+
+ m_initial_setup = false;
+ m_share = share;
+ m_mountpoint = mountpoint;
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+bool Smb4KSharesListViewItem::sameShareObject( Smb4KShare *share )
+{
+ return m_share.equals( *share );
+}
+
+
+void Smb4KSharesListViewItem::replaceShareObject( Smb4KShare *share )
+{
+ setupItem( *share, m_mountpoint );
+}
+
+
+void Smb4KSharesListViewItem::paintCell( QPainter *p, const QColorGroup &cg, int col, int width, int align )
+{
+ // Set the color of the item text:
+ QColorGroup colorgrp( cg );
+
+ if ( m_share.isForeign() )
+ {
+ colorgrp.setColor( QColorGroup::Text, Qt::gray );
+ }
+
+ if ( col != Usage )
+ {
+ KListViewItem::paintCell( p, colorgrp, col, width, align );
+
+ return;
+ }
+
+ // Draw the usage:
+ // This code was inspired by KAudioCreator.
+ p->setPen( colorgrp.base() );
+ p->drawRect( 0, 0, width, height() );
+
+ if ( isSelected() )
+ {
+ p->fillRect( 1, 1, width-2, height()-2, colorgrp.highlight() );
+ }
+ else
+ {
+ p->fillRect( 1, 1, width-2, height()-2, colorgrp.base() );
+ }
+
+ if ( !m_share.isBroken() )
+ {
+ int percent = (int)(((double)(width-2)) * (m_share.percentage()/100));
+
+ p->fillRect( 1, 1, percent, height()-2, !m_share.isForeign() ? Qt::red : Qt::red.light( 175 ) );
+ p->fillRect( percent+1, 1, width-percent-2, height()-2, !m_share.isForeign() ? Qt::green : Qt::green.light( 175 ) );
+
+ p->setPen( !m_share.isForeign() ? colorgrp.foreground() : Qt::gray );
+ p->drawRect( 1, 1, width-2, height()-2 );
+
+ // Show the text:
+ p->setPen( colorgrp.text() );
+
+ // if ( isSelected() )
+ // {
+ // p->setPen( colorgrp.highlightedText() );
+ // }
+
+ p->drawText( 0, 0, width-1, height()-1, Qt::AlignCenter, QString( "%1 \%" ).arg( m_share.percentage(), 0, 'f', 1 ) );
+ }
+ else
+ {
+ p->fillRect( 1, 1, width-2, height()-2, colorgrp.base() );
+
+ p->setPen( !m_share.isForeign() ? colorgrp.foreground() : Qt::gray );
+ p->drawRect( 1, 1, width-2, height()-2 );
+ }
+}
+
+
+bool Smb4KSharesListViewItem::acceptDrop( const QMimeSource *source ) const
+{
+ if ( source->provides( "text/plain" ) )
+ {
+ return true;
+ }
+
+ return false;
+}
diff --git a/smb4k/listview/smb4kshareslistviewitem.h b/smb4k/listview/smb4kshareslistviewitem.h
new file mode 100644
index 0000000..4b5ddc3
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistviewitem.h
@@ -0,0 +1,203 @@
+/***************************************************************************
+ smb4kshareslistviewitem - The shares list view item class of Smb4K.
+ -------------------
+ begin : Sa Jun 30 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESLISTVIEWITEM_H
+#define SMB4KSHARESLISTVIEWITEM_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qpainter.h>
+#include <qpalette.h>
+
+// KDE includes
+#include <klistview.h>
+#include <kiconloader.h>
+
+// application specific includes
+#include "../core/smb4kshare.h"
+
+// forward declarations
+class Smb4KSharesListView;
+
+/**
+ * This class provides the items for the shares icon view
+ * of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesListViewItem : public KListViewItem
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param share The Smb4KShare object that represents the share.
+ *
+ * @param mountpoint Tells the item if the mount point instead of the
+ * share name should be shown. Default is FALSE.
+ *
+ * @param parent The parent widget of this item.
+ */
+ Smb4KSharesListViewItem( Smb4KShare *share,
+ bool mountpoint = false,
+ Smb4KSharesListView *parent = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSharesListViewItem();
+
+ /**
+ * This function compares the encapsulated Smb4KShare object with @p item
+ * and returns TRUE if they contain equal values.
+ *
+ * @param item A Smb4KShare object that should be compared
+ *
+ * @returns TRUE if @p item has the same values stored as the
+ * encapsulated Smb4KShare object.
+ */
+ bool sameShareObject( Smb4KShare *share );
+
+ /**
+ * Replace the encapsulated Smb4KShare object. This function just passes
+ * the share object to setupItem() which does all the work.
+ *
+ * @param share The new Smb4KShare object
+ */
+ void replaceShareObject( Smb4KShare *share );
+
+ /**
+ * Returns a pointer to the share object that's represented by this item.
+ * You have to use it to access its data.
+ *
+ * @returns a pointer to a Smb4KShare object.
+ */
+ Smb4KShare *shareObject() { return &m_share; }
+
+ /**
+ * Enumeration for the columns.
+ */
+#ifndef __FreeBSD__
+ enum Columns { Item = 0,
+ Owner = 1,
+ Login = 2,
+ FileSystem = 3,
+ Free = 4,
+ Used = 5,
+ Total = 6,
+ Usage = 7 };
+#else
+ enum Columns { Item = 0,
+ Owner = 1,
+ FileSystem = 2,
+ Free = 3,
+ Used = 4,
+ Total = 5,
+ Usage = 6 };
+#endif
+
+ /**
+ * This function returns the desktop pixmap of this item.
+ *
+ * @returns the destop pixmap of this item.
+ */
+ const QPixmap &desktopPixmap() { return m_desktop_pixmap; }
+
+ protected:
+ /**
+ * Reimplemented from KListViewItem.
+ *
+ * This function paints the icon text and the usage. It uses Smb4KShare::isForeign() to
+ * determine the color of the icon text (TRUE: gray, FALSE: the default color).
+ *
+ * @param p The painter
+ *
+ * @param cg The color group
+ *
+ * @param column The column of the list view
+ *
+ * @param width The width of the area that will be painted.
+ *
+ * @param alignment The alignment of the column that will be used.
+ */
+ void paintCell( QPainter *p,
+ const QColorGroup &cg,
+ int column,
+ int width,
+ int alignment );
+
+ /**
+ * Reimplemented from KListViewItem.
+ *
+ * This function accepts or denies drops according to the contents of @p source.
+ *
+ * @param source The mime source
+ */
+ bool acceptDrop( const QMimeSource *source ) const;
+
+ private:
+ /**
+ * Set up the icon and text of the item with respect to @p share and @p mountpoint.
+ *
+ * @param share The Smb4KShare object.
+ *
+ * @param mountpoint If TRUE, the mount point will be shown instead of the
+ * share name.
+ */
+ void setupItem( const Smb4KShare &share,
+ bool mountpoint = false );
+
+ /**
+ * The Smb4KShare object representing the share.
+ */
+ Smb4KShare m_share;
+
+ /**
+ * Tells us if the mount point instead of the share
+ * name should be shown.
+ */
+ bool m_mountpoint;
+
+ /**
+ * Tells us that the initial setup already happened.
+ */
+ bool m_initial_setup;
+
+ /**
+ * The icon loader for this item.
+ */
+ KIconLoader *m_loader;
+
+ /**
+ * The desktop pixmap
+ */
+ QPixmap m_desktop_pixmap;
+};
+
+#endif
diff --git a/smb4k/listview/smb4kshareslistviewtooltip.cpp b/smb4k/listview/smb4kshareslistviewtooltip.cpp
new file mode 100644
index 0000000..110f412
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistviewtooltip.cpp
@@ -0,0 +1,429 @@
+/***************************************************************************
+ smb4kshareslistviewtooltip - Tool tip for the shares list view.
+ -------------------
+ begin : So Jul 8 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qtooltip.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qtimer.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "smb4kshareslistviewtooltip.h"
+#include "smb4kshareslistviewitem.h"
+
+
+Smb4KSharesListViewToolTip::Smb4KSharesListViewToolTip( Smb4KSharesListViewItem *item )
+: QLabel( 0, "SharesListViewToolTip", WStyle_StaysOnTop | WStyle_Customize |
+WStyle_NoBorder | WStyle_Tool | WX11BypassWM | WDestructiveClose ), m_item( item )
+{
+ setPalette( QToolTip::palette() );
+ setLineWidth( 1 );
+ setMidLineWidth( 1 );
+ setFrameShape( Box );
+ setFrameShadow( Plain );
+ setMouseTracking( true );
+
+ m_layout = new QGridLayout( this );
+ m_layout->setMargin( 10 );
+ m_layout->setSpacing( 3 );
+
+ m_is_set_up = false;
+
+ m_free = NULL;
+ m_used = NULL;
+ m_total = NULL;
+ m_usage = NULL;
+ m_pixmap = NULL;
+
+ // We will set up the tip in the showTip() function.
+}
+
+
+Smb4KSharesListViewToolTip::~Smb4KSharesListViewToolTip()
+{
+ // Never touch the Smb4KSharesListViewItem object here!
+}
+
+
+void Smb4KSharesListViewToolTip::showTip( const QPoint &pos )
+{
+ if ( !m_item || isShown() )
+ {
+ return;
+ }
+
+ setupTip();
+
+ adjustSize();
+
+ QDesktopWidget *d = QApplication::desktop();
+ QPoint p( pos );
+
+ if ( p.x() + width() > d->width() )
+ {
+ p.setX( p.x() - width() - 5 );
+ }
+ else
+ {
+ p.setX( p.x() + 5 );
+ }
+
+ if ( p.y() + height() > d->height() )
+ {
+ p.setY( p.y() - height() - 5 );
+ }
+ else
+ {
+ p.setY( p.y() + 5 );
+ }
+
+ setGeometry( p.x(), p.y(), width(), height() );
+ polish();
+ show();
+ QTimer::singleShot( 10000, this, SLOT( slotHideToolTip() ) );
+}
+
+
+void Smb4KSharesListViewToolTip::setupTip()
+{
+ if ( !m_item )
+ {
+ return;
+ }
+
+ m_layout->addWidget( new QLabel( i18n( "Share:" ), this ), 0, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->name(), this ), 0, 2, 0 );
+ m_layout->addWidget( new QLabel( i18n( "Mount point:" ), this ), 1, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->path(), this ), 1, 2, 0 );
+
+ if ( QString::compare( m_item->shareObject()->filesystem(), "smbfs" ) == 0 )
+ {
+ m_layout->addWidget( new QLabel( "Owner:", this ), 2, 1, 0 );
+ m_layout->addWidget( new QLabel( QString( "%1 - %2" ).arg( m_item->shareObject()->user(), m_item->shareObject()->group() ), this ), 2, 2, 0 );
+ }
+ else
+ {
+ m_layout->addWidget( new QLabel( "Login:", this ), 2, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->cifsLogin(), this ), 2, 2, 0 );
+ }
+
+ m_layout->addWidget( new QLabel( i18n( "File system:" ), this ), 3, 1, 0 );
+ m_layout->addWidget( new QLabel( m_item->shareObject()->filesystem().upper(), this ), 3, 2, 0 );
+
+ QFrame *line = new QFrame( this );
+ line->setLineWidth( 1 );
+ line->setMidLineWidth( 0 );
+ line->setFixedWidth( 100 );
+ line->setFrameShape( QFrame::HLine );
+ line->setFrameShadow( QFrame::Plain );
+
+ m_layout->addMultiCellWidget( line, 4, 4, 1, 2, Qt::AlignCenter );
+
+ // Prepare the disk usage stuff.
+ if ( !m_item->shareObject()->isBroken() )
+ {
+ QString total, free, used, total_dim, free_dim, used_dim;
+
+ if ( m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace() > 1024 )
+ {
+ double tmp_used = (m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace()) / 1024;
+ used_dim = "MB";
+
+ if ( tmp_used >= 1024 )
+ {
+ tmp_used = tmp_used / 1024;
+ used_dim = "GB";
+ }
+
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+ else
+ {
+ used_dim = "kB";
+ double tmp_used = m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace();
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->freeDiskSpace() >= 1024 )
+ {
+ double tmp_free = m_item->shareObject()->freeDiskSpace() / 1024;
+ free_dim = "MB";
+
+ if ( tmp_free >= 1024 )
+ {
+ tmp_free = tmp_free / 1024;
+ free_dim = "GB";
+ }
+
+ free = QString( "%1" ).arg( tmp_free, 0, 'f', 1 );
+ }
+ else
+ {
+ free_dim = "kB";
+ free = QString( "%1" ).arg( m_item->shareObject()->freeDiskSpace(), 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->totalDiskSpace() >= 1024 )
+ {
+ double tmp_total = m_item->shareObject()->totalDiskSpace() / 1024;
+ total_dim = "MB";
+
+ if ( tmp_total >= 1024 )
+ {
+ tmp_total = tmp_total / 1024;
+ total_dim = "GB";
+ }
+
+ total = QString( "%1" ).arg( tmp_total, 0, 'f', 1 );
+ }
+ else
+ {
+ total_dim = "kB";
+ total = QString( "%1" ).arg( m_item->shareObject()->totalDiskSpace(), 0, 'f', 1 );
+ }
+
+ m_layout->addWidget( new QLabel( i18n( "Free:" ), this, "FreeLabel" ), 5, 1, 0 );
+ m_free = new QLabel( QString( "%1 %2" ).arg( free, free_dim ), this );
+ m_layout->addWidget( m_free, 5, 2, 0 );
+
+ m_layout->addWidget( new QLabel( i18n( "Used:" ), this, "UsedLabel" ), 6, 1, 0 );
+ m_used = new QLabel( QString( "%1 %2" ).arg( used, used_dim ), this );
+ m_layout->addWidget( m_used, 6, 2, 0 );
+
+ m_layout->addWidget( new QLabel( i18n( "Total:" ), this, "TotalLabel" ), 7, 1, 0 );
+ m_total = new QLabel( QString( "%1 %2" ).arg( total, total_dim ), this );
+ m_layout->addWidget( m_total, 7, 2, 0 );
+
+ m_layout->addWidget( new QLabel( i18n( "Usage:" ), this, "UsageLabel" ), 8, 1, 0 );
+ m_usage = new QLabel( QString( "%1 %" ).arg( m_item->shareObject()->percentage(), 0, 'f', 1 ), this );
+ m_layout->addWidget( m_usage, 8, 2, 0 );
+ }
+ else
+ {
+ QLabel *error = new QLabel( i18n( "This share is inaccessible." ), this );
+
+ QFont font;
+ font.setItalic( true );
+
+ error->setFont( font );
+
+ m_layout->addMultiCellWidget( error, 5, 5, 1, 2, Qt::AlignCenter );
+ }
+
+ m_pixmap = new QLabel( this );
+ m_pixmap->setPixmap( m_item->desktopPixmap() );
+
+ m_layout->addMultiCellWidget( m_pixmap, 0, m_layout->numRows(), 0, 0, Qt::AlignCenter );
+
+ m_is_set_up = true;
+}
+
+
+void Smb4KSharesListViewToolTip::update()
+{
+ if ( !m_is_set_up )
+ {
+ return;
+ }
+
+ // Only change the variable entries:
+ if ( !m_item->shareObject()->isBroken() )
+ {
+ QString total, free, used, total_dim, free_dim, used_dim;
+
+ if ( m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace() > 1024 )
+ {
+ double tmp_used = (m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace()) / 1024;
+ used_dim = "MB";
+
+ if ( tmp_used >= 1024 )
+ {
+ tmp_used = tmp_used / 1024;
+ used_dim = "GB";
+ }
+
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+ else
+ {
+ used_dim = "kB";
+ double tmp_used = m_item->shareObject()->totalDiskSpace() - m_item->shareObject()->freeDiskSpace();
+ used = QString( "%1" ).arg( tmp_used, 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->freeDiskSpace() >= 1024 )
+ {
+ double tmp_free = m_item->shareObject()->freeDiskSpace() / 1024;
+ free_dim = "MB";
+
+ if ( tmp_free >= 1024 )
+ {
+ tmp_free = tmp_free / 1024;
+ free_dim = "GB";
+ }
+
+ free = QString( "%1" ).arg( tmp_free, 0, 'f', 1 );
+ }
+ else
+ {
+ free_dim = "kB";
+ free = QString( "%1" ).arg( m_item->shareObject()->freeDiskSpace(), 0, 'f', 1 );
+ }
+
+ if ( m_item->shareObject()->totalDiskSpace() >= 1024 )
+ {
+ double tmp_total = m_item->shareObject()->totalDiskSpace() / 1024;
+ total_dim = "MB";
+
+ if ( tmp_total >= 1024 )
+ {
+ tmp_total = tmp_total / 1024;
+ total_dim = "GB";
+ }
+
+ total = QString( "%1" ).arg( tmp_total, 0, 'f', 1 );
+ }
+ else
+ {
+ total_dim = "kB";
+ total = QString( "%1" ).arg( m_item->shareObject()->totalDiskSpace(), 0, 'f', 1 );
+ }
+
+ m_free->setText( QString( "%1 %2" ).arg( free, free_dim ) );
+ m_used->setText( QString( "%1 %2" ).arg( used, used_dim ) );
+ m_total->setText( QString( "%1 %2" ).arg( total, total_dim ) );
+ m_usage->setText( QString( "%1 %" ).arg( m_item->shareObject()->percentage(), 0, 'f', 1 ) );
+ }
+ else
+ {
+ QLabel *free_label = static_cast<QLabel *>( child( "FreeLabel", "QLabel" ) );
+
+ if ( free_label )
+ {
+ m_layout->remove( free_label );
+ delete free_label;
+ }
+
+ if ( m_free )
+ {
+ m_layout->remove( m_free );
+ delete m_free;
+ m_free = NULL;
+ }
+
+ QLabel *used_label = static_cast<QLabel *>( child( "UsedLabel", "QLabel" ) );
+
+ if ( used_label )
+ {
+ m_layout->remove( used_label );
+ delete used_label;
+ }
+
+ if ( m_used )
+ {
+ m_layout->remove( m_used );
+ delete m_used;
+ m_used = NULL;
+ }
+
+ QLabel *total_label = static_cast<QLabel *>( child( "TotalLabel", "QLabel" ) );
+
+ if ( total_label )
+ {
+ m_layout->remove( total_label );
+ delete total_label;
+ }
+
+ if ( m_total )
+ {
+ m_layout->remove( m_total );
+ delete m_total;
+ m_total = NULL;
+ }
+
+ QLabel *usage_label = static_cast<QLabel *>( child( "UsageLabel", "QLabel" ) );
+
+ if ( usage_label )
+ {
+ m_layout->remove( usage_label );
+ delete usage_label;
+ }
+
+ if ( m_usage )
+ {
+ m_layout->remove( m_usage );
+ delete m_usage;
+ m_usage = NULL;
+ }
+
+ QFont font;
+ font.setItalic( true );
+
+ QLabel *error = new QLabel( i18n( "This share is inaccessible." ), this );
+ error->setFont( font );
+ error->show();
+
+ m_layout->remove( m_pixmap );
+ m_pixmap->setPixmap( m_item->desktopPixmap() );
+
+ m_layout->addMultiCellWidget( error, 5, 5, 1, 2, Qt::AlignCenter );
+ m_layout->addMultiCellWidget( m_pixmap, 0, 5, 0, 0, Qt::AlignCenter );
+ }
+
+ adjustSize();
+}
+
+
+void Smb4KSharesListViewToolTip::mousePressEvent( QMouseEvent *e )
+{
+ hide();
+ QLabel::mousePressEvent( e );
+}
+
+
+void Smb4KSharesListViewToolTip::leaveEvent( QEvent *e )
+{
+ hide();
+ QLabel::leaveEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSharesListViewToolTip::slotHideToolTip()
+{
+ if ( isShown() )
+ {
+ hide();
+ }
+}
+
+#include "smb4kshareslistviewtooltip.moc"
diff --git a/smb4k/listview/smb4kshareslistviewtooltip.h b/smb4k/listview/smb4kshareslistviewtooltip.h
new file mode 100644
index 0000000..d15a68e
--- /dev/null
+++ b/smb4k/listview/smb4kshareslistviewtooltip.h
@@ -0,0 +1,160 @@
+/***************************************************************************
+ smb4kshareslistviewtooltip - Tool tip for the shares list view.
+ -------------------
+ begin : So Jul 8 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSHARESLISTVIEWTOOLTIP_H
+#define SMB4KSHARESLISTVIEWTOOLTIP_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qlabel.h>
+#include <qpoint.h>
+#include <qlayout.h>
+
+// Forward declarations:
+class Smb4KSharesListViewItem;
+
+/**
+ * This class provides the tool tip for the shares list view
+ * of Smb4K. It shows information about the associated share.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSharesListViewToolTip : public QLabel
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * Please note that the parent of the tool tip will be '0' and
+ * not the parent widget of @p item. Thus, you have to delete the
+ * tool tip object in the destructor of the parent widget.
+ *
+ * @param item The item for which the tool tip should be shown.
+ */
+ Smb4KSharesListViewToolTip( Smb4KSharesListViewItem *item );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSharesListViewToolTip();
+
+ /**
+ * Show the tool tip. Please note that the tool tip will not be
+ * shown exactly at position @p pos but with a displacement of 5
+ * pixels in x- and y-direction.
+ *
+ * @param pos The global position of the mouse pointer.
+ */
+ void showTip( const QPoint &pos );
+
+ /**
+ * The shares list view item for which the tool tip should be shown.
+ *
+ * @returns a pointer to a Smb4KSharesListViewItem object.
+ */
+ Smb4KSharesListViewItem *item() { return m_item; }
+
+ /**
+ * Update the tool tip by rereading the contents of the shareObject()
+ * provided by the Smb4KSharesListViewItem. This function only changes
+ * those entries that might have changed such as the free and used disk
+ * space and the usage.
+ */
+ void update();
+
+ protected:
+ /**
+ * Reimplemented from QLabel.
+ */
+ void mousePressEvent( QMouseEvent *e );
+
+ /**
+ * Reimplemented from QLabel.
+ */
+ void leaveEvent( QEvent *e );
+
+ protected slots:
+ /**
+ * This slot hides the tool tip after 10 sec.
+ */
+ void slotHideToolTip();
+
+ private:
+ /**
+ * The item for which the tool tip should be shown
+ */
+ Smb4KSharesListViewItem *m_item;
+
+ /**
+ * The layout of the tool tip.
+ */
+ QGridLayout *m_layout;
+
+ /**
+ * This function sets up the tool tip.
+ */
+ void setupTip();
+
+ /**
+ * Tells us if the tool tip has already been set up.
+ */
+ bool m_is_set_up;
+
+ /**
+ * This label holds the variable value of the free
+ * space left on the share.
+ */
+ QLabel *m_free;
+
+ /**
+ * This label holds the variable value of the used
+ * space on the share.
+ */
+ QLabel *m_used;
+
+ /**
+ * This label holds the value of the total space
+ * available on the share.
+ */
+ QLabel *m_total;
+
+ /**
+ * This label holds the variable value of the usage
+ */
+ QLabel *m_usage;
+
+ /**
+ * This label holds the pixmap.
+ */
+ QLabel *m_pixmap;
+};
+
+#endif
diff --git a/smb4k/main.cpp b/smb4k/main.cpp
new file mode 100644
index 0000000..e3907a6
--- /dev/null
+++ b/smb4k/main.cpp
@@ -0,0 +1,161 @@
+/***************************************************************************
+ main.cpp - Main file of the Smb4K program.
+ -------------------
+ begin : Sam M� 1 14:57:21 CET 2003
+ copyright : (C) 2003 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qstringlist.h>
+#include <qfile.h>
+
+// KDE includes
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <dcopclient.h>
+#include <kconfig.h>
+#include <kuniqueapplication.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+
+// system includes
+#include <stdlib.h>
+
+// application specific includes
+#include "smb4k.h"
+#include "core/smb4ksettings.h"
+#include "core/smb4kcore.h"
+
+
+static const char *description =
+ I18N_NOOP( "Smb4K is an advanced network neighborhood browser and a\n"
+ "front end to the programs of the Samba software suite." );
+
+static KCmdLineOptions options[] =
+{
+// { "+[File]", I18N_NOOP("file to open"), 0 },
+ { 0, 0, 0 }
+ // INSERT YOUR COMMANDLINE OPTIONS HERE
+};
+
+
+int main( int argc, char *argv[] )
+{
+ KAboutData aboutData( "smb4k", I18N_NOOP( "Smb4K" ),
+ VERSION, description, KAboutData::License_GPL,
+ I18N_NOOP( "(c) 2003-2008, Alexander Reinholdt\n(c) 2004-2008, Massimo Callegari\n(c) 2004, Franck Babin" ), 0, "http://smb4k.berlios.de", "[email protected]" );
+
+ // Authors:
+ aboutData.addAuthor( "Alexander Reinholdt", I18N_NOOP( "Developer" ), "[email protected]" );
+ aboutData.addAuthor( "Massimo Callegari", I18N_NOOP( "Developer" ), "[email protected]" );
+ aboutData.addAuthor( "Franck Babin", I18N_NOOP( "Developer" ), "[email protected]" );
+
+ // All our credits:
+ aboutData.addCredit( "Leopold Palomo Avellaneda", I18N_NOOP( "Catalan translation" ), "[email protected]" );
+ aboutData.addCredit( "Radoslaw Zawartko", I18N_NOOP( "Polish translation" ), "[email protected]" );
+ aboutData.addCredit( "Nick Chen", I18N_NOOP( "Chinese Simplified translation" ), "[email protected]" );
+ aboutData.addCredit( "Stanislav Yudin", I18N_NOOP( "Russian translation" ), "[email protected]" );
+ aboutData.addCredit( "Marc Hansen", I18N_NOOP( "Swedish translation and intensive testing" ), "[email protected]" );
+ aboutData.addCredit( "Giovanni Degani", I18N_NOOP( "Brazilian Portuguese translation" ), "[email protected]" );
+ aboutData.addCredit( "Ivan Petrouchtchak", I18N_NOOP( "Ukrainian translation" ), "[email protected]" );
+ aboutData.addCredit( "Karoly Barcza", I18N_NOOP( "Hungarian translation" ), "[email protected]" );
+ aboutData.addCredit( "Quique", I18N_NOOP( "Spanish translation" ), "[email protected]" );
+ aboutData.addCredit( "Michal Šulek", I18N_NOOP( "Slovak translation" ), "[email protected]" );
+ aboutData.addCredit( "Nicolas Ternisien", I18N_NOOP( "French translation" ), "[email protected]" );
+ aboutData.addCredit( "Toyohiro Asukai", I18N_NOOP( "Japanese translation" ), "[email protected]" );
+ aboutData.addCredit( "Atanas Mavrov", I18N_NOOP( "Bulgarian translation" ), "[email protected]" );
+ aboutData.addCredit( "Isidoro Russo", I18N_NOOP( "Italian translation" ), "[email protected]" );
+ aboutData.addCredit( "Nils Kristian Tomren", I18N_NOOP( "Norwegian translations" ), "[email protected]" );
+ aboutData.addCredit( "Alois Nešpor", I18N_NOOP( "Czech translation" ), "[email protected]" );
+ aboutData.addCredit( "Martín Carr", I18N_NOOP( "Spanish translation" ), "[email protected]" );
+ aboutData.addCredit( "Görkem Çetin", I18N_NOOP( "Turkish translation" ), "[email protected]" );
+ aboutData.addCredit( "Jack Liu", I18N_NOOP( "Chinese Traditional translation" ), "[email protected]" );
+ aboutData.addCredit( "Arnar Leósson", I18N_NOOP( "Icelandic translation" ), "[email protected]" );
+ aboutData.addCredit( "Michael Brinkloev", I18N_NOOP( "Danish translation" ), "[email protected]" );
+ aboutData.addCredit( "Joop Beris", I18N_NOOP( "Dutch translation" ), "[email protected]" );
+ aboutData.addCredit( "Lamarque V. Souza", I18N_NOOP( "Brazilian Portuguese translation" ), "[email protected]" );
+ aboutData.addCredit( "Serdar Soytetir", I18N_NOOP( "Turkish translation" ), "[email protected]" );
+ aboutData.addCredit( "Wei-Lun Chao", I18N_NOOP( "Chinese Traditional translation" ), "[email protected]" );
+ aboutData.addCredit( "Rashid N. Achilov", I18N_NOOP( "Testing of Smb4K under FreeBSD" ), "[email protected]" );
+ aboutData.addCredit( "Jerzy Trzeciak", I18N_NOOP( "Polish translation" ), "[email protected]" );
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+
+ KUniqueApplication::addCmdLineOptions();
+
+ // This is not needed, because KUniqueApplication::start()
+ // is called directly before the application is executed, but
+ // we use it anyway. There is no performance impact.
+ if ( !KUniqueApplication::start() )
+ {
+ exit( 0 );
+ }
+
+ KUniqueApplication app;
+
+ // Check the current config file and remove it if it belongs to
+ // a version < 0.9.0.
+ KConfig config( "smb4krc", false, false, "config" );
+
+ if ( !config.groupList().isEmpty() &&
+ (config.groupList().contains( "Browse Options" ) != 0 ||
+ config.groupList().contains( "Mount Options" ) != 0 ||
+ config.groupList().contains( "Rsync" ) != 0 ||
+ config.groupList().contains( "Super User Privileges") != 0 ||
+ config.groupList().contains( "User Interface" ) != 0 ||
+ config.groupList().contains( "System" ) != 0) )
+ {
+ int return_value = KMessageBox::warningContinueCancel( 0, i18n( "Smb4K now uses a different configuration system. Thus, your old settings are obsolete and you have to reconfigure the application.\nTo assure a clean transition, the current configuration file will be removed." ) );
+
+ if ( return_value == KMessageBox::Continue )
+ {
+ QString file_name = locateLocal( "config", "smb4krc", false );
+
+ if ( !file_name.isEmpty() && QFile::exists( file_name ) )
+ {
+ QFile::remove( file_name );
+ }
+ }
+ else
+ {
+ exit( 0 );
+ }
+ }
+
+ // Launch the application:
+ Smb4KApp *smb4k = new Smb4KApp( 0, "MainApp" );
+
+ app.setMainWidget( smb4k );
+
+ if ( !Smb4KSettings::embedIntoSystemTray() || !Smb4KSettings::startMainWindowDocked() )
+ {
+ smb4k->show();
+ }
+
+ Smb4KCore::self()->init();
+
+ int result = app.exec();
+
+ return result;
+}
diff --git a/smb4k/searchdlg/Makefile.am b/smb4k/searchdlg/Makefile.am
new file mode 100644
index 0000000..3045fab
--- /dev/null
+++ b/smb4k/searchdlg/Makefile.am
@@ -0,0 +1,10 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+kde_module_LTLIBRARIES = libsmb4ksearchdialog.la
+libsmb4ksearchdialog_la_LIBADD = $(top_builddir)/smb4k/core/libsmb4kcore.la \
+ $(LIB_KDECORE) $(LIB_KDEUI) $(KDE_PLUGIN) $(LIB_KPARTS) $(LIB_QT)
+noinst_HEADERS = smb4ksearchdialog.h smb4ksearchdialog_part.h \
+ smb4ksearchdialogitem.h
+libsmb4ksearchdialog_la_SOURCES = smb4ksearchdialog.cpp \
+ smb4ksearchdialog_part.cpp smb4ksearchdialogitem.cpp
+libsmb4ksearchdialog_la_LDFLAGS = -module -no-undefined $(all_libraries)
diff --git a/smb4k/searchdlg/smb4ksearchdialog.cpp b/smb4k/searchdlg/smb4ksearchdialog.cpp
new file mode 100644
index 0000000..bce09bb
--- /dev/null
+++ b/smb4k/searchdlg/smb4ksearchdialog.cpp
@@ -0,0 +1,200 @@
+/***************************************************************************
+ smb4ksearchdialog - The search dialog widget of Smb4K.
+ -------------------
+ begin : Sa Jun 2 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qlayout.h>
+#include <qstringlist.h>
+#include <qheader.h>
+
+// KDE includes
+#include <klocale.h>
+#include <kdebug.h>
+#include <kcombobox.h>
+
+// application specific includes
+#include "smb4ksearchdialog.h"
+#include "smb4ksearchdialogitem.h"
+#include "../core/smb4knetworkitems.h"
+
+Smb4KSearchDialog::Smb4KSearchDialog( QWidget *parent, const char *name )
+: QWidget( parent, name )
+{
+ QGridLayout *layout = new QGridLayout( this );
+ layout->setSpacing( 5 );
+
+ // Tool bar
+ m_tool_bar = new KToolBar( this, "SearchDialogToolBar", true, true );
+
+ m_tool_bar->insertCombo( QStringList(), Combo, true, SIGNAL( returnPressed() ),
+ this, SLOT( slotReturnPressed() ), true,
+ i18n( "Enter the search string here." ), -1, Combo );
+ m_tool_bar->setItemAutoSized( Combo, true );
+
+ m_tool_bar->insertSeparator();
+
+ m_tool_bar->insertButton( "find", Search, false, i18n( "Search" ) );
+ m_tool_bar->insertButton( "editdelete", Clear, false, i18n( "Clear" ) );
+ m_tool_bar->insertButton( "button_ok", Add, false, i18n( "Add" ) );
+
+ // List view
+ m_list_view = new KListView( this, "SearchDialogListView" );
+ m_list_view->addColumn( i18n( "Search Results" ), -1 );
+ m_list_view->header()->hide();
+ m_list_view->setSelectionMode( QListView::Single );
+
+ layout->addWidget( m_tool_bar, 0, 0, 0 );
+ layout->addWidget( m_list_view, 1, 0, 0 );
+
+ m_search_string = QString::null;
+
+ // Connections:
+ connect( m_tool_bar->getCombo( Combo ), SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( slotTextChanged( const QString & ) ) );
+
+ connect( m_tool_bar, SIGNAL( pressed( int ) ),
+ this, SLOT( slotButtonPressed( int ) ) );
+
+ connect( m_list_view, SIGNAL( clicked( QListViewItem * ) ),
+ this, SLOT( slotItemClicked( QListViewItem * ) ) );
+
+ connect( m_list_view, SIGNAL( selectionChanged( QListViewItem * ) ),
+ this, SLOT( slotSelectionChanged( QListViewItem * ) ) );
+}
+
+
+Smb4KSearchDialog::~Smb4KSearchDialog()
+{
+}
+
+
+const QString &Smb4KSearchDialog::searchString()
+{
+ m_search_string = m_tool_bar->getCombo( Combo )->currentText();
+
+ return m_search_string;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSearchDialog::slotReturnPressed()
+{
+ slotButtonPressed( Search );
+}
+
+
+void Smb4KSearchDialog::slotTextChanged( const QString &text )
+{
+ m_tool_bar->setItemEnabled( Search, !text.isEmpty() );
+ m_tool_bar->setItemEnabled( Clear, !text.isEmpty() );
+}
+
+
+void Smb4KSearchDialog::slotButtonPressed( int button_id )
+{
+ switch( button_id )
+ {
+ case Search:
+ {
+ // We will not remove the text from the edit line of the combo
+ // box like in earlier versions of Smb4K, but it will be selected
+ // later on, so that the user can easily remove it, if he wants to.
+ // We disable the combo box until the search process returns.
+ m_tool_bar->setItemEnabled( Combo, false );
+
+ break;
+ }
+ case Clear:
+ {
+ // Clear the combo box and the list view. The buttons
+ // will be disabled by slotTextChanged().
+ m_tool_bar->getCombo( Combo )->clear();
+ m_list_view->clear();
+
+ m_tool_bar->setItemEnabled( Search, false );
+ m_tool_bar->setItemEnabled( Clear, false );
+ m_tool_bar->setItemEnabled( Add, false );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ emit buttonPressed( button_id );
+}
+
+
+void Smb4KSearchDialog::slotItemClicked( QListViewItem *item )
+{
+ if ( !item )
+ {
+ // If there is no item, it means that the user clicked onto
+ // the viewport. In this case, disable the "Add" button and
+ // clear the current selection.
+ m_tool_bar->setItemEnabled( Add, false );
+
+ m_list_view->clearSelection();
+ }
+ else
+ {
+ // This is done by slotSelectionChanged().
+ }
+}
+
+
+void Smb4KSearchDialog::slotSelectionChanged( QListViewItem *item )
+{
+ if ( item )
+ {
+ // If we have got an item, enable the "Add" button if the
+ // item is regular. Otherwise disable the button.
+ Smb4KSearchDialogItem *search_item = static_cast<Smb4KSearchDialogItem *>( item );
+
+ if ( search_item->isRegular() )
+ {
+ m_tool_bar->setItemEnabled( Add, true );
+ }
+ else
+ {
+ m_tool_bar->setItemEnabled( Add, false );
+ }
+ }
+ else
+ {
+ // If there is no item, it means that the user clicked onto
+ // the viewport. In this case, disable the "Add" button and
+ // clear the current selection.
+ m_tool_bar->setItemEnabled( Add, false );
+
+ m_list_view->clearSelection();
+ }
+}
+
+#include "smb4ksearchdialog.moc"
diff --git a/smb4k/searchdlg/smb4ksearchdialog.h b/smb4k/searchdlg/smb4ksearchdialog.h
new file mode 100644
index 0000000..2b0f2eb
--- /dev/null
+++ b/smb4k/searchdlg/smb4ksearchdialog.h
@@ -0,0 +1,173 @@
+/***************************************************************************
+ smb4ksearchdialog - The search dialog widget of Smb4K.
+ -------------------
+ begin : Sa Jun 2 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSEARCHDIALOG_H
+#define SMB4KSEARCHDIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qwidget.h>
+#include <qstring.h>
+
+// KDE includes
+#include <klistview.h>
+#include <ktoolbar.h>
+
+// forward declarations
+class Smb4KHostItem;
+
+
+/**
+ * This is the search dialog. It enables the user to find servers,
+ * that were not found by the regular network scan.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+
+class Smb4KSearchDialog : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KSearchDialog( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSearchDialog();
+
+ /**
+ * This enumeration determines the place where the tool bar
+ * widgets are located.
+ */
+ enum ToolBarWidgets { Combo = 0, Search, Clear, Add };
+
+ /**
+ * Returns the search string the user entered. It's the current
+ * text of the combo box.
+ *
+ * @returns the search string.
+ */
+ const QString &searchString();
+
+ /**
+ * This function returns a pointer to the list view of this widget.
+ *
+ * @returns a pointer to the list view of this widget.
+ */
+ KListView *listView() { return m_list_view; }
+
+ /**
+ * This function returns a pointer to the tool bar of this widget.
+ *
+ * @returns a pointer to the tool bar of this widget.
+ */
+ KToolBar *toolBar() { return m_tool_bar; }
+
+ signals:
+ /**
+ * This signal is emitted everytime a button of the tool bar
+ * or the return key has been clicked. It passes the button id
+ * according to the ToolBarWidgets enumeration.
+ *
+ * @param button_id The button id
+ */
+ void buttonPressed( int button_id );
+
+ protected slots:
+ /**
+ * This slot is called when the search text has been entered
+ * and the return key has been pressed.
+ */
+ void slotReturnPressed();
+
+ /**
+ * This slot is activated when the text in the edit line of the
+ * combo box changed. It is used to enable and disable buttons.
+ *
+ * @param text The text input
+ */
+ void slotTextChanged( const QString &text );
+
+ /**
+ * This slot is activated when a button in the tool bar is pressed.
+ * It emits the buttonPressed() signal that can be processed by the
+ * KPart or other widgets. Additionally, it also executes those things
+ * that need not be done outside the widget, like clearing all the
+ * list box and the combo box.
+ *
+ * @param button_id The button id according to the ToolBarWidgets
+ * enumeration.
+ */
+ void slotButtonPressed( int button_id );
+
+ /**
+ * This slot is activated when the user clicked into the list view. It
+ * is used to disable the "Add" button in the tool bar when no item is
+ * selected, i.e. the user clicked on the viewport. The rest is done by
+ * slotSelectionChanged().
+ *
+ * @param item The list box item that the user clicked or NULL if
+ * he clicked onto the viewport.
+ */
+ void slotItemClicked( QListViewItem *item );
+
+ /**
+ * This slot is activated when the selection changed in the list view.
+ * It is used to enable/disable the "Add" button in the tool bar.
+ *
+ * @param item The list box item that's currently selected
+ */
+ void slotSelectionChanged( QListViewItem *item );
+
+ private:
+ /**
+ * The current search string
+ */
+ QString m_search_string;
+
+ /**
+ * The list box of this widget
+ */
+ KListView *m_list_view;
+
+ /**
+ * The tool bar of this widget
+ */
+ KToolBar *m_tool_bar;
+};
+
+#endif
diff --git a/smb4k/searchdlg/smb4ksearchdialog_part.cpp b/smb4k/searchdlg/smb4ksearchdialog_part.cpp
new file mode 100644
index 0000000..6a23df6
--- /dev/null
+++ b/smb4k/searchdlg/smb4ksearchdialog_part.cpp
@@ -0,0 +1,277 @@
+/***************************************************************************
+ smb4ksearchdialog_part - This Part encapsulates the search dialog
+ of Smb4K.
+ -------------------
+ begin : Fr Jun 1 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qimage.h>
+#include <qpixmap.h>
+
+// KDE includes
+#include <kaboutdata.h>
+#include <kinstance.h>
+#include <kdebug.h>
+#include <kiconeffect.h>
+#include <kiconloader.h>
+#include <kcombobox.h>
+
+// application specific includes
+#include "smb4ksearchdialog_part.h"
+#include "smb4ksearchdialog.h"
+#include "smb4ksearchdialogitem.h"
+#include "../core/smb4kcore.h"
+#include "../core/smb4knetworkitems.h"
+#include "../core/smb4kdefs.h"
+
+KInstance *Smb4KSearchDialogPartFactory::m_instance = 0L;
+KAboutData *Smb4KSearchDialogPartFactory::m_about = 0L;
+
+
+Smb4KSearchDialogPart::Smb4KSearchDialogPart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name )
+: KParts::Part( parent, name )
+{
+ // First of all we need an instance:
+ setInstance( Smb4KSearchDialogPartFactory::instance() );
+
+ // Set the XML file:
+// setXMLFile( "smb4ksearchdialog_part.rc" );
+
+ // Set the widget of this part:
+ m_widget = new Smb4KSearchDialog( parentWidget, widgetName );
+ setWidget( m_widget );
+
+ m_serial_number = 0;
+
+ // Connections:
+ connect( m_widget, SIGNAL( buttonPressed( int ) ),
+ this, SLOT( slotButtonPressed( int ) ) );
+
+ connect( m_widget->listView(), SIGNAL( doubleClicked( QListViewItem * ) ),
+ this, SLOT( slotItemDoubleClicked( QListViewItem * ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( searchResult( Smb4KHostItem * ) ),
+ this, SLOT( slotReceivedSearchResult( Smb4KHostItem * ) ) );
+
+ connect( Smb4KCore::scanner(), SIGNAL( hostListChanged() ),
+ this, SLOT( slotCheckItemIsKnown() ) );
+}
+
+
+Smb4KSearchDialogPart::~Smb4KSearchDialogPart()
+{
+}
+
+
+void Smb4KSearchDialogPart::customEvent( QCustomEvent *e )
+{
+ switch ( e->type() )
+ {
+ case EVENT_LOAD_SETTINGS:
+ {
+ // Not needed at the moment.
+
+ break;
+ }
+ case EVENT_SET_FOCUS:
+ {
+ m_widget->toolBar()->getCombo( Smb4KSearchDialog::Combo )->lineEdit()->setFocus();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ KParts::Part::customEvent( e );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS (Smb4KSearchDialogPart)
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSearchDialogPart::slotButtonPressed( int button_id )
+{
+ switch ( button_id )
+ {
+ case Smb4KSearchDialog::Search:
+ {
+ Smb4KCore::scanner()->search( m_widget->searchString() );
+
+ break;
+ }
+ case Smb4KSearchDialog::Add:
+ {
+ Smb4KSearchDialogItem *search_item = static_cast<Smb4KSearchDialogItem *>( m_widget->listView()->currentItem() );
+
+ if ( search_item && !search_item->isKnown() )
+ {
+ Smb4KCore::scanner()->insertHost( search_item->hostItem() );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void Smb4KSearchDialogPart::slotReceivedSearchResult( Smb4KHostItem *item )
+{
+ if ( item )
+ {
+ // Create a Smb4KSearchDialogItem. This will also add it
+ // to the list box.
+ (void) new Smb4KSearchDialogItem( m_widget->listView(), item, m_serial_number++ );
+
+ // Enable the combo box and set the focus:
+ m_widget->toolBar()->setItemEnabled( Smb4KSearchDialog::Combo, true );
+ m_widget->toolBar()->getCombo( Smb4KSearchDialog::Combo )->setFocus();
+
+ // Now select the text, so that the user can easily
+ // remove it.
+ int string_length = m_widget->toolBar()->getCombo( Smb4KSearchDialog::Combo )->lineEdit()->text().length();
+ m_widget->toolBar()->getCombo( Smb4KSearchDialog::Combo )->lineEdit()->setSelection( 0, string_length );
+
+ slotCheckItemIsKnown();
+ }
+}
+
+
+void Smb4KSearchDialogPart::slotCheckItemIsKnown()
+{
+ QListViewItemIterator it( m_widget->listView() );
+
+ while ( it.current() )
+ {
+ Smb4KSearchDialogItem *item = static_cast<Smb4KSearchDialogItem *>( it.current() );
+
+ if ( item && item->isRegular() )
+ {
+ Smb4KHostItem *host = Smb4KCore::scanner()->getHost( item->hostItem()->name(), item->hostItem()->workgroup() );
+
+ item->setKnown( (host ? true : false) );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ ++it;
+ }
+}
+
+
+void Smb4KSearchDialogPart::slotItemDoubleClicked( QListViewItem *item )
+{
+ if ( item )
+ {
+ // If we have got an item, enable the "Add" button if the
+ // item is regular. Otherwise disable the button.
+ Smb4KSearchDialogItem *search_item = static_cast<Smb4KSearchDialogItem *>( item );
+
+ if ( search_item && search_item->isRegular() && !search_item->isKnown() )
+ {
+ Smb4KCore::scanner()->insertHost( search_item->hostItem() );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// FACTORY STUFF
+/////////////////////////////////////////////////////////////////////////////
+
+Smb4KSearchDialogPartFactory::Smb4KSearchDialogPartFactory()
+: KParts::Factory()
+{
+}
+
+
+Smb4KSearchDialogPartFactory::~Smb4KSearchDialogPartFactory()
+{
+ delete m_instance;
+ delete m_about;
+
+ m_instance = 0L;
+}
+
+
+KParts::Part *Smb4KSearchDialogPartFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
+QObject *parent, const char *name, const char *, const QStringList & )
+{
+ Smb4KSearchDialogPart *obj = new Smb4KSearchDialogPart( parentWidget, widgetName, parent, name );
+
+ // See if we are to be read-write or not
+// if (QCString(classname) == "KParts::ReadOnlyPart")
+// {
+// obj->setReadWrite(false);
+// }
+
+ return obj;
+}
+
+
+KInstance *Smb4KSearchDialogPartFactory::instance()
+{
+ if( !m_instance )
+ {
+ m_about = new KAboutData( "smb4ksearchdialogpart", I18N_NOOP( "Smb4KSearchDialogPart" ), "1.0" );
+ m_about->addAuthor("Alexander Reinholdt", 0, "[email protected]");
+ m_about->setLicense( KAboutData::License_GPL );
+ m_instance = new KInstance( m_about );
+ }
+
+ return m_instance;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// INIT
+/////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+{
+ void *init_libsmb4ksearchdialog()
+ {
+ KGlobal::locale()->insertCatalogue( "smb4k" );
+ return new Smb4KSearchDialogPartFactory;
+ }
+}
+
+#include "smb4ksearchdialog_part.moc"
diff --git a/smb4k/searchdlg/smb4ksearchdialog_part.h b/smb4k/searchdlg/smb4ksearchdialog_part.h
new file mode 100644
index 0000000..0638a1b
--- /dev/null
+++ b/smb4k/searchdlg/smb4ksearchdialog_part.h
@@ -0,0 +1,171 @@
+/***************************************************************************
+ smb4ksearchdialog_part - This Part encapsulates the search dialog
+ of Smb4K.
+ -------------------
+ begin : Fr Jun 1 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSEARCHDIALOGPART_H
+#define SMB4KSEARCHDIALOGPART_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <qlistview.h>
+
+// KDE includes
+#include <kparts/part.h>
+#include <kparts/factory.h>
+
+// forward declarations
+class Smb4KSearchDialog;
+class Smb4KHostItem;
+
+
+/**
+ * This is one of the parts of Smb4K. It contains the search dialog.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSearchDialogPart : public KParts::Part
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parentWidget The parent widget
+ *
+ * @param widgetName The name the widget should have
+ *
+ * @param parent The parent object
+ *
+ * @param name The name this object should have
+ */
+ Smb4KSearchDialogPart( QWidget *parentWidget = 0, const char *widgetName = 0,
+ QObject *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ virtual ~Smb4KSearchDialogPart();
+
+ protected:
+ /**
+ * Reimplemented from KParts::Part.
+ */
+ void customEvent( QCustomEvent *e );
+
+ protected slots:
+ /**
+ * This slot is connected to the Smb4KSearchDialog::buttonPressed()
+ * signal. It initializes the search process, etc.
+ *
+ * @param button_id The button id according to
+ * Smb4KSearchDialog::ToolBarWidgets.
+ */
+ void slotButtonPressed( int button_id );
+
+ /**
+ * This slot retrieves the search result and puts it into the search
+ * dialog.
+ *
+ * @param item A Smb4KHostItem object
+ */
+ void slotReceivedSearchResult( Smb4KHostItem *item );
+
+ /**
+ * This slot is connected to the Smb4KScanner::hostListChanged() signal
+ * and checks whether the host is already known, i.e. it is in the browser,
+ * or if it is "new". If it is already known, this slot will change the icon
+ * of the host item from the default one to one with a tick layed over.
+ */
+ void slotCheckItemIsKnown();
+
+ /**
+ * This slot is invoked, when a user double clicks an item. It adds the item
+ * to the list of known hosts (if necessary).
+ *
+ * @param item The item that has been double clicked.
+ */
+ void slotItemDoubleClicked( QListViewItem *item );
+
+ private:
+ /**
+ * This is the actual search dialog widget.
+ */
+ Smb4KSearchDialog *m_widget;
+
+ /**
+ * Work around insertion "problems" of the search dialog items.
+ */
+ int m_serial_number;
+};
+
+
+class KInstance;
+class KAboutData;
+
+class Smb4KSearchDialogPartFactory : public KParts::Factory
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor
+ */
+ Smb4KSearchDialogPartFactory();
+
+ /**
+ * The destructor
+ */
+ virtual ~Smb4KSearchDialogPartFactory();
+
+ /**
+ * Reimplemented from KParts::Factory
+ */
+ virtual KParts::Part *createPartObject( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name,
+ const char *classname, const QStringList &args );
+
+ /**
+ * The instance
+ */
+ static KInstance *instance();
+
+ private:
+ /**
+ * The factory's instance.
+ */
+ static KInstance *m_instance;
+
+ /**
+ * The factory's KAboutData object
+ */
+ static KAboutData *m_about;
+};
+
+#endif
diff --git a/smb4k/searchdlg/smb4ksearchdialogitem.cpp b/smb4k/searchdlg/smb4ksearchdialogitem.cpp
new file mode 100644
index 0000000..525072e
--- /dev/null
+++ b/smb4k/searchdlg/smb4ksearchdialogitem.cpp
@@ -0,0 +1,140 @@
+/***************************************************************************
+ smb4ksearchdialogitem - This class is an enhanced version of a list
+ box item for Smb4K.
+ -------------------
+ begin : So Jun 3 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qimage.h>
+
+// KDE includes
+#include <kiconloader.h>
+#include <kiconeffect.h>
+#include <klocale.h>
+
+// application specific includes
+#include "smb4ksearchdialogitem.h"
+#include "smb4ksearchdialog.h"
+#include "../core/smb4knetworkitems.h"
+
+
+Smb4KSearchDialogItem::Smb4KSearchDialogItem( KListView *listView, Smb4KHostItem *item, int serial )
+: KListViewItem( listView ), m_item( *item ), m_serial( serial )
+{
+ m_is_known = false;
+
+ if ( !m_item.name().isEmpty() )
+ {
+ m_is_regular = true;
+
+ QString item_text = m_item.name();
+
+ if ( !m_item.workgroup().isEmpty() && !m_item.ip().isEmpty() )
+ {
+ item_text.append( " ["+m_item.workgroup()+", "+m_item.ip()+"]" );
+ }
+ else
+ {
+ if ( !m_item.workgroup().isEmpty() )
+ {
+ item_text.append( " ["+m_item.workgroup()+"]" );
+ }
+ else if ( !m_item.ip().isEmpty() )
+ {
+ // This case will most likely never appear.
+ item_text.append( " ["+m_item.ip()+"]" );
+ }
+ else
+ {
+ // Add nothing to the item text.
+ }
+ }
+
+ setText( 0, item_text );
+ setIcon();
+ }
+ else
+ {
+ m_is_regular = false;
+
+ setText( 0, i18n( "The search failed." ) );
+ setIcon();
+ }
+}
+
+
+Smb4KSearchDialogItem::~Smb4KSearchDialogItem()
+{
+}
+
+
+void Smb4KSearchDialogItem::setIcon()
+{
+ if ( m_is_regular )
+ {
+ if ( m_is_known )
+ {
+ KIconEffect e;
+ QImage over = SmallIcon( "button_ok" ).convertToImage();
+ QImage src = SmallIcon( "server" ).convertToImage();
+ e.semiTransparent( over );
+ e.overlay( src, over );
+
+ QPixmap pix( src );
+
+ setPixmap( 0, pix );
+ }
+ else
+ {
+ setPixmap( 0, SmallIcon( "server" ) );
+ }
+ }
+ else
+ {
+ setPixmap( 0, SmallIcon( "no" ) );
+ }
+}
+
+
+void Smb4KSearchDialogItem::setKnown( bool known )
+{
+ m_is_known = known;
+
+ setIcon();
+}
+
+
+int Smb4KSearchDialogItem::compare( QListViewItem *i, int, bool ascending ) const
+{
+ Smb4KSearchDialogItem *item = static_cast<Smb4KSearchDialogItem *>( i );
+
+ int result = 0;
+
+ if ( item )
+ {
+ result = item->serialNumber() - serialNumber();
+ }
+
+ return (ascending ? result : -result);
+}
+
diff --git a/smb4k/searchdlg/smb4ksearchdialogitem.h b/smb4k/searchdlg/smb4ksearchdialogitem.h
new file mode 100644
index 0000000..97dbbc9
--- /dev/null
+++ b/smb4k/searchdlg/smb4ksearchdialogitem.h
@@ -0,0 +1,166 @@
+/***************************************************************************
+ smb4ksearchdialogitem - This class is an enhanced version of a list
+ box item for Smb4K.
+ -------------------
+ begin : So Jun 3 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSEARCHDIALOGITEM_H
+#define SMB4KSEARCHDIALOGITEM_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Qt includes
+#include <klistview.h>
+
+// application specific includes
+#include "../core/smb4knetworkitems.h"
+
+
+/**
+ * This class is an enhanced version of KListViewItem, that is used
+ * by the search dialog of Smb4K to show the search results. It
+ * encapsulates a Smb4KHostItem which carries all the information needed.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KSearchDialog;
+class Smb4KSearchDialogItem : public KListViewItem
+{
+ public:
+ /**
+ * The constructor. It will construct an list view item and set its
+ * text according to the contents of @p item. If the search failed
+ * and @p item is empty, an error message will be displayed.
+ *
+ * @param listBox The parent list box.
+ *
+ * @param item The host item that represents the search
+ * result.
+ *
+ * @param serial The user supplied serial number of this item. It
+ * is used for sorting. See compare() for further information.
+ */
+ Smb4KSearchDialogItem( KListView *listView, Smb4KHostItem *item, int serial = 0 );
+
+ /**
+ * The destructor
+ */
+ ~Smb4KSearchDialogItem();
+
+ /**
+ * This function returns the Smb4KHostItem object that is encapsulated
+ * here.
+ *
+ * Make sure you copy the contents to a new item, because the pointer
+ * will be invalidated if this Smb4KSearchDialogItem is deleted.
+ *
+ * @returns the encapsulated Smb4KHostItem object.
+ */
+ Smb4KHostItem *hostItem() { return &m_item; }
+
+ /**
+ * This function returns TRUE, if the item is regular, that means it
+ * represents a host. If it represents a failed search, it returns
+ * FALSE.
+ *
+ * @returns TRUE is the item is a regular one.
+ */
+ bool isRegular() { return m_is_regular; }
+
+ /**
+ * This function notifies the item that the host that it represents is
+ * known to the application, i.e. it is in the list of hosts. It will set
+ * the pixmap accordingly and sets m_is_known.
+ *
+ * @param known Should be TRUE is the host is known.
+ */
+ void setKnown( bool known );
+
+ /**
+ * This function returns TRUE, if the item is already known by the scanner.
+ *
+ * @returns TRUE is the item is already known.
+ */
+ bool isKnown() { return m_is_known; }
+
+ /**
+ * This function is used for sorting.
+ *
+ * @returns the serial number of this item.
+ */
+ int serialNumber() const { return m_serial; }
+
+ /**
+ * Reimplemented from QListViewItem. It is used for sorting and compares the
+ * serial numbers of this item and @p item. If @p ascending is TRUE and the
+ * serial number of this item is greater than that of @p item, it will be inserted
+ * before @p item and else it will be inserted after. In this implementation,
+ * @p col is *not* used.
+ *
+ * @param item The list view item with that this one is compared.
+ *
+ * @param col The column that should be used for sorting. It is
+ * not used in this implementation.
+ *
+ * @param ascending Sort ascending if TRUE or descending if FALSE.
+ *
+ * @returns 0 if serialNumber() and @p item->serialNumber() are equal and != 0 if
+ * they are not. Which value and especially which algebraic sign is returned depends
+ * on the values that are returned by of both serialNumber() functions and on @p ascending.
+ */
+ int compare( QListViewItem *item, int col, bool ascending ) const;
+
+ private:
+ /**
+ * The Smb4KHostItem object
+ */
+ Smb4KHostItem m_item;
+
+ /**
+ * TRUE, if we have a regular item
+ */
+ bool m_is_regular;
+
+ /**
+ * TRUE is the item is known
+ */
+ bool m_is_known;
+
+ /**
+ * This function sets the icon of the item. It looks at m_is_known and
+ * m_is_regular to decide which icon to choose.
+ */
+ void setIcon();
+
+ /**
+ * The user defined index of this item.
+ */
+ int m_serial;
+};
+
+
+#endif
diff --git a/smb4k/smb4k.cpp b/smb4k/smb4k.cpp
new file mode 100644
index 0000000..a2877ae
--- /dev/null
+++ b/smb4k/smb4k.cpp
@@ -0,0 +1,1019 @@
+/***************************************************************************
+ smb4k.cpp - The main class of Smb4K.
+ -------------------
+ begin : Sam Mär 1 14:57:21 CET 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qvaluelist.h>
+#include <qpopupmenu.h>
+
+// KDE includes
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <klibloader.h>
+#include <kmessagebox.h>
+#include <kuniqueapplication.h>
+#include <kiconloader.h>
+#include <kactionclasses.h>
+#include <klocale.h>
+#include <kprogress.h>
+#include <kconfigdialog.h>
+#include <kaccel.h>
+
+// application specific includes
+#include "smb4k.h"
+#include "smb4ksystemtray.h"
+#include "dialogs/smb4kbookmarkeditor.h"
+#include "core/smb4ksettings.h"
+#include "core/smb4kcore.h"
+#include "core/smb4kglobal.h"
+#include "core/smb4kbookmark.h"
+#include "core/smb4kshare.h"
+#include "core/smb4kdefs.h"
+
+using namespace Smb4KGlobal;
+
+
+Smb4KApp::Smb4KApp( QWidget *parent, const char *name )
+: KParts::DockMainWindow( parent, name )
+{
+ m_system_tray = NULL;
+
+ m_shares_part = NULL;
+ m_browser_part = NULL;
+ m_search_part = NULL;
+
+ // Set XML file:
+ setXMLFile( "smb4k_shell.rc" );
+
+ // Set up the actions.
+ setupActions();
+
+ // Set up the status bar:
+ setupStatusBar();
+
+ // Set up the view:
+ setupView();
+
+ // Setup all things that need to be done *after* createGUI()
+ // was run:
+ QPopupMenu *settings = static_cast<QPopupMenu *>( child( "settings", "QPopupMenu", true ) );
+
+ if ( settings )
+ {
+ settings->insertItem( i18n( "&Dock Widgets" ), dockHideShowMenu(), 3, 3 );
+ }
+
+ slotSetupBookmarksMenu();
+
+ // Set up the system tray window:
+ setupSystemTray();
+
+ // Resize main window (will be overwritten by configuration):
+ resize( 800, 600 );
+
+ // Apply main window settings:
+ applyMainWindowSettings( Smb4KSettings::self()->config(), "MainWindow" );
+ readDockConfig( Smb4KSettings::self()->config(), "MainWindow" );
+
+ // We have to set the tab labels here. The writeDockConfig()
+ // readDockConfig() combo will ignore changes of the localization,
+ // because the first labels will be saved and then loaded again
+ // and again.
+ KDockWidget *dock = NULL;
+ KDockTabGroup *parent_group = NULL;
+
+ if ( (dock = manager()->getDockWidgetFromName( "NetworkBrowser" )) != NULL )
+ {
+ dock->setTabPageLabel( i18n( "Network Browser" ) );
+
+ if ( (parent_group = dock->parentDockTabGroup()) != NULL )
+ {
+ parent_group->changeTab( dock, i18n( "Network Browser" ) );
+ }
+ }
+
+ if ( (dock = manager()->getDockWidgetFromName( "SearchDialog" )) != NULL )
+ {
+ dock->setTabPageLabel( i18n( "Search Dialog" ) );
+
+ if ( (parent_group = dock->parentDockTabGroup()) != NULL )
+ {
+ parent_group->changeTab( dock, i18n( "Search Dialog" ) );
+ }
+ }
+
+ // Connections
+ connect( actionCollection(), SIGNAL( actionHighlighted( KAction * ) ),
+ this, SLOT( slotActionHighlighted( KAction * ) ) );
+
+ connect( Smb4KCore::self(), SIGNAL( runStateChanged() ),
+ this, SLOT( slotRunStateChanged() ) );
+
+ connect( Smb4KCore::bookmarkHandler(), SIGNAL( bookmarksUpdated() ),
+ this, SLOT( slotSetupBookmarksMenu() ) );
+
+ connect( Smb4KCore::mounter(), SIGNAL( updated() ),
+ this, SLOT( slotShareListUpdated() ) );
+}
+
+
+Smb4KApp::~Smb4KApp()
+{
+}
+
+
+void Smb4KApp::setupActions()
+{
+ actionCollection()->setHighlightingEnabled( true );
+
+ (void) KStdAction::quit( this, SLOT( slotQuit() ), actionCollection(), "quit_action" );
+
+ // Set up the "Settings" menu:
+ setStandardToolBarMenuEnabled( true );
+ createStandardStatusBarAction();
+
+ KActionMenu *view_modes = new KActionMenu( i18n( "Shares Vie&w" ), "view_choose",
+ actionCollection(), "view_modes_menu" );
+
+ KRadioAction *icon_view = new KRadioAction( i18n( "&Icon View" ), "view_icon", CTRL+Key_I,
+ this, SLOT( slotChangeSharesView() ), actionCollection(), "icon_view_action" );
+ icon_view->setExclusiveGroup( "SharesViewActions" );
+
+ KRadioAction *list_view = new KRadioAction( i18n( "List Vie&w" ), "view_detailed", CTRL+Key_W,
+ this, SLOT( slotChangeSharesView() ), actionCollection(), "list_view_action" );
+ list_view->setExclusiveGroup( "SharesViewActions" );
+
+ switch ( Smb4KSettings::sharesView() )
+ {
+ case Smb4KSettings::EnumSharesView::IconView:
+ {
+ icon_view->setChecked( true );
+
+ break;
+ }
+ case Smb4KSettings::EnumSharesView::ListView:
+ {
+ list_view->setChecked( true );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ view_modes->insert( icon_view, -1 );
+ view_modes->insert( list_view, -1 );
+
+ (void) KStdAction::preferences( this, SLOT( slotConfigDialog() ), actionCollection(), "configure_action" );
+
+ // Notes:
+ // (1) Actions from the parts will be included by setupView().
+ // (2) The list of dock widgets will be plugged into the menu
+ // by setupView().
+ // (3) The bookmark menu is managed by slotSetupBookmarksMenu().
+}
+
+
+void Smb4KApp::setupStatusBar()
+{
+ // Insert the items:
+ statusBar()->insertItem( i18n( "Ready." ), Message, 1, false );
+
+ KProgress *progress = new KProgress( statusBar(), "StatusBarProgressBar", 0 );
+ progress->setFixedWidth( 75 );
+ progress->setFixedHeight( fontMetrics().height() );
+ progress->setPercentageVisible( false );
+ statusBar()->addWidget( progress, 0, true );
+
+ statusBar()->insertFixedItem( QString( "Smb4K %1" ).arg( VERSION ), Version, true );
+
+ // Align the items:
+ statusBar()->setItemAlignment( Message, AlignAuto );
+ statusBar()->setItemAlignment( Progress, AlignCenter );
+ statusBar()->setItemAlignment( Version, AlignAuto );
+}
+
+
+void Smb4KApp::setupView()
+{
+ //
+ // Main widget (shares view):
+ //
+ KLibFactory *shares_factory = NULL;
+
+ m_current_shares_view = Smb4KSettings::sharesView();
+
+ switch ( Smb4KSettings::sharesView() )
+ {
+ case Smb4KSettings::EnumSharesView::IconView:
+ {
+ shares_factory = KLibLoader::self()->factory( "libsmb4ksharesiconview" );
+
+ break;
+ }
+ case Smb4KSettings::EnumSharesView::ListView:
+ {
+ shares_factory = KLibLoader::self()->factory( "libsmb4kshareslistview" );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if ( shares_factory )
+ {
+ m_shares_part = static_cast<KParts::Part *>( shares_factory->create( this, "SharesPart", "KParts::Part" ) );
+
+ if ( m_shares_part )
+ {
+ KDockWidget *main = createDockWidget( "SharesView", SmallIcon( "hdd_mount" ), 0L );
+ main->setWidget( m_shares_part->widget() );
+ main->setDockSite( KDockWidget::DockCorner );
+ main->setEnableDocking( KDockWidget::DockNone );
+ setView( main );
+ setMainDockWidget( main );
+
+ createGUI( m_shares_part );
+
+ accel()->insert( i18n( "Jump to shares view" ), CTRL+Key_3, this, SLOT( slotJumpToSharesView() ), false, true );
+ }
+ }
+ else
+ {
+ KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );
+
+ KApplication::exit( 0 );
+
+ return;
+ }
+
+ //
+ // Browser widget:
+ //
+ KLibFactory *browser_factory = KLibLoader::self()->factory( "libsmb4knetworkbrowser" );
+
+ if ( browser_factory )
+ {
+ m_browser_part = static_cast<KParts::Part *>( browser_factory->create( this, "BrowserPart", "KParts::Part" ) );
+
+ if ( m_browser_part )
+ {
+ KDockWidget *network = createDockWidget( "NetworkBrowser", SmallIcon( "network" ), 0L, i18n( "Network Browser" ) );
+ network->setWidget( m_browser_part->widget() );
+ network->manualDock( getMainDockWidget(), KDockWidget::DockLeft, 45 );
+
+ factory()->addClient( m_browser_part );
+
+ accel()->insert( i18n( "Jump to network browser" ), CTRL+Key_1, this, SLOT( slotJumpToNetworkBrowser() ), false, true );
+ }
+ }
+ else
+ {
+ KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );
+
+ KApplication::exit( 0 );
+
+ return;
+ }
+
+ //
+ // Search dialog
+ //
+ KLibFactory *search_factory = KLibLoader::self()->factory( "libsmb4ksearchdialog" );
+
+ if ( search_factory )
+ {
+ m_search_part = static_cast<KParts::Part *>( search_factory->create( this, "SearchDialogPart", "KParts::Part" ) );
+
+ if ( m_search_part )
+ {
+ KDockWidget *search = createDockWidget( "SearchDialog", SmallIcon( "find" ), 0L, i18n( "Search Dialog" ) );
+ search->setWidget( m_search_part->widget() );
+
+ KDockWidget *network = manager()->getDockWidgetFromName( "NetworkBrowser" );
+
+ if ( network )
+ {
+ search->manualDock( network, KDockWidget::DockCenter, 0 );
+ }
+ else
+ {
+ search->manualDock( getMainDockWidget(), KDockWidget::DockLeft, 45 );
+ }
+
+ factory()->addClient( m_search_part );
+
+ accel()->insert( i18n( "Jump to search dialog" ), CTRL+Key_2, this, SLOT( slotJumpToSearchDialog() ), false, true );
+ }
+ }
+ else
+ {
+ KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );
+
+ KApplication::exit( 0 );
+
+ return;
+ }
+}
+
+
+void Smb4KApp::setupSystemTray()
+{
+ if ( !m_system_tray )
+ {
+ m_system_tray = new Smb4KSystemTray( this, "SystemTray" );
+ }
+
+ connect( m_system_tray, SIGNAL( quitSelected() ),
+ this, SLOT( slotQuit() ) );
+
+ connect( m_system_tray, SIGNAL( settingsChanged() ),
+ this, SLOT( slotSettingsChanged() ) );
+
+ m_system_tray->embed( Smb4KSettings::embedIntoSystemTray() );
+}
+
+
+void Smb4KApp::changeSharesView()
+{
+ // Change the information about the current view:
+ m_current_shares_view = Smb4KSettings::sharesView();
+
+ // Save dock widget settings:
+ writeDockConfig( Smb4KSettings::self()->config(), "MainWindow" );
+
+ // Clear the shares view
+ factory()->removeClient( m_shares_part );
+
+ KDockWidget *dock = NULL;
+
+ if ( (dock = manager()->getDockWidgetFromName( "SharesView" )) != NULL )
+ {
+ delete dock;
+ }
+
+ // Load the new shares view:
+ KLibFactory *shares_factory = NULL;
+
+ switch ( Smb4KSettings::sharesView() )
+ {
+ case Smb4KSettings::EnumSharesView::IconView:
+ {
+ shares_factory = KLibLoader::self()->factory( "libsmb4ksharesiconview" );
+
+ break;
+ }
+ case Smb4KSettings::EnumSharesView::ListView:
+ {
+ shares_factory = KLibLoader::self()->factory( "libsmb4kshareslistview" );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if ( shares_factory )
+ {
+ m_shares_part = static_cast<KParts::Part *>( shares_factory->create( this, "SharesPart", "KParts::Part" ) );
+
+ if ( m_shares_part )
+ {
+ KDockWidget *main = createDockWidget( "SharesView", SmallIcon( "hdd_mount" ), this );
+ main->setWidget( m_shares_part->widget() );
+ main->setDockSite( KDockWidget::DockCorner );
+ main->setEnableDocking( KDockWidget::DockNone );
+ setView( main );
+ setMainDockWidget( main );
+
+ factory()->addClient( m_shares_part );
+ }
+ }
+ else
+ {
+ KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );
+
+ KApplication::exit( 0 );
+
+ return;
+ }
+
+ // Apply the settings to the dock widgets:
+ readDockConfig( Smb4KSettings::self()->config(), "MainWindow" );
+}
+
+
+bool Smb4KApp::queryExit()
+{
+ Smb4KSettings::setStartMainWindowDocked( !isVisible() );
+
+ saveMainWindowSettings( Smb4KSettings::self()->config(), "MainWindow" );
+ writeDockConfig( Smb4KSettings::self()->config(), "MainWindow" );
+
+ hide();
+
+ if ( m_system_tray )
+ {
+ delete m_system_tray;
+ m_system_tray = NULL;
+ }
+
+ // Save any options here that have to be written directly
+ // before the application exits:
+
+ return true;
+}
+
+
+bool Smb4KApp::queryClose()
+{
+ if ( !kapp->sessionSaving() && isVisible() && m_system_tray->isEmbedded() &&
+ Smb4KSettings::embedIntoSystemTray() )
+ {
+ // This part has been 'stolen' from JuK application.
+ KMessageBox::information(this,
+ i18n( "Closing the main window will keep Smb4K running in the system tray. "
+ "Use \"Quit\" from the \"File\" menu to quit the application."),
+ i18n( "Docking in System Tray" ), "ClosingMainWindowInfo" );
+
+ hide();
+
+ return false;
+
+ }
+ else
+ {
+ return true;
+ }
+}
+
+
+void Smb4KApp::timerEvent( QTimerEvent * )
+{
+ KProgress *progress_bar = static_cast<KProgress *>( child( "StatusBarProgressBar", "KProgress", true ) );
+
+ if ( progress_bar )
+ {
+ progress_bar->setProgress( progress_bar->progress() + 1 );
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////
+
+void Smb4KApp::slotQuit()
+{
+ statusBar()->changeItem( i18n( "Exiting..." ), Message );
+
+ if ( m_system_tray->isEmbedded() )
+ {
+ m_system_tray->embed( false );
+ }
+
+ KApplication::exit( 0 );
+}
+
+
+void Smb4KApp::slotChangeSharesView()
+{
+ // Let's be sure that the last action that was highlighted is
+ // indeed an action that changes the shares view:
+ QString action_name;
+
+ if ( m_action )
+ {
+ action_name = QString( m_action->name() );
+
+ if ( QString::compare( action_name, "icon_view_action" ) != 0 &&
+ QString::compare( action_name, "list_view_action" ) != 0 )
+ {
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ KRadioAction *shares_view_action = static_cast<KRadioAction *>( m_action );
+
+ // Set the check mark for the action:
+ if ( !shares_view_action->isChecked() )
+ {
+ shares_view_action->setChecked( true );
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ // Change the shares view setting and save it:
+ if ( QString::compare( action_name, "icon_view_action" ) == 0 )
+ {
+ Smb4KSettings::setSharesView( Smb4KSettings::EnumSharesView::IconView );
+ }
+ else if ( QString::compare( action_name, "list_view_action" ) == 0 )
+ {
+ Smb4KSettings::setSharesView( Smb4KSettings::EnumSharesView::ListView );
+ }
+ else
+ {
+ return;
+ }
+
+ Smb4KSettings::writeConfig();
+
+ changeSharesView();
+}
+
+
+void Smb4KApp::slotConfigDialog()
+{
+ // If the config dialog is already created and cached,
+ // we do not create a new one but show the old instead:
+ if ( KConfigDialog::showDialog( "ConfigDialog" ) )
+ {
+ return;
+ }
+
+ // Load the factory of the config dialog:
+ KLibFactory *config_factory = KLibLoader::self()->factory( "libsmb4kconfigdialog" );
+
+ if ( config_factory )
+ {
+ KConfigDialog *dlg = static_cast<KConfigDialog *>( config_factory->create( this, "ConfigDialog", "KConfigDialog" ) );
+
+ if ( dlg )
+ {
+ connect( dlg, SIGNAL( settingsChanged() ), this, SLOT( slotSettingsChanged() ) );
+
+ dlg->show();
+ }
+ }
+ else
+ {
+ KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );
+
+ return;
+ }
+}
+
+
+void Smb4KApp::slotSettingsChanged()
+{
+ // Adjust settings for the system tray widget:
+ if ( m_system_tray )
+ {
+ m_system_tray->loadSettings();
+ m_system_tray->embed( Smb4KSettings::embedIntoSystemTray() );
+ }
+
+ // (Re-)Load the correct shares view.
+ if ( m_current_shares_view != Smb4KSettings::sharesView() )
+ {
+ changeSharesView();
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ // Notify the parts to reload the settings.
+ // Note: QApplication::postEvent() will delete the QCustomEvent pointers.
+ QApplication::postEvent( m_browser_part, new QCustomEvent( EVENT_LOAD_SETTINGS ) );
+ QApplication::postEvent( m_search_part, new QCustomEvent( EVENT_LOAD_SETTINGS ) );
+ QApplication::postEvent( m_shares_part, new QCustomEvent( EVENT_LOAD_SETTINGS ) );
+}
+
+
+void Smb4KApp::slotBookmarkEditor()
+{
+ Smb4KBookmarkEditor *dlg = static_cast<Smb4KBookmarkEditor *>( child( "BookmarkEditor", "Smb4KBookmarkEditor", true ) );
+
+ if ( !dlg )
+ {
+ dlg = new Smb4KBookmarkEditor( this, "BookmarkEditor" );
+ }
+
+ dlg->show();
+}
+
+
+void Smb4KApp::slotRunStateChanged()
+{
+ // Get the progress bar:
+ KProgress *progress_bar = static_cast<KProgress *>( child( "StatusBarProgressBar", "KProgress", true ) );
+
+ // Clear the status bar:
+ statusBar()->clear();
+
+ // Set the status bar message:
+ switch( Smb4KCore::currentState() )
+ {
+ case SCANNER_INIT:
+ {
+ switch ( Smb4KSettings::browseList() )
+ {
+ case Smb4KSettings::EnumBrowseList::LookupDomains:
+ {
+ statusBar()->changeItem( i18n( "Looking up workgroups and domains..." ), Message );
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::QueryCurrentMaster:
+ {
+ statusBar()->changeItem( i18n( "Querying current master browser..." ), Message );
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::QueryCustomMaster:
+ {
+ statusBar()->changeItem( i18n( "Querying master browser %1..." ).arg( Smb4KSettings::customMasterBrowser().upper() ), Message );
+
+ break;
+ }
+ case Smb4KSettings::EnumBrowseList::ScanBroadcastAreas:
+ {
+ statusBar()->changeItem( i18n( "Scanning broadcast areas..." ), Message );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ break;
+ }
+ case SCANNER_OPENING_WORKGROUP:
+ {
+ statusBar()->changeItem( i18n( "Opening workgroup..." ), Message );
+
+ break;
+ }
+ case SCANNER_OPENING_HOST:
+ {
+ statusBar()->changeItem( i18n( "Retrieving list of shares..." ), Message );
+
+ break;
+ }
+ case SCANNER_RETRIEVING_INFO:
+ {
+ statusBar()->changeItem( i18n( "Retrieving additional information..." ), Message );
+
+ break;
+ }
+ case SCANNER_SEARCHING:
+ {
+ statusBar()->changeItem( i18n( "Searching..." ), Message );
+
+ break;
+ }
+ case SCANNER_RETRYING_OPENING_HOST:
+ {
+ statusBar()->changeItem( i18n( "Retrying to retrieve list of shares..." ), Message );
+
+ break;
+ }
+ case SCANNER_STOP:
+ {
+ statusBar()->changeItem( i18n( "Done." ), Message );
+
+ break;
+ }
+ case MOUNTER_MOUNTING:
+ {
+ statusBar()->changeItem( i18n( "Mounting share..." ), Message );
+
+ break;
+ }
+ case MOUNTER_UNMOUNTING:
+ {
+ statusBar()->changeItem( i18n( "Unmounting share..." ), Message );
+
+ break;
+ }
+ case MOUNTER_STOP:
+ {
+ statusBar()->changeItem( i18n( "Done." ), Message );
+
+ break;
+ }
+ case PRINT_START:
+ {
+ statusBar()->changeItem( i18n( "Printing file..." ), Message );
+
+ break;
+ }
+ case PRINT_STOP:
+ {
+ statusBar()->changeItem( i18n( "Done." ), Message );
+
+ break;
+ }
+ case SYNCHRONIZER_START:
+ {
+ statusBar()->changeItem( i18n( "Synchronizing data..." ), Message );
+
+ break;
+ }
+ case SYNCHRONIZER_STOP:
+ {
+ statusBar()->changeItem( i18n( "Done." ), Message );
+
+ break;
+ }
+ case PREVIEWER_START:
+ {
+ statusBar()->changeItem( i18n( "Generating preview..." ), Message );
+
+ break;
+ }
+ case PREVIEWER_STOP:
+ {
+ statusBar()->changeItem( i18n( "Done." ), Message );
+
+ break;
+ }
+ case CORE_STOP:
+ {
+ statusBar()->changeItem( i18n( "Ready." ), Message );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // Set up the progress bar:
+ if ( Smb4KCore::isRunning() )
+ {
+ // If the progress bar exists and is already set to
+ // a totalSteps == 0, we do not need to do anything
+ // here.
+ if ( progress_bar && progress_bar->totalSteps() != 0 )
+ {
+ progress_bar->setTotalSteps( 0 );
+
+ m_timer_id = startTimer( TIMER_INTERVAL );
+ }
+ }
+ else
+ {
+ if ( progress_bar )
+ {
+ killTimer( m_timer_id );
+
+ progress_bar->setTotalSteps( 100 );
+ progress_bar->reset();
+ }
+ }
+}
+
+
+void Smb4KApp::slotSetupBookmarksMenu()
+{
+ // Set up bookmark related actions:
+ QValueList<Smb4KBookmark *> bookmarks = Smb4KCore::bookmarkHandler()->getBookmarks();
+
+ if ( !actionCollection()->action( "edit_bookmarks_action" ) )
+ {
+ unplugActionList( "bookmark_actions" );
+
+ QPtrList<KAction> bookmark_actions;
+
+ // Create the "Edit Bookmarks" action:
+ bookmark_actions.append( new KAction( i18n( "&Edit Bookmarks" ), "bookmark", CTRL+Key_E,
+ this, SLOT( slotBookmarkEditor() ), actionCollection(),
+ "edit_bookmarks_action" ) );
+
+ // Get the "Add Bookmark" action from the browser:
+ QPtrList<KXMLGUIClient> clients_list = factory()->clients();
+
+ for ( QPtrList<KXMLGUIClient>::Iterator it = clients_list.begin(); it != clients_list.end(); ++it )
+ {
+ if ( (*it)->action( "bookmark_action" ) )
+ {
+ bookmark_actions.append( (*it)->action( "bookmark_action" ) );
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ bookmark_actions.append( new KActionSeparator() );
+
+ plugActionList( "bookmark_actions", bookmark_actions );
+ }
+
+ // Unplug the action list:
+ unplugActionList( "bookmarks" );
+
+ // Get the bookmark action list and delete all entries. We could
+ // also try to keep those actions that are not obsolete, but I think
+ // this is the cleanest way.
+ KActionPtrList list = actionCollection()->actions( "Bookmarks" );
+
+ for ( KActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ actionCollection()->remove( *it );
+ }
+
+ // Set up the menu:
+ if ( bookmarks.isEmpty() )
+ {
+ actionCollection()->action( "edit_bookmarks_action" )->setEnabled( false );
+ }
+ else
+ {
+ actionCollection()->action( "edit_bookmarks_action" )->setEnabled( true );
+
+ // Work around sorting problems:
+ QStringList display_strings;
+
+ for ( QValueListIterator<Smb4KBookmark *> it = bookmarks.begin(); it != bookmarks.end(); ++it )
+ {
+ if ( !(*it)->label().isEmpty() && Smb4KSettings::showCustomBookmarkLabel() )
+ {
+ display_strings.append( (*it)->label() );
+ }
+ else
+ {
+ display_strings.append( (*it)->bookmark() );
+ }
+ }
+
+ display_strings.sort();
+
+ // Create the bookmark list and plug it into the menu:
+ QPtrList<KAction> bookmark_list;
+
+ for ( QStringList::ConstIterator it = display_strings.begin(); it != display_strings.end(); ++it )
+ {
+ KAction *a = new KAction( *it, "folder", KShortcut::null(), 0, 0, actionCollection(), *it );
+ a->setGroup( "Bookmarks" );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotBookmarkActivated() ) );
+ bookmark_list.append( a );
+ }
+
+ plugActionList( "bookmarks", bookmark_list );
+ }
+}
+
+
+void Smb4KApp::slotBookmarkActivated()
+{
+ if ( m_action && QString::compare( m_action->group(), "Bookmarks" ) == 0 )
+ {
+ Smb4KBookmark *bookmark = NULL;
+
+ if ( !m_action->plainText().startsWith( "//" ) )
+ {
+ bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( m_action->plainText() );
+ }
+ else
+ {
+ bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByName( m_action->plainText() );
+ }
+
+ if ( bookmark )
+ {
+ Smb4KCore::mounter()->mountShare( bookmark->workgroup(), bookmark->host(),
+ bookmark->ip(), bookmark->share() );
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KApp::slotShareListUpdated()
+{
+ KActionPtrList list = actionCollection()->actions( "Bookmarks" );
+
+ if ( !list.isEmpty() )
+ {
+ QString name;
+
+ for ( KActionPtrList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ {
+ if ( !(*it)->plainText().startsWith( "//" ) )
+ {
+ Smb4KBookmark *bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( (*it)->plainText() );
+
+ name = bookmark->bookmark();
+ }
+ else
+ {
+ name = (*it)->plainText();
+ }
+
+ QValueList<Smb4KShare> share_list = Smb4KCore::mounter()->findShareByName( name );
+
+ bool enable = true;
+
+ for ( QValueList<Smb4KShare>::ConstIterator i = share_list.begin(); i != share_list.end(); ++i )
+ {
+ if ( !(*i).isForeign() )
+ {
+ enable = false;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ (*it)->setEnabled( enable );
+ }
+ }
+}
+
+
+void Smb4KApp::slotActionHighlighted( KAction *action )
+{
+ m_action = action;
+}
+
+
+void Smb4KApp::slotJumpToNetworkBrowser()
+{
+ KDockWidget *dock = NULL;
+
+ if ( (dock = manager()->getDockWidgetFromName( "NetworkBrowser" )) != NULL &&
+ dock->isHidden() )
+ {
+ manager()->getDockWidgetFromName( "NetworkBrowser" )->changeHideShowState();
+ }
+
+ // Send a custom focus event to the browser, that tells it to set
+ // the focus to the list view widget.
+ QApplication::postEvent( m_browser_part, new QCustomEvent( EVENT_SET_FOCUS ) );
+}
+
+
+void Smb4KApp::slotJumpToSearchDialog()
+{
+ KDockWidget *dock = NULL;
+
+ if ( (dock = manager()->getDockWidgetFromName( "SearchDialog" )) != NULL &&
+ dock->isHidden() )
+ {
+ manager()->getDockWidgetFromName( "SearchDialog" )->changeHideShowState();
+ }
+
+ // Send a custom focus event to the search dialog, that tells it
+ // to set the focus to the combo box in the tool bar.
+ QApplication::postEvent( m_search_part, new QCustomEvent( EVENT_SET_FOCUS ) );
+}
+
+
+void Smb4KApp::slotJumpToSharesView()
+{
+ // Send a custom focus event to the shares view, that tells it
+ // to set the focus to its main widget.
+ QApplication::postEvent( m_shares_part, new QCustomEvent( EVENT_SET_FOCUS ) );
+}
+
+#include "smb4k.moc"
+
diff --git a/smb4k/smb4k.desktop b/smb4k/smb4k.desktop
new file mode 100644
index 0000000..b0403f1
--- /dev/null
+++ b/smb4k/smb4k.desktop
@@ -0,0 +1,81 @@
+# KDE Config File
+[Desktop Entry]
+Name=Smb4K
+GenericName=The SMB/CIFS Share Browser
+GenericName[bg]=Самба ресурсен четец
+GenericName[ca]=El navegador de compartits SMB/CIFS
+GenericName[cs]=Prohližeč SMB/CIFS sdílení
+GenericName[da]=SMB/CIFS ressource browseren
+GenericName[de]=Der Browser für SMB/CIFS-Freigaben
+GenericName[es]=El explorador de recursos compartidos SMB/CIFS
+GenericName[fr]=L'explorateur de partages SMB / CIFS
+GenericName[hu]=Az SMB/CIFS böngésző
+GenericName[is]=SMB/CIFS sameignarflakkarinn
+GenericName[it]=Browser di condivisioni SMB/CIFS
+GenericName[ja]=SMB/CIFS 共有(シェア)・ブラウザー
+GenericName[nb]=SMB/CIFS ressursutforsker
+GenericName[nl]=De SMB/CIFS Share Browser
+GenericName[nn]=SMB/CIFS ressurs-surfar
+GenericName[pl]=Przeglądarka Zasobów SMB/CIFS
+GenericName[pt_BR]=O navegador de compartilhamentos SMB/CIFS
+GenericName[ru]=The SMB/CIFS Share Browser
+GenericName[sk]=Prehliadač SMB/CIFS zdieľaní
+GenericName[sv]=SMB Katalog programmed
+GenericName[tr]=The SMB/CIFS Share Browser
+GenericName[uk]=Навігатор спільних ресурсів SMB/CIFS
+GenericName[zh_CN]=SMB 共享浏览器
+#
+# The following lines seem to be necessary for SuSE.
+#
+Name[bg]=Smb4K
+Name[ca]=Smb4K
+Name[cs]=Smb4K
+Name[da]=Smb4K
+Name[de]=Smb4K
+Name[es]=Smb4K
+Name[fr]=Smb4K
+Name[hu]=Smb4K
+Name[is]=Smb4K
+Name[it]=Smb4K
+Name[ja]=Smb4K
+Name[nb]=Smb4K
+Name[nl]=Smb4K
+Name[nn]=Smb4K
+Name[pl]=Smb4K
+Name[pt_BR]=Smb4K
+Name[ru]=Smb4K
+Name[sk]=Smb4K
+Name[sv]=Smb4K
+Name[tr]=Smb4K
+Name[uk]=Smb4K
+Name[zh_CN]=Smb4K
+Comment=The SMB/CIFS Share Browser
+Comment[bg]=Самба ресурсен четец
+Comment[ca]=El navegador de compartits SMB/CIFS
+Comment[cs]=Prohližeč SMB/CIFS sdílení
+Comment[da]=SMB/CIFS ressource browseren
+Comment[de]=Der Browser für SMB/CIFS-Freigaben
+Comment[es]=El explorador de recursos compartidos SMB/CIFS
+Comment[fr]=L'explorateur de partages SMB / CIFS
+Comment[hu]=Az SMB/CIFS böngésző
+Comment[is]=SMB/CIFS sameignarflakkarinn
+Comment[it]=Browser di condivisioni SMB/CIFS
+Comment[ja]=SMB/CIFS 共有(シェア)・ブラウザー
+Comment[nb]=SMB/CIFS ressursutforsker
+Comment[nl]=De SMB/CIFS Share Browser
+Comment[nn]=SMB/CIFS ressurs-surfar
+Comment[pl]=Przeglądarka Zasobów SMB/CIFS
+Comment[pt_BR]=O navegador de compartilhamentos SMB/CIFS
+Comment[ru]=The SMB/CIFS Share Browser
+Comment[sk]=Prehliadač SMB/CIFS zdieľaní
+Comment[sv]=SMB Katalog programmed
+Comment[tr]=The SMB/CIFS Share Browser
+Comment[uk]=Навігатор спільних ресурсів SMB/CIFS
+Comment[zh_CN]=SMB 共享浏览器
+Exec=smb4k
+Icon=smb4k
+X-DocPath=smb4k/index.html
+Type=Application
+Terminal=false
+Categories=Qt;KDE;Utility;
+X-DCOP-ServiceType=Unique
diff --git a/smb4k/smb4k.h b/smb4k/smb4k.h
new file mode 100644
index 0000000..2021a47
--- /dev/null
+++ b/smb4k/smb4k.h
@@ -0,0 +1,229 @@
+/***************************************************************************
+ smb4k.h - The main class of Smb4K.
+ -------------------
+ begin : Sam M� 1 14:57:21 CET 2003
+ copyright : (C) 2003-2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4K_H
+#define SMB4K_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kaction.h>
+#include <kparts/dockmainwindow.h>
+
+// Forward declarations
+class Smb4KSystemTray;
+
+/**
+ * This is the application shell of Smb4K.
+ *
+ * @author Alexander Reinholdt <[email protected]>
+ */
+
+class Smb4KApp : public KParts::DockMainWindow
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent of this widget
+ *
+ * @param name The name of this widget
+ */
+ Smb4KApp( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KApp();
+
+ protected:
+ /**
+ * Reimplemented from KMainWindow.
+ */
+ bool queryExit();
+
+ /**
+ * Reimplemented from KMainWindow.
+ */
+ bool queryClose();
+
+ /**
+ * Reimplemented from QObject
+ */
+ void timerEvent( QTimerEvent *e );
+
+ protected slots:
+ /**
+ * Quit the application.
+ */
+ void slotQuit();
+
+ /**
+ * Replace the current shares view.
+ */
+ void slotChangeSharesView();
+
+ /**
+ * Open the configuration dialog. This slot is connected to the "Configure Smb4K..."
+ * action.
+ */
+ void slotConfigDialog();
+
+ /**
+ * This slot is invoked when the config dialog is closed and the settings have
+ * been changed. Emits the reloadSettings() signal and adjusts the system tray
+ * widget to the new settings afterwards.
+ */
+ void slotSettingsChanged();
+
+ /**
+ * Open the bookmark editor. This slot is connected to the "Edit Bookmarks"
+ * action.
+ */
+ void slotBookmarkEditor();
+
+ /**
+ * Show a message to the user what currently is done by the application. This
+ * slot is connected to the Smb4KCore::runStateChanged() signal.
+ */
+ void slotRunStateChanged();
+
+ /**
+ * This slot is invoked when the bookmarks have been updated. It inserts the
+ * bookmarks into the menu. Additionally, it enables the "Edit Bookmarks"
+ * action if there are bookmarks and else disables it.
+ */
+ void slotSetupBookmarksMenu();
+
+ /**
+ * This slot is invoked when/if a bookmark is activated.
+ */
+ void slotBookmarkActivated();
+
+ /**
+ * This slot is activated when the list of mounted shares has been updated.
+ * It is connected to the Smb4KMounter::updated() signal.
+ */
+ void slotShareListUpdated();
+
+ /**
+ * This slot is activated when an action is highlighted and lets m_action
+ * point to it. No validity checks are performed.
+ *
+ * @param action The action that has been highlighted
+ */
+ void slotActionHighlighted( KAction *action );
+
+ /**
+ * This slot sets the keyboard focus to the network browser and shows it
+ * if it is not already shown.
+ */
+ void slotJumpToNetworkBrowser();
+
+ /**
+ * This slot sets the keyboard focus to the search dialog and shows it
+ * if it is not already shown.
+ */
+ void slotJumpToSearchDialog();
+
+ /**
+ * This slot sets the keyboard focus to the shares view. Since it is the
+ * main widget, this slot does not care about it being hidden.
+ */
+ void slotJumpToSharesView();
+
+ private:
+ /**
+ * Set up actions.
+ */
+ void setupActions();
+
+ /**
+ * Set up the view.
+ */
+ void setupView();
+
+ /**
+ * Set up the status bar
+ */
+ void setupStatusBar();
+
+ /**
+ * Set up the system tray
+ */
+ void setupSystemTray();
+
+ /**
+ * Change the shares view.
+ */
+ void changeSharesView();
+
+ /**
+ * The shares view part
+ */
+ KParts::Part *m_shares_part;
+
+ /**
+ * The browser part
+ */
+ KParts::Part *m_browser_part;
+
+ /**
+ * The search dialog part
+ */
+ KParts::Part *m_search_part;
+
+ /**
+ * The system tray icon of this application
+ */
+ Smb4KSystemTray *m_system_tray;
+
+ /**
+ * Enumeration for the status bar
+ */
+ enum StatusBarItem{ Message = 0, Progress = 1, Version = 2 };
+
+ /**
+ * The currently highlighted KAction.
+ */
+ KAction *m_action;
+
+ /**
+ * This holds the config entry of the current shares
+ * view. This is used to avoid unnecessary loading.
+ */
+ int m_current_shares_view;
+
+ /**
+ * The timer id
+ */
+ int m_timer_id;
+};
+
+#endif
diff --git a/smb4k/smb4k_shell.rc b/smb4k/smb4k_shell.rc
new file mode 100644
index 0000000..365ed28
--- /dev/null
+++ b/smb4k/smb4k_shell.rc
@@ -0,0 +1,37 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="smb4k_shell" version="2">
+<MenuBar>
+ <Menu noMerge="1" name="file"><text>&amp;File</text>
+ <Action name="quit_action"/>
+ </Menu>
+ <Menu noMerge="1" name="network"><text>&amp;Network</text>
+ </Menu>
+ <Menu noMerge="1" name="shares"><text>Sh&amp;ares</text>
+ </Menu>
+ <Menu noMerge="1" name="bookmarks"><text>&amp;Bookmarks</text>
+ <!-- This menu will dynamically be filled by Smb4KApp. -->
+ <ActionList name="bookmark_actions"/>
+ <ActionList name="bookmarks"/>
+ </Menu>
+ <Menu noMerge="1" name="settings"><text>&amp;Settings</text>
+ <Merge name ="StandardToolBarMenuHandler"/>
+ <Action name="options_show_statusbar"/>
+ <Separator/>
+ <Merge/>
+ <Action name="view_modes_menu"/>
+ <Separator/>
+ <Action name="configure_action"/>
+ </Menu>
+</MenuBar>
+<!-- fullWidth="false" shortens the tool bar, so that it looks nicer. -->
+<ToolBar fullWidth="false" name="networkToolBar" index="0"><text>Network ToolBar</text>
+</ToolBar>
+<ToolBar fullWidth="false" name="sharesViewToolBar" index="1"><text>Shares View ToolBar</text>
+</ToolBar>
+<ToolBar fullWidth="true" noMerge="1" name="mainToolBar" index="2"><text>Main ToolBar</text>
+ <Action name="view_modes_menu"/>
+ <Action name="configure_action"/>
+ <Separator/>
+ <Action name="quit_action"/>
+</ToolBar>
+</kpartgui>
diff --git a/smb4k/smb4ksystemtray.cpp b/smb4k/smb4ksystemtray.cpp
new file mode 100644
index 0000000..336f0ec
--- /dev/null
+++ b/smb4k/smb4ksystemtray.cpp
@@ -0,0 +1,1079 @@
+/***************************************************************************
+ smb4ksystemtray - This is the system tray window class of Smb4K.
+ -------------------
+ begin : Mi Jun 13 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+// Qt includes
+#include <qtooltip.h>
+#include <qiconset.h>
+#include <qpixmap.h>
+#include <qimage.h>
+
+// KDE specific includes
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kpopupmenu.h>
+#include <kaction.h>
+#include <klibloader.h>
+#include <kmessagebox.h>
+#include <kconfigdialog.h>
+#include <kiconeffect.h>
+
+// application specific includes
+#include "smb4ksystemtray.h"
+#include "dialogs/smb4kmountdialog.h"
+#include "dialogs/smb4kbookmarkeditor.h"
+#include "dialogs/smb4ksynchronizationdialog.h"
+#include "core/smb4kcore.h"
+#include "core/smb4kbookmark.h"
+#include "core/smb4kshare.h"
+#include "core/smb4ksettings.h"
+
+
+Smb4KSystemTray::Smb4KSystemTray( QWidget *parent, const char *name )
+: KSystemTray( parent, name )
+{
+ setPixmap( loadIcon( "smb4k" ) );
+
+ QToolTip::add( this, i18n( "Smb4K" ) );
+
+ m_action = NULL;
+
+ // Enable highlighting of actions:
+ actionCollection()->setHighlightingEnabled( true );
+
+ // Set up the context menu (skeleton):
+ m_shares_menu = new KActionMenu( i18n( "Mounted Shares" ), "hdd_mount",
+ actionCollection(), "st_mounted_shares_action_menu" );
+ m_bookmarks_menu = new KActionMenu( i18n( "Bookmarks" ), "bookmark_folder",
+ actionCollection(), "st_bookmark_action_menu" );
+ KActionSeparator *sep = new KActionSeparator( this );
+ KAction *manual_mount = new KAction( i18n( "M&ount Manually" ), "connect_creating",
+ 0, this, SLOT( slotMountManually() ),
+ actionCollection(), "st_mount_manually_action" );
+ KAction *configure = KStdAction::preferences( this, SLOT( slotConfigDialog() ),
+ actionCollection(), "st_configure_action" );
+
+ m_shares_menu->plug( contextMenu() );
+ m_bookmarks_menu->plug( contextMenu() );
+ sep->plug( contextMenu() );
+ manual_mount->plug( contextMenu() );
+ configure->plug( contextMenu() );
+
+ // Set up the menus:
+ slotSetupBookmarksMenu();
+ slotSetupSharesMenu();
+
+ // Connections:
+ connect( actionCollection(), SIGNAL( actionHighlighted( KAction * ) ),
+ this, SLOT( slotActionHighlighted( KAction * ) ) );
+
+ connect( Smb4KCore::bookmarkHandler(), SIGNAL( bookmarksUpdated() ),
+ this, SLOT( slotSetupBookmarksMenu() ) );
+
+ connect( Smb4KCore::mounter(), SIGNAL( updated() ),
+ this, SLOT( slotEnableBookmarks() ) );
+
+ connect( Smb4KCore::mounter(), SIGNAL( updated() ),
+ this, SLOT( slotSetupSharesMenu() ) );
+
+ // Connection to quitSelected() signal must be done in parent widget.
+}
+
+
+Smb4KSystemTray::~Smb4KSystemTray()
+{
+}
+
+
+void Smb4KSystemTray::embed( bool ebd )
+{
+ if ( ebd )
+ {
+ show();
+ }
+ else
+ {
+ hide();
+ }
+}
+
+
+void Smb4KSystemTray::loadSettings()
+{
+ // Adjust the bookmarks menu.
+ // Since the menu is rebuilt everytime slotSetupBookmarksMenu() is
+ // called, we just call it and are done.
+ slotSetupBookmarksMenu();
+
+ // Adjust the shares menu.
+ // slotSetupSharesMenu() is doing everything for us, so just call it.
+ slotSetupSharesMenu();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KSystemTray::slotMountManually()
+{
+ Smb4KMountDialog *dlg = NULL;
+
+ if ( parentWidget() )
+ {
+ dlg = static_cast<Smb4KMountDialog *>( parentWidget()->child( "MountDialog", "Smb4KMountDialog", true ) );
+ }
+ else
+ {
+ dlg = static_cast<Smb4KMountDialog *>( child( "MountDialog", "Smb4KMountDialog", true ) );
+ }
+
+ if ( !dlg )
+ {
+ if ( parentWidget() && parentWidget()->isShown() )
+ {
+ dlg = new Smb4KMountDialog( parentWidget(), "MountDialog" );
+ }
+ else
+ {
+ dlg = new Smb4KMountDialog( this, "MountDialog" );
+ }
+ }
+
+ // The dialog will be closed destructively.
+ if ( !dlg->isShown() )
+ {
+ dlg->exec();
+ }
+}
+
+
+void Smb4KSystemTray::slotConfigDialog()
+{
+ // If the config dialog is already created and cached,
+ // we do not create a new one but show the old instead:
+ KConfigDialog *dlg = NULL;
+
+ if ( (dlg = KConfigDialog::exists( "ConfigDialog" )) && KConfigDialog::showDialog( "ConfigDialog" ) )
+ {
+ // To make sure we do not connect the config dialog several times
+ // to slotSettingsChanged(), we break the connection first and re-
+ // establish it afterwards:
+ disconnect( dlg, SIGNAL( settingsChanged() ), this, SLOT( slotSettingsChanged() ) );
+ connect( dlg, SIGNAL( settingsChanged() ), this, SLOT( slotSettingsChanged() ) );
+
+ return;
+ }
+
+ // Load the factory of the config dialog:
+ KLibFactory *config_factory = KLibLoader::self()->factory( "libsmb4kconfigdialog" );
+
+ if ( config_factory )
+ {
+ if ( parentWidget() && parentWidget()->isShown() )
+ {
+ dlg = static_cast<KConfigDialog *>( config_factory->create( parentWidget(), "ConfigDialog", "KConfigDialog" ) );
+ }
+ else
+ {
+ dlg = static_cast<KConfigDialog *>( config_factory->create( this, "ConfigDialog", "KConfigDialog" ) );
+ }
+
+ // ... and show it.
+ if ( dlg )
+ {
+ connect( dlg, SIGNAL( settingsChanged() ), this, SLOT( slotSettingsChanged() ) );
+
+ dlg->show();
+ }
+ }
+ else
+ {
+ KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );
+
+ return;
+ }
+}
+
+void Smb4KSystemTray::slotSettingsChanged()
+{
+ // Notify the parent that the settings changed:
+ emit settingsChanged();
+
+ // Execute loadSettings():
+ loadSettings();
+}
+
+
+void Smb4KSystemTray::slotSetupBookmarksMenu()
+{
+ // First check if we have to set up the menu completely:
+ if ( !actionCollection()->action( "st_edit_bookmarks_action" ) )
+ {
+ // OK, build the menu from ground up:
+ KAction *edit_bookmarks = new KAction( i18n( "&Edit Bookmarks" ), "bookmark", 0,
+ this, SLOT( slotBookmarkEditor() ), actionCollection(),
+ "st_edit_bookmarks_action" );
+ edit_bookmarks->setGroup( "BookmarkActions" );
+ edit_bookmarks->plug( m_bookmarks_menu->popupMenu() );
+
+ KActionSeparator *sep = new KActionSeparator( actionCollection(), "st_bookmark_action_separator" );
+ sep->setGroup( "BookmarkActions" );
+ sep->plug( m_bookmarks_menu->popupMenu() );
+ }
+
+ // Get the list of bookmark actions and delete all entries. We could
+ // also try to keep those actions that are not obsolete, but I think
+ // this is the cleanest way.
+ KActionPtrList list = actionCollection()->actions( "Bookmarks" );
+
+ for ( KActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ (*it)->unplug( m_bookmarks_menu->popupMenu() );
+ actionCollection()->remove( *it );
+ }
+
+ // Get the list of bookmarks:
+ QValueList<Smb4KBookmark *> bookmarks = Smb4KCore::bookmarkHandler()->getBookmarks();
+ QStringList display_strings;
+
+ // Prepare the list of bookmarks for display:
+ if ( !bookmarks.isEmpty() )
+ {
+ // Enable the "Edit Bookmarks" action:
+ actionCollection()->action( "st_edit_bookmarks_action" )->setEnabled( true );
+
+ // Work around sorting problems:
+ for ( QValueListIterator<Smb4KBookmark *> it = bookmarks.begin(); it != bookmarks.end(); ++it )
+ {
+ if ( !(*it)->label().isEmpty() && Smb4KSettings::showCustomBookmarkLabel() )
+ {
+ display_strings.append( (*it)->label() );
+ }
+ else
+ {
+ display_strings.append( (*it)->bookmark() );
+ }
+ }
+
+ display_strings.sort();
+ }
+ else
+ {
+ // Disable the "Edit Bookmarks" action:
+ actionCollection()->action( "st_edit_bookmarks_action" )->setEnabled( false );
+ }
+
+ for ( QStringList::ConstIterator it = display_strings.begin(); it != display_strings.end(); ++it )
+ {
+ // Create the bookmark action:
+ KAction *a = new KAction( *it, "folder", KShortcut::null(), 0, 0, actionCollection(), "st_"+*it );
+ a->setGroup( "Bookmarks" );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotBookmarkActivated() ) );
+
+ // Let's have a look if the bookmark action has to be enabled or disabled:
+ QString name;
+
+ if ( !(*it).startsWith( "//" ) )
+ {
+ Smb4KBookmark *bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( *it );
+
+ name = bookmark->bookmark();
+ }
+ else
+ {
+ name = *it;
+ }
+
+ QValueList<Smb4KShare> share_list = Smb4KCore::mounter()->findShareByName( name );
+
+ bool enable = true;
+
+ for ( QValueList<Smb4KShare>::ConstIterator i = share_list.begin(); i != share_list.end(); ++i )
+ {
+ if ( !(*i).isForeign() )
+ {
+ enable = false;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ a->setEnabled( enable );
+
+ // Plug the bookmark to the menu:
+ a->plug( m_bookmarks_menu->popupMenu() );
+ }
+}
+
+
+void Smb4KSystemTray::slotBookmarkEditor()
+{
+ Smb4KBookmarkEditor *dlg = NULL;
+
+ if ( parentWidget() )
+ {
+ dlg = static_cast<Smb4KBookmarkEditor *>( parentWidget()->child( "BookmarkEditor", "Smb4KBookmarkEditor", true ) );
+ }
+ else
+ {
+ dlg = static_cast<Smb4KBookmarkEditor *>( child( "BookmarkEditor", "Smb4KBookmarkEditor", true ) );
+ }
+
+ if ( !dlg )
+ {
+ if ( parentWidget() && parentWidget()->isShown() )
+ {
+ dlg = new Smb4KBookmarkEditor( parentWidget(), "BookmarkEditor" );
+ }
+ else
+ {
+ dlg = new Smb4KBookmarkEditor( this, "BookmarkEditor" );
+ }
+ }
+
+ if ( !dlg->isShown() )
+ {
+ dlg->show();
+ }
+}
+
+
+void Smb4KSystemTray::slotBookmarkActivated()
+{
+ if ( m_action && QString::compare( m_action->group(), "Bookmarks" ) == 0 )
+ {
+ Smb4KBookmark *bookmark = NULL;
+
+ if ( !m_action->plainText().startsWith( "//" ) )
+ {
+ bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( m_action->plainText() );
+ }
+ else
+ {
+ bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByName( m_action->plainText() );
+ }
+
+ if ( bookmark )
+ {
+ Smb4KCore::mounter()->mountShare( bookmark->workgroup(), bookmark->host(),
+ bookmark->ip(), bookmark->share() );
+ }
+ }
+ else
+ {
+ // Do nothing
+ }
+}
+
+
+void Smb4KSystemTray::slotEnableBookmarks()
+{
+ // Get the list of bookmarks:
+ KActionPtrList list = actionCollection()->actions( "Bookmarks" );
+
+ // Enable/diable the bookmark actions:
+ for ( KActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ QString name;
+
+ if ( !(*it)->plainText().startsWith( "//" ) )
+ {
+ Smb4KBookmark *bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( (*it)->plainText() );
+
+ name = bookmark->bookmark();
+ }
+ else
+ {
+ name = (*it)->plainText();
+ }
+
+ QValueList<Smb4KShare> share_list = Smb4KCore::mounter()->findShareByName( name );
+
+ bool enable = true;
+
+ for ( QValueList<Smb4KShare>::ConstIterator i = share_list.begin(); i != share_list.end(); ++i )
+ {
+ if ( !(*i).isForeign() )
+ {
+ enable = false;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ (*it)->setEnabled( enable );
+ }
+}
+
+
+void Smb4KSystemTray::slotSetupSharesMenu()
+{
+ // First check if we have to set up the menu completely:
+ if ( !actionCollection()->action( "st_unmount_all_action" ) )
+ {
+ // OK, build the menu from ground up:
+ KAction *unmount_all = new KAction( i18n( "U&nmount All" ), "gear", KShortcut::null(),
+ this, SLOT( slotUnmountAllShares() ), actionCollection(),
+ "st_unmount_all_action" );
+ unmount_all->setGroup( "ShareActions" );
+ unmount_all->plug( m_shares_menu->popupMenu(), 0 );
+
+ KActionSeparator *sep = new KActionSeparator( actionCollection(), "st_shares_action_separator" );
+ sep->setGroup( "ShareActions" );
+ sep->plug( m_shares_menu->popupMenu(), 1 );
+ }
+
+ // Since we are updating the list of shares very frequently, we should
+ // not delete all entries in the menu, but look for changes.
+
+ // Get the list of share actions:
+ KActionPtrList actions_list = actionCollection()->actions( "ShareMenus" );
+
+ // Get the list of mounted shares:
+ QValueList<Smb4KShare *> shares_list = Smb4KCore::mounter()->getShares();
+
+ if ( !shares_list.isEmpty() )
+ {
+ // Enable the "Unmount All" action:
+ actionCollection()->action( "st_unmount_all_action" )->setEnabled( true );
+
+ // Delete all obsolete actions:
+ for ( KActionPtrList::Iterator it = actions_list.begin(); it != actions_list.end(); ++it )
+ {
+ // Get the canonical path of the share action:
+ QString action_name = (*it)->name();
+ QString canonical_path = action_name.section( "st_[share_menu]_", 1, -1 );
+
+ // Check if the share is still present:
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );
+
+ // Decide if the share action has to be deleted or if it can stay:
+ if ( share )
+ {
+ // Keep the share if it either isn't foreign or all shares should
+ // be shown.
+ if ( !share->isForeign() || Smb4KSettings::showAllShares() )
+ {
+ // To avoid sorting problems later, we remove *all* actions that
+ // have *displayed texts* that do not match the current criterions.
+ if ( (!Smb4KSettings::showMountPoint() &&
+ QString::compare( (*it)->plainText(), share->name() ) == 0) ||
+ (Smb4KSettings::showMountPoint() &&
+ QString::compare( (*it)->plainText(), share->canonicalPath() ) == 0) )
+ {
+ // Find the "Force Unmount" action and decide if it needs to be
+ // enabled/disabled:
+ KAction *force = actionCollection()->action( "st_[force]_"+canonical_path );
+
+ if ( force )
+ {
+ force->setEnabled( Smb4KSettings::useForceUnmount() );
+ }
+
+ continue;
+ }
+ else
+ {
+ // First remove all actions that are in the submenu:
+ KAction *action = NULL;
+ KActionMenu *menu = static_cast<KActionMenu *>( *it );
+
+ if ( menu )
+ {
+ // Unmount action
+ action = actionCollection()->action( "st_[unmount]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+#ifdef __linux__
+ // Force Unmount action
+ action = actionCollection()->action( "st_[force]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+#endif
+
+ // Synchronize action
+ action = actionCollection()->action( "st_[synchronize]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konsole action
+ action = actionCollection()->action( "st_[konsole]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konqueror action
+ action = actionCollection()->action( "st_[filemanager]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+ }
+
+ // Now remove the menu itself:
+ (*it)->unplug( m_shares_menu->popupMenu() );
+ actionCollection()->remove( *it );
+
+ continue;
+ }
+ }
+ else
+ {
+ // First remove all actions that are in the submenu:
+ KAction *action = NULL;
+ KActionMenu *menu = static_cast<KActionMenu *>( *it );
+
+ if ( menu )
+ {
+ // Unmount action
+ action = actionCollection()->action( "st_[unmount]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+#ifdef __linux__
+ // Force Unmount action
+ action = actionCollection()->action( "st_[force]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+#endif
+
+ // Synchronize action
+ action = actionCollection()->action( "st_[synchronize]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konsole action
+ action = actionCollection()->action( "st_[konsole]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konqueror action
+ action = actionCollection()->action( "st_[filemanager]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+ }
+
+ // Now remove the menu itself:
+ (*it)->unplug( m_shares_menu->popupMenu() );
+ actionCollection()->remove( *it );
+
+ continue;
+ }
+ }
+ else
+ {
+ // First remove all actions that are in the submenu:
+ KAction *action = NULL;
+ KActionMenu *menu = static_cast<KActionMenu *>( *it );
+
+ if ( menu )
+ {
+ // Unmount action
+ action = actionCollection()->action( "st_[unmount]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+#ifdef __linux__
+ // Force Unmount action
+ action = actionCollection()->action( "st_[force]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+#endif
+
+ // Synchronize action
+ action = actionCollection()->action( "st_[synchronize]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konsole action
+ action = actionCollection()->action( "st_[konsole]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konqueror action
+ action = actionCollection()->action( "st_[filemanager]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+ }
+
+ // Now remove the menu itself:
+ (*it)->unplug( m_shares_menu->popupMenu() );
+ actionCollection()->remove( *it );
+
+ continue;
+ }
+ }
+
+ // Since we cannot sort the Smb4kShare items appropriately, we have to
+ // work around this problem. For that, let's create a string list:
+ QStringList strings;
+
+ for ( QValueList<Smb4KShare *>::ConstIterator it = shares_list.begin(); it != shares_list.end(); ++it )
+ {
+ if ( !(*it)->isForeign() || Smb4KSettings::showAllShares() )
+ {
+ if ( Smb4KSettings::showMountPoint() )
+ {
+ strings.append( (*it)->canonicalPath() );
+ }
+ else
+ {
+ // _::_ is the devider between share name and the canonical path of
+ // the share.
+ QString item = QString( "%1_::_%2" ).arg( (*it)->name(), (*it)->canonicalPath() );
+ strings.append( item );
+ }
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ strings.sort();
+
+ // We are ready to insert the new shares into the menu.
+ // We loop through the list of mounted shares and check if the
+ // single shares are already in the menu. If not, we plug them
+ // there:
+ for ( QValueList<Smb4KShare *>::ConstIterator it = shares_list.begin(); it != shares_list.end(); ++it )
+ {
+ KActionMenu *action_menu = NULL;
+
+ // Reread the list of share action menus:
+ KActionPtrList new_actions_list = actionCollection()->actions( "ShareMenus" );
+
+ for ( KActionPtrList::ConstIterator i = new_actions_list.begin(); i != new_actions_list.end(); ++i )
+ {
+ QString item = QString( "st_[share_menu]_%1" ).arg( (*it)->canonicalPath() );
+
+ if ( QString::compare( (*i)->name(), item ) == 0 )
+ {
+ action_menu = static_cast<KActionMenu *>( *i );
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ if ( !action_menu )
+ {
+ // Create a new KAction menu:
+ QIconSet set;
+ QPixmap pix;
+ KIconLoader loader;
+
+ int icon_state = (*it)->isForeign() ? KIcon::DisabledState : KIcon::DefaultState;
+
+ if ( (*it)->isBroken() )
+ {
+ QImage over = loader.loadIcon( "button_cancel", KIcon::Small,
+ 0, icon_state, 0L, false ).convertToImage();
+ QImage src = loader.loadIcon( "hdd_mount", KIcon::Small,
+ 0, icon_state, 0L, false ).convertToImage();
+
+ KIconEffect e;
+ e.semiTransparent( over );
+ e.overlay( src, over );
+
+ pix = QPixmap( src );
+ }
+ else
+ {
+ pix = loader.loadIcon( "hdd_mount", KIcon::Small,
+ 0, icon_state, 0L, false );
+ }
+
+ set.reset( pix, QIconSet::Automatic );
+
+ action_menu = new KActionMenu( Smb4KSettings::showMountPoint() ? (*it)->path() : (*it)->name(),
+ set, actionCollection(), "st_[share_menu]_"+(*it)->canonicalPath() );
+ action_menu->setGroup( "ShareMenus" );
+
+
+ // Define the actions that can be performed on a share from within
+ // the system tray widget:
+ KAction *umount = new KAction( i18n( "&Unmount" ), "hdd_unmount", KShortcut::null(), this,
+ SLOT( slotUnmountShare() ), actionCollection(), "st_[unmount]_"+(*it)->canonicalPath() );
+ umount->setGroup( "ShareActions" );
+#ifdef __linux__
+ KAction *force_umount = new KAction( i18n( "&Force Unmounting" ), "hdd_unmount", KShortcut::null(), this,
+ SLOT( slotForceUnmountShare() ), actionCollection(), "st_[force]_"+(*it)->canonicalPath() );
+ force_umount->setGroup( "ShareActions" );
+ force_umount->setEnabled( Smb4KSettings::useForceUnmount() );
+#endif
+ KAction *synchronize = new KAction( i18n( "S&ynchronize" ), "bottom", KShortcut::null(), this,
+ SLOT( slotSynchronize() ), actionCollection(), "st_[synchronize]_"+(*it)->canonicalPath() );
+ synchronize->setGroup( "ShareActions" );
+ synchronize->setEnabled( !Smb4KSettings::rsync().isEmpty() );
+
+ KAction *konsole = new KAction( i18n( "Open with Konso&le" ), "terminal", KShortcut::null(), this,
+ SLOT( slotKonsole() ), actionCollection(), "st_[konsole]_"+(*it)->canonicalPath() );
+ konsole->setGroup( "ShareActions" );
+ konsole->setEnabled( !Smb4KSettings::konsole().isEmpty() );
+
+ KAction *konqueror = new KAction( i18n( "Open with &Konqueror" ), "kfm_home", KShortcut::null(), this,
+ SLOT( slotFilemanager() ), actionCollection(), "st_[filemanager]_"+(*it)->canonicalPath() );
+ konqueror->setGroup( "ShareActions" );
+
+ // Set up the action submenu:
+ action_menu->insert( umount );
+#ifdef __linux__
+ action_menu->insert( force_umount );
+#endif
+ action_menu->popupMenu()->insertSeparator( -1 );
+ action_menu->insert( synchronize );
+ action_menu->popupMenu()->insertSeparator( -1 );
+ action_menu->insert( konsole );
+ action_menu->insert( konqueror );
+
+ // Plug the new menu to the popup menu:
+ int index = 0;
+
+ if ( !Smb4KSettings::showMountPoint() )
+ {
+ QString item = QString( "%1_::_%2" ).arg( (*it)->name(), (*it)->canonicalPath() );
+
+ index = strings.findIndex( item );
+ }
+ else
+ {
+ index = strings.findIndex( (*it)->canonicalPath() );
+ }
+
+ m_shares_menu->insert( action_menu, index + 2 ); // +2 due to "Unmount All" and separator
+ }
+ else
+ {
+ // Change icon and disable some actions, if the share got inaccessible
+ // in the meantime:
+ if ( (*it)->isBroken() )
+ {
+ QIconSet set;
+ QPixmap pix;
+ KIconLoader loader;
+
+ int icon_state = (*it)->isForeign() ? KIcon::DisabledState : KIcon::DefaultState;
+
+ QImage over = loader.loadIcon( "button_cancel", KIcon::Small,
+ 0, icon_state, 0L, false ).convertToImage();
+ QImage src = loader.loadIcon( "hdd_mount", KIcon::Small,
+ 0, icon_state, 0L, false ).convertToImage();
+
+ KIconEffect e;
+ e.semiTransparent( over );
+ e.overlay( src, over );
+
+ pix = QPixmap( src );
+
+ set.reset( pix, QIconSet::Automatic );
+
+ action_menu->setIconSet( set );
+
+ // Disable actions that should not be performed on an inaccessible
+ // share:
+ actionCollection()->action( "st_[synchronize]_"+(*it)->canonicalPath() )->setEnabled( false );
+ actionCollection()->action( "st_[konsole]_"+(*it)->canonicalPath() )->setEnabled( false );
+ actionCollection()->action( "st_[filemanager]_"+(*it)->canonicalPath() )->setEnabled( false );
+ }
+
+ // Change the text if necessary:
+ if ( !Smb4KSettings::showMountPoint() &&
+ QString::compare( action_menu->plainText(), (*it)->name() ) != 0 )
+ {
+ action_menu->setText( (*it)->name() );
+ }
+ else if ( Smb4KSettings::showMountPoint() &&
+ QString::compare( action_menu->plainText(), (*it)->path() ) != 0 )
+ {
+ action_menu->setText( (*it)->path() );
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+ }
+ }
+ else
+ {
+ // Remove all share action menus:
+ for ( KActionPtrList::Iterator it = actions_list.begin(); it != actions_list.end(); ++it )
+ {
+ KActionMenu *action_menu = static_cast<KActionMenu *>( *it );
+
+ // Get the canonical path of the share action:
+ QString action_name = action_menu->name();
+ QString canonical_path = action_name.section( "st_[share_menu]_", 1, -1 );
+
+ // Remove all children of the share action menus:
+ KAction *action = NULL;
+
+ // Unmount action
+ action = actionCollection()->action( "st_[unmount]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( action_menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+#ifdef __linux__
+ // Force Unmount action
+ action = actionCollection()->action( "st_[force]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( action_menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+#endif
+
+ // Synchronize action
+ action = actionCollection()->action( "st_[synchronize]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( action_menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konsole action
+ action = actionCollection()->action( "st_[konsole]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( action_menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Konqueror action
+ action = actionCollection()->action( "st_[filemanager]_"+canonical_path );
+
+ if ( action )
+ {
+ action->unplug( action_menu->popupMenu() );
+ actionCollection()->remove( action );
+ }
+
+ // Remove action menu itself:
+ action_menu->unplug( m_shares_menu->popupMenu() );
+ actionCollection()->remove( action_menu );
+ }
+
+ // Disable the "Unmount All" action:
+ actionCollection()->action( "st_unmount_all_action" )->setEnabled( false );
+ }
+}
+
+
+void Smb4KSystemTray::slotUnmountAllShares()
+{
+ Smb4KCore::mounter()->unmountAllShares();
+}
+
+
+void Smb4KSystemTray::slotUnmountShare()
+{
+ if ( m_action && QString( m_action->name() ).startsWith( "st_[unmount]_" ) )
+ {
+ QString canonical_path = QString( m_action->name() ).section( "st_[unmount]_", 1, 1 );
+
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );
+
+ if ( share )
+ {
+ Smb4KCore::mounter()->unmountShare( share, false, false );
+ }
+ }
+}
+
+
+void Smb4KSystemTray::slotForceUnmountShare()
+{
+ if ( m_action && QString( m_action->name() ).startsWith( "st_[force]_" ) )
+ {
+ QString canonical_path = QString( m_action->name() ).section( "st_[force]_", 1, 1 );
+
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );
+
+ if ( share )
+ {
+ Smb4KCore::mounter()->unmountShare( share, true, false );
+ }
+ }
+}
+
+
+void Smb4KSystemTray::slotSynchronize()
+{
+ // Since we want to allow the possibility to open several instances
+ // of the synchronization dialog, we do not checks like in slotConfigDialog()
+ if ( m_action && QString( m_action->name() ).startsWith( "st_[synchronize]_" ) )
+ {
+ QString canonical_path = QString( m_action->name() ).section( "st_[synchronize]_", 1, 1 );
+
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );
+
+ if ( share && !share->isBroken() )
+ {
+ Smb4KSynchronizationDialog *dlg = NULL;
+
+ if ( parentWidget() && parentWidget()->isShown() )
+ {
+ dlg = new Smb4KSynchronizationDialog( share, parentWidget(), "SynchronizationDialog" );
+ }
+ else
+ {
+ dlg = new Smb4KSynchronizationDialog( share, this, "SynchronizationDialog" );
+ }
+
+ dlg->show();
+ }
+ }
+}
+
+
+void Smb4KSystemTray::slotKonsole()
+{
+ if ( m_action && QString( m_action->name() ).startsWith( "st_[konsole]_" ) )
+ {
+ QString canonical_path = QString( m_action->name() ).section( "st_[konsole]_", 1, 1 );
+
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );
+
+ if ( share && !share->isBroken() )
+ {
+ Smb4KCore::open( share, Smb4KCore::Konsole );
+ }
+ }
+}
+
+
+void Smb4KSystemTray::slotFilemanager()
+{
+ if ( m_action && QString( m_action->name() ).startsWith( "st_[filemanager]_" ) )
+ {
+ QString canonical_path = QString( m_action->name() ).section( "st_[filemanager]_", 1, 1 );
+
+ Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );
+
+ if ( share && !share->isBroken() )
+ {
+ Smb4KCore::open( share, Smb4KCore::Konqueror );
+ }
+ }
+}
+
+
+void Smb4KSystemTray::slotActionHighlighted( KAction *action )
+{
+ // If the main window is not shown, the last action that
+ // is highlighted when the user clicks an action in a
+ // mounted-share-submenu is "st_mounted_shares_action_menu"
+ // and not the action the user clicked. That's why we need
+ // to filter this action out:
+ if ( action && !qstrcmp( action->name(), "st_mounted_shares_action_menu" ) )
+ {
+ return;
+ }
+
+ m_action = action;
+}
+
+#include "smb4ksystemtray.moc"
+
diff --git a/smb4k/smb4ksystemtray.h b/smb4k/smb4ksystemtray.h
new file mode 100644
index 0000000..c3d4d6b
--- /dev/null
+++ b/smb4k/smb4ksystemtray.h
@@ -0,0 +1,207 @@
+/***************************************************************************
+ smb4ksystemtray - This is the system tray window class of Smb4K.
+ -------------------
+ begin : Mi Jun 13 2007
+ copyright : (C) 2007 by Alexander Reinholdt
+ ***************************************************************************/
+
+/***************************************************************************
+ * 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, write to the *
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef SMB4KSYSTEMTRAY_H
+#define SMB4KSYSTEMTRAY_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <ksystemtray.h>
+#include <kactionclasses.h>
+
+class Smb4KSystemTray : public KSystemTray
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ *
+ * @param parent The parent widget of the system tray window
+ *
+ * @param name The name of the system tray window
+ */
+ Smb4KSystemTray( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ * The destructor.
+ */
+ ~Smb4KSystemTray();
+
+ /**
+ * Embeds the system tray window into the system tray, if @p ebd is
+ * TRUE. Otherwise, it removes it from there. Note, that the system tray
+ * icon won't be deleted but only hidden!
+ *
+ * @param ebd If TRUE the system tray icon will be embedded into
+ * the system tray.
+ */
+ void embed( bool ebd );
+
+ /**
+ * This function returns TRUE if the system tray window is embedded into
+ * the system tray and FALSE otherwise.
+ *
+ * @returns TRUE if the system tray window is embedded.
+ */
+ bool isEmbedded() { return isShown(); }
+
+ /**
+ * This function (re-)loads the settings for this widget. It basically just
+ * runs the slot slotSetupBookmarkMenu() and slotSetupSharesMenu(), that will
+ * do everything to properly set up the menus.
+ *
+ * This slot *does not* manage the appearance (or disappearance) of this widget
+ * in the system tray. You need to use embed() to do this.
+ */
+ void loadSettings();
+
+ signals:
+ /**
+ * This signal is emitted when the config dialog has been closed and the
+ * settings changed.
+ */
+ void settingsChanged();
+
+ protected slots:
+ /**
+ * This slot opens the dialog for mounting shares manually.
+ */
+ void slotMountManually();
+
+ /**
+ * This slot opens the configurations dialog.
+ */
+ void slotConfigDialog();
+
+ /**
+ * This slot is invoked when the config dialog is closed and the settings have
+ * been changed. Emits the reloadSettings() signal and adjusts the system tray
+ * widget to the new settings afterwards.
+ */
+ void slotSettingsChanged();
+
+ /**
+ * This slot is invoked when the bookmarks have been updated. It sets up the
+ * bookmark menu, inserts the bookmark actions into it and automatically
+ * disables them if they were already mounted (@see slotSetupSharesMenu() as well).
+ */
+ void slotSetupBookmarksMenu();
+
+ /**
+ * This slot opens the bookmark editor.
+ */
+ void slotBookmarkEditor();
+
+ /**
+ * This slot is called when a bookmark has been activated. It initializes the
+ * mounting of the represented share.
+ */
+ void slotBookmarkActivated();
+
+ /**
+ * This slot enables and disables the bookmarks. If a share that's represented
+ * by the bookmark is mounted, the bookmark will be disabled. It will be
+ * enabled, when it is unmounted again.
+ */
+ void slotEnableBookmarks();
+
+ /**
+ * This slot is activated when the list of mounted shares has been updated.
+ * It setus up the "Mounted Shares" menu and also enables/disables the
+ * bookmarks in the "Bookmarks" menu. It is connected to the
+ * Smb4KMounter::updated() signal.
+ */
+ void slotSetupSharesMenu();
+
+ /**
+ * This slot initializes the umounting of all shares. It is connected to the
+ * "Unmount All" action of the "Mounted Shares" menu.
+ */
+ void slotUnmountAllShares();
+
+ /**
+ * This slot is connected to the 'Unmount action'. You will be able to
+ * unmount a certain share when activating this slot.
+ */
+ void slotUnmountShare();
+
+ /**
+ * This slot is connected to the 'Force Unmounting' action and is, thus,
+ * only useful under Linux, because only there the possibility for a forced
+ * (i.e. lazy) unmount exists.
+ *
+ * When activating this slot, the selected share will be unmounted, even if
+ * it is not accessible or the server already went offline.
+ */
+ void slotForceUnmountShare();
+
+ /**
+ * This slot is connected to the 'Synchronize' action. The current item will be
+ * synchronized with a local copy (or vice versa) if you activate it.
+ */
+ void slotSynchronize();
+
+ /**
+ * This slot is connected to the 'Konsole' action. The mount point of the current
+ * share item will be opened in Konsole.
+ */
+ void slotKonsole();
+
+ /**
+ * This slot is connected to the 'Konqueror' action. The contents of the current
+ * share item will be opened in the file manager.
+ */
+ void slotFilemanager();
+
+ /**
+ * This slot is enabled when an action is highlighted. No validity checks are
+ * performed.
+ *
+ * @param action The currently highlighted action.
+ */
+ void slotActionHighlighted( KAction *action );
+
+ private:
+ /**
+ * The action menu for the bookmarks.
+ */
+ KActionMenu *m_bookmarks_menu;
+
+ /**
+ * The action menu for the mounted shares.
+ */
+ KActionMenu *m_shares_menu;
+
+ /**
+ * This is the currently highlighted action.
+ */
+ KAction *m_action;
+};
+
+#endif