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

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

"""
Module implementing the workspace viewmanager class.
"""

from qt import *

from ViewManager import ViewManager
import UI.PixmapCache

from UI.E3Action import E3Action

class Workspace(QWorkspace, ViewManager):
    """
    Class implementing the workspace viewmanager class.
    
    @signal lastEditorClosed emitted after the last editor window was closed
    @signal editorOpened emitted after an editor window was opened
    @signal editorSaved emitted after an editor window was saved
    @signal editorChanged(string) emitted when the current editor has changed
    """
    def __init__(self,parent, ui, dbs):
        """
        Constructor
        
        @param parent parent widget (QWidget)
        @param ui reference to the main user interface
        @param dbs reference to the debug server object
        """
        QWorkspace.__init__(self,parent)
        ViewManager.__init__(self, ui, dbs)
        self.setScrollBarsEnabled(1)
        self.lastFN = ''
        self.connect(self, SIGNAL('windowActivated(QWidget*)'),
            self.handleWindowActivated)
            
        dummy = self.trUtf8('dummy')
        
    def canCascade(self):
        """
        Public method to signal if cascading of managed windows is available.
        
        @return flag indicating cascading of windows is available
        """
        return 1
        
    def canTile(self):
        """
        Public method to signal if tiling of managed windows is available.
        
        @return flag indicating tiling of windows is available
        """
        return 1
    
    def canSplit(self):
        """
        public method to signal if splitting of the view is available.
        
        @return flag indicating splitting of the view is available.
        """
        return 0
        
    def tile(self):
        """
        Public method to tile the managed windows.
        """
        QWorkspace.tile(self)
        
    def cascade(self):
        """
        Public method to cascade the managed windows.
        """
        QWorkspace.cascade(self)
        
    def removeAllViews(self):
        """
        Private method to remove all views (i.e. windows)
        """
        for win in self.editors:
            self.removeView(win)
            
    def removeView(self, win):
        """
        Private method to remove a view (i.e. window)
        
        @param win editor window to be removed
        """
        self.lastFN = ''
        win.closeIt()
    
    def addView(self, win, fn=None):
        """
        Private method to add a view (i.e. window)
        
        @param win editor window to be added
        @param fn filename of this editor
        """
        if fn is None:
            self.untitledCount += 1
            win.setCaption(self.trUtf8("Untitled %1").arg(self.untitledCount))
        else:
            if self.lastFN != fn:
                self.lastFN = fn
                # QWorkspace is a little bit tricky
                win.hide()
        win.show()
        
        # Make the editor window a little bit smaller to make the whole
        # window with all decorations visible. This is not the most elegant
        # solution but more of a workaround for another QWorkspace strangeness.
        # 25 points are subtracted to give space for the scrollbars
        pw = win.parentWidget()
        sz = pw.size()
        sz.setWidth(min(self.width()-25, sz.width()))
        sz.setHeight(min(self.height()-25, sz.height()))
        pw.resize(sz)
        
        win.setFocus()
    
    def showView(self, win, fn=None):
        """
        Private method to show a view (i.e. window)
        
        @param win editor window to be shown
        @param fn filename of this editor
        """
        if fn is not None and self.lastFN != fn:
            self.lastFN = fn
            # QWorkspace is a little bit tricky
            win.hide()
        win.show()
        win.setFocus()

    def activeWindow(self):
        """
        Private method to return the active (i.e. current) window.
        
        @return reference to the active editor
        """
        return QWorkspace.activeWindow(self)

    def handleShowWindowMenu(self, windowMenu):
        """
        Private method to set up the viewmanager part of the Window menu.
        
        @param windowMenu reference to the window menu
        """
        windowMenu.insertSeparator()
        self.tileAct.addTo(windowMenu)
        self.cascadeAct.addTo(windowMenu)
        windowMenu.insertSeparator()
        
        idx = 0

        for sv in self.editors:
            id = windowMenu.insertItem(sv.caption(),
                                            self.handleSVWindow)
            windowMenu.setItemParameter(id,idx)
            windowMenu.setItemChecked(id,not sv.isHidden())

            idx = idx + 1

    def handleSVWindow(self,idx):
        """
        Private method to handle the toggle of an editor window.
        
        @param idx index of the editor window to toggle (int)
        """
        self.toggleWindow(self.editors[idx])
        
    def initWindowActions(self):
        """
        Define the user interface actions for window handling.
        """
        self.tileAct = E3Action(self.trUtf8('Tile'),
            self.trUtf8('&Tile'),0,0,self,'vm_window_tile')
        self.tileAct.setStatusTip(self.trUtf8('Tile the windows'))
        self.tileAct.setWhatsThis(self.trUtf8(
            """<b>Tile the windows</b>"""
            """<p>Rearrange and resize the windows so that they are tiled.</p>"""
        ))
        self.tileAct.connectIt(SIGNAL('activated()'),self.tile)
        self.windowActions.append(self.tileAct)

        self.cascadeAct = E3Action(self.trUtf8('Cascade'),
            self.trUtf8('&Cascade'),0,0,self,'vm_window_cascade')
        self.cascadeAct.setStatusTip(self.trUtf8('Cascade the windows'))
        self.cascadeAct.setWhatsThis(self.trUtf8(
            """<b>Cascade the windows</b>"""
            """<p>Rearrange and resize the windows so that they are cascaded.</p>"""
        ))
        self.cascadeAct.connectIt(SIGNAL('activated()'),self.cascade)
        self.windowActions.append(self.cascadeAct)

    def setEditorName(self, editor, newName):
        """
        Change the displayed name of the editor.
        
        @param editor editor window to be changed
        @param newName new name to be shown (string or QString)
        """
        pass

    def handleModificationStatusChanged(self, m, editor):
        """
        Private slot to handle the modificationStatusChanged signal.
        
        @param m flag indicating the modification status (boolean)
        @param editor editor window changed
        """
        if m:
            editor.setIcon(UI.PixmapCache.getPixmap("fileModified.png"))
        elif editor.hasSyntaxErrors():
            editor.setIcon(UI.PixmapCache.getPixmap("syntaxError.png"))
        else:
            editor.setIcon(UI.PixmapCache.getPixmap("empty.png"))
        self.checkActions(editor)

    def handleSyntaxErrorToggled(self, editor):
        """
        Private slot to handle the syntaxerrorToggled signal.
        
        @param editor editor that sent the signal
        """
        if editor.hasSyntaxErrors():
            editor.setIcon(UI.PixmapCache.getPixmap("syntaxError.png"))
        else:
            editor.setIcon(UI.PixmapCache.getPixmap("empty.png"))
                
        ViewManager.handleSyntaxErrorToggled(self, editor)
        
    def splitView(self, orientation = QSplitter.Horizontal):
        """
        Public method used to split the current view.
        
        @param orientation orientation of the split 
                (QSplitter.Horizontal or QSplitter.Vertical)
        """
        pass
        
    def removeSplit(self):
        """
        Public method used to remove the current split view.
        """
        pass
        
    def handleWindowActivated(self, editor):
        """
        Private slot to handle the windowActivated signal.
        
        @param editor the activated editor window
        """
        self.checkActions(editor)
        if editor is not None:
            fn = editor.getFileName()
            self.emit(PYSIGNAL('editorChanged'), (unicode(fn),))
