/***************************************************************************
                          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 <qvbox.h>
#include <qaccel.h>
#include <qdockwindow.h>
#include <qtextedit.h>
#include <qtooltip.h>
#include <qfile.h>
#include <qprocess.h>

// 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 "dcfiletool.h"
#include "dctranslator.h"
#include "dcevent.h"
#include "dcpluginmanager.h"
#include "dcmenuhandler.h"
#include "dciconloader.h"
#include <dcupdatemanager.h>

#include <DCDialogAbout.h>

#include "trayicon.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;

	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()) )
			pWorkspace->setPaletteBackgroundPixmap(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->dock();

		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->undock();

		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->undock();
		}
		else
		{
			fileToolbar->dock();

			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->undock();
			
			if ( (w != 0) && (h != 0) )
			{
				windowsTabBar->resize(w,h);
			}
		
			windowsTabBar->move(x,y);
		}
		else
		{
			windowsTabBar->dock();
			
			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);
			} */
		}
	}

	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(tr("Options"), QIconSet( g_pIconLoader->GetPixmap(eiCONFIGURE) ), tr("&Options"), QAccel::stringToKey(tr("Ctrl+O")), this);
	fileOptions->setStatusTip(tr("Open option dialog"));
	fileOptions->setWhatsThis(tr(""));
	connect(fileOptions, SIGNAL(activated()), this, SLOT(slotFileOptions()));

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

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

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

	/** Default download mode */
	fileDefaultDldAsk = new QAction(tr("Download mode: Ask"), tr("Download mode: Ask"), QAccel::stringToKey(tr("")), this, 0, true);
//	fileDefaultDldAsk->setStatusTip(tr(""));
//	fileDefaultDldAsk->setWhatsThis(tr(""));
	fileDefaultDldSingle = new QAction(tr("Download mode: Single"), tr("Download mode: Single"), QAccel::stringToKey(tr("")), this, 0, true);
	fileDefaultDldMulti = new QAction(tr("Download mode: Multi"), tr("Download mode: Multi"), QAccel::stringToKey(tr("")), this, 0, true);
	fileDefaultDldGroup = new QActionGroup( this, "Download type", TRUE );
        connect( fileDefaultDldGroup, SIGNAL( selected(QAction*) ), this, SLOT(slotChangeDefaultDldMode(QAction*)) );
	fileDefaultDldGroup->add(fileDefaultDldAsk);
	fileDefaultDldGroup->add(fileDefaultDldSingle);
	fileDefaultDldGroup->add(fileDefaultDldMulti);

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

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

	fileQuit = new QAction(tr("Exit"), QIconSet( g_pIconLoader->GetPixmap(eiEXIT) ), tr("Exit"), QAccel::stringToKey(tr("Ctrl+Q")), this);
	fileQuit->setStatusTip(tr("Quits the application"));
	fileQuit->setWhatsThis(tr("Exit\n\nQuits the application."));
	connect(fileQuit, SIGNAL(activated()), this, SLOT(slotFileQuit()));

	viewTabBar = new QAction(tr("Tabbar"), tr("Tabbar"), 0, this, 0, 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("Toolbar"), tr("Tool&bar"), 0, this, 0, 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"), tr("&Statusbar"), 0, this, 0, 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"), tr("&Dock"), 0, this );
	viewDock->setStatusTip(tr("Dock the application"));
	viewDock->setWhatsThis(tr("Dock\n\nDock the application."));
	connect(viewDock, SIGNAL(activated()), this, SLOT(slotViewDock()));

	windowCascade = new QAction(tr("Cascade"), tr("&Cascade"), 0, this);
	windowCascade->setStatusTip(tr("Cascades all windows"));
	windowCascade->setWhatsThis(tr("Cascade\n\nCascades all windows."));
	connect(windowCascade, SIGNAL(activated()), pWorkspace, SLOT(cascade()));

	windowTile = new QAction(tr("Tile Vertically"), tr("&Tile Vertically"), 0, this);
	windowTile->setStatusTip(tr("Tiles all windows vertically"));
	windowTile->setWhatsThis(tr("Tile Vertically\n\nTiles all windows vertically."));
	connect(windowTile, SIGNAL(activated()), this, SLOT(tileVertically()));

	windowTileHor = new QAction(tr("Tile &Horizontally"), tr("Tile &Horizontally"), 0, this);
	windowTileHor->setStatusTip(tr("Tiles all windows horizontally."));
	windowTileHor->setWhatsThis(tr("Tile Horizontally\n\nTiles all windows horizontally."));
	connect(windowTileHor, SIGNAL(activated()), pWorkspace, SLOT(tile()));

	windowMinimize = new QAction(tr("Minimize"), tr("&Minimize"), 0, this);
	windowMinimize->setStatusTip(tr("Minimize all windows."));
	windowMinimize->setWhatsThis(tr("Minimize\n\nMinimize all windows."));
	connect(windowMinimize, SIGNAL(activated()), this, SLOT(slotWindowMinimize()));

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

	windowCloseHubs = new QAction(tr("Close disconnected hubs."), tr("Close disconnected hubs."), 0, this);
	windowCloseHubs->setStatusTip(tr("Close all disconnected hub windows."));
	windowCloseHubs->setWhatsThis(tr("Close disconnected hubs\n\nClose all disconnected hub windows."));
	connect(windowCloseHubs, SIGNAL(activated()), this, SLOT(slotWindowCloseHubs()));

	windowAction = new QActionGroup(this, 0, false);
	windowAction->insert(windowCascade);
	windowAction->insert(windowTile);
	windowAction->insert(windowTileHor);
	windowAction->insert(windowMinimize);
	windowAction->insert(windowCloseChats);
	windowAction->insert(windowCloseHubs);

	/** server list */
	actionServerList = new QAction(tr("Hub List"), QIconSet( g_pIconLoader->GetPixmap(eiSERVER) ), tr("H&ub List"), QAccel::stringToKey(tr("Ctrl+U")), this, 0, false);
	actionServerList->setStatusTip(tr("Show Hub List."));
	actionServerList->setWhatsThis(tr(""));
	connect(actionServerList, SIGNAL(activated()), this, SLOT(slotActionServerList()));

	/** tranfer list */
	actionTransferList = new QAction(tr("Transfer List"), QIconSet( g_pIconLoader->GetPixmap(eiTRANSFER) ), tr("&Transfer List"), QAccel::stringToKey(tr("Ctrl+T")), this, 0, false);
	actionTransferList->setStatusTip(tr("Show Transfer List."));
	actionTransferList->setWhatsThis(tr(""));
	connect(actionTransferList, SIGNAL(activated()), this, SLOT(slotActionTransferList()));

	/** hub search */
	actionHubSearch = new QAction(tr("Hub Search"), QIconSet( g_pIconLoader->GetPixmap(eiFIND) ), tr("Hub &Search"), QAccel::stringToKey(tr("Ctrl+S")), this, 0, false);
	actionHubSearch->setStatusTip(tr("Show Hub Search."));
	actionHubSearch->setWhatsThis(tr(""));
	connect(actionHubSearch, SIGNAL(activated()), this, SLOT(slotActionHubSearch()));

	/** spy */
	actionSpy = new QAction(tr("Spy"), QIconSet( g_pIconLoader->GetPixmap(eiSPY) ), tr("S&py"), QAccel::stringToKey(tr("Ctrl+P")), this, 0, false);
	actionSpy->setStatusTip(tr("Show Search Spy."));
	actionSpy->setWhatsThis(tr(""));
	connect(actionSpy, SIGNAL(activated()), this, SLOT(slotActionSpy()));

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

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

	/** away mode normal */
	actionAwayModeNormal = new QAction(tr("Normal"), tr("&Normal"), QAccel::stringToKey(tr("Ctrl+N")), actionGroupAwayMode, 0, true);
	actionAwayModeNormal->setStatusTip(tr("Set away mode."));
	actionAwayModeNormal->setWhatsThis(tr(""));
	actionAwayModeNormal->setToggleAction(TRUE);
	actionAwayModeNormal->setOn(TRUE);

	/** away mode away */
	actionAwayModeAway = new QAction(tr("Away"), tr("&Away"), QAccel::stringToKey(tr("Ctrl+A")), actionGroupAwayMode, 0, true);
	actionAwayModeAway->setStatusTip(tr("Set away mode."));
	actionAwayModeAway->setWhatsThis(tr(""));
	actionAwayModeAway->setToggleAction(TRUE);

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

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

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

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

	helpNewVersionApp = new QAction(tr("Latest release"), tr("&Latest release..."), 0, this);
	helpNewVersionApp->setStatusTip(tr("Latest release"));
	helpNewVersionApp->setWhatsThis(tr("Latest release\n\nShow latest release."));
	connect(helpNewVersionApp, SIGNAL(activated()), 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 QPopupMenu();
	fileOptions->addTo(pFileMenu);
	pQuickOptionsMenu=new QPopupMenu();
	fileDefaultDldGroup->addTo(pQuickOptionsMenu);
	pFileMenu->insertItem(tr("Quick Options"),pQuickOptionsMenu);
	pFileMenu->insertSeparator();
	fileFileListBrowser->addTo(pFileMenu);
	fileFileListBrowserLocal->addTo(pFileMenu);
	pFileMenu->insertSeparator();
	fileReloadPlugins->addTo(pFileMenu);
	pFileMenu->insertSeparator();
	fileQuit->addTo(pFileMenu);

	///////////////////////////////////////////////////////////////////
	// menuBar entry viewMenu
	pViewMenu=new QPopupMenu();
	pViewMenu->setCheckable(true);
	viewTabBar->addTo(pViewMenu);
	viewToolBar->addTo(pViewMenu);
	viewStatusBar->addTo(pViewMenu);
	viewDock->addTo(pViewMenu);

	///////////////////////////////////////////////////////////////////
	// menuBar awayMenu
	pAwayMenu=new QPopupMenu();
	actionAwayModeNormal->addTo(pAwayMenu);
	actionAwayModeAway->addTo(pAwayMenu);

	///////////////////////////////////////////////////////////////////
	// menuBar actionMenu
	pActionMenu=new QPopupMenu();
	actionServerList->addTo(pActionMenu);
	actionTransferList->addTo(pActionMenu);
	actionHubSearch->addTo(pActionMenu);
	actionSpy->addTo(pActionMenu);
	actionUsers->addTo(pActionMenu);
	pActionMenu->insertSeparator();
	pActionMenu->insertItem(tr("Away &Mode"),pAwayMenu);

	///////////////////////////////////////////////////////////////////
	// menuBar entry windowMenu
	pWindowMenu = new QPopupMenu(this);
	pWindowMenu->setCheckable(true);
	connect(pWindowMenu, SIGNAL(aboutToShow()), this, SLOT(windowMenuAboutToShow()));

	///////////////////////////////////////////////////////////////////
	// menuBar entry helpMenu
	pHelpMenu=new QPopupMenu();
	helpAboutApp->addTo(pHelpMenu);
	pHelpMenu->insertSeparator();
	helpManualApp->addTo(pHelpMenu);
	pHelpMenu->insertSeparator();
	helpSupportApp->addTo(pHelpMenu);
	pHelpMenu->insertSeparator();
	helpNewVersionApp->addTo(pHelpMenu);
	pHelpMenu->insertSeparator();
	pHelpMenu->insertItem(tr("What's &This"), this, SLOT(whatsThis()), SHIFT+Key_F1);

	menuBar()->insertItem(tr("&File"), pFileMenu);
	menuBar()->insertItem(tr("&View"), pViewMenu);
	menuBar()->insertItem(tr("&Action"), pActionMenu);
	menuBar()->insertItem(tr("&Window"), pWindowMenu);
	menuBar()->insertItem(tr("&Help"), pHelpMenu);
}

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

	QWhatsThis::whatsThisButton(fileToolbar);

	fileToolbar->addSeparator();

	QPixmap preferencesIcon = g_pIconLoader->GetPixmap(eiCONFIGURE_22x22);
//	QToolButton * preferencesOpen =
	new QToolButton( preferencesIcon, tr("Open option dialog"), QString::null,
				this, SLOT(slotFileOptions()), fileToolbar, "options" );

	fileToolbar->addSeparator();

	QPixmap serverIcon = g_pIconLoader->GetPixmap(eiSERVER);
//	QToolButton * serverOpen =
	new QToolButton( serverIcon, tr("Show Hub List"), QString::null,
				this, SLOT(slotActionServerList()), fileToolbar, "hublist" );

	QPixmap searchIcon = g_pIconLoader->GetPixmap(eiFIND_22x22);
//	QToolButton * searchOpen =
	new QToolButton( searchIcon, tr("Show Hub Search"), QString::null,
				this, SLOT(slotActionHubSearch()), fileToolbar, "search" );

	QPixmap transferIcon = g_pIconLoader->GetPixmap(eiTRANSFER);
//	QToolButton * transferOpen =
	new QToolButton( transferIcon, tr("Show Transfer List"), QString::null,
				this, SLOT(slotActionTransferList()), fileToolbar, "transfer list" );

	QPixmap spyIcon = g_pIconLoader->GetPixmap(eiSPY);
//	QToolButton * spyOpen =
	new QToolButton( spyIcon, tr("Show Spy"), QString::null,
				this, SLOT(slotActionSpy()), fileToolbar, "spy" );

	QPixmap shareIcon = g_pIconLoader->GetPixmap(eiRELOAD_22x22);
//	QToolButton * spyOpen =
	new QToolButton( shareIcon, tr("Recreate share"), QString::null,
				this, SLOT(slotFileCreateShare()), fileToolbar, "recreate share" );

	QPixmap updateIcon = g_pIconLoader->GetPixmap(eiINFO_22x22);
	new QToolButton( updateIcon, tr("Show update manager"), QString::null,
				this, SLOT(slotActionUpdateManager()), fileToolbar, "update manager" );

	// ADD USERS HERE
	fileToolbar->addSeparator();
	
	
	windowsTabBar = new QToolBar(this, tr("Tab Bar"));
	windowsTabBar->setLabel(tr("Tab Bar"));
	
	// 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()
{
	QVBox* view_back = new QVBox( this );
//	view_back->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
	pWorkspace = new QWorkspace( view_back );
	setCentralWidget(view_back);
	pWorkspace->showMaximized();
	
	connect( pWorkspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(slotWorkspaceWindowActivated( QWidget *)) );

	setDockMenuEnabled(FALSE);

	// create update manager
	//new DCUpdateManager(pWorkspace,0,WDestructiveClose);
	//g_pUpdateManager->installEventFilter(this);
	//g_pUpdateManager->hide();
	//g_pUpdateManager->setEnabled(FALSE);
	g_pUpdateManager = 0;
	
	// create connection manager view
	new DCConnectionManager(pWorkspace,0,WDestructiveClose);
	g_pConnectionManager->installEventFilter(this);
	g_pConnectionManager->hide();
	g_pConnectionManager->setEnabled(FALSE);

	// create hublist manager view
	new DCHubListManager(pWorkspace,0,WDestructiveClose);
	g_pHubListManager->installEventFilter(this);
	g_pHubListManager->hide();
	g_pHubListManager->setEnabled(FALSE);

	// create dock window for transfer view
	pTransferViewDock = new QDockWindow( QDockWindow::InDock, this );
	pTransferViewDock->setCaption(tr("Transfer List"));
	pTransferViewDock->setResizeEnabled(TRUE);
	moveDockWindow(pTransferViewDock,Qt::DockBottom);
	pTransferViewDock->hide();

	// create transfer view
	new DCTransferView(pTransferViewDock,0,WDestructiveClose);
	g_pTransferView->SetWorkspace(pWorkspace);
	g_pTransferView->installEventFilter(this);

	pTransferViewDock->setWidget(g_pTransferView);

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

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

	// create users view
	new DCUsersList(pWorkspace,0,WDestructiveClose);
	g_pUsersList->installEventFilter(this);
	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 ( pTransferViewDock )
	{
		removeDockWindow(pTransferViewDock);
	}

	if ( g_pTransferView )
	{
		g_pTransferView->removeEventFilter(this);
		delete g_pTransferView;
	}
	
	if ( 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->setEnabled(TRUE);

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

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

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

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

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

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

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

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

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

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

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

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

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

		if ( (*map)["ENABLED"].toInt() == 0 )
			g_pUsersList->hide();
		else
			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 TrayIcon();
		m_pTrayIcon->setIcon( g_pIconLoader->GetPixmap(eiICON_22x22) );

		m_pTrayIcon->show();

		connect( m_pTrayIcon, SIGNAL(clicked( const QPoint&, int )), this, SLOT(slotTrayMenu( const QPoint&, int )) );
	}
}

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

/** */
bool DCGuiApp::queryExit()
{
	int exit=QMessageBox::question(this, tr("Quit..."),
				tr("Do you really want to quit?"),
				QMessageBox::Ok, QMessageBox::Cancel);

	if (exit==QMessageBox::Ok)
	{
	}
	else
	{
	}

	return (exit==QMessageBox::Ok);
}

/** */
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 ( ((DCTransferView*)object == g_pTransferView) && (g_pTransferView != 0) )
		{
			((DCTransferView*)object)->hide();
			((DCTransferView*)object)->setEnabled(FALSE);
			m_bTransferViewDockVisible = FALSE;
		}
		else if ( ((DCHubListManager*)object == g_pHubListManager) && (g_pHubListManager != 0) )
		{
			g_pHubListManager->hide();
			g_pHubListManager->setEnabled(FALSE);
		}
		else if ( ((DCHubSearch*)object == g_pHubSearch) && (g_pHubSearch != 0) )
		{
			g_pHubSearch->hide();
			g_pHubSearch->setEnabled(FALSE);
		}
		else if ( ((DCSpy*)object == g_pSpy) && (g_pSpy != 0) )
		{
			g_pSpy->hide();
			g_pSpy->setEnabled(FALSE);
		}
		else if ( ((DCUsersList*)object == g_pUsersList) && (g_pUsersList != 0) )
		{
			g_pUsersList->hide();
			g_pUsersList->setEnabled(FALSE);
		}
		else if ( ((DCUpdateManager*)object == g_pUpdateManager) && (g_pUpdateManager != 0) )
		{
			g_pUpdateManager->hide();
			g_pUpdateManager->setEnabled(FALSE);
		}
	}
	else if((event->type() == QEvent::Close)&&((DCGuiApp*)object==this))
	{
		QCloseEvent* e=(QCloseEvent*)event;

		if ( slotFileQuit() == FALSE ) {
			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: ")+CUtils::GetTransferString(e->m_pDownloadManagerInfo->Rate()).Data()+\
			QString(" DL: ")+\
			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 )
		{
			int id;
			QPopupMenu *m;

			m = new QPopupMenu(this);

			DCMenuHandler::InsertMenu( m, emiRESET );

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

			delete m;

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

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

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

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

	// primitive horizontal tiling
	QWidgetList windows = pWorkspace->windowList();
	if ( !windows.count() )
		return;

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

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

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

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

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

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

	for ( i = 0; i < pWorkspace->windowList().count(); i++ )
	{
		if ( pWorkspace->windowList().at(i)->isVisible() )
			pWorkspace->windowList().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->area()!=0));
	
	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->area()!=0));

	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->area()!=0));

	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;
	DCDialogAbout * dlg;
	ulonglong up = CSocket::m_Traffic.GetTraffic(ettTX);
	ulonglong down = CSocket::m_Traffic.GetTraffic(ettRX);
	float ratio = 0;
	
	if ( down > 0 )
	{
		ratio = (double) up / (double) down;
	}
	
	dlg = new DCDialogAbout(this);
	
	s  = dlg->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 += ")";

	dlg->TextLabel_VERSION->setText( "Valknut " VERSION );
	dlg->PixmapLabel_ICON->setPixmap( g_pIconLoader->GetPixmap(eiGLOBE) );
	
	dlg->TextLabel2->setText( s );

	dlg->TextEdit_AUTHORS->append(g_sAboutAuthors);
	dlg->TextEdit_AUTHORS->setCursorPosition(0,0);

	// load license file
	QFile f(g_pConfig->GetValknutDataPath() + DIRSEPARATOR + "COPYING");
	
	if ( f.open(IO_ReadOnly) == TRUE )
	{
		QTextStream t( &f );
		t.setEncoding(QTextStream::UnicodeUTF8);
		dlg->TextEdit_LICENSE->setText( t.read() );
	}
	else
	{
		dlg->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 * pr = new QProcess();
		QByteArray buf;
		pr->addArgument(g_pConfig->GetBrowser().Data());
		pr->addArgument("http://wxdcgui.sourceforge.net/doc/manual.html");
		pr->launch(buf);
		delete pr;
	}
}

/** 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 * w )
{
}

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

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

	pWindowMenu->insertSeparator();

	QWidgetList windows = pWorkspace->windowList();

	c = 0;

	for ( int i = 0; i < int(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, pWorkspace->activeWindow() == windows.at(i) );
			c++;
		}
	}

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

/** */
void DCGuiApp::windowMenuActivated( int id )
{
	QWidget* w = pWorkspace->windowList().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( QWidget * widget )
{
	if ( widget != 0 )
	{
		if ( widget->isMinimized() )
		{
			widget->setEnabled(TRUE);
			widget->showNormal();
		}
		else if ( widget->isVisible() )
		{
			if ( pWorkspace->activeWindow() == widget )
			{
				widget->setEnabled(FALSE);
				widget->hide();
			}
			else
			{
				widget->setEnabled(TRUE);
				widget->setFocus();
			}
		}
		else if ( widget->isMaximized() )
		{
			widget->setEnabled(TRUE);
			widget->showMaximized();
		}
		else
		{
			widget->setEnabled(TRUE);
			widget->show();
		}
	}
}

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

	showMDIWidget(g_pHubListManager);

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

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

	showMDIWidget(g_pHubSearch);

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

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

	showMDIWidget(g_pSpy);

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

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

	showMDIWidget(g_pUsersList);

	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);
		
		statusBar()->message(tr("Ready."));
	}
	else
	{
		QMessageBox::information(
			this,
			tr("Update Manager"),
			tr("The update manager is disabled."),
			QMessageBox::Ok,
			QMessageBox::NoButton,
			QMessageBox::NoButton
		);
	}
}

/** show the tray menu icon */
void DCGuiApp::slotTrayMenu( const QPoint&, int i )
{
	int id;

	QPopupMenu *m;

	if ( i == RightButton )
	{
		m = new QPopupMenu(this);

		DCMenuHandler::InsertMenu( m, emiUSER_CAPTION, FALSE, "Valknut" );
		DCMenuHandler::InsertMenu( m, emiSEPARATOR );
		DCMenuHandler::InsertMenu( m, emiEXIT );

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

		delete m;

		if ( id == emiEXIT )
		{
			slotFileQuit();
		}
	}
	else
	{
		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 );
		}
	}
}
