Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

browsermainwindow.cpp Example File
demos/browser/browsermainwindow.cpp

 /****************************************************************************
 **
 ** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved.
 **
 ** This file is part of the documentation of the Qt Toolkit.
 **
 ** This file may be used under the terms of the GNU General Public
** License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file.  Alternatively you may (at
** your option) use any later version of the GNU General Public
** License if such license has been publicly approved by Trolltech ASA
** (or its successors, if any) and the KDE Free Qt Foundation. In
** addition, as a special exception, Trolltech gives you certain
** additional rights. These rights are described in the Trolltech GPL
** Exception version 1.2, which can be found at
** http://www.trolltech.com/products/qt/gplexception/ and in the file
** GPL_EXCEPTION.txt in this package.
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/. If
** you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** In addition, as a special exception, Trolltech, as the sole
** copyright holder for Qt Designer, grants users of the Qt/Eclipse
** Integration plug-in the right for the Qt/Eclipse Integration to
** link to functionality provided by Qt Designer and its related
** libraries.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
** granted herein.
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 **
 ****************************************************************************/

 #include "browsermainwindow.h"

 #include "webview.h"
 #include "browsertabproxy.h"
 #include "chasewidget.h"
 #include "sourcecodeview.h"
 #include "cookiejar.h"
 #include "history.h"
 #include "settings.h"
 #include "autosave.h"
 #include "toolbarsearch.h"
 #include "ui_passworddialog.h"
 #include "downloadmanager.h"

 #include <QtCore/QSettings>
 #include <qdebug.h>
 #include <QtGui/QApplication>
 #include <QtGui/QDesktopWidget>
 #include <QtGui/QFileDialog>
 #include <QtGui/QLabel>
 #include <QtGui/QLineEdit>
 #include <QtGui/QMenu>
 #include <QtGui/QMenuBar>
 #include <QtGui/QMessageBox>
 #include <QtGui/QMovie>
 #include <QtGui/QStatusBar>
 #include <QtGui/QStyle>
 #include <QtGui/QShortcut>
 #include <QtGui/QTabWidget>
 #include <QtGui/QTextDocument>
 #include <QtGui/QToolBar>
 #include <QtGui/QToolButton>
 #include <QtGui/QCompleter>

 #include <QtNetwork/QAuthenticator>
 #include <QtNetwork/QNetworkReply>

 #include <QtWebKit/QWebFrame>
 #include <QtWebKit/QWebPage>

 #define PERFORM_WEBPAGE_ACTION(ACTION) \
     if (currentTab())                  \
         currentTab()->page()->triggerAction(QWebPage::ACTION);

 BrowserMainWindow::BrowserMainWindow()
     : m_mainTabWidget(new QTabWidget(this))
     , m_cookieJar(0)
     , m_history(0)
     , m_autoSave(new AutoSave(this))
     , m_downloadManager()
     , m_historyBack(0)
     , m_historyForward(0)
     , m_stop(0)
     , m_reload(0)
     , m_cut(0)
     , m_copy(0)
     , m_paste(0)
     , m_undo(0)
     , m_redo(0)
     , m_newTab(0)
     , m_closeTab(0)
     , m_proxy(new BrowserTabProxy(this))
 {
     if (!QWebHistoryInterface::defaultInterface()) {
         m_history = new History(0);
         QWebHistoryInterface::setDefaultInterface(m_history);
     } else {
         m_history = qobject_cast<History*>(QWebHistoryInterface::defaultInterface());
     }

     setAttribute(Qt::WA_DeleteOnClose);
     statusBar()->setSizeGripEnabled(true);

     setupMenu();
     setupToolBar();
     setCentralWidget(m_mainTabWidget);

     slotNewTab();

     connect(m_mainTabWidget, SIGNAL(currentChanged(int)),
             SLOT(slotCurrentTabChanged(int)));
     connect(m_proxy, SIGNAL(linkHovered(const QString&)),
             statusBar(), SLOT(showMessage(const QString&)));
     m_mainTabWidget->setElideMode(Qt::ElideRight);

     QToolButton *addTabButton = new QToolButton;
     m_newTab->setIcon(QIcon(":addtab.png"));
     m_newTab->setIconVisibleInMenu(false);
     addTabButton->setDefaultAction(m_newTab);
     addTabButton->setAutoRaise(true);
     addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
     m_mainTabWidget->setCornerWidget(addTabButton, Qt::TopLeftCorner);

     QToolButton *closeTabButton = new QToolButton;
     m_closeTab->setIcon(QIcon(":closetab.png"));
     m_closeTab->setIconVisibleInMenu(false);
     closeTabButton->setDefaultAction(m_closeTab);
     closeTabButton->setAutoRaise(true);
     closeTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
     m_mainTabWidget->setCornerWidget(closeTabButton, Qt::TopRightCorner);

     QShortcut *locationBarShortcut = new QShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_L), this);
     connect(locationBarShortcut, SIGNAL(activated()), m_urlEdit, SLOT(selectAll()));
     connect(locationBarShortcut, SIGNAL(activated()), m_urlEdit, SLOT(setFocus()));

     currentTab()->setFocus();
     slotUpdateWindowTitle(QString());
     setWindowIcon(QIcon(":browser.svg"));
     restore();
 }

 BrowserMainWindow::~BrowserMainWindow()
 {
     m_autoSave->changed();
     m_autoSave->saveNow();
 }

 void BrowserMainWindow::restore()
 {
     QSettings settings;
     settings.beginGroup("MainWindow");

     QRect desktopRect = QApplication::desktop()->screenGeometry();
     QSize size = settings.value("Size", desktopRect.size() * 0.8).toSize();
     resize(size);

     bool showStatusbar = (settings.value("viewStatusbar", false).toBool());
     statusBar()->setVisible(showStatusbar);
     updateStatusbarActionText(showStatusbar);

     bool showToolbar = settings.value("viewNavigationbar", true).toBool();
     navigationBar->setVisible(showToolbar);
     updateToolbarActionText(showToolbar);

     QStringList openTabs = settings.value("openTabs").toStringList();
     m_restoreLastSession->setEnabled(openTabs.count() > 0);

     QStringList args = QCoreApplication::arguments();
     if (args.count() > 1)
         loadPage(args.last());
     else
         QTimer::singleShot(0, this, SLOT(slotHome()));
     settings.endGroup();
 }

 void BrowserMainWindow::restoreLastSession()
 {
     QSettings settings;
     settings.beginGroup("MainWindow");
     QStringList openTabs = settings.value("openTabs").toStringList();
     for (int i = 0; i < openTabs.count(); ++i) {
         slotNewTab();
         loadPage(openTabs.at(i));
     }
 }

 void BrowserMainWindow::save()
 {
     QSettings settings;
     settings.beginGroup("MainWindow");
     settings.setValue("Size", size());
     settings.setValue("viewNavigationbar", !navigationBar->isHidden());
     settings.setValue("viewStatusbar", !statusBar()->isHidden());

     QStringList openTabs;
     for (int i = 0; i < m_mainTabWidget->count(); ++i) {
         QWidget *widget = m_mainTabWidget->widget(i);
         if (WebView *tab = qobject_cast<WebView*>(widget)) {
             openTabs.append(tab->url().toString());
         }
     }
     settings.setValue("openTabs", openTabs);
     settings.endGroup();
 }

 void BrowserMainWindow::setupMenu()
 {
     QMenu *fileMenu = menuBar()->addMenu(tr("&File"));

     fileMenu->addAction(tr("&New Window"), this, SLOT(slotNewWindow()), QKeySequence::New);
     m_newTab = fileMenu->addAction(tr("New &Tab"), this, SLOT(slotNewTab()), QKeySequence::AddTab);
     fileMenu->addAction(tr("&Open File"), this, SLOT(slotOpenFile()), QKeySequence::Open);
     m_closeTab = fileMenu->addAction(tr("&Close Tab"), this, SLOT(slotCloseTab()), QKeySequence::Close);
     fileMenu->addSeparator();

     fileMenu->addAction(tr("&Quit"), qApp, SLOT(quit()));

     QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
     m_undo = editMenu->addAction(tr("&Undo"), this, SLOT(slotUndo()), QKeySequence::Undo);
     m_redo = editMenu->addAction(tr("&Redo"), this, SLOT(slotRedo()), QKeySequence::Redo);
     editMenu->addSeparator();
     m_cut = editMenu->addAction(tr("Cu&t"), this, SLOT(slotCut()), QKeySequence::Cut);
     m_copy = editMenu->addAction(tr("&Copy"), this, SLOT(slotCopy()), QKeySequence::Copy);
     m_paste = editMenu->addAction(tr("&Paste"), this, SLOT(slotPaste()), QKeySequence::Paste);
     editMenu->addSeparator();
     editMenu->addAction(tr("&Preferences"), this, SLOT(slotPreferences()), tr("Ctrl+,"));

     QMenu *viewMenu = menuBar()->addMenu(tr("&View"));

     m_viewStatusbar = new QAction(this);
     updateStatusbarActionText(true);
     m_viewStatusbar->setShortcut(tr("Ctrl+/"));
     connect(m_viewStatusbar, SIGNAL(triggered()), this, SLOT(slotToggleStatusbar()));
     viewMenu->addAction(m_viewStatusbar);

     m_viewToolbar = new QAction(this);
     updateToolbarActionText(true);
     m_viewToolbar->setShortcut(tr("Ctrl+|"));
     connect(m_viewToolbar, SIGNAL(triggered()), this, SLOT(slotToggleToolbar()));
     viewMenu->addAction(m_viewToolbar);
     viewMenu->addSeparator();

     m_stop = viewMenu->addAction(tr("&Stop"), this, SLOT(slotStop()), QKeySequence(Qt::CTRL | Qt::Key_Period));
     m_reload = viewMenu->addAction(tr("Reload Page"), this, SLOT(slotReload()), QKeySequence::Refresh);
     m_stopIcon = style()->standardIcon(QStyle::SP_BrowserStop);
     m_reloadIcon = style()->standardIcon(QStyle::SP_BrowserReload);

     m_textBigger = viewMenu->addAction(tr("&Make Text Bigger"), this, SLOT(slotTextBigger()), QKeySequence(Qt::CTRL | Qt::Key_Plus));
     m_textNormal = viewMenu->addAction(tr("&Make Text Normal"), this, SLOT(slotTextNormal()), QKeySequence(Qt::CTRL | Qt::Key_0));
     m_textSmaller = viewMenu->addAction(tr("&Make Text Smaller"), this, SLOT(slotTextSmaller()), QKeySequence(Qt::CTRL | Qt::Key_Minus));

 #if 0
     viewMenu->addSeparator();
     viewMenu->addAction(tr("&Zoom In"), this, SLOT(slotZoomIn()));
     viewMenu->addAction(tr("Zoom &Out"), this, SLOT(slotZoomOut()));
 #endif
     viewMenu->addSeparator();
     viewMenu->addAction(tr("Page S&ource"), this, SLOT(slotPageSource()), tr("Ctrl+Alt+U"));
     QAction *a = viewMenu->addAction(tr("&Full Screen"), this, SLOT(slotToggleFullScreen(bool)));
     a->setCheckable(true);

     HistoryMenu *historyMenu = new HistoryMenu(m_history, this);
     connect(historyMenu, SIGNAL(openUrl(const QUrl&)), this, SLOT(slotLoadUrl(const QUrl&)));
     historyMenu->setTitle(tr("Hi&story"));
     menuBar()->addMenu(historyMenu);
     QList<QAction*> historyActions;

     m_historyBack = new QAction(tr("Back"), this);
     connect(m_historyBack, SIGNAL(triggered()), this, SLOT(slotBack()));
     m_historyBack->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft));
     m_historyBack->setIconVisibleInMenu(false);

     m_historyForward = new QAction(tr("Forward"), this);
     connect(m_historyForward, SIGNAL(triggered()), this, SLOT(slotForward()));
     m_historyForward->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_BracketRight));
     m_historyForward->setIconVisibleInMenu(false);

     QAction *m_historyHome = new QAction(tr("Home"), this);
     connect(m_historyHome, SIGNAL(triggered()), this, SLOT(slotHome()));
     m_historyHome->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H));

     m_recentlyClosedTabsMenu = new QMenu(this);
     connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()),
             this, SLOT(slotAboutToShowRecentTabs()));
     connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)),
             this, SLOT(slotAboutToShowRecentTriggered(QAction *)));
     m_recentlyClosedTabsAction = new QAction("Recently Closed Tabs", this);
     m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu);
     m_recentlyClosedTabsAction->setEnabled(false);

     m_restoreLastSession = new QAction(tr("Restore Last Session"), this);
     connect(m_restoreLastSession, SIGNAL(triggered()), this, SLOT(restoreLastSession()));

     historyActions.append(m_historyBack);
     historyActions.append(m_historyForward);
     historyActions.append(m_historyHome);
     historyActions.append(m_recentlyClosedTabsAction);
     historyActions.append(m_restoreLastSession);
     historyMenu->setInitialActions(historyActions);

     QMenu *windowMenu = menuBar()->addMenu(tr("&Window"));
     m_nextTab = windowMenu->addAction(tr("Show Next Tab"), this, SLOT(slotNextTab()), QKeySequence(tr("Ctrl+}")));
     m_previousTab = windowMenu->addAction(tr("Show Previous Tab"), this, SLOT(slotPreviousTab()), QKeySequence(tr("Ctrl+{")));
     (void)new QShortcut(Qt::ControlModifier + Qt::Key_PageDown, this, SLOT(slotNextTab()));
     (void)new QShortcut(Qt::ControlModifier + Qt::Key_PageUp, this, SLOT(slotPreviousTab()));
     windowMenu->addSeparator();
     m_downloads = windowMenu->addAction(tr("Downloads"), this, SLOT(slotDownloadManager()), QKeySequence(tr("Alt+Ctrl+L", "Download Manager")));

     QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools"));
     toolsMenu->addAction(tr("Web &Search"), this, SLOT(slotWebSearch()), QKeySequence(tr("Ctrl+K", "Web Search")));
 #ifndef Q_CC_MINGW
     a = toolsMenu->addAction(tr("Enable Web &Inspector"), this, SLOT(slotToggleInspector(bool)));
     a->setCheckable(true);
 #endif

     QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
     helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt()));
     helpMenu->addAction(tr("About &WebKit"), this, SLOT(slotAboutApplication()));
 }

 void BrowserMainWindow::setupToolBar()
 {
     setUnifiedTitleAndToolBarOnMac(true);
     navigationBar = addToolBar(tr("Navigation"));

     m_historyBack->setIcon(style()->standardIcon(QStyle::SP_ArrowBack, 0, this));
     navigationBar->addAction(m_historyBack);

     m_historyForward->setIcon(style()->standardIcon(QStyle::SP_ArrowForward, 0, this));
     navigationBar->addAction(m_historyForward);

     m_stopReload = new QAction(this);
     navigationBar->addAction(m_stopReload);

     m_urlEdit = new QLineEdit(navigationBar);
     navigationBar->addWidget(m_urlEdit);
     HistoryCompletionModel *completionModel = new HistoryCompletionModel();
     completionModel->setSourceModel(m_history->historyFilterModel());
     QCompleter *completer = new QCompleter(completionModel, m_urlEdit);
     m_urlEdit->setCompleter(completer);
     connect(m_urlEdit, SIGNAL(returnPressed()), SLOT(slotUrlEntered()));

     m_toolbarSearch = new ToolbarSearch(navigationBar);
     navigationBar->addWidget(m_toolbarSearch);
     connect(m_toolbarSearch, SIGNAL(search(const QUrl&)), SLOT(slotSearch(const QUrl&)));

     m_chaseWidget = new ChaseWidget(this);
     navigationBar->addWidget(m_chaseWidget);
 }

 void BrowserMainWindow::slotToggleToolbar()
 {
     if (navigationBar->isVisible()) {
         updateToolbarActionText(false);
         navigationBar->close();
     } else {
         updateToolbarActionText(true);
         navigationBar->show();
     }
     m_autoSave->changed();
 }

 void BrowserMainWindow::updateStatusbarActionText(bool visible)
 {
     m_viewStatusbar->setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar"));
 }

 void BrowserMainWindow::updateToolbarActionText(bool visible)
 {
     m_viewToolbar->setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar"));
 }

 void BrowserMainWindow::slotToggleStatusbar()
 {
     if (statusBar()->isVisible()) {
         updateStatusbarActionText(false);
         statusBar()->close();
     } else {
         updateStatusbarActionText(true);
         statusBar()->show();
     }
     m_autoSave->changed();
 }

 QUrl BrowserMainWindow::guessUrlFromString(const QString &string)
 {
     QString urlStr = string.trimmed();
     QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*"));

     // Check if it looks like a qualified URL. Try parsing it and see.
     bool hasSchema = test.exactMatch(urlStr);
     if (hasSchema) {
         QUrl url(urlStr, QUrl::TolerantMode);
         if (url.isValid())
             return url;
     }

     // Might be a file.
     if (QFile::exists(urlStr))
         return QUrl::fromLocalFile(urlStr);

     // Might be a shorturl - try to detect the schema.
     if (!hasSchema) {
         int dotIndex = urlStr.indexOf(QLatin1Char('.'));
         if (dotIndex != -1) {
             QString prefix = urlStr.left(dotIndex).toLower();
             QString schema = (prefix == QLatin1String("ftp")) ? prefix : QLatin1String("http");
             QUrl url(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode);
             if (url.isValid())
                 return url;
         }
     }

     // Fall back to QUrl's own tolerant parser.
     return QUrl(string, QUrl::TolerantMode);
 }

 void BrowserMainWindow::slotSearch(const QUrl &url)
 {
     replaceCurrentUrl(url);

     if (currentTab()) {
         currentTab()->loadUrl(url);
         currentTab()->setFocus();
     }
 }

 void BrowserMainWindow::slotDownloadManager()
 {
     m_downloadManager->show();
 }

 WebView *BrowserMainWindow::createTab()
 {
     WebView *tab = new WebView(this, m_mainTabWidget);
     if (CookieJar *jar = qobject_cast<CookieJar*>(tab->page()->networkAccessManager()->cookieJar())) {
         m_cookieJar = jar;
     } else {
         m_cookieJar = new CookieJar(this);
         tab->page()->networkAccessManager()->setCookieJar(m_cookieJar);
     }

     connect(tab, SIGNAL(titleChanged(const QString&)), SLOT(slotWebViewTitleChanged(const QString&)));
     connect(tab, SIGNAL(iconChanged()), SLOT(slotWebViewIconChanged()));
     connect(tab, SIGNAL(authenticationRequired(WebView*,QNetworkReply*,QAuthenticator*)),
             SLOT(slotAuthenticationRequired(WebView*,QNetworkReply*,QAuthenticator*)));
     connect(tab, SIGNAL(proxyAuthenticationRequired(WebView*,const QNetworkProxy&, QAuthenticator*)),
             SLOT(slotProxyAuthenticationRequired(WebView*,const QNetworkProxy&, QAuthenticator*)));
     connect(tab, SIGNAL(sslErrors(WebView*,QNetworkReply*, const QList<QSslError>&)),
             SLOT(slotSslErrors(WebView*, QNetworkReply*, const QList<QSslError>&)));

     if (!m_downloadManager)
         m_downloadManager = new DownloadManager(tab->page()->networkAccessManager(), this);
     tab->page()->setForwardUnsupportedContent(true);
     connect(tab->page(), SIGNAL(unsupportedContent(QNetworkReply *)),
             this, SLOT(slotHandleUnsupportedContent(QNetworkReply *)));
     connect(tab->page(), SIGNAL(downloadRequested(const QNetworkRequest &)),
             m_downloadManager, SLOT(download(const QNetworkRequest &)));

     m_mainTabWidget->addTab(tab, tr("(Untitled)"));

     replaceCurrentUrl(QString());
     m_urlEdit->setFocus();
     m_autoSave->changed();

     return tab;
 }

 void BrowserMainWindow::slotHandleUnsupportedContent(QNetworkReply *reply)
 {
     if (reply->error() == QNetworkReply::NoError) {
         m_downloadManager->handleUnsupportedContent(reply);
         return;
     }
     // Simple, basic solution for now.
     QMessageBox::information(this, tr("Network Error"),
         QString("Error: %1\nUrl: %2").arg(reply->errorString()).arg(reply->url().toString()));
 }

 void BrowserMainWindow::slotNewTab()
 {
     WebView *tab = createTab();
     m_urlEdit->setFocus();
     m_mainTabWidget->setCurrentWidget(tab);
     setCurrentTab(tab);
     m_autoSave->changed();
 }

 void BrowserMainWindow::slotPreferences()
 {
     if (!m_cookieJar)
         return;
     SettingsDialog *s = new SettingsDialog(m_cookieJar, this);
     s->show();
 }

 void BrowserMainWindow::slotCloseTab(int index)
 {
     QWidget *widget = m_mainTabWidget->widget(index);

     if (qobject_cast<WebView*>(widget)) {
         WebView *tab = static_cast<WebView*>(widget);
         if (tab->isModified()) {
             QMessageBox closeConfirmation(tab);
             closeConfirmation.setWindowFlags(Qt::Sheet);
             closeConfirmation.setWindowTitle(tr("Do you really want to close this page?"));
             closeConfirmation.setInformativeText(tr("You have modified this page and when closing it you will lose the modification.\n"
                                                      "Do you really want to close this page?\n"));
             closeConfirmation.setIcon(QMessageBox::Question);
             closeConfirmation.addButton(QMessageBox::Yes);
             closeConfirmation.addButton(QMessageBox::No);
             closeConfirmation.setEscapeButton(QMessageBox::No);
             if (closeConfirmation.exec() == QMessageBox::No)
                 return;
         }

         m_recentlyClosedTabsAction->setEnabled(true);
         m_recentlyClosedUrls.prepend(tab->url());
         if (m_recentlyClosedUrls.size() >= BrowserMainWindow::LastClosedUrlsSize)
             m_recentlyClosedUrls.removeLast();
     }

     m_mainTabWidget->removeTab(index);
     setCurrentTab(currentTab());

     if (m_mainTabWidget->count() == 0) {
         close();
         slotNewTab();
         slotHome();
     }
     m_autoSave->changed();
 }

 void BrowserMainWindow::slotUpdateStatusbar(const QString& txt)
 {
     statusBar()->showMessage(txt);
 }

 void BrowserMainWindow::slotUpdateWindowTitle(const QString& title)
 {
     if (title.isEmpty())
         setWindowTitle(tr("Qt Example Browser"));
     else
         setWindowTitle(tr("%1 - Qt Example Browser", "Page title and Browser name").arg(title));
 }

 void BrowserMainWindow::slotWebViewTitleChanged(const QString& newTitle)
 {
     WebView *tab = qobject_cast<WebView*>(sender());
     Q_ASSERT(sender() && tab);
     m_history->updateHistoryItem(tab->url(), newTitle);
     m_mainTabWidget->setTabText(m_mainTabWidget->indexOf(tab), newTitle);
 }

 void BrowserMainWindow::slotWebViewIconChanged()
 {
     WebView *browser = qobject_cast<WebView*>(sender());

     m_mainTabWidget->setTabIcon(m_mainTabWidget->indexOf(browser), browser->icon());
 }

 void BrowserMainWindow::slotNextTab()
 {
     int next = m_mainTabWidget->currentIndex() + 1;
     if (next == m_mainTabWidget->count())
         next = 0;
     m_mainTabWidget->setCurrentIndex(next);
 }

 void BrowserMainWindow::slotPreviousTab()
 {
     int next = m_mainTabWidget->currentIndex() - 1;
     if (next < 0)
         next = m_mainTabWidget->count() - 1;
     m_mainTabWidget->setCurrentIndex(next);
 }

 void BrowserMainWindow::slotAboutApplication()
 {
     QMessageBox::about(this, tr("About"), tr(
         "Version %1"
         "<p>This example demonstrates Qt's "
         "webkit facilities in action, providing an example "
         "browser for you to experiment with.<p>"
         "<p>QtWebKit is based on the Open Source WebKit Project developed at <a href=\"http://webkit.org/\">http://webkit.org/</a>."
         ).arg(QCoreApplication::applicationVersion()));
 }

 void BrowserMainWindow::slotNewWindow()
 {
     QWidget *w = new BrowserMainWindow;
     w->show();
 }

 void BrowserMainWindow::slotOpenFile()
 {
     QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(),
             tr("Web Resources (*.html *.htm *.svg *.svgz)"));

     if (file.isEmpty())
         return;

     loadPage(file);
 }

 void BrowserMainWindow::slotCloseTab()
 {
     if (!m_mainTabWidget->currentWidget())
         return;

     slotCloseTab(m_mainTabWidget->currentIndex());
 }

 void BrowserMainWindow::slotUndo()
 {
     PERFORM_WEBPAGE_ACTION(Undo)
 }

 void BrowserMainWindow::slotRedo()
 {
     PERFORM_WEBPAGE_ACTION(Redo)
 }

 void BrowserMainWindow::slotCut()
 {
     PERFORM_WEBPAGE_ACTION(Cut)
 }

 void BrowserMainWindow::slotCopy()
 {
     PERFORM_WEBPAGE_ACTION(Copy)
 }

 void BrowserMainWindow::slotPaste()
 {
     PERFORM_WEBPAGE_ACTION(Paste)
 }

 void BrowserMainWindow::slotStop()
 {
     PERFORM_WEBPAGE_ACTION(Stop)
 }

 void BrowserMainWindow::slotReload()
 {
     PERFORM_WEBPAGE_ACTION(Reload)
 }

 void BrowserMainWindow::slotTextBigger()
 {
     if (!currentTab())
         return;
     currentTab()->setTextSizeMultiplier(currentTab()->textSizeMultiplier() + 0.5);
 }

 void BrowserMainWindow::slotTextNormal()
 {
     if (!currentTab())
         return;
     currentTab()->setTextSizeMultiplier(1.0);
 }

 void BrowserMainWindow::slotTextSmaller()
 {
     if (!currentTab())
         return;
     currentTab()->setTextSizeMultiplier(currentTab()->textSizeMultiplier() - 0.5);
 }

 void BrowserMainWindow::slotToggleFullScreen(bool makeFullScreen)
 {
     makeFullScreen ? showFullScreen() : showNormal();
 }

 void BrowserMainWindow::slotPageSource()
 {
     if (!currentTab())
         return;

     QString markup = currentTab()->page()->mainFrame()->toHtml();
     SourceCodeView *view = new SourceCodeView(markup);
     view->setWindowTitle(tr("Page Source of %1").arg(currentTab()->title()));
     view->setMinimumWidth(640);
     view->setAttribute(Qt::WA_DeleteOnClose);
     view->show();
 }

 void BrowserMainWindow::slotBack()
 {
     PERFORM_WEBPAGE_ACTION(Back)
 }

 void BrowserMainWindow::slotForward()
 {
     PERFORM_WEBPAGE_ACTION(Forward)
 }

 void BrowserMainWindow::slotHome()
 {
     QSettings settings;
     settings.beginGroup("MainWindow");
     QString home = settings.value("home", "http://www.trolltech.com/").toString();
     loadPage(home);
 }

 void BrowserMainWindow::slotWebSearch()
 {
     m_toolbarSearch->selectAll();
     m_toolbarSearch->setFocus();
 }

 void BrowserMainWindow::slotToggleInspector(bool enable)
 {
     QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable);
     if (enable) {
         int result = QMessageBox::question(this, tr("Web Inspector"),
                                            tr("The web inspector will only work correctly for pages that were loaded after enabling.\n"
                                            "Do you want to reload all pages?"),
                                            QMessageBox::Yes | QMessageBox::No);
         if (result == QMessageBox::Yes) {
             for (int i = 0; i < m_mainTabWidget->count(); ++i)
                 static_cast<WebView *>(m_mainTabWidget->widget(i))->triggerPageAction(QWebPage::Reload);
         }
     }
 }

 void BrowserMainWindow::slotUrlEntered()
 {
     loadPage(m_urlEdit->text());

     if (currentTab())
         currentTab()->setFocus();
 }

 void BrowserMainWindow::slotAboutToShowRecentTabs()
 {
     m_recentlyClosedTabsMenu->clear();
     for (int i = 0; i < m_recentlyClosedUrls.count(); ++i) {
         QAction *action = new QAction(this);
         action->setData(i);
         action->setIcon(style()->standardIcon(QStyle::SP_FileIcon));
         action->setText(m_recentlyClosedUrls.at(i).toString());
         m_recentlyClosedTabsMenu->addAction(action);
     }
 }

 void BrowserMainWindow::slotAboutToShowRecentTriggered(QAction *action)
 {
     int row = action->data().toInt();
     slotLoadUrl(m_recentlyClosedUrls.value(row));
 }

 void BrowserMainWindow::loadPage(const QString& page)
 {
     if (!currentTab())
         return;

     QUrl url = guessUrlFromString(page);
     m_urlEdit->setText(url.toString());
     slotLoadUrl(url);
 }

 void BrowserMainWindow::slotLoadUrl(const QUrl &url)
 {
     currentTab()->loadUrl(url);
 }

 WebView *BrowserMainWindow::currentTab() const
 {
     // We might not have a tab, or it might be some kind of special widget
     return qobject_cast<WebView*>(m_mainTabWidget->currentWidget());
 }

 /*
  * The goal is to not change URL when the user is currently entering something.
  *
  * We assume that if the URL Edit has focus the user is trying to enter something
  */
 void BrowserMainWindow::replaceCurrentUrl(const QUrl& url)
 {
     if (!m_urlEdit->hasFocus())
         m_urlEdit->setText(url.toString());
 }

 void BrowserMainWindow::slotCurrentTabChanged(int index)
 {
     // Can be 0, e.g. if we don't have a BrowserTab in our tabwidget
     setCurrentTab(qobject_cast<WebView*>(m_mainTabWidget->widget(index)));
 }

 void BrowserMainWindow::setCurrentTab(WebView *tab)
 {
     // All the magic will happen there
     m_proxy->setTab(tab);
 }

 void BrowserMainWindow::slotLoadStarted()
 {
     m_chaseWidget->setAnimated(true);
     m_stopReload->setIcon(m_stopIcon);
     m_stopReload->setToolTip(tr("Stop loading the current page"));
 }

 void BrowserMainWindow::slotLoadFinished()
 {
     m_chaseWidget->setAnimated(false);
     disconnect(m_stopReload, SIGNAL(triggered()), this, SLOT(slotStop()));
     m_stopReload->setIcon(m_reloadIcon);
     connect(m_stopReload, SIGNAL(triggered()), this, SLOT(slotReload()));
     m_stopReload->setToolTip(tr("Reload the current page"));
 }

 void BrowserMainWindow::slotUrlChanged(const QUrl &url)
 {
     m_autoSave->changed();
     disconnect(m_stopReload, SIGNAL(triggered()), this, SLOT(slotReload()));
     replaceCurrentUrl(url);
     connect(m_stopReload, SIGNAL(triggered()), this, SLOT(slotStop()));
 }

 QString BrowserMainWindow::currentPage() const
 {
     return m_urlEdit->text();
 }

 void BrowserMainWindow::slotAuthenticationRequired(WebView *tab, QNetworkReply *reply, QAuthenticator *auth)
 {
     QDialog dialog(this);
     dialog.setWindowFlags(Qt::Sheet);

     Ui::PasswordDialog passwordDialog;
     passwordDialog.setupUi(&dialog);

     passwordDialog.lblInfo->setText(QString());
     passwordDialog.lblInfo->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, this).pixmap(32, 32));

     QString introMessage = QCoreApplication::translate("PasswordDialog", "<qt>Please enter a Username and Password for \"%1\" from %2</qt>");
     introMessage = introMessage.arg(Qt::escape(tab->title())).arg(Qt::escape(reply->url().toString()));
     passwordDialog.lblIntro->setText(introMessage);
     passwordDialog.lblIntro->setWordWrap(true);

     if (dialog.exec() == QDialog::Accepted) {
         auth->setUser(passwordDialog.lneUsername->text());
         auth->setPassword(passwordDialog.lnePassword->text());
     }
 }

 void BrowserMainWindow::slotProxyAuthenticationRequired(WebView*, const QNetworkProxy&, QAuthenticator*)
 {
 }

 void BrowserMainWindow::slotSslErrors(WebView*, QNetworkReply *reply, const QList<QSslError>&)
 {
     reply->ignoreSslErrors();
 }


Copyright © 2008 Trolltech Trademarks
Qt 4.4.0-beta1