/***************************************************************************
* Copyright (C) 2004 by Massimo Callegari *
* massimocallegari@yahoo.it *
* *
* 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., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
// Qt includes
#include <qlabel.h>
#include <qtooltip.h>
#include <qstring.h>
#include <qwidget.h>
#include <qlayout.h>
#include <qpainter.h>
#include <qheader.h>
#include <qvaluelist.h>
#include <qpixmap.h>
#include <qtoolbutton.h>
#include <qtoolbar.h>
#include <qdir.h>
// KDE includes
#include <kinstance.h>
#include <klocale.h>
#include <kiconloader.h>
#include <klistview.h>
#include <kdialogbase.h>
#include <kcombobox.h>
#include <ktoolbarbutton.h>
#include <kaction.h>
// plugin specific includes
// #include "smb4k_konqplugin.moc"
#include "smb4k_konqplugin.h"
#include "../smb4k/widgets/smb4kbrowserwidgetitem.h"
#include "../smb4k/widgets/smb4koptionsdlg.h"
#include "../smb4k/widgets/smb4kcustomoptionsdialog.h"
#include "../smb4k/core/smb4kglobal.h"
using namespace Smb4KGlobal;
smb4kWidget::smb4kWidget( QWidget * parent, const char * name, WFlags f )
: QVBox(parent, name, f)
{
// Nothing exciting to do !
}
KonqSidebar_Smb4K::KonqSidebar_Smb4K(KInstance *inst,QObject *parent,QWidget *widgetParent, QString &desktopName, const char* name):
KonqSidebarPlugin(inst,parent,widgetParent,desktopName,name)
{
widget = new smb4kWidget( widgetParent );
KToolBar *topBar = new KToolBar( widget, "Topbar" );
topBar->setIconSize(16);
topBar->insertButton( "reload", 0, SIGNAL( clicked() ), this, SLOT( slotRescan() ) , TRUE, i18n( "Scan Network" ) );
topBar->insertButton( "find", 1, SIGNAL( clicked() ), this, SLOT( slotSearch() ) , TRUE, i18n( "Search" ) );
topBar->insertButton( "configure", 2, SIGNAL( clicked() ), this, SLOT( slotSmb4KOptionsDlg() ) , TRUE, i18n( "Configure" ) );
smb4kList = new KListView( widget, "NetworkView" );
smb4kList->addColumn( i18n( "Network" ), -1 );
smb4kList->addColumn( i18n( "Type" ), -1 );
smb4kList->addColumn( i18n( "IP Address" ), -1 );
smb4kList->addColumn( i18n( "Comment" ), -1 );
smb4kList->setRootIsDecorated( true );
QToolTip::add( smb4kList, i18n( "Network neighborhood" ) );
// The core:
m_core = new Smb4KCore( widgetParent, "Core" );
// Action menu stuff
m_collection = new KActionCollection( this, "KonquerorPlugin_ActionCollection", KGlobal::instance() );
m_menu = new Smb4KBrowserActionMenu( Smb4KBrowserActionMenu::KonqPlugin, m_collection, QString::null, QIconSet(), widget, "KonquerorPlugin_ActionMenu" );
m_menu->popupMenu()->insertSeparator( -1 );
m_menu->insert( new KAction( i18n( "Configuration" ), "configure", CTRL+Key_O, 0, 0, m_collection, "configure_action" ) );
m_menu->askpassAction()->setEnabled( false );
m_menu->mountAction()->setEnabled( false );
m_menu->customOptionsAction()->setEnabled( false );
slotReadOptions();
// Action connections
connect( m_collection->action( "rescan_action" ), SIGNAL( activated() ), this, SLOT( slotRescan() ) );
connect( m_collection->action( "askpass_action" ), SIGNAL( activated() ), this, SLOT( slotAskPass() ) );
connect( m_collection->action( "mount_action" ), SIGNAL( activated() ), this, SLOT( slotMountShare() ) );
connect( m_collection->action( "configure_action" ), SIGNAL( activated() ), this, SLOT( slotSmb4KOptionsDlg() ) );
connect( m_collection->action( "custom_options_action" ), SIGNAL( activated() ), this, SLOT( slotCustomOptions() ) );
// Widget specific connections.
connect( smb4kList, SIGNAL( executed( QListViewItem * ) ), SLOT( slotItemExecuted( QListViewItem * ) ) );
connect( smb4kList, SIGNAL( expanded( QListViewItem * ) ), SLOT( slotItemExpandedCollapsed( QListViewItem * ) ) );
connect( smb4kList, SIGNAL( collapsed( QListViewItem * ) ), SLOT( slotItemExpandedCollapsed( QListViewItem * ) ) );
connect( smb4kList, SIGNAL( selectionChanged( QListViewItem * ) ), SLOT( slotSelectionChanged( QListViewItem * ) ) );
connect( smb4kList, SIGNAL( rightButtonPressed( QListViewItem *, const QPoint &, int ) ), SLOT( slotRightButtonPressed( QListViewItem *, const QPoint &, int ) ) );
// External connections.
connect( m_core, SIGNAL( runStateChanged() ), this, SLOT( slotCoreRunStateChanged() ) );
connect( m_core->scanner(), SIGNAL( workgroups( const QValueList<Smb4KWorkgroupItem *> & ) ), this, SLOT( slotWorkgroups( const QValueList<Smb4KWorkgroupItem *> & ) ) );
connect( m_core->scanner(), SIGNAL( members( const QString &, const QValueList<Smb4KHostItem *> & ) ),
this, SLOT( slotMembers( const QString &, const QValueList<Smb4KHostItem *> & ) ) );
connect( m_core->scanner(), SIGNAL( shares( const QString &, const QValueList<Smb4KShareItem *> & ) ),
this, SLOT( slotShares( const QString &, const QValueList<Smb4KShareItem *> & ) ) );
connect( m_core->scanner(), SIGNAL( ipAddress( Smb4KHostItem * ) ), this, SLOT( slotAddIPAddress( Smb4KHostItem * ) ) );
connect( m_core->mounter(), SIGNAL( updated() ), this, SLOT( slotMarkShares() ) );
connect( m_core->mounter(), SIGNAL( mountedShare( const QString &) ), this, SLOT( slotMountedShare( const QString & ) ) );
connect( m_core->mounter(), SIGNAL( alreadyMountedShare( const QString &) ), this, SLOT( slotMountedShare( const QString & ) ) );
widget->show();
}
KonqSidebar_Smb4K::~KonqSidebar_Smb4K()
{
if ( m_menu )
{
delete m_menu;
}
uint index = 0;
while ( index < m_collection->count() )
{
delete m_collection->action( index++ );
}
m_collection->clear();
// Let the mounter perform last actions before the plugin
// and thus the core enter nirvana:
// (FIXME: Should we do this only if the last Konqueror instance
// is closed? How can we find out when this is the case???)
m_core->mounter()->prepareForShutdown();
}
extern "C"
{
void* create_konqsidebar_smb4k(KInstance *instance,QObject *par,QWidget *widp,QString &desktopname,const char *name)
{
KGlobal::locale()->insertCatalogue("smb4k");
return new KonqSidebar_Smb4K(instance,par,widp,desktopname,name);
}
};
extern "C"
{
bool add_konqsidebar_smb4k(QString* fn, QString* /*param*/, QMap<QString,QString> *map)
{
map->insert("Type","Link");
map->insert("Icon","smb4k");
map->insert("Name",i18n("Samba Browser"));
map->insert("Open","false");
map->insert("X-KDE-KonqSidebarModule","konqsidebar_smb4k");
fn->setLatin1("smb4k%1.desktop");
return true;
}
}
void KonqSidebar_Smb4K::handleURL(const KURL &url)
{
currentKonquerorURL = url.path();
//kdDebug() << "KonqSidebar_Smb4K::handleURL - "<< currentKonquerorURL << endl;
}
void KonqSidebar_Smb4K::setOpen( QListViewItem *item, bool open, bool use_setOpen )
{
if ( open )
{
switch ( item->depth() )
{
case 0:
{
Smb4KWorkgroupItem *i = smb4k_core->scanner()->getWorkgroup( item->text( Network ) );
smb4k_core->scanner()->getWorkgroupMembers( item->text( Network ), i->master(), i->ip() );
break;
}
case 1:
{
smb4k_core->scanner()->getShares( item->parent()->text( Network ), item->text( Network ), item->text( IP ) );
break;
}
default:
break;
}
}
else
{
switch ( item->depth() )
{
case 1:
{
// Remove all children (shares).
QListViewItem *shareItem = item->firstChild();
while ( shareItem )
{
delete shareItem;
shareItem = item->firstChild();
}
break;
}
default:
break;
}
}
if ( use_setOpen )
{
smb4kList->setOpen( item, open );
}
}
void KonqSidebar_Smb4K::slotCoreRunStateChanged()
{
return;
}
void KonqSidebar_Smb4K::slotItemExecuted( QListViewItem *item )
{
if ( item )
{
if ( item->depth() == 2 )
{
if ( item->text( Type ).contains( "Printer" ) == 0 )
{
slotMountShare();
}
// else
// {
// slotPrint();
// }
}
else
{
setOpen( item, !item->isOpen(), true );
}
}
}
void KonqSidebar_Smb4K::slotItemExpandedCollapsed( QListViewItem *item )
{
smb4kList->setSelected( item, true );
// Since it seems to be not easy to intercept KListView::setOpen(), we
// handle the opening and closing of an item via the root decoration
// this way:
setOpen( item, item->isOpen(), false );
}
void KonqSidebar_Smb4K::slotSelectionChanged( QListViewItem *item )
{
if ( item && item->depth() == 2 )
{
m_collection->action( "askpass_action" )->setEnabled( true );
if ( item->text( Type ).contains( "Printer" ) == 0 )
{
m_collection->action( "mount_action" )->setEnabled( true );
m_collection->action( "custom_options_action" )->setEnabled( true );
}
else
{
m_collection->action( "mount_action" )->setEnabled( false );
m_collection->action( "custom_options_action" )->setEnabled( false );
}
}
else if ( item && item->depth() == 1 )
{
m_collection->action( "askpass_action" )->setEnabled( true );
m_collection->action( "mount_action" )->setEnabled( false );
m_collection->action( "custom_options_action" )->setEnabled( true );
}
else
{
m_collection->action( "mount_action" )->setEnabled( false );
m_collection->action( "askpass_action" )->setEnabled( false );
m_collection->action( "custom_options_action" )->setEnabled( false );
}
}
void KonqSidebar_Smb4K::slotRightButtonPressed( QListViewItem *item, const QPoint &point, int )
{
if ( !item )
{
m_menu->popupMenu()->changeTitle( 0, SmallIcon( "network" ), i18n( "Network" ) );
}
else
{
m_menu->popupMenu()->changeTitle( 0, *(item->pixmap( 0 )), item->text( 0 ) );
if ( item->depth() == 0 )
{
m_collection->action( "rescan_action" )->setText( i18n( "Scan Wo&rkgroup" ) );
}
else
{
m_collection->action( "rescan_action" )->setText( i18n( "Scan Compute&r" ) );
}
}
slotSelectionChanged( item );
m_menu->popupMenu()->exec( point, 0 );
m_collection->action( "rescan_action" )->setText( i18n( "Scan Netwo&rk" ) );
}
void KonqSidebar_Smb4K::slotWorkgroups( const QValueList<Smb4KWorkgroupItem *> &list )
{
// Clear the network tab completely.
//sapp->view()->networkTab()->clear( 0 );
// Clear the list view:
smb4kList->clear();
// Adjust the columns.
for ( int index = 0; index < smb4kList->columns(); index++ )
{
if ( smb4kList->columnWidth( index ) != 0 )
smb4kList->adjustColumn( index );
}
// Put the workgroups into the list view.
if ( !list.isEmpty() )
{
for ( QValueList<Smb4KWorkgroupItem *>::ConstIterator it = list.begin(); it != list.end(); ++it )
{
if ( smb4kList->findItem( (*it)->workgroup(), Network, CaseSensitive|ExactMatch ) == 0 )
{
Smb4KBrowserWidgetItem *workgroup = new Smb4KBrowserWidgetItem( smb4kList, *it );
workgroup->setExpandable( true );
}
else
{
continue;
}
}
}
}
void KonqSidebar_Smb4K::slotMembers( const QString &, const QValueList<Smb4KHostItem *> &list )
{
// Massimo: I just fixed the connection. The code is still the old one, i.e.
// without the enhancements I did to the code in Smb4KBrowserWidget. If you want
// them here as well, please have a look at Smb4KBrowserWidget::slotWorkgroupMembers().
// I think, it will be only a matter of copy and paste to make the code work here.
if ( !list.isEmpty() )
{
for ( QValueList<Smb4KHostItem *>::ConstIterator it = list.begin(); it != list.end(); ++it )
{
Smb4KBrowserWidgetItem *item = (Smb4KBrowserWidgetItem *)(smb4kList->findItem( (*it)->name(), Network, CaseSensitive|ExactMatch ));
if ( item )
{
item->update( *it );
continue;
}
else
{
QListViewItem *workgroup = smb4kList->findItem( (*it)->workgroup(), Network, ExactMatch|CaseSensitive );
if ( workgroup )
{
Smb4KBrowserWidgetItem *host = new Smb4KBrowserWidgetItem( workgroup, *it );
host->setExpandable( true );
}
}
}
}
}
void KonqSidebar_Smb4K::slotShares( const QString &, const QValueList<Smb4KShareItem *> &list )
{
// Massimo: I just fixed the connection. The code is still the old one, i.e.
// without the enhancements I did to the code in Smb4KBrowserWidget. If you want
// them here as well, please have a look at Smb4KBrowserWidget::slotShares().
// I think, it will be only a matter of copy and paste to make the code work here.
if ( !list.isEmpty() )
{
for ( QValueList<Smb4KShareItem *>::ConstIterator it = list.begin(); it != list.end(); ++it )
{
QListViewItem *host = smb4kList->findItem( (*it)->host(), Network, ExactMatch|CaseSensitive );
if ( host != 0 )
{
if ( !m_hidden && (*it)->name().endsWith( "$" ) )
{
continue;
}
else
{
if ( !m_ipc && (*it)->name().contains( "IPC" ) != 0 )
continue;
if ( !m_admin && (*it)->name().contains( "ADMIN" ) != 0 )
continue;
}
if ( !m_printer && QString::compare( (*it)->name(), "Printer" ) == 0 )
{
continue;
}
Smb4KBrowserWidgetItem *test = (Smb4KBrowserWidgetItem *)(smb4kList->findItem( (*it)->name(), Network, ExactMatch|CaseSensitive ));
if ( !test || test->parent() != host )
{
Smb4KBrowserWidgetItem *share = new Smb4KBrowserWidgetItem( host, *it );
share->setExpandable( false );
continue;
}
else if ( test && test->parent() == host )
{
if ( QString::compare( test->text( Comment ), (*it)->comment() ) != 0 )
{
test->update( *it );
}
continue;
}
}
}
}
}
void KonqSidebar_Smb4K::slotMountShare()
{
if ( smb4kList->currentItem() && smb4kList->currentItem()->depth() == 2 )
{
m_core->mounter()->mountShare( smb4kList->currentItem()->parent()->parent()->text( Network ), smb4kList->currentItem()->parent()->text( Network ), smb4kList->currentItem()->parent()->text( IP ), smb4kList->currentItem()->text( Network ) );
}
}
void KonqSidebar_Smb4K::slotUnmountShare()
{
Smb4KBrowserWidgetItem *i = (Smb4KBrowserWidgetItem *)smb4kList->currentItem();
QString tmpPath;
if ( i && i->depth() == 2 )
{
Smb4KShare *share = m_core->mounter()->findShareByName( QString( "//%1/%2" ).arg( i->parent()->text( Network ), i->text( Network ) ) );
tmpPath = share->path();
//kdDebug() << "KonqSidebar_Smb4K::slotUnmountShare - "<< tmpPath << endl;
if ( QString::compare( tmpPath, currentKonquerorURL ) == 0 )
emit openURLRequest( KURL( QDir::home().canonicalPath() ) );
m_core->mounter()->unmountShare( share, false, false );
}
}
void KonqSidebar_Smb4K::slotAskPass()
{
if ( smb4kList->currentItem() && smb4kList->currentItem()->depth() == 1 )
{
QString workgroup = smb4kList->currentItem()->parent()->text( Network );
QString host = smb4kList->currentItem()->text( Network );
QString share = QString::null;
passwordHandler()->askpass( workgroup, host, share, Smb4KPasswordHandler::NewData );
}
else if ( smb4kList->currentItem() && smb4kList->currentItem()->depth() == 2 )
{
QString workgroup = smb4kList->currentItem()->parent()->parent()->text( Network );
QString host = smb4kList->currentItem()->parent()->text( Network );
QString share = smb4kList->currentItem()->text( Network );
passwordHandler()->askpass( workgroup, host, share, Smb4KPasswordHandler::NewData );
}
}
void KonqSidebar_Smb4K::slotAddIPAddress( Smb4KHostItem *item )
{
if ( item )
{
Smb4KBrowserWidgetItem *workgroup = (Smb4KBrowserWidgetItem *)(smb4kList->findItem( item->workgroup(), Network, ExactMatch|CaseSensitive ));
if ( workgroup && QString::compare( workgroup->text( Network ), item->workgroup() ) == 0 )
{
Smb4KWorkgroupItem *wg = smb4k_core->scanner()->getWorkgroup( item->workgroup() );
if ( wg )
{
workgroup->update( wg );
}
}
Smb4KBrowserWidgetItem *hostItem = (Smb4KBrowserWidgetItem *)(smb4kList->findItem( item->name(), Network, ExactMatch|CaseSensitive ));
if ( hostItem && hostItem->parent() && QString::compare( hostItem->parent()->text( Network ), item->workgroup() ) == 0 )
{
hostItem->update( item );
if ( smb4kList->columnWidth( IP ) != 0 )
{
smb4kList->adjustColumn( IP );
}
}
}
}
void KonqSidebar_Smb4K::slotMarkShares()
{
config()->setGroup( "User Interface" );
bool show_all = config()->readBoolEntry( "Show All Shares", false );
QListViewItemIterator it( smb4kList );
QListViewItem *item;
while ((item = it.current()) != 0 )
{
++it;
if ( item->depth() == 2 )
{
Smb4KShare *share = m_core->mounter()->findShareByName( QString( "//%1/%2" ).arg( item->parent()->text( Network ), item->text( Network ) ) );
if ( m_core->mounter()->isMounted( QString( "//%1/%2" ).arg( item->parent()->text( Network ), item->text( Network ) ) )
&& ( !share->isForeign() || show_all ) )
{
if ( !((Smb4KBrowserWidgetItem *)item)->isMounted() )
{
((Smb4KBrowserWidgetItem *)item)->setMounted( true );
}
continue;
}
else
{
((Smb4KBrowserWidgetItem *)item)->setMounted( false );
continue;
}
}
else
continue;
}
}
void KonqSidebar_Smb4K::slotMountedShare( const QString &mountedShare )
{
emit openURLRequest( KURL(mountedShare) );
}
void KonqSidebar_Smb4K::slotSmb4KOptionsDlg()
{
if ( child( "ConfigDialog", "KDialogBase", true ) == 0 )
{
Smb4KOptionsDlg *configDlg = new Smb4KOptionsDlg( widget, "ConfigDialog", false );
connect( configDlg, SIGNAL( savedOptions() ), this, SLOT( slotReadOptions() ) );
configDlg->show();
}
}
void KonqSidebar_Smb4K::slotRescan()
{
smb4k_core->scanner()->rescan();
}
void KonqSidebar_Smb4K::slotSearch()
{
KDialogBase *searchDialog = new KDialogBase( KDialogBase::Plain, i18n( "Search Dialog" ), KDialogBase::Close,
KDialogBase::NoDefault, widget, "sd", true, true );
QFrame *frame = searchDialog->plainPage();
QGridLayout *layout = new QGridLayout( frame );
layout->setSpacing( 10 );
layout->setMargin( 0 );
searchDialog->resize(400,300);
m_search_dialog = new Smb4KSearchDialog( frame );
layout->addWidget ( m_search_dialog, 0, 0, 0 );
// We do not want the dialog to be closed if the user presses return.
// Instead we want that a search is started:
searchDialog->actionButton( KDialogBase::Close )->setAutoDefault( false
);
searchDialog->show();
}
void KonqSidebar_Smb4K::slotCustomOptions()
{
if ( smb4kList->currentItem() )
{
Smb4KCustomOptionsDialog *dlg = NULL;
if ( smb4kList->currentItem()->depth() == 1 )
{
dlg = new Smb4KCustomOptionsDialog( ((Smb4KBrowserWidgetItem *)smb4kList->currentItem())->hostItem(),
smb4kList,
"CustomOptionsDialog" );
}
else if ( smb4kList->currentItem()->depth() == 2 )
{
dlg = new Smb4KCustomOptionsDialog( ((Smb4KBrowserWidgetItem *)smb4kList->currentItem())->shareItem(),
smb4kList,
"CustomOptionsDialog" );
}
else
{
delete dlg;
return;
}
if ( dlg->initialized() )
{
dlg->exec();
}
else
{
delete dlg;
}
// The dialog will be closed destructively.
}
}
void KonqSidebar_Smb4K::slotReadOptions()
{
// Read the configuration.
config()->setGroup( "User Interface" );
bool showType = config()->readBoolEntry( "Show Type", true );
bool showComment = config()->readBoolEntry( "Show Comment", true );
bool showIP = config()->readBoolEntry( "Show IP", true );
// Now put everything back in according to the wishes of the user.
if ( showIP )
{
smb4kList->setColumnWidth( IP, 10 );
smb4kList->setColumnWidthMode( IP, QListView::Maximum );
}
else
{
smb4kList->setColumnWidth( IP, 0 );
smb4kList->setColumnWidthMode( IP, QListView::Manual );
}
if ( showType )
{
smb4kList->setColumnWidth( Type, 10 );
smb4kList->setColumnWidthMode( Type, QListView::Maximum );
}
else
{
smb4kList->setColumnWidth( Type, 0 );
smb4kList->setColumnWidthMode( Type, QListView::Manual );
}
if ( showComment )
{
smb4kList->setColumnWidth( Comment, 10 );
smb4kList->setColumnWidthMode( Comment, QListView::Maximum );
}
else
{
smb4kList->setColumnWidth( Comment, 0 );
smb4kList->setColumnWidthMode( Comment, QListView::Manual );
}
// Adjust the columns. Avoid those that have a width of 0.
int index = 0;
while ( index < smb4kList->columns() )
{
if ( smb4kList->columnWidth( index ) != 0 )
smb4kList->adjustColumn( index );
index++;
}
// Initialize the rest.
m_hidden = config()->readBoolEntry( "Show Hidden", true );
m_ipc = config()->readBoolEntry( "Show IPC", false );
m_admin = config()->readBoolEntry( "Show ADMIN", false );
m_printer = config()->readBoolEntry( "Show Printer", true );
}
#include "smb4k_konqplugin.moc"
syntax highlighted by Code2HTML, v. 0.9.1