/***************************************************************************
    smb4knetworkbrowser_part  -  This Part encapsulates the network
    browser of Smb4K.
                             -------------------
    begin                : Fr Jan 5 2007
    copyright            : (C) 2007 by Alexander Reinholdt
    email                : dustpuppy@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   General Public License for more details.                              *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,   *
 *   MA  02110-1301 USA                                                    *
 ***************************************************************************/

// TQt includes
#include <tqheader.h>

// KDE includes
#include <tdeaboutdata.h>
#include <tdeaction.h>
#include <tdeshortcut.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <tdeversion.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/smb4tdeglobal.h"
#include "../core/smb4kpasswordhandler.h"
#include "../core/smb4ksettings.h"
#include "../core/smb4kbookmark.h"
#include "../core/smb4kdefs.h"

using namespace Smb4TDEGlobal;

TDEInstance *Smb4KNetworkBrowserPartFactory::m_instance = 0L;
TDEAboutData *Smb4KNetworkBrowserPartFactory::m_about = 0L;


Smb4KNetworkBrowserPart::Smb4KNetworkBrowserPart( TQWidget *parentWidget, const char *widgetName,
                                                  TQObject *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,             TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint & , int ) ),
           this,                 TQ_SLOT( slotContextMenuRequested( TQListViewItem *, const TQPoint &, int ) ) );

  connect( m_widget,             TQ_SIGNAL( selectionChanged( TQListViewItem * ) ),
           this,                 TQ_SLOT( slotSelectionChanged( TQListViewItem * ) ) );

  connect( m_widget,             TQ_SIGNAL( pressed( TQListViewItem * ) ),
           this,                 TQ_SLOT( slotPressed( TQListViewItem * ) ) );

  connect( m_widget,             TQ_SIGNAL( expanded( TQListViewItem * ) ),
           this,                 TQ_SLOT( slotItemExpanded( TQListViewItem * ) ) );

  connect( m_widget,             TQ_SIGNAL( collapsed( TQListViewItem * ) ),
           this,                 TQ_SLOT( slotItemCollapsed( TQListViewItem * ) ) );

  connect( m_widget,             TQ_SIGNAL( executed( TQListViewItem * ) ),
           this,                 TQ_SLOT( slotItemExecuted( TQListViewItem * ) ) );

  connect( m_widget,             TQ_SIGNAL( aboutToShowToolTip( Smb4KNetworkBrowserItem * ) ),
           this,                 TQ_SLOT( slotAboutToShowToolTip( Smb4KNetworkBrowserItem * ) ) );

  connect( Smb4KCore::scanner(), TQ_SIGNAL( workgroups( const TQValueList<Smb4KWorkgroupItem *> & ) ),
           this,                 TQ_SLOT( slotWorkgroups( const TQValueList<Smb4KWorkgroupItem *> & ) ) );

  connect( Smb4KCore::scanner(), TQ_SIGNAL( members( const TQString &, const TQValueList<Smb4KHostItem *> & ) ),
           this,                 TQ_SLOT( slotWorkgroupMembers( const TQString &, const TQValueList<Smb4KHostItem *> & ) ) );

  connect( Smb4KCore::scanner(), TQ_SIGNAL( shares( const TQString &, const TQValueList<Smb4KShareItem *> & ) ),
           this,                 TQ_SLOT( slotShares( const TQString &, const TQValueList<Smb4KShareItem *> & ) ) );

  connect( Smb4KCore::scanner(), TQ_SIGNAL( ipAddress( Smb4KHostItem * ) ),
           this,                 TQ_SLOT( slotAddIPAddress( Smb4KHostItem * ) ) );

  connect( Smb4KCore::scanner(), TQ_SIGNAL( info( Smb4KHostItem * ) ),
           this,                 TQ_SLOT( slotAddInformation( Smb4KHostItem * ) ) );

  connect( Smb4KCore::scanner(), TQ_SIGNAL( hostAdded( Smb4KHostItem * ) ),
           this,                 TQ_SLOT( slotInsertHost( Smb4KHostItem * ) ) );

  connect( Smb4KCore::mounter(), TQ_SIGNAL( updated() ),
           this,                 TQ_SLOT( slotMarkMountedShares() ) );

  connect( Smb4KCore::self(),    TQ_SIGNAL( runStateChanged() ),
           this,                 TQ_SLOT( slotRunStateChanged() ) );
}


Smb4KNetworkBrowserPart::~Smb4KNetworkBrowserPart()
{
}


void Smb4KNetworkBrowserPart::setupActions()
{
  TDEAction *rescan =        new TDEAction( i18n( "Scan Netwo&rk" ), "reload", TDEShortcut( CTRL+Key_R ),
                                        this, TQ_SLOT( slotRescan() ),
                                        actionCollection(), "rescan_action" );
  TDEAction *abort =         new TDEAction( i18n( "&Abort" ) , "process-stop", TDEShortcut( CTRL+Key_A ),
                                        this, TQ_SLOT( slotAbort() ),
                                        actionCollection(), "abort_action" );
  TDEActionSeparator *sep1 = new TDEActionSeparator( actionCollection(),
                                        "separator_1" );
  TDEAction *manual_mount  = new TDEAction( i18n( "M&ount Manually" ), "connect_creating", TDEShortcut( CTRL+Key_O ),
                                        this, TQ_SLOT( slotMountManually() ),
                                        actionCollection(), "mount_manually_action" );
  TDEActionSeparator *sep2 = new TDEActionSeparator( actionCollection(),
                                        "separator_2" );
  TDEAction *auth =          new TDEAction( i18n( "Au&thentication" ), "identity", TDEShortcut( CTRL+Key_T ),
                                        this, TQ_SLOT( slotAuthentication() ),
                                        actionCollection(), "askpass_action" );
  TDEAction *custom =        new TDEAction( i18n( "&Custom Options" ), "samba", TDEShortcut( CTRL+Key_C ),
                                        this, TQ_SLOT( slotCustomOptions() ),
                                        actionCollection(), "custom_action" );
  TDEAction *bookmark =      new TDEAction( i18n( "Add &Bookmark" ), "bookmark_add", TDEShortcut( CTRL+Key_B ),
                                        this, TQ_SLOT( slotBookmark() ),
                                        actionCollection(), "bookmark_action" );
  TDEAction *preview =       new TDEAction( i18n( "Pre&view" ), "view_icon", TDEShortcut( CTRL+Key_V ),
                                        this, TQ_SLOT( slotPreview() ),
                                        actionCollection(), "preview_action" );
  TDEAction *print =         new TDEAction( i18n( "&Print File" ), "printer", TDEShortcut( CTRL+Key_P ),
                                        this, TQ_SLOT( slotPrint() ),
                                        actionCollection(), "print_action" );
  TDEAction *mount =         new TDEAction( i18n( "&Mount" ), "drive-harddisk-mounted", TDEShortcut( CTRL+Key_M ),
                                        this, TQ_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 TDEActionMenu( 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 )
  {
    TDEAction *unmount =     new TDEAction( i18n( "&Unmount" ), "drive-harddisk-unmounted", TDEShortcut( CTRL+Key_U ),
                                        this, TQ_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, TQListView::Maximum );
    m_widget->header()->setResizeEnabled( true, Smb4KNetworkBrowser::IP );
  }
  else
  {
    m_widget->setColumnWidth( Smb4KNetworkBrowser::IP, 0 );
    m_widget->setColumnWidthMode( Smb4KNetworkBrowser::IP, TQListView::Manual );
    m_widget->header()->setResizeEnabled( false, Smb4KNetworkBrowser::IP );
  }

  if ( Smb4KSettings::showType() )
  {
    m_widget->setColumnWidth( Smb4KNetworkBrowser::Type, 10 );
    m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Type, TQListView::Maximum );
    m_widget->header()->setResizeEnabled( true, Smb4KNetworkBrowser::Type );
  }
  else
  {
    m_widget->setColumnWidth( Smb4KNetworkBrowser::Type, 0 );
    m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Type, TQListView::Manual );
    m_widget->header()->setResizeEnabled( false, Smb4KNetworkBrowser::Type );
  }

  if ( Smb4KSettings::showComment() )
  {
    m_widget->setColumnWidth( Smb4KNetworkBrowser::Comment, 10 );
    m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Comment, TQListView::Maximum );
    m_widget->header()->setResizeEnabled( true, Smb4KNetworkBrowser::Comment );
  }
  else
  {
    m_widget->setColumnWidth( Smb4KNetworkBrowser::Comment, 0 );
    m_widget->setColumnWidthMode( Smb4KNetworkBrowser::Comment, TQListView::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( TQCustomEvent *e )
{
  switch ( e->type() )
  {
    case EVENT_LOAD_SETTINGS:
    {
      loadSettings();

      break;
    }
    case EVENT_SET_FOCUS:
    {
      TDEListView *view = static_cast<TDEListView *>( 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( TQListViewItem *item, const TQPoint &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( TQListViewItem *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( TQListViewItem *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( TQListViewItem *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( TQListViewItem *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( TQListViewItem *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 TQValueList<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 )
    {
      TQListViewItemIterator 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 )
        {
          TQValueList<Smb4KWorkgroupItem *>::ConstIterator i;

          for ( i = list.begin(); i != list.end(); ++i )
          {
            if ( TQString::compare( item->workgroupItem()->name(), (*i)->name() ) == 0 )
            {
              TQString 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 ( TQString::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 ( TQValueList<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 TQString &workgroup, const TQValueList<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:
        TQListViewItemIterator 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 &&
               TQString::compare( item->hostItem()->workgroup(), workgroupItem->workgroupItem()->name() ) == 0 )
          {
            TQValueList<Smb4KHostItem *>::ConstIterator i;

            for ( i = list.begin(); i != list.end(); ++i )
            {
              if ( TQString::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 ( TQString::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 ( TQValueList<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 ( TQString::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:
      TQListViewItem *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 TQString &host, const TQValueList<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 )
      {
        TQListViewItemIterator 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 &&
               TQString::compare( item->shareItem()->host(), hostItem->hostItem()->name() ) == 0 )
          {
            TQValueList<Smb4KShareItem *>::ConstIterator i;

            for ( i = list.begin(); i != list.end(); ++i )
            {
              if ( TQString::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 ( TQValueList<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 );

      TQListViewItem *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 && TQString::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() && TQString::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 ( TQString::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 ( TQString::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() &&
         TQString::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:
  TQPoint 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(),
                                    TQString(),
                                    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() )
    {
      TQString share_name = TQString( "//%1/%2" ).arg( browser_item->shareItem()->host(),
                                                     browser_item->shareItem()->name() );

      TQValueList<Smb4KShare> list = Smb4KCore::mounter()->findShareByName( share_name );
      Smb4KShare *share = NULL;

      for ( TQValueList<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()
{
  TQListViewItemIterator it( m_widget );
  TQListViewItem *item;

  while ((item = it.current()) != 0 )
  {
    ++it;

    if ( item->depth() == 2 )
    {
      Smb4KShareItem *share_item = static_cast<Smb4KNetworkBrowserItem *>( item )->shareItem();

      TQValueList<Smb4KShare> list = Smb4KCore::mounter()->findShareByName( TQString( "//%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 ( TQValueList<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( TQWidget *parentWidget, const char *widgetName,
TQObject *parent, const char *name, const char *, const TQStringList &args )
{
  Smb4KNetworkBrowserPart *obj = NULL;

  for ( TQStringList::ConstIterator it = args.begin(); it != args.end(); ++it )
  {
    TQString arg = (*it).section( "=", 0, 0 ).stripWhiteSpace();
    TQString value = (*it).section( "=", 1, -1 ).stripWhiteSpace();

    if ( TQString::compare( arg, "konqplugin" ) == 0 )
    {
      if ( TQString::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 ;
}


TDEInstance *Smb4KNetworkBrowserPartFactory::instance()
{
  if( !m_instance )
  {
    m_about = new TDEAboutData( "smb4knetworkbrowserpart", I18N_NOOP( "Smb4KNetworkBrowserPart" ), "1.0" );
    m_about->addAuthor("Alexander Reinholdt", 0, "dustpuppy@users.berlios.de");
    m_about->setLicense( TDEAboutData::License_GPL );
    m_instance = new TDEInstance( m_about );
  }

  return m_instance;
}


/////////////////////////////////////////////////////////////////////////////
// INIT
/////////////////////////////////////////////////////////////////////////////

extern "C"
{
  TDE_EXPORT void *init_libsmb4knetworkbrowser()
  {
    TDEGlobal::locale()->insertCatalogue( "smb4k" );
    return new Smb4KNetworkBrowserPartFactory;
  }
}


#include "smb4knetworkbrowser_part.moc"
