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

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

"""
Module implementing a dialog for the configuration of eric3s keyboard shortcuts.
"""

from qt import *

from KdeQt import KQMessageBox

from ShortcutsForm import ShortcutsForm
from ShortcutDialog import ShortcutDialog

import Preferences


class ShortcutsDialog(ShortcutsForm):
    """
    Class implementing a dialog for the configuration of eric3s keyboard shortcuts.
    """
    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
        """
        Constructor
        
        @param parent The parent widget of this dialog. (QWidget)
        @param name The name of this dialog. (QString)
        @param modal Flag indicating a modal dialog. (boolean)
        @param fl The window flags.
        """
        ShortcutsForm.__init__(self,parent,name,modal,fl)
        
        self.shortcutsList.setColumnWidthMode(3,QListView.Manual)
        self.shortcutsList.setColumnWidth(3,0)
        
        self.shortcutDialog = ShortcutDialog()
        self.connect(self.shortcutDialog, PYSIGNAL('shortcutChanged'),
                     self.handleShortcutChanged)
        self.connect(self.shortcutsList, 
                     SIGNAL("itemRenamed(QListViewItem*, int)"),
                     self.handleItemRenamed)
        
    def showEvent(self, evt):
        """
        Public method called when the dialog is about to be shown.
        
        @param evt the event (QShowEvent)
        """
        ui = qApp.mainWidget()
        
        self.shortcutsList.clear()
        
        # populate the various lists
        self.projectItem = QListViewItem(self.shortcutsList, self.trUtf8("Project"))
        self.projectItem.setOpen(1)
        for act in ui.getProject().getActions():
            itm = QListViewItem(self.projectItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.uiItem = QListViewItem(self.shortcutsList, self.trUtf8("General"))
        self.uiItem.setOpen(1)
        for act in ui.getActions():
            itm = QListViewItem(self.uiItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.debugItem = QListViewItem(self.shortcutsList, self.trUtf8("Debug"))
        self.debugItem.setOpen(1)
        for act in ui.getDebugger().getActions():
            itm = QListViewItem(self.debugItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.wizardsItem = QListViewItem(self.shortcutsList, self.trUtf8("Wizards"))
        self.wizardsItem.setOpen(1)
        for act in ui.getWizards().getActions():
            itm = QListViewItem(self.wizardsItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.editItem = QListViewItem(self.shortcutsList, self.trUtf8("Edit"))
        self.editItem.setOpen(1)
        for act in ui.getViewManager().getActions('edit'):
            itm = QListViewItem(self.editItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.fileItem = QListViewItem(self.shortcutsList, self.trUtf8("File"))
        self.fileItem.setOpen(1)
        for act in ui.getViewManager().getActions('file'):
            itm = QListViewItem(self.fileItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.searchItem = QListViewItem(self.shortcutsList, self.trUtf8("Search"))
        self.searchItem.setOpen(1)
        for act in ui.getViewManager().getActions('search'):
            itm = QListViewItem(self.searchItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.viewItem = QListViewItem(self.shortcutsList, self.trUtf8("View"))
        self.viewItem.setOpen(1)
        for act in ui.getViewManager().getActions('view'):
            itm = QListViewItem(self.viewItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.macroItem = QListViewItem(self.shortcutsList, self.trUtf8("Macro"))
        self.macroItem.setOpen(1)
        for act in ui.getViewManager().getActions('macro'):
            itm = QListViewItem(self.macroItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        self.bookmarkItem = QListViewItem(self.shortcutsList, self.trUtf8("Bookmarks"))
        self.bookmarkItem.setOpen(1)
        for act in ui.getViewManager().getActions('bookmark'):
            itm = QListViewItem(self.bookmarkItem, act.text(), QString(act.accel()),
                                QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
            
        actions = ui.getViewManager().getActions('window')
        if actions:
            self.windowItem = QListViewItem(self.shortcutsList, self.trUtf8("Window"))
            self.windowItem.setOpen(1)
            for act in actions:
                itm = QListViewItem(self.windowItem, act.text(), QString(act.accel()),
                                    QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
                
        ref = ui.getRefactoring()
        if ref is not None:
            self.refactoringItem = QListViewItem(self.shortcutsList, self.trUtf8("Refactoring"))
            self.refactoringItem.setOpen(1)
            for act in ref.getActions():
                itm = QListViewItem(self.refactoringItem, act.text(), QString(act.accel()),
                                    QString(act.alternateAccel()), act.name())
            itm.setRenameEnabled(1, True)
            itm.setRenameEnabled(2, True)
        
    def handleDoubleClicked(self, itm):
        """
        Private slot to handle a double click in the shortcuts list view.
        
        @param itm The listview item that was double clicked (QListViewItem)
        """
        if itm.firstChild():
            return
            
        self.shortcutDialog.setKeys(QKeySequence(itm.text(1)), QKeySequence(itm.text(2)))
        self.shortcutDialog.show()
        
    def handleItemRenamed(self, itm, col):
        """
        Private slot to handle the edit of a shortcut key.
        
        @param itm reference to the item changed (QListViewItem)
        @param col column changed (integer)
        """
        keystr = unicode(itm.text(col)).title()
        if not self.checkShortcut(QKeySequence(keystr)):
            itm.setText(col, "")
        else:
            itm.setText(col, keystr)

    def handleShortcutChanged(self, keysequence, altKeysequence):
        """
        Private slot to handle the shortcutChanged signal of the shortcut dialog.
        
        @param keysequence the keysequence of the changed action (QKeySequence)
        @param altKeysequence the alternative keysequence of the changed 
            action (QKeySequence)
        """
        if not self.checkShortcut(keysequence) or \
           not self.checkShortcut(altKeysequence):
            return
            
        self.shortcutsList.currentItem().setText(1, QString(keysequence))
        self.shortcutsList.currentItem().setText(2, QString(altKeysequence))
        
    def checkShortcut(self, keysequence):
        """
        Private method to check a keysequence for uniqueness.
        
        @param keysequence the keysequence to check (QKeySequence)
        @return flag indicating uniqueness (boolean)
        """
        if keysequence.isEmpty():
            return 1
            
        ui = qApp.mainWidget()
        
        parentitems = [self.projectItem, self.uiItem, self.debugItem,
            self.wizardsItem, self.editItem, self.fileItem,
            self.searchItem, self.viewItem, self.macroItem,
            self.bookmarkItem]
        if ui.getViewManager().getActions('window'):
            parentitems.append(self.windowItem)
        if ui.getRefactoring():
            parentitems.append(self.refactoringItem)
            
        keystr = unicode(QString(keysequence))
        keyname = unicode(self.shortcutsList.currentItem().text(0))
        for parent in parentitems:
            itm = parent.firstChild()
            while itm:
                if unicode(itm.text(0)) != keyname:
                    for col in [1, 2]:  # check against primary, then alternative binding
                        itmseq = unicode(itm.text(col))
                        # step 1: check if shortcut is already allocated
                        if keystr == itmseq:
                            res = KQMessageBox.warning(None,
                                self.trUtf8("Edit shortcuts"),
                                self.trUtf8(\
                                    """<p><b>%1</b> has already been allocated to the <b>%2</b> action. """
                                    """Remove this binding?</p>""")
                                    .arg(keystr).arg(itm.text(0)),
                                self.trUtf8("&Yes"),
                                self.trUtf8("&No"),
                                QString.null,
                                1, -1)
                            if res == 0:
                                itm.setText(col, "")
                                return 1
                            else:
                                return 0
                            
                        if not itmseq:
                            continue
                            
                        # step 2: check if shortcut hides an already allocated
                        if itmseq.startswith("%s+" % keystr):
                            res = KQMessageBox.warning(None,
                                self.trUtf8("Edit shortcuts"),
                                self.trUtf8(\
                                    """<p><b>%1</b> hides the <b>%2</b> action. """
                                    """Remove this binding?</p>""")
                                    .arg(keystr).arg(itm.text(0)),
                                self.trUtf8("&Yes"),
                                self.trUtf8("&No"),
                                QString.null,
                                1, -1)
                            if res == 0:
                                itm.setText(col, "")
                                return 1
                            else:
                                return 0
                        
                        # step 3: check if shortcut is hidden by an already allocated
                        if keystr.startswith("%s+" % itmseq):
                            res = KQMessageBox.warning(None,
                                self.trUtf8("Edit shortcuts"),
                                self.trUtf8(\
                                    """<p><b>%1</b> is hidden by the <b>%2</b> action. """
                                    """Remove this binding?</p>""")
                                    .arg(keystr).arg(itm.text(0)),
                                self.trUtf8("&Yes"),
                                self.trUtf8("&No"),
                                QString.null,
                                1, -1)
                            if res == 0:
                                itm.setText(col, "")
                                return 1
                            else:
                                return 0
                
                itm = itm.nextSibling()
            
        return 1
        
    def handleOk(self):
        """
        Private slot to handle the OK button press.
        """
        ui = qApp.mainWidget()
        
        actions = ui.getProject().getActions()
        itm = self.projectItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getActions()
        itm = self.uiItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getDebugger().getActions()
        itm = self.debugItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getWizards().getActions()
        itm = self.wizardsItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('edit')
        itm = self.editItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('file')
        itm = self.fileItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('search')
        itm = self.searchItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('view')
        itm = self.viewItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('macro')
        itm = self.macroItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('bookmark')
        itm = self.bookmarkItem.firstChild()
        while itm:
            txt = str(itm.text(3))
            for act in actions:
                if txt == str(act.name()):
                    act.setAccel(QKeySequence(itm.text(1)))
                    act.setAlternateAccel(QKeySequence(itm.text(2)))
            itm = itm.nextSibling()
            
        actions = ui.getViewManager().getActions('window')
        if actions:
            itm = self.windowItem.firstChild()
            while itm:
                txt = str(itm.text(3))
                for act in actions:
                    if txt == str(act.name()):
                        act.setAccel(QKeySequence(itm.text(1)))
                        act.setAlternateAccel(QKeySequence(itm.text(2)))
                itm = itm.nextSibling()
            
        ref = ui.getRefactoring()
        if ref is not None:
            actions = ref.getActions()
            itm = self.refactoringItem.firstChild()
            while itm:
                txt = str(itm.text(3))
                for act in actions:
                    if txt == str(act.name()):
                        act.setAccel(QKeySequence(itm.text(1)))
                        act.setAlternateAccel(QKeySequence(itm.text(2)))
                itm = itm.nextSibling()
            
        Preferences.saveShortcuts()
        Preferences.syncPreferences()
        
        self.emit(PYSIGNAL('updateShortcuts'), ())
        self.hide()
