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

// Qt includes
#include <qtooltip.h>
#include <qfile.h>
#include <QProcess>
//Added by qt3to4:
#include <QLabel>
#include <QPixmap>
#include <QMouseEvent>
#include <QEvent>
#include <QCloseEvent>
#include <QTextStream>
#include <QMdiArea>
#include <QMdiSubWindow>

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

#include "dcgui.h"
#include "dcoptions.h"
#include "dchublistmanager.h"
#include "dcconnectionmanager.h"
#include "dctransferview.h"
#include "dcconfig.h"
#include "dchubsearch.h"
#include "dcgeturl.h"
#include "dcspy.h"
#include "dcuserslist.h"
#include "dctranslator.h"
#include "dcevent.h"
#include "dcpluginmanager.h"
#include "dcmenuhandler.h"
#include "dciconloader.h"
#include "dcupdatemanager.h"

#include "DCDialogAbout.h"

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

#include "about.h"

/** */
DCGuiApp::DCGuiApp()
{
	StringMap * map;
	StringMap * tabBarMap;
	int width,height;
	bool b;
	
	m_bIsQuitPromptVisible = FALSE;
	
	g_pTransferView      = 0;
	g_pHubListManager    = 0;
	g_pConnectionManager = 0;
	g_pHubSearch         = 0;
	g_pSpy               = 0;
	g_pUsersList         = 0;

	setCaption( tr("Valknut " VERSION ) );

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

	SetTheme();

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

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

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

	b = TRUE;

	// init transferview
	if ( g_pConfig->GetMap("TRANSFERVIEW",map) == TRUE )
	{
		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->setOn(true);
	viewToolBar->setOn(true);
	viewStatusBar->setOn(true);
	
	m_bWasMaximized = FALSE;

	// init main window
	if ( g_pConfig->GetMap("MAINVIEW",map) == TRUE )
	{
		if ( (*map)["MAXIMIZED"].toInt() == 1 )
		{
			showMaximized();
			m_bWasMaximized = TRUE;
		}
		else
		{
			show();
			m_bWasMaximized = FALSE;
		}

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

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

	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() == TRUE )
	{
		pTransferViewDock->show();
		m_bTransferViewDockVisible = TRUE;
	}
	else
	{
		pTransferViewDock->hide();
		pTransferViewDock->setEnabled(FALSE);
		m_bTransferViewDockVisible = FALSE;
	}

	// restore tabbar position and state
	if ( g_pConfig->GetMap("TABBAR",tabBarMap) == TRUE )
	{
		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());
	
	g_pTranslator = new DCTranslator();

	// install event filter on qApp ;-)
	qApp->installEventFilter(&m_ApplicationEvents);

	// init timer
	m_pTimer = new QTimer();

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

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

/** */
DCGuiApp::~DCGuiApp()
{
	deinitActions();

	// remove event-filter from appl.
	qApp->removeEventFilter(&m_ApplicationEvents);

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

	deinitTray();

	deinitView();

	delete g_pTranslator;
	g_pTranslator = 0;
}

/** */
void DCGuiApp::initActions()
{
	fileOptions = new QAction(QIcon( g_pIconLoader->GetPixmap(eiCONFIGURE) ), tr("&Options"), this);
	fileOptions->setShortcut(tr("Ctrl+O"));
	fileOptions->setStatusTip(tr("Open option dialog"));
	fileOptions->setWhatsThis(tr(""));
	connect(fileOptions, SIGNAL(triggered()), this, SLOT(slotFileOptions()));

	fileFileListBrowser = new QAction(tr("Filelist browser"), this);
	fileFileListBrowser->setStatusTip(tr("Open filelist browser"));
	fileFileListBrowser->setWhatsThis(tr(""));
	connect(fileFileListBrowser, SIGNAL(triggered()), this, SLOT(slotFileFileListBrowser()));

	fileFileListBrowserLocal = new QAction(tr("Filelist browser local"), this);
	fileFileListBrowserLocal->setStatusTip(tr("Open local filelist browser"));
	fileFileListBrowserLocal->setWhatsThis(tr(""));
	connect(fileFileListBrowserLocal, SIGNAL(triggered()), this, SLOT(slotFileFileListBrowserLocal()));

	fileQuickOptions = new QAction(tr("Quick options"), this);
	fileQuickOptions->setShortcut(tr("F12"));
//	fileQuickOptions->setStatusTip(tr("Context menu for a few options"));
//	fileQuickOptions->setWhatsThis(tr(""));
	connect(fileQuickOptions, SIGNAL(triggered()), this, SLOT(slotFileQuickOptions()));

	/** Default download mode */
	fileDefaultDldAsk = new QAction(tr("Download mode: Ask"), this);
	fileDefaultDldAsk->setCheckable(TRUE);
//	fileDefaultDldAsk->setStatusTip(tr(""));
//	fileDefaultDldAsk->setWhatsThis(tr(""));
	fileDefaultDldSingle = new QAction(tr("Download mode: Single"), this);
	fileDefaultDldSingle->setCheckable(TRUE);
	fileDefaultDldMulti = new QAction(tr("Download mode: Multi"),this);
	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);

	switch (g_pConfig->GetDefaultDownloadMode())
	{
		case 0: fileDefaultDldAsk->setChecked(TRUE); break;
		case 1: fileDefaultDldSingle->setChecked(TRUE); break;
		case 2: fileDefaultDldMulti->setChecked(TRUE); break;
	}

	fileReloadPlugins = new QAction(tr("&Reload Plugins"), this);
	fileReloadPlugins->setStatusTip(tr("Reload Plugins"));
	fileReloadPlugins->setWhatsThis(tr(""));
	connect(fileReloadPlugins, SIGNAL(triggered()), this, SLOT(slotFileReloadPlugins()));

	fileQuit = new QAction(QIcon( g_pIconLoader->GetPixmap(eiEXIT) ), tr("Exit"), this);
	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(tr("Tabbar"), this);
	viewTabBar->setCheckable(TRUE);
	viewTabBar->setStatusTip(tr("Enables/disables the tabbar"));
	viewTabBar->setWhatsThis(tr("Tabbar\n\nEnables/disables the tabbar."));
	connect(viewTabBar, SIGNAL(toggled(bool)), this, SLOT(slotViewTabBar(bool)));
	
	viewToolBar = new QAction(tr("Tool&bar"), this);
	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(tr("&Statusbar"), this);
	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)));

	viewDock = new QAction(tr("&Dock"), this );
	viewDock->setStatusTip(tr("Dock the application"));
	viewDock->setWhatsThis(tr("Dock\n\nDock the application."));
	connect(viewDock, SIGNAL(triggered()), this, SLOT(slotViewDock()));

	windowCascade = new QAction(tr("&Cascade"), this);
	windowCascade->setStatusTip(tr("Cascades all windows"));
	windowCascade->setWhatsThis(tr("Cascade\n\nCascades all windows."));
	connect(windowCascade, SIGNAL(triggered()), pMdiArea, SLOT(cascadeSubWindows()));

	windowTile = new QAction(tr("&Tile Vertically"), this);
	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(tr("Tile &Horizontally"), this);
	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(tr("&Minimize"), this);
	windowMinimize->setStatusTip(tr("Minimize all windows."));
	windowMinimize->setWhatsThis(tr("Minimize\n\nMinimize all windows."));
	connect(windowMinimize, SIGNAL(triggered()), this, SLOT(slotWindowMinimize()));

	windowCloseChats = new QAction(tr("Close chat windows."), this);
	windowCloseChats->setStatusTip(tr("Close all chat windows."));
	windowCloseChats->setWhatsThis(tr("Close chat windows\n\nClose all chat windows."));
	connect(windowCloseChats, SIGNAL(triggered()), this, SLOT(slotWindowCloseChats()));

	windowCloseHubs = new QAction(tr("Close disconnected hubs."), this);
	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()));

	windowAction = new QActionGroup(this);
	windowAction->addAction(windowCascade);
	windowAction->addAction(windowTile);
	windowAction->addAction(windowTileHor);
	windowAction->addAction(windowMinimize);
	windowAction->addAction(windowCloseChats);
	windowAction->addAction(windowCloseHubs);

	/** server list */
	actionServerList = new QAction(QIcon( g_pIconLoader->GetPixmap(eiSERVER) ), tr("H&ub List"), this);
	actionServerList->setShortcut(tr("Ctrl+U"));
	actionServerList->setStatusTip(tr("Show Hub List."));
	actionServerList->setWhatsThis(tr(""));
	connect(actionServerList, SIGNAL(triggered()), this, SLOT(slotActionServerList()));

	/** tranfer list */
	actionTransferList = new QAction(QIcon( g_pIconLoader->GetPixmap(eiTRANSFER) ), tr("&Transfer List"), this);
	actionTransferList->setShortcut(tr("Ctrl+T"));
	actionTransferList->setStatusTip(tr("Show Transfer List."));
	actionTransferList->setWhatsThis(tr(""));
	connect(actionTransferList, SIGNAL(triggered()), this, SLOT(slotActionTransferList()));

	/** hub search */
	actionHubSearch = new QAction(QIcon( g_pIconLoader->GetPixmap(eiFIND) ), tr("Hub &Search"), this);
	actionHubSearch->setShortcut(tr("Ctrl+S"));
	actionHubSearch->setStatusTip(tr("Show Hub Search."));
	actionHubSearch->setWhatsThis(tr(""));
	connect(actionHubSearch, SIGNAL(triggered()), this, SLOT(slotActionHubSearch()));

	/** spy */
	actionSpy = new QAction(QIcon( g_pIconLoader->GetPixmap(eiSPY) ), tr("S&py"), this);
	actionSpy->setShortcut(tr("Ctrl+P"));
	actionSpy->setStatusTip(tr("Show Search Spy."));
	actionSpy->setWhatsThis(tr(""));
	connect(actionSpy, SIGNAL(triggered()), this, SLOT(slotActionSpy()));

	/** users */
	actionUsers = new QAction(tr("Users"), this);
	actionUsers->setShortcut(tr("Ctrl+F"));
	actionUsers->setStatusTip(tr("Show users: search tab and friends tab."));
	actionUsers->setWhatsThis(tr(""));
	connect(actionUsers, SIGNAL(triggered()), this, SLOT(slotActionUsers()));

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

	/** away mode normal */
	actionAwayModeNormal = new QAction(tr("&Normal"), this);
	actionAwayModeNormal->setCheckable(TRUE);
	actionAwayModeNormal->setActionGroup(actionGroupAwayMode);
	actionAwayModeNormal->setShortcut(tr("Ctrl+N"));
	actionAwayModeNormal->setStatusTip(tr("Set away mode."));
	actionAwayModeNormal->setWhatsThis(tr(""));
	actionAwayModeNormal->setOn(TRUE);

	/** away mode away */
	actionAwayModeAway = new QAction(tr("&Away"), this);
	actionAwayModeAway->setActionGroup(actionGroupAwayMode);
	actionAwayModeAway->setShortcut(tr("Ctrl+A"));
	actionAwayModeAway->setStatusTip(tr("Set away mode."));
	actionAwayModeAway->setWhatsThis(tr(""));
	actionAwayModeAway->setCheckable(TRUE);

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

	helpAboutApp = new QAction(tr("&About..."), this);
	helpAboutApp->setStatusTip(tr("About the application."));
	helpAboutApp->setWhatsThis(tr("About\n\nAbout the application."));
	connect(helpAboutApp, SIGNAL(triggered()), this, SLOT(slotHelpAbout()));

	helpManualApp = new QAction(tr("&Manual..."), this);
	helpManualApp->setStatusTip(tr("Online User Manual."));
	helpManualApp->setWhatsThis(tr("Manual\n\nOnline User Manual."));
	connect(helpManualApp, SIGNAL(triggered()), this, SLOT(slotHelpManual()));

	helpSupportApp = new QAction(tr("&Support..."), this);
	helpSupportApp->setStatusTip(tr("Connect to Valknut hub"));
	helpSupportApp->setWhatsThis(tr("Support\n\nConnect to the Valknut hub."));
	connect(helpSupportApp, SIGNAL(triggered()), this, SLOT(slotHelpSupport()));

	helpNewVersionApp = new QAction(tr("&Latest release..."), this);
	helpNewVersionApp->setStatusTip(tr("Latest release"));
	helpNewVersionApp->setWhatsThis(tr("Latest release\n\nShow latest release."));
	connect(helpNewVersionApp, SIGNAL(triggered()), this, SLOT(slotHelpNewVersion()));
}

/** */
void DCGuiApp::deinitActions()
{
	delete fileOptions;
	delete fileQuickOptions;
	delete fileDefaultDldAsk;
	delete fileDefaultDldSingle;
	delete fileDefaultDldMulti;
	delete fileDefaultDldGroup;
	delete fileReloadPlugins;
	delete fileQuit;

	delete viewTabBar;
	delete viewToolBar;
	delete viewStatusBar;
	delete viewDock;

	delete windowCascade;
	delete windowTile;
	delete windowTileHor;
	delete windowMinimize;
	delete windowCloseChats;
	delete windowCloseHubs;
	delete windowAction;

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

	delete helpAboutApp;
	delete helpSupportApp;
	delete helpNewVersionApp;
}

/** */
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(fileReloadPlugins);
	pFileMenu->addSeparator();
	pFileMenu->addAction(fileQuit);

	///////////////////////////////////////////////////////////////////
	// menuBar entry viewMenu
	pViewMenu=new QMenu(this);
	pViewMenu->setTitle(tr("&View"));
	pViewMenu->addAction(viewTabBar);
	pViewMenu->addAction(viewToolBar);
	pViewMenu->addAction(viewStatusBar);
	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(helpNewVersionApp);
	//pHelpMenu->insertSeparator();
	//pHelpMenu->insertItem(tr("What's &This"), this, SLOT(whatsThis()), Qt::ShiftModifier+Qt::Key_F1);

	menuBar()->addMenu(pFileMenu);
	menuBar()->addMenu(pViewMenu);
	menuBar()->addMenu(pActionMenu);
	menuBar()->addMenu(pWindowMenu);
	menuBar()->addMenu(pHelpMenu);
}

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

	QAction * whatsthis = QWhatsThis::createAction(fileToolbar);
	fileToolbar->addAction(whatsthis);

	fileToolbar->addSeparator();

	QPixmap preferencesIcon = g_pIconLoader->GetPixmap(eiCONFIGURE_22x22);
//	QToolButton * preferencesOpen =
	fileToolbar->addAction( QIcon(preferencesIcon), tr("Open option dialog"),
					this, SLOT(slotFileOptions()) );

	fileToolbar->addSeparator();

	QPixmap serverIcon = g_pIconLoader->GetPixmap(eiSERVER);
//	QToolButton * serverOpen =
	fileToolbar->addAction( QIcon(serverIcon), tr("Show Hub List"),
					this, SLOT(slotActionServerList()) );

	QPixmap searchIcon = g_pIconLoader->GetPixmap(eiFIND_22x22);
//	QToolButton * searchOpen =
	fileToolbar->addAction( QIcon(searchIcon), tr("Show Hub Search"),
					this, SLOT(slotActionHubSearch()) );

	QPixmap transferIcon = g_pIconLoader->GetPixmap(eiTRANSFER);
//	QToolButton * transferOpen =
	fileToolbar->addAction( QIcon(transferIcon), tr("Show Transfer List"),
					this, SLOT(slotActionTransferList()) );

	QPixmap spyIcon = g_pIconLoader->GetPixmap(eiSPY);
//	QToolButton * spyOpen =
	fileToolbar->addAction( QIcon(spyIcon), tr("Show Spy"),
					this, SLOT(slotActionSpy()) );

	QPixmap shareIcon = g_pIconLoader->GetPixmap(eiRELOAD_22x22);
//	QToolButton * spyOpen =
	fileToolbar->addAction( QIcon(shareIcon), tr("Recreate share"),
					this, SLOT(slotFileCreateShare()) );

	QPixmap updateIcon = g_pIconLoader->GetPixmap(eiINFO_22x22);
	fileToolbar->addAction( QIcon(updateIcon), tr("Show update manager"),
					this, SLOT(slotActionUpdateManager()) );

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

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

	statusDMLabel = new QLabel(statusBar(),"Label");
	statusDMLabel->setFrameShape( QFrame::NoFrame );
	statusDMLabel->setFrameShadow( QFrame::Plain );
	statusBar()->addWidget(statusDMLabel,0,TRUE);

	statusTRLabel = new QLabel(statusBar(),"Label");
	statusTRLabel->setFrameShape( QFrame::NoFrame );
	statusTRLabel->setFrameShadow( QFrame::Plain );
	statusBar()->addWidget(statusTRLabel,0,TRUE);
	QToolTip::add( statusTRLabel, tr("RX/TX Traffic.") );

	statusDSLabel = new QLabel(statusBar(),"Label");
	statusDSLabel->setFrameShape( QFrame::NoFrame );
	statusDSLabel->setFrameShadow( QFrame::Plain );
	statusBar()->addWidget(statusDSLabel,0,TRUE);
	QToolTip::add( statusDSLabel, tr("Available disc space.") );

	statusFMLabel = new QLabel(statusBar(),"Label");
	statusFMLabel->setFrameShape( QFrame::NoFrame );
	statusFMLabel->setFrameShadow( QFrame::Plain );
	statusBar()->addWidget(statusFMLabel,0,TRUE);
	statusFMLabel->hide();

	statusTRLabel->installEventFilter(this);
}

/** */
void DCGuiApp::initView()
{
	pMdiArea = new QMdiArea( this );
	setCentralWidget(pMdiArea);
	pMdiArea->showMaximized();
	
	// create update manager
	//new DCUpdateManager(pMdiArea,0,0);
	//g_pUpdateManager->installEventFilter(this);
	//g_pUpdateManager->GetMdiSubWindow()->hide();
	//g_pUpdateManager->GetMdiSubWindow()->setEnabled(FALSE);
	//g_pUpdateManager->hide();
	//g_pUpdateManager->setEnabled(FALSE);
	g_pUpdateManager = 0;
	
	// create connection manager view
	new DCConnectionManager(pMdiArea,0,0);
	g_pConnectionManager->installEventFilter(this);
	g_pConnectionManager->hide();
	g_pConnectionManager->setEnabled(FALSE);

	// create hublist manager view
	new DCHubListManager(pMdiArea,0,0);
	g_pHubListManager->installEventFilter(this);
	g_pHubListManager->GetMdiSubWindow()->hide();
	g_pHubListManager->GetMdiSubWindow()->setEnabled(FALSE);
	g_pHubListManager->hide();
	g_pHubListManager->setEnabled(FALSE);
	
	// 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
	new DCTransferView(pTransferViewDock,0,0);
	g_pTransferView->SetMdiArea(pMdiArea);
	g_pTransferView->installEventFilter(this);

	pTransferViewDock->setWidget(g_pTransferView);

	// create multi hub search view
	new DCHubSearch(pMdiArea,0,0);
	g_pHubSearch->installEventFilter(this);
	g_pHubSearch->GetMdiSubWindow()->hide();
	g_pHubSearch->GetMdiSubWindow()->setEnabled(FALSE);
	g_pHubSearch->hide();
	g_pHubSearch->setEnabled(FALSE);

	// create spy view
	new DCSpy(pMdiArea,0,0);
	g_pSpy->installEventFilter(this);
	g_pSpy->GetMdiSubWindow()->hide();
	g_pSpy->GetMdiSubWindow()->setEnabled(FALSE);
	g_pSpy->hide();
	g_pSpy->setEnabled(FALSE);

	// create users view
	new DCUsersList(pMdiArea,0,0);
	g_pUsersList->installEventFilter(this);
	g_pUsersList->GetMdiSubWindow()->hide();
	g_pUsersList->GetMdiSubWindow()->setEnabled(FALSE);
	g_pUsersList->hide();
	g_pUsersList->setEnabled(FALSE);

/*	if ( g_pConfig->GetMode() == ecmACTIVE )
	{
		CString error;
		if ( g_pTransferView->DLM_InitListen(error) == FALSE )
		{
			QString s;
			s = error.Data();

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

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

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

/** */
void DCGuiApp::deinitView()
{
	if ( g_pHubSearch )
	{
		g_pHubSearch->removeEventFilter(this);
		delete g_pHubSearch;
	}

	if ( g_pTransferView )
	{
		g_pTransferView->removeEventFilter(this);
		delete g_pTransferView;
	}
	
	if ( pTransferViewDock )
	{
		removeDockWidget(pTransferViewDock);
		delete pTransferViewDock;
		pTransferViewDock = 0;
	}
	
	if ( g_pHubListManager )
	{
		g_pHubListManager->removeEventFilter(this);
		delete g_pHubListManager;
	}
	
	if ( g_pConnectionManager )
	{
		g_pConnectionManager->removeEventFilter(this);
		delete g_pConnectionManager;
	}
	
	if ( g_pUpdateManager )
	{
		g_pUpdateManager->removeEventFilter(this);
		delete g_pUpdateManager;
	}
	
	if ( g_pSpy )
	{
		g_pSpy->removeEventFilter(this);
		delete g_pSpy;
	}
	
	if ( g_pUsersList )
	{
		g_pUsersList->removeEventFilter(this);
		delete g_pUsersList;
	}
}

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

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

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		g_pHubListManager->GetMdiSubWindow()->setEnabled(TRUE);
		g_pHubListManager->setEnabled(TRUE);

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

		if ( (*map)["ENABLED"].toInt() == 0 )
		{
			g_pHubListManager->GetMdiSubWindow()->hide();
			g_pHubListManager->hide();
		}
		else
		{
			g_pHubListManager->GetMdiSubWindow()->setEnabled(TRUE);
			g_pHubListManager->setEnabled(TRUE);
		}
	}

	// setup searchview
	g_pConfig->GetMap("SEARCHVIEW",map);

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		g_pHubSearch->GetMdiSubWindow()->setEnabled(TRUE);
		g_pHubSearch->setEnabled(TRUE);

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

		if ( (*map)["ENABLED"].toInt() == 0 )
		{
			g_pHubSearch->GetMdiSubWindow()->hide();
			g_pHubSearch->hide();
		}
		else
		{
			g_pHubSearch->GetMdiSubWindow()->setEnabled(TRUE);
			g_pHubSearch->setEnabled(TRUE);
		}
	}

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

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		g_pSpy->GetMdiSubWindow()->setEnabled(TRUE);
		g_pSpy->setEnabled(TRUE);

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

		if ( (*map)["ENABLED"].toInt() == 0 )
		{
			g_pSpy->GetMdiSubWindow()->hide();
			g_pSpy->hide();
		}
		else
		{
			g_pSpy->GetMdiSubWindow()->setEnabled(TRUE);
			g_pSpy->setEnabled(TRUE);
		}
	}

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

	if ( (*map)["VISIBLE"].toInt() == 1 )
	{
		g_pUsersList->GetMdiSubWindow()->setEnabled(TRUE);
		g_pUsersList->setEnabled(TRUE);

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

		if ( (*map)["ENABLED"].toInt() == 0 )
		{
			g_pUsersList->GetMdiSubWindow()->hide();
			g_pUsersList->hide();
		}
		else
		{
			g_pUsersList->GetMdiSubWindow()->setEnabled(TRUE);
			g_pUsersList->setEnabled(TRUE);
		}
	}
}

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

	if ( g_pConfig->GetEnableTray() == 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 * 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();
	}
}

/** deinitialize the tray icon */
void DCGuiApp::deinitTray()
{
	if ( m_pTrayIcon )
	{
		m_pTrayIcon->hide();
		delete m_pTrayIcon;
	}
}

/** */
bool DCGuiApp::queryExit()
{
	if ( m_bIsQuitPromptVisible == FALSE )
	{
		m_bIsQuitPromptVisible = TRUE;
		int exit = QMessageBox::question(this, tr("Quit..."),
				tr("Do you really want to quit?"),
				QMessageBox::Ok, 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() == TRUE )
	{
		// check for user input
		if ( m_ApplicationEvents.m_nNoUserInputTimer == 0 )
		{
			// check away mode and reset to normal
			if ( g_pConfig->GetAwayMode() != euamNORMAL )
			{
				actionAwayModeNormal->setOn(TRUE);
			}

			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->setOn(TRUE);
				}

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

	showFreeDiscSpace();
}

/** */
void DCGuiApp::showFreeDiscSpace()
{
	CDir di;
	CString s;
	ulonglong n;

	s = g_pConfig->GetDownloadFolder();
	n = 0;
	
	if ( s != "" )
	{
		if ( di.FreeDiscSpace( s, &n ) == FALSE )
		{
			n = 0;
		}
	}
	
	s = CUtils::GetSizeString(n,g_pConfig->GetUnit());

	statusDSLabel->setText(s.Data());
}

/** */
bool DCGuiApp::eventFilter(QObject* object, QEvent* event)
{
	QString s;

	if((event->type() == QEvent::Close)&&((DCGuiApp*)object!=this))
	{
		QCloseEvent * e = (QCloseEvent*) event;
		
		if ( (g_pTransferView != 0) && (DCTransferView*)object == g_pTransferView )
		{
			g_pTransferView->hide();
			g_pTransferView->setEnabled(FALSE);
			m_bTransferViewDockVisible = FALSE;
			e->accept();
			return TRUE;
		}
		else if ( (g_pHubListManager != 0) && (DCHubListManager*)object == g_pHubListManager )
		{
			g_pHubListManager->GetMdiSubWindow()->hide();
			g_pHubListManager->GetMdiSubWindow()->setEnabled(FALSE);
			e->accept();
			return TRUE;
		}
		else if ( (g_pHubSearch != 0) && (DCHubSearch*)object == g_pHubSearch )
		{
			g_pHubSearch->GetMdiSubWindow()->hide();
			g_pHubSearch->GetMdiSubWindow()->setEnabled(FALSE);
			e->accept();
			return TRUE;
		}
		else if ( (g_pSpy != 0) && (DCSpy*)object == g_pSpy )
		{
			g_pSpy->GetMdiSubWindow()->hide();
			g_pSpy->GetMdiSubWindow()->setEnabled(FALSE);
			e->accept();
			return TRUE;
		}
		else if ( (g_pUsersList != 0) && (DCUsersList*)object == g_pUsersList )
		{
			g_pUsersList->GetMdiSubWindow()->hide();
			g_pUsersList->GetMdiSubWindow()->setEnabled(FALSE);
			e->accept();
			return TRUE;
		}
		else if ( (g_pUpdateManager != 0) && (DCUpdateManager*)object == g_pUpdateManager )
		{
			g_pUpdateManager->GetMdiSubWindow()->hide();
			g_pUpdateManager->GetMdiSubWindow()->setEnabled(FALSE);
			e->accept();
			return TRUE;
		}
	}
	else if((event->type() == QEvent::Close)&&((DCGuiApp*)object==this))
	{
		QCloseEvent* e=(QCloseEvent*)event;

		if ( m_bIsQuitPromptVisible == FALSE )
		{
			if ( slotFileQuit() == FALSE )
			{
				e->ignore();
				return TRUE;
			}
			else
			{
				e->accept();
				return TRUE;
			}
		}
		else
		{
			// TODO find a way to raise the window on the user's desktop
			e->ignore();
			return TRUE;
		}
	}
	else if( (event->type() == EVENT_UPDATE_DM_STATUSBAR) && ((DCGuiApp*)object!=this) )
	{
		DC_DownloadManagerEvent * e = (DC_DownloadManagerEvent*)event;

		s  = "SL: "+QString().setNum(e->m_pDownloadManagerInfo->slot_use_settings)+QString("/")+QString().setNum(e->m_pDownloadManagerInfo->slot_max) + " ";
		s += QString().setNum(e->m_pDownloadManagerInfo->slot_use_operator)+QString("/")+
		     QString().setNum(e->m_pDownloadManagerInfo->slot_use_user)+QString("/")+
		     QString().setNum(e->m_pDownloadManagerInfo->slot_use_special);

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

		statusDMLabel->setText(s);

		// set trayicon tooltip
		if ( m_pTrayIcon )
			m_pTrayIcon->setToolTip(s + "\n" + statusTRLabel->text() );
	}
	else if( (event->type() == EVENT_UPDATE_FM_STATUSBAR) && ((DCGuiApp*)object!=this) )
	{
		DC_FileManagerEvent * e = (DC_FileManagerEvent*)event;

		switch(e->m_pFileManagerInfo->m_eFileManagerStatus)
		{
			case efmsCREATESHARELIST:
				s = "L ";
				break;
			case efmsCREATESEARCHINDEX:
				s = "S ";
				break;
			case efmsCREATEHASHLIST:
				s = "H ";
				break;
			default:
				s = "";
				break;
		}
		
		if ( s != "" )
		{
			s += QString().setNum(e->m_pFileManagerInfo->m_nProgress,'f',2) + "%";
		}

		if ( CFileManager::Instance()->IsCreateShareListRunning() == FALSE )
		{
			statusFMLabel->hide();
			statusBar()->message(tr("Refresh share finished."));
		}
		else if ( !statusFMLabel->isVisible() )
		{
			statusFMLabel->show();
		}

		statusFMLabel->setText(s);
	}
	else if( (event->type() == EVENT_UPDATE_TR_STATUSBAR) && ((DCGuiApp*)object!=this) )
	{
		DC_TrafficInfoEvent * e = (DC_TrafficInfoEvent*)event;

		s = ( "RX: " + CUtils::GetSizeString(e->m_pTrafficInfo->m_nRx,g_pConfig->GetUnit()) + " TX: " +
		    CUtils::GetSizeString(e->m_pTrafficInfo->m_nTx,g_pConfig->GetUnit()) ).Data();

		statusTRLabel->setText(s);

		// set trayicon tooltip
		if ( m_pTrayIcon )
			m_pTrayIcon->setToolTip( statusDMLabel->text() + "\n" + s );
	}
	else if ( (event->type() == QEvent::MouseButtonPress) && ((QLabel*)object == statusTRLabel) )
	{
		QMouseEvent * e = (QMouseEvent*)event;

		if ( e->button() == Qt::RightButton )
		{
			QAction * chosen = 0;
			QMenu * m=  new QMenu(this);
			DCMenuHandler mhandler;

			QAction * reset = mhandler.addAction( m, emiRESET );

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

			delete m;

			if ( chosen == reset )
			{
				CSocket::m_Traffic.ResetTraffic();
				g_pConfig->ResetSessionStats();
				statusTRLabel->setText("");
			}
		}
	}

	return QWidget::eventFilter( object, event );    // standard event processing
}

/** */
void DCGuiApp::closeEvent( QCloseEvent * event )
{
	if ( m_bIsQuitPromptVisible == FALSE )
	{
		if ( slotFileQuit() == FALSE )
		{
			event->ignore();
		}
		else
		{
			event->accept();
		}
	}
	else
	{
		// TODO find a way to raise the window on the user's desktop
		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::slotWindowCloseChats()
{
	g_pConnectionManager->CloseAllChats();
}

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

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

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

	od = new DCOptions();

	od->SetValues();

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

	delete od;

	/** reset or set theme */
	SetTheme();

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

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

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

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

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

/** */
void DCGuiApp::slotChangeDefaultDldMode(QAction* DldType)
{
	DldType->setOn(TRUE);
	if (fileDefaultDldAsk->isOn())
	{
		g_pConfig->SetDefaultDownloadMode(0);
	}
	else if (fileDefaultDldSingle->isOn())
	{
		g_pConfig->SetDefaultDownloadMode(1);
	}
	else  if (fileDefaultDldMulti->isOn())
	{
		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()->message(s);
}

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

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

	if ( g_pConfig->GetQueryOnExit() )
	{
		if ( queryExit() == false )
		{
			statusBar()->message(tr("Exiting application... aborted"));
			return FALSE;
		}
	}

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

	while( (g_pTransferView->DLM_ShutdownState() != essSHUTDOWNREADY) ||
	       (g_pHubSearch->IsSearch() == TRUE) ||
	       (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->isOn());
	g_pConfig->SetToolBar(viewToolBar->isOn());
	g_pConfig->SetStatusBar(viewStatusBar->isOn());
	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 ) == TRUE )
	{
		(*map)["DOCK"] = QString().setNum(dock3);
		
		QString nlstring;
		if (nl3 == TRUE)
		{
			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 search view settings
	g_pHubSearch->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()));

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

	if ( getLocation( fileToolbar, dock, index, nl, extraOffset ) == TRUE )
	{
		(*map)["DOCK"] = QString().setNum(dock);
	} */
	
	/* Qt::Dock dock2;
	int index2;
	bool nl2;
	int extraOffset2;
	
	if ( getLocation( windowsTabBar, dock2, index2, nl2, extraOffset2 ) == TRUE )
	{
		(*tabBarMap)["DOCK"] = QString().setNum(dock2);
		
		QString nlstring;
		if (nl2 == TRUE)
		{
			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()->message(tr("Ready."));

	return TRUE;
}

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

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

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

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

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

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

	statusBar()->message(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()->message(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);

		// restore transferview settings
		if ( m_bTransferViewDockVisible )
		{
			pTransferViewDock->show();
		}

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

	statusBar()->message(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\n";
	s += tr("Ratio: Overall: ");
	s += QString().setNum( ratio, 'f', 2 );
	s += tr(" (Up: ");
	s += CUtils::GetSizeString( up, g_pConfig->GetUnit() ).Data();
	s += tr(", Down: ");
	s += CUtils::GetSizeString( down, g_pConfig->GetUnit() ).Data();
	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 += CUtils::GetSizeString( up, g_pConfig->GetUnit() ).Data();
	s += tr(", Down: ");
	s += CUtils::GetSizeString( down, g_pConfig->GetUnit() ).Data();
	s += ")";

	ui.TextLabel_VERSION->setText( "Valknut " VERSION );
	ui.PixmapLabel_ICON->setPixmap( g_pIconLoader->GetPixmap(eiGLOBE) );

	ui.TextLabel2->setText( s );

	ui.TextEdit_AUTHORS->setHtml(g_sAboutAuthors);

	// load license file
	QFile f(g_pConfig->GetValknutDataPath() + DIRSEPARATOR + "COPYING");
	
	if ( f.open(QIODevice::ReadOnly) == TRUE )
	{
		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()
{
	if ( g_pConfig->GetBrowser() != "" )
	{
		QProcess::startDetached( QString(g_pConfig->GetBrowser().Data()) + QString(" 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("","valknut.dyndns.info:59176");
}

/** check for new versions */
void DCGuiApp::slotHelpNewVersion()
{
	QString release="";
	DCGetURL * d;

	d = new DCGetURL("http://dcgui.berlios.de/version.xml");

	if ( d->exec() == QDialog::Accepted )
	{
		CString s;
		CByteArray in;
		d->GetData(&in);
		s.Set((char*)in.Data(),in.Size());

		if ( s != "" )
		{
			release = g_pConfig->ParseVersion(s).Data();
		}

		if ( release == "" )
		{
			release = tr("Can't get release info from server");
		}
		else
		{
			release = tr("latest release is: ") + release;
		}

		QMessageBox::about(this,tr("Latest release..."),
				release );
	}

	delete d;
}

/** */
void DCGuiApp::slotStatusHelpMsg(const QString &text)
{
	///////////////////////////////////////////////////////////////////
	// change status message of whole statusbar temporary (text, msec)
	statusBar()->message(text, 2000);
}

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

	g_pConnectionManager->SendMyInfoToConnectedServers();
}

/** widget from workspace activated */
/* void DCGuiApp::slotWorkspaceWindowActivated( QWidget * )
{
} */

/** */
void DCGuiApp::windowMenuAboutToShow()
{
	int c;

	pWindowMenu->clear();
	windowCascade->addTo(pWindowMenu);
	windowTile->addTo(pWindowMenu);
	windowTileHor->addTo(pWindowMenu);
	windowMinimize->addTo(pWindowMenu);
	windowCloseChats->addTo(pWindowMenu);
	windowCloseHubs->addTo(pWindowMenu);

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

	if ( windows.isEmpty() )
	{
		windowAction->setEnabled(false);
	}
	else
	{
		windowAction->setEnabled(true);
	}

	pWindowMenu->insertSeparator();

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

	for ( int i = 0; i < windows.count(); i++ )
	{
		if ( windows.at(i)->isEnabled() )
		{
			int id = pWindowMenu->insertItem(QString("&%1 ").arg(c+1)+windows.at(i)->caption(), this, SLOT( windowMenuActivated( int ) ) );
			pWindowMenu->setItemParameter( id, i );
			pWindowMenu->setItemChecked( id, pMdiArea->activeSubWindow() == windows.at(i) );
			c++;
		}
	}

	if ( c == 0 )
	{
		windowAction->setEnabled(false);
	}
}

/** */
void DCGuiApp::windowMenuActivated( int id )
{
	QMdiSubWindow * w = pMdiArea->subWindowList().at( id );
	if ( w )
	{
		w->show();
		w->setFocus();
	}
}

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

	if ( g_pTransferView != 0 )
	{
		if ( g_pTransferView->isVisible() )
		{
			m_bTransferViewDockVisible = FALSE;
			pTransferViewDock->setEnabled(FALSE);
			pTransferViewDock->hide();
		}
		else
		{
			m_bTransferViewDockVisible = TRUE;
			pTransferViewDock->setEnabled(TRUE);
			pTransferViewDock->show();
		}
	}

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

/** show/hide mdi widget */
void DCGuiApp::showMDIWidget( QMdiSubWindow * window )
{
	if ( window != 0 )
	{
		if ( window->isMinimized() )
		{
			window->setEnabled(TRUE);
			window->widget()->setEnabled(TRUE);
			window->showNormal();
			window->widget()->showNormal();
		}
		else if ( window->isVisible() )
		{
			if ( pMdiArea->activeSubWindow() == window )
			{
				window->setEnabled(FALSE);
				window->widget()->setEnabled(FALSE);
				window->hide();
				window->widget()->hide();
			}
			else
			{
				window->setEnabled(TRUE);
				window->widget()->setEnabled(TRUE);
				pMdiArea->setActiveSubWindow(window);
				//widget->setFocus();
			}
		}
		else if ( window->isMaximized() )
		{
			window->setEnabled(TRUE);
			window->widget()->setEnabled(TRUE);
			window->showMaximized();
			window->widget()->showMaximized();
		}
		else
		{
			window->setEnabled(TRUE);
			window->widget()->setEnabled(TRUE);
			window->show();
			window->widget()->show();
		}
	}
}

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

	showMDIWidget(g_pHubListManager->GetMdiSubWindow());

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

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

	showMDIWidget(g_pHubSearch->GetMdiSubWindow());

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

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

	showMDIWidget(g_pSpy->GetMdiSubWindow());

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

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

	showMDIWidget(g_pUsersList->GetMdiSubWindow());

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

/** show/hide update manager window */
void DCGuiApp::slotActionUpdateManager()
{
	if ( g_pUpdateManager != 0 )
	{
		statusBar()->message(tr("Show/hide update manager window ..."));
		
		showMDIWidget(g_pUpdateManager->GetMdiSubWindow());
		
		statusBar()->message(tr("Ready."));
	}
	else
	{
		QMessageBox::information(
			this,
			tr("Update Manager"),
			tr("The update manager is disabled."),
			QMessageBox::Ok,
			QMessageBox::NoButton,
			QMessageBox::NoButton
		);
	}
}

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

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

	if ( g_pConfig->GetThemeSupport() == TRUE )
	{
		s = g_pConfig->GetTheme().Data();

		if ( s == "" )
		{
			printf("Can't set empty theme");
		}
		else
		{
			QApplication::setStyle( s );
		}
	}
}
