/*
 * setupdlg.cpp
 * Copyright (C) 1999-2008 Kurt Granroth <granroth@kde.org>
 *
 * This file contains the implementation of the setup dialog
 * class for KBiff.
 */
#include "setupdlg.h"
#include "setupdlg.moc"

#include <ntqgroupbox.h>
#include <ntqfileinfo.h>
#include <ntqlineedit.h>
#include <ntqcheckbox.h>
#include <ntqpushbutton.h>
#include <ntqcombobox.h>
#include <ntqheader.h>
#include <ntqtabwidget.h>

#include <ntqpixmap.h>
#include <ntqfont.h>
#include <ntqlabel.h>
#include <ntqstrlist.h>
#include <ntqlayout.h>
#include <ntqtooltip.h>
#include <ntqdict.h>
#include <ntqptrlist.h>
#include <ntqwhatsthis.h>
#include <ntqstylesheet.h>

#include <kaudioplayer.h>
#include <tdemessagebox.h>
#include <tdefiledialog.h>
#include <kapp.h>
#include <tdeglobal.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <kstddirs.h>
#include <ksimpleconfig.h>
#include <kbiffurl.h>
#include <kprocess.h>
#include <krun.h>
#include <kurllabel.h>
#include <twin.h>

#include <kbiffcodec.h>
#include "version.h"

#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>

#define CONFIG_FILE "kbiffrc"

#ifdef HAVE_PATHS_H
#include <paths.h>
#endif

#ifndef _PATH_MAILDIR
#define _PATH_MAILDIR "/var/spool/mail"
#endif

///////////////////////////////////////////////////////////////////////////
// KBiffSetup
///////////////////////////////////////////////////////////////////////////
KBiffSetup::KBiffSetup(const TQString& profile_, bool secure_)
    : KDialog(0, 0, true)
{
  // set the icon just to be cute
  KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon());

  // make sure the profile is *something*
  TQString the_profile;
  if (profile_.isEmpty() || profile_.isNull())
    the_profile = getSomeProfile();
  else
    the_profile = profile_;

  setCaption(i18n("KBiff Setup"));

  // The profile combo box and buttons all go in this groupbox
  TQGroupBox* profile_groupbox = new TQGroupBox(i18n("Profile"), this);

  // combo box to hold the profile names
  comboProfile = new TQComboBox(false, profile_groupbox);
  comboProfile->setSizeLimit(10);

  TQString whatsthis = i18n(
      "This is a list of all of the KBiff <b>profiles</b><p>"
      "A profile is a logical grouping of settings for either one "
      "mailbox or several mailboxes.  Each profile gets one icon "
      "and one new mail sound and one... well, everything");
  TQWhatsThis::add(comboProfile, whatsthis);

  // Add New Profile button
  TQPushButton *new_profile_button = new TQPushButton(i18n("&New..."),
                                                    profile_groupbox);
  whatsthis = i18n("Create a new profile");
  TQWhatsThis::add(new_profile_button, whatsthis);
  connect(new_profile_button, TQ_SIGNAL(clicked()), TQ_SLOT(slotAddNewProfile()));

  // Rename Profile button
  TQPushButton *rename_profile_button = new TQPushButton(i18n("&Rename..."),
                                                       profile_groupbox);
  whatsthis = i18n("Rename the current profile");
  TQWhatsThis::add(rename_profile_button, whatsthis);
  connect(rename_profile_button, TQ_SIGNAL(clicked()), TQ_SLOT(slotRenameProfile()));

  // Delete Profile button
  TQPushButton *delete_profile_button = new TQPushButton(i18n("&Delete"),
                                                       profile_groupbox);
  whatsthis = i18n("Delete the current profile");
  TQWhatsThis::add(delete_profile_button, whatsthis);
  connect(delete_profile_button, TQ_SIGNAL(clicked()), TQ_SLOT(slotDeleteProfile()));

  // setup the tabs
  TQTabWidget *tabctl = new TQTabWidget(this);
  generalTab = new KBiffGeneralTab(the_profile, tabctl);
  newmailTab = new KBiffNewMailTab(the_profile, tabctl);
  mailboxTab = new KBiffMailboxTab(the_profile, tabctl);
  aboutTab   = new KBiffAboutTab(tabctl); 

  connect(comboProfile, TQ_SIGNAL(highlighted(const TQString&)),
          generalTab, TQ_SLOT(readConfig(const TQString&)));
  connect(comboProfile, TQ_SIGNAL(highlighted(const TQString&)),
          newmailTab, TQ_SLOT(readConfig(const TQString&)));
  connect(comboProfile, TQ_SIGNAL(highlighted(const TQString&)),
          mailboxTab, TQ_SLOT(readConfig(const TQString&)));

  // add the tabs
  tabctl->addTab(generalTab, i18n("General"));
  tabctl->addTab(newmailTab, i18n("New Mail"));
  tabctl->addTab(mailboxTab, i18n("Mailbox"));
  tabctl->addTab(aboutTab, i18n("About"));

  // help button
  TQPushButton *help_button = new TQPushButton(i18n("&Help"), this);
  connect(help_button, TQ_SIGNAL(clicked()), TQ_SLOT(invokeHelp()));

  // ok button
  TQPushButton *ok_button = new TQPushButton(i18n("&OK"), this);
  ok_button->setDefault(true);
  connect(ok_button, TQ_SIGNAL(clicked()), TQ_SLOT(slotDone()));

  // cancel button
  TQPushButton *cancel_button = new TQPushButton(i18n("&Cancel"), this);
  connect(cancel_button, TQ_SIGNAL(clicked()), TQ_SLOT(reject()));

  // are we secure?
  isSecure = secure_;

  // NOW, SETUP ALL THE LAYOUTS!
  // This layout handles the buttons for the profile combobox
  TQBoxLayout *pro_button_layout = new TQBoxLayout(TQBoxLayout::LeftToRight, 12);
  pro_button_layout->addWidget(new_profile_button);
  pro_button_layout->addWidget(rename_profile_button);
  pro_button_layout->addWidget(delete_profile_button);

  // This layout handles the upper profile groupbox
  TQBoxLayout *profile_layout = new TQBoxLayout(profile_groupbox,
      TQBoxLayout::Down, 12);
  profile_layout->addSpacing(8);
  profile_layout->addWidget(comboProfile);
  profile_layout->addLayout(pro_button_layout);

  // This layout handles the dialog buttons
  TQBoxLayout *dialog_button_layout = new TQBoxLayout(TQBoxLayout::LeftToRight,
      12);
  dialog_button_layout->addWidget(help_button);
  dialog_button_layout->addStretch(1);
  dialog_button_layout->addWidget(ok_button);
  dialog_button_layout->addWidget(cancel_button);

  // This is the outermost layout
  TQBoxLayout *top_layout = new TQBoxLayout(this, TQBoxLayout::Down, 12);
  top_layout->addWidget(profile_groupbox);
  top_layout->addWidget(tabctl, 1);
  top_layout->addLayout(dialog_button_layout);

  // Read in the config for this profile
  readConfig(the_profile);
}

KBiffSetup::~KBiffSetup()
{
}

bool KBiffSetup::getSecure() const
{
  return isSecure;
}

const TQString KBiffSetup::getProfile() const
{
  return comboProfile->currentText();
}

const KBiffURL KBiffSetup::getCurrentMailbox() const
{
  return mailboxTab->getMailbox();
}

const TQPtrList<KBiffMailbox> KBiffSetup::getMailboxList() const
{
  return mailboxTab->getMailboxList();
}

const TQString KBiffSetup::getMailClient() const
{
  return generalTab->getMailClient();
}

const TQString KBiffSetup::getNoMailIcon() const
{
  return generalTab->getButtonNoMail();
}

const TQString KBiffSetup::getNewMailIcon() const
{
  return generalTab->getButtonNewMail();
}

const TQString KBiffSetup::getOldMailIcon() const
{
  return generalTab->getButtonOldMail();
}

const TQString KBiffSetup::getNoConnIcon() const
{
  return generalTab->getButtonNoConn();
}

const TQString KBiffSetup::getStoppedIcon() const
{
  return generalTab->getButtonStopped();
}

bool KBiffSetup::getSessionManagement() const
{
  return generalTab->getSessionManagement();
}

bool KBiffSetup::getCheckStartup() const
{
  return generalTab->getCheckStartup();
}

bool KBiffSetup::getDock() const
{
  return generalTab->getDock();
}

unsigned int KBiffSetup::getPoll() const
{
  return generalTab->getPoll();
}

const TQString KBiffSetup::getRunCommandPath() const
{
  return newmailTab->getRunCommandPath();
}

const TQString KBiffSetup::getRunResetCommandPath() const
{
  return newmailTab->getRunResetCommandPath();
}

const TQString KBiffSetup::getPlaySoundPath() const
{
  return newmailTab->getPlaySoundPath();
}

bool KBiffSetup::getRunCommand() const
{
  return newmailTab->getRunCommand();
}

bool KBiffSetup::getRunResetCommand() const
{
  return newmailTab->getRunResetCommand();
}

bool KBiffSetup::getPlaySound() const
{
  return newmailTab->getPlaySound();
}

bool KBiffSetup::getSystemBeep() const
{
  return newmailTab->getSystemBeep();
}

bool KBiffSetup::getNotify() const
{
  return newmailTab->getNotify();
}

bool KBiffSetup::getStatus() const
{
  return newmailTab->getStatus();
}

void KBiffSetup::invokeHelp()
{
  kapp->invokeHelp();
}

void KBiffSetup::readConfig(const TQString& profile_)
{
  TQStringList profile_list;

  // open the config file
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true);
  config->setDollarExpansion(false);

  config->setGroup("General");

  // read in the mailboxes
  profile_list = config->readListEntry("Profiles", ',');
  int number_of_mailboxes = profile_list.count();
  delete config;

  // check if we have any mailboxes to read in
  if (number_of_mailboxes > 0)
  {
    comboProfile->clear();

    // load up the combo box
    comboProfile->insertStringList(profile_list);

    // read in the data from the first mailbox if we don't have a name
    for (int i = 0; i < comboProfile->count(); i++)
    {
      if (TQString(profile_) == comboProfile->text(i))
      {
        comboProfile->setCurrentItem(i);
        break;
      }
    }
  }
  else
    comboProfile->insertItem(profile_);
}

TQString KBiffSetup::getSomeProfile() const
{
  TQStringList profile_list;

  // open the config file
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true);
  config->setGroup("General");

  // read in the mailboxes
  profile_list = config->readListEntry("Profiles", ',');
  int number_of_mailboxes = profile_list.count();
  delete config;

  // get the first mailbox if it exists
  if (number_of_mailboxes > 0)
    return profile_list.last();
  else
    return TQString("Inbox");
}

void KBiffSetup::saveConfig()
{
  // open the config file for writing
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE);

  config->setGroup("General");

  // get the list of profiles
  TQStringList profile_list;
  for (int i = 0; i < comboProfile->count(); i++)
    profile_list.append(comboProfile->text(i));

  // write the mailboxes
  config->writeEntry("Profiles", profile_list, ',');

  delete config;
}

///////////////////////////////////////////////////////////////////////
// Protected slots
///////////////////////////////////////////////////////////////////////
void KBiffSetup::slotDone()
{
  TQString profile = comboProfile->currentText();
  saveConfig();
  generalTab->saveConfig(profile);
  newmailTab->saveConfig(profile);
  mailboxTab->saveConfig(profile);
  accept();
}

void KBiffSetup::slotAddNewProfile()
{
  KBiffNewDlg dlg;

  // popup the name chooser
  dlg.setCaption(i18n("New Profile"));
  if (dlg.exec())
  {
    TQString profile_name = dlg.getName();

    // bail out if we already have this name
    for (int i = 0; i < comboProfile->count(); i++)
    {
      if (profile_name == comboProfile->text(i))
        return;
    }

    // continue only if we received a decent name
    if (profile_name.isEmpty() == false)
    {
      comboProfile->insertItem(profile_name, 0);

      saveConfig();
      readConfig(profile_name);
      generalTab->readConfig(profile_name);
      newmailTab->readConfig(profile_name);
      mailboxTab->readConfig(profile_name);
    }
  }
}

void KBiffSetup::slotRenameProfile()
{
  KBiffNewDlg dlg;
  TQString title;
  TQString old_profile = comboProfile->currentText();

  title = i18n("Rename Profile: %1").arg(old_profile);
  dlg.setCaption(title);
  // popup the name chooser
  if (dlg.exec())
  {
    TQString profile_name = dlg.getName();

    // bail out if we already have this name
    for (int i = 0; i < comboProfile->count(); i++)
    {
      if (profile_name == comboProfile->text(i))
        return;
    }

    // continue only if we received a decent name
    if (profile_name.isNull() == false)
    {
      comboProfile->removeItem(comboProfile->currentItem());
      comboProfile->insertItem(profile_name, 0);

      // remove the reference from the config file
      KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE);
      // nuke the group
      config->deleteGroup(old_profile, true);
      delete config;

      // now save the profile settings
      saveConfig();
      generalTab->saveConfig(profile_name);
      newmailTab->saveConfig(profile_name);
      mailboxTab->saveConfig(profile_name);
    }
  }
}

void KBiffSetup::slotDeleteProfile()
{
  TQString title, msg;
  TQString profile = comboProfile->currentText();

  title = i18n("Delete Profile: %1").arg(profile);
  msg = i18n("Are you sure you wish to delete this profile?\n");

  switch (KMessageBox::warningYesNo(this, msg, title))
  {
    case KMessageBox::Yes:
      {
        comboProfile->removeItem(comboProfile->currentItem());

        saveConfig();

        // remove the reference from the config file
        KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE);
        // nuke the group
        config->deleteGroup(profile, true);
        delete config;

        if (comboProfile->count() == 0)
        {
          readConfig("Inbox");
          generalTab->readConfig("Inbox");
          newmailTab->readConfig("Inbox");
          mailboxTab->readConfig("Inbox");
        }
        else
        {
          readConfig(comboProfile->currentText());
          generalTab->readConfig(comboProfile->currentText());
          newmailTab->readConfig(comboProfile->currentText());
          mailboxTab->readConfig(comboProfile->currentText());
        }

        break;
      }
    case KMessageBox::No:
    default:
      break;
  }
}

///////////////////////////////////////////////////////////////////////
// KBiffGeneralTab
///////////////////////////////////////////////////////////////////////
KBiffGeneralTab::KBiffGeneralTab(const TQString& profile_, TQWidget *parent_)
  : TQWidget(parent_)
{
  // the poll time (in seconds)
  TQLabel* poll_label = new TQLabel(i18n("P&oll (sec):"), this);
  editPoll = new TQLineEdit(this);
  poll_label->setBuddy(editPoll);
  TQString whatsthis = i18n(
      "This is the interval (in seconds) that KBiff will check "
      "for new mail.  Typically, this can be quite small (under "
      "60 seconds) for local mailboxes but should be around 5 "
      "minutes (300 seconds) for remote mailboxes");
  TQWhatsThis::add(editPoll, whatsthis);

  // the command to run when clicked
  TQLabel *mail_label = new TQLabel(i18n("&Mail client:"), this);
  editCommand = new TQLineEdit(this);
  mail_label->setBuddy(editCommand);
  whatsthis = i18n(
      "This is the mail client that KBiff was use when you click "
      "on the icon or the Mailer button.  If it's not in your path, "
      "then you must specify the location using an absolute path. "
      "This recognizes the <b>%m</b> and <b>%u</b> arguments.  The "
      "first is replaced with the first mailbox containing new mail "
      "and the latter is replaced with the mailbox's URL.");
  TQWhatsThis::add(editCommand, whatsthis);

  // do we dock automatically?
  checkDock = new TQCheckBox(i18n("Doc&k in panel"), this);

  // should we support session management?
  checkNoSession = new TQCheckBox(i18n("Use &session management"), this);

  // should we check at startup?
  checkNoStartup = new TQCheckBox(i18n("Don't &check at startup"), this);
  whatsthis = i18n(
      "This option is for those people using KBiff to check their "
      "IMAP4 or POP3 account over a dial-up connection.  If KBiff "
      "tries to connect at startup and you are not connected, the "
      "DNS lookup will hang for a long time.  If this is checked, "
      "then KBiff will not check for new mail on startup.  You will "
      "need to manually start it every time you connect");
  TQWhatsThis::add(checkNoStartup, whatsthis);

  // group box to hold the icons together
  TQGroupBox* icons_groupbox = new TQGroupBox(i18n("Icons:"), this);

  // "stopped" pixmap button
  TQLabel* stopped_label = new TQLabel(i18n("&Stopped:"), icons_groupbox);
  buttonStopped = new TDEIconButton(icons_groupbox);
  buttonStopped->setFixedSize(50, 50);
  buttonStopped->setIconType(TDEIcon::User, TDEIcon::Any, true);
  stopped_label->setBuddy(buttonStopped);

  // "no mailbox" pixmap button
  TQLabel* noconn_label = new TQLabel(i18n("No Mail&box:"), icons_groupbox);
  buttonNoConn = new TDEIconButton(icons_groupbox);
  buttonNoConn->setFixedSize(50, 50);
  buttonNoConn->setIconType(TDEIcon::User, TDEIcon::Any, true);
  noconn_label->setBuddy(buttonNoConn);

  // "no mail" pixmap button
  TQLabel* nomail_label = new TQLabel(i18n("No M&ail:"), icons_groupbox);
  buttonNoMail = new TDEIconButton(icons_groupbox);
  buttonNoMail->setIconType(TDEIcon::User, TDEIcon::Any, true);
  buttonNoMail->setFixedSize(50, 50);
  nomail_label->setBuddy(buttonNoMail);

  // "old mail" pixmap button
  TQLabel* oldmail_label = new TQLabel(i18n("O&ld Mail:"), icons_groupbox);
  buttonOldMail = new TDEIconButton(icons_groupbox);
  buttonOldMail->setIconType(TDEIcon::User, TDEIcon::Any, true);
  buttonOldMail->setFixedSize(50, 50);
  oldmail_label->setBuddy(buttonOldMail);

  // "new mail" pixmap button
  TQLabel* newmail_label = new TQLabel(i18n("N&ew Mail:"), icons_groupbox);
  buttonNewMail = new TDEIconButton(icons_groupbox);
  buttonNewMail->setIconType(TDEIcon::User, TDEIcon::Any, true);
  buttonNewMail->setFixedSize(50, 50);
  newmail_label->setBuddy(buttonNewMail);

  // poll time layout
  TQGridLayout *info_layout = new TQGridLayout(5, 3, 8);
  info_layout->addWidget(poll_label, 0, 0);
  info_layout->addWidget(editPoll, 0, 1);
  info_layout->setColStretch(2, 1);

  info_layout->addWidget(mail_label, 1, 0);
  info_layout->addMultiCellWidget(editCommand, 1, 1, 1, 2);
  info_layout->addMultiCellWidget(checkDock, 2, 2, 1, 2);
  info_layout->addMultiCellWidget(checkNoSession, 3, 3, 1, 2);
  info_layout->addMultiCellWidget(checkNoStartup, 4, 4, 1, 2);

  // icons layout
  TQVBoxLayout *stopped_layout = new TQVBoxLayout;
  stopped_layout->addWidget(stopped_label);
  stopped_layout->addWidget(buttonStopped);

  TQVBoxLayout *no_conn_layout = new TQVBoxLayout;
  no_conn_layout->addWidget(noconn_label);
  no_conn_layout->addWidget(buttonNoConn);

  TQVBoxLayout *no_mail_layout = new TQVBoxLayout;
  no_mail_layout->addWidget(nomail_label);
  no_mail_layout->addWidget(buttonNoMail);

  TQVBoxLayout *old_mail_layout = new TQVBoxLayout;
  old_mail_layout->addWidget(oldmail_label);
  old_mail_layout->addWidget(buttonOldMail);

  TQVBoxLayout *new_mail_layout = new TQVBoxLayout;
  new_mail_layout->addWidget(newmail_label);
  new_mail_layout->addWidget(buttonNewMail);

  TQHBoxLayout *inner_icon_layout = new TQHBoxLayout;
  inner_icon_layout->addStretch(1);
  inner_icon_layout->addLayout(stopped_layout);
  inner_icon_layout->addStretch(1);
  inner_icon_layout->addLayout(no_conn_layout);
  inner_icon_layout->addStretch(1);
  inner_icon_layout->addLayout(no_mail_layout);
  inner_icon_layout->addStretch(1);
  inner_icon_layout->addLayout(old_mail_layout);
  inner_icon_layout->addStretch(1);
  inner_icon_layout->addLayout(new_mail_layout);
  inner_icon_layout->addStretch(1);

  TQBoxLayout *outer_icon_layout = new TQBoxLayout(icons_groupbox,
                                                 TQBoxLayout::Down, 5);
  outer_icon_layout->addSpacing(8);
  outer_icon_layout->addLayout(inner_icon_layout);
  outer_icon_layout->addStretch(1);

  // main "outer" layout for this tab
  TQVBoxLayout *top_layout = new TQVBoxLayout(this, 12);
  top_layout->addLayout(info_layout);
  top_layout->addWidget(icons_groupbox);
  top_layout->addStretch(1);

  // now read in the config data for this profile
  readConfig(profile_);
}

KBiffGeneralTab::~KBiffGeneralTab()
{
}

bool KBiffGeneralTab::getSessionManagement() const
{
  return checkNoSession->isChecked();
}

bool KBiffGeneralTab::getCheckStartup() const
{
  return checkNoStartup->isChecked();
}

bool KBiffGeneralTab::getDock() const
{
  return checkDock->isChecked();
}

const TQString KBiffGeneralTab::getButtonOldMail() const
{
  return buttonOldMail->icon();
}

const TQString KBiffGeneralTab::getButtonNewMail() const
{
  return buttonNewMail->icon();
}

const TQString KBiffGeneralTab::getButtonNoMail() const
{
  return buttonNoMail->icon();
}

const TQString KBiffGeneralTab::getButtonNoConn() const
{
  return buttonNoConn->icon();
}

const TQString KBiffGeneralTab::getButtonStopped() const
{
  return buttonStopped->icon();
}

const TQString KBiffGeneralTab::getMailClient() const
{
  return editCommand->text();
}

int KBiffGeneralTab::getPoll() const
{
  return TQString(editPoll->text()).toInt();
}

void KBiffGeneralTab::readConfig(const TQString& profile_)
{
  // open the config file
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true);

  config->setGroup(profile_);

  // someday, we need to read in the system email prefs
  editPoll->setText(config->readEntry("Poll", "60"));
  editCommand->setText(config->readEntry("MailClient", "kmail -check"));
  checkDock->setChecked(config->readBoolEntry("Docked", true));
  checkNoSession->setChecked(config->readBoolEntry("Sessions", true));
  checkNoStartup->setChecked(config->readBoolEntry("DontCheck", false));

  TQString stopped, no_mail, old_mail, new_mail, no_conn;
  stopped  = config->readEntry("StoppedPixmap", "stopped");
  no_mail  = config->readEntry("NoMailPixmap", "nomail");
  old_mail = config->readEntry("OldMailPixmap", "oldmail");
  new_mail = config->readEntry("NewMailPixmap", "newmail");
  no_conn  = config->readEntry("NoConnPixmap", "noconn");

  buttonOldMail->setIcon(old_mail);
  buttonNewMail->setIcon(new_mail);
  buttonNoMail->setIcon(no_mail);
  buttonNoConn->setIcon(no_conn);
  buttonStopped->setIcon(stopped);

  delete config;
}

static TQString justIconName(const TQString& icon_name)
{
  // the following code is a bit of a hack, but there is a rationale
  // to it.  if possible, we want to just save the name of the icons
  // (without extension), and not the whole path due to name munging
  // later on.
  TQFileInfo info( icon_name );

  // we first test if the basename (filename without extensions) is
  // the same as the filename.  if it is, then we are perfect.  no
  // need to do anything further
  if ( info.baseName() == info.fileName() )
    return icon_name;

  // now we see if we can load based just on the basename
  TQPixmap icon = TDEGlobal::iconLoader()->loadIcon( info.baseName(), TDEIcon::User );

  // if it's null, then it's in a non-standard path so we must use an
  // absolute path.  no need to go further
  if ( icon.isNull() )
    return icon_name;

  // now we know that the icon loader can find it.. but is it the same
  // one as the one the user picked?
  if ( TDEGlobal::iconLoader()->iconPath( info.baseName(), TDEIcon::User ) !=
       TDEGlobal::iconLoader()->iconPath( icon_name, TDEIcon::User ) )
    return icon_name;

  // FINALLY done!  if we got this far, then we know that the icon
  // loader can handle just the name and that the icon returned is the
  // same one that the user wanted.  whew!
  return info.baseName();
}

void KBiffGeneralTab::saveConfig(const TQString& profile_)
{
  // open the config file for writing
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE);

  config->setGroup(profile_);

  config->writeEntry("Poll", editPoll->text());
  config->writeEntry("MailClient", editCommand->text());
  config->writeEntry("Docked", checkDock->isChecked());
  config->writeEntry("Sessions", checkNoSession->isChecked());
  config->writeEntry("DontCheck", checkNoStartup->isChecked());
  config->writeEntry("NoMailPixmap", justIconName(buttonNoMail->icon()));
  config->writeEntry("NewMailPixmap", justIconName(buttonNewMail->icon()));
  config->writeEntry("OldMailPixmap", justIconName(buttonOldMail->icon()));
  config->writeEntry("NoConnPixmap", justIconName(buttonNoConn->icon()));
  config->writeEntry("StoppedPixmap", justIconName(buttonStopped->icon()));
  delete config;
}

///////////////////////////////////////////////////////////////////////
// KBiffNewMailTab
///////////////////////////////////////////////////////////////////////
KBiffNewMailTab::KBiffNewMailTab(const TQString& profile_, TQWidget *parent_)
  : TQWidget(parent_)
{
  // setup the Run Command stuff
  checkRunCommand = new TQCheckBox(i18n("R&un Command"), this);
  editRunCommand = new TQLineEdit(this);
  buttonBrowseRunCommand = new TQPushButton(i18n("Browse"), this);

  // setup the Run Reset Command stuff
  checkRunResetCommand = new TQCheckBox(i18n("R&un Reset-Command"), this);
  editRunResetCommand = new TQLineEdit(this);
  buttonBrowseRunResetCommand = new TQPushButton(i18n("Browse"), this);

  // setup the Play Sound stuff
  checkPlaySound = new TQCheckBox(i18n("&Play Sound"), this);
  editPlaySound = new TQLineEdit(this);
  buttonBrowsePlaySound = new TQPushButton(i18n("Browse"), this);

  buttonTestPlaySound = new TQPushButton(this);
  buttonTestPlaySound->setPixmap(UserIcon("playsound"));

  // setup the System stuff
  checkBeep = new TQCheckBox(i18n("System &Beep"), this);
  checkNotify = new TQCheckBox(i18n("N&otify"), this);
  checkStatus = new TQCheckBox(i18n("&Floating Status"), this);

  // connect some slots and signals
  connect(buttonBrowsePlaySound, TQ_SIGNAL(clicked()), TQ_SLOT(browsePlaySound()));
  connect(buttonBrowseRunCommand, TQ_SIGNAL(clicked()), TQ_SLOT(browseRunCommand()));
  connect(buttonBrowseRunResetCommand, TQ_SIGNAL(clicked()), TQ_SLOT(browseRunResetCommand()));
  connect(checkPlaySound, TQ_SIGNAL(toggled(bool)), TQ_SLOT(enablePlaySound(bool)));
  connect(buttonTestPlaySound, TQ_SIGNAL(clicked()), TQ_SLOT(testPlaySound()));
  connect(checkRunCommand, TQ_SIGNAL(toggled(bool)), TQ_SLOT(enableRunCommand(bool)));
  connect(checkRunResetCommand, TQ_SIGNAL(toggled(bool)), TQ_SLOT(enableRunResetCommand(bool)));

  // NOW DO THE LAYOUT
  TQHBoxLayout *run_command_layout = new TQHBoxLayout(5);
  run_command_layout->addWidget(editRunCommand);
  run_command_layout->addWidget(buttonBrowseRunCommand);

  TQHBoxLayout *run_reset_command_layout = new TQHBoxLayout(5);
  run_reset_command_layout->addWidget(editRunResetCommand);
  run_reset_command_layout->addWidget(buttonBrowseRunResetCommand);

  TQHBoxLayout *play_sound_layout = new TQHBoxLayout(5);
  play_sound_layout->addWidget(buttonTestPlaySound, 0);
  play_sound_layout->addWidget(editPlaySound, 1);
  play_sound_layout->addWidget(buttonBrowsePlaySound);

  TQVBoxLayout *top_layout = new TQVBoxLayout(this, 5);
  top_layout->addWidget(checkRunCommand);
  top_layout->addLayout(run_command_layout);

  top_layout->addWidget(checkRunResetCommand);
  top_layout->addLayout(run_reset_command_layout);

  top_layout->addWidget(checkPlaySound);
  top_layout->addLayout(play_sound_layout);

  top_layout->addWidget(checkBeep);
  top_layout->addWidget(checkNotify);
  top_layout->addWidget(checkStatus);
  top_layout->addStretch(1);

  readConfig(profile_);
}

KBiffNewMailTab::~KBiffNewMailTab()
{
}

void KBiffNewMailTab::testPlaySound()
{
  KAudioPlayer::play(getPlaySoundPath());
}

void KBiffNewMailTab::readConfig(const TQString& profile_)
{
  // open the config file
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true);

  config->setGroup(profile_);

  checkRunCommand->setChecked(config->readBoolEntry("RunCommand", false));
  checkRunResetCommand->setChecked(config->readBoolEntry("RunResetCommand", false));
  checkPlaySound->setChecked(config->readBoolEntry("PlaySound", false));
  checkBeep->setChecked(config->readBoolEntry("SystemBeep", true));
  checkNotify->setChecked(config->readBoolEntry("Notify", true));
  checkStatus->setChecked(config->readBoolEntry("Status", true));
  editRunCommand->setText(config->readEntry("RunCommandPath"));
  editRunResetCommand->setText(config->readEntry("RunResetCommandPath"));
  editPlaySound->setText(config->readEntry("PlaySoundPath"));

  enableRunCommand(checkRunCommand->isChecked());
  enableRunResetCommand(checkRunResetCommand->isChecked());
  enablePlaySound(checkPlaySound->isChecked());

  delete config;
}

void KBiffNewMailTab::saveConfig(const TQString& profile_)
{
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE);

  config->setGroup(profile_);

  config->writeEntry("RunCommand", checkRunCommand->isChecked());
  config->writeEntry("RunResetCommand", checkRunResetCommand->isChecked());
  config->writeEntry("PlaySound", checkPlaySound->isChecked());
  config->writeEntry("SystemBeep", checkBeep->isChecked());
  config->writeEntry("Notify", checkNotify->isChecked());
  config->writeEntry("Status", checkStatus->isChecked());
  config->writeEntry("RunCommandPath", editRunCommand->text());
  config->writeEntry("RunResetCommandPath", editRunResetCommand->text());
  config->writeEntry("PlaySoundPath", editPlaySound->text());

  delete config;
}

bool KBiffNewMailTab::getRunCommand() const
{
  return checkRunCommand->isChecked();
}

const TQString KBiffNewMailTab::getRunCommandPath() const
{
  return editRunCommand->text();
}

bool KBiffNewMailTab::getRunResetCommand() const
{
  return checkRunResetCommand->isChecked();
}

const TQString KBiffNewMailTab::getRunResetCommandPath() const
{
  return editRunResetCommand->text();
}

bool KBiffNewMailTab::getPlaySound() const
{
  return checkPlaySound->isChecked();
}

const TQString KBiffNewMailTab::getPlaySoundPath() const
{
  return editPlaySound->text();
}

bool KBiffNewMailTab::getSystemBeep() const
{
  return checkBeep->isChecked();
}

bool KBiffNewMailTab::getNotify() const
{
  return checkNotify->isChecked();
}

bool KBiffNewMailTab::getStatus() const
{
  return checkStatus->isChecked();
}

void KBiffNewMailTab::enableRunCommand(bool enable)
{
  editRunCommand->setEnabled(enable);
  buttonBrowseRunCommand->setEnabled(enable);
}

void KBiffNewMailTab::enableRunResetCommand(bool enable)
{
  editRunResetCommand->setEnabled(enable);
  buttonBrowseRunResetCommand->setEnabled(enable);
}

void KBiffNewMailTab::enablePlaySound(bool enable)
{
  editPlaySound->setEnabled(enable);
  buttonBrowsePlaySound->setEnabled(enable);
  buttonTestPlaySound->setEnabled(enable);
}

void KBiffNewMailTab::browseRunCommand()
{

  KURL url = KFileDialog::getOpenURL();

  if( url.isEmpty() )
    return;

  if( !url.isLocalFile() )
  {
    KMessageBox::sorry( 0L, i18n( "Only local files can be executed." ) );
    return;
  }

  editRunCommand->setText( url.path() );
}

void KBiffNewMailTab::browseRunResetCommand()
{

  KURL url = KFileDialog::getOpenURL();

  if( url.isEmpty() )
    return;

  if( !url.isLocalFile() )
  {
    return;
  }

  editRunResetCommand->setText( url.path() );
}

void KBiffNewMailTab::browsePlaySound()
{

  KURL url = KFileDialog::getOpenURL();

  if( url.isEmpty() )
    return;

  if( !url.isLocalFile() )
  {
    KMessageBox::sorry( 0L, i18n( "Only local files are supported yet." ) );
    return;
  }

  editPlaySound->setText( url.path() );
}


//////////////////////////////////////////////////////////////////////
// KBiffMailboxTab
//////////////////////////////////////////////////////////////////////
KBiffMailboxAdvanced::KBiffMailboxAdvanced()
  : KDialog(0, 0, true, 0)
{
  setCaption(i18n("Advanced Options"));

  TQLabel *mailbox_label = new TQLabel(i18n("Mailbox &URL:"), this);
  mailbox_label->setAlignment(AlignVCenter | AlignRight);
  mailbox = new TQLineEdit(this);
  mailbox_label->setBuddy(mailbox);
  TQString whatsthis = i18n(
      "KBiff uses URLs to specify a mailbox and the parameters "
      "to the mailbox.  This allows you to modify the URL directly. "
      "Do so <i>only</i> if you really really know what you're doing!");
  TQWhatsThis::add(mailbox, whatsthis);

  TQLabel *port_label = new TQLabel(i18n("P&ort:"), this);
  port_label->setAlignment(AlignVCenter | AlignRight);
  port = new TQLineEdit(this);
  port_label->setBuddy(port);
  whatsthis = i18n(
      "This allows you to specify the port of your socket protocol. "
      "It usually is correct, so the only time you would change it is "
      "if you are accessing a non-standard server or going through "
      "a proxy (or something similar");
  TQWhatsThis::add(port, whatsthis);

  whatsthis = i18n(
      "IMAP4, POP3, and NNTP sockets each have their own timeout "
      "before they give up. If you have a slow connection, you might "
      "want to set this to some random high value");
  TQLabel *timeout_label = new TQLabel(i18n("&Timeout:"), this);
  timeout_label->setAlignment(AlignVCenter | AlignRight);
  timeout = new TQLineEdit(this);
  TQWhatsThis::add(timeout, whatsthis);
  timeout_label->setBuddy(timeout);

  preauth = new TQCheckBox(i18n("&PREAUTH"), this);
  preauth->setEnabled(false);
  whatsthis = i18n(
      "Check this if you login to your IMAP4 or POP3 server before "
      "kbiff accesses it.");
  TQWhatsThis::add(preauth, whatsthis);

  keepalive = new TQCheckBox(i18n("&Keep Alive"), this);
  keepalive->setEnabled(false);
  whatsthis = i18n(
      "If this is checked, then the IMAP4, POP3, or NNTP client "
      "will not log off each time");
  TQWhatsThis::add(keepalive, whatsthis);

  async = new TQCheckBox(i18n("&Asynchronous"), this);
  async->setEnabled(false);
  whatsthis = i18n(
      "If this is checked, then the socket protocols will access "
      "the server asynchronously");
  TQWhatsThis::add(async, whatsthis);
  
  apop = new TQCheckBox(i18n("&Disable APOP"), this);
  apop->setEnabled(false);
  whatsthis = i18n(
      "If this is checked, then POP mailboxes will not use Authenticated POP where available, "
      "and send passwords in plaintext over the network, which is a security risk");
  TQWhatsThis::add(apop, whatsthis);

  TQPushButton *ok = new TQPushButton(i18n("&OK"), this);
  ok->setDefault(true);

  TQPushButton *cancel = new TQPushButton(i18n("&Cancel"), this);

  // connect all the slots to signals
  connect(preauth, TQ_SIGNAL(toggled(bool)), TQ_SLOT(preauthModified(bool)));
  connect(keepalive, TQ_SIGNAL(toggled(bool)), TQ_SLOT(keepaliveModified(bool)));
  connect(async, TQ_SIGNAL(toggled(bool)), TQ_SLOT(asyncModified(bool)));
  connect(apop, TQ_SIGNAL(toggled(bool)), TQ_SLOT(apopModified(bool)));
  connect(port, TQ_SIGNAL(textChanged(const TQString&)),
                TQ_SLOT(portModified(const TQString&)));
  connect(ok, TQ_SIGNAL(clicked()), TQ_SLOT(accept()));
  connect(cancel, TQ_SIGNAL(clicked()), TQ_SLOT(reject()));
  connect(timeout, TQ_SIGNAL(textChanged(const TQString&)),
                   TQ_SLOT(timeoutModified(const TQString&)));

  // NOW DO THE LAYOUT
  TQGridLayout *top_layout = new TQGridLayout(this, 7, 4, 12);
  top_layout->addWidget(mailbox_label, 0, 0);
  top_layout->addMultiCellWidget(mailbox, 0, 0, 1, 3);
  top_layout->addWidget(port_label, 1, 0);
  top_layout->addWidget(port, 1, 1);
  top_layout->addWidget(timeout_label, 1, 2);
  top_layout->addWidget(timeout, 1, 3);
  top_layout->addWidget(preauth, 2, 1);
  top_layout->addWidget(keepalive, 3, 1);
  top_layout->addWidget(async, 4, 1);
  top_layout->addWidget(apop, 4, 1);
  top_layout->addWidget(ok, 6, 2);
  top_layout->addWidget(cancel, 6, 3);
}

KBiffMailboxAdvanced::~KBiffMailboxAdvanced()
{
}

const KBiffURL KBiffMailboxAdvanced::getMailbox() const
{
  KBiffURL url(mailbox->text());
  url.setPass(password);
  return url;
}

unsigned int KBiffMailboxAdvanced::getPort() const
{
  return TQString(port->text()).toInt();
}

void KBiffMailboxAdvanced::setMailbox(const KBiffURL& url)
{
  password = url.pass();
  KBiffURL new_url(url);
  new_url.setPass("");
  mailbox->setText(new_url.url());
}

void KBiffMailboxAdvanced::setPort(unsigned int the_port, bool enable)
{
  port->setEnabled(enable);
  port->setText(TQString().setNum(the_port));
}

void KBiffMailboxAdvanced::portModified(const TQString& text)
{
  KBiffURL url = getMailbox();
  url.setPort(TQString(text).toInt());
  setMailbox(url);
}

void KBiffMailboxAdvanced::setTimeout(unsigned int the_to, bool enable)
{
  timeout->setEnabled(enable);
  timeout->setText(TQString().setNum(the_to));
}

void KBiffMailboxAdvanced::timeoutModified(const TQString& text)
{
  KBiffURL url = getMailbox();
  url.setSearchPar("timeout", text.local8Bit());
  setMailbox(url);
}

void KBiffMailboxAdvanced::preauthModified(bool is_preauth)
{
  KBiffURL url = getMailbox();
  if (is_preauth)
    url.setSearchPar("preauth", "yes");
  else
    url.setSearchPar("preauth", "no");
  setMailbox(url);
}

void KBiffMailboxAdvanced::keepaliveModified(bool is_keepalive)
{
  KBiffURL url = getMailbox();
  if (is_keepalive)
    url.setSearchPar("keepalive", "yes");
  else
    url.setSearchPar("keepalive", "no");
  setMailbox(url);
}

void KBiffMailboxAdvanced::asyncModified(bool is_async)
{
  KBiffURL url = getMailbox();
  if (is_async)
    url.setSearchPar("async", "yes");
  else
    url.setSearchPar("async", "no");
  setMailbox(url);
}

void KBiffMailboxAdvanced::apopModified(bool disable_apop)
{
  KBiffURL url = getMailbox();
  if ( url.protocol() == "pop3" || url.protocol() == "pop3s" )
  {
    if ( disable_apop )
      url.setSearchPar("apop", "no");
    else
      url.setSearchPar("apop", "yes");
    setMailbox(url);
  }
}

void KBiffMailboxAdvanced::setPreauth(bool on)
{
  preauth->setEnabled(true);
  preauth->setChecked(on);
}

void KBiffMailboxAdvanced::setKeepalive(bool on)
{
  keepalive->setEnabled(true);
  keepalive->setChecked(on);
}

void KBiffMailboxAdvanced::setAsync(bool on)
{
  async->setEnabled(true);
  async->setChecked(on);
}

void KBiffMailboxAdvanced::setDisableApop(bool on)
{
  apop->setEnabled(true);
  apop->setChecked(on);
}

bool KBiffMailboxAdvanced::getPreauth() const
{
  return preauth->isChecked();
}

KBiffMailboxTab::KBiffMailboxTab(const TQString& profile_, TQWidget *parent_)
  : TQWidget(parent_), mailboxHash(new TQDict<KBiffMailbox>)
{
  if (mailboxHash)
    mailboxHash->setAutoDelete(true);

  mailboxes = new TQListView(this);
  mailboxes->setFrameStyle(TQFrame::WinPanel | TQFrame::Sunken);
  mailboxes->addColumn(i18n("Mailbox:"));
  mailboxes->header()->hide();

  TQPushButton *new_mailbox = new TQPushButton(this);
  new_mailbox->setPixmap(UserIcon("mailbox"));
  TQToolTip::add(new_mailbox, i18n("New Mailbox"));

  TQPushButton *delete_mailbox = new TQPushButton(this);
  delete_mailbox->setPixmap(UserIcon("delete"));
  TQToolTip::add(delete_mailbox, i18n("Delete Mailbox"));

  TQLabel *protocol_label = new TQLabel(i18n("Pro&tocol:"), this);
  comboProtocol = new TQComboBox(this);
  comboProtocol->insertItem("");
  comboProtocol->insertItem("mbox");
  comboProtocol->insertItem("maildir");    
  comboProtocol->insertItem("imap4");
  comboProtocol->insertItem("pop3");
  comboProtocol->insertItem("mh");
  comboProtocol->insertItem("file");
  comboProtocol->insertItem("nntp");
#ifdef USE_SSL
  comboProtocol->insertItem("imap4s");
  comboProtocol->insertItem("pop3s");
#endif // USE_SSL
  protocol_label->setBuddy(comboProtocol);

  TQLabel *mailbox_label = new TQLabel(i18n("&Mailbox:"), this);
  editMailbox = new TQLineEdit(this);
  mailbox_label->setBuddy(editMailbox);
  buttonBrowse = new TQPushButton("...", this);

  TQLabel *server_label = new TQLabel(i18n("&Server:"), this);
  editServer = new TQLineEdit(this);
  server_label->setBuddy(editServer);

  TQLabel *user_label = new TQLabel(i18n("&User:"), this);
  editUser = new TQLineEdit(this);
  user_label->setBuddy(editUser);

  TQLabel *password_label = new TQLabel(i18n("P&assword:"), this);
  editPassword = new TQLineEdit(this);
  editPassword->setEchoMode(TQLineEdit::Password);
  password_label->setBuddy(editPassword);

  checkStorePassword = new TQCheckBox(i18n("S&tore password"), this);
  TQPushButton *advanced_button = new TQPushButton(i18n("&Advanced"), this);

  // the command to run before polling
  TQGroupBox *fetch_box = new TQGroupBox(this);
  fetch_box->setTitle(i18n("Pre-&Polling Command"));
  fetch_box->setColumnLayout(0, TQt::Vertical );
  fetch_box->layout()->setSpacing(0);
  fetch_box->layout()->setMargin(0);

  checkFetchCommand = new TQCheckBox(i18n("&Enable"), fetch_box);
  editFetchCommand = new TQLineEdit(fetch_box);
  buttonBrowseFetchCommand = new TQPushButton(i18n("Browse"), fetch_box);
  TQString whatsthis = i18n(
      "This command shall be run <em>before</em> KBiff polls for new "
      "mail.  It is useful for those people that want to download their "
      "POP3 mail regularly using (for instance) 'fetchmail'");
  TQWhatsThis::add(checkFetchCommand, whatsthis);
  TQWhatsThis::add(editFetchCommand, whatsthis);
  TQWhatsThis::add(buttonBrowseFetchCommand, whatsthis);
  enableFetchCommand(false);

  // connect all the signals
  connect(mailboxes, TQ_SIGNAL(selectionChanged(TQListViewItem *)),
                     TQ_SLOT(slotMailboxSelected(TQListViewItem *)));
  connect(new_mailbox, TQ_SIGNAL(clicked()), TQ_SLOT(slotNewMailbox()));
  connect(delete_mailbox, TQ_SIGNAL(clicked()), TQ_SLOT(slotDeleteMailbox()));
  connect(comboProtocol, TQ_SIGNAL(highlighted(int)),
                         TQ_SLOT(protocolSelected(int)));
  connect(buttonBrowse, TQ_SIGNAL(clicked()), TQ_SLOT(browse()));
  connect(advanced_button, TQ_SIGNAL(clicked()), TQ_SLOT(advanced()));
  connect(buttonBrowseFetchCommand, TQ_SIGNAL(clicked()), TQ_SLOT(browseFetchCommand()));
  connect(checkFetchCommand, TQ_SIGNAL(toggled(bool)), TQ_SLOT(enableFetchCommand(bool)));

  // NOW DO THE LAYOUT
  TQHBoxLayout *fetch_command_layout = new TQHBoxLayout(5);
  fetch_command_layout->addWidget(editFetchCommand, 1);
  fetch_command_layout->addWidget(buttonBrowseFetchCommand);

  TQVBoxLayout *group_layout = new TQVBoxLayout(fetch_box->layout());
  group_layout->setAlignment(TQt::AlignTop);
  group_layout->setSpacing(6);
  group_layout->setMargin(11);
  group_layout->addWidget(checkFetchCommand);
  group_layout->addLayout(fetch_command_layout);

  TQHBoxLayout *advanced_layout = new TQHBoxLayout;
  advanced_layout->addStretch(1);
  advanced_layout->addWidget(advanced_button);

  TQGridLayout *param_layout = new TQGridLayout(6, 3, 12);
  param_layout->addWidget(protocol_label, 0, 0);
  param_layout->addWidget(comboProtocol, 0, 1, 1);
  param_layout->addWidget(buttonBrowse, 0, 2);
  param_layout->addWidget(mailbox_label, 1, 0);
  param_layout->addMultiCellWidget(editMailbox, 1, 1, 1, 2);
  param_layout->addWidget(server_label, 2, 0);
  param_layout->addMultiCellWidget(editServer, 2, 2, 1, 2);
  param_layout->addWidget(user_label, 3, 0);
  param_layout->addMultiCellWidget(editUser, 3, 3, 1, 2);
  param_layout->addWidget(password_label, 4, 0);
  param_layout->addMultiCellWidget(editPassword, 4, 4, 1, 2);
  param_layout->addMultiCellWidget(checkStorePassword, 5, 5, 1, 2);
  param_layout->setColStretch(1, 1);

  TQVBoxLayout *right_side_layout = new TQVBoxLayout;
  right_side_layout->addLayout(param_layout);
  right_side_layout->addWidget(fetch_box);
  right_side_layout->addLayout(advanced_layout);
  right_side_layout->addStretch(1);

  TQGridLayout *mailbox_layout = new TQGridLayout(2, 2, 1);
  mailbox_layout->addMultiCellWidget(mailboxes, 0, 0, 0, 1);
  mailbox_layout->addWidget(new_mailbox, 1, 0);
  mailbox_layout->addWidget(delete_mailbox, 1, 1);

  TQHBoxLayout *top_layout = new TQHBoxLayout(this, 12);
  top_layout->addLayout(mailbox_layout);
  top_layout->addLayout(right_side_layout);

  readConfig(profile_);
}

KBiffMailboxTab::~KBiffMailboxTab()
{
  delete mailboxHash;
}

void KBiffMailboxTab::readConfig(const TQString& profile_)
{
  // initialize some variables that need initing
  oldItem = 0;

  // open the config file
  KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true);
  config->setDollarExpansion(false);

  mailboxHash->clear();
  mailboxes->clear();

  config->setGroup(profile_);

  TQStringList mailbox_list;

  mailbox_list = config->readListEntry("Mailboxes", ',');
  int number_of_mailboxes = mailbox_list.count();

  if (number_of_mailboxes > 0)
  {
    for (unsigned int i = 0; i < mailbox_list.count(); i+=3)
    {
      KBiffMailbox *mailbox = new KBiffMailbox();
      mailbox->key = *mailbox_list.at(i);
      mailbox->url = KBiffURL(*mailbox_list.at(i+1));
      TQString password(KBiffCodecs::base64Decode(*mailbox_list.at(i+2)));

      if (password.isEmpty())
        mailbox->store = false;
      else
      {
        mailbox->store = true;
        mailbox->url.setPass(password);
      }

      TQListViewItem *item = new TQListViewItem(mailboxes, mailbox->key);
      item->setPixmap(0, TQPixmap(UserIcon("mailbox")));

      mailboxHash->insert(mailbox->key, mailbox);
    }
  }
  else
  {
    KBiffMailbox *mailbox = new KBiffMailbox();
    mailbox->key = i18n("Default");
    mailbox->store = false;
    mailbox->url = defaultMailbox();
    mailboxHash->insert(mailbox->key, mailbox);

    TQListViewItem *item = new TQListViewItem(mailboxes, mailbox->key);
    item->setPixmap(0, TQPixmap(UserIcon("mailbox")));
  }

  mailboxes->setSelected(mailboxes->firstChild(), true);
  delete config;
}

void KBiffMailboxTab::saveConfig(const TQString& profile_)
{
    // open the config file
    KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE);
    config->setDollarExpansion(false);

    config->setGroup(profile_);

    TQStringList mailbox_list;

    for (TQListViewItem *item = mailboxes->firstChild();
         item;
          item = item->nextSibling())
    {
        KBiffMailbox *mailbox = new KBiffMailbox();
        TQString item_text(item->text(0));

        // if this mailbox is the current one, then use the current
        // settings instead of the hash
        if (item == mailboxes->currentItem())
        {
            mailbox->store = checkStorePassword->isChecked();
            mailbox->url   = getMailbox();

            mailboxHash->replace(item_text, mailbox);
        }

        mailbox = mailboxHash->find(item_text);

        TQString password(KBiffCodecs::base64Encode(mailbox->url.pass().local8Bit()));
        KBiffURL url = mailbox->url;
        url.setPass("");

        if (mailbox->store == false)
            password = "";
    
        mailbox_list.append(item_text);
        mailbox_list.append(url.url());
        mailbox_list.append(password);
    }

    config->writeEntry("Mailboxes", mailbox_list, ',');
    delete config;
}

void KBiffMailboxTab::enableFetchCommand(bool enable)
{
  editFetchCommand->setEnabled(enable);
  buttonBrowseFetchCommand->setEnabled(enable);
}

void KBiffMailboxTab::browseFetchCommand()
{
  KURL url = KFileDialog::getOpenURL();

  if( url.isEmpty() )
    return;

  if( !url.isLocalFile() )
  {
    KMessageBox::sorry( 0L, i18n( "Only local files can be executed." ) );
    return;
  }

  editFetchCommand->setText( url.path() );
}

void KBiffMailboxTab::setMailbox(const KBiffURL& url)
{
    TQString prot(url.protocol());

    if (prot == "mbox")
        protocolSelected(1);
    else if (prot == "maildir")
        protocolSelected(2);
    else if (prot == "imap4")
        protocolSelected(3);
    else if (prot == "pop3")
        protocolSelected(4);
    else if (prot == "mh")
        protocolSelected(5);
    else if (prot == "file")
        protocolSelected(6);
    else if (prot == "nntp")
        protocolSelected(7);
#ifdef USE_SSL
    else if (prot == "imap4s")
        protocolSelected(8);
    else if (prot == "pop3s")
        protocolSelected(9);
#endif // USE_SSL
    else
        return;

    if (editMailbox->isEnabled())
    {
        TQString path(url.path());
        if (((prot == "imap4") || (prot == "nntp") || (prot == "imap4s")) && !path.isEmpty() && path[0] == '/')
            path.remove(0, 1);

        editMailbox->setText(path);
    }

    port = url.port();

    if (editServer->isEnabled())
        editServer->setText(url.host());
    if (editUser->isEnabled())
    {
        TQString user(url.user());
        editUser->setText(user);
    }
    if (editPassword->isEnabled())
    {
        TQString passwd(url.pass());
        editPassword->setText(passwd);
    }

    timeout = url.searchPar("timeout").toInt();
    preauth = url.searchPar("preauth") == "yes" ? true : false;
    keepalive = url.searchPar("keepalive") == "yes" ? true : false;
    async = url.searchPar("async") == "yes" ? true : false;
    useApop = url.searchPar("apop") == "no" ? false : true;

    TQString fetch = url.searchPar("fetch");
    checkFetchCommand->setChecked(!fetch.isEmpty());
    editFetchCommand->setText(fetch);
}

const KBiffURL KBiffMailboxTab::getMailbox() const
{
    KBiffURL url;

    url.setProtocol(comboProtocol->currentText());
    TQString prot(url.protocol());

    if (editUser->isEnabled())
    {
        TQString user(editUser->text());
        url.setUser(user);
    }

    if (editPassword->isEnabled())
    {
        TQString passwd(editPassword->text());
        url.setPass(passwd);
    }

    if (editServer->isEnabled())
        url.setHost(editServer->text());

    url.setPort(port);

    if (editMailbox->isEnabled())
    {
        TQString path(editMailbox->text());
        if (!path.isEmpty() && path[0] != '/')
            path.prepend("/");
        url.setPath(path);
    }

    if ((prot == "imap4") || (prot == "pop3") || (prot == "nntp") || (prot == "imap4s") || (prot == "pop3s"))
    {
        if (keepalive)
            url.setSearchPar("keepalive", "yes");
        else
            url.setSearchPar("keepalive", "no");

        if (async)
            url.setSearchPar("async", "yes");
        else
            url.setSearchPar("async", "no");

        if ((prot == "pop3s") || (prot == "pop3") )
        {
            if (useApop)
                url.setSearchPar("apop", "yes");
            else
                url.setSearchPar("apop", "no");
        }
        url.setSearchPar("timeout", TQString().setNum(timeout));
    }

    if (checkFetchCommand->isChecked() && !editFetchCommand->text().isEmpty())
        url.setSearchPar("fetch", editFetchCommand->text());

    return url;
}

const TQPtrList<KBiffMailbox> KBiffMailboxTab::getMailboxList() const
{
    TQPtrList<KBiffMailbox> mbox_list;

    for (TQListViewItem *item = mailboxes->firstChild();
         item;
         item = item->nextSibling())
    {
        KBiffMailbox *mailbox = mailboxHash->find(item->text(0));
        // without the next line the key of the first mailbox is lost.
        // it's a mystery for me
        mailbox->key = item->text(0);
        mbox_list.append(mailbox);
    }
    return mbox_list;
}

void KBiffMailboxTab::slotDeleteMailbox()
{
    /* only delete the non default mailboxes */
    if (mailboxes->childCount() == 1)
        return;

    /* need some "Are you sure?" code here */
    TQListViewItem *item = mailboxes->currentItem();

    mailboxHash->remove(item->text(0));
    mailboxes->takeItem(item);
    item = 0;

    mailboxes->setSelected(mailboxes->firstChild(), true);
}

void KBiffMailboxTab::slotNewMailbox()
{
    KBiffNewDlg dlg;

    // popup the name chooser
    dlg.setCaption(i18n("New Mailbox"));
    if (dlg.exec())
    {
        TQString mailbox_name = dlg.getName();

        // continue only if we received a decent name
        if (mailbox_name.isEmpty() == false)
        {
            TQListViewItem *item = new TQListViewItem(mailboxes, mailbox_name);
            item->setPixmap(0, TQPixmap(UserIcon("mailbox")));

            KBiffMailbox *mailbox = new KBiffMailbox();
            mailbox->store = false;
            mailbox->url   = defaultMailbox();

            mailboxHash->insert(mailbox_name, mailbox);
            mailboxes->setSelected(item, true);
        }
    }
}

void KBiffMailboxTab::slotMailboxSelected(TQListViewItem *item)
{
    KBiffMailbox *mailbox;

    // if an "old" item exists, save the current info as it
    if (oldItem && !oldItem->text(0).isNull())
    {
        mailbox = mailboxHash->find(oldItem->text(0));

        if (mailbox)
        {
            // change the hash only if the item is different
            KBiffURL url(getMailbox());
            bool checked = checkStorePassword->isChecked();
            if (mailbox->url.url() != url.url() || mailbox->store != checked)
            {
                mailbox->url   = getMailbox();
                mailbox->store = checkStorePassword->isChecked();
            }
        }
    }

    mailbox = mailboxHash->find(item->text(0));

    if (mailbox)
    {
        setMailbox(mailbox->url);
        checkStorePassword->setChecked(mailbox->store);

        // save this as the "old" item
        oldItem = item;
    }
}

void KBiffMailboxTab::protocolSelected(int protocol)
{
    comboProtocol->setCurrentItem(protocol);

    switch (protocol)
    {
        case 1: // mbox
        case 2: // maildir
        case 5: // mh
        case 6: // file
            port = 0;
            buttonBrowse->setEnabled(true);
            editMailbox->setEnabled(true);
            editServer->setEnabled(false);
            editUser->setEnabled(false);
            editPassword->setEnabled(false);
            checkStorePassword->setEnabled(false);
            break;
        case 3: // IMAP4
            port = 143;
            timeout = 10;
            editMailbox->setEnabled(true);
            buttonBrowse->setEnabled(true);
            editServer->setEnabled(true);
            editUser->setEnabled(true);
            editPassword->setEnabled(true);
            checkStorePassword->setEnabled(true);
            break;
#ifdef USE_SSL
        case 8: // IMAP4S
            port = 993;
            timeout = 10;
            editMailbox->setEnabled(true);
            buttonBrowse->setEnabled(true);
            editServer->setEnabled(true);
            editUser->setEnabled(true);
            editPassword->setEnabled(true);
            checkStorePassword->setEnabled(true);
            break;
#endif // USE_SSL
        case 7: // NNTP
            port = 119;
            timeout = 10;
            editMailbox->setEnabled(true);
            buttonBrowse->setEnabled(false);
            editServer->setEnabled(true);
            editUser->setEnabled(true);
            editPassword->setEnabled(true);
            checkStorePassword->setEnabled(true);
            break;
        case 4: // POP3
            port = 110;
            timeout = 10;
            editMailbox->setEnabled(false);
            buttonBrowse->setEnabled(false);
            editServer->setEnabled(true);
            editUser->setEnabled(true);
            editPassword->setEnabled(true);
            checkStorePassword->setEnabled(true);
            break;
#ifdef USE_SSL
        case 9: // POP3S
            port = 995;
            timeout = 10;
            editMailbox->setEnabled(false);
            buttonBrowse->setEnabled(false);
            editServer->setEnabled(true);
            editUser->setEnabled(true);
            editPassword->setEnabled(true);
            checkStorePassword->setEnabled(true);
            break;
#endif // USE_SSL
        default: // blank
            port = 0;
            timeout = 0;
            editMailbox->setEnabled(false);
            buttonBrowse->setEnabled(false);
            editServer->setEnabled(false);
            editUser->setEnabled(false);
            editPassword->setEnabled(false);
            checkStorePassword->setEnabled(false);
            break;
    }
}

void KBiffMailboxTab::browse()
{
  TQString proto(getMailbox().protocol());

  if (proto == "imap4" || proto == "imap4s")
  {
    KURL start;
    start.setProtocol((proto == "imap4s") ? "imaps" : "imap");
    start.setUser(getMailbox().user());
    start.setHost(getMailbox().host());
    start.setPath("/");
    KURL url = KFileDialog::getOpenURL(start.url());
    if (url.url().isEmpty())
      return;
    
    TQString path(url.path());
    if (path.isEmpty())
      return;

    if (path[0] == '/')
      path = path.right(path.length() - 1);
    if (path.right(1) == "/")
      path = path.left(path.length() - 1);

    editMailbox->setText( path );
    return;
  }
  else
  {
    TQString file;
    if (proto == "maildir")
      file = KFileDialog::getExistingDirectory();
    else
      file = KFileDialog::getOpenFileName();

    if( file.isEmpty() )
      return;

    editMailbox->setText( file );
  }
}

void KBiffMailboxTab::advanced()
{
  KBiffMailboxAdvanced advanced_dlg;
  TQString prot(getMailbox().protocol());

  if (prot == "mbox" || prot == "maildir" || prot == "file" || prot == "mh")
  {
    advanced_dlg.setPort(port, false);
    advanced_dlg.setTimeout(timeout, false);
  }
  else
  {
    advanced_dlg.setPort(port);
    advanced_dlg.setTimeout(timeout);
  }

  if ((prot == "imap4") || (prot == "imap4s"))
  {
    advanced_dlg.setPreauth(preauth);
    advanced_dlg.setKeepalive(keepalive);
    advanced_dlg.setAsync(async);
  }

  if ((prot == "pop3") || (prot == "nntp") || (prot == "pop3s"))
  {
    advanced_dlg.setKeepalive(keepalive);
    advanced_dlg.setAsync(async);
    advanced_dlg.setDisableApop(!useApop);
  }

  advanced_dlg.setMailbox(getMailbox());
  if (advanced_dlg.exec())
  {
    port = advanced_dlg.getPort();
    setMailbox(advanced_dlg.getMailbox());
  }
}

const KBiffURL KBiffMailboxTab::defaultMailbox() const
{
  TQFileInfo mailbox_info(getenv("MAIL"));
  if (mailbox_info.exists() == false)
  {
    TQString s(_PATH_MAILDIR);
    s += "/";
    s += getpwuid(getuid())->pw_name;
    mailbox_info.setFile(s);
  }

  TQString default_path = mailbox_info.isDir() ? TQString("maildir:") :
                                                TQString("mbox:");
  default_path.append(mailbox_info.absFilePath());

  return KBiffURL(default_path);
}

//////////////////////////////////////////////////////////////////////
// KBiffAboutTab
//////////////////////////////////////////////////////////////////////
KBiffAboutTab::KBiffAboutTab(TQWidget *parent_)
  : TQWidget(parent_)
{
  // load in the kbiff pixmap
  TQPixmap logo_pixmap(kapp->icon());

  TQLabel *pixmap_label = new TQLabel(this);
  pixmap_label->setPixmap(logo_pixmap);

  // we want a bigger logo
  TQFont logo_font = TQApplication::font();
  logo_font.setPointSize(logo_font.pointSize() * 1.5);
  logo_font.setBold(true);

  KURLLabel *logo_label = new KURLLabel(this);
  logo_label->setURL("http://kbiff.granroth.org");
  logo_label->setFont(logo_font);
  logo_label->setText("KBiff");
  logo_label->setUnderline(false);
  logo_label->setGlow(false);
  logo_label->setFloat(true);
  connect(logo_label, TQ_SIGNAL(leftClickedURL(const TQString&)),
                      TQ_SLOT(homepage(const TQString&)));

  TQLabel *version_label = new TQLabel(this);
  version_label->setText(TQString("Version %1\n\nCopyright (C) 1998-2008\nKurt Granroth").arg(kbiff_version));

  KURLLabel *email_label = new KURLLabel(this);
  email_label->setText("granroth@kde.org");
  email_label->setURL("mailto:granroth@kde.org");
  email_label->setUnderline(false);
  email_label->setGlow(false);
  email_label->setFloat(true);
  connect(email_label, TQ_SIGNAL(leftClickedURL(const TQString&)),
                       TQ_SLOT(mailTo(const TQString&)));

  // about tab text layout
  TQVBoxLayout *text_layout = new TQVBoxLayout(0);
  text_layout->addWidget(version_label);
  text_layout->addWidget(email_label);

  // main about tab layout
  TQGridLayout *about_layout = new TQGridLayout(this, 3, 2, 12, 0);
  about_layout->addWidget(pixmap_label, 0, 0);
  about_layout->addWidget(logo_label, 0, 1);
  about_layout->addLayout(text_layout, 1, 1);
  about_layout->setRowStretch(2, 1);
}

KBiffAboutTab::~KBiffAboutTab()
{
}

void KBiffAboutTab::mailTo(const TQString& url)
{
  (void) new KRun ( url );
}

void KBiffAboutTab::homepage(const TQString& url)
{
  (void) new KRun ( url );
}

KBiffNewDlg::KBiffNewDlg(TQWidget* parent_, const char * name_)
  : KDialog(parent_, name_, true)
{
  // set my name
  setCaption(i18n("New Name"));

  TQLabel* label = new TQLabel(i18n("&New Name:"), this);
  editName = new TQLineEdit(this);
  editName->setFocus();
  label->setBuddy(editName);

  // ok button
  TQPushButton* button_ok = new TQPushButton(i18n("&OK"), this);
  button_ok->setDefault(true);

  // cancel button
  TQPushButton* button_cancel = new TQPushButton(i18n("&Cancel"), this);

  connect(button_ok, TQ_SIGNAL(clicked()), TQ_SLOT(accept()));
  connect(button_cancel, TQ_SIGNAL(clicked()), TQ_SLOT(reject()));

  // NOW DO THE LAYOUT
  TQGridLayout *top_layout = new TQGridLayout(this, 2, 3, 12);
  top_layout->addWidget(label, 0, 0);
  top_layout->addMultiCellWidget(editName, 0, 0, 1, 2);
  top_layout->addWidget(button_ok, 1, 1);
  top_layout->addWidget(button_cancel, 1, 2);
}
