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

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

"""
Module implementing a dialog for editing breakpoints.
"""

from qt import *

from UI.Info import *
from BreakpointForm import BreakpointForm
from EditBreakpointDialog import EditBreakpointDialog


class BreakpointDialog(BreakpointForm):
    """
    Class implementing a dialog for editing breakpoints.
    
    In this dialog all currently set breakpoint can be delete or be changed.
    Unconditional breakpoints can be converted to conditional ones by
    entering a condition term, conditional ones to unconditional by 
    removing the condition term. This dialog has three different modes.
    In 'project' mode all breakpoints of the current project are shown,
    in 'global' mode all breakpoints and in 'file' mode the breakpoints of
    a specific file.
    """
    def __init__(self,parent = None,name = None,modal = 0,fl = 0,fn = None):
        """
        Constructor
        
        Arguments
        
            parent -- parent widget of this dialog (QWidget)
            
            name -- the name of this dialog (string or QString)
            
            modal -- flag to indicate a modal dialog (boolean)
            
            fl -- window flags
            
            fn -- determines the mode of the dialog
            
                None -- the 'global' breakpoint dialog
                
                'project' -- the 'project' breakpoint dialog
                
                filename -- the 'file' breakpoint dialog
        """
        BreakpointForm.__init__(self,parent,name,modal,fl)

        if fn:
            if fn == 'project':
                self.setCaption(self.trUtf8('%1 - Project Breakpoints')
                    .arg(Program))
            else:
                self.setCaption(self.trUtf8('%1 - Breakpoints of %2')
                    .arg(Program)
                    .arg(fn))
        else:
            self.setCaption(self.trUtf8('%1 - All Breakpoints')
                .arg(Program))

        if not fn or fn == 'project':
            self.bpListview.addColumn(self.trUtf8("Filename"))
            
        col = self.bpListview.addColumn(self.trUtf8("Line"))
        self.bpListview.setColumnAlignment(col, Qt.AlignRight)
        
        self.bpListview.addColumn(self.trUtf8("Condition"))
        
        col = self.bpListview.addColumn(self.trUtf8("Temporary"))
        self.bpListview.setColumnAlignment(col, Qt.AlignHCenter)
        
        col = self.bpListview.addColumn(self.trUtf8("Enabled"))
        self.bpListview.setColumnAlignment(col, Qt.AlignHCenter)
        
        col = self.bpListview.addColumn(self.trUtf8("Ignore Count"))
        self.bpListview.setColumnAlignment(col, Qt.AlignRight)
        
        self.bpListview.setSelectionMode(QListView.Extended)
        self.bpListview.setAllColumnsShowFocus(1)
        self.bpListview.setSorting(0)
        
        self.filename = fn
        self.viewmanager = parent.getViewManager()
        self.dbg = parent.getDebugger()
        
        # populate the listbox
        if not fn or fn == 'project':
            if fn is None:
                bpDict = self.dbg.getAllBreakpoints()
            else:
                bpDict = self.dbg.getProjectBreakpoints()
            for fname, bpList in bpDict.items():
                for (lineno, cond, temp, enabled, count) in bpList:
                    QListViewItem(self.bpListview, 
                        fname, 
                        " %5s" % str(lineno), 
                        cond,
                        temp and self.trUtf8("Yes") or self.trUtf8("No"),
                        enabled and self.trUtf8("Yes") or self.trUtf8("No"),
                        " %5s" % str(count), 
                    )
        else:
            bpList = self.dbg.getFileBreakpoints(fn)
            for (lineno, cond, temp, enabled, count) in bpList:
                QListViewItem(self.bpListview,
                    " %5s" % str(lineno),
                    cond,
                    temp and self.trUtf8("Yes") or self.trUtf8("No"),
                    enabled and self.trUtf8("Yes") or self.trUtf8("No"),
                    " %5s" % str(count),
                )
                
        self.currItem = None
        self.condHistory = QStringList()
        
        # create the popup menu
        self.menu = QPopupMenu(self)
        self.menu.insertItem(self.trUtf8('Edit...'), self.handleEditBP)
        self.menu.insertItem(self.trUtf8('Delete'), self.handleDeleteSingle)
        self.menu.insertItem(self.trUtf8('Goto'), self.handleGoto)

    def handleDeleteAll(self):
        """
        Private slot to delete all breakpoints listed in the listview.
        """
        item = self.bpListview.firstChild()
        
        while item:
            if not self.filename or self.filename == 'project':
                fn = str(item.text(0))
                line = int(str(item.text(1)))
            else:
                fn = str(self.filename)
                line = int(str(item.text(0)))
            self.dbg.toggleBreakpoint(fn, line)
            self.bpListview.takeItem(item)
            del item
            item = self.bpListview.firstChild()

    def handleDeleteSelected(self):
        """
        Private slot to delete the selected breakpoints of the listview.
        """
        item = self.bpListview.firstChild()
        
        while item:
            if item.isSelected():
                if not self.filename or self.filename == 'project':
                    fn = str(item.text(0))
                    line = int(str(item.text(1)))
                else:
                    fn = str(self.filename)
                    line = int(str(item.text(0)))
                self.dbg.toggleBreakpoint(fn, line)
                olditem = item
                item = olditem.itemBelow()
                self.bpListview.takeItem(olditem)
                del olditem
            else:
                item = item.itemBelow()

    def handleDeleteSingle(self):
        """
        Private slot to delete a single breakpoint.
        """
        if self.currItem:
            if not self.filename or self.filename == 'project':
                fn = str(self.currItem.text(0))
                line = int(str(self.currItem.text(1)))
            else:
                fn = str(self.filename)
                line = int(str(self.currItem.text(0)))
            self.dbg.toggleBreakpoint(fn, line)
            self.bpListview.takeItem(self.currItem)
            del self.currItem
            self.currItem = None
        
    def handleEditBP(self):
        """
        Private slot to edit the properties of the selected breakpoint.
        """
        if self.currItem:
            if not self.filename or self.filename == 'project':
                fn = str(self.currItem.text(0))
                line = int(str(self.currItem.text(1)))
                cond = self.currItem.text(2)
                if self.currItem.text(3).compare(self.trUtf8("Yes")):
                    temp = 0
                else:
                    temp = 1
                if self.currItem.text(4).compare(self.trUtf8("Yes")):
                    enabled = 0
                else:
                    enabled = 1
                count = int(str(self.currItem.text(5)))
            else:
                fn = str(self.filename)
                line = int(str(self.currItem.text(0)))
                cond = self.currItem.text(1)
                if self.currItem.text(2).compare(self.trUtf8("Yes")):
                    temp = 0
                else:
                    temp = 1
                if self.currItem.text(3).compare(self.trUtf8("Yes")):
                    enabled = 0
                else:
                    enabled = 1
                count = int(str(self.currItem.text(4)))
                
            dlg = EditBreakpointDialog((cond, temp, enabled, count),
                self.condHistory, self, modal = 1)
            if dlg.exec_loop() == QDialog.Accepted:
                cond, temp, enabled, count = dlg.getData()
                if cond is not None:
                    self.condHistory.remove(cond)
                    self.condHistory.prepend(cond)
                                
                self.dbg.setBreakpointProperties(fn, line, (cond, temp, enabled, count))
                
                if cond is None:
                    cond = ''
                if self.filename and self.filename != 'project':
                    self.currItem.setText(1, cond)
                    self.currItem.setText(2, temp and self.trUtf8("Yes") or self.trUtf8("No"))
                    self.currItem.setText(3, enabled and self.trUtf8("Yes") or self.trUtf8("No"))
                    self.currItem.setText(4, " %5s" % str(count))
                else:
                    self.currItem.setText(2, cond)
                    self.currItem.setText(3, temp and self.trUtf8("Yes") or self.trUtf8("No"))
                    self.currItem.setText(4, enabled and self.trUtf8("Yes") or self.trUtf8("No"))
                    self.currItem.setText(5, " %5s" % str(count))
                    
            self.currItem = None
                
    def handleListContextmenu(self, item, pos, col):
        """
        Private slot to show the context menu of the listview.
        
        Arguments
        
            item -- the item under the mouse cursor (QListViewItem)
            
            pos -- global position of the context menu (QPoint)
            
            col -- column of the mouse cursor (int)
        """
        if item:
            self.currItem = item
            self.menu.popup(pos)

    def handleGoto(self):
        """
        Private slot to go to a breakpoint.
        """
        if self.currItem:
            if not self.filename or self.filename == 'project':
                fn = str(self.currItem.text(0))
                line = int(str(self.currItem.text(1)))
            else:
                fn = str(self.filename)
                line = int(str(self.currItem.text(0)))
            self.viewmanager.displayPythonFile(fn, line)

