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

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

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

import os

from qt import *

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

from BookmarkDialog import BookmarkDialog
from SearchDialog import SearchDialog
from HelpBrowser import HelpBrowser
import Preferences
import UI.PixmapCache

class HelpWindow(QMainWindow):
    """
    Class implementing the helpviewer main window.
    
    It was ported to PyQt from the Qt examples.
    This version includes some enhancements to the original like a search
    dialog, a history and a bookmark function.
    """
    helpwindows = []
    mBookmarks = {
        "Names" : QStringList(),
        "Files" : QStringList()
    }
    editBMDialog = None

    def __init__(self, home, path, parent, name, fromEric=0):
        """
        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 eric3 (boolean)
        """
        QMainWindow.__init__(self,parent,name,Qt.WDestructiveClose)
        
        self.fromEric = fromEric
        self.setIcon(UI.PixmapCache.getPixmap("eric.png"))

        if not fromEric:
            from UI.IconProvider import IconProvider
            # Generate and set our icon provider for KQFileDialog
            self.iconProvider = IconProvider()
            KQFileDialog.setIconProvider(self.iconProvider)
                
        self.mHistory = QStringList()
        self.pathCombo = None
        
        self.readHistory()
        if not len(self.__class__.mBookmarks["Names"]):
            self.readBookmarks()
        
        self.browser = HelpBrowser(self)
        QWhatsThis.add(self.browser, self.trUtf8(
                """<b>Help Browser</b>"""
                """<p>This is the main window of the helpviewer. It"""
                """displays the selected help information. Only"""
                """html help files can be displayed.</p>"""
                ))
        
        # set and initialize the MimeSourceFactory
        self.mimeSourceFactory = QMimeSourceFactory()
        self.browser.setMimeSourceFactory(self.mimeSourceFactory)
        if path is None:
            path = QString.null
        self.browser.mimeSourceFactory().setFilePath(QStringList(path))
        
        self.browser.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        self.connect(self.browser, SIGNAL('textChanged()'), self.handleTextChanged)
        
        self.setCentralWidget(self.browser)
        
        if home:
            self.browser.setSource(QString(home))
            
        self.connect(self.browser, SIGNAL('highlighted(const QString&)'),
                     self.statusBar(), SLOT('message(const QString&)'))
        self.connect(self.browser, SIGNAL('backwardAvailable(bool)'),
                     self.setBackwardAvailable)
        self.connect(self.browser, SIGNAL('forwardAvailable(bool)'),
                     self.setForwardAvailable)
                     
        self.findDlg = SearchDialog(self.browser, self, 'Find')
        
        self.resize(700, 800)
        
        self.initActions()
        self.initMenus()
        self.initToolbars()
        
        self.setRightJustification(1)
        self.pathCombo.insertItem(home)
        self.browser.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.
        """
        self.newAct = QAction(self.trUtf8('New Window'), 
                        QIconSet(UI.PixmapCache.getPixmap("newWindow.png")), 
                        self.trUtf8('&New Window'), 
                        QKeySequence(self.trUtf8("CTRL+N","File|New Window")), 
                        self)
        self.newAct.setStatusTip(self.trUtf8('Opens a new help window'))
        self.newAct.setWhatsThis(self.trUtf8(
                """<b>New Window</b>"""
                """<p>This opens a new help window. The new window is"""
                """ a clone of the current one.</p>"""
        ))
        self.connect(self.newAct, SIGNAL('activated()'), self.handleNewWindow)
        
        self.openAct = QAction(self.trUtf8('Open File'), 
                        QIconSet(UI.PixmapCache.getPixmap("open.png")), 
                        self.trUtf8('&Open File'), 
                        QKeySequence(self.trUtf8("CTRL+O","File|Open")), 
                        self)
        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.connect(self.openAct, SIGNAL('activated()'), self.handleOpenFile)
        
        self.printAct = QAction(self.trUtf8('Print'), 
                        QIconSet(UI.PixmapCache.getPixmap("print.png")), 
                        self.trUtf8('&Print'), 
                        QKeySequence(self.trUtf8("CTRL+P","File|Print")), 
                        self)
        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.connect(self.printAct, SIGNAL('activated()'), self.handlePrintFile)
        
        self.closeAct = QAction(self.trUtf8('Close'), 
                        QIconSet(UI.PixmapCache.getPixmap("close.png")), 
                        self.trUtf8('&Close'), 
                        QKeySequence(self.trUtf8("CTRL+W","File|Close")), 
                        self)
        self.closeAct.setStatusTip(self.trUtf8('Close the current help window'))
        self.closeAct.setWhatsThis(self.trUtf8(
                """<b>Close</b>"""
                """<p>Closes the current help window. If the master"""
                """ help window is closed, all others are closed as well.</p>"""
        ))
        self.connect(self.closeAct, SIGNAL('activated()'), self, SLOT('close()'))
        
        if not self.fromEric:
            self.exitAct = QAction(self.trUtf8('Quit'), 
                            QIconSet(UI.PixmapCache.getPixmap("exit.png")), 
                            self.trUtf8('&Quit'), 
                            QKeySequence(self.trUtf8("CTRL+Q","File|Quit")), 
                            self)
            self.exitAct.setStatusTip(self.trUtf8('Quit the application'))
            self.exitAct.setWhatsThis(self.trUtf8(
                    """<b>Quit</b>"""
                    """<p>Quit the application.</p>"""
            ))
            self.connect(self.exitAct, SIGNAL('activated()'), qApp, SLOT('closeAllWindows()'))
        
        self.backAct = QAction(self.trUtf8('Backward'), 
                        QIconSet(UI.PixmapCache.getPixmap("back.png")), 
                        self.trUtf8('&Backward'), 
                        Qt.CTRL+Qt.Key_Left, self)
        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.connect(self.backAct, SIGNAL('activated()'),
                     self.browser, SLOT('backward()'))
                     
        self.forwardAct = QAction(self.trUtf8('Forward'), 
                        QIconSet(UI.PixmapCache.getPixmap("forward.png")), 
                        self.trUtf8('&Forward'), 
                        Qt.CTRL+Qt.Key_Right, self)
        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.connect(self.forwardAct, SIGNAL('activated()'),
                     self.browser, SLOT('forward()'))
                     
        self.homeAct = QAction(self.trUtf8('Home'), 
                        QIconSet(UI.PixmapCache.getPixmap("home.png")), 
                        self.trUtf8('&Home'), 0, self)
        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.connect(self.homeAct, SIGNAL('activated()'),
                     self.browser, SLOT('home()'))
        
        self.reloadAct = QAction(self.trUtf8('Reload'), 
                        QIconSet(UI.PixmapCache.getPixmap("reload.png")), 
                        self.trUtf8('&Reload'), 0, self)
        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.connect(self.reloadAct, SIGNAL('activated()'),
                     self.browser, SLOT('reload()'))
        
        self.findAct = QAction(self.trUtf8('Search'),
                        QIconSet(UI.PixmapCache.getPixmap("find.png")),
                        self.trUtf8('&Search...'),
                        QKeySequence(self.trUtf8("CTRL+F","Search|Search")),
                        self)
        self.findAct.setStatusTip(self.trUtf8('Search text in page'))
        self.findAct.setWhatsThis(self.trUtf8(
                """<b>Search</b>"""
                """<p>Search text in the current page.</p>"""
        ))
        self.connect(self.findAct, SIGNAL('activated()'),
                     self.handleFind)
                     
        self.findAgainAct = QAction(self.trUtf8('Search again'),
                        QIconSet(UI.PixmapCache.getPixmap("findNext.png")),
                        self.trUtf8('Search &again'),
                        Qt.Key_F3, self)
        self.findAgainAct.setStatusTip(self.trUtf8('Search text again in page'))
        self.findAgainAct.setWhatsThis(self.trUtf8(
                """<b>Search again</b>"""
                """<p>Search for the next occurance of text in the current page.</p>"""
        ))
        self.connect(self.findAgainAct, SIGNAL('activated()'),
                     self.findDlg.handleFindNext)
                     
        self.clearHistoryAct = QAction(self.trUtf8('Clear History'), 
                        self.trUtf8('&Clear History'), 0, self)
        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.connect(self.clearHistoryAct,SIGNAL('activated()'),self.handleClearHistory)

        self.addBookmarkAct = QAction(self.trUtf8('Add Bookmark'), 
                                QIconSet(UI.PixmapCache.getPixmap("addBookmark.png")), 
                                self.trUtf8('&Add Bookmark'),0,self)
        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.connect(self.addBookmarkAct,SIGNAL('activated()'),self.handleAddBookmark)
                     
        self.editBookmarksAct = QAction(self.trUtf8('Edit Bookmarks'), 
                                QIconSet(UI.PixmapCache.getPixmap("editBookmarks.png")),
                                self.trUtf8('&Edit Bookmarks...'),0,self)
        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.connect(self.editBookmarksAct,SIGNAL('activated()'),self.handleEditBookmarks)
        
        self.whatsThisAct = QAction(self.trUtf8('What\'s This?'),
                                QIconSet(UI.PixmapCache.getPixmap("whatsThis.png")),
                                self.trUtf8('&What\'s This?'),
                                Qt.SHIFT+Qt.Key_F1,self)
        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.connect(self.whatsThisAct,SIGNAL('activated()'),self.whatsThis)

        self.aboutAct = QAction(self.trUtf8('About'),
                            self.trUtf8('&About'),0,self)
        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.connect(self.aboutAct,SIGNAL('activated()'),self.handleAbout)
                     
        self.aboutQtAct = QAction(self.trUtf8('About Qt'),
                            self.trUtf8('About &Qt'),0,self)
        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.connect(self.aboutQtAct,SIGNAL('activated()'),self.handleAboutQt)

        self.zoomInAct = QAction(self.trUtf8('Zoom in'),
                            QIconSet(UI.PixmapCache.getPixmap("zoomIn.png")),
                            self.trUtf8('Zoom &in'),
                            Qt.CTRL+Qt.Key_Plus, self)
        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.connect(self.zoomInAct,SIGNAL('activated()'),self.browser,SLOT('zoomIn()'))
        
        self.zoomOutAct = QAction(self.trUtf8('Zoom out'),
                            QIconSet(UI.PixmapCache.getPixmap("zoomOut.png")),
                            self.trUtf8('Zoom &out'),
                            Qt.CTRL+Qt.Key_Minus, self)
        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.connect(self.zoomOutAct,SIGNAL('activated()'),self.browser,SLOT('zoomOut()'))
        
        self.copyAct = QAction(self.trUtf8('Copy'),
                            QIconSet(UI.PixmapCache.getPixmap("editCopy.png")),
                            self.trUtf8('&Copy'),
                            QKeySequence(self.trUtf8("CTRL+C","Edit|Copy")), 
                            self)
        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.connect(self.copyAct,SIGNAL('activated()'),self.browser,SLOT('copy()'))
        
        self.backAct.setEnabled(0)
        self.forwardAct.setEnabled(0)
    
    def initMenus(self):
        """
        Private method to create the menus.
        """
        mb = self.menuBar()

        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('&File'),menu)
        menu.insertTearOffHandle()
        self.newAct.addTo(menu)
        self.openAct.addTo(menu)
        self.printAct.addTo(menu)
        menu.insertSeparator()
        self.closeAct.addTo(menu)
        if not self.fromEric:
            self.exitAct.addTo(menu)

        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('&Edit'), menu)
        menu.insertTearOffHandle()
        self.copyAct.addTo(menu)
        menu.insertSeparator()
        self.findAct.addTo(menu)
        self.findAgainAct.addTo(menu)
        
        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('&View'), menu)
        menu.insertTearOffHandle()
        self.zoomInAct.addTo(menu)
        self.zoomOutAct.addTo(menu)
        
        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('&Go'), menu)
        menu.insertTearOffHandle()
        self.backAct.addTo(menu)
        self.forwardAct.addTo(menu)
        self.homeAct.addTo(menu)
        self.reloadAct.addTo(menu)
        
        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('H&istory'), menu)
        self.connect(menu, SIGNAL('aboutToShow()'), self.handleShowHistoryMenu)
        self.connect(menu, SIGNAL('activated(int)'), self.handleHistChosen)
        self.historyMenu = menu
        
        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('&Bookmarks'), menu)
        self.connect(menu, SIGNAL('aboutToShow()'), self.handleShowBookmarksMenu)
        self.connect(menu, SIGNAL('activated(int)'), self.handleBookmChosen)
        self.bookmarksMenu = menu
        
        mb.insertSeparator()
        
        menu = QPopupMenu(self)
        mb.insertItem(self.trUtf8('&Help'),menu)
        menu.insertTearOffHandle()
        self.aboutAct.addTo(menu)
        self.aboutQtAct.addTo(menu)
        menu.insertSeparator()
        self.whatsThisAct.addTo(menu)
    
    def initToolbars(self):
        """
        Private method to create the toolbars.
        """
        filetb = QToolBar(self)
        edittb = QToolBar(self)
        viewtb = QToolBar(self)
        findtb = QToolBar(self)
        bookmarktb = QToolBar(self)
        helptb = QToolBar(self)
        gotb = QToolBar(self)
        
        self.newAct.addTo(filetb)
        self.openAct.addTo(filetb)
        self.printAct.addTo(filetb)
        
        filetb.addSeparator()
        
        self.closeAct.addTo(filetb)
        if not self.fromEric:
            self.exitAct.addTo(filetb)
        
        self.copyAct.addTo(edittb)
        
        self.zoomInAct.addTo(viewtb)
        self.zoomOutAct.addTo(viewtb)
        
        self.findAct.addTo(findtb)
        self.findAgainAct.addTo(findtb)
        
        self.addBookmarkAct.addTo(bookmarktb)
        self.editBookmarksAct.addTo(bookmarktb)
        
        self.backAct.addTo(gotb)
        self.forwardAct.addTo(gotb)
        self.homeAct.addTo(gotb)
        self.reloadAct.addTo(gotb)
        
        gotb.addSeparator()
        
        self.pathCombo = QComboBox(1, gotb)
        self.pathCombo.setDuplicatesEnabled(0)
        self.pathCombo.setInsertionPolicy(QComboBox.AtTop)
        self.pathCombo.setEditable(1)
        self.pathCombo.setAutoCompletion(1)
        self.connect(self.pathCombo, SIGNAL('activated(const QString &)'),
                     self.handlePathSelected)
        gotb.setStretchableWidget(self.pathCombo)
        QWhatsThis.add(self.pathCombo,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.whatsThisAct.addTo(helptb)
        
        
    def handleShowHistoryMenu(self):
        """
        Private slot called in order to show the history menu.
        """
        self.historyMenu.clear()
        self.historyMenu.insertTearOffHandle()
        self.clearHistoryAct.addTo(self.historyMenu)
        self.historyMenu.insertSeparator()
        idx = 0
        for hist in self.mHistory:
            self.historyMenu.insertItem(hist,idx)
            idx += 1
        
    def handleShowBookmarksMenu(self):
        """
        Private slot called in order to show the bookmarks menu.
        """
        self.bookmarksMenu.clear()
        self.bookmarksMenu.insertTearOffHandle()
        self.addBookmarkAct.addTo(self.bookmarksMenu)
        self.editBookmarksAct.addTo(self.bookmarksMenu)
        self.bookmarksMenu.insertSeparator()
        idx = 0
        for bookm in self.__class__.mBookmarks["Names"]:
            self.bookmarksMenu.insertItem(bookm,idx)
            idx += 1
        
    def handlePathSelected(self, path):
        """
        Private slot called when a file is selected in the combobox.
        """
        self.browser.setSource(path)
        
        if self.mHistory.contains(path):
            self.mHistory.remove(path)
            
        self.mHistory.prepend(path)
        
        if self.mHistory.count() > 20:
            self.mHistory = self.mHistory[:20]

    def handleTextChanged(self):
        """
        Private slot called when the displayed text of the combobox is changed.
        """
        if self.browser.documentTitle().isNull():
            self.setCaption(unicode(self.browser.context()))
        else:
            self.setCaption(unicode(self.browser.documentTitle()))
            
        selectedURL = self.browser.context()
        
        if not selectedURL.isEmpty() and self.pathCombo:
            exists = 0
            i = 0
            for i in range(0, self.pathCombo.count()):
                if unicode(self.pathCombo.text(i)) == unicode(selectedURL):
                    exists = 1
                    break
                    
            if not exists:
                self.pathCombo.insertItem(selectedURL, 0)
                self.pathCombo.setCurrentItem(0)
                if self.mHistory.contains(selectedURL):
                    self.mHistory.remove(selectedURL)
                    
                self.mHistory.prepend(selectedURL)
                
                if self.mHistory.count() > 20:
                    self.mHistory = self.mHistory[:20]
            else:
                self.pathCombo.setCurrentItem(i)
            

    def handleNewWindow(self, link = None):
        """
        Public slot called to open a new help window.
        
        This new help window is a clone of the current one
        unless a new file is given.
        
        @param link file to be displayed in the new window (QString)
        """
        if link is None:
            link = self.browser.source()
        h = HelpWindow(link, ".", self.parent(), "qbrowser", self.fromEric)
        h.show()
        
    def handleOpenFile(self):
        """
        Private slot called to open a file.
        """
        fn = KQFileDialog.getOpenFileName(\
            QString.null,
            self.trUtf8("Help Files (*.html *.htm);;PDF Files (*.pdf);;All Files (*)"),
            self, None,
            self.trUtf8("Open File"),
            None, 1)
        if not fn.isEmpty():
            self.browser.setSource(fn)
        
    def handlePrintFile(self):
        """
        Private slot called to print the displayed file.
        """
        printer = KQPrinter()
        printer.setFullPage(1)
        if Preferences.getPrinter("ColorMode"):
            printer.setColorMode(KQPrinter.Color)
        else:
            printer.setColorMode(KQPrinter.GrayScale)
        if Preferences.getPrinter("FirstPageFirst"):
            printer.setPageOrder(KQPrinter.FirstPageFirst)
        else:
            printer.setPageOrder(KQPrinter.LastPageFirst)
        printer.setPrinterName(Preferences.getPrinter("PrinterName"))
        
        if printer.setup(self):
            p = QPainter()
            if not p.begin(printer):
                return
                
            qApp.eventLoop().processEvents(QEventLoop.ExcludeUserInput)
            
            metrics = QPaintDeviceMetrics(p.device())
            dpix = metrics.logicalDpiX()
            dpiy = metrics.logicalDpiY()
            margin = 72 # pt
            body = QRect(margin * dpix / 72, margin * dpiy / 72,
                         metrics.width() - margin * dpix / 72 * 2,
                         metrics.height() - margin * dpiy / 72 * 2)
            font = QFont("times", 10)
            richText = QSimpleRichText(self.browser.text(), font,
                        self.browser.context(),
                        self.browser.styleSheet(),
                        self.browser.mimeSourceFactory(),
                        body.height())
            richText.setWidth(p, body.width())
            numCopies = printer.numCopies()
            curr = 0
            pgFrom = printer.fromPage()
            pgTo = printer.toPage()
            while curr < numCopies:
                view = QRect(body)
                page = 1
                while 1:
                    qApp.eventLoop().processEvents(QEventLoop.ExcludeUserInput)
                    
                    richText.draw(p, body.left(), body.top(), view, self.colorGroup())
                    view.moveBy(0, body.height())
                    p.translate(0, -body.height())
                    if page >= pgFrom:
                        p.setFont(font)
                        p.drawText(view.right() - p.fontMetrics().width(QString.number(page)),
                            view.bottom() + p.fontMetrics().ascent() + 5, QString.number(page))
                    if view.top() >= richText.height() or page == pgTo:
                        break
                    if page < pgFrom:
                        p.eraseRect(view)
                    else:
                        printer.newPage()
                    page += 1
                    
                curr += 1
                if curr < numCopies:
                    printer.newPage()
            p.end()
            
            qApp.eventLoop().processEvents(QEventLoop.ExcludeUserInput)
        
    def handleAbout(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 handleAboutQt(self):
        """
        Private slot to show info about Qt.
        """
        QMessageBox.aboutQt(self, self.trUtf8("Helpviewer"))

    def readHistory(self):
        """
        Private function to read the history from the eric3 preferences file.
        """
        hist, ok = Preferences.Prefs.settings.readListEntry('/eric3/History/Files')
        if ok:
            self.mHistory = hist
        
    def readBookmarks(self):
        """
        Private function to read the bookmarks from the eric3 preferences file.
        """
        bmNames, ok = Preferences.Prefs.settings.readListEntry('/eric3/Bookmarks/Names')
        if not ok:
            return
            
        bmFiles, ok = Preferences.Prefs.settings.readListEntry('/eric3/Bookmarks/Files')
        if not ok:
            return
            
        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 eric3 preferences file.
        """
        ok = Preferences.Prefs.settings.writeEntry('/eric3/Bookmarks/Names',
            self.__class__.mBookmarks["Names"])
        ok = Preferences.Prefs.settings.writeEntry('/eric3/Bookmarks/Files',
            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 handleClearHistory(self):
        """
        Private slot called to clear the current history.
        """
        self.mHistory = QStringList()
        
    def handleHistChosen(self, i):
        """
        Private slot called by the history menu to display the selected file.
        """
        if i >= 0:
            self.browser.setSource(self.mHistory[i])
        
    def handleBookmChosen(self, i):
        """
        Private slot called by the bookmarks menu to display the selected file.
        """
        if i >= 0:
            self.browser.setSource(self.__class__.mBookmarks["Files"][i])
        
    def handleAddBookmark(self):
        """
        Private slot called to add the displayed file to the bookmarks.
        """
        self.__class__.mBookmarks["Names"].append(self.caption())
        self.__class__.mBookmarks["Files"].append(self.browser.context())
        self.writeBookmarks()
                                
    def handleEditBookmarks(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 handleFind(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 to the eric3
        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.
        """
        ok = Preferences.Prefs.settings.writeEntry('/eric3/History/Files',
            self.mHistory)
        
        del self.__class__.helpwindows[self.__class__.helpwindows.index(self)]
        e.accept()
