/***************************************************************************
    smb4ksystemtray  -  This is the system tray window class of Smb4K.
                             -------------------
    begin                : Mi Jun 13 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 <tqtooltip.h>
#include <tqiconset.h>
#include <tqpixmap.h>
#include <tqimage.h>

// KDE specific includes
#include <kiconloader.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdepopupmenu.h>
#include <tdeaction.h>
#include <klibloader.h>
#include <tdemessagebox.h>
#include <tdeconfigdialog.h>
#include <kiconeffect.h>

// application specific includes
#include "smb4ksystemtray.h"
#include "dialogs/smb4kmountdialog.h"
#include "dialogs/smb4kbookmarkeditor.h"
#include "dialogs/smb4ksynchronizationdialog.h"
#include "core/smb4kcore.h"
#include "core/smb4kbookmark.h"
#include "core/smb4kshare.h"
#include "core/smb4ksettings.h"


Smb4KSystemTray::Smb4KSystemTray( TQWidget *parent, const char *name )
: KSystemTray( parent, name )
{
  setPixmap( loadIcon( "smb4k" ) );

  TQToolTip::add( this, i18n( "Smb4K" ) );

  m_action = NULL;

  // Enable highlighting of actions:
  actionCollection()->setHighlightingEnabled( true );

  // Set up the context menu (skeleton):
  m_shares_menu         = new TDEActionMenu( i18n( "Mounted Shares" ), "drive-harddisk-mounted",
                          actionCollection(), "st_mounted_shares_action_menu" );
  m_bookmarks_menu      = new TDEActionMenu( i18n( "Bookmarks" ), "bookmark_folder",
                          actionCollection(), "st_bookmark_action_menu" );
  TDEActionSeparator *sep = new TDEActionSeparator( this );
  TDEAction *manual_mount = new TDEAction( i18n( "M&ount Manually" ), "connect_creating",
                          0, this, TQ_SLOT( slotMountManually() ),
                          actionCollection(), "st_mount_manually_action" );
  TDEAction *configure    = KStdAction::preferences( this, TQ_SLOT( slotConfigDialog() ),
                          actionCollection(), "st_configure_action" );

  m_shares_menu->plug( contextMenu() );
  m_bookmarks_menu->plug( contextMenu() );
  sep->plug( contextMenu() );
  manual_mount->plug( contextMenu() );
  configure->plug( contextMenu() );

  // Set up the menus:
  slotSetupBookmarksMenu();
  slotSetupSharesMenu();

  // Connections:
  connect( actionCollection(),           TQ_SIGNAL( actionHighlighted( TDEAction * ) ),
           this,                         TQ_SLOT( slotActionHighlighted( TDEAction * ) ) );

  connect( Smb4KCore::bookmarkHandler(), TQ_SIGNAL( bookmarksUpdated() ),
           this,                         TQ_SLOT( slotSetupBookmarksMenu() ) );

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

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

  // Connection to quitSelected() signal must be done in parent widget.
}


Smb4KSystemTray::~Smb4KSystemTray()
{
}


void Smb4KSystemTray::embed( bool ebd )
{
  if ( ebd )
  {
    show();
  }
  else
  {
    hide();
  }
}


void Smb4KSystemTray::loadSettings()
{
  // Adjust the bookmarks menu.
  // Since the menu is rebuilt everytime slotSetupBookmarksMenu() is
  // called, we just call it and are done.
  slotSetupBookmarksMenu();

  // Adjust the shares menu.
  // slotSetupSharesMenu() is doing everything for us, so just call it.
  slotSetupSharesMenu();
}


/////////////////////////////////////////////////////////////////////////////
// SLOT IMPLEMENTATIONS
/////////////////////////////////////////////////////////////////////////////

void Smb4KSystemTray::slotMountManually()
{
  Smb4KMountDialog *dlg = NULL;

  if ( parentWidget() )
  {
    dlg = static_cast<Smb4KMountDialog *>( parentWidget()->child( "MountDialog", "Smb4KMountDialog", true ) );
  }
  else
  {
    dlg = static_cast<Smb4KMountDialog *>( child( "MountDialog", "Smb4KMountDialog", true ) );
  }

  if ( !dlg )
  {
    if ( parentWidget() && parentWidget()->isShown() )
    {
      dlg = new Smb4KMountDialog( parentWidget(), "MountDialog" );
    }
    else
    {
      dlg = new Smb4KMountDialog( this, "MountDialog" );
    }
  }

  // The dialog will be closed destructively.
  if ( !dlg->isShown() )
  {
    dlg->exec();
  }
}


void Smb4KSystemTray::slotConfigDialog()
{
  // If the config dialog is already created and cached,
  // we do not create a new one but show the old instead:
  TDEConfigDialog *dlg = NULL;

  if ( (dlg = TDEConfigDialog::exists( "ConfigDialog" )) && TDEConfigDialog::showDialog( "ConfigDialog" ) )
  {
    // To make sure we do not connect the config dialog several times
    // to slotSettingsChanged(), we break the connection first and re-
    // establish it afterwards:
    disconnect( dlg, TQ_SIGNAL( settingsChanged() ), this, TQ_SLOT( slotSettingsChanged() ) );
    connect( dlg, TQ_SIGNAL( settingsChanged() ), this, TQ_SLOT( slotSettingsChanged() ) );

    return;
  }

  // Load the factory of the config dialog:
  KLibFactory *config_factory = KLibLoader::self()->factory( "libsmb4tdeconfigdialog" );

  if ( config_factory )
  {
    if ( parentWidget() && parentWidget()->isShown() )
    {
      dlg = static_cast<TDEConfigDialog *>( config_factory->create( parentWidget(), "ConfigDialog", "TDEConfigDialog" ) );
    }
    else
    {
      dlg = static_cast<TDEConfigDialog *>( config_factory->create( this, "ConfigDialog", "TDEConfigDialog" ) );
    }

    // ... and show it.
    if ( dlg )
    {
      connect( dlg, TQ_SIGNAL( settingsChanged() ), this, TQ_SLOT( slotSettingsChanged() ) );

      dlg->show();
    }
  }
  else
  {
    KMessageBox::error( 0, "<qt>"+KLibLoader::self()->lastErrorMessage()+"</qt>" );

    return;
  }
}

void Smb4KSystemTray::slotSettingsChanged()
{
  // Notify the parent that the settings changed:
  emit settingsChanged();

  // Execute loadSettings():
  loadSettings();
}


void Smb4KSystemTray::slotSetupBookmarksMenu()
{
  // First check if we have to set up the menu completely:
  if ( !actionCollection()->action( "st_edit_bookmarks_action" ) )
  {
    // OK, build the menu from ground up:
    TDEAction *edit_bookmarks = new TDEAction( i18n( "&Edit Bookmarks" ), "bookmark", 0,
                              this, TQ_SLOT( slotBookmarkEditor() ), actionCollection(),
                              "st_edit_bookmarks_action" );
    edit_bookmarks->setGroup( "BookmarkActions" );
    edit_bookmarks->plug( m_bookmarks_menu->popupMenu() );

    TDEActionSeparator *sep   = new TDEActionSeparator( actionCollection(), "st_bookmark_action_separator" );
    sep->setGroup( "BookmarkActions" );
    sep->plug( m_bookmarks_menu->popupMenu() );
  }

  // Get the list of bookmark actions and delete all entries. We could
  // also try to keep those actions that are not obsolete, but I think
  // this is the cleanest way.
  TDEActionPtrList list = actionCollection()->actions( "Bookmarks" );

  for ( TDEActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
  {
    (*it)->unplug( m_bookmarks_menu->popupMenu() );
    actionCollection()->remove( *it );
  }

  // Get the list of bookmarks:
  TQValueList<Smb4KBookmark *> bookmarks = Smb4KCore::bookmarkHandler()->getBookmarks();
  TQStringList display_strings;

  // Prepare the list of bookmarks for display:
  if ( !bookmarks.isEmpty() )
  {
    // Enable the "Edit Bookmarks" action:
    actionCollection()->action( "st_edit_bookmarks_action" )->setEnabled( true );

    // Work around sorting problems:
    for ( TQValueListIterator<Smb4KBookmark *> it = bookmarks.begin(); it != bookmarks.end(); ++it )
    {
      if ( !(*it)->label().isEmpty() && Smb4KSettings::showCustomBookmarkLabel() )
      {
        display_strings.append( (*it)->label() );
      }
      else
      {
        display_strings.append( (*it)->bookmark() );
      }
    }

    display_strings.sort();
  }
  else
  {
    // Disable the "Edit Bookmarks" action:
    actionCollection()->action( "st_edit_bookmarks_action" )->setEnabled( false );
  }

  for ( TQStringList::ConstIterator it = display_strings.begin(); it != display_strings.end(); ++it )
  {
    // Create the bookmark action:
    TDEAction *a = new TDEAction( *it, "folder", TDEShortcut::null(), 0, 0, actionCollection(), ("st_"+*it).utf8() );
    a->setGroup( "Bookmarks" );
    connect( a, TQ_SIGNAL( activated() ), this, TQ_SLOT( slotBookmarkActivated() ) );

    // Let's have a look if the bookmark action has to be enabled or disabled:
    TQString name;

    if ( !(*it).startsWith( "//" ) )
    {
      Smb4KBookmark *bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( *it );

      name = bookmark->bookmark();
    }
    else
    {
      name = *it;
    }

    TQValueList<Smb4KShare> share_list = Smb4KCore::mounter()->findShareByName( name );

    bool enable = true;

    for ( TQValueList<Smb4KShare>::ConstIterator i = share_list.begin(); i != share_list.end(); ++i )
    {
      if ( !(*i).isForeign() )
      {
        enable = false;

        break;
      }
      else
      {
        continue;
      }
    }

    a->setEnabled( enable );

    // Plug the bookmark to the menu:
    a->plug( m_bookmarks_menu->popupMenu() );
  }
}


void Smb4KSystemTray::slotBookmarkEditor()
{
  Smb4KBookmarkEditor *dlg = NULL;

  if ( parentWidget() )
  {
    dlg = static_cast<Smb4KBookmarkEditor *>( parentWidget()->child( "BookmarkEditor", "Smb4KBookmarkEditor", true ) );
  }
  else
  {
    dlg = static_cast<Smb4KBookmarkEditor *>( child( "BookmarkEditor", "Smb4KBookmarkEditor", true ) );
  }

  if ( !dlg )
  {
    if ( parentWidget() && parentWidget()->isShown() )
    {
      dlg = new Smb4KBookmarkEditor( parentWidget(), "BookmarkEditor" );
    }
    else
    {
      dlg = new Smb4KBookmarkEditor( this, "BookmarkEditor" );
    }
  }

  if ( !dlg->isShown() )
  {
    dlg->show();
  }
}


void Smb4KSystemTray::slotBookmarkActivated()
{
  if ( m_action && TQString::compare( m_action->group(), "Bookmarks" ) == 0 )
  {
    Smb4KBookmark *bookmark = NULL;

    if ( !m_action->plainText().startsWith( "//" ) )
    {
      bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( m_action->plainText() );
    }
    else
    {
      bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByName( m_action->plainText() );
    }

    if ( bookmark )
    {
      Smb4KCore::mounter()->mountShare( bookmark->workgroup(), bookmark->host(),
                                        bookmark->ip(), bookmark->share() );
    }
  }
  else
  {
    // Do nothing
  }
}


void Smb4KSystemTray::slotEnableBookmarks()
{
  // Get the list of bookmarks:
  TDEActionPtrList list = actionCollection()->actions( "Bookmarks" );

  // Enable/diable the bookmark actions:
  for ( TDEActionPtrList::Iterator it = list.begin(); it != list.end(); ++it )
  {
    TQString name;

    if ( !(*it)->plainText().startsWith( "//" ) )
    {
      Smb4KBookmark *bookmark = Smb4KCore::bookmarkHandler()->findBookmarkByLabel( (*it)->plainText() );

      name = bookmark->bookmark();
    }
    else
    {
      name = (*it)->plainText();
    }

    TQValueList<Smb4KShare> share_list = Smb4KCore::mounter()->findShareByName( name );

    bool enable = true;

    for ( TQValueList<Smb4KShare>::ConstIterator i = share_list.begin(); i != share_list.end(); ++i )
    {
      if ( !(*i).isForeign() )
      {
        enable = false;

        break;
      }
      else
      {
        continue;
      }
    }

    (*it)->setEnabled( enable );
  }
}


void Smb4KSystemTray::slotSetupSharesMenu()
{
  // First check if we have to set up the menu completely:
  if ( !actionCollection()->action( "st_unmount_all_action" ) )
  {
    // OK, build the menu from ground up:
    TDEAction *unmount_all  = new TDEAction( i18n( "U&nmount All" ), "gear", TDEShortcut::null(),
                            this, TQ_SLOT( slotUnmountAllShares() ), actionCollection(),
                            "st_unmount_all_action" );
    unmount_all->setGroup( "ShareActions" );
    unmount_all->plug( m_shares_menu->popupMenu(), 0 );

    TDEActionSeparator *sep = new TDEActionSeparator( actionCollection(), "st_shares_action_separator" );
    sep->setGroup( "ShareActions" );
    sep->plug( m_shares_menu->popupMenu(), 1 );
  }

  // Since we are updating the list of shares very frequently, we should
  // not delete all entries in the menu, but look for changes.

  // Get the list of share actions:
  TDEActionPtrList actions_list = actionCollection()->actions( "ShareMenus" );

  // Get the list of mounted shares:
  TQValueList<Smb4KShare *> shares_list = Smb4KCore::mounter()->getShares();

  if ( !shares_list.isEmpty() )
  {
    // Enable the "Unmount All" action:
    actionCollection()->action( "st_unmount_all_action" )->setEnabled( true );

    // Delete all obsolete actions:
    for ( TDEActionPtrList::Iterator it = actions_list.begin(); it != actions_list.end(); ++it )
    {
      // Get the canonical path of the share action:
      TQString action_name = (*it)->name();
      TQString canonical_path = action_name.section( "st_[share_menu]_", 1, -1 );

      // Check if the share is still present:
      Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );

      // Decide if the share action has to be deleted or if it can stay:
      if ( share )
      {
        // Keep the share if it either isn't foreign or all shares should
        // be shown.
        if ( !share->isForeign() || Smb4KSettings::showAllShares() )
        {
          // To avoid sorting problems later, we remove *all* actions that
          // have *displayed texts* that do not match the current criterions.
          if ( (!Smb4KSettings::showMountPoint() &&
               TQString::compare( (*it)->plainText(), share->name() ) == 0) ||
               (Smb4KSettings::showMountPoint() &&
               TQString::compare( (*it)->plainText(), share->canonicalPath() ) == 0) )
          {
            // Find the "Force Unmount" action and decide if it needs to be
            // enabled/disabled:
            TDEAction *force = actionCollection()->action( ("st_[force]_"+canonical_path).utf8() );

            if ( force )
            {
              force->setEnabled( Smb4KSettings::useForceUnmount() );
            }

            continue;
          }
          else
          {
            // First remove all actions that are in the submenu:
            TDEAction *action = NULL;
            TDEActionMenu *menu = static_cast<TDEActionMenu *>( *it );

            if ( menu )
            {
              // Unmount action
              action = actionCollection()->action( ("st_[unmount]_"+canonical_path).utf8() );

              if ( action )
              {
                action->unplug( menu->popupMenu() );
                actionCollection()->remove( action );
              }

#ifdef __linux__
              // Force Unmount action
              action = actionCollection()->action( ("st_[force]_"+canonical_path).utf8() );

              if ( action )
              {
                action->unplug( menu->popupMenu() );
                actionCollection()->remove( action );
              }
#endif

              // Synchronize action
              action = actionCollection()->action( ("st_[synchronize]_"+canonical_path).utf8() );

              if ( action )
              {
                action->unplug( menu->popupMenu() );
                actionCollection()->remove( action );
              }

              // Konsole action
              action = actionCollection()->action( ("st_[konsole]_"+canonical_path).utf8() );

              if ( action )
              {
                action->unplug( menu->popupMenu() );
                actionCollection()->remove( action );
              }

              // Konqueror action
              action = actionCollection()->action( ("st_[filemanager]_"+canonical_path).utf8() );

              if ( action )
              {
                action->unplug( menu->popupMenu() );
                actionCollection()->remove( action );
              }
            }

            // Now remove the menu itself:
            (*it)->unplug( m_shares_menu->popupMenu() );
            actionCollection()->remove( *it );

            continue;
          }
        }
        else
        {
          // First remove all actions that are in the submenu:
          TDEAction *action = NULL;
          TDEActionMenu *menu = static_cast<TDEActionMenu *>( *it );

          if ( menu )
          {
            // Unmount action
            action = actionCollection()->action( ("st_[unmount]_"+canonical_path).utf8() );

            if ( action )
            {
              action->unplug( menu->popupMenu() );
              actionCollection()->remove( action );
            }

#ifdef __linux__
            // Force Unmount action
            action = actionCollection()->action( ("st_[force]_"+canonical_path).utf8() );

            if ( action )
            {
              action->unplug( menu->popupMenu() );
              actionCollection()->remove( action );
            }
#endif

            // Synchronize action
            action = actionCollection()->action( ("st_[synchronize]_"+canonical_path).utf8() );

            if ( action )
            {
              action->unplug( menu->popupMenu() );
              actionCollection()->remove( action );
            }

            // Konsole action
            action = actionCollection()->action( ("st_[konsole]_"+canonical_path).utf8() );

            if ( action )
            {
              action->unplug( menu->popupMenu() );
              actionCollection()->remove( action );
            }

            // Konqueror action
            action = actionCollection()->action( ("st_[filemanager]_"+canonical_path).utf8() );

            if ( action )
            {
              action->unplug( menu->popupMenu() );
              actionCollection()->remove( action );
            }
          }

          // Now remove the menu itself:
          (*it)->unplug( m_shares_menu->popupMenu() );
          actionCollection()->remove( *it );

          continue;
        }
      }
      else
      {
        // First remove all actions that are in the submenu:
        TDEAction *action = NULL;
        TDEActionMenu *menu = static_cast<TDEActionMenu *>( *it );

        if ( menu )
        {
          // Unmount action
          action = actionCollection()->action( ("st_[unmount]_"+canonical_path).utf8() );

          if ( action )
          {
            action->unplug( menu->popupMenu() );
            actionCollection()->remove( action );
          }

#ifdef __linux__
          // Force Unmount action
          action = actionCollection()->action( ("st_[force]_"+canonical_path).utf8() );

          if ( action )
          {
            action->unplug( menu->popupMenu() );
            actionCollection()->remove( action );
          }
#endif

          // Synchronize action
          action = actionCollection()->action( ("st_[synchronize]_"+canonical_path).utf8() );

          if ( action )
          {
            action->unplug( menu->popupMenu() );
            actionCollection()->remove( action );
          }

            // Konsole action
          action = actionCollection()->action( ("st_[konsole]_"+canonical_path).utf8() );

          if ( action )
          {
            action->unplug( menu->popupMenu() );
            actionCollection()->remove( action );
          }

          // Konqueror action
          action = actionCollection()->action( ("st_[filemanager]_"+canonical_path).utf8() );

          if ( action )
          {
            action->unplug( menu->popupMenu() );
            actionCollection()->remove( action );
          }
        }

        // Now remove the menu itself:
        (*it)->unplug( m_shares_menu->popupMenu() );
        actionCollection()->remove( *it );

        continue;
      }
    }

    // Since we cannot sort the Smb4kShare items appropriately, we have to
    // work around this problem. For that, let's create a string list:
    TQStringList strings;

    for ( TQValueList<Smb4KShare *>::ConstIterator it = shares_list.begin(); it != shares_list.end(); ++it )
    {
      if ( !(*it)->isForeign() || Smb4KSettings::showAllShares() )
      {
        if ( Smb4KSettings::showMountPoint() )
        {
          strings.append( (*it)->canonicalPath() );
        }
        else
        {
          // _::_ is the devider between share name and the canonical path of
          // the share.
          TQString item = TQString( "%1_::_%2" ).arg( TQString((*it)->name()), TQString((*it)->canonicalPath()) );
          strings.append( item );
        }

        continue;
      }
      else
      {
        continue;
      }
    }

    strings.sort();

    // We are ready to insert the new shares into the menu.
    // We loop through the list of mounted shares and check if the
    // single shares are already in the menu. If not, we plug them
    // there:
    for ( TQValueList<Smb4KShare *>::ConstIterator it = shares_list.begin(); it != shares_list.end(); ++it )
    {
      TDEActionMenu *action_menu = NULL;

      // Reread the list of share action menus:
      TDEActionPtrList new_actions_list = actionCollection()->actions( "ShareMenus" );

      for ( TDEActionPtrList::ConstIterator i = new_actions_list.begin(); i != new_actions_list.end(); ++i )
      {
        TQString item = TQString( "st_[share_menu]_%1" ).arg( TQString((*it)->canonicalPath()) );

        if ( TQString::compare( (*i)->name(), item ) == 0 )
        {
          action_menu = static_cast<TDEActionMenu *>( *i );

          break;
        }
        else
        {
          continue;
        }
      }

      if ( !action_menu )
      {
        // Create a new TDEAction menu:
        TQIconSet set;
        TQPixmap pix;
        TDEIconLoader loader;

        int icon_state = (*it)->isForeign() ? TDEIcon::DisabledState : TDEIcon::DefaultState;

        if ( (*it)->isBroken() )
        {
          TQImage over = loader.loadIcon( "button_cancel", TDEIcon::Small,
                                         0, icon_state, 0L, false ).convertToImage();
          TQImage src  = loader.loadIcon( "drive-harddisk-mounted", TDEIcon::Small,
                                         0, icon_state, 0L, false ).convertToImage();

          TDEIconEffect e;
          e.semiTransparent( over );
          e.overlay( src, over );

          pix = TQPixmap( src );
        }
        else
        {
          pix = loader.loadIcon( "drive-harddisk-mounted", TDEIcon::Small,
                                 0, icon_state, 0L, false );
        }

        set.reset( pix, TQIconSet::Automatic );

        action_menu = new TDEActionMenu( Smb4KSettings::showMountPoint() ? (*it)->path() : (*it)->name(),
                      set, actionCollection(), "st_[share_menu]_"+(*it)->canonicalPath() );
        action_menu->setGroup( "ShareMenus" );


        // Define the actions that can be performed on a share from within
        // the system tray widget:
        TDEAction *umount       = new TDEAction( i18n( "&Unmount" ), "drive-harddisk-unmounted", TDEShortcut::null(), this,
                                TQ_SLOT( slotUnmountShare() ), actionCollection(), "st_[unmount]_"+(*it)->canonicalPath() );
        umount->setGroup( "ShareActions" );
#ifdef __linux__
        TDEAction *force_umount = new TDEAction( i18n( "&Force Unmounting" ), "drive-harddisk-unmounted", TDEShortcut::null(), this,
                                TQ_SLOT( slotForceUnmountShare() ), actionCollection(), "st_[force]_"+(*it)->canonicalPath() );
        force_umount->setGroup( "ShareActions" );
        force_umount->setEnabled( Smb4KSettings::useForceUnmount() );
#endif
        TDEAction *synchronize =  new TDEAction( i18n( "S&ynchronize" ), "go-bottom", TDEShortcut::null(), this,
                                TQ_SLOT( slotSynchronize() ), actionCollection(), "st_[synchronize]_"+(*it)->canonicalPath() );
        synchronize->setGroup( "ShareActions" );
        synchronize->setEnabled( !Smb4KSettings::rsync().isEmpty() );

        TDEAction *konsole =      new TDEAction( i18n( "Open with Konso&le" ), "terminal", TDEShortcut::null(), this,
                                TQ_SLOT( slotKonsole() ), actionCollection(), "st_[konsole]_"+(*it)->canonicalPath() );
        konsole->setGroup( "ShareActions" );
        konsole->setEnabled( !Smb4KSettings::konsole().isEmpty() );

        TDEAction *konqueror =    new TDEAction( i18n( "Open with &Konqueror" ), "kfm_home", TDEShortcut::null(), this,
                                TQ_SLOT( slotFilemanager() ), actionCollection(), "st_[filemanager]_"+(*it)->canonicalPath() );
        konqueror->setGroup( "ShareActions" );

        // Set up the action submenu:
        action_menu->insert( umount );
#ifdef __linux__
        action_menu->insert( force_umount );
#endif
        action_menu->popupMenu()->insertSeparator( -1 );
        action_menu->insert( synchronize );
        action_menu->popupMenu()->insertSeparator( -1 );
        action_menu->insert( konsole );
        action_menu->insert( konqueror );

        // Plug the new menu to the popup menu:
        int index = 0;

        if ( !Smb4KSettings::showMountPoint() )
        {
          TQString item = TQString( "%1_::_%2" ).arg( TQString((*it)->name()), TQString((*it)->canonicalPath()) );

          index = strings.findIndex( item );
        }
        else
        {
          index = strings.findIndex( (*it)->canonicalPath() );
        }

        m_shares_menu->insert( action_menu, index + 2 );  // +2 due to "Unmount All" and separator
      }
      else
      {
        // Change icon and disable some actions, if the share got inaccessible
        // in the meantime:
        if ( (*it)->isBroken() )
        {
          TQIconSet set;
          TQPixmap pix;
          TDEIconLoader loader;

          int icon_state = (*it)->isForeign() ? TDEIcon::DisabledState : TDEIcon::DefaultState;

          TQImage over = loader.loadIcon( "button_cancel", TDEIcon::Small,
                                         0, icon_state, 0L, false ).convertToImage();
          TQImage src  = loader.loadIcon( "drive-harddisk-mounted", TDEIcon::Small,
                                         0, icon_state, 0L, false ).convertToImage();

          TDEIconEffect e;
          e.semiTransparent( over );
          e.overlay( src, over );

          pix = TQPixmap( src );

          set.reset( pix, TQIconSet::Automatic );

          action_menu->setIconSet( set );

          // Disable actions that should not be performed on an inaccessible
          // share:
          actionCollection()->action( TQString("st_[synchronize]_"+(*it)->canonicalPath()).utf8() )->setEnabled( false );
          actionCollection()->action( TQString("st_[konsole]_"+(*it)->canonicalPath()).utf8() )->setEnabled( false );
          actionCollection()->action( TQString("st_[filemanager]_"+(*it)->canonicalPath()).utf8() )->setEnabled( false );
        }

        // Change the text if necessary:
        if ( !Smb4KSettings::showMountPoint() &&
             TQString::compare( action_menu->plainText(), (*it)->name() ) != 0 )
        {
          action_menu->setText( (*it)->name() );
        }
        else if ( Smb4KSettings::showMountPoint() &&
             TQString::compare( action_menu->plainText(), (*it)->path() ) != 0 )
        {
          action_menu->setText( (*it)->path() );
        }
        else
        {
          // Do nothing
        }
      }
    }
  }
  else
  {
    // Remove all share action menus:
    for ( TDEActionPtrList::Iterator it = actions_list.begin(); it != actions_list.end(); ++it )
    {
      TDEActionMenu *action_menu = static_cast<TDEActionMenu *>( *it );

      // Get the canonical path of the share action:
      TQString action_name = action_menu->name();
      TQString canonical_path = action_name.section( "st_[share_menu]_", 1, -1 );

      // Remove all children of the share action menus:
      TDEAction *action = NULL;

      // Unmount action
      action = actionCollection()->action( ("st_[unmount]_"+canonical_path).utf8() );

      if ( action )
      {
        action->unplug( action_menu->popupMenu() );
        actionCollection()->remove( action );
      }

#ifdef __linux__
      // Force Unmount action
      action = actionCollection()->action( ("st_[force]_"+canonical_path).utf8() );

      if ( action )
      {
        action->unplug( action_menu->popupMenu() );
        actionCollection()->remove( action );
      }
#endif

      // Synchronize action
      action = actionCollection()->action( ("st_[synchronize]_"+canonical_path).utf8() );

      if ( action )
      {
        action->unplug( action_menu->popupMenu() );
        actionCollection()->remove( action );
      }

      // Konsole action
      action = actionCollection()->action( ("st_[konsole]_"+canonical_path).utf8() );

      if ( action )
      {
        action->unplug( action_menu->popupMenu() );
        actionCollection()->remove( action );
      }

      // Konqueror action
      action = actionCollection()->action( ("st_[filemanager]_"+canonical_path).utf8() );

      if ( action )
      {
        action->unplug( action_menu->popupMenu() );
        actionCollection()->remove( action );
      }

      // Remove action menu itself:
      action_menu->unplug( m_shares_menu->popupMenu() );
      actionCollection()->remove( action_menu );
    }

    // Disable the "Unmount All" action:
    actionCollection()->action( "st_unmount_all_action" )->setEnabled( false );
  }
}


void Smb4KSystemTray::slotUnmountAllShares()
{
  Smb4KCore::mounter()->unmountAllShares();
}


void Smb4KSystemTray::slotUnmountShare()
{
  if ( m_action && TQString( m_action->name() ).startsWith( "st_[unmount]_" ) )
  {
    TQString canonical_path = TQString( m_action->name() ).section( "st_[unmount]_", 1, 1 );

    Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );

    if ( share )
    {
      Smb4KCore::mounter()->unmountShare( share, false, false );
    }
  }
}


void Smb4KSystemTray::slotForceUnmountShare()
{
  if ( m_action && TQString( m_action->name() ).startsWith( "st_[force]_" ) )
  {
    TQString canonical_path = TQString( m_action->name() ).section( "st_[force]_", 1, 1 );

    Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );

    if ( share )
    {
      Smb4KCore::mounter()->unmountShare( share, true, false );
    }
  }
}


void Smb4KSystemTray::slotSynchronize()
{
  // Since we want to allow the possibility to open several instances
  // of the synchronization dialog, we do not checks like in slotConfigDialog()
  if ( m_action && TQString( m_action->name() ).startsWith( "st_[synchronize]_" ) )
  {
    TQString canonical_path = TQString( m_action->name() ).section( "st_[synchronize]_", 1, 1 );

    Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );

    if ( share && !share->isBroken() )
    {
      Smb4KSynchronizationDialog *dlg = NULL;

      if ( parentWidget() && parentWidget()->isShown() )
      {
        dlg = new Smb4KSynchronizationDialog( share, parentWidget(), "SynchronizationDialog" );
      }
      else
      {
        dlg = new Smb4KSynchronizationDialog( share, this, "SynchronizationDialog" );
      }

      dlg->show();
    }
  }
}


void Smb4KSystemTray::slotKonsole()
{
  if ( m_action && TQString( m_action->name() ).startsWith( "st_[konsole]_" ) )
  {
    TQString canonical_path = TQString( m_action->name() ).section( "st_[konsole]_", 1, 1 );

    Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );

    if ( share && !share->isBroken() )
    {
      Smb4KCore::open( share, Smb4KCore::Konsole );
    }
  }
}


void Smb4KSystemTray::slotFilemanager()
{
  if ( m_action && TQString( m_action->name() ).startsWith( "st_[filemanager]_" ) )
  {
    TQString canonical_path = TQString( m_action->name() ).section( "st_[filemanager]_", 1, 1 );

    Smb4KShare *share = Smb4KCore::mounter()->findShareByPath( canonical_path );

    if ( share && !share->isBroken() )
    {
      Smb4KCore::open( share, Smb4KCore::Konqueror );
    }
  }
}


void Smb4KSystemTray::slotActionHighlighted( TDEAction *action )
{
  // If the main window is not shown, the last action that
  // is highlighted when the user clicks an action in a
  // mounted-share-submenu is "st_mounted_shares_action_menu"
  // and not the action the user clicked. That's why we need
  // to filter this action out:
  if ( action && !qstrcmp( action->name(), "st_mounted_shares_action_menu" ) )
  {
    return;
  }

  m_action = action;
}

#include "smb4ksystemtray.moc"

