/***************************************************************************
                          dcgui.cpp  -  description
                             -------------------
    begin                : Mon Okt  1 19:59:45 CEST 2001
    copyright            : (C) 2001-2005 by Mathias Küster
    email                : mathen@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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "dcgui.h"
#include <config.h>
// Qt includes
#include <QApplication>
#include <QAction>
#include <QComboBox>
#include <QDialog>
#include <QFile>
#include <QLabel>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QPixmap>
#include <QStatusBar>
#include <QToolBar>
#include <QWhatsThis>
#include <QCloseEvent>
#include <QTextStream>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QStyle>
#include <QMetaObject>
#include <QDateTime>
#include <QPushButton>
#include <QProcess>
#include <QProgressBar>
#include <QDir>
#include <QDesktopServices>
#include <QUrl>

// for TabPosition enum
#include <QTabWidget>

// application specific includes
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif

#include "dcoptions.h"
#include "dchublistmanager.h"
#include "dcconnectionmanager.h"
#include "dctransferview.h"
#include "dcconfig.h"
#include "dchubsearch.h"
#include "dcspy.h"
#include "dcuserslist.h"
#include "dctranslator.h"
#include "dcevent.h"
#include "dcpluginmanager.h"
#include "dcmenuhandler.h"
#include "dciconloader.h"
#include "dcguiutils.h"
#include "dcquickconnect.h"

#ifndef WIN32
#include "dcinotifycontrol.h"
#endif

#include "dcclient.h"
#include "dcantispam.h"
#include "dcantispamcontrol.h"
#include "dcipfilter.h"
#include "dcipfiltercontrol.h"

#include <iostream>

#include "DCDialogAbout.h"
#include "ui/DCDialogDebugSettings.h"

#include <dclib/dcos.h>
#include <dclib/dcobject.h>
#include <dclib/cdownloadmanager.h>
#include <dclib/cfilemanager.h>
#include <dclib/csearchmanager.h>
#include <dclib/cutils.h>
#include <dclib/core/cdir.h>
#include <dclib/dclib.h>
#include <dclib/core/csocket.h>

#ifdef HAVE_MALLOC_H
#include <malloc.h>
#include <stdio.h>
#endif

QMdiArea *DCGuiApp::s_pMdiArea = NULL;
DCGuiApp *DCGuiApp::pMainWin = NULL;

/** */
DCGuiApp::DCGuiApp() {
    StringMap * map;
    StringMap * tabBarMap;
    int width, height;
    bool b;

    m_bTransferViewGotTrayed = false;
    m_bIsQuitPromptVisible = false;

    setWindowTitle(tr("EiskaltDC") + QString(" ") + QString(PACKAGE_VERSION));

    // set default icon
    setWindowIcon(DCIconLoader::Instance()->GetPixmap(eiICON_APPL));

    SetTheme();

    ///////////////////////////////////////////////////////////////////
    // call inits to invoke all other construction parts
    initView();
    initActions();
    initMenuBar();
    initToolBar();
    initStatusBar();
    initTray();

    connect(DCConfig::Instance(), SIGNAL(defaultDownloadModeChanged()), this, SLOT(slotDefaultDownloadModeChanged()));
    connect(DCConfig::Instance(), SIGNAL(awayModeChanged(eUserAwayMode)), this, SLOT(slotAwayModeChanged(eUserAwayMode)));
    connect(DCConfig::Instance(), SIGNAL(autoAwayModeChanged(bool)), this, SLOT(slotAutoAwayModeChanged(bool)));

    if (!(DCConfig::Instance()->GetBackgroundPixmap().isEmpty())) {
        QPixmap bp;
        if (bp.load(DCConfig::Instance()->GetBackgroundPixmap()))
            pMdiArea->setBackground(bp);
    }

    DCConfig::Instance()->GetAppGeometry(width, height);
    resize(width, height);

    b = true;

    // init transferview
    if (DCConfig::Instance()->GetMap("TRANSFERVIEW", map)) {
        if ((*map)["DOCKED"].toInt() == 0) {
            b = false;
        }
    }

    if (b) {
        pTransferViewDock->setFloating(false);

        if (((*map)["HEIGHT"].toInt() != 0) &&
                ((*map)["WIDTH"].toInt() != 0)) {
            //pTransferViewDock->setFixedExtentHeight((*map)["HEIGHT"].toInt());
            //pTransferViewDock->setFixedExtentWidth((*map)["WIDTH"].toInt());
        }

        bool nl = true;
        if ((*map)["NL"] == "FALSE") {
            nl = false;
        }
        //moveDockWindow( pTransferViewDock, Qt::Dock((*map)["DOCK"].toInt()), nl, (*map)["INDEX"].toInt(), (*map)["EXTRAOFFSET"].toInt() );
    } else {
        pTransferViewDock->setFloating(true);

        if (((*map)["HEIGHT"].toInt() != 0) &&
                ((*map)["WIDTH"].toInt() != 0)) {
            pTransferViewDock->resize((*map)["WIDTH"].toInt(), (*map)["HEIGHT"].toInt());
        }
    }

    viewTabBar->setChecked(true);
    viewToolBar->setChecked(true);
    viewStatusBar->setChecked(true);

    m_bWasMaximized = false;

    // init main window
    if (DCConfig::Instance()->GetMap("MAINVIEW", map)) {
        if ((*map)["MAXIMIZED"].toInt() == 1) {
            m_bWasMaximized = true;
        } else {
            m_bWasMaximized = false;
        }

        if ((*map)["DOCKED"].toInt() == 0) {
            //fileToolbar->setFloating(true);
        } else {
            //fileToolbar->setFloating(false);

            //moveDockWindow( fileToolbar, Qt::Dock((*map)["DOCK"].toInt()) );
        }
    }

    if (DCConfig::Instance()->GetTabBar() == false)
        viewTabBar->toggle();
    if (DCConfig::Instance()->GetToolBar() == false)
        viewToolBar->toggle();
    if (DCConfig::Instance()->GetStatusBar() == false)
        viewStatusBar->toggle();
    if (DCConfig::Instance()->GetShowTransferWin()) {
        switch (DCConfig::Instance()->GetTransferViewType()) {
            case etvtDOCK:
                pTransferViewDock->setWidget(DCTransferView::Instance());
                pTransferViewDock->show();

                break;
            case etvtWINDOW:
                DCTransferView::Instance()->initContainer();

                showMDIWidget(DCTransferView::Instance()->GetContainer());
                connect(DCTransferView::Instance(), SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));

                DCConnectionManager::Instance()->addTab(DCTransferView::Instance(), QApplication::translate("DCDialogTransfer", "Transfer List", 0, QApplication::UnicodeUTF8));

                break;
        }
    }

    // restore tabbar position and state
    if (DCConfig::Instance()->GetMap("TABBAR", tabBarMap)) {
        int x = (*tabBarMap)["X"].toInt();
        int y = (*tabBarMap)["Y"].toInt();
        int w = (*tabBarMap)["WIDTH"].toInt();
        int h = (*tabBarMap)["HEIGHT"].toInt();

        if ((*tabBarMap)["DOCKED"].toInt() == 0) {
            //windowsTabBar->setFloating(true);

            if ((w != 0) && (h != 0)) {
                windowsTabBar->resize(w, h);
            }

            windowsTabBar->move(x, y);
        } else {
            //windowsTabBar->setFloating(false);

            bool nl = true;
            if ((*tabBarMap)["NL"] == "FALSE") {
                nl = false;
            }

            //moveDockWindow( windowsTabBar, Qt::Dock((*tabBarMap)["DOCK"].toInt()), nl, (*tabBarMap)["INDEX"].toInt(), (*tabBarMap)["EXTRAOFFSET"].toInt() );

            /* if ( (w != 0) && (h != 0) )
            {
                    windowsTabBar->setFixedExtentWidth(w);
                    windowsTabBar->setFixedExtentHeight(h);
            } */
        }
    }

    restoreState(DCConfig::Instance()->GetQMainWindowState());

    DCTranslator::SetInstance(new DCTranslator(this));

    // install event filter on qApp ;-)
    if (DCConfig::Instance()->GetAutoAwayMode()) {
        qApp->installEventFilter(&m_ApplicationEvents);
    }

    // init timer
    m_pTimer = new QTimer();

    connect(m_pTimer, SIGNAL(timeout()), this, SLOT(slotTimeout()));

    // start timer
    m_pTimer->start(1000);

    SetMdiAreaInstance(s_pMdiArea);

    ready2Unload = false;

    qc = NULL;

    slotFileInotifyEnable();

    if (DCConfig::Instance()->GetAntiSpamEnabled()) {
        DCAntiSpam::SetInstance(new DCAntiSpam());

        DCAntiSpam::Instance()->loadSettings();
        DCAntiSpam::Instance()->loadLists();
    }

    if (DCConfig::Instance()->GetIPFilterEnabled()) {
        DCIPFilter::SetInstance(new DCIPFilter());

        DCIPFilter::Instance()->loadList();
    }

    installEventFilter(this);

    QPalette pal = palette();

    QColor bg = pal.background().color();
    QColor fg = pal.base().color();

    slotLoadCSS();

    // Load quick connect history
    DCConfig::Instance()->LoadQuickConnectHistory();
}

/** */
DCGuiApp::~DCGuiApp() {
    deinitActions();
    // remove event-filter from appl.
    if (DCConfig::Instance()->GetAutoAwayMode()) {
        qApp->removeEventFilter(&m_ApplicationEvents);
    }

    // stop timer
    m_pTimer->stop();
    delete m_pTimer;
    deinitTray();

    deinitView();

    delete DCTranslator::Instance();

    if (DCAntiSpam::Instance()) {

        DCAntiSpam::Instance()->saveLists();
        DCAntiSpam::Instance()->saveSettings();

        delete DCAntiSpam::Instance();
        DCAntiSpam::SetInstance(NULL);
    }

    if (DCIPFilter::Instance()) {
        DCIPFilter::Instance()->saveList();

        delete DCIPFilter::Instance();

        DCIPFilter::SetInstance(NULL);
    }

    /*if (DCInotifyControl::Instance()){
	DCInotifyControl::Instance()->Shutdown();
	delete DCInotifyControl::Instance();

	DCInotifyControl::SetInstance(NULL);
    }*/

    // Save quick connect history
    DCConfig::Instance()->SaveQuickConnectHistory();
}

/** */
void DCGuiApp::initActions() {
    actionClearChat = new QAction(this);
    actionClearChat->setObjectName("action_clear_chat");
    actionClearChat->setText(tr("Clear Current chat"));
    actionClearChat->setStatusTip(tr("Clear Current chat"));
    actionClearChat->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiCLEAR)));
    actionClearChat->setShortcut(tr("Ctrl+R"));
    connect(actionClearChat, SIGNAL(triggered()), this, SLOT(slotClearCurrentChat()));

    QIcon optionsIcon(DCIconLoader::Instance()->GetPixmap(eiCONFIGURE_32x32));
    optionsIcon.addPixmap(DCIconLoader::Instance()->GetPixmap(eiCONFIGURE));
    fileOptions = new QAction(this);
    fileOptions->setObjectName("action_file_options");
    fileOptions->setText(tr("&Options"));
    fileOptions->setIcon(optionsIcon);
    fileOptions->setShortcut(tr("Ctrl+O"));
    fileOptions->setStatusTip(tr("Open options dialog"));
    fileOptions->setWhatsThis(tr("Open options dialog\n\nOpens a dialog where settings can be changed."));
    connect(fileOptions, SIGNAL(triggered()), this, SLOT(slotFileOptions()));

    fileQuickConnect = new QAction(this);
    fileQuickConnect->setObjectName("action_file_quick_connect");
    fileQuickConnect->setText(tr("&Quick connect"));
    fileQuickConnect->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiCONNECT)));
    fileQuickConnect->setStatusTip(tr("Open quick-connect dialog"));
    fileQuickConnect->setShortcut(tr("Ctrl+H"));
    connect(fileQuickConnect, SIGNAL(triggered()), this, SLOT(slotFileQuickConnect()));

    fileHubReconnect = new QAction(this);
    fileHubReconnect->setObjectName("action_file_hub_reconnect");
    fileHubReconnect->setText(tr("Reconnect to hub"));
    fileHubReconnect->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiRECONNECT)));
    fileHubReconnect->setStatusTip(tr("Reconnect to the disconnected hub"));
    connect(fileHubReconnect, SIGNAL(triggered()), this, SLOT(slotHubReconnect()));

#ifndef WIN32
    fileInotifyEnable = new QAction(this);
    fileInotifyEnable->setText(tr("Inotify enabled"));
    fileInotifyEnable->setStatusTip(tr("Enables INotify support"));
    fileInotifyEnable->setCheckable(true);
    fileInotifyEnable->setChecked(DCConfig::Instance()->GetInotifyEnabled());
    connect(fileInotifyEnable, SIGNAL(triggered()), this, SLOT(slotFileInotifyEnable()));

    fileInotify = new QAction(this);
    fileInotify->setText(tr("&Inotify control"));
    fileInotify->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiINOTIFY)));
    fileInotify->setEnabled(DCConfig::Instance()->GetInotifyEnabled());
    connect(fileInotify, SIGNAL(triggered()), this, SLOT(slotInotify()));

    slotFileInotifyEnable();
#endif

    fileFileListBrowser = new QAction(this);
    fileFileListBrowser->setText(tr("Filelist browser"));
    fileFileListBrowser->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiVIEW_SIDETREE)));
    fileFileListBrowser->setStatusTip(tr("Open filelist browser"));
    fileFileListBrowser->setWhatsThis(tr("Open filelist browser\n\nOpen an empty filelist browser that you can use to open filelists from disk."));
    connect(fileFileListBrowser, SIGNAL(triggered()), this, SLOT(slotFileFileListBrowser()));

    fileFileListBrowserLocal = new QAction(this);
    fileFileListBrowserLocal->setText(tr("Filelist browser local"));
    fileFileListBrowserLocal->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiVIEW_SIDETREE)));
    fileFileListBrowserLocal->setStatusTip(tr("Open local filelist browser"));
    fileFileListBrowserLocal->setWhatsThis(tr("Open local filelist browser\n\nView the files in your own share."));
    connect(fileFileListBrowserLocal, SIGNAL(triggered()), this, SLOT(slotFileFileListBrowserLocal()));

    fileMenuBar = new QAction(this);
    fileMenuBar->setObjectName("action_file_menu_bar");
    fileMenuBar->setText(tr("Main menu"));
    fileMenuBar->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiICON_APPL)));
    connect(fileMenuBar, SIGNAL(triggered()), this, SLOT(slotFileMenuBar()));

    QIcon refreshIcon(DCIconLoader::Instance()->GetPixmap(eiRELOAD_32x32));
    refreshIcon.addPixmap(DCIconLoader::Instance()->GetPixmap(eiRELOAD));
    fileFileListRefresh = new QAction(this);
    fileFileListRefresh->setObjectName("action_file_filelist_refresh");
    fileFileListRefresh->setText(tr("Refresh share"));
    fileFileListRefresh->setIcon(refreshIcon);
    fileFileListRefresh->setStatusTip(tr("Refresh share"));
    fileFileListRefresh->setWhatsThis(tr("Refresh share\n\nUpdate your share to match file changes on disk."));
    connect(fileFileListRefresh, SIGNAL(triggered()), this, SLOT(slotFileCreateShare()));

    fileOpenDownloadDir = new QAction(this);
    fileOpenDownloadDir->setText(tr("Open download directory"));
    fileOpenDownloadDir->setStatusTip(tr("Open download directory in standard system filemanager"));
    fileOpenDownloadDir->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiFOLDER_BLUE_OPEN)));
    connect(fileOpenDownloadDir, SIGNAL(triggered()), this, SLOT(slotOpenDownloadDir()));

    fileQuickOptions = new QAction(this);
    fileQuickOptions->setText(tr("Quick options"));
    fileQuickOptions->setShortcut(tr("F12"));
    fileQuickOptions->setStatusTip(tr("Select default download mode"));
    connect(fileQuickOptions, SIGNAL(triggered()), this, SLOT(slotFileQuickOptions()));

    /** Default download mode */
    fileDefaultDldAsk = new QAction(this);
    fileDefaultDldAsk->setText(tr("Download mode: Ask"));
    fileDefaultDldAsk->setStatusTip(tr("Set default download mode to: Ask"));
    fileDefaultDldAsk->setWhatsThis(tr("Download mode: Ask\n\nPrompt for single or multi source mode when starting a download."));
    fileDefaultDldAsk->setCheckable(true);
    fileDefaultDldSingle = new QAction(this);
    fileDefaultDldSingle->setText(tr("Download mode: Single"));
    fileDefaultDldSingle->setStatusTip(tr("Set default download mode to: Single"));
    fileDefaultDldSingle->setWhatsThis(tr("Download mode: Single\n\nEach file will be downloaded from a single user without using chunked downloading."));
    fileDefaultDldSingle->setCheckable(true);
    fileDefaultDldMulti = new QAction(this);
    fileDefaultDldMulti->setText(tr("Download mode: Multi"));
    fileDefaultDldMulti->setStatusTip(tr("Set default download mode to: Multi"));
    fileDefaultDldMulti->setWhatsThis(tr("Download mode: Multi\n\nEach file will be downloaded in multiple chunks possibly from different users."));
    fileDefaultDldMulti->setCheckable(true);
    fileDefaultDldGroup = new QActionGroup(this);
    connect(fileDefaultDldGroup, SIGNAL(selected(QAction*)), this, SLOT(slotChangeDefaultDldMode(QAction*)));
    fileDefaultDldGroup->addAction(fileDefaultDldAsk);
    fileDefaultDldGroup->addAction(fileDefaultDldSingle);
    fileDefaultDldGroup->addAction(fileDefaultDldMulti);

    slotDefaultDownloadModeChanged();

    fileReloadPlugins = new QAction(this);
    fileReloadPlugins->setText(tr("&Reload Plugins"));
    fileReloadPlugins->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiRELOAD_PLUGINS)));
    fileReloadPlugins->setStatusTip(tr("Reload Plugins"));
    fileReloadPlugins->setWhatsThis(tr("Reload Plugins\n\nScan for new and reload any add-on software."));
    connect(fileReloadPlugins, SIGNAL(triggered()), this, SLOT(slotFileReloadPlugins()));

    fileQuit = new QAction(this);
    fileQuit->setObjectName("action_file_quit");
    fileQuit->setText(tr("Exit"));
    fileQuit->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiEXIT)));
    fileQuit->setShortcut(tr("Ctrl+Q"));
    fileQuit->setStatusTip(tr("Quits the application"));
    fileQuit->setWhatsThis(tr("Exit\n\nQuits the application."));
    connect(fileQuit, SIGNAL(triggered()), this, SLOT(slotFileQuit()));

    chatZoomIn = new QAction(this);
    chatZoomIn->setObjectName("action_chat_zoomin");
    chatZoomIn->setText(tr("Zoom In Chat"));
    chatZoomIn->setStatusTip(tr("Zoom In Chat"));
    chatZoomIn->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiZOOM_IN)));
    connect(chatZoomIn, SIGNAL(triggered()), this, SLOT(slotChatZoomIn()));

    chatZoomOut = new QAction(this);
    chatZoomOut->setObjectName("action_chat_zoomout");
    chatZoomOut->setText(tr("Zoom Out Chat"));
    chatZoomOut->setStatusTip(tr("Zoom Out Chat"));
    chatZoomOut->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiZOOM_OUT)));
    connect(chatZoomOut, SIGNAL(triggered()), this, SLOT(slotChatZoomOut()));

    chatOff = new QAction(this);
    chatOff->setObjectName("action_chat_off");
    chatOff->setText(tr("Disable chat"));
    chatOff->setStatusTip(tr("Disable current chat"));
    chatOff->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_CL_LISTS)));
    chatOff->setCheckable(true);
    connect(chatOff, SIGNAL(triggered()), this, SLOT(slotChatOff()));

    viewTabBar = new QAction(this);
    viewTabBar->setText(tr("Tabbar"));
    viewTabBar->setCheckable(true);
    viewTabBar->setStatusTip(tr("Enables/disables the tabbar"));
    viewTabBar->setWhatsThis(tr("Tabbar\n\nEnables/disables the tabbar. The tabbar shows a tab for each hub window."));
    connect(viewTabBar, SIGNAL(toggled(bool)), this, SLOT(slotViewTabBar(bool)));

    viewToolBar = new QAction(this);
    viewToolBar->setText(tr("Tool&bar"));
    viewToolBar->setCheckable(true);
    viewToolBar->setStatusTip(tr("Enables/disables the toolbar"));
    viewToolBar->setWhatsThis(tr("Toolbar\n\nEnables/disables the toolbar."));
    connect(viewToolBar, SIGNAL(toggled(bool)), this, SLOT(slotViewToolBar(bool)));

    viewStatusBar = new QAction(this);
    viewStatusBar->setText(tr("&Statusbar"));
    viewStatusBar->setCheckable(true);
    viewStatusBar->setStatusTip(tr("Enables/disables the statusbar"));
    viewStatusBar->setWhatsThis(tr("Statusbar\n\nEnables/disables the statusbar."));
    connect(viewStatusBar, SIGNAL(toggled(bool)), this, SLOT(slotViewStatusBar(bool)));

    viewTrayIcon = new QAction(this);
    viewTrayIcon->setText(tr("System Tray Icon"));
    viewTrayIcon->setCheckable(true);
    viewTrayIcon->setStatusTip(tr("Enables/disables the system tray icon"));
    viewTrayIcon->setWhatsThis(tr("System Tray Icon\n\nAdds or removes an icon in the system tray area."));
    viewTrayIcon->setChecked(DCConfig::Instance()->GetEnableTray());
    connect(viewTrayIcon, SIGNAL(toggled(bool)), this, SLOT(slotViewTrayIcon(bool)));

    viewDock = new QAction(this);
    viewDock->setText(tr("&Dock"));
    viewDock->setStatusTip(tr("Dock the application"));
    viewDock->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_ICON)));
    viewDock->setWhatsThis(tr("Dock\n\nDock the application. Only the system tray icon will be visible."));
    viewDock->setEnabled(DCConfig::Instance()->GetEnableTray());
    connect(viewDock, SIGNAL(triggered()), this, SLOT(slotViewDock()));

    viewReloadCSS = new QAction(this);
    viewReloadCSS->setText(tr("Reload CSS-Style"));
    viewReloadCSS->setStatusTip(tr("Load css-style from ~/.eiskaldc/style.css file"));
    viewReloadCSS->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiRELOAD_PLUGINS)));
    connect(viewReloadCSS, SIGNAL(triggered()), this, SLOT(slotLoadCSS()));

    viewToolBarIconOnly = new QAction(this);
    viewToolBarIconOnly->setText(tr("Icon only"));
    viewToolBarIconOnly->setStatusTip(tr("Only display the icon"));
    viewToolBarIconOnly->setCheckable(true);

    viewToolBarTextOnly = new QAction(this);
    viewToolBarTextOnly->setText(tr("Text only"));
    viewToolBarTextOnly->setStatusTip(tr("Only display the text"));
    viewToolBarTextOnly->setCheckable(true);

    viewToolBarTextBIcon = new QAction(this);
    viewToolBarTextBIcon->setText(tr("Text beside the icon"));
    viewToolBarTextBIcon->setStatusTip(tr("The text appears beside the icon"));
    viewToolBarTextBIcon->setCheckable(true);

    viewToolBarTextUIcon = new QAction(this);
    viewToolBarTextUIcon->setText(tr("Text under the icon"));
    viewToolBarTextUIcon->setStatusTip(tr("The text appears under the icon"));
    viewToolBarTextUIcon->setCheckable(true);

    viewMenuBarCompact = new QAction(this);
    viewMenuBarCompact->setText(tr("Compact view"));
    viewMenuBarCompact->setStatusTip(tr("Hide Menubar and add new action to the toolbar"));
    viewMenuBarCompact->setCheckable(true);

    viewMenuBarNormal = new QAction(this);
    viewMenuBarNormal->setText(tr("Normal view"));
    viewMenuBarNormal->setStatusTip(tr("Restores Menubar at the top of main window"));
    viewMenuBarNormal->setCheckable(true);

    viewToolBarGrp = new QActionGroup(this);
    viewToolBarGrp->addAction(viewToolBarIconOnly);
    viewToolBarGrp->addAction(viewToolBarTextOnly);
    viewToolBarGrp->addAction(viewToolBarTextBIcon);
    viewToolBarGrp->addAction(viewToolBarTextUIcon);
    connect(viewToolBarGrp, SIGNAL(selected(QAction*)), this, SLOT(slotToolBarBtnStyle(QAction*)));

    viewMenuBar = new QActionGroup(this);
    viewMenuBar->addAction(viewMenuBarNormal);
    viewMenuBar->addAction(viewMenuBarCompact);
    connect(viewMenuBar, SIGNAL(selected(QAction*)), this, SLOT(slotMenuBarView(QAction*)));

    QAction *t = NULL;

    switch (DCConfig::Instance()->GetToolBarButtonStyle()){
        case Qt::ToolButtonIconOnly:
            t = viewToolBarIconOnly;
            break;
        case Qt::ToolButtonTextOnly:
            t = viewToolBarTextOnly;
            break;
        case Qt::ToolButtonTextBesideIcon:
            t = viewToolBarTextBIcon;
            break;
        case Qt::ToolButtonTextUnderIcon:
            t = viewToolBarTextUIcon;
            break;
    }

    if (t)
        t->setChecked(true);

    t = viewMenuBarNormal;

    if (DCConfig::Instance()->GetHideMenuBar())
        t = viewMenuBarCompact;

    t->setChecked(true);

    actionTransferViewType = new QAction(this);
    actionTransferViewType->setText(tr("Transfer View type"));
    actionTransferViewType->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiTRANSFER)));
    actionTransferViewType->setStatusTip(tr("Change transfer view type"));
    connect(actionTransferViewType, SIGNAL(triggered()), this, SLOT(slotActionTransferViewType()));

    windowCascade = new QAction(this);
    windowCascade->setText(tr("&Cascade"));
    windowCascade->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_TILED)));
    windowCascade->setStatusTip(tr("Cascades all windows"));
    windowCascade->setWhatsThis(tr("Cascade\n\nCascades all windows."));
    connect(windowCascade, SIGNAL(triggered()), pMdiArea, SLOT(cascadeSubWindows()));

    windowTile = new QAction(this);
    windowTile->setText(tr("&Tile Vertically"));
    windowTile->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_VERT)));
    windowTile->setStatusTip(tr("Tiles all windows vertically"));
    windowTile->setWhatsThis(tr("Tile Vertically\n\nTiles all windows vertically."));
    connect(windowTile, SIGNAL(triggered()), this, SLOT(tileVertically()));

    windowTileHor = new QAction(this);
    windowTileHor->setText(tr("Tile &Horizontally"));
    windowTileHor->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_HORIZ)));
    windowTileHor->setStatusTip(tr("Tiles all windows horizontally."));
    windowTileHor->setWhatsThis(tr("Tile Horizontally\n\nTiles all windows horizontally."));
    connect(windowTileHor, SIGNAL(triggered()), pMdiArea, SLOT(tileSubWindows()));

    windowMinimize = new QAction(this);
    windowMinimize->setText(tr("&Minimize"));
    windowMinimize->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_ICON)));
    windowMinimize->setStatusTip(tr("Minimize all windows."));
    windowMinimize->setWhatsThis(tr("Minimize\n\nMinimize all windows."));
    connect(windowMinimize, SIGNAL(triggered()), this, SLOT(slotWindowMinimize()));

    windowCloseHubs = new QAction(this);
    windowCloseHubs->setText(tr("Close disconnected hubs"));
    windowCloseHubs->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_CL_HUBS)));
    windowCloseHubs->setStatusTip(tr("Close all disconnected hub windows."));
    windowCloseHubs->setWhatsThis(tr("Close disconnected hubs\n\nClose all disconnected hub windows."));
    connect(windowCloseHubs, SIGNAL(triggered()), this, SLOT(slotWindowCloseHubs()));

    windowCloseAllChats = new QAction(this);
    windowCloseAllChats->setText(tr("Close all chat windows"));
    windowCloseAllChats->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_CL_ALL)));
    windowCloseAllChats->setStatusTip(tr("Close all chat windows."));
    windowCloseAllChats->setWhatsThis(tr("Close all chat windows\n\nClose all chat windows."));
    connect(windowCloseAllChats, SIGNAL(triggered()), this, SLOT(slotWindowCloseAllChats()));

    windowCloseOfflineChats = new QAction(this);
    windowCloseOfflineChats->setText(tr("Close all offline chat windows"));
    windowCloseOfflineChats->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_CL_OFFLINE)));
    windowCloseOfflineChats->setStatusTip(tr("Close all offline chat windows."));
    windowCloseOfflineChats->setWhatsThis(tr("Close all offline chat windows\n\nClose all chat windows where the user is no longer on the hub."));
    connect(windowCloseOfflineChats, SIGNAL(triggered()), this, SLOT(slotWindowCloseOfflineChats()));

    windowCloseFilelists = new QAction(this);
    windowCloseFilelists->setText(tr("Close all filelist windows"));
    windowCloseFilelists->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_CL_LISTS)));
    windowCloseFilelists->setStatusTip(tr("Close all filelist windows."));
    windowCloseFilelists->setWhatsThis(tr("Close all filelist windows\n\nClose all filelist browsers."));
    connect(windowCloseFilelists, SIGNAL(triggered()), this, SLOT(slotWindowCloseFilelists()));

    windowCloseSearches = new QAction(this);
    windowCloseSearches->setText(tr("Close all search windows"));
    windowCloseSearches->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiWINDOWS_CL_FIND)));
    windowCloseSearches->setStatusTip(tr("Close all search windows."));
    windowCloseSearches->setWhatsThis(tr("Close all search windows\n\nClose all search windows."));
    connect(windowCloseSearches, SIGNAL(triggered()), this, SLOT(slotWindowCloseSearches()));

    windowAction = new QActionGroup(this);
    windowAction->addAction(windowCascade);
    windowAction->addAction(windowTile);
    windowAction->addAction(windowTileHor);
    windowAction->addAction(windowMinimize);
    windowAction->addAction(windowCloseHubs);
    windowAction->addAction(windowCloseAllChats);
    windowAction->addAction(windowCloseOfflineChats);
    windowAction->addAction(windowCloseFilelists);
    windowAction->addAction(windowCloseSearches);
    windowsGroup = new QActionGroup(this);
    connect(windowsGroup, SIGNAL(triggered(QAction*)), this, SLOT(windowMenuActivated(QAction*)));

    /** server list */
    actionServerList = new QAction(this);
    actionServerList->setObjectName("action_server_list");
    actionServerList->setText(tr("H&ub List"));
    actionServerList->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiSERVER)));
    actionServerList->setShortcut(tr("Ctrl+U"));
    actionServerList->setStatusTip(tr("Show Hub List."));
    actionServerList->setWhatsThis(tr("Hub List\n\nShows the lists of public and bookmarks hubs."));
    connect(actionServerList, SIGNAL(triggered()), this, SLOT(slotActionServerList()));

    /** tranfer list */
    actionTransferList = new QAction(this);
    actionTransferList->setObjectName("action_transfer_list");
    actionTransferList->setText(tr("&Transfer List"));
    actionTransferList->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiTRANSFER)));
    actionTransferList->setShortcut(tr("Ctrl+T"));
    actionTransferList->setStatusTip(tr("Show Transfer List."));
    actionTransferList->setWhatsThis(tr("Transfer List\n\nShows running transfers, users you are waiting to download from, files you have queued to download, slots granted, and log of transfers."));
    connect(actionTransferList, SIGNAL(triggered()), this, SLOT(slotActionTransferList()));

    /** hub search */
    QIcon searchIcon(DCIconLoader::Instance()->GetPixmap(eiFIND_32x32));
    searchIcon.addPixmap(DCIconLoader::Instance()->GetPixmap(eiFIND));
    actionHubSearch = new QAction(this);
    actionHubSearch->setObjectName("action_hub_search");
    actionHubSearch->setText(tr("Hub &Search"));
    actionHubSearch->setIcon(searchIcon);
    actionHubSearch->setShortcut(tr("Ctrl+S"));
    actionHubSearch->setStatusTip(tr("Open Hub Search."));
    actionHubSearch->setWhatsThis(tr("Hub Search\n\nOpens a search window where you can search for files."));
    connect(actionHubSearch, SIGNAL(triggered()), this, SLOT(slotActionHubSearch()));

    /** spy */
    actionSpy = new QAction(this);
    actionSpy->setObjectName("action_spy");
    actionSpy->setText(tr("S&py"));
    actionSpy->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiSPY)));
    actionSpy->setShortcut(tr("Ctrl+P"));
    actionSpy->setStatusTip(tr("Show Search Spy."));
    actionSpy->setWhatsThis(tr("Spy\n\nThe search spy shows incoming searches and search statistics."));
    connect(actionSpy, SIGNAL(triggered()), this, SLOT(slotActionSpy()));

    /** users */
    QIcon usersIcon(DCIconLoader::Instance()->GetPixmap(eiUSERS_32x32));
    usersIcon.addPixmap(DCIconLoader::Instance()->GetPixmap(eiUSERS));
    actionUsers = new QAction(this);
    actionUsers->setObjectName("action_users");
    actionUsers->setText(tr("Users"));
    actionUsers->setIcon(usersIcon);
    actionUsers->setShortcut(tr("Ctrl+F"));
    actionUsers->setStatusTip(tr("Show Users List."));
    actionUsers->setWhatsThis(tr("Users\n\nList of favorite users, showing if they are online."));
    connect(actionUsers, SIGNAL(triggered()), this, SLOT(slotActionUsers()));

    /** actiongroup for away mode */
    actionGroupAwayMode = new QActionGroup(this);
    actionGroupAwayMode->setExclusive(true);

    /** away mode normal */
    actionAwayModeNormal = new QAction(this);
    actionAwayModeNormal->setText(tr("&Normal"));
    actionAwayModeNormal->setCheckable(true);
    actionAwayModeNormal->setActionGroup(actionGroupAwayMode);
    actionAwayModeNormal->setShortcut(tr("Ctrl+N"));
    actionAwayModeNormal->setStatusTip(tr("Set away mode to normal"));
    actionAwayModeNormal->setWhatsThis(tr("Away mode: normal\n\nNormal mode, away message will not be sent automatically."));
    actionAwayModeNormal->setChecked(true);

    /** away mode away */
    actionAwayModeAway = new QAction(this);
    actionAwayModeAway->setText(tr("&Away"));
    actionAwayModeAway->setActionGroup(actionGroupAwayMode);
    actionAwayModeAway->setShortcut(tr("Ctrl+A"));
    actionAwayModeAway->setStatusTip(tr("Set away mode to away."));
    actionAwayModeAway->setWhatsThis(tr("Away mode: normal\n\nYou will be marked as away and your away message will be sent in response to a new private message."));
    actionAwayModeAway->setCheckable(true);

    connect(actionGroupAwayMode, SIGNAL(selected(QAction*)), this, SLOT(slotChangeAwayMode()));

    actionAntiSpam = new QAction(this);
    actionAntiSpam->setObjectName("action_antispam");
    actionAntiSpam->setText(tr("AntiSpam Control"));
    actionAntiSpam->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiSPAM)));
    actionAntiSpam->setStatusTip(tr("Show AntiSpam control dialog"));
    connect(actionAntiSpam, SIGNAL(triggered()), this, SLOT(slotActionAntiSpam()));

    actionIPFilter = new QAction(this);
    actionIPFilter->setObjectName("action_ipfilter");
    actionIPFilter->setText(tr("IPFilter Control"));
    actionIPFilter->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiFILTER)));
    actionIPFilter->setStatusTip(tr("Show IPFilter control dialog"));
    connect(actionIPFilter, SIGNAL(triggered()), this, SLOT(slotActionIPFilter()));

    helpAboutApp = new QAction(this);
    helpAboutApp->setText(tr("&About..."));
    helpAboutApp->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiICON_APPL)));
    helpAboutApp->setStatusTip(tr("About the application."));
    helpAboutApp->setWhatsThis(tr("About\n\nAbout the application. Displays version, copyright and licensing information."));
    connect(helpAboutApp, SIGNAL(triggered()), this, SLOT(slotHelpAbout()));

    helpManualApp = new QAction(this);
    helpManualApp->setText(tr("&Manual..."));
    helpManualApp->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiONLINEMANUAL)));
    helpManualApp->setStatusTip(tr("Online User Manual."));
    helpManualApp->setWhatsThis(tr("Manual\n\nOnline User Manual. Launches the configured web browser."));
    connect(helpManualApp, SIGNAL(triggered()), this, SLOT(slotHelpManual()));

    helpSupportApp = new QAction(this);
    helpSupportApp->setText(tr("&Support..."));
    helpSupportApp->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiSUPPORT)));
    helpSupportApp->setStatusTip(tr("Connect to Valknut hub"));
    helpSupportApp->setWhatsThis(tr("Support\n\nConnect to the Valknut hub."));
    connect(helpSupportApp, SIGNAL(triggered()), this, SLOT(slotHelpSupport()));

    debugSettings = new QAction(this);
    debugSettings->setText(tr("Debug Settings..."));
    debugSettings->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiDEBUG)));
    debugSettings->setStatusTip(tr("Settings for debugging"));
    debugSettings->setWhatsThis(tr("Debug Settings\n\nChange settings useful for debugging."));
    connect(debugSettings, SIGNAL(triggered()), this, SLOT(slotDebugSettings()));
}

/** */
void DCGuiApp::deinitActions() {
    delete fileOptions;
    delete fileFileListBrowser;
    delete fileFileListBrowserLocal;
    delete fileFileListRefresh;
    delete fileQuickOptions;
    delete fileHubReconnect;
    delete fileDefaultDldAsk;
    delete fileDefaultDldSingle;
    delete fileDefaultDldMulti;
    delete fileDefaultDldGroup;
    delete fileReloadPlugins;
    delete fileQuit;
    delete fileInotify;
    delete fileInotifyEnable;
    delete fileOpenDownloadDir;
    delete actionClearChat;
    delete viewToolBarIconOnly;
    delete viewToolBarTextOnly;
    delete viewToolBarTextBIcon;
    delete viewToolBarTextUIcon;
    delete viewTabBar;
    delete viewToolBar;
    delete viewStatusBar;
    delete viewTrayIcon;
    delete viewDock;
    delete viewReloadCSS;
    delete viewMenuBarCompact;
    delete viewMenuBarNormal;
    delete viewMenuBar;

    delete windowCascade;
    delete windowTile;
    delete windowTileHor;
    delete windowMinimize;
    delete windowCloseHubs;
    delete windowCloseAllChats;
    delete windowCloseOfflineChats;
    delete windowCloseFilelists;
    delete windowCloseSearches;
    delete windowAction;
    delete windowsGroup;

    delete actionServerList;
    delete actionTransferList;
    delete actionHubSearch;
    delete actionSpy;
    delete actionUsers;
    delete actionAwayModeNormal;
    delete actionAwayModeAway;
    delete actionGroupAwayMode;

    delete helpAboutApp;
    delete helpManualApp;
    delete helpSupportApp;

    delete debugSettings;
}

/** */
void DCGuiApp::initMenuBar() {
    ///////////////////////////////////////////////////////////////////
    // MENUBAR

    ///////////////////////////////////////////////////////////////////
    // menuBar entry pFileMenu
    pFileMenu = new QMenu(this);
    pFileMenu->setTitle(tr("&File"));
    pFileMenu->addAction(fileOptions);
    pQuickOptionsMenu = new QMenu(this);
    pQuickOptionsMenu->addActions(fileDefaultDldGroup->actions());
    pQuickOptionsMenu->setTitle(tr("Quick Options"));
    pQuickOptionsMenu->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiQUICKOPTIONS)));
#ifndef WIN32
    pInotify = new QMenu(this);
    pInotify->setTitle(tr("INotify"));
    pInotify->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiINOTIFY)));
    pInotify->addAction(fileInotifyEnable);
    pInotify->addSeparator();
    pInotify->addAction(fileInotify);
    pQuickOptionsMenu->addMenu(pInotify);
#endif
    pFileMenu->addMenu(pQuickOptionsMenu);
    pFileMenu->addSeparator();
    pFileMenu->addAction(fileFileListBrowser);
    pFileMenu->addAction(fileFileListBrowserLocal);
#ifndef WIN32
    pFileMenu->addAction(fileInotify);
#endif
    pFileMenu->addSeparator();
    pFileMenu->addAction(fileQuickConnect);
    pFileMenu->addAction(fileHubReconnect);
    pFileMenu->addSeparator();
    pFileMenu->addAction(fileFileListRefresh);
    pFileMenu->addSeparator();
    pFileMenu->addAction(fileReloadPlugins);
    pFileMenu->addSeparator();
    pFileMenu->addAction(actionClearChat);
    pFileMenu->addSeparator();
    pFileMenu->addAction(fileOpenDownloadDir);
    pFileMenu->addSeparator();
    pFileMenu->addAction(fileQuit);

    ///////////////////////////////////////////////////////////////////
    // menuBar entry viewMenu
    /*pMenuBarHide = new QMenu(this);
    pMenuBarHide->setTitle(tr("MenuBar"));
    pMenuBarHide->addActions(viewMenuBar->actions());*/

    pToolBarMenu = new QMenu(this);
    pToolBarMenu->setTitle(tr("Toolbar button style"));
    pToolBarMenu->addActions(viewToolBarGrp->actions());

    pViewMenu = new QMenu(this);

    pViewMenu->setTitle(tr("&View"));
    pViewMenu->addAction(viewTabBar);
    pViewMenu->addAction(viewToolBar);
    pViewMenu->addAction(viewStatusBar);
    pViewMenu->addAction(viewTrayIcon);
    pViewMenu->addAction(viewDock);
    pViewMenu->addSeparator();
    pViewMenu->addAction(actionTransferViewType);
    pViewMenu->addMenu(pToolBarMenu);
    //pViewMenu->addMenu(pMenuBarHide);
    pViewMenu->addSeparator();
    pViewMenu->addAction(viewReloadCSS);

    ///////////////////////////////////////////////////////////////////
    // menuBar awayMenu
    pAwayMenu = new QMenu(this);
    pAwayMenu->setTitle(tr("Away &Mode"));
    pAwayMenu->setIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiISAWAY)));
    pAwayMenu->addAction(actionAwayModeNormal);
    pAwayMenu->addAction(actionAwayModeAway);

    ///////////////////////////////////////////////////////////////////
    // menuBar actionMenu
    pActionMenu = new QMenu(this);
    pActionMenu->setTitle(tr("&Action"));
    pActionMenu->addAction(actionServerList);
    pActionMenu->addAction(actionTransferList);
    pActionMenu->addAction(actionHubSearch);
    pActionMenu->addAction(actionSpy);
    pActionMenu->addAction(actionUsers);
    pActionMenu->addSeparator();
    pActionMenu->addMenu(pAwayMenu);
    pActionMenu->addSeparator();
    pActionMenu->addAction(actionAntiSpam);
    pActionMenu->addAction(actionIPFilter);

    ///////////////////////////////////////////////////////////////////
    // menuBar entry windowMenu
    pWindowMenu = new QMenu(this);
    pWindowMenu->setTitle(tr("&Window"));
    connect(pWindowMenu, SIGNAL(aboutToShow()), this, SLOT(windowMenuAboutToShow()));

    ///////////////////////////////////////////////////////////////////
    // menuBar entry helpMenu
    pHelpMenu = new QMenu(this);
    pHelpMenu->setTitle(tr("&Help"));
    pHelpMenu->addAction(helpAboutApp);
    pHelpMenu->addSeparator();
    pHelpMenu->addAction(helpManualApp);
    pHelpMenu->addSeparator();
    pHelpMenu->addAction(helpSupportApp);
    pHelpMenu->addSeparator();
    pHelpMenu->addAction(debugSettings);
    pHelpMenu->addSeparator();
    pHelpMenu->addAction(QWhatsThis::createAction(pHelpMenu));

    menubar_menus.append(menuBar()->addMenu(pFileMenu));
    menubar_menus.append(menuBar()->addMenu(pViewMenu));
    menubar_menus.append(menuBar()->addMenu(pActionMenu));
    menubar_menus.append(menuBar()->addMenu(pWindowMenu));
    menubar_menus.append(menuBar()->addMenu(pHelpMenu));

    if (DCConfig::Instance()->GetHideMenuBar())
        menuBar()->hide();
}

/** */
void DCGuiApp::initToolBar() {
    ///////////////////////////////////////////////////////////////////
    // TOOLBAR
    fileToolbar = new QToolBar(this);
    fileToolbar->setObjectName("FileToolBar");
    fileToolbar->setWindowTitle(tr("Toolbar"));

    QAction *sep;

    //fileToolbar->addAction(fileMenuBar);
    //toolbar_actions.push_back(fileMenuBar);
    //sep = fileToolbar->addSeparator();
    //sep->setObjectName("action_file_menubar_separator");
    //toolbar_actions.push_back(sep);
    fileToolbar->addAction(fileQuickConnect);
    fileToolbar->addAction(fileHubReconnect);
    //toolbar_actions.push_back(fileQuickConnect);
    //toolbar_actions.push_back(fileHubReconnect);
    sep = fileToolbar->addSeparator();
    sep->setObjectName("action_separator_0");
    //toolbar_actions.push_back(sep);
    fileToolbar->addAction(fileFileListRefresh);
    fileToolbar->addAction(fileOptions);
    //toolbar_actions.push_back(fileFileListRefresh);
    //toolbar_actions.push_back(fileOptions);
    sep = fileToolbar->addSeparator();
    sep->setObjectName("action_separator_1");
    //toolbar_actions.push_back(sep);
    fileToolbar->addAction(actionServerList); 
    fileToolbar->addAction(actionHubSearch);
    fileToolbar->addAction(actionTransferList);
    fileToolbar->addAction(actionSpy);
    fileToolbar->addAction(actionUsers);
    fileToolbar->addAction(actionAntiSpam);
    fileToolbar->addAction(actionIPFilter);
    //toolbar_actions.push_back(actionServerList);
    //toolbar_actions.push_back(actionHubSearch);
    //toolbar_actions.push_back(actionTransferList);
    //toolbar_actions.push_back(actionSpy);
    //toolbar_actions.push_back(actionUsers);
    //toolbar_actions.push_back(actionAntiSpam);
    //toolbar_actions.push_back(actionIPFilter);
    sep = fileToolbar->addSeparator();
    sep->setObjectName("action_separator_2");
    //toolbar_actions.push_back(sep);
    fileToolbar->addAction(chatZoomOut);
    fileToolbar->addAction(chatZoomIn);
    fileToolbar->addAction(actionClearChat);
    fileToolbar->addAction(chatOff);
    //toolbar_actions.push_back(chatZoomOut);
    //toolbar_actions.push_back(chatZoomIn);
    //toolbar_actions.push_back(actionClearChat);
    //toolbar_actions.push_back(chatOff);
    sep = fileToolbar->addSeparator();
    sep->setObjectName("action_separator_3");
    //toolbar_actions.push_back(sep);
    fileToolbar->addAction(fileQuit);
    //toolbar_actions.push_back(fileQuit);

    // ADD USERS HERE
    fileToolbar->addSeparator()->setObjectName("action_separator_4");
    addToolBar(Qt::TopToolBarArea, fileToolbar);

    windowsTabBar = new QToolBar(this);
    windowsTabBar->setWindowTitle(tr("Tab Bar"));
    windowsTabBar->setObjectName("ClientsTabBar");
    addToolBar(Qt::TopToolBarArea, windowsTabBar);

    // init tabbar
    DCConnectionManager::Instance()->InitTabBar(windowsTabBar);

    fileToolbar->setToolButtonStyle(DCConfig::Instance()->GetToolBarButtonStyle());

    fileToolbar->setContextMenuPolicy(Qt::CustomContextMenu);
    /*connect(fileToolbar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotRightButtonFileToolbar(QPoint)));

    QStringList disabled_actions = DCConfig::Instance()->GetToolBarDisabledButtons();

    if (!disabled_actions.empty()){
        for (int i = 0; i < disabled_actions.size(); i++){
            QAction *act = this->findChild<QAction*>(disabled_actions.at(i));
            if (act)
                fileToolbar->removeAction(act);
        }
    }

    if (!DCConfig::Instance()->GetHideMenuBar() && !DCConfig::Instance()->GetToolBarDisabledButtons().contains(fileMenuBar->objectName())){
        QStringList disabled_actions = DCConfig::Instance()->GetToolBarDisabledButtons();
        disabled_actions << fileMenuBar->objectName() << "action_file_menubar_separator";

        DCConfig::Instance()->SetToolBarDisabledButtons(disabled_actions);
        fileMenuBar->setVisible(false);
        QAction *act = this->findChild<QAction*>("action_file_menubar_separator");

        if (act)
            act->setVisible(false);
    }
    else if (DCConfig::Instance()->GetHideMenuBar())
        slotMenuBarView(viewMenuBarCompact);*/
}

/** */
void DCGuiApp::initStatusBar() {
    ///////////////////////////////////////////////////////////////////
    //STATUSBAR
    statusBar()->showMessage(tr("Ready."));

    statusDMLabel = new QLabel(statusBar());
    statusDMLabel->setObjectName("DownloadManagerStatusLabel");
    statusDMLabel->setFrameShape(QFrame::NoFrame);
    statusDMLabel->setFrameShadow(QFrame::Plain);

    statusDMLabel->setToolTip(tr("SL: Slots:\tUsual slots: used/maximum\n\tExtra slots: used/maximum\n\tAdditional slots: operator/user/special\nUL: Upload speed\nDL: Download speed"));

    statusBar()->addPermanentWidget(statusDMLabel);

    statusTRLabel = new QLabel(statusBar());
    statusTRLabel->setObjectName("TransferStatusLabel");
    statusTRLabel->setFrameShape(QFrame::NoFrame);
    statusTRLabel->setFrameShadow(QFrame::Plain);
    statusBar()->addPermanentWidget(statusTRLabel);
    statusTRLabel->setToolTip(tr("RX/TX Traffic."));

    statusDSLabel = new QLabel(statusBar());
    statusDSLabel->setObjectName("DiscSpaceStatusLabel");
    statusDSLabel->setFrameShape(QFrame::NoFrame);
    statusDSLabel->setFrameShadow(QFrame::Plain);
    statusBar()->addPermanentWidget(statusDSLabel);
    statusDSLabel->setToolTip(tr("Available disc space."));

    m_pProgessBar = new QProgressBar(statusBar());
    m_pProgessBar->setMinimumWidth(180);
    m_pProgessBar->setMaximumWidth(180);
    m_pProgessBar->setMaximumHeight(18);
    m_pProgessBar->setMaximum(100);
    m_pProgessBar->setMinimum(0);
    m_pProgessBar->hide();
    //bar->setFormat("");
    statusBar()->addPermanentWidget(m_pProgessBar);

    statusTRLabel->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(statusTRLabel, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotContextMenuTraffic(const QPoint &)));
}

/** */
void DCGuiApp::initView() {
    pMdiArea = new QMdiArea(this);

    //if QT_VERSION >= 0x040400
    //	pMdiArea->setActivationOrder( QMdiArea::StackingOrder );
    //endif

    /*
     * this is so you can compile with QT 4.3 but if you run with QT 4.4
     * the property still gets set
     */
    if (pMdiArea->property("activationOrder").isValid()) {
        pMdiArea->setProperty("activationOrder", QMdiArea::StackingOrder);
    }

    setCentralWidget(pMdiArea);
    pMdiArea->showMaximized();

    // create connection manager view
    DCConnectionManager::SetInstance(new DCConnectionManager(pMdiArea));
    CConnectionManager::SetInstance(DCConnectionManager::Instance());

    // create hublist manager view
    DCHubListManager::SetInstance(new DCHubListManager(pMdiArea));
    CHubListManager::SetInstance(DCHubListManager::Instance());
    DCHubListManager::Instance()->GetMdiSubWindow()->hide();
    DCHubListManager::Instance()->hide();

    // create dock window for transfer view
    pTransferViewDock = new QDockWidget(pMdiArea);
    pTransferViewDock->setWindowTitle(tr("Transfer view"));
    pTransferViewDock->setObjectName("TransferViewDock");
    pTransferViewDock->setTitleBarWidget(0);
    //pTransferViewDock->setResizeEnabled(true);
    pTransferViewDock->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);

    if (DCConfig::Instance()->GetTransferViewType() == etvtDOCK)
        addDockWidget(Qt::BottomDockWidgetArea, pTransferViewDock);

    pTransferViewDock->hide();
    //connect( pTransferViewDock, SIGNAL(placeChanged( Q3DockWindow::Place )), this, SLOT(slotTransferViewDockPlaceChanged( Q3DockWindow::Place )) );

    // create transfer view
    DCTransferView::SetInstance(new DCTransferView(pTransferViewDock));
    CDownloadManager::SetInstance(DCTransferView::Instance());

    //pTransferViewDock->setWidget(DCTransferView::Instance());

    // create spy view
    DCSpy::SetInstance(new DCSpy(pMdiArea));
    DCSpy::Instance()->GetMdiSubWindow()->hide();
    DCSpy::Instance()->hide();

    // create users view
    DCUsersList::SetInstance(new DCUsersList(pMdiArea));
    DCUsersList::Instance()->GetMdiSubWindow()->hide();
    DCUsersList::Instance()->hide();

    /*	if ( DCConfig::Instance()->GetMode() == ecmACTIVE )
            {
                    CString error;
                    if ( DCTransferView::Instance()->DLM_InitListen(error) == false )
                    {
                            QString s;
                            s = error.Data();

                            if ( s.isEmpty() )
                                    s = tr("(no error message from socket)");
                            else
                                    s = "(" + s + ")";

                            QMessageBox::critical( 0, "Valknut",
                            tr("TCP listen failed, change to passive mode! ") + s );

                            DCConfig::Instance()->SetMode(ecmPASSIVE);
                    }
            }
     */
}

/** */
void DCGuiApp::deinitView() {

    if (DCTransferView::Instance()) {
        delete DCTransferView::Instance();
    }

    if (pTransferViewDock) {
        eTransferViewType type = DCConfig::Instance()->GetTransferViewType();

        switch (type) {
            case etvtDOCK:
                removeDockWidget(pTransferViewDock);

                break;
            case etvtWINDOW:
                break;
        }

        delete pTransferViewDock;

        pTransferViewDock = 0;
    }

    DCConnectionManager::Instance()->CloseAllTabs();

    if (DCHubListManager::Instance()) {
        delete DCHubListManager::Instance();
    }

    if (DCSpy::Instance()) {
        delete DCSpy::Instance();
    }

    if (DCUsersList::Instance()) {
        delete DCUsersList::Instance();
    }

    if (DCConnectionManager::Instance()) {
        delete DCConnectionManager::Instance();
    }

    DCHubSearch::DeInitCompleterDict();
}

/** setup all windows */
void DCGuiApp::initWindows() {
    ////////////////////////////////////////////////////////////////////
    StringMap * map;

    // setup hubview
    DCConfig::Instance()->GetMap("HUBVIEW", map);

    if ((*map)["VISIBLE"].toInt() == 1) {
        const QPoint oldpos = DCHubListManager::Instance()->GetMdiSubWindow()->pos();
        slotActionServerList();
        DCHubListManager::Instance()->GetMdiSubWindow()->move(oldpos);

        if ((*map)["MAXIMIZED"].toInt() == 1) {
            DCHubListManager::Instance()->GetMdiSubWindow()->showMaximized();
            DCHubListManager::Instance()->showMaximized();
        } else if ((*map)["MINIMIZED"].toInt() == 1) {
            DCHubListManager::Instance()->GetMdiSubWindow()->showMinimized();
            DCHubListManager::Instance()->showMinimized();
        } else {
            DCHubListManager::Instance()->GetMdiSubWindow()->show();
            DCHubListManager::Instance()->show();
        }
    }

    // setup spyview
    DCConfig::Instance()->GetMap("SPYVIEW", map);

    if ((*map)["VISIBLE"].toInt() == 1) {
        const QPoint oldpos = DCSpy::Instance()->GetMdiSubWindow()->pos();
        slotActionSpy();
        DCSpy::Instance()->GetMdiSubWindow()->move(oldpos);

        if ((*map)["MAXIMIZED"].toInt() == 1) {
            DCSpy::Instance()->GetMdiSubWindow()->showMaximized();
            DCSpy::Instance()->showMaximized();
        } else if ((*map)["MINIMIZED"].toInt() == 1) {
            DCSpy::Instance()->GetMdiSubWindow()->showMinimized();
            DCSpy::Instance()->showMinimized();
        } else {
            DCSpy::Instance()->GetMdiSubWindow()->show();
            DCSpy::Instance()->show();
        }
    }

    // setup userview
    DCConfig::Instance()->GetMap("USERVIEW", map);

    if ((*map)["VISIBLE"].toInt() == 1) {
        const QPoint oldpos = DCUsersList::Instance()->GetMdiSubWindow()->pos();
        slotActionUsers();
        DCUsersList::Instance()->GetMdiSubWindow()->move(oldpos);

        if ((*map)["MAXIMIZED"].toInt() == 1) {
            DCUsersList::Instance()->GetMdiSubWindow()->showMaximized();
            DCUsersList::Instance()->showMaximized();
        } else if ((*map)["MINIMIZED"].toInt() == 1) {
            DCUsersList::Instance()->GetMdiSubWindow()->showMinimized();
            DCUsersList::Instance()->showMinimized();
        } else {
            DCUsersList::Instance()->GetMdiSubWindow()->show();
            DCUsersList::Instance()->show();
        }
    }
}

/** initialize the tray icon */
void DCGuiApp::initTray() {
    m_pTrayIcon = 0;
    m_bTray = false;

    if (DCConfig::Instance()->GetEnableTray()) {
        m_bEnableTray = true;

        m_pTrayIcon = new QSystemTrayIcon();
        m_pTrayIcon->setIcon(DCIconLoader::Instance()->GetPixmap(eiICON_APPL));

        QMenu * traymenu = new QMenu(this);

        traymenu->setTitle("EiskaltDC");

        QAction * title = traymenu->addAction("EiskaltDC");
        title->setEnabled(false);

        traymenu->addSeparator();

        QAction * dock = traymenu->addAction(tr("Dock/Undock"));
        connect(dock, SIGNAL(triggered(bool)), this, SLOT(slotViewDock()));

        QAction * remove = traymenu->addAction(tr("Remove tray icon"));
        connect(remove, SIGNAL(triggered(bool)), this, SLOT(slotRemoveTrayIcon()));

        traymenu->addSeparator();

        QAction * open_download_dir = traymenu->addAction(tr("Open download directory"));
        connect(open_download_dir, SIGNAL(triggered()), this, SLOT(slotOpenDownloadDir()));

        traymenu->addSeparator();

        QAction * exit = traymenu->addAction(DCIconLoader::Instance()->GetPixmap(eiEXIT), tr("Exit"));
        connect(exit, SIGNAL(triggered(bool)), this, SLOT(slotFileQuit()));

        m_pTrayIcon->setContextMenu(traymenu);

        connect(m_pTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotTrayMenuTriggered(QSystemTrayIcon::ActivationReason)));

        m_pTrayIcon->show();
    } else {
        m_bEnableTray = false;
    }
}

/** deinitialize the tray icon */
void DCGuiApp::deinitTray() {
    if (m_pTrayIcon) {
        disconnect(m_pTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotTrayMenuTriggered(QSystemTrayIcon::ActivationReason)));

        delete m_pTrayIcon->contextMenu();
        m_pTrayIcon->hide();
        delete m_pTrayIcon;
        m_pTrayIcon = 0;

        m_bEnableTray = false;
    }
}

/** */
bool DCGuiApp::queryExit() {
    if (m_bIsQuitPromptVisible == false) {
        show();
        raise();
        m_bTray = false;
        m_bIsQuitPromptVisible = true;
        int exit = QMessageBox::question(this, tr("Quit..."),
                tr("Do you really want to quit?"),
                QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
        m_bIsQuitPromptVisible = false;

        return (exit == QMessageBox::Ok);
    } else {
        // never get here, m_bIsQuitPromptVisible is checked at event processing
        printf("Already asking to quit.\n");
        return false;
    }
}

/** */
void DCGuiApp::slotTimeout() {
    if (DCConfig::Instance()->GetAutoAwayMode()) {
        // check for user input
        if (m_ApplicationEvents.m_nNoUserInputTimer == 0) {
            // check away mode and reset to normal
            if (DCConfig::Instance()->GetAwayMode() != euamNORMAL) {
                actionAwayModeNormal->setChecked(true);
                DCConfig::Instance()->CConfig::SetAwayMode(euamNORMAL);
            }

            m_ApplicationEvents.m_nNoUserInputTimer = time(0);
        } else {
            // away timeout
            if ((time(0) - m_ApplicationEvents.m_nNoUserInputTimer) >= DCConfig::Instance()->GetAutoAwayTime()) {
                // check away mode
                if (DCConfig::Instance()->GetAwayMode() == euamNORMAL) {
                    actionAwayModeAway->setChecked(true);
                    DCConfig::Instance()->CConfig::SetAwayMode(euamAWAY);
                }

                m_ApplicationEvents.m_nNoUserInputTimer = time(0);
            }
        }
    }

    showFreeDiscSpace();
}

/** */
void DCGuiApp::showFreeDiscSpace() {
    CString s = DCConfig::Instance()->GetDownloadFolder();
    ulonglong n = 0;

    if (s.NotEmpty()) {
        if (CDir::FreeDiscSpace(s, &n) == false) {
            n = 0;
        }
    }

    statusDSLabel->setText(DCGuiUtils::GetSizeString(n));
}

/** */
void DCGuiApp::customEvent(QEvent * event) {
    if (event->type() == EVENT_UPDATE_DM_STATUSBAR) {
        DC_DownloadManagerEvent * e = (DC_DownloadManagerEvent*) event;

        QString s = "SL: ";
        s += QString().setNum(e->m_pDownloadManagerInfo->slot_use_settings);
        s += '/';
        s += QString().setNum(e->m_pDownloadManagerInfo->slot_max);
        s += ' ';
        s += QString().setNum(e->m_pDownloadManagerInfo->slot_use_rate_extra);
        s += '/';
        if (DCConfig::Instance()->GetExtraSlotsRate() > 0) {
            s += QString().setNum(DCConfig::Instance()->GetMaxExtraSlots());
        } else {
            s += '0';
        }
        s += ' ';
        s += QString().setNum(e->m_pDownloadManagerInfo->slot_use_operator);
        s += '/';
        s += QString().setNum(e->m_pDownloadManagerInfo->slot_use_user);
        s += '/';
        s += QString().setNum(e->m_pDownloadManagerInfo->slot_use_special);

        s += " UL: ";
        s += QString::fromAscii(CUtils::GetTransferString(e->m_pDownloadManagerInfo->Rate()).Data());
        s += " DL: ";
        s += QString::fromAscii(CUtils::GetTransferString(e->m_pDownloadManagerInfo->rate_dl).Data());

        statusDMLabel->setText(s);

        // set trayicon tooltip
        if (m_pTrayIcon) {
            QString tt = tr("Connected to ");
            tt += QString().setNum(DCConnectionManager::Instance()->GetConnectedHubCount());
            tt += tr(" hubs");
            tt += '\n';
            tt += s;
            tt += '\n';
            tt += statusTRLabel->text();
            m_pTrayIcon->setToolTip(tt);
        }

        event->accept();
    } else if (event->type() == EVENT_UPDATE_FM_STATUSBAR) {
        DC_FileManagerEvent * e = (DC_FileManagerEvent*) event;

        bool s = false;

        switch (e->m_pFileManagerInfo->m_eFileManagerStatus) {
            case efmsCREATESHARELIST:
                s = true;
                m_pProgessBar->setFormat(tr("Share List") + " %p%");
                break;
            case efmsCREATESEARCHINDEX:
                m_pProgessBar->setFormat(tr("Search Index") + " %p%");
                s = true;
                break;
            case efmsCREATEHASHLIST:
                m_pProgessBar->setFormat(tr("Hash List") + " %p%");
                s = true;
                break;
            case efmsNONE:
                //statusFMLabel->hide();
                m_pProgessBar->hide();
                statusBar()->showMessage(tr("Refresh share finished."));
                break;
            default:
                break;
        }

        if (s) {
            //s += QString().setNum(e->m_pFileManagerInfo->m_nProgress,'f',2);
            //s += "%";
            //statusFMLabel->setText(s);
            m_pProgessBar->setValue((int) e->m_pFileManagerInfo->m_nProgress);
            m_pProgessBar->show();
        }

        event->accept();
    } else if (event->type() == EVENT_UPDATE_TR_STATUSBAR) {
        DC_TrafficInfoEvent * e = (DC_TrafficInfoEvent*) event;

        QString s = "RX: ";
        s += DCGuiUtils::GetSizeString(e->m_pTrafficInfo->m_nRx);
        s += " TX: ";
        s += DCGuiUtils::GetSizeString(e->m_pTrafficInfo->m_nTx);

        statusTRLabel->setText(s);

        // set trayicon tooltip
        if (m_pTrayIcon) {
            QString tt = tr("Connected to ");
            tt += QString().setNum(DCConnectionManager::Instance()->GetConnectedHubCount());
            tt += tr(" hubs");
            tt += '\n';
            tt += statusDMLabel->text();
            tt += '\n';
            tt += s;
            m_pTrayIcon->setToolTip(tt);
        }

        event->accept();
    } else {
        event->ignore();
    }
}

/** */
void DCGuiApp::closeEvent(QCloseEvent * event) {
    if (!ready2Unload) {
        event->ignore();
        slotViewDock();
    } else {
        event->accept();
    }
}

/** */
void DCGuiApp::showEvent(QShowEvent *e) {
    QMainWindow::showEvent(e);
    e->accept();

    if (isVisible() || isActiveWindow()) {
        if (m_pTrayIcon)
            m_pTrayIcon->setIcon(DCIconLoader::Instance()->GetPixmap(eiICON_APPL));
        DCConnectionManager::Instance()->repaintTabbarIcons();
    }
}

/** */
void DCGuiApp::changeEvent(QEvent *e) {
    QMainWindow::changeEvent(e);

    if (e->type() == QEvent::ActivationChange && isVisible()) {
        if (m_pTrayIcon)
            m_pTrayIcon->setIcon(DCIconLoader::Instance()->GetPixmap(eiICON_APPL));
    }

    e->accept();
}

/** */
bool DCGuiApp::eventFilter(QObject *obj, QEvent *e){
    if (e->type() == QEvent::KeyRelease){
	QKeyEvent *k_e = (QKeyEvent*)e;

	if ((k_e->key() == Qt::Key_Escape) && isActiveWindow())
	    slotViewDock();
        else if (k_e->modifiers() == Qt::ControlModifier){
            DCTabBar *tabbar = DCConnectionManager::Instance()->getTabBar();

            if (!tabbar)
                return QMainWindow::eventFilter(obj, e);

            if (k_e->key() == Qt::Key_PageUp)//prev
                tabbar->prevTab();
            else if (k_e->key() == Qt::Key_PageDown)//next
                tabbar->nextTab();
        }
	else if (qc){//DCQuickConnect is modal dialog
	    DCQuickConnect *dcqc = (DCQuickConnect*)qc;

	    if (k_e->key() == Qt::Key_Enter)
		dcqc->slotAccept();
	}
    }

    return QMainWindow::eventFilter(obj, e);
}

/////////////////////////////////////////////////////////////////////
// SLOT IMPLEMENTATION
/////////////////////////////////////////////////////////////////////

/** */
void DCGuiApp::tileVertically() {
    int i, count = 0;
    int y = 0;
    int heightForEach;

    // primitive horizontal tiling
    QList<QMdiSubWindow*> windows = pMdiArea->subWindowList();
    if (windows.count() == 0) {
        return;
    }

    for (i = 0; i < windows.count(); i++) {
        if (windows.at(i)->isEnabled())
            count++;
    }

    if (count > 0) {
        heightForEach = pMdiArea->height() / count;

        for (i = 0; i < windows.count(); i++) {
            if (!windows.at(i)->isEnabled())
                continue;
            QMdiSubWindow * window = windows.at(i);
            if ((window->isMaximized()) || (window->isMinimized())) {
                // prevent flicker
                window->hide();
                window->showNormal();
            }

            int preferredHeight = window->minimumHeight() + window->parentWidget()->baseSize().height();
            int actHeight = QMAX(heightForEach, preferredHeight);

            window->setGeometry(0, y, pMdiArea->width(), actHeight);
            y += actHeight;
        }
    }
}

/** minimize all windows */
void DCGuiApp::slotWindowMinimize() {
    int i;

    QList<QMdiSubWindow*> windows = pMdiArea->subWindowList();

    for (i = 0; i < windows.count(); i++) {
        if (windows.at(i)->isVisible())
            windows.at(i)->showMinimized();
    }
}

/** close all chat windows */
void DCGuiApp::slotWindowCloseAllChats() {
    DCConnectionManager::Instance()->CloseAllChats(false);
}

/** */
void DCGuiApp::slotWindowCloseOfflineChats() {
    DCConnectionManager::Instance()->CloseAllChats(true);
}

/** close all chat windows */
void DCGuiApp::slotWindowCloseHubs() {
    DCConnectionManager::Instance()->CloseDisconnectedHubs();
}

/** */
void DCGuiApp::slotWindowCloseFilelists() {
    closeWindowsOfClass("DCFileBrowser");
}

/** */
void DCGuiApp::slotWindowCloseSearches() {
    closeWindowsOfClass("DCHubSearch");
}

/** */
void DCGuiApp::slotFileOptions() {
    DCOptions * od;

    statusBar()->showMessage(tr("Open options dialog..."));

    od = new DCOptions(this);

    od->SetValues();

    if (QDialog::Accepted == od->exec()) {
        // move values to dcconfig
        od->GetValues();
        // save values
        DCConfig::Instance()->Save();
        // update connected servers
        DCConnectionManager::Instance()->SendMyInfoToConnectedServers();
    }

    /*
     * set theme only if it has changed, or reset theme if a different one was tested
     * also set theme if one theme was tested, but the old theme then saved
     * but no need to set the theme if it was set with the test button
     * od->GetTestedTheme() == old value of DCConfig::Instance()->GetTheme() if test button not pressed
     */
    if (od->GetTestedTheme() != DCConfig::Instance()->GetTheme()) {
        SetTheme();
    }

    delete od;

    statusBar()->showMessage(tr("Ready."));
}

/** */
void DCGuiApp::slotFileFileListBrowser() {
    DCTransferView::Instance()->NewFileBrowser(QString::null, QString::null, QString::null, QString::null);
}

/** */
void DCGuiApp::slotFileFileListBrowserLocal() {
    DCTransferView::Instance()->NewLocalFileBrowser(false);
}

/** */
void DCGuiApp::slotFileReloadPlugins() {
    DCPluginManager::Instance()->DeInitPlugins();
    DCPluginManager::Instance()->Load();
}

/** */
void DCGuiApp::slotFileQuickOptions() {
    pQuickOptionsMenu->exec(QCursor::pos());
}

/** */
void DCGuiApp::slotRightButtonFileToolbar(QPoint){
    /*QHash<QAction*, QAction*> actions_hash;
    QMenu *m = new QMenu(this);

    for (int i = 0; i < toolbar_actions.size(); i++){
        QAction *tool_action = toolbar_actions.at(i);
        QAction *menu_action = new QAction(this);
        menu_action->setText(tool_action->text());
        menu_action->setIcon(tool_action->icon());
        menu_action->setCheckable(true);
        menu_action->setChecked(fileToolbar->actions().contains(tool_action));

        if (tool_action->isSeparator())
            menu_action->setText("--" + tr("Separator") + "--");

        m->addAction(menu_action);

        actions_hash.insert(menu_action, tool_action);
    }

    QAction *ch = m->exec(QCursor::pos());

    delete m;

    if (!ch)
        return;

    QAction *t_action = actions_hash[ch];
    QStringList disabled_actions = DCConfig::Instance()->GetToolBarDisabledButtons();

    if (!ch->isChecked()){
        fileToolbar->removeAction(t_action);
        disabled_actions << t_action->objectName();
    }
    else{
        int index = toolbar_actions.indexOf(t_action);
        QAction *before = NULL;

        if (index > 0)
           before = toolbar_actions.at(index-1);

        fileToolbar->insertAction(before, t_action);

        disabled_actions.removeAt(disabled_actions.indexOf(t_action->objectName()));
    }

    DCConfig::Instance()->SetToolBarDisabledButtons(disabled_actions);

    QHash<QAction*, QAction*>::const_iterator it = actions_hash.constBegin();
    for (; it != actions_hash.constEnd(); ++it){
         delete it.key();
    }*/
}

void DCGuiApp::slotFileMenuBar(){
    QMenu menu;

    menu.addActions(menubar_menus);

    menu.exec(QCursor::pos());
}

/** */
void DCGuiApp::slotHubReconnect(){
    if (DCChat::ActiveChat()){
        DCClient *cl = DCChat::ActiveChat()->GetClient();

        if (cl)
            cl->reconnect();
    }
}

/** */
void DCGuiApp::slotChangeDefaultDldMode(QAction* DldType) {
    DldType->setChecked(true);
    if (fileDefaultDldAsk->isChecked()) {
        DCConfig::Instance()->SetDefaultDownloadMode(eDownloadAsk);
    } else if (fileDefaultDldSingle->isChecked()) {
        DCConfig::Instance()->SetDefaultDownloadMode(eDownloadSingle);
    } else if (fileDefaultDldMulti->isChecked()) {
        DCConfig::Instance()->SetDefaultDownloadMode(eDownloadMulti);
    }
}

/** */
void DCGuiApp::slotFileCreateShare() {
    QString s;

    if (CFileManager::Instance()->CreateShareList())
        s = tr("Refresh share in progress.");
    else
        s = tr("Refresh share already in progress.");

    statusBar()->showMessage(s);
}

/** */
bool DCGuiApp::slotFileQuit() {
    StringMap * map;
    StringMap * tabBarMap;

    statusBar()->showMessage(tr("Exiting application..."));

    if (DCConfig::Instance()->GetQueryOnExit()) {
        if (queryExit() == false) {
            statusBar()->showMessage(tr("Exiting application... aborted"));
            return false;
        }
    }

    // close all search windows
    slotWindowCloseSearches();

    // shutdown all transfers
    DCTransferView::Instance()->DLM_Shutdown();
    // stop running searches
    CSearchManager::Instance()->StopSearch();
    // close all clients
    DCConnectionManager::Instance()->DisconnectAllClients();

    while ((DCTransferView::Instance()->DLM_ShutdownState() != essSHUTDOWNREADY) ||
            (CSearchManager::Instance()->IsSearch()) ||
            (DCConnectionManager::Instance()->GetConnectedHubCount() > 0)) {
        qApp->processEvents();
#ifdef WIN32
        Sleep(100);
#else
        usleep(100);
#endif
    }

    // close all hub windows
    DCConnectionManager::Instance()->CloseDisconnectedHubs();

    DCConfig::Instance()->SetTabBar(viewTabBar->isChecked());
    DCConfig::Instance()->SetToolBar(viewToolBar->isChecked());
    DCConfig::Instance()->SetStatusBar(viewStatusBar->isChecked());
    DCConfig::Instance()->SetAppGeometry(width(), height());

    // save transfer view settings
    DCConfig::Instance()->GetMap("TRANSFERVIEW", map);

    (*map)["X"] = QString().setNum(pTransferViewDock->x());
    (*map)["Y"] = QString().setNum(pTransferViewDock->y());
    (*map)["WIDTH"] = QString().setNum(pTransferViewDock->width());
    (*map)["HEIGHT"] = QString().setNum(pTransferViewDock->height());
    (*map)["DOCKED"] = QString().setNum(!(pTransferViewDock->isFloating()));

    /* Qt::Dock dock3;
    int index3;
    bool nl3;
    int extraOffset3;
    if ( getLocation( pTransferViewDock, dock3, index3, nl3, extraOffset3 ) )
    {
            (*map)["DOCK"] = QString().setNum(dock3);

            QString nlstring;
            if ( nl3 )
            {
                    nlstring = "TRUE";
            }
            else
            {
                    nlstring = "FALSE";
            }

            (*map)["NL"] = nlstring;
            (*map)["INDEX"] = QString().setNum(index3);
            (*map)["EXTRAOFFSET"] = QString().setNum(extraOffset3);
    } */

    // save tabbar position and state
    DCConfig::Instance()->GetMap("TABBAR", tabBarMap);
    (*tabBarMap)["X"] = QString().setNum(windowsTabBar->x());
    (*tabBarMap)["Y"] = QString().setNum(windowsTabBar->y());
    (*tabBarMap)["WIDTH"] = QString().setNum(windowsTabBar->width());
    (*tabBarMap)["HEIGHT"] = QString().setNum(windowsTabBar->height());
    (*tabBarMap)["DOCKED"] = QString().setNum(!(windowsTabBar->isFloating()));

    DCConfig::Instance()->SetQMainWindowState(saveState());

    switch (DCConfig::Instance()->GetTransferViewType()) {
        case etvtDOCK:
            DCConfig::Instance()->SetShowTransferWin(pTransferViewDock->isVisible());

            break;
        case etvtWINDOW:
            if (DCTransferView::Instance()->GetContainer())
                DCConfig::Instance()->SetShowTransferWin(DCTransferView::Instance()->GetContainer()->isVisible());

            break;
    }

    // save transfer list settings
    DCTransferView::Instance()->DeInitDocument();

    // save hub list settings
    DCHubListManager::Instance()->DeInitDocument();

    // save spy view settings
    DCSpy::Instance()->DeInitDocument();

    // save user view settings
    DCUsersList::Instance()->DeInitDocument();

    // init main window
    DCConfig::Instance()->GetMap("MAINVIEW", map);
    (*map)["MAXIMIZED"] = QString().setNum(isMaximized());
    (*map)["DOCKED"] = QString().setNum(!(fileToolbar->isFloating()));
    //(*map)["USETABS"]   = QString().setNum(viewUseTabs->isChecked());

    if (pMdiArea->property("tabPosition").isValid()) {
        map->insert("TABPOSITION", pMdiArea->property("tabPosition").toString());
    }

    /* Qt::Dock dock;
    int index;
    bool nl;
    int  extraOffset;

    if ( getLocation( fileToolbar, dock, index, nl, extraOffset ) )
    {
            (*map)["DOCK"] = QString().setNum(dock);
    } */

    /* Qt::Dock dock2;
    int index2;
    bool nl2;
    int extraOffset2;

    if ( getLocation( windowsTabBar, dock2, index2, nl2, extraOffset2 ) )
    {
            (*tabBarMap)["DOCK"] = QString().setNum(dock2);

            QString nlstring;
            if ( nl2 )
            {
                    nlstring = "TRUE";
            }
            else
            {
                    nlstring = "FALSE";
            }

            (*tabBarMap)["NL"] = nlstring;
            (*tabBarMap)["INDEX"] = QString().setNum(index2);
            (*tabBarMap)["EXTRAOFFSET"] = QString().setNum(extraOffset2);
    } */

    // save gui config
    DCConfig::Instance()->SaveDCGui();

    m_pTimer->stop();

    ready2Unload = true;

    qApp->quit();

    statusBar()->showMessage(tr("Ready."));

    return ready2Unload;

}

/** */
void DCGuiApp::slotViewTabBar(bool toggle) {
    statusBar()->showMessage(tr("Toggle tabbar..."));
    ///////////////////////////////////////////////////////////////////
    // turn Toolbar on or off
    if (toggle == false) {
        windowsTabBar->hide();
    } else {
        windowsTabBar->show();
    }

    statusBar()->showMessage(tr("Ready."));
}

/** */
void DCGuiApp::slotViewToolBar(bool toggle) {
    statusBar()->showMessage(tr("Toggle toolbar..."));
    ///////////////////////////////////////////////////////////////////
    // turn Toolbar on or off
    if (toggle == false) {
        fileToolbar->hide();
    } else {
        fileToolbar->show();
    }

    statusBar()->showMessage(tr("Ready."));
}

/** */
void DCGuiApp::slotViewStatusBar(bool toggle) {
    statusBar()->showMessage(tr("Toggle statusbar..."));
    ///////////////////////////////////////////////////////////////////
    //turn Statusbar on or off

    if (toggle == false) {
        statusBar()->hide();
    } else {
        statusBar()->show();
    }

    statusBar()->showMessage(tr("Ready."));
}

/** dock the application */
void DCGuiApp::slotViewDock() {
    if (!m_pTrayIcon) {
        QMessageBox::information(this, tr("Dock Application"), tr("The system tray icon must be enabled to dock the application."));
        return;
    }

    statusBar()->showMessage(tr("Dock/Undock application..."));
    ///////////////////////////////////////////////////////////////////
    //dock/undock the application
    if (m_bTray) {
        if (m_bWasMaximized) {
            showMaximized();
        } else {
            show();
        }
        // show dcgui in front of any applications after undock
        raise();
        // restore desktop position
        move(m_DesktopPosition);

        m_bTray = false;
    } else if (!m_bTray && DCConfig::Instance()->GetInTray()) {
        if (m_bWasMaximized) {
            showMaximized();
        } else {
            show();
        }

        if (pTransferViewDock->widget() == 0) {
            if (DCConfig::Instance()->GetTransferViewType() == etvtDOCK) {
                slotActionTransferList();
                slotActionTransferList();
            }
        }

    } else {
        if (isMinimized()) {
            showNormal();
        } else {
            // save old desktop position
            m_DesktopPosition = pos();
            // save old maximized status
            m_bWasMaximized = isMaximized();

            if (pTransferViewDock->isVisible() && pTransferViewDock->isFloating()) {
                m_bTransferViewGotTrayed = true;
                pTransferViewDock->hide();
            } else {
                m_bTransferViewGotTrayed = false;
            }

            // hide application
            hide();
            //DCConfig::Instance()->SetInTray(true);
            m_bTray = true;
        }
    }

    DCConfig::Instance()->SetInTray(!this->isVisible());

    statusBar()->showMessage(tr("Ready."));
}

/** */
void DCGuiApp::slotToolBarBtnStyle(QAction *act){
    if (!act)
        return;

    Qt::ToolButtonStyle b_style = Qt::ToolButtonIconOnly;

    if (act == viewToolBarTextOnly)
        b_style = Qt::ToolButtonTextOnly;
    else if (act == viewToolBarTextBIcon)
        b_style = Qt::ToolButtonTextBesideIcon;
    else if (act == viewToolBarTextUIcon)
        b_style = Qt::ToolButtonTextUnderIcon;

    DCConfig::Instance()->SetToolBarButtonStyle(b_style);
    fileToolbar->setToolButtonStyle(b_style);
}

/** */
void DCGuiApp::slotMenuBarView(QAction *sel){
    QStringList disabled_actions = DCConfig::Instance()->GetToolBarDisabledButtons();
    QAction *act = this->findChild<QAction*>("action_file_menubar_separator");

    if (sel == viewMenuBarCompact){
        menuBar()->hide();

        fileMenuBar->setVisible(true);

        if (act)
            act->setVisible(false);

        if (disabled_actions.contains(fileMenuBar->objectName()))
            disabled_actions.removeAt(disabled_actions.indexOf(fileMenuBar->objectName()));
        if (act && disabled_actions.contains(act->objectName()))
            disabled_actions.removeAt(disabled_actions.indexOf(act->objectName()));
    }
    else if (sel == viewMenuBarNormal){
        menuBar()->show();

        disabled_actions << fileMenuBar->objectName() << "action_file_menubar_separator";

        DCConfig::Instance()->SetToolBarDisabledButtons(disabled_actions);
        fileMenuBar->setVisible(false);
        QAction *act = this->findChild<QAction*>("action_file_menubar_separator");

        if (act)
            act->setVisible(false);
    }

    DCConfig::Instance()->SetHideMenuBar(sel == viewMenuBarCompact);
}

/** */
void DCGuiApp::slotHelpAbout() {
    QString s;
    QDialog * dlg = 0;
    Ui::DCDialogAbout ui;
    ulonglong up = CSocket::m_Traffic.GetTraffic(ettTX);
    ulonglong down = CSocket::m_Traffic.GetTraffic(ettRX);
    double ratio = 0;

    if (down > 0) {
        ratio = (double) up / (double) down;
    }

    dlg = new QDialog(this);
    ui.setupUi(dlg);

    s = ui.TextLabel2->text();

    s += "\n\n";
    s += tr("EiskaltDC ");
    s += PACKAGE_VERSION;
    s += " (";
    s += EISKALTDC_BUILD_INFO;
    s += ")\n";
    s += tr("Using dclib ");
    s += dclibVersion();
    s += " (";
    s += dclibBuildInfo();
    s += ")\n";
    s += trUtf8("Using Qt® ");
    s += qVersion();

    s += "\n\n";
    s += tr("Ratio: Overall: ");
    s += QString().setNum(ratio, 'f', 2);
    s += tr(" (Up: ");
    s += DCGuiUtils::GetSizeString(up);
    s += tr(", Down: ");
    s += DCGuiUtils::GetSizeString(down);
    s += tr(")\nThis session: ");

    up -= DCConfig::Instance()->GetStartUploaded();
    down -= DCConfig::Instance()->GetStartDownloaded();

    if (down > 0) {
        ratio = (double) up / (double) down;
    } else {
        ratio = 0;
    }

    s += QString().setNum(ratio, 'f', 2);
    s += tr(" (Up: ");
    s += DCGuiUtils::GetSizeString(up);
    s += tr(", Down: ");
    s += DCGuiUtils::GetSizeString(down);
    s += ")";

    ui.TextLabel_VERSION->setText(QString("EiskaltDC ") + QString(PACKAGE_VERSION));
    dlg->setWindowIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiINFO)));
    ui.PixmapLabel_ICON->setPixmap(DCIconLoader::Instance()->GetPixmap(eiICON_APPL));

    ui.TextLabel2->setText(s);

    /* not usually done but is allowed, including a file in the middle of a function */
#include "about.h"
    ui.TextEdit_AUTHORS->setHtml(g_sAboutAuthors);

    // load license file
    QFile f(DCConfig::Instance()->GetValknutDataPath() + DIRSEPARATOR + "COPYING");

    if (f.open(QIODevice::ReadOnly)) {
        QTextStream t(&f);
        t.setCodec("UTF-8");
        ui.TextEdit_LICENSE->setPlainText(t.readAll());
    } else {
        ui.TextEdit_LICENSE->append(tr("Warning license file not found !"));
    }

    dlg->exec();

    delete dlg;
}

/** open the online manual in web browser */
void DCGuiApp::slotHelpManual() {
    DCConfig::Instance()->OpenURL("http://wxdcgui.sourceforge.net/doc/manual.html");
}

/** connect to the valknut hub */
void DCGuiApp::slotHelpSupport() {
    // TODO: Check to see if we are already connected or not.
    DCConnectionManager::Instance()->Connect(CString(), "valknut.dyndns.info:59176");
}

/** change user away mode */
void DCGuiApp::slotChangeAwayMode() {
    switch (DCConfig::Instance()->GetAwayMode()) {
        case euamAWAY:
            actionAwayModeNormal->setChecked(true);
            DCConfig::Instance()->CConfig::SetAwayMode(euamNORMAL);
            break;
        default:
            actionAwayModeAway->setChecked(true);
            DCConfig::Instance()->CConfig::SetAwayMode(euamAWAY);
            break;
    }

    DCConnectionManager::Instance()->SendMyInfoToConnectedServers();
}

/** */
void DCGuiApp::slotAwayModeChanged(eUserAwayMode mode) {
    if (mode == euamNORMAL) {
        actionAwayModeNormal->setChecked(true);
    } else {
        actionAwayModeAway->setChecked(true);
    }
}

/** */
void DCGuiApp::windowMenuAboutToShow() {
    int i = 0;

    pWindowMenu->clear();
    pWindowMenu->addAction(windowCascade);
    pWindowMenu->addAction(windowTile);
    pWindowMenu->addAction(windowTileHor);
    pWindowMenu->addAction(windowMinimize);
    pWindowMenu->addSeparator();
    pWindowMenu->addAction(windowCloseHubs);
    pWindowMenu->addAction(windowCloseAllChats);
    pWindowMenu->addAction(windowCloseOfflineChats);
    pWindowMenu->addAction(windowCloseFilelists);
    pWindowMenu->addAction(windowCloseSearches);

    QList<QMdiSubWindow*> windows = pMdiArea->subWindowList();
    qDeleteAll(windowsGroup->actions());

    //printf("window list length =%d\n", windows.size());

    for (i = 0; i < windows.count(); i++) {
        QAction * act = windowsGroup->addAction(QString("&%1 ").arg(i + 1) + windows.at(i)->windowTitle());
        act->setData(i);
        act->setCheckable(true);
        act->setChecked(pMdiArea->activeSubWindow() == windows.at(i));

        if (i == 0) {
            pWindowMenu->addSeparator();
        }

        pWindowMenu->addAction(act);
    }

    if (i == 0) {
        windowAction->setEnabled(false);
    } else {
        windowAction->setEnabled(true);
    }
}

/** */
void DCGuiApp::windowMenuActivated(QAction * action) {
    if (action) {
        QMdiSubWindow * w = pMdiArea->subWindowList().at(action->data().toInt());
        if (w) {
            w->show();
            w->setFocus();
        }
    }
}

/** show/hide transfer list window */
void DCGuiApp::slotActionTransferList() {
    statusBar()->showMessage(tr("Show/hide transfer list window ..."));

    if (DCConfig::Instance()->GetTransferViewType() == etvtNONE)
        slotActionTransferViewType();

    eTransferViewType t_type = DCConfig::Instance()->GetTransferViewType();

    if (DCTransferView::Instance() != 0) {
        if (DCTransferView::Instance()->isVisible()) {
            if (t_type == etvtDOCK) {
                pTransferViewDock->hide();
            } else {
                if (DCTransferView::Instance()->GetContainer()) {
                    DCTransferView::Instance()->GetContainer()->close();
                    DCTransferView::Instance()->deinitContainer();
                }
            }
        } else {
            if (t_type == etvtDOCK) {
                pTransferViewDock->setWidget(DCTransferView::Instance());
                pTransferViewDock->show();
            } else {
                DCTransferView::Instance()->initContainer();

                showMDIWidget(DCTransferView::Instance()->GetContainer());
                DCTransferView::Instance()->GetContainer()->setWindowIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiTRANSFER)));

                connect(DCTransferView::Instance(), SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));

                DCConnectionManager::Instance()->addTab(DCTransferView::Instance(), QApplication::translate("DCDialogTransfer", "Transfer List", 0, QApplication::UnicodeUTF8));
            }
        }
    }

    showNotification(QApplication::translate("DCDialogTransfer", "Transfer List", 0, QApplication::UnicodeUTF8), "Hi!");

    statusBar()->showMessage(tr("Ready."));
}

/** show/hide mdi widget */
void DCGuiApp::showMDIWidget(QMdiSubWindow * window) {
    if (window != 0) {
        if (window->parent() == 0) {
            /* well this is as stupid as it looks */
            const QPoint oldpos = window->pos();
            pMdiArea->addSubWindow(window);
            window->move(oldpos);
        }

        if (window->isMinimized()) {
            window->showNormal();
            window->widget()->showNormal();
        } else if (window->isVisible()) {
            if (pMdiArea->activeSubWindow() == window) {
                window->close();
            } else {
                pMdiArea->setActiveSubWindow(window);
            }
        } else if (window->isMaximized()) {
            window->showMaximized();
            window->widget()->showMaximized();
        } else {
            window->show();
            window->widget()->show();
        }
    }
}

/** show/hide server list window */
void DCGuiApp::slotActionServerList() {
    statusBar()->showMessage(tr("Show/hide hub list window ..."));

    QMdiSubWindow *wnd = DCHubListManager::Instance()->GetMdiSubWindow();

    if (wnd->isVisible()) {
        wnd->close();
        return;
    }

    showMDIWidget(wnd);

    DCHubListManager *mngr = DCHubListManager::Instance();
    connect(mngr, SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));
    mngr->setWindowIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiSERVER)));

    DCConnectionManager::Instance()->addTab((QWidget*) mngr,
            QApplication::translate("DCDialogHubListManager", "Hub List", 0, QApplication::UnicodeUTF8));

    statusBar()->showMessage(tr("Ready."));
}

/** show/hide multi hub search window */
void DCGuiApp::slotActionHubSearch() {
    statusBar()->showMessage(tr("Open hub search window ..."));

    DCHubSearch * hubsearch = new DCHubSearch(pMdiArea);
    connect(hubsearch, SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));
    hubsearch->setWindowIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiFIND)));

    DCConnectionManager::Instance()->addTab((QWidget*) hubsearch,
            QApplication::translate("DCDialogHubSearch", "Hub Search", 0, QApplication::UnicodeUTF8));

    hubsearch->show();
    //hubsearch->raise();
    hubsearch->raiseFocus();

    statusBar()->showMessage(tr("Ready."));
}

/** show/hide spy window */
void DCGuiApp::slotActionSpy() {
    statusBar()->showMessage(tr("Show/hide spy window ..."));

    QMdiSubWindow *wnd = DCSpy::Instance()->GetMdiSubWindow();

    if (wnd->isVisible()) {
        wnd->close();
        return;
    }

    showMDIWidget(wnd);

    DCSpy *spy = DCSpy::Instance();
    spy->setWindowIcon(QIcon(DCIconLoader::Instance()->GetPixmap(eiSPY)));
    connect(spy, SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));

    DCConnectionManager::Instance()->addTab((QWidget*) spy, QApplication::translate("DCDialogSpy", "Spy", 0, QApplication::UnicodeUTF8));

    statusBar()->showMessage(tr("Ready."));
}

/** show/hide users window */
void DCGuiApp::slotActionUsers() {
    statusBar()->showMessage(tr("Show/hide users window ..."));

    QMdiSubWindow *wnd = DCUsersList::Instance()->GetMdiSubWindow();

    if (wnd->isVisible()) {
        wnd->close();
        return;
    }

    showMDIWidget(wnd);

    DCUsersList *user_lst = DCUsersList::Instance();
    connect(user_lst, SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));
    DCConnectionManager::Instance()->addTab((QWidget*) user_lst, QApplication::translate("DCDialogUsersList", "Users List", 0, QApplication::UnicodeUTF8));

    statusBar()->showMessage(tr("Ready."));
}

void DCGuiApp::slotActionAntiSpam() {
    DCAntiSpamControl *wnd = new DCAntiSpamControl(this);
    wnd->setWindowModality(Qt::WindowModal);
    wnd->setAttribute(Qt::WA_DeleteOnClose);

    wnd->exec();
}

void DCGuiApp::slotActionIPFilter() {
    DCIPFilterControl *wnd = new DCIPFilterControl(this);
    wnd->setWindowModality(Qt::WindowModal);
    wnd->setAttribute(Qt::WA_DeleteOnClose);

    wnd->exec();
}

/** Called when the tray icon is activated */
void DCGuiApp::slotTrayMenuTriggered(QSystemTrayIcon::ActivationReason reason) {
    // if single clicked
    if (reason == QSystemTrayIcon::Trigger) {
        slotViewDock();
    }
}

/** Called when the remove item is chosen from the tray icon's menu */
void DCGuiApp::slotRemoveTrayIcon() {
    // undock if docked!
    if (m_bTray) {
        slotViewDock();
    }

    deinitTray();

    viewTrayIcon->setChecked(false);
    viewDock->setEnabled(false);
    DCConfig::Instance()->SetEnableTray(false);
}

/** */
void DCGuiApp::SetTheme() {
    if (DCConfig::Instance()->GetThemeSupport()) {
        QString s = DCConfig::Instance()->GetTheme();

        if (s.isEmpty()) {
            printf("Can't set empty theme\n");
        } else {
            QApplication::setStyle(s);
        }
    }
}

void DCGuiApp::WakeUp() {
    if (m_bTray) {
	slotViewDock();
	return;
    }
    if (!this->isVisible()) {
	show();
	raise();
    }
}

void DCGuiApp::showNotification(QString sender, QString message, eTrayMessageType type, bool show_anyway) {
    if (!DCConfig::Instance()->GetEnableTray() || !m_pTrayIcon || !m_bEnableTray)
	return;

    TrayMessageType t_type = DCConfig::Instance()->GetTrayMessageType();

    if (IS_TRAY_MSG_NONE(t_type))
	return;
    if (((!IS_TRAY_MSG_DISC(t_type) && (type == eTrayMessageTypeDISC)) ||
         (!IS_TRAY_MSG_NICK(t_type) && (type == eTrayMessageTypeNICK)) ||
         (!IS_TRAY_MSG_PRIV(t_type) && (type == eTrayMessageTypePRIV)))&&
         !show_anyway
        )
    {
	return;
    }

    if (((!IS_TRAY_WND_ACTV(t_type) && isActiveWindow()) ||
         (!IS_TRAY_WND_VSBL(t_type) && isVisible() && !isActiveWindow()))
        && !show_anyway
        )
    {
        return;
    }

    if (type == eTrayMessageTypePRIV) {
	m_pTrayIcon->setIcon(DCIconLoader::Instance()->GetPixmap(eiICON_MSG));
    }

    QString popup = QDir::homePath() + "/.eiskaltdc/popup.sh";

    if (QFile::exists(popup)) {
	QProcess proc(this);
	QStringList args;

	args << popup << "\"" + sender + "\"" << "\"" + message + "\"";

	proc.start(QString("sh"), args);

	proc.waitForFinished(200);

	return;
    }
    int k;
		switch (type){
		case eTrayMessageTypeNICK:
			k = DCConfig::Instance()->GetNotifyLength(type);
			if (message.length() > k){
			message=message.left(k)+"...";
		}
		break;
		case eTrayMessageTypePRIV:
			k = DCConfig::Instance()->GetNotifyLength(type);
			if (message.length() > k){
			message=message.left(k)+"...";
		}
		break;
		case eTrayMessageTypeDISC:
		k = DCConfig::Instance()->GetNotifyLength(type);
			if (message.length() > k){
			message=message.left(k)+"...";
		}
		break;
	}
    m_pTrayIcon->showMessage(sender + ":\n\t", message);
}

/** */
void DCGuiApp::slotLoadCSS(){
    QString css_file = QDir::homePath() + "/.eiskaltdc/style.css";
    QFile css(css_file);

    if (!css.exists() || !css.open(QIODevice::ReadOnly | QIODevice::Text))
	return;

    QString css_string = css.readAll().data();

    if (css_string != "")
	qApp->setStyleSheet(css_string);

    css.close();
}

/** */
void DCGuiApp::slotDefaultDownloadModeChanged() {
    switch (DCConfig::Instance()->GetDefaultDownloadMode()) {
        case eDownloadAsk: fileDefaultDldAsk->setChecked(true);
            break;
        case eDownloadSingle: fileDefaultDldSingle->setChecked(true);
            break;
        case eDownloadMulti: fileDefaultDldMulti->setChecked(true);
            break;
        default: break;
    }
}

/** */
void DCGuiApp::slotViewTrayIcon(bool toggle) {
    DCConfig::Instance()->SetEnableTray(toggle);

    if (toggle) {
        initTray();
    } else {
        deinitTray();
    }

    viewDock->setEnabled(toggle);
}

/** */
void DCGuiApp::closeWindowsOfClass(QString classname) {
    QList<QMdiSubWindow*> windows = pMdiArea->subWindowList(QMdiArea::CreationOrder);

    for (int i = 0; i < windows.size(); ++i) {
        if (windows.at(i)->widget() && (windows.at(i)->widget()->metaObject()->className() == classname)) {
            windows.at(i)->close();
        }
    }
}

/** */
void DCGuiApp::slotContextMenuTraffic(const QPoint & /* pos */) {
    QMenu * m = new QMenu(this);

    QAction * reset = DCMenuHandler::addAction(m, emiRESET);

    QAction * chosen = m->exec(QCursor::pos());

    delete m;

    if (chosen == reset) {
        CSocket::m_Traffic.ResetTraffic();
        DCConfig::Instance()->ResetSessionStats();
        statusTRLabel->clear();
    }
}

/** */
void DCGuiApp::slotDebugSettings() {
    QDialog * dialog = new QDialog(this);
    Ui::DCDialogDebugSettings ui;
    ui.setupUi(dialog);

    ui.ComboBox_PRINTF->setCurrentIndex(dclibVerbose());
    ui.ComboBox_SOCKETLOG->setCurrentIndex(CSocket::m_eSocketLog);

#if defined(HAVE_MALLINFO) || defined(HAVE_MALLOC_STATS)
    connect(ui.PushButton_MALLOC_INFO, SIGNAL(clicked()), this, SLOT(slotMallocInfo()));
#else
    ui.PushButton_MALLOC_INFO->setEnabled(false);
#endif

    if (dialog->exec() == QDialog::Accepted) {
        setdclibVerbose(ui.ComboBox_PRINTF->currentIndex());
        switch (ui.ComboBox_SOCKETLOG->currentIndex()) {
            case 0:
                CSocket::m_eSocketLog = eslNONE;
                break;
            case 1:
                CSocket::m_eSocketLog = eslSEND;
                break;
            case 2:
                CSocket::m_eSocketLog = eslRECV;
                break;
            case 3:
                CSocket::m_eSocketLog = eslBOTH;
                break;
            default:
                CSocket::m_eSocketLog = eslNONE;
                break;
        }
    }

    delete dialog;
}

/** */
void DCGuiApp::slotMallocInfo() {
#if defined(HAVE_MALLOC_STATS)
    fprintf(stderr, "%s %s malloc_stats()\n", PACKAGE_STRING, QDateTime::currentDateTime().toString().toLocal8Bit().constData());
    malloc_stats();
#endif

#if defined(HAVE_MALLINFO)
    struct mallinfo mi = mallinfo();

    /* this stuff is for debugging so is not translated or even explained */
    QMessageBox * mb = new QMessageBox(pMdiArea);
    mb->setAttribute(Qt::WA_DeleteOnClose);
    mb->setIcon(QMessageBox::Information);
    mb->setWindowTitle("mallinfo");
    mb->setText(
            QDateTime::currentDateTime().toString() +
            "\n\narena " + QString::number(mi.arena) +
            "\nordblks " + QString::number(mi.ordblks) +
            "\nsmblks " + QString::number(mi.smblks) +
            "\nhblks " + QString::number(mi.hblks) +
            "\nhblkhd " + QString::number(mi.hblkhd) +
            "\nusmblks " + QString::number(mi.usmblks) +
            "\nfsmblks " + QString::number(mi.fsmblks) +
            "\nuordblks " + QString::number(mi.uordblks) +
            "\nfordblks " + QString::number(mi.fordblks) +
            "\nkeepcost " + QString::number(mi.keepcost)
            );
    mb->setModal(false);
    mb->show();
#endif
}

/** */
void DCGuiApp::slotAutoAwayModeChanged(bool enabled) {
    if (enabled) {
        qApp->installEventFilter(&m_ApplicationEvents);
    } else {
        qApp->removeEventFilter(&m_ApplicationEvents);
    }

    m_ApplicationEvents.m_nNoUserInputTimer = 0;
}

void DCGuiApp::slotChildOnDie(QWidget *wnd) {
    if (!wnd)
        return;
    DCConnectionManager::Instance()->remTab(wnd);
}

void DCGuiApp::slotActionTransferViewType() {

    eTransferViewType t_type = DCConfig::Instance()->GetTransferViewType();
    QMessageBox msg_box;
    QPushButton *dock_btn, *wind_btn;

    dock_btn = msg_box.addButton(tr("Dock mode"), QMessageBox::YesRole);
    wind_btn = msg_box.addButton(tr("Window mode"), QMessageBox::YesRole);

    msg_box.setText(tr("Please, select transfer view type"));

    msg_box.exec();

    if (msg_box.clickedButton() == dock_btn)
        DCConfig::Instance()->SetTransferViewType(etvtDOCK);
    else if (msg_box.clickedButton() == wind_btn)
        DCConfig::Instance()->SetTransferViewType(etvtWINDOW);
    else
        return;

    if (t_type != etvtNONE) {
        if (t_type == etvtDOCK && (msg_box.clickedButton() == wind_btn)) {
            pTransferViewDock->hide();
            pTransferViewDock->setWidget(0);
            removeDockWidget(pTransferViewDock);

            DCTransferView::Instance()->initContainer();

            showMDIWidget(DCTransferView::Instance()->GetContainer());
            connect(DCTransferView::Instance(), SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));

            DCConnectionManager::Instance()->addTab(DCTransferView::Instance(), QApplication::translate("DCDialogTransfer", "Transfer List", 0, QApplication::UnicodeUTF8));
        } else {
            if (DCTransferView::Instance()->GetContainer()) {
                DCTransferView::Instance()->GetContainer()->close();
                DCTransferView::Instance()->deinitContainer();
            }
            pTransferViewDock->setWidget(DCTransferView::Instance());
            addDockWidget(Qt::BottomDockWidgetArea, pTransferViewDock);
            pTransferViewDock->show();
        }
    } else {
        switch (t_type) {
            case etvtDOCK:
                pTransferViewDock->setWidget(DCTransferView::Instance());
                pTransferViewDock->show();

                break;
            case etvtWINDOW:
            default:
                pTransferViewDock->hide();
                pTransferViewDock->setWidget(0);

                DCTransferView::Instance()->initContainer();

                showMDIWidget(DCTransferView::Instance()->GetContainer());
                connect(DCTransferView::Instance(), SIGNAL(onDie(QWidget*)), this, SLOT(slotChildOnDie(QWidget*)));

                DCConnectionManager::Instance()->addTab(DCTransferView::Instance(), QApplication::translate("DCDialogTransfer", "Transfer List", 0, QApplication::UnicodeUTF8));

                break;
        }
    }

}



void DCGuiApp::slotFileQuickConnect() {
    DCQuickConnect *qc = new DCQuickConnect(this);
    qc->setAttribute(Qt::WA_DeleteOnClose);
    qc->setWindowModality(Qt::WindowModal);

    this->qc = qc;

    qc->exec();

    this->qc = NULL;
}


#ifndef WIN32

void DCGuiApp::slotInotify() {
    if (DCInotifyControl::Instance()) {

        DCInotifyControl::Instance()->setWindowModality(Qt::WindowModal);
        DCInotifyControl::Instance()->exec();
        DCInotifyControl::Instance()->setWindowModality(Qt::NonModal);

    }
}

void DCGuiApp::slotFileInotifyEnable() {
    DCConfig::Instance()->SetInotifyEnabled(fileInotifyEnable->isChecked());

    if (DCConfig::Instance()->GetInotifyEnabled()) {
        DCInotifyControl::SetInstance(new DCInotifyControl(this));

        fileInotify->setEnabled(true);
    } else {
	if (DCInotifyControl::Instance()){
            DCInotifyControl::Instance()->Shutdown();
	    delete DCInotifyControl::Instance();
	}
        DCInotifyControl::SetInstance(NULL);
        fileInotify->setEnabled(false);
    }
}
#endif

void DCGuiApp::slotClearCurrentChat() {
    if (DCChat::ActiveChat())
        DCChat::ActiveChat()->ClearChat();
}

void DCGuiApp::slotChatZoomIn() {
    if (DCChat::ActiveChat())
        DCChat::ActiveChat()->ZoomIn();
}

void DCGuiApp::slotChatZoomOut() {
    if (DCChat::ActiveChat())
        DCChat::ActiveChat()->ZoomOut();
}

void DCGuiApp::slotChatOff() {
    if (DCChat::ActiveChat())
        DCChat::ActiveChat()->SetChatOff();
}

void DCGuiApp::SetChatOff(bool b) {
    chatOff->setChecked(b);

    if (b) {
        chatOff->setText(tr("Enable chat"));
        chatOff->setStatusTip(tr("Enable chat output"));
    } else {
        chatOff->setText(tr("Disable chat"));
        chatOff->setStatusTip(tr("Disable chat output"));
    }
}

void DCGuiApp::slotOpenDownloadDir(){
    QString directory = DCConfig::Instance()->GetDownloadFinishedFolder().Data();

    if (directory.isEmpty() || directory.isNull() || !QDir(directory).exists())
        directory = DCConfig::Instance()->GetDownloadFolder().Data();

    QDesktopServices::openUrl(QUrl(directory));
}

void DCTabBar::mousePressEvent(QMouseEvent *e) {
    e->accept();

    QTabBar::mousePressEvent(e);

    if (e->button() == Qt::MidButton) {

        QPoint p = mapFromGlobal(QCursor::pos());
        int tab = this->tabAt(p);

        QWidget *wgt = DCConnectionManager::Instance()->GetWidgetForTab(tab);

        if (wgt)
            wgt->close();
    }
}

void DCTabBar::nextTab(){
    int new_index = -1;

    if (currentIndex() == (count()-1))
        new_index = 0;
    else
        new_index = currentIndex() + 1;

    setCurrentIndex(new_index);

    emit currentChanged(new_index);
}

void DCTabBar::prevTab(){
    int new_index = -1;

    if (currentIndex() == 0)
        new_index = count()-1;
    else
        new_index = currentIndex()-1;

    setCurrentIndex(new_index);

    emit currentChanged(new_index);
}
