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

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

"""
Module implementing a subclass of QCanvasView for viewing a pixmap.
"""

import sys

from qt import *
from qtcanvas import *

from KdeQt import KQMessageBox
from KdeQt.KQPrinter import KQPrinter

from ZoomDialog import ZoomDialog
import Preferences

class PixmapCanvasView(QCanvasView):
    """
    Class implementing a specialized canvasview for viewing a pixmap.
    """
    def __init__(self, canvas, parent=None, name=None, flags=0):
        """
        Constructor
        
        @param canvas canvas that is managed by the view (QCanvas)
        @param parent parent widget of the view (QWidget)
        @param name name of the view widget (QString or string)
        @param flags the window flags to be passed to the view widget
        """
        QCanvasView.__init__(self, canvas, parent, name, flags)
        
        self.zoom = 1.0
        
        self.menuIDs = {}
        self.menu = QPopupMenu(self)
        self.menu.insertItem(self.trUtf8("Print"), self.handlePrintDiagram)
        self.menu.insertSeparator()
        self.menu.insertItem(self.trUtf8("Zoom in"), self.handleZoomIn)
        self.menu.insertItem(self.trUtf8("Zoom out"), self.handleZoomOut)
        self.menu.insertItem(self.trUtf8("Zoom..."), self.handleZoom)
        self.menu.insertItem(self.trUtf8("Reset Zoom"), self.handleZoomReset)
        
    def showPixmap(self, pixmapfile):
        """
        Method used to show a pixmap.
        
        @param pixmapfile filename of the graphics file (QString or string)
        @return flag indicating successful loading of the file (boolean)
        """
        self.pixmap = QPixmap(pixmapfile)
        if self.pixmap.isNull():
            KQMessageBox.warning(None,
                self.trUtf8("Pixmap-Viewer"),
                self.trUtf8("""<p>The file <b>%1</b> cannot be displayed."""
                    """ The format is not supported.</p>""").arg(pixmapfile),
                self.trUtf8("&OK"),
                QString.null,
                QString.null,
                0, -1)
            return 0

        self.canvas().resize(self.pixmap.width(), self.pixmap.height())
        self.canvas().setBackgroundPixmap(self.pixmap)
        return 1
    
    def contextMenuEvent(self, evt):
        """
        Overriden method to handle a context menu event.
        
        @param evt context menu event (QContextMenuEvent)
        """
        evt.accept()
        self.menu.popup(evt.globalPos())        
        
    def handlePrintDiagram(self):
        """
        Private slot called to print the diagram.
        """
        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(printer)
            metrics = QPaintDeviceMetrics(p.device())
            offsetX = 0
            offsetY = 0
            widthX = 0
            heightY = 0
            font = QFont("times", 10)
            p.setFont(font)
            fm = p.fontMetrics()
            fontHeight = fm.lineSpacing()
            marginX = printer.margins().width()
            marginY = printer.margins().height()
            
            # double the margin on bottom of page
            if printer.orientation() == KQPrinter.Portrait:
                width = metrics.width() - marginX * 2
                height = metrics.height() - fontHeight - 4 - marginY * 3
            else:
                marginX *= 2
                width = metrics.width() - marginX * 2
                height = metrics.height() - fontHeight - 4 - marginY * 2
            
            finishX = 0
            finishY = 0
            page = 0
            pageX = 0
            pageY = 1
            while not finishX or not finishY:
                if not finishX:
                    offsetX = pageX * width
                    pageX += 1
                elif not finishY:
                    offsetY = pageY * height
                    offsetX = 0
                    pageY += 1
                    finishX = 0
                    pageX = 1
                if (width + offsetX) > self.pixmap.width():
                    finishX = 1
                    widthX = self.pixmap.width() - offsetX
                else:
                    widthX = width
                if self.pixmap.width() < width:
                    widthX = self.pixmap.width()
                    finishX = 1
                    offsetX = 0
                if (height + offsetY) > self.pixmap.height():
                    finishY = 1
                    heightY = self.pixmap.height() - offsetY
                else:
                    heightY = height
                if self.pixmap.height() < height:
                    finishY = 1
                    heightY = self.pixmap.height()
                    offsetY = 0
                    
                p.drawPixmap(marginX, marginY, self.pixmap,
                             offsetX, offsetY, widthX, heightY)
                # write a foot note
                s = QString(self.trUtf8("Diagram: %1, Page %2")
                    .arg(self.parent().getDiagramName()).arg(page + 1))
                tc = QColor(50, 50, 50)
                p.setPen(tc)
                p.drawRect(marginX, marginY, width, height)
                p.drawLine(marginX, marginY + height + 2, 
                           marginX + width, marginY + height + 2)
                p.setFont(font)
                p.drawText(marginX, marginY + height + 4, width,
                           fontHeight, Qt.AlignRight, s)
                if not finishX or not finishY:
                    printer.newPage()
                    page += 1
                
            p.end()
        
    def doZoom(self):
        """
        Private method to perform the zooming.
        """
        wm = QWMatrix()
        wm.scale(self.zoom, self.zoom)
        self.setWorldMatrix(wm)
        
    def handleZoomIn(self):
        """
        Private method to handle the zoom in context menu entry.
        """
        self.zoom *= 2.0
        self.doZoom()
        
    def handleZoomOut(self):
        """
        Private method to handle the zoom out context menu entry.
        """
        self.zoom /= 2.0
        self.doZoom()
    
    def handleZoomReset(self):
        """
        Private method to handle the reset zoom context menu entry.
        """
        self.zoom = 1.0
        self.doZoom()
        
    def handleZoom(self):
        """
        Private method to handle the zoom context menu action.
        """
        dlg = ZoomDialog(self.zoom, self, None, 1)
        if dlg.exec_loop() == QDialog.Accepted:
            self.zoom = dlg.getZoomSize()
            self.doZoom()
