###########################################################################
#
# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
#
# PyQt port in November 2010 by Hans-Peter Jansen <hpj@urpla.net>
#
###########################################################################

import sys
Q_WS_MAC = sys.platform.startswith("darwin")

from PyQt4 import QtCore, QtWebKit, QtGui

from autosaver import AutoSaver
from bookmarks import ..
from browserapplication import BrowserApplication
from chasewidget import ..
from downloadmanager import ..
from history import ..
from settings import ..
from tabwidget import TabWidget
from toolbarsearch import ..
from ui_passworddialog import ..
from webview import ..

class BrowserMainWindow(QtGui.QMainWindow):
    """ The MainWindow of the Browser Application.
        Handles the tab widget and all the actions
    """

public:
    BrowserMainWindow(QtGui.QWidget *parent = 0, QtCore.Qt.WindowFlags flags = 0)
    ~BrowserMainWindow()
    QtCore.QSize sizeHint() const
public:
    TabWidget *tabWidget() const
    WebView *currentTab() const
    QtCore.QByteArray saveState(bool withTabs = True) const
    bool restoreState(const QtCore.QByteArray &state)
public slots:
    void loadPage(const QtCore.QString &url)
    void slotHome()
protected:
    void closeEvent(QtGui.QCloseEvent *event)
private slots:
    void save()
    void slotLoadProgress(int)
    void slotUpdateStatusbar(const QtCore.QString &string)
    void slotUpdateWindowTitle(const QtCore.QString &title = QtCore.QString())
    void loadUrl(const QtCore.QUrl &url)
    void slotPreferences()
    void slotFileNew()
    void slotFileOpen()
    void slotFilePrintPreview()
    void slotFilePrint()
    void slotPrivateBrowsing()
    void slotFileSaveAs()
    void slotEditFind()
    void slotEditFindNext()
    void slotEditFindPrevious()
    void slotShowBookmarksDialog()
    void slotAddBookmark()
    void slotViewZoomIn()
    void slotViewZoomOut()
    void slotViewResetZoom()
    void slotViewZoomTextOnly(bool enable)
    void slotViewToolbar()
    void slotViewBookmarksBar()
    void slotViewStatusbar()
    void slotViewPageSource()
    void slotViewFullScreen(bool enable)
    void slotWebSearch()
    void slotToggleInspector(bool enable)
    void slotAboutApplication()
    void slotDownloadManager()
    void slotSelectLineEdit()
    void slotAboutToShowBackMenu()
    void slotAboutToShowForwardMenu()
    void slotAboutToShowWindowMenu()
    void slotOpenActionUrl(QtGui.QAction *action)
    void slotShowWindow()
    void slotSwapFocus()
    void printRequested(QtWebKit.QWebFrame *frame)
    void geometryChangeRequested(const QtCore.QRect &geometry)
    void updateToolbarActionText(bool visible)
    void updateBookmarksToolbarActionText(bool visible)
private:
    void loadDefaultState()
    void setupMenu()
    void setupToolBar()
    void updateStatusbarActionText(bool visible)
private:
    QtGui.QToolBar *self._navigationBar
    ToolbarSearch *m_toolbarSearch
    BookmarksToolBar *self._bookmarksToolbar
    ChaseWidget *m_chaseWidget
    TabWidget *self._tabWidget
    AutoSaver *self._autoSaver
    QtGui.QAction *self._historyBack
    QtGui.QMenu *self._historyBackMenu
    QtGui.QAction *self._historyForward
    QtGui.QMenu *self._historyForwardMenu
    QtGui.QMenu *m_windowMenu
    QtGui.QAction *self._stop
    QtGui.QAction *self._reload
    QtGui.QAction *self._stopReload
    QtGui.QAction *m_viewToolbar
    QtGui.QAction *m_viewBookmarkBar
    QtGui.QAction *m_viewStatusbar
    QtGui.QAction *m_restoreLastSession
    QtGui.QAction *m_addBookmark
    QtGui.QIcon self._reloadIcon
    QtGui.QIcon self._stopIcon
    QtCore.QString m_lastSearch

    def __init__(self, parent, wflags):
        super(BrowserMainWindow, self).__init__(parent, flags)
        self._tabWidget = TabWidget(self)
        self._autoSaver = AutoSaver(self)
        self._historyBack = None
        self._historyForward = None
        self._stop = None
        self._reload = None

        self.setToolButtonStyle(QtCore.Qt.ToolButtonFollowStyle)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
        self.statusBar().setSizeGripEnabled(True)
        self.setupMenu()
        self.setupToolBar()
        centralWidget = QtGui.QWidget(self)
        boomarksModel = BrowserApplication.bookmarksManager().bookmarksModel()
        self._bookmarksToolbar = BookmarksToolBar(boomarksModel, self)
        self._bookmarksToolbar.openUrl.connect(self._tabWidget.loadUrlInCurrentTab)
        self._bookmarksToolbar.toggleViewAction().toggled.connect(
                self.updateBookmarksToolbarActionText)
        layout = QtGui.QVBoxLayout()
        layout.setSpacing(0)
        layout.setMargin(0)
        if Q_WS_MAC:
            layout.addWidget(self._bookmarksToolbar)
            layout.addWidget(new QtGui.QWidget) # <- OS X tab widget style bug
        else:
            self.addToolBarBreak()
            self.addToolBar(self._bookmarksToolbar)

        layout.addWidget(self._tabWidget)
        centralWidget.setLayout(layout)
        self.setCentralWidget(centralWidget)
        self._tabWidget.loadPage.connect(self.loadPage)
        self._tabWidget.setCurrentTitle.connect(self.slotUpdateWindowTitle)
        self._tabWidget.showStatusBarMessage.connect(self.statusBar().showMessage)
        self._tabWidget.linkHovered.connect(self.statusBar().showMessage)
        self._tabWidget.loadProgress.connect(self.slotLoadProgress)
        self._tabWidget.tabsChanged.connect(self._autoSaver.changeOccurred)
        self._tabWidget.geometryChangeRequested.connect(self.geometryChangeRequested)
        self._tabWidget.printRequested.connect(self.printRequested)
        self._tabWidget.menuBarVisibilityChangeRequested.connect(self.menuBar().setVisible)
        self._tabWidget.statusBarVisibilityChangeRequested.connect(self.statusBar().setVisible)
        self._tabWidget.toolBarVisibilityChangeRequested.connect(self._navigationBar.setVisible)
        self._tabWidget.toolBarVisibilityChangeRequested.connect(self._bookmarksToolbar.setVisible)
    if Q_WS_MAC:
        self._tabWidget.lastTabClosed.connect(self.close)
    else:
        self._tabWidget.lastTabClosed.connect(self._tabWidget.newTab)

        self.slotUpdateWindowTitle()
        self.loadDefaultState()
        self._tabWidget.newTab()
        size = self._tabWidget.lineEditStack().sizeHint().height()
        self._navigationBar.setIconSize(QtCore.QSize(size, size))

    def __del__(self):
        self._autoSaver.changeOccurred()
        self._autoSaver.saveIfNeccessary()

    def loadDefaultState(self):
        settings = QtCore.QSettings()
        settings.beginGroup("BrowserMainWindow")
        data = settings.value("defaultState")
        self.restoreState(data)
        settings.endGroup()

    QtCore.QSize BrowserMainWindow.sizeHint() const
    {
        QtCore.QRect desktopRect = QtGui.QApplication.desktop().screenGeometry()
        QtCore.QSize size = desktopRect.size() * qreal(0.9)
        return size
    }
    def save()
    {
        BrowserApplication.instance().saveSession()
        QtCore.QSettings settings
        settings.beginGroup("BrowserMainWindow")
        QtCore.QByteArray data = saveState(False)
        settings.setValue("defaultState", data)
        settings.endGroup()
    }
    static const qint32 BrowserMainWindowMagic = 0xba
    QtCore.QByteArray BrowserMainWindow.saveState(bool withTabs) const
    {
        int version = 2
        QtCore.QByteArray data
        QtCore.QDataStream stream(&data, QtCore.QIODevice.WriteOnly)
        stream << qint32(BrowserMainWindowMagic)
        stream << qint32(version)
        stream << size()
        stream << !self._navigationBar.isHidden()
        stream << !self._bookmarksToolbar.isHidden()
        stream << !statusBar().isHidden()
        if withTabs)
            stream << tabWidget().saveState()
        else
            stream << QtCore.QByteArray()
        return data
    }
    bool BrowserMainWindow.restoreState(const QtCore.QByteArray &state)
    {
        int version = 2
        QtCore.QByteArray sd = state
        QtCore.QDataStream stream(&sd, QtCore.QIODevice.ReadOnly)
        if stream.atEnd())
            return False
        qint32 marker
        qint32 v
        stream >> marker
        stream >> v
        if marker != BrowserMainWindowMagic or v != version)
            return False
        QtCore.QSize size
        bool showToolbar
        bool showBookmarksBar
        bool showStatusbar
        QtCore.QByteArray tabState
        stream >> size
        stream >> showToolbar
        stream >> showBookmarksBar
        stream >> showStatusbar
        stream >> tabState
        resize(size)
        self._navigationBar.setVisible(showToolbar)
        updateToolbarActionText(showToolbar)
        self._bookmarksToolbar.setVisible(showBookmarksBar)
        updateBookmarksToolbarActionText(showBookmarksBar)
        statusBar().setVisible(showStatusbar)
        updateStatusbarActionText(showStatusbar)
        if not tabWidget().restoreState(tabState))
            return False
        return True
    }
    def setupMenu()
    {
        new QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_F6), self.slotSwapFocus)
        # File
        QtGui.QMenu *fileMenu = menuBar().addMenu(tr("&File"))
        fileMenu.addAction(tr("&New Window"), self, SLOT(slotFileNew()), QtGui.QKeySequence.New)
        fileMenu.addAction(self._tabWidget.newTabAction())
        fileMenu.addAction(tr("&Open File..."), self, SLOT(slotFileOpen()), QtGui.QKeySequence.Open)
        fileMenu.addAction(tr("Open &Location..."), self,
                    SLOT(slotSelectLineEdit()), QtGui.QKeySequence(QtCore.Qt.ControlModifier + QtCore.Qt.Key_L))
        fileMenu.addSeparator()
        fileMenu.addAction(self._tabWidget.closeTabAction())
        fileMenu.addSeparator()
        fileMenu.addAction(tr("&Save As..."), self,
                    SLOT(slotFileSaveAs()), QtGui.QKeySequence(QtGui.QKeySequence.Save))
        fileMenu.addSeparator()
        BookmarksManager *bookmarksManager = BrowserApplication.bookmarksManager()
        fileMenu.addAction(tr("&Import Bookmarks..."), bookmarksManager.importBookmarks)
        fileMenu.addAction(tr("&Export Bookmarks..."), bookmarksManager.exportBookmarks)
        fileMenu.addSeparator()
        fileMenu.addAction(tr("P&rint Preview..."), self.slotFilePrintPreview)
        fileMenu.addAction(tr("&Print..."), self, SLOT(slotFilePrint()), QtGui.QKeySequence.Print)
        fileMenu.addSeparator()
        QtGui.QAction *action = fileMenu.addAction(tr("Private &Browsing..."), self.slotPrivateBrowsing)
        action.setCheckable(True)
        fileMenu.addSeparator()
    #if defined(Q_WS_MAC)
        fileMenu.addAction(tr("&Quit"), BrowserApplication.instance(), SLOT(quitBrowser()), QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_Q))
    #else
        fileMenu.addAction(tr("&Quit"), self, SLOT(close()), QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_Q))
    #endif
        # Edit
        QtGui.QMenu *editMenu = menuBar().addMenu(tr("&Edit"))
        QtGui.QAction *m_undo = editMenu.addAction(tr("&Undo"))
        m_undo.setShortcuts(QtGui.QKeySequence.Undo)
        self._tabWidget.addWebAction(m_undo, QtWebKit.QWebPage.Undo)
        QtGui.QAction *m_redo = editMenu.addAction(tr("&Redo"))
        m_redo.setShortcuts(QtGui.QKeySequence.Redo)
        self._tabWidget.addWebAction(m_redo, QtWebKit.QWebPage.Redo)
        editMenu.addSeparator()
        QtGui.QAction *m_cut = editMenu.addAction(tr("Cu&t"))
        m_cut.setShortcuts(QtGui.QKeySequence.Cut)
        self._tabWidget.addWebAction(m_cut, QtWebKit.QWebPage.Cut)
        QtGui.QAction *m_copy = editMenu.addAction(tr("&Copy"))
        m_copy.setShortcuts(QtGui.QKeySequence.Copy)
        self._tabWidget.addWebAction(m_copy, QtWebKit.QWebPage.Copy)
        QtGui.QAction *m_paste = editMenu.addAction(tr("&Paste"))
        m_paste.setShortcuts(QtGui.QKeySequence.Paste)
        self._tabWidget.addWebAction(m_paste, QtWebKit.QWebPage.Paste)
        editMenu.addSeparator()
        QtGui.QAction *m_find = editMenu.addAction(tr("&Find"))
        m_find.setShortcuts(QtGui.QKeySequence.Find)
        m_find.triggered.connect(self.slotEditFind)
        new QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Slash), self.slotEditFind)
        QtGui.QAction *m_findNext = editMenu.addAction(tr("&Find Next"))
        m_findNext.setShortcuts(QtGui.QKeySequence.FindNext)
        m_findNext.triggered.connect(self.slotEditFindNext)
        QtGui.QAction *m_findPrevious = editMenu.addAction(tr("&Find Previous"))
        m_findPrevious.setShortcuts(QtGui.QKeySequence.FindPrevious)
        m_findPrevious.triggered.connect(self.slotEditFindPrevious)
        editMenu.addSeparator()
        editMenu.addAction(tr("&Preferences"), self, SLOT(slotPreferences()), tr("Ctrl+,"))
        # View
        QtGui.QMenu *viewMenu = menuBar().addMenu(tr("&View"))
        m_viewBookmarkBar = new QtGui.QAction(self)
        updateBookmarksToolbarActionText(True)
        m_viewBookmarkBar.setShortcut(tr("Shift+Ctrl+B"))
        m_viewBookmarkBar.triggered.connect(self.slotViewBookmarksBar)
        viewMenu.addAction(m_viewBookmarkBar)
        m_viewToolbar = new QtGui.QAction(self)
        updateToolbarActionText(True)
        m_viewToolbar.setShortcut(tr("Ctrl+|"))
        m_viewToolbar.triggered.connect(self.slotViewToolbar)
        viewMenu.addAction(m_viewToolbar)
        m_viewStatusbar = new QtGui.QAction(self)
        updateStatusbarActionText(True)
        m_viewStatusbar.setShortcut(tr("Ctrl+/"))
        m_viewStatusbar.triggered.connect(self.slotViewStatusbar)
        viewMenu.addAction(m_viewStatusbar)
        viewMenu.addSeparator()
        self._stop = viewMenu.addAction(tr("&Stop"))
        QList<QtGui.QKeySequence> shortcuts
        shortcuts.append(QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_Period))
        shortcuts.append(QtCore.Qt.Key_Escape)
        self._stop.setShortcuts(shortcuts)
        self._tabWidget.addWebAction(self._stop, QtWebKit.QWebPage.Stop)
        self._reload = viewMenu.addAction(tr("Reload Page"))
        self._reload.setShortcuts(QtGui.QKeySequence.Refresh)
        self._tabWidget.addWebAction(self._reload, QtWebKit.QWebPage.Reload)
        viewMenu.addAction(tr("Zoom &In"), self, SLOT(slotViewZoomIn()), QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_Plus))
        viewMenu.addAction(tr("Zoom &Out"), self, SLOT(slotViewZoomOut()), QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_Minus))
        viewMenu.addAction(tr("Reset &Zoom"), self, SLOT(slotViewResetZoom()), QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_0))
        QtGui.QAction *zoomTextOnlyAction = viewMenu.addAction(tr("Zoom &Text Only"))
        zoomTextOnlyAction.toggled.connect(self.slotViewZoomTextOnly)
        zoomTextOnlyAction.setCheckable(True)
        zoomTextOnlyAction.setChecked(False)
        viewMenu.addSeparator()
        viewMenu.addAction(tr("Page S&ource"), self, SLOT(slotViewPageSource()), tr("Ctrl+Alt+U"))
        QtGui.QAction *a = viewMenu.addAction(tr("&Full Screen"), self, SLOT(slotViewFullScreen(bool)),  QtCore.Qt.Key_F11)
        a.setCheckable(True)
        # History
        HistoryMenu *historyMenu = new HistoryMenu(self)
        historyMenu.openUrl.connect(
                self._tabWidget.loadUrlInCurrentTab)
        historyMenu.hovered.connect( self,
                SLOT(slotUpdateStatusbar(QtCore.QString)))
        historyMenu.setTitle(tr("Hi&story"))
        menuBar().addMenu(historyMenu)
        QList<QtGui.QAction*> historyActions
        self._historyBack = new QtGui.QAction(tr("Back"), this)
        self._tabWidget.addWebAction(self._historyBack, QtWebKit.QWebPage.Back)
        self._historyBack.setShortcuts(QtGui.QKeySequence.Back)
        self._historyBack.setIconVisibleInMenu(False)
        self._historyForward = new QtGui.QAction(tr("Forward"), this)
        self._tabWidget.addWebAction(self._historyForward, QtWebKit.QWebPage.Forward)
        self._historyForward.setShortcuts(QtGui.QKeySequence.Forward)
        self._historyForward.setIconVisibleInMenu(False)
        QtGui.QAction *m_historyHome = new QtGui.QAction(tr("Home"), this)
        m_historyHome.triggered.connect(self.slotHome)
        m_historyHome.setShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.SHIFT | QtCore.Qt.Key_H))
        m_restoreLastSession = new QtGui.QAction(tr("Restore Last Session"), this)
        m_restoreLastSession.triggered.connect(BrowserApplication.instance().restoreLastSession)
        m_restoreLastSession.setEnabled(BrowserApplication.instance().canRestoreSession())
        historyActions.append(self._historyBack)
        historyActions.append(self._historyForward)
        historyActions.append(m_historyHome)
        historyActions.append(self._tabWidget.recentlyClosedTabsAction())
        historyActions.append(m_restoreLastSession)
        historyMenu.setInitialActions(historyActions)
        # Bookmarks
        BookmarksMenu *bookmarksMenu = new BookmarksMenu(self)
        bookmarksMenu.openUrl.connect(
                self._tabWidget.loadUrlInCurrentTab)
        bookmarksMenu.hovered.connect(
                self.slotUpdateStatusbar)
        bookmarksMenu.setTitle(tr("&Bookmarks"))
        menuBar().addMenu(bookmarksMenu)
        QList<QtGui.QAction*> bookmarksActions
        QtGui.QAction *showAllBookmarksAction = new QtGui.QAction(tr("Show All Bookmarks"), this)
        showAllBookmarksAction.triggered.connect(self.slotShowBookmarksDialog)
        m_addBookmark = new QtGui.QAction(QtGui.QIcon(":addbookmark.png")), tr("Add Bookmark...", this)
        m_addBookmark.setIconVisibleInMenu(False)
        m_addBookmark.triggered.connect(self.slotAddBookmark)
        m_addBookmark.setShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL | QtCore.Qt.Key_D))
        bookmarksActions.append(showAllBookmarksAction)
        bookmarksActions.append(m_addBookmark)
        bookmarksMenu.setInitialActions(bookmarksActions)
        # Window
        m_windowMenu = menuBar().addMenu(tr("&Window"))
        m_windowMenu.aboutToShow.connect(
                self.slotAboutToShowWindowMenu)
        slotAboutToShowWindowMenu()
        QtGui.QMenu *toolsMenu = menuBar().addMenu(tr("&Tools"))
        toolsMenu.addAction(tr("Web &Search"), self.slotWebSearch()), QtGui.QKeySequence(tr)
        a = toolsMenu.addAction(tr("Enable Web &Inspector"), self.slotToggleInspector)
        a.setCheckable(True)
        QtGui.QMenu *helpMenu = menuBar().addMenu(tr("&Help"))
        helpMenu.addAction(tr("About &QtCore.Qt"), qApp.aboutQt)
        helpMenu.addAction(tr("About &Demo Browser"), self.slotAboutApplication)
    }
    def setupToolBar()
    {
        setUnifiedTitleAndToolBarOnMac(True)
        self._navigationBar = addToolBar(tr("Navigation"))
        self._navigationBar.toggleViewAction().toggled.connect(
                self.updateToolbarActionText)
        self._historyBack.setIcon(style().standardIcon(QtGui.QStyle.SP_ArrowBack, 0, this))
        self._historyBackMenu = new QtGui.QMenu(self)
        self._historyBack.setMenu(self._historyBackMenu)
        self._historyBackMenu.aboutToShow.connect(
                self.slotAboutToShowBackMenu)
        self._historyBackMenu.triggered.connect(
                self.slotOpenActionUrl)
        self._navigationBar.addAction(self._historyBack)
        self._historyForward.setIcon(style().standardIcon(QtGui.QStyle.SP_ArrowForward, 0, this))
        self._historyForwardMenu = new QtGui.QMenu(self)
        self._historyForwardMenu.aboutToShow.connect(
                self.slotAboutToShowForwardMenu)
        self._historyForwardMenu.triggered.connect(
                self.slotOpenActionUrl)
        self._historyForward.setMenu(self._historyForwardMenu)
        self._navigationBar.addAction(self._historyForward)
        self._stopReload = new QtGui.QAction(self)
        self._reloadIcon = style().standardIcon(QtGui.QStyle.SP_BrowserReload)
        self._stopReload.setIcon(self._reloadIcon)
        self._navigationBar.addAction(self._stopReload)
        self._navigationBar.addWidget(self._tabWidget.lineEditStack())
        m_toolbarSearch = new ToolbarSearch(self._navigationBar)
        self._navigationBar.addWidget(m_toolbarSearch)
        m_toolbarSearch.search.connect( SLOT(loadUrl(QtCore.QUrl)))
        m_chaseWidget = new ChaseWidget(self)
        self._navigationBar.addWidget(m_chaseWidget)
    }
    def slotShowBookmarksDialog()
    {
        BookmarksDialog *dialog = new BookmarksDialog(self)
        dialog.openUrl.connect(
                self._tabWidget.loadUrlInCurrentTab)
        dialog.show()
    }
    def slotAddBookmark()
    {
        WebView *webView = currentTab()
        QtCore.QString url = webView.url().toString()
        QtCore.QString title = webView.title()
        AddBookmarkDialog dialog(url, title)
        dialog.exec()
    }
    def slotViewToolbar()
    {
        if self._navigationBar.isVisible()) {
            updateToolbarActionText(False)
            self._navigationBar.close()
        } else {
            updateToolbarActionText(True)
            self._navigationBar.show()
        }
        self._autoSaver.changeOccurred()
    }
    def slotViewBookmarksBar()
    {
        if self._bookmarksToolbar.isVisible()) {
            updateBookmarksToolbarActionText(False)
            self._bookmarksToolbar.close()
        } else {
            updateBookmarksToolbarActionText(True)
            self._bookmarksToolbar.show()
        }
        self._autoSaver.changeOccurred()
    }
    def updateStatusbarActionText(bool visible)
    {
        m_viewStatusbar.setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar"))
    }
    def updateToolbarActionText(bool visible)
    {
        m_viewToolbar.setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar"))
    }
    def updateBookmarksToolbarActionText(bool visible)
    {
        m_viewBookmarkBar.setText(!visible ? tr("Show Bookmarks bar") : tr("Hide Bookmarks bar"))
    }
    def slotViewStatusbar()
    {
        if statusBar().isVisible()) {
            updateStatusbarActionText(False)
            statusBar().close()
        } else {
            updateStatusbarActionText(True)
            statusBar().show()
        }
        self._autoSaver.changeOccurred()
    }
    def loadUrl(const QtCore.QUrl &url)
    {
        if not currentTab() or !url.isValid())
            return
        self._tabWidget.currentLineEdit().setText(QtCore.QString.fromUtf8(url.toEncoded()))
        self._tabWidget.loadUrlInCurrentTab(url)
    }
    def slotDownloadManager()
    {
        BrowserApplication.downloadManager().show()
    }
    def slotSelectLineEdit()
    {
        self._tabWidget.currentLineEdit().selectAll()
        self._tabWidget.currentLineEdit().setFocus()
    }
    def slotFileSaveAs()
    {
        BrowserApplication.downloadManager().download(currentTab().url(), True)
    }
    def slotPreferences()
    {
        SettingsDialog *s = new SettingsDialog(self)
        s.show()
    }
    def slotUpdateStatusbar(const QtCore.QString &string)
    {
        statusBar().showMessage(string, 2000)
    }
    def slotUpdateWindowTitle(const QtCore.QString &title)
    {
        if title.isEmpty()) {
            setWindowTitle(tr("QtCore.Qt Demo Browser"))
        } else {
    #if defined(Q_WS_MAC)
            setWindowTitle(title)
    #else
            setWindowTitle(tr("%1 - QtCore.Qt Demo Browser", "Page title and Browser name").arg(title))
    #endif
        }
    }
    def slotAboutApplication()
    {
        QtGui.QMessageBox.about(this, tr("About"), tr(
            "Version %1"
            "<p>This demo demonstrates QtCore.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(QtCore.QCoreApplication.applicationVersion()))
    }
    def slotFileNew()
    {
        BrowserApplication.instance().newMainWindow()
        BrowserMainWindow *mw = BrowserApplication.instance().mainWindow()
        mw.slotHome()
    }
    def slotFileOpen()
    {
        QtCore.QString file = QtGui.QFileDialog.getOpenFileName(this, tr("Open Web Resource"), QtCore.QString(),
                tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)"))
        if file.isEmpty())
            return
        loadPage(file)
    }
    def slotFilePrintPreview()
    {
    #ifndef QT_NO_PRINTER
        if not currentTab())
            return
        QtGui.QPrintPreviewDialog *dialog = new QtGui.QPrintPreviewDialog(self)
        dialog.paintRequested.connect(
                currentTab().print)
        dialog.exec()
    #endif
    }
    def slotFilePrint()
    {
        if not currentTab())
            return
        printRequested(currentTab().page().mainFrame())
    }
    def printRequested(QtWebKit.QWebFrame *frame)
    {
    #ifndef QT_NO_PRINTER
        QtGui.QPrinter printer
        QtGui.QPrintDialog *dialog = new QtGui.QPrintDialog(&printer, this)
        dialog.setWindowTitle(tr("Print Document"))
        if dialog.exec() != QtGui.QDialog.Accepted)
            return
        frame.print(&printer)
    #endif
    }
    def slotPrivateBrowsing()
    {
        QtWebKit.QWebSettings *settings = QtWebKit.QWebSettings.globalSettings()
        bool pb = settings.testAttribute(QtWebKit.QWebSettings.PrivateBrowsingEnabled)
        if not pb) {
            QtCore.QString title = tr("Are you sure you want to turn on private browsing?")
            QtCore.QString text = tr("<b>%1</b><br><br>When private browsing in turned on,"
                " webpages are not added to the history,"
                " items are automatically removed from the Downloads window," \
                " new cookies are not stored, current cookies can't be accessed," \
                " site icons wont be stored, session wont be saved, " \
                " and searches are not added to the pop-up menu in the Google search box." \
                "  Until you close the window, you can still click the Back and Forward buttons" \
                " to return to the webpages you have opened.").arg(title)
            QtGui.QMessageBox.StandardButton button = QtGui.QMessageBox.question(this, QtCore.QString(), text,
                                   QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel,
                                   QtGui.QMessageBox.Ok)
            if button == QtGui.QMessageBox.Ok) {
                settings.setAttribute(QtWebKit.QWebSettings.PrivateBrowsingEnabled, True)
            }
        } else {
            settings.setAttribute(QtWebKit.QWebSettings.PrivateBrowsingEnabled, False)
            QList<BrowserMainWindow*> windows = BrowserApplication.instance().mainWindows()
            for (int i = 0; i < windows.count(); ++i) {
                BrowserMainWindow *window = windows.at(i)
                window.m_lastSearch = QtCore.QString.null
                window.tabWidget().clear()
            }
        }
    }
    def closeEvent(QtGui.QCloseEvent *event)
    {
        if self._tabWidget.count() > 1) {
            int ret = QtGui.QMessageBox.warning(this, QtCore.QString(),
                               tr("Are you sure you want to close the window?"
                                  "  There are %1 tabs open").arg(self._tabWidget.count()),
                               QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                               QtGui.QMessageBox.No)
            if ret == QtGui.QMessageBox.No) {
                event.ignore()
                return
            }
        }
        event.accept()
        deleteLater()
    }
    def slotEditFind()
    {
        if not currentTab())
            return
        bool ok
        QtCore.QString search = QtGui.QInputDialog.getText(this, tr("Find"),
                                              tr("Text:"), QtGui.QLineEdit.Normal,
                                              m_lastSearch, &ok)
        if ok and !search.isEmpty()) {
            m_lastSearch = search
            if not currentTab().findText(m_lastSearch))
                slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch))
        }
    }
    def slotEditFindNext()
    {
        if not currentTab() and !m_lastSearch.isEmpty())
            return
        currentTab().findText(m_lastSearch)
    }
    def slotEditFindPrevious()
    {
        if not currentTab() and !m_lastSearch.isEmpty())
            return
        currentTab().findText(m_lastSearch, QtWebKit.QWebPage.FindBackward)
    }
    def slotViewZoomIn()
    {
        if not currentTab())
            return
        currentTab().setZoomFactor(currentTab().zoomFactor() + 0.1)
    }
    def slotViewZoomOut()
    {
        if not currentTab())
            return
        currentTab().setZoomFactor(currentTab().zoomFactor() - 0.1)
    }
    def slotViewResetZoom()
    {
        if not currentTab())
            return
        currentTab().setZoomFactor(1.0)
    }
    def slotViewZoomTextOnly(bool enable)
    {
        if not currentTab())
            return
        currentTab().page().settings().setAttribute(QtWebKit.QWebSettings.ZoomTextOnly, enable)
    }
    def slotViewFullScreen(bool makeFullScreen)
    {
        if makeFullScreen) {
            showFullScreen()
        } else {
            if isMinimized())
                showMinimized()
            else if isMaximized())
                showMaximized()
            else showNormal()
        }
    }
    def slotViewPageSource()
    {
        if not currentTab())
            return
        QtCore.QString markup = currentTab().page().mainFrame().toHtml()
        QtGui.QPlainTextEdit *view = new QtGui.QPlainTextEdit(markup)
        view.setWindowTitle(tr("Page Source of %1").arg(currentTab().title()))
        view.setMinimumWidth(640)
        view.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        view.show()
    }
    def slotHome()
    {
        QtCore.QSettings settings
        settings.beginGroup("MainWindow")
        QtCore.QString home = settings.value("home"), QtCore.QLatin1String("http:#qt.nokia.com/").toString()
        loadPage(home)
    }
    def slotWebSearch()
    {
        m_toolbarSearch.lineEdit().selectAll()
        m_toolbarSearch.lineEdit().setFocus()
    }
    def slotToggleInspector(bool enable)
    {
        QtWebKit.QWebSettings.globalSettings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, enable)
        if enable) {
            int result = QtGui.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?"),
                                               QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
            if result == QtGui.QMessageBox.Yes) {
                self._tabWidget.reloadAllTabs()
            }
        }
    }
    def slotSwapFocus()
    {
        if currentTab().hasFocus())
            self._tabWidget.currentLineEdit().setFocus()
        else
            currentTab().setFocus()
    }
    def loadPage(const QtCore.QString &page)
    {
        QtCore.QUrl url = QtCore.QUrl.fromUserInput(page)
        loadUrl(url)
    }
    TabWidget *BrowserMainWindow.tabWidget() const
    {
        return self._tabWidget
    }
    WebView *BrowserMainWindow.currentTab() const
    {
        return self._tabWidget.currentWebView()
    }
    def slotLoadProgress(int progress)
    {
        if progress < 100 and progress > 0) {
            m_chaseWidget.setAnimated(True)
            disself._stopReload.triggered.connect(self._reload.trigger)
            if self._stopIcon.isNull())
                self._stopIcon = style().standardIcon(QtGui.QStyle.SP_BrowserStop)
            self._stopReload.setIcon(self._stopIcon)
            self._stopReload.triggered.connect(self._stop.trigger)
            self._stopReload.setToolTip(tr("Stop loading the current page"))
        } else {
            m_chaseWidget.setAnimated(False)
            disself._stopReload.triggered.connect(self._stop.trigger)
            self._stopReload.setIcon(self._reloadIcon)
            self._stopReload.triggered.connect(self._reload.trigger)
            self._stopReload.setToolTip(tr("Reload the current page"))
        }
    }
    def slotAboutToShowBackMenu()
    {
        self._historyBackMenu.clear()
        if not currentTab())
            return
        QtWebKit.QWebHistory *history = currentTab().history()
        int historyCount = history.count()
        for (int i = history.backItems(historyCount).count() - 1; i >= 0; --i) {
            QtWebKit.QWebHistoryItem item = history.backItems(history.count()).at(i)
            QtGui.QAction *action = new QtGui.QAction(self)
            action.setData(-1*(historyCount-i-1))
            QtGui.QIcon icon = BrowserApplication.instance().icon(item.url())
            action.setIcon(icon)
            action.setText(item.title())
            self._historyBackMenu.addAction(action)
        }
    }
    def slotAboutToShowForwardMenu()
    {
        self._historyForwardMenu.clear()
        if not currentTab())
            return
        QtWebKit.QWebHistory *history = currentTab().history()
        int historyCount = history.count()
        for (int i = 0; i < history.forwardItems(history.count()).count(); ++i) {
            QtWebKit.QWebHistoryItem item = history.forwardItems(historyCount).at(i)
            QtGui.QAction *action = new QtGui.QAction(self)
            action.setData(historyCount-i)
            QtGui.QIcon icon = BrowserApplication.instance().icon(item.url())
            action.setIcon(icon)
            action.setText(item.title())
            self._historyForwardMenu.addAction(action)
        }
    }
    def slotAboutToShowWindowMenu()
    {
        m_windowMenu.clear()
        m_windowMenu.addAction(self._tabWidget.nextTabAction())
        m_windowMenu.addAction(self._tabWidget.previousTabAction())
        m_windowMenu.addSeparator()
        m_windowMenu.addAction(tr("Downloads"), self.slotDownloadManager()), QtGui.QKeySequence(tr)
        m_windowMenu.addSeparator()
        QList<BrowserMainWindow*> windows = BrowserApplication.instance().mainWindows()
        for (int i = 0; i < windows.count(); ++i) {
            BrowserMainWindow *window = windows.at(i)
            QtGui.QAction *action = m_windowMenu.addAction(window.windowTitle(), self.slotShowWindow)
            action.setData(i)
            action.setCheckable(True)
            if window == this)
                action.setChecked(True)
        }
    }
    def slotShowWindow()
    {
        if QtGui.QAction *action = qobject_cast<QtGui.QAction*>(sender())) {
            QtCore.QVariant v = action.data()
            if v.canConvert<int>()) {
                int offset = qvariant_cast<int>(v)
                QList<BrowserMainWindow*> windows = BrowserApplication.instance().mainWindows()
                windows.at(offset).activateWindow()
                windows.at(offset).currentTab().setFocus()
            }
        }
    }
    def slotOpenActionUrl(QtGui.QAction *action)
    {
        int offset = action.data().toInt()
        QtWebKit.QWebHistory *history = currentTab().history()
        if offset < 0)
            history.goToItem(history.backItems(-1*offset).first()); # back
        else if offset > 0)
            history.goToItem(history.forwardItems(history.count() - offset + 1).back()); # forward
     }
    def geometryChangeRequested(const QtCore.QRect &geometry)
    {
        setGeometry(geometry)
    }

