/****************************************************************************
** Dooble - The Secure Internet Web Browser
**
** Copyright (c) 2008, 2009, 2010 Alexis Megas, 
** Gunther van Dooble, and the Dooble Team. 
** All rights reserved.
**
** License: GPL2 only:
** 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; version 2 of the License only.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
** or see here: http://www.gnu.org/licenses/gpl.html
**
** For the WebKit library, please see: http://webkit.org.
**
** THE CODE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY
** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
** IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS APPLICATION, EVEN IF ADVISED
** OF THE POSSIBILITY OF SUCH DAMAGE.
**
** Please report all praise, requests, bugs, and problems to the project
** team and administrators: http://sf.net/projects/dooble.
**
** You can find us listed at our project page. New team members are welcome.
** The name of the authors should not be used to endorse or promote products
** derived from Dooble without specific prior written permission.
** If you use this code for other projects, please let us know.
**
** Web sites:
**   http://dooble.net/projects/dooble
**   http://dooble.sf.net
**   http://www.getadooble.com
****************************************************************************/

#include <QDir>
#include <QDebug>
#include <QPrinter>
#include <QProcess>
#include <QLineEdit>
#include <QSettings>
#include <QSplitter>
#include <QSqlQuery>
#include <QWebFrame>
#include <QClipboard>
#include <QFileDialog>
#include <QMessageBox>
#include <QTranslator>
#include <QApplication>
#include <QPrintDialog>
#include <QSqlDatabase>
#include <QNetworkReply>
#include <QAuthenticator>
#include <QDesktopServices>
#include <QPrintPreviewDialog>

#include "dooble.h"
#include "dsettings.h"
#include "dpagesourcewindow.h"
#include "ui_passwordPrompt.h"

static int doobleCounter = 0;
static dsettings *settingsWindow = 0;
static ddownloadwindow *downloadWindow = 0;

int main(int argc, char *argv[])
{
  QApplication qapp(argc, argv);

  /*
  ** Clear the clipboard.
  */

  QApplication::clipboard()->clear();

  /*
  ** Configure translations.
  */

  QTranslator qtTranslator;

  qtTranslator.load("qt_" + QLocale::system().name(), "translations");
  qapp.installTranslator(&qtTranslator);

  QTranslator myappTranslator;

  myappTranslator.load("dooble_" + QLocale::system().name(),
		       "translations");
  qapp.installTranslator(&myappTranslator);

#ifdef Q_WS_WIN
  QProcess::startDetached("startYACY.bat");
  QProcess::startDetached("RetroLocal.exe");
  QProcess::startDetached("offsystem.exe");
#endif
#ifdef Q_WS_MAC
  QProcess::startDetached("startYACY.command");
#else
  QProcess::startDetached("./startYACY.sh");
#endif

  QDir homeDir(QDir::home());

  homeDir.mkdir(".dooble");
  QWebSettings::globalSettings()->setIconDatabasePath
    (QDir::homePath() + "/.dooble");

  /*
  ** Set application attributes.
  */

  QCoreApplication::setApplicationName("Dooble");
  QCoreApplication::setApplicationVersion("0.09.01");
  QCoreApplication::setOrganizationName("Dooble");
  QCoreApplication::setOrganizationDomain("dooble.sf.net");

  /*
  ** Remove old configuration settings.
  */

  QSettings settings;

  settings.remove("mainWindow/pos");
  settings.remove("mainWindow/size");
  settings.remove("downloadWindow/pos");
  settings.remove("downloadWindow/size");
  settings.remove("settingsWindow/size");
  settings.remove("settingsWindow/browsingProxyEnabled");
  settings.remove("settingsWindow/downloadProxyEnabled");

  QList<QString> list(settings.allKeys());
  QMutableListIterator<QString> it(list);

  while(it.hasNext())
    if(it.next().startsWith("settingsWindow/backgroundImage"))
      settings.remove(it.value());

  list.clear();

  /*
  ** We need to set this before creating some of the support windows.
  */

  if(!settings.contains("iconSet"))
    settings.setValue("iconSet",
		      QString("%1/%2").arg(QDir::currentPath()).
		      arg("Icons/nuvola/configuration.cfg"));

  if(!settings.contains("settingsWindow/iconSet1"))
    settings.setValue("settingsWindow/iconSet1", settings.value("iconSet"));

  QWebSettings::globalSettings()->setAttribute
    (QWebSettings::JavaEnabled,
     settings.value("settingsWindow/javaEnabled", false).toBool());
  QWebSettings::globalSettings()->setAttribute
    (QWebSettings::JavascriptEnabled,
     settings.value("settingsWindow/javascriptEnabled", true).toBool());
  QWebSettings::globalSettings()->setAttribute
    (QWebSettings::JavascriptCanOpenWindows,
     settings.value("settingsWindow/javascriptAllowNewWindows",
		    false).toBool());
  QWebSettings::globalSettings()->setAttribute
    (QWebSettings::AutoLoadImages, true);
  downloadWindow = new ddownloadwindow();
  settingsWindow = new dsettings();

  dooble *dbl = 0;
  QString urlText = QString("%1/Tab/Default/search.html").arg
    (QDir::currentPath());

  if(argc > 1)
    {
      if(QFile(argv[1]).exists() && QFileInfo(argv[1]).isReadable())
	dbl = new dooble(QUrl::fromLocalFile(argv[1]));
      else
	dbl = new dooble(QUrl(argv[1]));
    }
  else
    dbl = new dooble(QUrl::fromLocalFile(urlText));

  qapp.connect(&qapp, SIGNAL(lastWindowClosed(void)), dbl,
	       SLOT(slotQuit(void)));
  return qapp.exec();
}

void dooble::init(void)
{
  showFindFrame = false;
  doobleCounter += 1;
  ui.setupUi(this);
#ifdef Q_WS_MAC
  ui.actionFull_Screen_Mode->setShortcut
    (QKeySequence(Qt::ControlModifier + Qt::Key_F11));
#endif
  ui.marker->setVisible(false);
  ui.restoreToolButton->setVisible(false);
  sbWidget = new QWidget(this);
  desktopWidget = new ddesktopwidget(this);
  sb.setupUi(sbWidget);
  sb.progressBar->setVisible(false);
  sb.statusLabel->setVisible(true);
  ui.findFrame->setVisible(false);
  ui.backToolButton->setMenu(new QMenu(this));
  ui.forwardToolButton->setMenu(new QMenu(this));
  connect(this,
	  SIGNAL(iconsChanged(void)),
	  downloadWindow,
	  SLOT(slotSetIcons(void)));
  connect(settingsWindow,
	  SIGNAL(fontChanged(const QFont &)),
	  this,
	  SLOT(slotFontChanged(const QFont &)));
  connect(settingsWindow,
	  SIGNAL(iconsChanged(void)),
	  this,
	  SLOT(slotSetIcons(void)));
  connect(this,
	  SIGNAL(iconsChanged(void)),
	  ui.searchLineEdit,
	  SLOT(slotSetIcons(void)));
  connect(this,
	  SIGNAL(iconsChanged(void)),
	  ui.locationLineEdit,
	  SLOT(slotSetIcons(void)));
  connect(ui.locationLineEdit,
	  SIGNAL(loadPage(const QUrl &)),
	  this,
	  SLOT(slotLoadPage(const QUrl &)));
  connect(desktopWidget,
	  SIGNAL(backgroundImageChanged(void)),
	  this,
	  SLOT(slotChangeDesktopBackgrounds(void)));
  connect(downloadWindow, SIGNAL(saveUrl(const QUrl &)), this,
	  SLOT(slotSaveUrl(const QUrl &)));
  connect(ui.tabWidget, SIGNAL(currentChanged(int)), this,
	  SLOT(slotTabSelected(int)));
  connect(ui.actionNew_Tab, SIGNAL(triggered(void)), this,
	  SLOT(slotNewTab(void)));
  connect(ui.tabWidget, SIGNAL(createTab(void)), this,
	  SLOT(slotNewTab(void)));
  connect(ui.tabWidget, SIGNAL(openInNewWindow(const int)), this,
	  SLOT(slotOpenPageInNewWindow(const int)));
  connect(ui.actionNew_Window, SIGNAL(triggered(void)), this,
	  SLOT(slotNewWindow(void)));
  connect(ui.actionOpen_URL, SIGNAL(triggered(void)), this,
	  SLOT(slotOpenUrl(void)));
  connect(ui.actionClose_Tab, SIGNAL(triggered(void)), this,
	  SLOT(slotCloseTab(void)));
  connect(ui.tabWidget, SIGNAL(closeTab(const int)), this,
	  SLOT(slotCloseTab(const int)));
  connect(ui.actionClose_Window, SIGNAL(triggered(void)), this,
	  SLOT(slotClose(void)));
  connect(ui.actionQuit, SIGNAL(triggered(void)), this,
	  SLOT(slotQuit(void)));
  connect(ui.locationLineEdit->menu(), SIGNAL(triggered(QAction *)),
	  this, SLOT(slotLoadPage(QAction *)));
  connect(ui.locationLineEdit->goButton(), SIGNAL(clicked(void)),
	  this, SLOT(slotLoadPage(void)));
  connect(ui.locationLineEdit, SIGNAL(textChanged(const QString &)),
	  this, SLOT(slotTextChanged(const QString &)));
  connect(ui.locationLineEdit, SIGNAL(returnPressed(void)), this,
	  SLOT(slotLoadPage(void)));
  connect(ui.locationLineEdit, SIGNAL(copySignal(void)), this,
	  SLOT(slotTextCopied(void)));
  connect(ui.searchLineEdit, SIGNAL(copySignal(void)), this,
	  SLOT(slotTextCopied(void)));
  connect(ui.backToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotBack(void)));
  connect(ui.forwardToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotForward(void)));
  connect(ui.reloadToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotReload(void)));
  connect(ui.actionReload, SIGNAL(triggered(void)), this,
	  SLOT(slotReload(void)));
  connect(ui.stopToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotStop(void)));
  connect(ui.actionStop, SIGNAL(triggered(void)), this,
	  SLOT(slotStop(void)));
  connect(ui.homeToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotGoHome(void)));
  connect(ui.searchLineEdit, SIGNAL(returnPressed(void)), this,
	  SLOT(slotSearch(void)));
  connect(ui.searchLineEdit->findButton(), SIGNAL(clicked(void)), this,
	  SLOT(slotSearch(void)));
  connect(ui.actionAbout_Dooble, SIGNAL(triggered(void)), this,
	  SLOT(slotAbout(void)));
  connect(ui.actionSave_Page, SIGNAL(triggered(void)), this,
	  SLOT(slotSavePage(void)));
  connect(ui.actionDownloads, SIGNAL(triggered(void)), this,
	  SLOT(slotDisplayDownloadWindow(void)));
  connect(ui.actionFind, SIGNAL(triggered(void)), this,
	  SLOT(slotShowFind(void)));
  connect(ui.actionPrint, SIGNAL(triggered(void)), this,
	  SLOT(slotPrint(void)));
  connect(ui.actionPrint_Preview, SIGNAL(triggered(void)), this,
	  SLOT(slotPrintPreview(void)));
  connect(ui.actionDesktop, SIGNAL(triggered(void)), this,
	  SLOT(slotShowDesktopTab(void)));
  connect(ui.actionPage_Source, SIGNAL(triggered(void)), this,
	  SLOT(slotShowPageSource(void)));
  connect(ui.actionSettings, SIGNAL(triggered(void)), this,
	  SLOT(slotShowSettingsWindow(void)));
  connect(ui.hideFindToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotHideFind(void)));
  connect(ui.findLineEdit, SIGNAL(returnPressed(void)), this,
	  SLOT(slotFind(void)));
  connect(ui.findLineEdit, SIGNAL(textChanged(const QString &)), this,
	  SLOT(slotFind(const QString &)));
  connect(ui.desktopToolButton, SIGNAL(clicked(void)), this,
	  SLOT(slotShowDesktopTab(void)));
  connect(ui.actionStatusbar, SIGNAL(triggered(void)), this,
	  SLOT(slotStatusBarDisplay(void)));
  connect(ui.actionOpen_Directory, SIGNAL(triggered(void)), this,
	  SLOT(slotOpenDirectory(void)));
  connect(ui.actionZoom_In, SIGNAL(triggered(void)), this,
	  SLOT(slotViewZoomIn(void)));
  connect(ui.actionZoom_Out, SIGNAL(triggered(void)), this,
	  SLOT(slotViewZoomOut(void)));
  connect(ui.actionReset_Zoom, SIGNAL(triggered(void)), this,
	  SLOT(slotViewResetZoom(void)));
  connect(ui.actionZoom_Text_Only, SIGNAL(toggled(bool)), this,
	  SLOT(slotViewZoomTextOnly(bool)));
  connect(ui.actionMy_Retrieved_Files, SIGNAL(triggered(void)), this,
	  SLOT(slotOpenMyRetrievedFiles(void)));
  connect(ui.actionCopy, SIGNAL(triggered(void)), this,
	  SLOT(slotCopy(void)));
  connect(ui.actionPaste, SIGNAL(triggered(void)), this,
	  SLOT(slotPaste(void)));
  connect(ui.actionSelect_All_Content, SIGNAL(triggered(void)), this,
	  SLOT(slotSelectAllContent(void)));
  connect(ui.actionFull_Screen_Mode, SIGNAL(triggered(void)), this,
	  SLOT(slotFullScreenMode(void)));
  connect(ui.marker, SIGNAL(markerEntered(void)), this,
	  SLOT(slotMarkerEntered(void)));
  connect(ui.restoreToolButton, SIGNAL(clicked(void)),
	  this, SLOT(slotFullScreenMode(void)));
  ui.actionZoom_Text_Only->setCheckable(true);
  ui.actionZoom_Text_Only->setChecked(false);
  ui.viewMenu->insertSeparator(ui.zoomMenu->menuAction());

  if(ui.historyMenu->actions().isEmpty())
    {
      QSettings settings;
      QSettings cfgSettings
	(settings.value("iconSet").toString(), QSettings::IniFormat);

      cfgSettings.beginGroup("mainWindow");

      QAction *action = ui.historyMenu->addAction
	(QIcon(cfgSettings.value("historyMenu").toString()),
	 tr("&Clear History"));

      action->setEnabled(false);
      connect(action, SIGNAL(triggered(void)), this,
	      SLOT(slotClearHistory(void)));
    }

  {
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "history");

    db.setDatabaseName(QDir::homePath() + "/.dooble/history.db");

    if(db.open())
      {
	QSqlQuery query(db);

	query.exec("SELECT url, title FROM history");

	while(query.next())
	  {
	    if(ui.historyMenu->actions().size() == 1)
	      {
		ui.historyMenu->actions()[0]->setEnabled(true);
		ui.historyMenu->addSeparator();
	      }

	    QAction *action = 0;

	    action = ui.historyMenu->addAction(QIcon(),
					       query.value(1).toString());
	    action->setData(query.value(0).toString());
	    connect(action, SIGNAL(triggered(void)), this,
		    SLOT(slotHistoryActionTriggered(void)));
	  }
      }

    db.close();
  }

  QSqlDatabase::removeDatabase("history");
  ui.forwardToolButton->setVisible(false);
  ui.backToolButton->setVisible(false);
  ui.stopToolButton->setVisible(false);
  ui.reloadToolButton->setVisible(false);
  ui.homeToolButton->setVisible(false);
  ui.searchLineEdit->setVisible(false);
  ui.locationLineEdit->setVisible(false);
  ui.editMenu->setEnabled(false);
  ui.viewMenu->setEnabled(false);
  ui.historyMenu->setEnabled(false);
  ui.actionPrint->setEnabled(false);
  ui.actionPrint_Preview->setEnabled(false);
  ui.actionOpen_URL->setEnabled(false);
  ui.actionSave_Page->setEnabled(false);
  ui.actionCopy->setEnabled(false);

  QClipboard *clipboard = QApplication::clipboard();

  if(clipboard && !clipboard->text().isEmpty())
    ui.actionPaste->setEnabled(true);
  else
    ui.actionPaste->setEnabled(false);

  for(int i = 0; i < ui.tabWidget->count(); i++)
    if(ui.tabWidget->tabData(i).toString() == "Desktop")
      {
	ui.desktopToolButton->setVisible(false);
	break;
      }

  QFont font;
  QSettings settings;

  if(font.fromString(settings.value("settingsWindow/globalFont").toString()))
    {
      QApplication *qapp = qobject_cast<QApplication *>
	(QApplication::instance());

      if(qapp)
	qapp->setFont(font);

      foreach(QWidget *widget, findChildren<QWidget *> ())
	widget->setFont(font);

      menuBar()->setFont(font);

      foreach(QMenu *menu, menuBar()->findChildren<QMenu *> ())
	foreach(QAction *action, menu->actions())
	  action->setFont(font);
    }

  /*
  ** According to Qt documentation, resize() followed by move() should
  ** be used to restore a window's geometry. Actual results may vary.
  */

  if(settings.contains("mainWindow/geometry"))
    setGeometry(settings.value("mainWindow/geometry").toRect());

  statusBar()->addPermanentWidget(sbWidget, 100);
  statusBar()->setStyleSheet("QStatusBar::item {"
			     "border: none; "
			     "}");
  statusBar()->setMaximumHeight(sbWidget->height());
  statusBar()->setVisible
    (settings.value("mainWindow/statusbarDisplay", true).toBool());
  ui.actionStatusbar->setChecked(!statusBar()->isHidden());
  slotSetIcons();
}

dooble::dooble(void):QMainWindow()
{
  init();

  QSettings settings;

  if(!settings.value("settingsWindow/displayDesktopCheckBox", false).toBool())
    {
      closeDesktop(); // Close the Desktop tab.
      QApplication::sendPostedEvents(this, 0);
    }
  else
    slotShowDesktopTab();

  show();
}

dooble::dooble(const QUrl &url):
  QMainWindow(), dest_url_(url.toString(QUrl::StripTrailingSlash))
{
  init();
  newTab(url);

  QSettings settings;

  if(!settings.value("settingsWindow/displayDesktopCheckBox", false).toBool())
    {
      closeDesktop(); // Close the Desktop tab.
      QApplication::sendPostedEvents(this, 0);
    }
  else
    slotShowDesktopTab();

  show();
}

dooble::dooble(dview *p, const QString &tabTitle):
  QMainWindow(),
  dest_url_(p ? p->url().toString(QUrl::StripTrailingSlash) : "")
{
  init();
  newTab(p, tabTitle);

  QSettings settings;

  if(!settings.value("settingsWindow/displayDesktopCheckBox", false).toBool())
    {
      closeDesktop(); // Close the Desktop tab.
      QApplication::sendPostedEvents(this, 0);
    }
  else
    slotShowDesktopTab();

  show();
}

dooble::~dooble()
{
  doobleCounter -= 1;
}

void dooble::slotSetIcons(void)
{
  QSettings settings;
  QSettings cfgSettings(settings.value("iconSet").toString(),
			QSettings::IniFormat);

  cfgSettings.beginGroup("mainWindow");
  ui.backToolButton->setIcon
    (QIcon(cfgSettings.value("backToolButton").toString()));
  ui.forwardToolButton->setIcon
    (QIcon(cfgSettings.value("forwardToolButton").toString()));
  ui.reloadToolButton->setIcon
    (QIcon(cfgSettings.value("reloadToolButton").toString()));
  ui.stopToolButton->setIcon
    (QIcon(cfgSettings.value("stopToolButton").toString()));
  ui.homeToolButton->setIcon
    (QIcon(cfgSettings.value("homeToolButton").toString()));
  ui.hideFindToolButton->setIcon
    (QIcon(cfgSettings.value("hideFindToolButton").toString()));
  ui.actionNew_Tab->setIcon
    (QIcon(cfgSettings.value("actionNew_Tab").toString()));
  ui.actionNew_Window->setIcon
    (QIcon(cfgSettings.value("actionNew_Window").toString()));
  ui.actionOpen_URL->setIcon
    (QIcon(cfgSettings.value("actionOpen_URL").toString()));
  ui.actionClose_Tab->setIcon
    (QIcon(cfgSettings.value("actionClose_Tab").toString()));
  ui.actionClose_Window->setIcon
    (QIcon(cfgSettings.value("actionClose_Window").toString()));
  ui.actionSave_Page->setIcon
    (QIcon(cfgSettings.value("actionSave_Page").toString()));
  ui.actionPrint->setIcon
    (QIcon(cfgSettings.value("actionPrint").toString()));
  ui.actionPrint_Preview->setIcon
    (QIcon(cfgSettings.value("actionPrint_Preview").toString()));
  ui.actionQuit->setIcon
    (QIcon(cfgSettings.value("actionQuit").toString()));
  ui.actionFind->setIcon
    (QIcon(cfgSettings.value("actionFind").toString()));
  ui.actionReload->setIcon
    (QIcon(cfgSettings.value("actionReload").toString()));
  ui.actionStop->setIcon
    (QIcon(cfgSettings.value("actionStop").toString()));
  ui.actionDesktop->setIcon
    (QIcon(cfgSettings.value("actionDesktop").toString()));
  ui.actionPage_Source->setIcon
    (QIcon(cfgSettings.value("actionPage_Source").toString()));
  ui.actionDownloads->
    setIcon(QIcon(cfgSettings.value("actionDownloads").toString()));
  ui.actionSettings->setIcon
    (QIcon(cfgSettings.value("actionSettings").toString()));
  ui.actionAbout_Dooble->
    setIcon(QIcon(cfgSettings.value("actionAbout_Dooble").toString()));
  ui.desktopToolButton->
    setIcon(QIcon(cfgSettings.value("desktopToolButton").toString()));
  ui.actionOpen_Directory->setIcon
    (QIcon(cfgSettings.value("actionOpen_Directory").toString()));
  ui.actionMy_Retrieved_Files->setIcon
    (QIcon(cfgSettings.value("actionMy_Retrieved_Files").toString()));
  ui.restoreToolButton->setIcon
    (QIcon(cfgSettings.value("restoreToolButton").toString()));
  ui.actionCopy->setIcon
    (QIcon(cfgSettings.value("actionCopy").toString()));
  ui.actionPaste->setIcon
    (QIcon(cfgSettings.value("actionPaste").toString()));
  ui.actionSelect_All_Content->setIcon
    (QIcon(cfgSettings.value("actionSelect_All_Content").toString()));
  ui.zoomMenu->setIcon
    (QIcon(cfgSettings.value("zoomMenu").toString()));
  ui.actionFull_Screen_Mode->setIcon
    (QIcon(cfgSettings.value("actionFull_Screen_Mode").toString()));

  /*
  ** The 0th tab is not necessarily the Desktop.
  */

  for(int i = 0; i < ui.tabWidget->count(); i++)
    if(ui.tabWidget->tabData(i).toString() == "Desktop")
      {
	ui.tabWidget->setTabIcon
	  (i, QIcon(cfgSettings.value("tabWidget").toString()));
	break;
      }

  setWindowIcon(QIcon(cfgSettings.value("windowIcon").toString()));
  emit iconsChanged();
}

void dooble::newTabInit(dview *p, const QString &tabTitle)
{
  if(!p)
    return;

  connect(p, SIGNAL(urlChanged(const QUrl &)), this,
	  SLOT(slotUrlChanged(const QUrl &)));
  connect(p, SIGNAL(titleChanged(const QString &)), this,
	  SLOT(slotTitleChanged(const QString &)));
  connect(p, SIGNAL(loadFinished(bool)), this,
	  SLOT(slotLoadFinished(bool)));
  connect(p, SIGNAL(loadProgress(int)), this,
	  SLOT(slotLoadProgress(int)));
  connect(p, SIGNAL(iconChanged(void)), this,
	  SLOT(slotIconChanged(void)));
  connect(p, SIGNAL(loadStarted(void)), this,
	  SLOT(slotLoadStarted(void)));
  connect(p, SIGNAL(openLinkInNewTab(const QUrl &)), this,
	  SLOT(slotOpenLinkInNewTab(const QUrl &)));
  connect(p, SIGNAL(openLinkInNewWindow(const QUrl &)), this,
	  SLOT(slotOpenLinkInNewWindow(const QUrl &)));
  connect(p, SIGNAL(copyLink(const QUrl &)), this,
	  SLOT(slotCopyLink(const QUrl &)));
  connect(p, SIGNAL(saveUrl(const QUrl &)), this,
	  SLOT(slotSaveUrl(const QUrl &)));
  connect(p, SIGNAL(viewImage(const QUrl &)), this,
	  SLOT(slotLoadPage(const QUrl &)));
  connect(p->page(),
	  SIGNAL(linkHovered(const QString &, const QString &,
			     const QString &)),
	  this,
	  SLOT(slotLinkHovered(const QString &, const QString &,
			       const QString &)));
  connect(p->page(),
	  SIGNAL(unsupportedContent(QNetworkReply *)),
	  this,
	  SLOT(slotUnsupportedContent(QNetworkReply *)));
  connect(p->page(),
	  SIGNAL(linkClicked(const QUrl &)),
	  this,
	  SLOT(slotLoadPage(const QUrl &)));
  connect(p->page()->networkAccessManager(),
	  SIGNAL(authenticationRequired(QNetworkReply *, QAuthenticator *)),
	  this,
	  SLOT(slotAuthenticationRequired(QNetworkReply *, QAuthenticator *)));
  connect(p->page(), SIGNAL(windowCloseRequested(void)),
	  this, SLOT(slotClose(void)));
  connect(this,
	  SIGNAL(clearHistory(void)),
	  p,
	  SLOT(slotClearHistory(void)));
  connect(p, SIGNAL(viewEntered(void)), this,
	  SLOT(slotViewEntered(void)));
  connect(p, SIGNAL(selectionChanged(const QString &)),
	  this, SLOT(slotSelectionChanged(const QString &)));
  connect(p, SIGNAL(textCopied(void)),
	  this, SLOT(slotTextCopied(void)));
  ui.tabWidget->addTab(p, p->icon(), tabTitle);

  QSettings settings;

  if(settings.value("settingsWindow/proceedToNewTab", true).toBool())
    ui.tabWidget->setCurrentWidget(p);

  sb.statusLabel->clear();
  ui.tabWidget->setTabsClosable(ui.tabWidget->count() > 1);
  ui.actionClose_Tab->setEnabled(ui.tabWidget->count() > 1);
  ui.tabWidget->cornerWidget(Qt::TopRightCorner)->setEnabled
    (ui.tabWidget->count() > 1);
}

dview *dooble::newTab(dview *p, const QString &tabTitle)
{
  if(p)
    {
      p->setParent(this);
      newTabInit(p, tabTitle);
    }

  return p;
}

dview *dooble::newTab(const QUrl &url)
{
  dview *p = new dview(this);

  newTabInit(p, tr("(Untitled)"));
  p->load(url);
  ui.zoomMenu->setEnabled(!p->isDir() && !p->isFtp());
  ui.actionFind->setEnabled(!p->isDir() && !p->isFtp());
  ui.actionSelect_All_Content->setEnabled(!p->isDir() && !p->isFtp());

  if(p->isDir() || p->isFtp())
    ui.findFrame->setVisible(false);
  else
    ui.findFrame->setVisible(showFindFrame);

  return p;
}

void dooble::slotQuit(void)
{
#ifdef Q_WS_WIN
  QProcess process;

  process.start("taskkill /F /IM offsystem.exe");
  QProcess::startDetached("stopYACY.bat");
#endif
#ifdef Q_WS_MAC
  QProcess::startDetached("stopYACY.command");
#else
  QProcess::startDetached("./stopYACY.sh");
#endif
  downloadWindow->deleteLater();
  saveSettings();

  QSettings settings;

  if(!settings.value("settingsWindow/saveHistory", true).toBool() ||
     settings.value
     ("settingsWindow/saveHistoryCheckedId", 0).toInt() == 0)
    {
      {
	QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "history");

	db.setDatabaseName(QDir::homePath() + "/.dooble/history.db");

	if(db.open())
	  {
	    QSqlQuery query(db);

	    query.exec("DELETE FROM history");
	  }

	db.close();
      }

      QSqlDatabase::removeDatabase("history");
    }

  foreach(QWidget *widget, QApplication::allWidgets())
    if(qobject_cast<dooble *> (widget))
      qobject_cast<dooble *> (widget)->deleteLater();

  QApplication::instance()->exit(0);
}

void dooble::saveSettings(void)
{
  if(!isFullScreen())
    {
      QSettings settings;

      settings.setValue("mainWindow/geometry", geometry());
    }
}

void dooble::loadPage(const QUrl &url)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    {
      int index = -1;
      QString str(url.toString(QUrl::StripTrailingSlash).trimmed());
      QString scheme(QUrl(str).scheme().toLower());

      if(str.isEmpty())
        str = "http://localhost:8080/yacysearch.html";

      /*
      ** Replace the user's text with an improved version.
      */

      if((index = ui.locationLineEdit->findText
	  (url.toString(QUrl::StripTrailingSlash))) > -1)
	ui.locationLineEdit->setItemText(index, str);

      ui.locationLineEdit->blockSignals(true);
      ui.locationLineEdit->setText(str);
      ui.locationLineEdit->blockSignals(false);
      sb.progressBar->setVisible(true);
      ui.stopToolButton->setEnabled(true);
      ui.actionStop->setEnabled(true);
      ui.zoomMenu->setEnabled(!QFileInfo(QUrl(str).toLocalFile()).isDir() &&
			      QUrl(str).scheme().toLower() != "ftp");
      ui.actionSelect_All_Content->setEnabled
	(!QFileInfo(QUrl(str).toLocalFile()).isDir() &&
	 QUrl(str).scheme().toLower() != "ftp");
      ui.tabWidget->setTabText(ui.tabWidget->indexOf(p), tr("Loading..."));
      p->load(QUrl(str));
      ui.locationLineEdit->setIcon(p->icon());
      ui.actionFind->setEnabled(!p->isDir() && !p->isFtp());

      if(p->isDir() || p->isFtp())
	ui.findFrame->setVisible(false);
      else
	ui.findFrame->setVisible(showFindFrame);
    }
}

void dooble::slotLoadPage(void)
{
  loadPage(QUrl::fromUserInput(ui.locationLineEdit->text().trimmed()));
}

void dooble::slotLoadPage(bool)
{
  loadPage(QUrl(dest_url_));
}

void dooble::slotLoadPage(const QUrl &url)
{
  loadPage(url);
}

void dooble::slotLoadPage(QAction *action)
{
  if(action)
    loadPage(QUrl(action->text()));
}

void dooble::slotNewTab(void)
{
  QUrl url = QUrl::fromLocalFile
    (QString("%1/Tab/Default/search.html").arg(QDir::currentPath()));

  newTab(url);
}

void dooble::slotNewWindow(void)
{
  QUrl url = QUrl::fromLocalFile
    (QString("%1/Tab/Default/search.html").arg(QDir::currentPath()));

  Q_UNUSED(new dooble(url));
}

void dooble::slotClose(void)
{
  close();
}

void dooble::closeEvent(QCloseEvent *event)
{
  if(event)
    event->accept();

  deleteLater();

  if(doobleCounter <= 1)
    slotQuit();
}

void dooble::slotStop(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    p->stop();

  sb.progressBar->setVisible(false);
  ui.stopToolButton->setEnabled(false);
  ui.actionStop->setEnabled(false);
}

void dooble::slotReload(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    {
      sb.progressBar->setVisible(true);
      ui.stopToolButton->setEnabled(true);
      ui.actionStop->setEnabled(true);
      p->reload();
    }
}

void dooble::slotBack(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    {
      ui.forwardToolButton->setEnabled(p->canGoForward());
      sb.progressBar->setVisible(true);
      ui.stopToolButton->setEnabled(true);
      ui.actionStop->setEnabled(true);
      p->back();
    }
}

void dooble::slotForward(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    {
      ui.backToolButton->setEnabled(p->canGoBack());
      sb.progressBar->setVisible(true);
      ui.stopToolButton->setEnabled(true);
      ui.actionStop->setEnabled(true);
      p->forward();
    }
}

void dooble::slotTabSelected(const int index)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->widget(index));

  if(p)
    {
      ui.forwardToolButton->setVisible(true);
      ui.backToolButton->setVisible(true);
      ui.stopToolButton->setVisible(true);
      ui.reloadToolButton->setVisible(true);
      ui.homeToolButton->setVisible(true);
      ui.searchLineEdit->setVisible(true);
      ui.locationLineEdit->setVisible(true);
      ui.reloadToolButton->setEnabled(true);
      ui.homeToolButton->setEnabled(true);
      ui.searchLineEdit->setEnabled(true);
      ui.editMenu->setEnabled(true);
      ui.viewMenu->setEnabled(true);
      ui.historyMenu->setEnabled(true);
      ui.actionPrint->setEnabled(true);
      ui.actionPrint_Preview->setEnabled(true);
      ui.actionOpen_URL->setEnabled(true);
      ui.actionSave_Page->setEnabled(true);

      if(p->title().isEmpty())
	setWindowTitle(tr("Dooble Web Browser"));
      else
	setWindowTitle(p->title() + tr(" - Dooble Web Browser"));

      sb.progressBar->setVisible(!p->isLoaded());
      sb.progressBar->setValue(p->progress());
      ui.stopToolButton->setEnabled(!p->isLoaded());
      ui.actionStop->setEnabled(!p->isLoaded());
      ui.backToolButton->setEnabled(p->canGoBack());
      ui.forwardToolButton->setEnabled(p->canGoForward());
      ui.locationLineEdit->setIcon(p->icon());
      ui.locationLineEdit->blockSignals(true);
      ui.locationLineEdit->setText
	(p->url().toString(QUrl::StripTrailingSlash));
      ui.locationLineEdit->blockSignals(false);
      prepareNavigationButtonMenus(p);
      statusBar()->setVisible(ui.actionStatusbar->isChecked() &&
			      !isFullScreen());

      if(p->isDir() || p->isFtp())
	ui.findFrame->setVisible(false);
      else
	ui.findFrame->setVisible(showFindFrame);

      ui.actionFind->setEnabled(!p->isDir() && !p->isFtp());
      ui.zoomMenu->setEnabled(!p->isDir() && !p->isFtp());
      ui.actionSelect_All_Content->setEnabled(!p->isDir() && !p->isFtp());
    }
  else
    {
      setWindowTitle(tr("Dooble Web Browser"));
      ui.forwardToolButton->setVisible(false);
      ui.backToolButton->setVisible(false);
      ui.stopToolButton->setVisible(false);
      ui.reloadToolButton->setVisible(false);
      ui.homeToolButton->setVisible(false);
      ui.searchLineEdit->setVisible(false);
      ui.locationLineEdit->setVisible(false);
      ui.editMenu->setEnabled(false);
      ui.viewMenu->setEnabled(false);
      ui.historyMenu->setEnabled(false);
      ui.actionPrint->setEnabled(false);
      ui.actionPrint_Preview->setEnabled(false);
      ui.actionOpen_URL->setEnabled(false);
      ui.actionSave_Page->setEnabled(false);
      ui.searchLineEdit->clear();
      ui.findFrame->setVisible(false);
      sb.statusLabel->clear();
      sb.progressBar->setValue(0);
      sb.progressBar->setVisible(false);
      statusBar()->setVisible(false);
    }
}

void dooble::slotTextChanged(const QString &text)
{
  dest_url_ = text;
}

void dooble::slotUrlChanged(const QUrl &url)
{
  QString urlText(url.toString(QUrl::StripTrailingSlash));

  if(ui.locationLineEdit->findText(urlText) == -1)
    ui.locationLineEdit->addItem(urlText);

  dview *p = qobject_cast<dview *> (sender());

  if(p == qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    {
      ui.locationLineEdit->blockSignals(true);
      ui.locationLineEdit->setText(urlText);
      ui.locationLineEdit->blockSignals(false);
    }
}

void dooble::slotTitleChanged(const QString &title_)
{
  dview *p = qobject_cast<dview *> (sender());
  QString title(title_.trimmed());

  if(p == qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    {
      if(title_.isEmpty())
	setWindowTitle(tr("Dooble Web Browser"));
      else
	setWindowTitle(title + tr(" - Dooble Web Browser"));
    }

  if(p)
    {
      if(title.isEmpty())
	/*
	** The tab's title will be set to the URL.
	*/

	title = p->url().toString(QUrl::StripTrailingSlash);

      /*
      ** Restrict the size of the tab.
      */

      if(title.length() > MAX_NUMBER_OF_TAB_TITLE_CHARACTERS)
	title = title.mid(0, MAX_NUMBER_OF_TAB_TITLE_CHARACTERS - 3) + "...";
      else if(title.length() < MAX_NUMBER_OF_TAB_TITLE_CHARACTERS)
	title = title.leftJustified(MAX_NUMBER_OF_TAB_TITLE_CHARACTERS, ' ');

      ui.tabWidget->setTabText(ui.tabWidget->indexOf(p),
			       title.replace("&", "&&"));
      ui.tabWidget->setTabToolTip(ui.tabWidget->indexOf(p),
				  p->title());
    }
}

void dooble::slotIconChanged(void)
{
  dview *p = qobject_cast<dview *> (sender());

  if(p == qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    ui.locationLineEdit->setIcon(p->icon());

  if(p)
    {
      int index = ui.locationLineEdit->findText
	(p->url().toString(QUrl::StripTrailingSlash));

      if(index > -1)
	ui.locationLineEdit->setItemIcon(index, p->icon());

      ui.tabWidget->setTabIcon(ui.tabWidget->indexOf(p), p->icon());
    }
}

void dooble::slotLoadProgress(int progress)
{
  dview *p = qobject_cast<dview *> (sender());

  if(p == qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    {
      sb.progressBar->setValue(progress >= 0 ? progress : 0);
      ui.locationLineEdit->setIcon(p->icon());
    }

  if(p)
    {
      int index = ui.locationLineEdit->findText
	(p->url().toString(QUrl::StripTrailingSlash));

      if(index > -1)
	ui.locationLineEdit->setItemIcon(index, p->icon());

      ui.tabWidget->setTabIcon(ui.tabWidget->indexOf(p), p->icon());
    }
}

void dooble::slotUnsupportedContent(QNetworkReply *reply)
{
  Q_UNUSED(reply);
}

void dooble::slotLoadFinished(bool ok)
{
  Q_UNUSED(ok);
  dview *p = qobject_cast<dview *> (sender());

  if(p == qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    {
      sb.progressBar->setVisible(false);
      ui.stopToolButton->setEnabled(false);
      ui.actionStop->setEnabled(false);
      ui.backToolButton->setEnabled(p->canGoBack());
      ui.forwardToolButton->setEnabled(p->canGoForward());
    }

  if(p && !p->title().isNull())
    {
      bool actionExists = false;
      QList<QAction *> actions = ui.historyMenu->actions();

      for(int i = 0; i < actions.size(); i++)
	if(actions.at(i)->data().toString() == p->url().toString
	   (QUrl::StripTrailingSlash))
	  {
	    actions.at(i)->setIcon(p->icon());
	    actionExists = true;
	    break;
	  }

      actions.clear();

      if(!actionExists)
	{
	  if(ui.historyMenu->actions().size() == 1)
	    {
	      ui.historyMenu->addSeparator();
	      ui.historyMenu->actions()[0]->setEnabled(true);
	    }

	  QString title(p->title());

	  if(title.isEmpty())
	    title = p->url().toString(QUrl::StripTrailingSlash);

	  if(title.length() > MAX_NUMBER_OF_MENU_TITLE_CHARACTERS)
	    title = title.mid(0, MAX_NUMBER_OF_MENU_TITLE_CHARACTERS - 3) +
	      "...";

	  if(title.contains("&"))
	    title = title.replace("&", "&&");

	  QAction *action = ui.historyMenu->addAction
	    (p->icon(), title, this,
	     SLOT(slotHistoryActionTriggered(void)));

	  if(action)
	    action->setData
	      (QVariant(p->url().toString(QUrl::StripTrailingSlash)));
	}

      saveHistoryItem(p->webHistory()->currentItem());
    }

  prepareNavigationButtonMenus(p);
}

void dooble::prepareNavigationButtonMenus(dview *p)
{
  if(!p)
    return;

  while(!ui.backToolButton->menu()->actions().isEmpty())
    ui.backToolButton->menu()->removeAction
      (ui.backToolButton->menu()->actions().takeFirst());

  QList<dwebhistoryitem> list(p->backItems(50));

  for(int i = 0; i < list.size(); i++)
    {
      QString title(list.at(i).title());

      if(title.length() > MAX_NUMBER_OF_MENU_TITLE_CHARACTERS)
	title = title.mid(0, MAX_NUMBER_OF_MENU_TITLE_CHARACTERS - 3) + "...";

      if(title.contains("&"))
	title = title.replace("&", "&&");

      QIcon icon(QWebSettings::iconForUrl(list.at(i).url()));

      if(icon.isNull())
	{
	  QSettings settings;
	  QSettings cfgSettings
	    (settings.value("iconSet").toString(), QSettings::IniFormat);

	  icon = QIcon(cfgSettings.value("mainWindow/emptyIcon").toString());
	}

      QAction *action = ui.backToolButton->menu()->addAction
	(icon, title, this, SLOT(slotHistoryActionTriggered(void)));

      if(action)
	action->setData
	  (QVariant(list.at(i).url().toString(QUrl::StripTrailingSlash)));
    }

  list.clear();

  while(!ui.forwardToolButton->menu()->actions().isEmpty())
    ui.forwardToolButton->menu()->removeAction
      (ui.forwardToolButton->menu()->actions().takeFirst());

  list = p->forwardItems(50);

  for(int i = 0; i < list.size(); i++)
    {
      QString title(list.at(i).title());

      if(title.length() > MAX_NUMBER_OF_MENU_TITLE_CHARACTERS)
	title = title.mid(0, MAX_NUMBER_OF_MENU_TITLE_CHARACTERS - 3) + "...";

      if(title.contains("&"))
	title = title.replace("&", "&&");

      QIcon icon(QWebSettings::iconForUrl(list.at(i).url()));

      if(icon.isNull())
	{
	  QSettings settings;
	  QSettings cfgSettings
	    (settings.value("iconSet").toString(), QSettings::IniFormat);

	  icon = QIcon(cfgSettings.value("mainWindow/emptyIcon").toString());
	}

      QAction *action = ui.forwardToolButton->menu()->addAction
	(icon, title, this, SLOT(slotHistoryActionTriggered(void)));

      if(action)
	action->setData
	  (QVariant(list.at(i).url().toString(QUrl::StripTrailingSlash)));
    }

  list.clear();
}

void dooble::slotGoHome(void)
{
  QSettings settings;

  settings.beginGroup("settingsWindow");

  QStringList allKeys = settings.allKeys();

  for(int i = 0; i < allKeys.size(); i++)
    {
      if(!allKeys[i].startsWith("url"))
	continue;

      QString value(settings.value(allKeys[i], "").toString().trimmed());

      if(value.endsWith("/"))
	value.remove(value.size() - 1);

      if(!value.isEmpty())
	{
	  bool urlFound = false;

	  foreach(dview *p, findChildren<dview *> ())
	    {
	      if(p->url().toString(QUrl::StripTrailingSlash) ==
		 QUrl::fromUserInput(value).toString(QUrl::StripTrailingSlash))
		{
		  urlFound = true;
		  break;
		}
	    }

	  if(!urlFound)
	    {
	      value = settings.value(allKeys[i], "").toString().trimmed();
	      newTab(QUrl::fromUserInput(value));
	    }
	}
    }

  allKeys.clear();
}

void dooble::closeTab(const int index)
{
  if(index > -1)
    {
      int count = 0;

      if((count = ui.tabWidget->count()) > 1)
	{
	  dview *p = qobject_cast<dview *> (ui.tabWidget->widget(index));

	  if(p)
	    {
	      p->stop();
	      p->deleteLater();
	    }
	  else
	    closeDesktop();

	  count -= 1;
	}

      ui.tabWidget->setTabsClosable(count > 1);
      ui.actionClose_Tab->setEnabled(count > 1);
      ui.tabWidget->cornerWidget(Qt::TopRightCorner)->setEnabled(count > 1);
      QApplication::sendPostedEvents(this, 0);
    }
}

void dooble::slotCloseTab(void)
{
  closeTab(ui.tabWidget->currentIndex());
}

void dooble::slotCloseTab(const int index)
{
  closeTab(index);
}

void dooble::slotOpenUrl(void)
{
  ui.locationLineEdit->setFocus();
  ui.locationLineEdit->selectAll();
  update();
}

void dooble::slotHistoryActionTriggered(void)
{
  QAction *action = qobject_cast<QAction *> (sender());

  if(action)
    loadPage(action->data().toString());
}

void dooble::slotLoadStarted(void)
{
  dview *p = qobject_cast<dview *> (sender());

  if(p == qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    {
      sb.statusLabel->clear();
      sb.progressBar->setVisible(true);
      ui.stopToolButton->setEnabled(true);
      ui.actionStop->setEnabled(true);
    }
}

void dooble::slotSearch(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    {
      QString urlText("");
      QString searchName(ui.searchLineEdit->type());

      if(searchName == "dooble search")
	urlText = QString("http://www.metager.de/meta/cgi-bin/meta.ger1?"
			  "start=1&mm=and&maxtreffer=200&time=3"
			  "&hitsPerServer=5&textmenge=1&wikiboost=on"
			  "&QuickTips=beschleuniger&linkTest=no"
			  "&check_time=3&wikipedia=on"
			  "&yacy=on&eingabe=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "my dooble search")
        urlText = QString
	  ("http://localhost:8080/yacysearch.html?display=2&count=100"
	   "&resource=global&query=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "kvk book search")
	urlText = QString("http://kvk.ubka.uni-karlsruhe.de/"
			  "hylib-bin/kvk/nph-kvk2.cgi?maske="
			  "kvk-last&title=UB+Karlsruhe:+Karlsruhe+"
			  "Virtual+Catalog+KVK+:+Search+"
			  "results&header=http://www.ubka.uni-karlsruhe.de/"
			  "kvk/kvk/kvk-header_en_2007_07.html&spacer="
			  "http://www.ubka.uni-karlsruhe.de/kvk/kvk/"
			  "kvk-spacer_en_2007_07.html&footer="
			  "http://www.ubka.uni-karlsruhe.de/kvk/kvk/"
			  "kvk-footer_en_2008_01.html&lang=en&css="
			  "http://www.ubka.uni-karlsruhe.de/kvk/kvk/"
			  "kvk-neu2.css&input-charset=utf-8&TI=&PY="
			  "&AU=&SB=&CI=&SS=&ST=&PU=&VERBUENDE=&kataloge="
			  "SWB&kataloge=BVB&kataloge=NRW&kataloge="
			  "HEBIS&kataloge=HEBIS_RETRO&kataloge="
			  "KOBV&kataloge=GBV&kataloge=DDB&kataloge="
			  "DFG_EBOOKS&kataloge=STABI_BERLIN&kataloge="
			  "TIB&kataloge=OEVK_GBV&kataloge=ZDB&OESTERREICH="
			  "&kataloge=BIBOPAC&kataloge=OENB_1992&SCHWEIZ="
			  "&kataloge=HELVETICAT&kataloge=BASEL&kataloge="
			  "ZUERICH&kataloge=ETH&kataloge=NLAU&kataloge="
			  "CISTI&kataloge=NLCA&kataloge=NB_TSCHECHIEN&"
			  "kataloge=DAENEMARK_REX&kataloge=EROMM&kataloge="
			  "UBHS&kataloge=BNF_PARIS&kataloge=ABES&kataloge="
			  "NB_UNGARN&kataloge=VERBUND_ISRAEL&kataloge="
			  "ITALIEN_VERBUND&kataloge=ITALIEN_SERIALS&kataloge="
			  "LUXEMBURG&kataloge=NB_NIEDERLANDE&kataloge="
			  "VERBUND_NORWEGEN&kataloge=NB_POLEN&kataloge="
			  "PORTUGAL&kataloge=STAATSBIB_RUSSLAND&kataloge="
			  "BNE&kataloge=REBIUN&kataloge=VERBUND_SCHWEDEN&"
			  "kataloge=COPAC&kataloge=BL&kataloge=LOC_DIREKT&"
			  "kataloge=NLM&target=_blank&Timeout=120&ALL=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "metager")
	urlText = QString("http://www.metager.de/meta/cgi-bin/meta.ger1?"
			  "start=1&mm=and&maxtreffer=100&time="
			  "3&hitsPerServer=5&textmenge=1&wikiboost="
			  "on&QuickTips=beschleuniger&linkTest=no&"
			  "check_time=3&exalead=on&wikipedia=on&"
			  "yacy=on&msn=on&yahoo=on&bildersuche="
			  "on&audioclipping=on&onlinks=on&eingabe=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "faroo")
        urlText = QString("http://www.faroo.com/search?"
			  "language=&fq=&tr=&start=0"
                          "&qt=search&q=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "open source applications")
        urlText = QString("http://sourceforge.net/search/"
                          "?type_of_search=soft&sort=num_downloads_week"
                          "&sortdir=desc&limit=50&words=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "open street map")
	urlText = QString("http://gazetteer.openstreetmap.org/"
			  "namefinder/?find=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "news search")
        urlText = QString("http://www.altavista.com/"
                          "news/results?q=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "youtube mp3")
        urlText = QString("http://www.youtube-mp3.org/"
                          "search?q=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "youtube video")
        urlText = QString("http://www.youtube.com/"
                          "results?search_query=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "web 2.0 search")
        urlText = QString("http://www.eepsites.com/Content/Search/"
                          "SearchResults.aspx?ResultsFor=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "science net")
	{
	  urlText = "http://sciencenet.fzk.de:8080/yacysearch.html?query=";

	  QString searchText
	    (ui.searchLineEdit->text().trimmed().replace(" ", "+"));

	  urlText += searchText + "&Enter=query";
	}
      else if(searchName == "wikipedia")
	{
	  QLocale locale;

	  urlText = QString
	    ("http://%1.wikipedia.org/wiki/Special:"
	     "Search?search=%2").
	    arg(locale.name().left(2)).
	    arg(ui.searchLineEdit->text().trimmed().replace(" ", "+"));
	}
      else if(searchName == "scroogle")
        urlText = QString("https://ssl.scroogle.org/"
                          "cgi-bin/nbbw.cgi?Gw=%1").arg
	  (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "search china ??????")
        urlText = QString("https://www.google.com/search?num=50&hl=lang_zh-CN&"
                          "lr=lang_zh-CN&aq=f&q=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "baidu ??")
        urlText = QString("http://www.baidu.com/s?wd=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));
      else if(searchName == "ixquick")
        urlText = QString("https://ixquick.com/do/metasearch.pl?"
                          "cat=web&query=%1").arg
          (ui.searchLineEdit->text().trimmed().replace(" ", "+"));

      ui.zoomMenu->setEnabled
	(!QFileInfo(QUrl(urlText).toLocalFile()).isDir() &&
	 QUrl(urlText).scheme().toLower() != "ftp");
      ui.actionSelect_All_Content->setEnabled
	(!QFileInfo(QUrl(urlText).toLocalFile()).isDir() &&
	 QUrl(urlText).scheme().toLower() != "ftp");
      ui.tabWidget->setTabText(ui.tabWidget->indexOf(p),
			       tr("Loading..."));
      p->load(QUrl(urlText));
      ui.actionFind->setEnabled(!p->isDir() && !p->isFtp());

      if(p->isDir() || p->isFtp())
	ui.findFrame->setVisible(false);
      else
	ui.findFrame->setVisible(showFindFrame);
    }
}

void dooble::slotCopyLink(const QUrl &url)
{
  QApplication::clipboard()->setText(url.toString(QUrl::StripTrailingSlash));
}

void dooble::slotOpenLinkInNewTab(const QUrl &url)
{
  newTab(url);
}

void dooble::slotOpenLinkInNewWindow(const QUrl &url)
{
  Q_UNUSED(new dooble(url));
}

void dooble::slotOpenPageInNewWindow(const int index)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->widget(index));

  if(p)
    {
      Q_UNUSED(new dooble(p, ui.tabWidget->tabText(index)));
      ui.tabWidget->setTabsClosable(ui.tabWidget->count() > 1);
      ui.actionClose_Tab->setEnabled(ui.tabWidget->count() > 1);
      ui.tabWidget->cornerWidget(Qt::TopRightCorner)->setEnabled
	(ui.tabWidget->count() > 1);
    }
}

void dooble::slotLinkHovered(const QString &link, const QString &title,
			     const QString &textContent)
{
  Q_UNUSED(title);
  Q_UNUSED(textContent);

  if(link.isEmpty())
    sb.statusLabel->clear();
  else
    sb.statusLabel->setText(link.trimmed().mid(0, 100));
}

void dooble::slotAbout(void)
{
  QMessageBox mb(this);

  mb.setWindowTitle(tr("Dooble Web Browser: About"));
  mb.setTextFormat(Qt::RichText);
  mb.setText("<html>"
             "Version 0.09.01.<br><br>"
             "Open Source software for Linux, Mac, and Windows.<br><br>"
             "Copyright (c) 2008, 2009, 2010<br>"
             "The Dooble Team."
	     "<hr>"
             "Please visit <a href='http://dooble.sf.net'>"
             "http://dooble.sf.net</a><br>for more information."
             "</html>");
  mb.setStandardButtons(QMessageBox::Ok);
  mb.setIconPixmap(QPixmap("Icons/AxB/dooble.png"));
  mb.exec();
}

void dooble::slotSavePage(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    saveUrl(p->url());
}

void dooble::slotSaveUrl(const QUrl &url)
{
  saveUrl(url);
}

void dooble::saveUrl(const QUrl &url)
{
  if(url.isEmpty())
    return;

  QString path("");
  QSettings settings;

  if(settings.contains("settingsWindow/myRetrievedFiles"))
    path = settings.value("settingsWindow/myRetrievedFiles").toString();
  else
    {
      path = QDesktopServices::storageLocation
	(QDesktopServices::DesktopLocation);

      if(path.isEmpty() || !QFile::exists(path) ||
	 !QFileInfo(path).isReadable())
	path = QDir::homePath();
    }

  QWidget *parent = qobject_cast<QWidget *> (sender());

  if(!parent)
    parent = this;

  QFileDialog *fileDialog = new QFileDialog(parent);

  fileDialog->setProperty("url", url);
  fileDialog->setWindowTitle(tr("Dooble Web Browser: Save As"));
  fileDialog->setFileMode(QFileDialog::AnyFile);
  fileDialog->setDirectory(path);
  fileDialog->setLabelText(QFileDialog::Accept, tr("&Save"));
  fileDialog->setAcceptMode(QFileDialog::AcceptSave);
  connect(fileDialog,
	  SIGNAL(finished(int)),
	  this,
	  SLOT(slotSaveDialogFinished(int)));

#ifdef Q_WS_MAC
  /*
  ** Attempt to find the QLineEdit widget.
  */

  QLineEdit *lineEdit = fileDialog->findChild<QLineEdit *> ("fileNameEdit");

  if(!lineEdit)
    lineEdit = fileDialog->findChild<QLineEdit *> ();
#endif

  if(url.path().isEmpty() || url.path() == "/")
#ifdef Q_WS_MAC
    {
      if(lineEdit)
	lineEdit->setText("index.html");
    }
#else
    fileDialog->selectFile("index.html");
#endif
  else if(url.path().contains("/"))
    {
      QString fileName = QFileInfo(url.path()).fileName();

      if(fileName.isEmpty())
	fileName = "index.html";

#ifdef Q_WS_MAC
      if(lineEdit)
	lineEdit->setText(fileName);
#else
      fileDialog->selectFile(fileName);
#endif
    }

  fileDialog->setWindowModality(Qt::WindowModal);
#ifndef Q_WS_MAC
  fileDialog->setModal(true);
#endif
  fileDialog->show();
#ifdef Q_WS_MAC
  fileDialog->setModal(true);
#endif
}

void dooble::slotDisplayDownloadWindow(void)
{
  downloadWindow->show();
}

void dooble::slotShowFind(void)
{
  if(ui.tabWidget->
     tabData(ui.tabWidget->currentIndex()).toString() != "Desktop")
    {
      dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

      if(p && (p->isDir() || p->isFtp()))
	ui.findFrame->setVisible(false);
      else
	{
	  showFindFrame = true;
	  ui.findFrame->setVisible(true);
	}

      if(p)
	ui.actionFind->setEnabled(!p->isDir() && !p->isFtp());
    }

  if(ui.tabWidget->isVisible())
    {
      ui.findLineEdit->setFocus();
      ui.findLineEdit->selectAll();
      update();
    }
}

void dooble::slotHideFind(void)
{
  showFindFrame = false;
  ui.findFrame->setVisible(false);
}

void dooble::slotFind(void)
{
  slotFind(ui.findLineEdit->text());
}

void dooble::slotFind(const QString &text)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());
  static QPalette lineEditPalette(ui.findLineEdit->palette());

  if(p)
    {
      p->page()->findText("");

      QWebPage::FindFlags findFlags = QWebPage::FindWrapsAroundDocument;

      if(ui.matchCaseCheckBox->isChecked())
	findFlags |= QWebPage::FindCaseSensitively;

      if(ui.highlightAllCheckBox->isChecked())
	findFlags |= QWebPage::HighlightAllOccurrences;

      if(p->page()->findText(text, findFlags) || text.isEmpty())
	ui.findLineEdit->setPalette(lineEditPalette);
      else
	{
	  QColor color(240, 128, 128); // Light Coral
	  QPalette palette(ui.findLineEdit->palette());

	  palette.setColor(ui.findLineEdit->backgroundRole(), color);
	  ui.findLineEdit->setPalette(palette);
	  p->page()->findText("");
	}
    }
}

void dooble::keyPressEvent(QKeyEvent *event)
{
  if(event)
    {
      if(event->key() == Qt::Key_Escape && ui.findFrame->isVisible())
	{
	  showFindFrame = false;
	  ui.findFrame->setVisible(false);
	}
      else if(event->key() == Qt::Key_Escape)
	slotStop();
      else if(event->key() == Qt::Key_X &&
	      event->modifiers() == Qt::AltModifier)
	showMinimized();

      if(isFullScreen())
	{
	  /*
	  ** OK, this is going to be tricky.
	  ** Grab all the actions.
	  ** For every action that is enabled, determine
	  ** its shortcuts. If a shortcut matches the event's key
	  ** and the event's modifier, issue the action's trigger() method.
	  */

#ifdef Q_WS_X11
	  if(QKeySequence(event->modifiers() + event->key()) ==
	     QKeySequence(Qt::ControlModifier + Qt::ShiftModifier +
			  Qt::Key_Plus))
	    {
	      ui.actionZoom_In->trigger();
	      return;
	    }
#endif

	  QKeySequence shortcut(event->modifiers() + event->key());

	  foreach(QAction *action, findChildren<QAction *> ())
	    if(action->isEnabled() && !action->shortcuts().isEmpty())
	      {
		QList<QKeySequence> shortcuts(action->shortcuts());

		for(int i = 0; i < shortcuts.size(); i++)
		  if(shortcut == shortcuts.at(i))
		    {
		      action->trigger();
		      break;
		    }

		shortcuts.clear();
	      }
	}
    }
}

void dooble::slotPrint(void)
{
  QPrinter printer;
  QPrintDialog printDialog(&printer, this);

  printDialog.setSizeGripEnabled(true);

  if(printDialog.exec() == QDialog::Accepted)
    {
      dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

      if(p)
	p->print(&printer);
    }
}

void dooble::slotPrintPreview(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p && p->currentFrame())
    {
      QPrinter printer;
      QPrintPreviewDialog printDialog(&printer, this);

      printDialog.setSizeGripEnabled(true);
      connect(&printDialog,
	      SIGNAL(paintRequested(QPrinter *)),
	      p->currentFrame(),
	      SLOT(print(QPrinter *)));

      if(printDialog.exec() == QDialog::Accepted)
	p->print(&printer);
    }
}

void dooble::slotShowDesktopTab(void)
{
  bool desktopFound = false;

  for(int i = 0; i < ui.tabWidget->count(); i++)
    if(ui.tabWidget->tabData(i).toString() == "Desktop")
      {
	desktopFound = true;
	ui.tabWidget->setCurrentIndex(i);
	break;
      }

  if(!desktopFound)
    {
      QSettings settings;
      QSettings cfgSettings
	(settings.value("iconSet").toString(), QSettings::IniFormat);

      cfgSettings.beginGroup("mainWindow");
      ui.tabWidget->addTab(desktopWidget,
			   QIcon(cfgSettings.value("tabWidget").toString()),
			   tr("Dooble Desktop"));
      ui.tabWidget->setTabData(ui.tabWidget->count() - 1,
			       QVariant("Desktop"));
      ui.tabWidget->setTabToolTip(ui.tabWidget->count() - 1,
				  tr("Dooble Desktop"));
      ui.tabWidget->setCurrentWidget(desktopWidget);
      ui.desktopToolButton->setVisible(false);
      ui.tabWidget->setTabsClosable(ui.tabWidget->count() > 1);
      ui.actionClose_Tab->setEnabled(ui.tabWidget->count() > 1);
      ui.tabWidget->cornerWidget(Qt::TopRightCorner)->setEnabled
	(ui.tabWidget->count() > 1);
    }
}

void dooble::slotShowPageSource(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p && p->currentFrame())
    {
      dpagesourcewindow *ps = new dpagesourcewindow
	(p->url(),
	 p->currentFrame()->toHtml());

      connect(this,
	      SIGNAL(iconsChanged(void)),
	      ps,
	      SLOT(slotSetIcons(void)));

      /*
      ** The dpagesourcewindow object automatically destroys
      ** itselft whenever it is closed.
      */
    }
}

void dooble::slotClearHistory(void)
{
  foreach(QWidget *widget, QApplication::allWidgets())
    if(qobject_cast<dooble *> (widget))
      {
	dooble *d = qobject_cast<dooble *> (widget);

	/*
	** Clear every page's history.
	*/

	emit d->clearHistory();

	/*
	** Remove all but one of the history menu's actions.
	*/

	while(d->ui.historyMenu->actions().size() > 1)
	  d->ui.historyMenu->removeAction(d->ui.historyMenu->actions().last());

	if(!d->ui.historyMenu->actions().isEmpty())
	  d->ui.historyMenu->actions().at(0)->setEnabled(false);

	/*
	** Clear the history of the back and forward buttons' menus.
	*/

	d->ui.backToolButton->menu()->clear();
	d->ui.forwardToolButton->menu()->clear();
	d->ui.backToolButton->setEnabled(false);
	d->ui.forwardToolButton->setEnabled(false);
      }

  {
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "history");

    db.setDatabaseName(QDir::homePath() + "/.dooble/history.db");

    if(db.open())
      {
	QSqlQuery query(db);

	query.exec("DELETE FROM history");
      }

    db.close();
  }

  QSqlDatabase::removeDatabase("history");
}

void dooble::slotShowSettingsWindow(void)
{
  settingsWindow->exec(this);
}

void dooble::slotViewZoomIn(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p && p->page() && p->page()->currentFrame())
    {
      p->page()->currentFrame()->setZoomFactor
	(p->page()->currentFrame()->zoomFactor() + 0.1);
      update();
    }
}

void dooble::slotViewZoomOut(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());
	
  if(p && p->page() && p->page()->currentFrame())
    {
      p->page()->currentFrame()->setZoomFactor
	(p->page()->currentFrame()->zoomFactor() - 0.1);
      update();
    }
}

void dooble::slotViewResetZoom(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p && p->page()->currentFrame())
    {
      p->page()->currentFrame()->setZoomFactor(1.0);
      update();
    }
}

void dooble::slotViewZoomTextOnly(bool enable)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p && p->page()->currentFrame())
    {
      p->page()->currentFrame()->page()->settings()->setAttribute
	(QWebSettings::ZoomTextOnly, enable);
      update();
    }
}

void dooble::slotStatusBarDisplay(void)
{
  if(isFullScreen())
    return;

  statusBar()->setVisible(ui.actionStatusbar->isChecked());

  QSettings settings;

  settings.setValue("mainWindow/statusbarDisplay", statusBar()->isVisible());
}

void dooble::closeDesktop(void)
{
  /*
  ** Destroy the widget that is housing the Desktop.
  */

  for(int i = 0; i < ui.tabWidget->count(); i++)
    if(ui.tabWidget->tabData(i).toString() == "Desktop")
      {
	ui.tabWidget->removeTab(i);
	ui.desktopToolButton->setVisible(true);
	break;
      }

  ui.tabWidget->setTabsClosable(ui.tabWidget->count() > 1);
  ui.actionClose_Tab->setEnabled(ui.tabWidget->count() > 1);
  ui.tabWidget->cornerWidget(Qt::TopRightCorner)->setEnabled
    (ui.tabWidget->count() > 1);
  QApplication::sendPostedEvents(this, 0);
}

void dooble::slotOpenDirectory(void)
{
  QFileDialog fileDialog(this);

  fileDialog.setWindowModality(Qt::WindowModal);
  fileDialog.setWindowTitle(tr("Dooble Web Browser: Open Directory"));
  fileDialog.setFileMode(QFileDialog::Directory);
  fileDialog.setDirectory(QDir::homePath());
  fileDialog.setLabelText(QFileDialog::Accept, tr("&Open"));
  fileDialog.setAcceptMode(QFileDialog::AcceptOpen);

  if(fileDialog.exec() == QDialog::Accepted)
    {
      QStringList list(fileDialog.selectedFiles());

      if(!list.isEmpty())
	{
	  if(ui.tabWidget->
	     tabData(ui.tabWidget->currentIndex()).toString() == "Desktop")
	    desktopWidget->showFileManagerWindow
	      (QUrl::fromLocalFile(list[0]));
	  else
	    loadPage(QUrl::fromLocalFile(list[0]));

	  list.clear();
	}
    }
}

void dooble::slotOpenMyRetrievedFiles(void)
{
  if(ui.tabWidget->
     tabData(ui.tabWidget->currentIndex()).toString() == "Desktop")
    desktopWidget->showFileManagerWindow();
  else
    {
      QString path("");
      QSettings settings;

      if(settings.contains("settingsWindow/myRetrievedFiles"))
	path = settings.value("settingsWindow/myRetrievedFiles").toString();
      else
	{
	  QString path = QDesktopServices::storageLocation
	    (QDesktopServices::DesktopLocation);

	  if(path.isEmpty() || !QFile::exists(path))
	    path = QDir::homePath();
	}

      loadPage(QUrl::fromLocalFile(path));
    }
}

void dooble::slotChangeDesktopBackgrounds(void)
{
  foreach(QWidget *widget, QApplication::allWidgets())
    if(qobject_cast<dooble *> (widget))
      {
	dooble *d = qobject_cast<dooble *> (widget);

	emit d->updateDesktopBackground();
      }
}

void dooble::saveHistoryItem(const QWebHistoryItem &item)
{
  QSettings settings;

  if(!settings.value("settingsWindow/saveHistory", true).toBool())
    return;

  {
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "history");

    db.setDatabaseName(QDir::homePath() + "/.dooble/history.db");

    if(db.open())
      {
	QSqlQuery query(db);

	query.exec("CREATE TABLE IF NOT EXISTS history ("
		   "url TEXT NOT NULL PRIMARY KEY, "
		   "icon BLOB, "
		   "last_visited TEXT, "
		   "title TEXT)");
	query.prepare
	  ("INSERT OR REPLACE INTO history "
	   "(url, icon, last_visited, title) "
	   "VALUES (?, ?, ?, ?)");
	query.bindValue(0, item.url().toString());
	query.bindValue(1, QVariant()); // Not yet implemented.
	query.bindValue(2, item.lastVisited().toString(Qt::ISODate));
	query.bindValue(3, item.title());
	query.exec();
      }

    db.close();
  }

  QSqlDatabase::removeDatabase("history");
}

void dooble::slotCopy(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    {
      p->page()->triggerAction(QWebPage::Copy);

      if(!p->page()->selectedText().isEmpty())
	ui.actionPaste->setEnabled(true);
    }
}

void dooble::slotPaste(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    p->page()->triggerAction(QWebPage::Paste);
}

void dooble::slotSelectAllContent(void)
{
  dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

  if(p)
    p->page()->triggerAction(QWebPage::SelectAll);
}

void dooble::slotAuthenticationRequired(QNetworkReply *reply,
					QAuthenticator *authenticator)
{
  /*
  ** We should inspect the reply object. However, based on the
  ** name of the signal authenticationRequired and the capabilities of
  ** QAuthenticator, we can conclude that credentials are sought.
  */

  Q_UNUSED(reply);
  QDialog dialog(this);
  Ui_passwordDialog ui;

  ui.setupUi(&dialog);

  if(dialog.exec() == QDialog::Accepted)
    {
      authenticator->setUser(ui.usernameLineEdit->text());
      authenticator->setPassword(ui.passwordLineEdit->text());
    }
  else
    {
      /*
      ** Abort the load if the user has rejected the dialog.
      */

      QNetworkAccessManager *networkAccessManager =
	qobject_cast<QNetworkAccessManager *> (sender());

      if(networkAccessManager)
	{
	  QWebPage *webPage = qobject_cast<QWebPage *>
	    (networkAccessManager->parent());

	  if(webPage)
	    {
	      QWebView *webView = qobject_cast<QWebView *> (webPage->parent());

	      if(webView)
		webView->stop();
	    }
	}
    }
}

void dooble::slotSaveDialogFinished(int result)
{
  QFileDialog *fileDialog = qobject_cast<QFileDialog *> (sender());

  if(fileDialog && result == QDialog::Accepted)
    {
      QUrl url(fileDialog->property("url").toUrl());
      QStringList list(fileDialog->selectedFiles());

      if(!list.isEmpty())
	{
	  if(url.scheme().toLower().startsWith("ftp") ||
	     QFileInfo(url.toLocalFile()).isDir())
	    {
	      dview *p = qobject_cast<dview *> (ui.tabWidget->currentWidget());

	      if(p)
		{
		  QFile file(list[0]);

		  if(file.open(QIODevice::WriteOnly | QIODevice::Text))
		    {
		      QTextStream out(&file);

		      out << p->html();
		      file.close();
		    }
		}
	    }
	  else
	    {
	      downloadWindow->show();

	      if(!url.scheme().toLower().startsWith("file"))
		downloadWindow->addItem(url, list[0]);
	      else
		downloadWindow->addItem(url.toLocalFile(),
					list[0]);
	    }

	  list.clear();
	}
    }

  if(fileDialog)
    fileDialog->deleteLater();
}

void dooble::slotFullScreenMode(void)
{
  bool setVisible = false;
  static QSize m_size = size();

  if(ui.actionFull_Screen_Mode->text().contains("Full"))
    {
      setVisible = false;
      ui.actionFull_Screen_Mode->setText("Normal Screen Mode");
    }
  else
    {
      setVisible = true;
      ui.actionFull_Screen_Mode->setText("Full Screen Tablet Mode");
    }

  if(!setVisible)
    {
      m_size = size();
      showFullScreen();
    }
  else
    {
      showNormal();
      resize(m_size);
    }

  menuBar()->setVisible(setVisible);
  ui.actionStatusbar->setEnabled(setVisible);

  if(qobject_cast<dview *> (ui.tabWidget->currentWidget()))
    statusBar()->setVisible(ui.actionStatusbar->isChecked() && setVisible);
  else
    statusBar()->setVisible(false);

  ui.marker->setVisible(!setVisible);
  ui.urlFrame->setVisible(setVisible);
  ui.tabWidget->setBarVisible(setVisible);
  ui.restoreToolButton->setVisible(!setVisible);
  activateWindow();
}

void dooble::slotMarkerEntered(void)
{
  ui.marker->setVisible(false);
  ui.urlFrame->setVisible(true);
  ui.tabWidget->setBarVisible(true);
  ui.restoreToolButton->setVisible(true);
}

void dooble::slotViewEntered(void)
{
  if(isFullScreen())
    {
      ui.urlFrame->setVisible(false);
      ui.tabWidget->setBarVisible(false);
      ui.restoreToolButton->setVisible(false);
      ui.marker->setVisible(true);
    }
}

void dooble::slotFontChanged(const QFont &font)
{
  QApplication *qapp = qobject_cast<QApplication *>
    (QApplication::instance());

  if(qapp)
    qapp->setFont(font);

  foreach(QWidget *widget, QApplication::allWidgets())
    widget->setFont(font);

  menuBar()->setFont(font);

  foreach(QMenu *menu, menuBar()->findChildren<QMenu *> ())
    foreach(QAction *action, menu->actions())
      action->setFont(font);
}

void dooble::slotSelectionChanged(const QString &text)
{
  ui.actionCopy->setEnabled(!text.isEmpty());
}

void dooble::slotTextCopied(void)
{
  ui.actionPaste->setEnabled(true);
}
