/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include // 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 & ) ), this, SLOT( slotWorkgroups( const QValueList & ) ) ); connect( m_core->scanner(), SIGNAL( members( const QString &, const QValueList & ) ), this, SLOT( slotMembers( const QString &, const QValueList & ) ) ); connect( m_core->scanner(), SIGNAL( shares( const QString &, const QValueList & ) ), this, SLOT( slotShares( const QString &, const QValueList & ) ) ); 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 *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 &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::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 &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::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 &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::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"