# -*- coding: utf-8 -*-

# Copyright (c) 2002 - 2007 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the helpviewer main window.
"""

import os

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from KdeQt import KQFileDialog, KQMessageBox
import KdeQt.KQPrinter
from KdeQt.KQPrintDialog import KQPrintDialog

from BookmarkDialog import BookmarkDialog
from SearchDialog import SearchDialog
from HelpBrowser import HelpBrowser

from E4Gui.E4TabWidget import E4TabWidget
from E4Gui.E4Action import E4Action

import Preferences
import UI.PixmapCache
import UI.Config

from ThirdParty.compactpath import compactpath

class HelpWindow(QMainWindow):
    """
    Class implementing the helpviewer main window.
    
    @signal helpClosed() emitted after the window was requested to close down
    """
    helpwindows = []
    mBookmarks = {
        "Names" : QStringList(),
        "Files" : QStringList()
    }
    editBMDialog = None

    maxMenuFilePathLen = 75
    
    def __init__(self, home, path, parent, name, fromEric = False):
        """
        Constructor
        
        @param home the helpfile to be shown (string or QString)
        @param path the path of the working dir (usually '.') (string or QString)
        @param parent parent widget of this window (QWidget)
        @param name name of this window (string or QString)
        @param fromEric flag indicating whether it was called from within eric4 (boolean)
        """
        QMainWindow.__init__(self,parent)
        self.setObjectName(name)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle(self.trUtf8("eric4 Help Viewer"))
        
        self.fromEric = fromEric
        self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))

        self.mHistory = QStringList()
        self.pathCombo = None
        
        self.__readHistory()
        if not len(self.__class__.mBookmarks["Names"]):
            self.__readBookmarks()
        
        self.tabContextMenuIndex = -1
        self.tabWidget = E4TabWidget(self)
        self.connect(self.tabWidget, SIGNAL('currentChanged(int)'),
            self.__currentChanged)
        self.tabWidget.setTabContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.tabWidget, 
                     SIGNAL('customTabContextMenuRequested(const QPoint &, int)'),
                     self.__showContextMenu)
        
        self.setCentralWidget(self.tabWidget)
        
        self.closeButton = QToolButton(self.tabWidget)
        self.closeButton.setIcon(UI.PixmapCache.getIcon("close.png"))
        self.closeButton.setToolTip(self.trUtf8("Close the current help window"))
        self.closeButton.setEnabled(False)
        self.tabWidget.setCornerWidget(self.closeButton, Qt.TopRightCorner)
        self.connect(self.closeButton, SIGNAL("clicked(bool)"), self.__close)
        
        self.newTabButton = QToolButton(self.tabWidget)
        self.newTabButton.setIcon(UI.PixmapCache.getIcon("new.png"))
        self.newTabButton.setToolTip(self.trUtf8("Open a new help window tab"))
        self.tabWidget.setCornerWidget(self.newTabButton, Qt.TopLeftCorner)
        self.connect(self.newTabButton, SIGNAL("clicked(bool)"), self.newTab)
        
        self.findDlg = SearchDialog(self, 'Find')
        
        if Preferences.getHelp("SaveGeometry"):
            g = Preferences.getGeometry("HelpViewerGeometry")
        else:
            g = QByteArray()
        if g.isEmpty():
            s = QSize(700, 800)
            self.resize(s)
        else:
            self.restoreGeometry(g)
        
        self.__initActions()
        self.__initMenus()
        self.__initToolbars()
        self.__initTabContextMenu()
        
        self.newBrowser(home)
        self.currentBrowser().setFocus()
        
        self.__class__.helpwindows.append(self)
        
        # generate the edit bookmarks dialog
        if self.__class__.editBMDialog is None:
            self.__class__.editBMDialog = BookmarkDialog(self)
        
    def __initActions(self):
        """
        Private method to define the user interface actions.
        """
        # list of all actions
        self.__actions = []
        
        self.newTabAct = E4Action(self.trUtf8('New Tab'), 
            UI.PixmapCache.getIcon("new.png"),
            self.trUtf8('&New Tab'), 
            QKeySequence(self.trUtf8("Ctrl+T","File|New Tab")), 
            0, self, 'help_file_new_tab')
        self.newTabAct.setStatusTip(self.trUtf8('Open a new help window tab'))
        self.newTabAct.setWhatsThis(self.trUtf8(
                """<b>New Tab</b>"""
                """<p>This opens a new help window tab.</p>"""
        ))
        self.newTabAct.connectIt(SIGNAL('triggered()'), self.newTab)
        self.__actions.append(self.newTabAct)
        
        self.newAct = E4Action(self.trUtf8('New Window'), 
            UI.PixmapCache.getIcon("newWindow.png"),
            self.trUtf8('N&ew Window'), 
            QKeySequence(self.trUtf8("Ctrl+N","File|New Window")), 
            0, self, 'help_file_new_window')
        self.newAct.setStatusTip(self.trUtf8('Open a new help browser window'))
        self.newAct.setWhatsThis(self.trUtf8(
                """<b>New Window</b>"""
                """<p>This opens a new help browser window.</p>"""
        ))
        self.newAct.connectIt(SIGNAL('triggered()'), self.newWindow)
        self.__actions.append(self.newAct)
        
        self.openAct = E4Action(self.trUtf8('Open File'), 
            UI.PixmapCache.getIcon("open.png"),
            self.trUtf8('&Open File'), 
            QKeySequence(self.trUtf8("Ctrl+O","File|Open")), 
            0, self, 'help_file_open')
        self.openAct.setStatusTip(self.trUtf8('Open a help file for display'))
        self.openAct.setWhatsThis(self.trUtf8(
                """<b>Open File</b>"""
                """<p>This opens a new help file for display."""
                """ It pops up a file selection dialog.</p>"""
        ))
        self.openAct.connectIt(SIGNAL('triggered()'), self.__openFile)
        self.__actions.append(self.openAct)
        
        self.openTabAct = E4Action(self.trUtf8('Open File in New Tab'), 
            UI.PixmapCache.getIcon("openNewTab.png"),
            self.trUtf8('Open File in New &Tab'), 
            QKeySequence(self.trUtf8("Shift+Ctrl+O","File|Open in new tab")), 
            0, self, 'help_file_open_tab')
        self.openTabAct.setStatusTip(\
            self.trUtf8('Open a help file for display in a new tab'))
        self.openTabAct.setWhatsThis(self.trUtf8(
                """<b>Open File in New Tab</b>"""
                """<p>This opens a new help file for display in a new tab."""
                """ It pops up a file selection dialog.</p>"""
        ))
        self.openTabAct.connectIt(SIGNAL('triggered()'), self.__openFileNewTab)
        self.__actions.append(self.openTabAct)
        
        self.printAct = E4Action(self.trUtf8('Print'), 
            UI.PixmapCache.getIcon("print.png"),
            self.trUtf8('&Print'), 
            QKeySequence(self.trUtf8("Ctrl+P","File|Print")), 
            0, self, 'help_file_print')
        self.printAct.setStatusTip(self.trUtf8('Print the displayed help'))
        self.printAct.setWhatsThis(self.trUtf8(
                """<b>Print</b>"""
                """<p>Print the displayed help text.</p>"""
        ))
        self.printAct.connectIt(SIGNAL('triggered()'), self.__printFile)
        self.__actions.append(self.printAct)
        
        self.closeAct = E4Action(self.trUtf8('Close'), 
            UI.PixmapCache.getIcon("close.png"),
            self.trUtf8('&Close'), 
            QKeySequence(self.trUtf8("Ctrl+W","File|Close")), 
            0, self, 'help_file_close')
        self.closeAct.setStatusTip(self.trUtf8('Close the current help window'))
        self.closeAct.setWhatsThis(self.trUtf8(
                """<b>Close</b>"""
                """<p>Closes the current help window.</p>"""
        ))
        self.closeAct.connectIt(SIGNAL('triggered()'), self.__close)
        self.__actions.append(self.closeAct)
        
        self.closeAllAct = E4Action(self.trUtf8('Close All'), 
            self.trUtf8('Close &All'), 
            0, 0, self, 'help_file_close_all')
        self.closeAllAct.setStatusTip(self.trUtf8('Close the all help windows'))
        self.closeAllAct.setWhatsThis(self.trUtf8(
                """<b>Close All</b>"""
                """<p>Closes all help windows except the first one.</p>"""
        ))
        self.closeAllAct.connectIt(SIGNAL('triggered()'), self.__closeAll)
        self.__actions.append(self.closeAllAct)
        
        self.exitAct = E4Action(self.trUtf8('Quit'), 
            UI.PixmapCache.getIcon("exit.png"),
            self.trUtf8('&Quit'), 
            QKeySequence(self.trUtf8("Ctrl+Q","File|Quit")), 
            0, self, 'help_file_quit')
        self.exitAct.setStatusTip(self.trUtf8('Quit the help viewer'))
        self.exitAct.setWhatsThis(self.trUtf8(
                """<b>Quit</b>"""
                """<p>Quit the help viewer.</p>"""
        ))
        if self.fromEric:
            self.exitAct.connectIt(SIGNAL('triggered()'), self, SLOT('close()'))
        else:
            self.exitAct.connectIt(SIGNAL('triggered()'), qApp, SLOT('closeAllWindows()'))
        self.__actions.append(self.exitAct)
        
        self.backAct = E4Action(self.trUtf8('Backward'), 
            UI.PixmapCache.getIcon("back.png"),
            self.trUtf8('&Backward'), 
            QKeySequence(self.trUtf8("Alt+Left","Go|Backward")), 
            QKeySequence(self.trUtf8("Backspace","Go|Backward")), 
            self, 'help_go_backward')
        self.backAct.setStatusTip(self.trUtf8('Move one help screen backward'))
        self.backAct.setWhatsThis(self.trUtf8(
                """<b>Backward</b>"""
                """<p>Moves one help screen backward. If none is"""
                """ available, this action is disabled.</p>"""
        ))
        self.backAct.connectIt(SIGNAL('triggered()'), self.__backward)
        self.__actions.append(self.backAct)
        
        self.forwardAct = E4Action(self.trUtf8('Forward'), 
            UI.PixmapCache.getIcon("forward.png"),
            self.trUtf8('&Forward'), 
            QKeySequence(self.trUtf8("Alt+Right","Go|Forward")), 
            QKeySequence(self.trUtf8("Shift+Backspace","Go|Forward")), 
            self, 'help_go_foreward')
        self.forwardAct.setStatusTip(self.trUtf8('Move one help screen forward'))
        self.forwardAct.setWhatsThis(self.trUtf8(
                """<b>Forward</b>"""
                """<p>Moves one help screen forward. If none is"""
                """ available, this action is disabled.</p>"""
        ))
        self.forwardAct.connectIt(SIGNAL('triggered()'), self.__forward)
        self.__actions.append(self.forwardAct)
        
        self.homeAct = E4Action(self.trUtf8('Home'), 
            UI.PixmapCache.getIcon("home.png"),
            self.trUtf8('&Home'), 
            QKeySequence(self.trUtf8("Ctrl+Home","Go|Home")), 
            0, self, 'help_go_home')
        self.homeAct.setStatusTip(self.trUtf8('Move to the initial help screen'))
        self.homeAct.setWhatsThis(self.trUtf8(
                """<b>Home</b>"""
                """<p>Moves to the initial help screen.</p>"""
        ))
        self.homeAct.connectIt(SIGNAL('triggered()'), self.__home)
        self.__actions.append(self.homeAct)
        
        self.reloadAct = E4Action(self.trUtf8('Reload'), 
            UI.PixmapCache.getIcon("reload.png"),
            self.trUtf8('&Reload'), 
            QKeySequence(self.trUtf8("Ctrl+R","Go|Reload")), 
            0, self, 'help_go_reload')
        self.reloadAct.setStatusTip(self.trUtf8('Reload the current help screen'))
        self.reloadAct.setWhatsThis(self.trUtf8(
                """<b>Reload</b>"""
                """<p>Reloads the current help screen.</p>"""
        ))
        self.reloadAct.connectIt(SIGNAL('triggered()'), self.__reload)
        self.__actions.append(self.reloadAct)
        
        self.copyAct = E4Action(self.trUtf8('Copy'), 
            UI.PixmapCache.getIcon("editCopy.png"),
            self.trUtf8('&Copy'), 
            QKeySequence(self.trUtf8("Ctrl+C","Edit|Copy")), 
            0, self, 'help_edit_copy')
        self.copyAct.setStatusTip(self.trUtf8('Copy the selected text'))
        self.copyAct.setWhatsThis(self.trUtf8(
                """<b>Copy</b>"""
                """<p>Copy the selected text to the clipboard.</p>"""
        ))
        self.copyAct.connectIt(SIGNAL('triggered()'), self.__copy)
        self.__actions.append(self.copyAct)
        
        self.findAct = E4Action(self.trUtf8('Find...'), 
            UI.PixmapCache.getIcon("find.png"),
            self.trUtf8('&Find...'), 
            QKeySequence(self.trUtf8("Ctrl+F","Edit|Find")), 
            0, self, 'help_edit_find')
        self.findAct.setStatusTip(self.trUtf8('Find text in page'))
        self.findAct.setWhatsThis(self.trUtf8(
                """<b>Find</b>"""
                """<p>Find text in the current page.</p>"""
        ))
        self.findAct.connectIt(SIGNAL('triggered()'), self.__find)
        self.__actions.append(self.findAct)
        
        self.findNextAct = E4Action(self.trUtf8('Find next'), 
            UI.PixmapCache.getIcon("findNext.png"),
            self.trUtf8('Find &next'), 
            QKeySequence(self.trUtf8("F3","Edit|Find next")), 
            0, self, 'help_edit_find_next')
        self.findNextAct.setStatusTip(self.trUtf8('Find next occurance of text in page'))
        self.findNextAct.setWhatsThis(self.trUtf8(
                """<b>Find next</b>"""
                """<p>Find the next occurance of text in the current page.</p>"""
        ))
        self.findNextAct.connectIt(SIGNAL('triggered()'), self.findDlg.findNext)
        self.__actions.append(self.findNextAct)
        
        self.findPrevAct = E4Action(self.trUtf8('Find previous'), 
            UI.PixmapCache.getIcon("findPrev.png"),
            self.trUtf8('Find &previous'), 
            QKeySequence(self.trUtf8("Shift+F3","Edit|Find previous")), 
            0, self, 'help_edit_find_previous')
        self.findPrevAct.setStatusTip(\
            self.trUtf8('Find previous occurance of text in page'))
        self.findPrevAct.setWhatsThis(self.trUtf8(
                """<b>Find previous</b>"""
                """<p>Find the previous occurance of text in the current page.</p>"""
        ))
        self.findPrevAct.connectIt(SIGNAL('triggered()'), self.findDlg.findPrevious)
        self.__actions.append(self.findPrevAct)
        
        self.clearHistoryAct = E4Action(self.trUtf8('Clear History'), 
            self.trUtf8('C&lear History'), 
            0, 0, self, 'help_history_clear')
        self.clearHistoryAct.setStatusTip(self.trUtf8('Clear the history information.'))
        self.clearHistoryAct.setWhatsThis(self.trUtf8(
                """<b>Clear History</b>"""
                """<p>Clears the history information.</p>"""
        ))
        self.clearHistoryAct.connectIt(SIGNAL('triggered()'), self.__clearHistory)
        self.__actions.append(self.clearHistoryAct)
        
        self.addBookmarkAct = E4Action(self.trUtf8('Add Bookmark'), 
            UI.PixmapCache.getIcon("addBookmark.png"),
            self.trUtf8('&Add Bookmark'), 
            0, 0, self, 'help_bookmark_add')
        self.addBookmarkAct.setStatusTip(self.trUtf8('Add a bookmarks.'))
        self.addBookmarkAct.setWhatsThis(self.trUtf8(
                """<b>Add Bookmark</b>"""
                """<p>Adds the currently displayed help screen to"""
                """ the list of bookmarks.</p>"""
        ))
        self.addBookmarkAct.setData(QVariant(-1))
        self.addBookmarkAct.connectIt(SIGNAL('triggered()'), self.__addBookmark)
        self.__actions.append(self.addBookmarkAct)
        
        self.editBookmarksAct = E4Action(self.trUtf8('Edit Bookmarks...'), 
            UI.PixmapCache.getIcon("editBookmarks.png"),
            self.trUtf8('&Edit Bookmarks...'), 
            0, 0, self, 'help_bookmark_edit')
        self.editBookmarksAct.setStatusTip(self.trUtf8('Edit Bookmarks'))
        self.editBookmarksAct.setWhatsThis(self.trUtf8(
                """<b>Edit Bookmarks</b>"""
                """<p>This action displayes a dialog in which you can"""
                """ change the name and the file of a bookmark as well"""
                """ as the order of the bookmarks in the menu.</p>"""
        ))
        self.editBookmarksAct.setData(QVariant(-1))
        self.editBookmarksAct.connectIt(SIGNAL('triggered()'), self.__editBookmarks)
        self.__actions.append(self.editBookmarksAct)
        
        self.whatsThisAct = E4Action(self.trUtf8('What\'s This?'), 
            UI.PixmapCache.getIcon("whatsThis.png"),
            self.trUtf8('&What\'s This?'), 
            QKeySequence(self.trUtf8("Shift+F1","Help|What's This?'")), 
            0, self, 'help_help_whats_this')
        self.whatsThisAct.setStatusTip(self.trUtf8('Context sensitive help'))
        self.whatsThisAct.setWhatsThis(self.trUtf8(
                """<b>Display context sensitive help</b>"""
                """<p>In What's This? mode, the mouse cursor shows an arrow with a"""
                """ question mark, and you can click on the interface elements to get"""
                """ a short description of what they do and how to use them. In"""
                """ dialogs, this feature can be accessed using the context help button"""
                """ in the titlebar.</p>"""
        ))
        self.whatsThisAct.connectIt(SIGNAL('triggered()'), self.__whatsThis)
        self.__actions.append(self.whatsThisAct)
        
        self.aboutAct = E4Action(self.trUtf8('About'), 
            self.trUtf8('&About'), 
            0, 0, self, 'help_help_about')
        self.aboutAct.setStatusTip(self.trUtf8('Display information about this software'))
        self.aboutAct.setWhatsThis(self.trUtf8(
                """<b>About</b>"""
                """<p>Display some information about this software.</p>"""
        ))
        self.aboutAct.connectIt(SIGNAL('triggered()'), self.__about)
        self.__actions.append(self.aboutAct)
        
        self.aboutQtAct = E4Action(self.trUtf8('About Qt'), 
            self.trUtf8('About &Qt'), 
            0, 0, self, 'help_help_about_qt')
        self.aboutQtAct.setStatusTip(\
            self.trUtf8('Display information about the Qt toolkit'))
        self.aboutQtAct.setWhatsThis(self.trUtf8(
                """<b>About Qt</b>"""
                """<p>Display some information about the Qt toolkit.</p>"""
        ))
        self.aboutQtAct.connectIt(SIGNAL('triggered()'), self.__aboutQt)
        self.__actions.append(self.aboutQtAct)
        
        self.zoomInAct = E4Action(self.trUtf8('Zoom in'), 
            UI.PixmapCache.getIcon("zoomIn.png"),
            self.trUtf8('Zoom &in'), 
            QKeySequence(self.trUtf8("Ctrl++","View|Zoom in")), 
            0, self, 'help_view_zoom_in')
        self.zoomInAct.setStatusTip(self.trUtf8('Zoom in on the text'))
        self.zoomInAct.setWhatsThis(self.trUtf8(
                """<b>Zoom in</b>"""
                """<p>Zoom in on the text. This makes the text bigger.</p>"""
        ))
        self.zoomInAct.connectIt(SIGNAL('triggered()'), self.__zoomIn)
        self.__actions.append(self.zoomInAct)
        
        self.zoomOutAct = E4Action(self.trUtf8('Zoom out'), 
            UI.PixmapCache.getIcon("zoomOut.png"),
            self.trUtf8('Zoom &out'), 
            QKeySequence(self.trUtf8("Ctrl+-","View|Zoom out")), 
            0, self, 'help_view_zoom_out')
        self.zoomOutAct.setStatusTip(self.trUtf8('Zoom out on the text'))
        self.zoomOutAct.setWhatsThis(self.trUtf8(
                """<b>Zoom out</b>"""
                """<p>Zoom out on the text. This makes the text smaller.</p>"""
        ))
        self.zoomOutAct.connectIt(SIGNAL('triggered()'), self.__zoomOut)
        self.__actions.append(self.zoomOutAct)
        
        self.backAct.setEnabled(False)
        self.forwardAct.setEnabled(False)
        
        # now read the keyboard shortcuts for the actions
        Preferences.readShortcuts(helpViewer = self)
    
    def getActions(self):
        """
        Public method to get a list of all actions.
        
        @return list of all actions (list of E4Action)
        """
        return self.__actions[:]
        
    def __initMenus(self):
        """
        Private method to create the menus.
        """
        mb = self.menuBar()
        
        menu = mb.addMenu(self.trUtf8('&File'))
        menu.setTearOffEnabled(True)
        menu.addAction(self.newTabAct)
        menu.addAction(self.newAct)
        menu.addAction(self.openAct)
        menu.addAction(self.openTabAct)
        menu.addAction(self.printAct)
        menu.addSeparator()
        menu.addAction(self.closeAct)
        menu.addAction(self.closeAllAct)
        menu.addSeparator()
        menu.addAction(self.exitAct)
        
        menu = mb.addMenu(self.trUtf8('&Edit'))
        menu.setTearOffEnabled(True)
        menu.addAction(self.copyAct)
        menu.addSeparator()
        menu.addAction(self.findAct)
        menu.addAction(self.findNextAct)
        menu.addAction(self.findPrevAct)
        
        menu = mb.addMenu(self.trUtf8('&View'))
        menu.setTearOffEnabled(True)
        menu.addAction(self.zoomInAct)
        menu.addAction(self.zoomOutAct)
        
        menu = mb.addMenu(self.trUtf8('&Go'))
        menu.setTearOffEnabled(True)
        menu.addAction(self.backAct)
        menu.addAction(self.forwardAct)
        menu.addAction(self.homeAct)
        menu.addAction(self.reloadAct)
        
        self.historyMenu = mb.addMenu(self.trUtf8('H&istory'))
        self.historyMenu.setTearOffEnabled(True)
        self.connect(self.historyMenu, SIGNAL('aboutToShow()'),
                     self.__showHistoryMenu)
        self.connect(self.historyMenu, SIGNAL('triggered(QAction *)'),
                     self.__historyChosen)
        
        self.bookmarksMenu = mb.addMenu(self.trUtf8('&Bookmarks'))
        self.bookmarksMenu.setTearOffEnabled(True)
        self.connect(self.bookmarksMenu, SIGNAL('aboutToShow()'),
                     self.__showBookmarksMenu)
        self.connect(self.bookmarksMenu, SIGNAL('triggered(QAction *)'),
                     self.__bookmarkChosen)
        
        mb.addSeparator()
        
        menu = mb.addMenu(self.trUtf8('&Help'))
        menu.setTearOffEnabled(True)
        menu.addAction(self.aboutAct)
        menu.addAction(self.aboutQtAct)
        menu.addSeparator()
        menu.addAction(self.whatsThisAct)
    
    def __initTabContextMenu(self):
        """
        Private mezhod to create the tab context menu.
        """
        self.__tabContextMenu = QMenu(self.tabWidget)
        self.leftMenuAct = \
            self.__tabContextMenu.addAction(UI.PixmapCache.getIcon("1leftarrow.png"),
            self.trUtf8('Move Left'), self.__tabContextMenuMoveLeft)
        self.rightMenuAct = \
            self.__tabContextMenu.addAction(UI.PixmapCache.getIcon("1rightarrow.png"),
            self.trUtf8('Move Right'), self.__tabContextMenuMoveRight)
        self.__tabContextMenu.addSeparator()
        self.tabContextCloseAct = \
            self.__tabContextMenu.addAction(UI.PixmapCache.getIcon("close.png"),
                self.trUtf8('Close'), self.__tabContextMenuClose)
        self.__tabContextMenu.addAction(self.closeAllAct)
        self.__tabContextMenu.addSeparator()
        self.__tabContextMenu.addAction(UI.PixmapCache.getIcon("print.png"),
            self.trUtf8('Print'), self.__tabContextMenuPrint)
    
    def __initToolbars(self):
        """
        Private method to create the toolbars.
        """
        filetb = self.addToolBar(self.trUtf8("File"))
        filetb.setIconSize(UI.Config.ToolBarIconSize)
        filetb.addAction(self.newTabAct)
        filetb.addAction(self.newAct)
        filetb.addAction(self.openAct)
        filetb.addAction(self.openTabAct)
        filetb.addAction(self.printAct)
        filetb.addSeparator()
        filetb.addAction(self.closeAct)
        filetb.addAction(self.exitAct)
        
        edittb = self.addToolBar(self.trUtf8("Edit"))
        edittb.setIconSize(UI.Config.ToolBarIconSize)
        edittb.addAction(self.copyAct)
        
        viewtb = self.addToolBar(self.trUtf8("View"))
        viewtb.setIconSize(UI.Config.ToolBarIconSize)
        viewtb.addAction(self.zoomInAct)
        viewtb.addAction(self.zoomOutAct)
        
        findtb = self.addToolBar(self.trUtf8("Find"))
        findtb.setIconSize(UI.Config.ToolBarIconSize)
        findtb.addAction(self.findAct)
        findtb.addAction(self.findNextAct)
        findtb.addAction(self.findPrevAct)
        
        bookmarktb = self.addToolBar(self.trUtf8("Bookmarks"))
        bookmarktb.setIconSize(UI.Config.ToolBarIconSize)
        bookmarktb.addAction(self.addBookmarkAct)
        bookmarktb.addAction(self.editBookmarksAct)
        
        helptb = self.addToolBar(self.trUtf8("Help"))
        helptb.setIconSize(UI.Config.ToolBarIconSize)
        helptb.addAction(self.whatsThisAct)
        
        self.addToolBarBreak()
        
        gotb = self.addToolBar(self.trUtf8("Go"))
        gotb.setIconSize(UI.Config.ToolBarIconSize)
        gotb.addAction(self.backAct)
        gotb.addAction(self.forwardAct)
        gotb.addAction(self.homeAct)
        gotb.addAction(self.reloadAct)
        gotb.addSeparator()
        
        self.pathCombo = QComboBox()
        self.pathCombo.setDuplicatesEnabled(False)
        self.pathCombo.setInsertPolicy(QComboBox.InsertAtTop)
        self.pathCombo.setEditable(1)
        self.pathCombo.setAutoCompletion(True)
        self.connect(self.pathCombo, SIGNAL('activated(const QString &)'),
                     self.__pathSelected)
        self.pathCombo.setWhatsThis(self.trUtf8(
                """<p>Enter the help file to be displayed directly into this"""
                """ edit field. Select a previously shown help file from the"""
                """ drop down list.</p>"""
        ))
        self.pathCombo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        gotb.addWidget(self.pathCombo)
        
    def __whatsThis(self):
        """
        Private slot called in to enter Whats This mode.
        """
        QWhatsThis.enterWhatsThisMode()
        
    def __showHistoryMenu(self):
        """
        Private slot called in order to show the history menu.
        """
        self.historyMenu.clear()
        self.historyMenu.addAction(self.clearHistoryAct)
        self.clearHistoryAct.setData(QVariant(-1))
        self.historyMenu.addSeparator()
        idx = 0
        for hist in self.mHistory:
            act = self.historyMenu.addAction(\
                compactpath.compactPath(unicode(hist), self.maxMenuFilePathLen))
            act.setData(QVariant(idx))
            idx += 1
        
    def __showBookmarksMenu(self):
        """
        Private slot called in order to show the bookmarks menu.
        """
        self.bookmarksMenu.clear()
        act = self.bookmarksMenu.addAction(self.addBookmarkAct)
        act = self.bookmarksMenu.addAction(self.editBookmarksAct)
        self.bookmarksMenu.addSeparator()
        idx = 0
        for bookm in self.__class__.mBookmarks["Names"]:
            act = self.bookmarksMenu.addAction(bookm)
            act.setData(QVariant(idx))
            idx += 1
        
    def __pathSelected(self, path):
        """
        Private slot called when a file is selected in the combobox.
        """
        self.currentBrowser().setSource(QUrl(path))
        
        if self.mHistory.contains(path):
            self.mHistory.removeAll(path)
            
        self.mHistory.prepend(path)
        
        if len(self.mHistory) > 20:
            self.mHistory = self.mHistory[:20]

    def __sourceChanged(self, url):
        """
        Private slot called when the displayed text of the combobox is changed.
        """
        if self.currentBrowser().documentTitle().isNull():
            self.tabWidget.setTabText(self.tabWidget.currentIndex(), url.toString())
        else:
            self.tabWidget.setTabText(self.tabWidget.currentIndex(), 
                                      self.currentBrowser().documentTitle())
        
        selectedURL = url.toString()
        
        if not selectedURL.isEmpty() and self.pathCombo:
            i = self.pathCombo.findText(selectedURL)
            if i == -1:
                self.pathCombo.insertItem(0, selectedURL)
                self.pathCombo.setCurrentIndex(0)
                if self.mHistory.contains(selectedURL):
                    self.mHistory.removeAll(selectedURL)
                    
                self.mHistory.prepend(selectedURL)
                
                if len(self.mHistory) > 20:
                    self.mHistory = self.mHistory[:20]
            else:
                self.pathCombo.setCurrentIndex(i)

    def newTab(self, link = None):
        """
        Public slot called to open a new help window tab.
        
        @param link file to be displayed in the new window (QUrl)
        """
        if link is None:
            linkName = ""
        elif isinstance(link, QUrl):
            linkName = link.toString()
        else:
            linkName = link
        self.newBrowser(linkName)
    
    def newWindow(self, link = None):
        """
        Public slot called to open a new help browser dialog.
        
        @param link file to be displayed in the new window (QUrl)
        """
        if link is None:
            linkName = ""
        elif isinstance(link, QUrl):
            linkName = link.toString()
        else:
            linkName = link
        h = HelpWindow(linkName, ".", self.parent(), "qbrowser", self.fromEric)
        h.show()
    
    def __openFile(self):
        """
        Private slot called to open a file.
        """
        fn = KQFileDialog.getOpenFileName(\
            self, self.trUtf8("Open File"),
            QString(),
            self.trUtf8("Help Files (*.html *.htm);;"
                        "PDF Files (*.pdf);;"
                        "CHM Files (*.chm);;"
                        "All Files (*)"
            ))
        if not fn.isEmpty():
            self.currentBrowser().setSource(QUrl(fn))
        
    def __openFileNewTab(self):
        """
        Private slot called to open a file in a new tab.
        """
        fn = KQFileDialog.getOpenFileName(\
            self, self.trUtf8("Open File"),
            QString(),
            self.trUtf8("Help Files (*.html *.htm);;"
                        "PDF Files (*.pdf);;"
                        "CHM Files (*.chm);;"
                        "All Files (*)"
            ))
        if not fn.isEmpty():
            self.newTab(fn)
        
    def __printFile(self, document = None):
        """
        Private slot called to print the displayed file.
        
        @param document reference to the document to be printed (QTextDocument)
        """
        printer = KdeQt.KQPrinter.KQPrinter()
        printer.setFullPage(1)
        if Preferences.getPrinter("ColorMode"):
            printer.setColorMode(KdeQt.KQPrinter.Color)
        else:
            printer.setColorMode(KdeQt.KQPrinter.GrayScale)
        if Preferences.getPrinter("FirstPageFirst"):
            printer.setPageOrder(KdeQt.KQPrinter.FirstPageFirst)
        else:
            printer.setPageOrder(KdeQt.KQPrinter.LastPageFirst)
        printer.setPrinterName(Preferences.getPrinter("PrinterName"))
        
        printDialog = KQPrintDialog(printer, self)
        if printDialog.exec_() == QDialog.Accepted:
            if document is None:
                document = self.currentBrowser().document()
            document.print_(printer)
        
    def __about(self):
        """
        Private slot to show the about information.
        """
        KQMessageBox.about(self, self.trUtf8("Helpviewer"), self.trUtf8(
            """<h3> About Helpviewer </h3>"""
            """<p>The Helpviewer window is a little HTML browser to"""
            """ display HTML help files like the Qt documentation</p>"""
        ))
        
    def __aboutQt(self):
        """
        Private slot to show info about Qt.
        """
        KQMessageBox.aboutQt(self, self.trUtf8("Helpviewer"))

    def __readHistory(self):
        """
        Private function to read the history from the eric4 preferences file.
        """
        hist = Preferences.Prefs.settings.value('History/Files')
        if hist.isValid():
            self.mHistory = hist.toStringList()
        
    def __readBookmarks(self):
        """
        Private function to read the bookmarks from the eric4 preferences file.
        """
        bmNames = Preferences.Prefs.settings.value('Bookmarks/Names')
        bmFiles = Preferences.Prefs.settings.value('Bookmarks/Files')
        
        if bmNames.isValid() and bmFiles.isValid():
            bmNames = bmNames.toStringList()
            bmFiles = bmFiles.toStringList()
            if len(bmNames) == len(bmFiles):
                self.__class__.mBookmarks["Names"] = bmNames
                self.__class__.mBookmarks["Files"] = bmFiles
        
    def writeBookmarks(self):
        """
        Public function to write the bookmarks to the eric4 preferences file.
        """
        Preferences.Prefs.settings.setValue('Bookmarks/Names',
            QVariant(self.__class__.mBookmarks["Names"]))
        Preferences.Prefs.settings.setValue('Bookmarks/Files',
            QVariant(self.__class__.mBookmarks["Files"]))

    def __setBackwardAvailable(self, b):
        """
        Private slot called when backward references are available.
        """
        self.backAct.setEnabled(b)
        
    def __setForwardAvailable(self, b):
        """
        Private slot called when forward references are available.
        """
        self.forwardAct.setEnabled(b)
        
    def __clearHistory(self):
        """
        Private slot called to clear the current history.
        """
        self.mHistory = QStringList()
        self.currentBrowser().clearHistory()
        
    def __historyChosen(self, act):
        """
        Private slot called by the history menu to display the selected file.
        
        @param act reference to the action that triggered (QAction)
        """
        idx, ok = act.data().toInt()
        if ok and idx >= 0:
            self.currentBrowser().setSource(QUrl(self.mHistory[idx]))
        
    def __bookmarkChosen(self, act):
        """
        Private slot called by the bookmarks menu to display the selected file.
        
        @param act reference to the action that triggered (QAction)
        """
        idx, ok = act.data().toInt()
        if ok and idx >= 0:
            self.currentBrowser().setSource(QUrl(self.__class__.mBookmarks["Files"][idx]))
        
    def __addBookmark(self):
        """
        Private slot called to add the displayed file to the bookmarks.
        """
        self.__class__.mBookmarks["Names"].append(\
            self.tabWidget.tabText(self.tabWidget.currentIndex()))
        self.__class__.mBookmarks["Files"].append(\
            self.currentBrowser().source().toString())
        self.writeBookmarks()
        
    def __editBookmarks(self):
        """
        Private slot called to edit the bookmarks.
        
        It opens the bookmark dialog to rearrange, delete or
        edit the collection of bookmarks.
        """
        try:
            self.__class__.editBMDialog.show()
        except:
            # regenerate the edit bookmarks dialog
            self.__class__.editBMDialog = BookmarkDialog(self)
            self.__class__.editBMDialog.show()
        
    def __find(self):
        """
        Private slot to handle the find action.
        
        It opens the search dialog in order to perform the various
        search actions and to collect the various search info.
        """
        self.findDlg.showFind()
        
    def closeEvent(self, e):
        """
        Private event handler for the close event.
        
        This handler saves the current history entries and the window
        geomety to the eric4 Preferences file.
        
        @param e the close event (QCloseEvent)
                <br />This event is simply accepted after the history has been
                saved and all window references have been deleted.
        """
        Preferences.Prefs.settings.setValue('History/Files',
            QVariant(self.mHistory))
        
        if Preferences.getHelp("SaveGeometry"):
            Preferences.setGeometry("HelpViewerGeometry", self.saveGeometry())
        else:
            Preferences.setGeometry("HelpViewerGeometry", QByteArray())
        Preferences.savePreferences()
        
        del self.__class__.helpwindows[self.__class__.helpwindows.index(self)]
        e.accept()
        self.emit(SIGNAL("helpClosed"))

    def __backward(self):
        """
        Private slot called to handle the backward action.
        """
        self.currentBrowser().backward()
    
    def __forward(self):
        """
        Private slot called to handle the forward action.
        """
        self.currentBrowser().forward()
    
    def __home(self):
        """
        Private slot called to handle the home action.
        """
        self.currentBrowser().home()
    
    def __reload(self):
        """
        Private slot called to handle the reload action.
        """
        self.currentBrowser().reload()
    
    def __zoomIn(self):
        """
        Private slot called to handle the zoom in action.
        """
        self.currentBrowser().zoomIn()
    
    def __zoomOut(self):
        """
        Private slot called to handle the zoom out action.
        """
        self.currentBrowser().zoomOut()
    
    def __copy(self):
        """
        Private slot called to handle the copy action.
        """
        self.currentBrowser().copy()
    
    def __close(self):
        """
        Private slot called to handle the close action.
        """
        browser = self.currentBrowser()
        self.tabWidget.removeTab(self.tabWidget.currentIndex())
        del browser
        if self.tabWidget.count() == 1:
            self.closeAct.setEnabled(False)
            self.closeAllAct.setEnabled(False)
            self.closeButton.setEnabled(False)
        self.__currentChanged(self.tabWidget.currentIndex())
    
    def __closeAll(self):
        """
        Private slot called to handle the close all action.
        """
        for index in range(self.tabWidget.count()-1, 0, -1):
            browser = self.tabWidget.widget(index)
            self.tabWidget.removeTab(index)
            del browser
            self.closeAct.setEnabled(False)
            self.closeAllAct.setEnabled(False)
            self.closeButton.setEnabled(False)
    
    def currentBrowser(self):
        """
        Public method to get a reference to the current help browser.
        
        @return reference to the current help browser (HelpBrowser)
        """
        return self.tabWidget.currentWidget()
    
    def newBrowser(self, link):
        """
        Public method to create a new help browser tab.
        
        @param link link to be shown (string or QString)
        """
        browser = HelpBrowser(self)
        
        self.connect(browser, SIGNAL('sourceChanged(const QUrl &)'),
                     self.__sourceChanged)
        
        index = self.tabWidget.addTab(browser, self.trUtf8("..."))
        self.tabWidget.setCurrentIndex(index)
        if link:
            browser.setSource(QUrl(link))
            if browser.documentTitle().isNull():
                self.tabWidget.setTabText(index, link)
            else:
                self.tabWidget.setTabText(index, browser.documentTitle())
        
        self.connect(browser, SIGNAL('highlighted(const QString&)'),
                     self.statusBar(), SLOT('showMessage(const QString&)'))
        self.connect(browser, SIGNAL('backwardAvailable(bool)'),
                     self.__setBackwardAvailable)
        self.connect(browser, SIGNAL('forwardAvailable(bool)'),
                     self.__setForwardAvailable)
        
        self.closeAct.setEnabled(self.tabWidget.count() > 1)
        self.closeAllAct.setEnabled(self.tabWidget.count() > 1)
        self.closeButton.setEnabled(self.tabWidget.count() > 1)
    
    def __currentChanged(self, index):
        """
        Private slot to handle the currentChanged signal.
        
        @param index index of the current tab
        """
        self.__setForwardAvailable(self.currentBrowser().isForwardAvailable())
        self.__setBackwardAvailable(self.currentBrowser().isBackwardAvailable())
        
        url = self.currentBrowser().source().toString()
        index = self.pathCombo.findText(url)
        if index > -1:
            self.pathCombo.setCurrentIndex(index)
    
    def __showContextMenu(self, coord, index):
        """
        Private slot to show the tab context menu.
        
        @param coord the position of the mouse pointer (QPoint)
        @param index index of the tab the menu is requested for (integer)
        """
        self.tabContextMenuIndex = index
        self.leftMenuAct.setEnabled(index > 0)
        self.rightMenuAct.setEnabled(index < self.tabWidget.count() - 1)
        self.tabContextCloseAct.setEnabled(self.tabWidget.count() > 1)
        
        coord = self.mapToGlobal(coord)
        self.__tabContextMenu.popup(coord)
    
    def __tabContextMenuMoveLeft(self):
        """
        Private method to move a tab one position to the left.
        """
        self.tabWidget.moveTab(self.tabContextMenuIndex, self.tabContextMenuIndex - 1)
    
    def __tabContextMenuMoveRight(self):
        """
        Private method to move a tab one position to the right.
        """
        self.tabWidget.moveTab(self.tabContextMenuIndex, self.tabContextMenuIndex + 1)
    
    def __tabContextMenuClose(self):
        """
        Private method to close the selected tab.
        """
        browser = self.tabWidget.widget(self.tabContextMenuIndex)
        self.tabWidget.removeTab(self.tabContextMenuIndex)
        del browser
        if self.tabWidget.count() == 1:
            self.closeAct.setEnabled(False)
            self.closeAllAct.setEnabled(False)
            self.closeButton.setEnabled(False)
        self.__currentChanged(self.tabWidget.currentIndex())
    
    def __tabContextMenuPrint(self):
        """
        Private method to print the selected tab.
        """
        browser = self.tabWidget.widget(self.tabContextMenuIndex)
        self.__printFile(browser.document())
