/***************************************************************************
                          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"

// Qt includes
#include <qapplication.h>
#include <qaction.h>
#include <qcombobox.h>
#include <qdialog.h>
#include <qfile.h>
#include <qlabel.h>
#include <qmenu.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qpixmap.h>
#include <qstatusbar.h>
#include <qtoolbar.h>
#include <qwhatsthis.h>
//Added by qt3to4:
#include <QCloseEvent>
#include <QTextStream>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QStyle>
#include <QMetaObject>
#include <QDateTime>
#include <QPushButton>

// 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 "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>

#if defined(HAVE_CONFIG_H)
#include <config.h>
#endif

#if defined(HAVE_MALLOC_H)
#include <malloc.h>
#include <stdio.h>
#endif

DCGuiApp * g_pMainWin = NULL;

/** */
DCGuiApp::DCGuiApp()
{
	StringMap * map;
	StringMap * tabBarMap;
	int width,height;
	bool b;
	
	m_bTransferViewGotTrayed = false;
	m_bIsQuitPromptVisible = false;
	
	setWindowTitle( tr("Valknut") + QString(" ") + QString(PACKAGE_VERSION) );

	// set default icon
	setWindowIcon( g_pIconLoader->GetPixmap(eiICON_22x22) );

	SetTheme();

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

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

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

	g_pConfig->GetAppGeometry( width, height );
	resize( width, height );

	b = true;

	// init transferview
	if ( g_pConfig->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 ( g_pConfig->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 ( (*map)["USETABS"].toInt() == 1 )
		{
			viewUseTabs->setChecked(true);
			slotChangeMDIViewMode(viewUseTabs);
		}
		else
		{
			viewUseWindows->setChecked(true);
		}
	}

	if ( g_pConfig->GetTabBar() == false )
		viewTabBar->toggle();
	if ( g_pConfig->GetToolBar() == false )
		viewToolBar->toggle();
	if ( g_pConfig->GetStatusBar() == false )
		viewStatusBar->toggle();
	if ( g_pConfig->GetShowTransferWin() )
	{
		pTransferViewDock->show();
	}
	else
	{
		pTransferViewDock->hide();
	}

	// restore tabbar position and state
	if ( g_pConfig->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(g_pConfig->GetQMainWindowState());
	
	new DCTranslator( this );

	// install event filter on qApp ;-)
	if ( g_pConfig->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 );
	
	g_pMainWin = this;
}

/** */
DCGuiApp::~DCGuiApp()
{
	g_pMainWin = NULL;
	
	deinitActions();

	// remove event-filter from appl.
	if ( g_pConfig->GetAutoAwayMode() )
	{
		qApp->removeEventFilter(&m_ApplicationEvents);
	}

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

	deinitTray();

	deinitView();

	delete g_pTranslator;
}

/** */
void DCGuiApp::initActions()
{
	QIcon optionsIcon( g_pIconLoader->GetPixmap(eiCONFIGURE_32x32) );
	optionsIcon.addPixmap( g_pIconLoader->GetPixmap(eiCONFIGURE) );
	fileOptions = new QAction(this);
	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()));

	fileFileListBrowser = new QAction(this);
	fileFileListBrowser->setText(tr("Filelist browser"));
	fileFileListBrowser->setIcon( QIcon( g_pIconLoader->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( g_pIconLoader->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()));

	QIcon refreshIcon( g_pIconLoader->GetPixmap(eiRELOAD_32x32) );
	refreshIcon.addPixmap( g_pIconLoader->GetPixmap(eiRELOAD) );
	fileFileListRefresh = new QAction(this);
	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()) );

	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->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->setText(tr("Exit"));
	fileQuit->setIcon( QIcon( g_pIconLoader->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()));

	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(g_pConfig->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->setWhatsThis(tr("Dock\n\nDock the application. Only the system tray icon will be visible."));
	viewDock->setEnabled(g_pConfig->GetEnableTray());
	connect(viewDock, SIGNAL(triggered()), this, SLOT(slotViewDock()));

	viewUseWindows = new QAction(this);
	viewUseWindows->setText(tr("Windows"));
	viewUseWindows->setStatusTip(tr("Use windows"));
	viewUseWindows->setWhatsThis(tr("Use windows\n\nUse the classic multiple document interface, the valknut window will contain other windows."));
	viewUseWindows->setCheckable(true);
	
	viewUseTabs = new QAction(this);
	viewUseTabs->setText(tr("Tabs"));
	viewUseTabs->setStatusTip(tr("Use tabs"));
	viewUseTabs->setWhatsThis(tr("Use tabs\n\nUse tabs for everything similar to recent versions of DC++ and LinuxDC++."));
	viewUseTabs->setCheckable(true);

	// exclusive by default
	viewUseTabsGroup = new QActionGroup(this);
	connect( viewUseTabsGroup, SIGNAL(selected(QAction*)), this, SLOT(slotChangeMDIViewMode(QAction*)) );
	viewUseTabsGroup->addAction(viewUseWindows);
	viewUseTabsGroup->addAction(viewUseTabs);

	windowCascade = new QAction(this);
	windowCascade->setText(tr("&Cascade"));
	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->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->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->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->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->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->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->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->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->setText(tr("H&ub List"));
	actionServerList->setIcon( QIcon( g_pIconLoader->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->setText(tr("&Transfer List"));
	actionTransferList->setIcon( QIcon( g_pIconLoader->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( g_pIconLoader->GetPixmap(eiFIND_32x32) );
	searchIcon.addPixmap( g_pIconLoader->GetPixmap(eiFIND) );
	actionHubSearch = new QAction(this);
	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->setText(tr("S&py"));
	actionSpy->setIcon( QIcon( g_pIconLoader->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( g_pIconLoader->GetPixmap(eiUSERS_32x32) );
	usersIcon.addPixmap( g_pIconLoader->GetPixmap(eiUSERS) );
	actionUsers = new QAction(this);
	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() ) );

	helpAboutApp = new QAction(this);
	helpAboutApp->setText(tr("&About..."));
	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->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->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->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 fileDefaultDldAsk;
	delete fileDefaultDldSingle;
	delete fileDefaultDldMulti;
	delete fileDefaultDldGroup;
	delete fileReloadPlugins;
	delete fileQuit;

	delete viewTabBar;
	delete viewToolBar;
	delete viewStatusBar;
	delete viewTrayIcon;
	delete viewDock;
	delete viewUseWindows;
	delete viewUseTabs;
	delete viewUseTabsGroup;

	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"));
	pFileMenu->addMenu(pQuickOptionsMenu);
	pFileMenu->addSeparator();
	pFileMenu->addAction(fileFileListBrowser);
	pFileMenu->addAction(fileFileListBrowserLocal);
	pFileMenu->addSeparator();
	pFileMenu->addAction(fileFileListRefresh);
	pFileMenu->addSeparator();
	pFileMenu->addAction(fileReloadPlugins);
	pFileMenu->addSeparator();
	pFileMenu->addAction(fileQuit);

	///////////////////////////////////////////////////////////////////
	// menuBar entry viewMenu
	pViewMenu=new QMenu(this);
	
	/* FIXME remove once QT >= 4.4 is required */
	if ( pMdiArea->property("viewMode").isValid() )
	{
		QMenu * alltabs = new QMenu(pViewMenu);
		alltabs->setTitle(tr("View mode"));
		alltabs->addActions(viewUseTabsGroup->actions());
		pViewMenu->addMenu(alltabs);
		pViewMenu->addSeparator();
	}
	
	pViewMenu->setTitle(tr("&View"));
	pViewMenu->addAction(viewTabBar);
	pViewMenu->addAction(viewToolBar);
	pViewMenu->addAction(viewStatusBar);
	pViewMenu->addAction(viewTrayIcon);
	pViewMenu->addAction(viewDock);

	///////////////////////////////////////////////////////////////////
	// menuBar awayMenu
	pAwayMenu=new QMenu(this);
	pAwayMenu->setTitle(tr("Away &Mode"));
	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);

	///////////////////////////////////////////////////////////////////
	// 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()->addMenu(pFileMenu);
	menuBar()->addMenu(pViewMenu);
	menuBar()->addMenu(pActionMenu);
	menuBar()->addMenu(pWindowMenu);
	menuBar()->addMenu(pHelpMenu);
}

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

	fileToolbar->addAction(QWhatsThis::createAction(fileToolbar));
	fileToolbar->addSeparator();
	fileToolbar->addAction(fileOptions);
	fileToolbar->addSeparator();
	fileToolbar->addAction(actionServerList);
	fileToolbar->addAction(actionHubSearch);
	fileToolbar->addAction(actionTransferList);
	fileToolbar->addAction(actionSpy);
	fileToolbar->addAction(actionUsers);
	fileToolbar->addSeparator();
	fileToolbar->addAction(fileFileListRefresh);

	// ADD USERS HERE
	fileToolbar->addSeparator();
	addToolBar(Qt::TopToolBarArea, fileToolbar);
	
	windowsTabBar = new QToolBar(this);
	windowsTabBar->setWindowTitle(tr("Tab Bar"));
	windowsTabBar->setObjectName("ClientsTabBar");
	addToolBar(Qt::TopToolBarArea, windowsTabBar);
	
	// init tabbar
	g_pConnectionManager->InitTabBar(windowsTabBar);
}

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

	statusDMLabel = new QLabel(statusBar());
	statusDMLabel->setObjectName("DownloadManagerStatusLabel");
	statusDMLabel->setFrameShape( QFrame::NoFrame );
	statusDMLabel->setFrameShadow( QFrame::Plain );
	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.") );

	statusFMLabel = new QLabel(statusBar());
	statusFMLabel->setObjectName("FileManagerStatusLabel");
	statusFMLabel->setFrameShape( QFrame::NoFrame );
	statusFMLabel->setFrameShadow( QFrame::Plain );
	statusBar()->addPermanentWidget(statusFMLabel);
	statusFMLabel->hide();

	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
	CConnectionManager::SetInstance(new DCConnectionManager(pMdiArea));

	// create hublist manager view
	CHubListManager::SetInstance(new DCHubListManager(pMdiArea));
	g_pHubListManager->GetMdiSubWindow()->hide();
	g_pHubListManager->hide();
	
	// create dock window for transfer view
	pTransferViewDock = new QDockWidget( this );
	pTransferViewDock->setWindowTitle(tr("Transfer List"));
	pTransferViewDock->setObjectName("TransferViewDock");
	//pTransferViewDock->setResizeEnabled(true);
	addDockWidget(Qt::BottomDockWidgetArea, pTransferViewDock);
	pTransferViewDock->hide();
	//connect( pTransferViewDock, SIGNAL(placeChanged( Q3DockWindow::Place )), this, SLOT(slotTransferViewDockPlaceChanged( Q3DockWindow::Place )) );

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

	pTransferViewDock->setWidget(g_pTransferView);

	// create spy view
	new DCSpy(pMdiArea);
	g_pSpy->GetMdiSubWindow()->hide();
	g_pSpy->hide();

	// create users view
	new DCUsersList(pMdiArea);
	g_pUsersList->GetMdiSubWindow()->hide();
	g_pUsersList->hide();

/*	if ( g_pConfig->GetMode() == ecmACTIVE )
	{
		CString error;
		if ( g_pTransferView->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 );

			g_pConfig->SetMode(ecmPASSIVE);
		}
	}
	*/
}

/** */
void DCGuiApp::deinitView()
{
	if ( g_pTransferView )
	{
		delete g_pTransferView;
	}
	
	if ( pTransferViewDock )
	{
		removeDockWidget(pTransferViewDock);
		delete pTransferViewDock;
		pTransferViewDock = 0;
	}
	
	if ( g_pHubListManager )
	{
		delete g_pHubListManager;
	}
	
	if ( g_pSpy )
	{
		delete g_pSpy;
	}
	
	if ( g_pUsersList )
	{
		delete g_pUsersList;
	}
	
	if ( g_pConnectionManager )
	{
		delete g_pConnectionManager;
	}
}

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

	// setup hubview
	g_pConfig->GetMap("HUBVIEW",map);

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		const QPoint oldpos = g_pHubListManager->GetMdiSubWindow()->pos();
		pMdiArea->addSubWindow( g_pHubListManager->GetMdiSubWindow() );
		g_pHubListManager->GetMdiSubWindow()->move(oldpos);
		
		if ( (*map)["MAXIMIZED"].toInt() == 1 )
		{
			g_pHubListManager->GetMdiSubWindow()->showMaximized();
			g_pHubListManager->showMaximized();
		}
		else if ( (*map)["MINIMIZED"].toInt() == 1 )
		{
			g_pHubListManager->GetMdiSubWindow()->showMinimized();
			g_pHubListManager->showMinimized();
		}
		else
		{
			g_pHubListManager->GetMdiSubWindow()->show();
			g_pHubListManager->show();
		}
	}

	// setup spyview
	g_pConfig->GetMap("SPYVIEW",map);

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		const QPoint oldpos = g_pSpy->GetMdiSubWindow()->pos();
		pMdiArea->addSubWindow( g_pSpy->GetMdiSubWindow() );
		g_pSpy->GetMdiSubWindow()->move(oldpos);
		
		if ( (*map)["MAXIMIZED"].toInt() == 1 )
		{
			g_pSpy->GetMdiSubWindow()->showMaximized();
			g_pSpy->showMaximized();
		}
		else if ( (*map)["MINIMIZED"].toInt() == 1 )
		{
			g_pSpy->GetMdiSubWindow()->showMinimized();
			g_pSpy->showMinimized();
		}
		else
		{
			g_pSpy->GetMdiSubWindow()->show();
			g_pSpy->show();
		}	
	}

	// setup userview
	g_pConfig->GetMap("USERVIEW",map);

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		const QPoint oldpos = g_pUsersList->GetMdiSubWindow()->pos();
		pMdiArea->addSubWindow( g_pUsersList->GetMdiSubWindow() );
		g_pUsersList->GetMdiSubWindow()->move(oldpos);

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

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

	if ( g_pConfig->GetEnableTray() )
	{
		m_bEnableTray = true;
		
		m_pTrayIcon = new QSystemTrayIcon();
		m_pTrayIcon->setIcon( g_pIconLoader->GetPixmap(eiICON_22x22) );

		QMenu * traymenu = new QMenu(this);
		
		traymenu->setTitle("Valknut");
		
		QAction * title = traymenu->addAction("Valknut");
		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()) );
		
		QAction * exit = traymenu->addAction(g_pIconLoader->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 ( g_pConfig->GetAutoAwayMode() )
	{
		// check for user input
		if ( m_ApplicationEvents.m_nNoUserInputTimer == 0 )
		{
			// check away mode and reset to normal
			if ( g_pConfig->GetAwayMode() != euamNORMAL )
			{
				actionAwayModeNormal->setChecked(true);
				g_pConfig->CConfig::SetAwayMode( euamNORMAL );
			}

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

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

	showFreeDiscSpace();
}

/** */
void DCGuiApp::showFreeDiscSpace()
{
	CString s = g_pConfig->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 ( g_pConfig->GetExtraSlotsRate() > 0 )
		{
			s += QString().setNum(g_pConfig->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(g_pConnectionManager->GetConnectedHubCount());
			tt += ' ';
			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;

		QString s;

		switch(e->m_pFileManagerInfo->m_eFileManagerStatus)
		{
			case efmsCREATESHARELIST:
				s = "L ";
				break;
			case efmsCREATESEARCHINDEX:
				s = "S ";
				break;
			case efmsCREATEHASHLIST:
				s = "H ";
				break;
			case efmsNONE:
				statusFMLabel->hide();
				statusBar()->showMessage(tr("Refresh share finished."));
				break;
			default:
				break;
		}
		
		if ( !s.isEmpty() )
		{
			s += QString().setNum(e->m_pFileManagerInfo->m_nProgress,'f',2);
			s += "%";
			statusFMLabel->setText(s);
			statusFMLabel->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(g_pConnectionManager->GetConnectedHubCount());
			tt += ' ';
			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 ( m_bIsQuitPromptVisible == false )
	{
		if ( slotFileQuit() == false )
		{
			event->ignore();
		}
		else
		{
			event->accept();
		}
	}
	else
	{
		show();
		raise();
		m_bTray = false;
		event->ignore();
	}
}

/////////////////////////////////////////////////////////////////////
// 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()
{
	g_pConnectionManager->CloseAllChats(false);
}

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

/** close all chat windows */
void DCGuiApp::slotWindowCloseHubs()
{
	g_pConnectionManager->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
		g_pConfig->Save();
		// update connected servers
                g_pConnectionManager->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 g_pConfig->GetTheme() if test button not pressed
	 */
	if ( od->GetTestedTheme() != g_pConfig->GetTheme() )
	{
		SetTheme();
	}

	delete od;

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

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

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

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

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

/** */
void DCGuiApp::slotChangeDefaultDldMode(QAction* DldType)
{
	DldType->setChecked(true);
	if (fileDefaultDldAsk->isChecked())
	{
		g_pConfig->SetDefaultDownloadMode(0);
	}
	else if (fileDefaultDldSingle->isChecked())
	{
		g_pConfig->SetDefaultDownloadMode(1);
	}
	else  if (fileDefaultDldMulti->isChecked())
	{
		g_pConfig->SetDefaultDownloadMode(2);
	}
}

/** */
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 ( g_pConfig->GetQueryOnExit() )
	{
		if ( queryExit() == false )
		{
			statusBar()->showMessage(tr("Exiting application... aborted"));
			return false;
		}
	}

	// close all search windows
	slotWindowCloseSearches();

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

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

	// close all hub windows
	g_pConnectionManager->CloseDisconnectedHubs();

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

	// save transfer view settings
	g_pConfig->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
	g_pConfig->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()));

	g_pConfig->SetQMainWindowState(saveState());

	g_pConfig->SetShowTransferWin( pTransferViewDock->isVisible() );

	// save transfer list settings
	g_pTransferView->DeInitDocument();

	// save hub list settings
	g_pHubListManager->DeInitDocument();

	// save spy view settings
	g_pSpy->DeInitDocument();

	// save user view settings
	g_pUsersList->DeInitDocument();

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

	/* 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
	g_pConfig->SaveDCGui();

	m_pTimer->stop();

	qApp->quit();

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

	return true;
}

/** */
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);

		if ( m_bTransferViewGotTrayed )
		{
			pTransferViewDock->show();
		}

		m_bTray = false;
	}
	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();
		
			m_bTray = true;
		}
	}

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

/** */
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("Valknut ");
	s += PACKAGE_VERSION;
	s += " (";
	s += VALKNUT_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 -= g_pConfig->GetStartUploaded();
	down -= g_pConfig->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("Valknut ") + QString(PACKAGE_VERSION) );
	dlg->setWindowIcon( QIcon( g_pIconLoader->GetPixmap(eiINFO) ) );
	ui.PixmapLabel_ICON->setPixmap( g_pIconLoader->GetPixmap(eiICON_22x22) );

	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(g_pConfig->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()
{
	g_pConfig->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.
	g_pConnectionManager->Connect(CString(),"valknut.dyndns.info:59176");
}

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

	g_pConnectionManager->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 ( g_pTransferView != 0 )
	{
		if ( g_pTransferView->isVisible() )
		{
			pTransferViewDock->hide();
		}
		else
		{
			pTransferViewDock->show();
		}
	}

	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 ..."));

	showMDIWidget(g_pHubListManager->GetMdiSubWindow());

	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 );
	hubsearch->show();

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

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

	showMDIWidget(g_pSpy->GetMdiSubWindow());

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

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

	showMDIWidget(g_pUsersList->GetMdiSubWindow());

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

/** 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);	
	g_pConfig->SetEnableTray(false);
}

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

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

/** */
void DCGuiApp::slotDefaultDownloadModeChanged()
{
	switch (g_pConfig->GetDefaultDownloadMode())
	{
		case 0: fileDefaultDldAsk->setChecked(true); break;
		case 1: fileDefaultDldSingle->setChecked(true); break;
		case 2: fileDefaultDldMulti->setChecked(true); break;
		default: break;
	}
}

/** */
void DCGuiApp::slotChangeMDIViewMode( QAction * action )
{
	/*
	 * FIXME replace setProperty with proper function and enum
	 * when QT 4.4 is required for compilation
	 */
	
	if ( pMdiArea->property("viewMode").isValid() )
	{
		if ( action == viewUseTabs )
		{
			/* arranging windows does not make sense if everything is in tabs */
			windowTile->setEnabled(false);
			windowTileHor->setEnabled(false);
			windowCascade->setEnabled(false);
			windowMinimize->setEnabled(false);
			
			pMdiArea->setProperty("viewMode",1); // QMdiArea::TabbedView
		}
		else if ( action == viewUseWindows )
		{
			windowTile->setEnabled(true);
			windowTileHor->setEnabled(true);
			windowCascade->setEnabled(true);
			windowMinimize->setEnabled(true);
			
			pMdiArea->setProperty("viewMode",0); // QMdiArea::SubWindowView
		}
	}
}

/** */
void DCGuiApp::slotViewTrayIcon( bool toggle )
{
	g_pConfig->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();
		g_pConfig->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;
}
