Revision: 8064
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8064&view=rev
Author:   jdh2358
Date:     2010-01-03 18:30:04 +0000 (Sun, 03 Jan 2010)

Log Message:
-----------
added qt4_editor dialog

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
    trunk/matplotlib/setup.py

Added Paths:
-----------
    trunk/matplotlib/lib/matplotlib/backends/qt4_editor/
    trunk/matplotlib/lib/matplotlib/backends/qt4_editor/__init__.py
    trunk/matplotlib/lib/matplotlib/backends/qt4_editor/figureoptions.py
    trunk/matplotlib/lib/matplotlib/backends/qt4_editor/formlayout.py
    trunk/matplotlib/license/LICENSE_QT4_EDITOR

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2010-01-02 06:30:15 UTC (rev 8063)
+++ trunk/matplotlib/CHANGELOG  2010-01-03 18:30:04 UTC (rev 8064)
@@ -1,3 +1,5 @@
+2010-01-03 Added Pierre's qt4 formlayout editor and toolbar button - JDH
+
 2009-12-31 Add support for using math text as marker symbols (Thanks to tcb)
            - MGD
 

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py     2010-01-02 
06:30:15 UTC (rev 8063)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py     2010-01-03 
18:30:04 UTC (rev 8064)
@@ -12,6 +12,7 @@
 from matplotlib.figure import Figure
 from matplotlib.mathtext import MathTextParser
 from matplotlib.widgets import SubplotTool
+import matplotlib.backends.qt4_editor.figureoptions as figureoptions
 
 try:
     from PyQt4 import QtCore, QtGui, Qt
@@ -330,10 +331,16 @@
         a = self.addAction(self._icon('subplots.png'), 'Subplots',
                 self.configure_subplots)
         a.setToolTip('Configure subplots')
+
+        a = self.addAction(self._icon("qt4_editor_options.svg"),
+                           'Customize', self.edit_parameters)
+        a.setToolTip('Edit curves line and axes parameters')
+
         a = self.addAction(self._icon('filesave.svg'), 'Save',
                 self.save_figure)
         a.setToolTip('Save the figure')
 
+
         self.buttons = {}
 
         # Add the x,y location widget at the right side of the toolbar
@@ -352,6 +359,36 @@
         # reference holder for subplots_adjust window
         self.adj_window = None
 
+    def edit_parameters(self):
+        allaxes = self.canvas.figure.get_axes()
+        if len(allaxes) == 1:
+            axes = allaxes[0]
+        else:
+            titles = []
+            for axes in allaxes:
+                title = axes.get_title()
+                ylabel = axes.get_ylabel()
+                if title:
+                    text = title
+                    if ylabel:
+                        text += ": "+ylabel
+                    text += " (%s)"
+                elif ylabel:
+                    text = "%s (%s)" % ylabel
+                else:
+                    text = "%s"
+                titles.append(text % repr(axes))
+            item, ok = QtGui.QInputDialog.getItem(self, 'Customize',
+                                                  'Select axes:', titles,
+                                                  0, False)
+            if ok:
+                axes = allaxes[titles.index(unicode(item))]
+            else:
+                return
+
+        figureoptions.figure_edit(axes, self)
+
+
     def dynamic_update( self ):
         self.canvas.draw()
 

Added: trunk/matplotlib/lib/matplotlib/backends/qt4_editor/figureoptions.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/qt4_editor/figureoptions.py        
                        (rev 0)
+++ trunk/matplotlib/lib/matplotlib/backends/qt4_editor/figureoptions.py        
2010-01-03 18:30:04 UTC (rev 8064)
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © 2009 Pierre Raybaut
+# Licensed under the terms of the MIT License
+# see the mpl licenses directory for a copy of the license
+
+"""Module that provides a GUI-based editor for matplotlib's figure options"""
+
+import os.path as osp
+
+import matplotlib.backends.qt4_editor.formlayout as formlayout
+from PyQt4.QtGui import QIcon
+
+def get_icon(name):
+    import matplotlib
+    basedir = osp.join(matplotlib.rcParams['datapath'], 'images')
+    return QIcon(osp.join(basedir, name))
+
+LINESTYLES = {
+              '-': 'Solid',
+              '--': 'Dashed',
+              '-.': 'DashDot',
+              ':': 'Dotted',
+              'steps': 'Steps',
+              'none': 'None',
+              }
+
+MARKERS = {
+           'none': 'None',
+           'o': 'circles',
+           '^': 'triangle_up',
+           'v': 'triangle_down',
+           '<': 'triangle_left',
+           '>': 'triangle_right',
+           's': 'square',
+           '+': 'plus',
+           'x': 'cross',
+           '*': 'star',
+           'D': 'diamond',
+           'd': 'thin_diamond',
+           '1': 'tripod_down',
+           '2': 'tripod_up',
+           '3': 'tripod_left',
+           '4': 'tripod_right',
+           'h': 'hexagon',
+           'H': 'rotated_hexagon',
+           'p': 'pentagon',
+           '|': 'vertical_line',
+           '_': 'horizontal_line',
+           '.': 'dots',
+           }
+
+COLORS = {'b': '#0000ff', 'g': '#00ff00', 'r': '#ff0000', 'c': '#ff00ff',
+          'm': '#ff00ff', 'y': '#ffff00', 'k': '#000000', 'w': '#ffffff'}
+
+def col2hex(color):
+    """Convert matplotlib color to hex"""
+    return COLORS.get(color, color)
+
+def figure_edit(axes, parent=None):
+    """Edit matplotlib figure options"""
+    sep = (None, None) # separator
+
+    has_curve = len(axes.get_lines()) > 0
+
+    # Get / General
+    xmin, xmax = axes.get_xlim()
+    ymin, ymax = axes.get_ylim()
+    general = [('Title', axes.get_title()),
+               sep,
+               (None, "<b>X-Axis</b>"),
+               ('Min', xmin), ('Max', xmax),
+               ('Label', axes.get_xlabel()),
+               ('Scale', [axes.get_xscale(), 'linear', 'log']),
+               sep,
+               (None, "<b>Y-Axis</b>"),
+               ('Min', ymin), ('Max', ymax),
+               ('Label', axes.get_ylabel()),
+               ('Scale', [axes.get_yscale(), 'linear', 'log'])
+               ]
+
+    if has_curve:
+        # Get / Curves
+        linedict = {}
+        for line in axes.get_lines():
+            label = line.get_label()
+            if label == '_nolegend_':
+                continue
+            linedict[label] = line
+        curves = []
+        linestyles = LINESTYLES.items()
+        markers = MARKERS.items()
+        curvelabels = sorted(linedict.keys())
+        for label in curvelabels:
+            line = linedict[label]
+            curvedata = [
+                         ('Label', label),
+                         sep,
+                         (None, '<b>Line</b>'),
+                         ('Style', [line.get_linestyle()] + linestyles),
+                         ('Width', line.get_linewidth()),
+                         ('Color', col2hex(line.get_color())),
+                         sep,
+                         (None, '<b>Marker</b>'),
+                         ('Style', [line.get_marker()] + markers),
+                         ('Size', line.get_markersize()),
+                         ('Facecolor', col2hex(line.get_markerfacecolor())),
+                         ('Edgecolor', col2hex(line.get_markeredgecolor())),
+                         ]
+            curves.append([curvedata, label, ""])
+
+    datalist = [(general, "Axes", "")]
+    if has_curve:
+        datalist.append((curves, "Curves", ""))
+    result = formlayout.fedit(datalist, title="Figure options", parent=parent,
+                   icon=get_icon('qt4_editor_options.svg'))
+    if result is None:
+        return
+
+    if has_curve:
+        general, curves = result
+    else:
+        general, = result
+
+    # Set / General
+    title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale = general
+    axes.set_xscale(xscale)
+    axes.set_yscale(yscale)
+    axes.set_title(title)
+    axes.set_xlim(xmin, xmax)
+    axes.set_xlabel(xlabel)
+    axes.set_ylim(ymin, ymax)
+    axes.set_ylabel(ylabel)
+
+    if has_curve:
+        # Set / Curves
+        for index, curve in enumerate(curves):
+            line = linedict[curvelabels[index]]
+            label, linestyle, linewidth, color, \
+                marker, markersize, markerfacecolor, markeredgecolor = curve
+            line.set_label(label)
+            line.set_linestyle(linestyle)
+            line.set_linewidth(linewidth)
+            line.set_color(color)
+            if marker is not 'none':
+                line.set_marker(marker)
+                line.set_markersize(markersize)
+                line.set_markerfacecolor(markerfacecolor)
+                line.set_markeredgecolor(markeredgecolor)
+
+    # Redraw
+    figure = axes.get_figure()
+    figure.canvas.draw()
+

Added: trunk/matplotlib/lib/matplotlib/backends/qt4_editor/formlayout.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/qt4_editor/formlayout.py           
                (rev 0)
+++ trunk/matplotlib/lib/matplotlib/backends/qt4_editor/formlayout.py   
2010-01-03 18:30:04 UTC (rev 8064)
@@ -0,0 +1,487 @@
+# -*- coding: utf-8 -*-
+"""
+formlayout
+==========
+
+Module creating PyQt4 form dialogs/layouts to edit various type of parameters
+
+
+formlayout License Agreement (MIT License)
+------------------------------------------
+
+Copyright (c) 2009 Pierre Raybaut
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"""
+
+__version__ = '1.0.5'
+__license__ = __doc__
+
+DEBUG = False
+
+import sys
+STDERR = sys.stderr
+
+try:
+    from PyQt4.QtGui import QFormLayout
+except ImportError:
+    raise ImportError, "Warning: formlayout requires PyQt4 >v4.3"
+
+from PyQt4.QtGui import (QWidget, QLineEdit, QComboBox, QLabel, QSpinBox, 
QIcon,
+                         QStyle, QDialogButtonBox, QHBoxLayout, QVBoxLayout,
+                         QDialog, QColor, QPushButton, QCheckBox, QColorDialog,
+                         QPixmap, QTabWidget, QApplication, QStackedWidget,
+                         QDateEdit, QDateTimeEdit, QFont, QFontComboBox,
+                         QFontDatabase, QGridLayout)
+from PyQt4.QtCore import (Qt, SIGNAL, SLOT, QSize, QString,
+                          pyqtSignature, pyqtProperty)
+from datetime import date
+
+
+class ColorButton(QPushButton):
+    """
+    Color choosing push button
+    """
+    __pyqtSignals__ = ("colorChanged(QColor)",)
+    
+    def __init__(self, parent=None):
+        QPushButton.__init__(self, parent)
+        self.setFixedSize(20, 20)
+        self.setIconSize(QSize(12, 12))
+        self.connect(self, SIGNAL("clicked()"), self.chooseColor)
+        self._color = QColor()
+    
+    def chooseColor(self):
+        rgba, valid = QColorDialog.getRgba(self._color.rgba(),
+                                           self.parentWidget())
+        if valid:
+            color = QColor.fromRgba(rgba)
+            self.setColor(color)
+    
+    def color(self):
+        return self._color
+    
+    @pyqtSignature("QColor")
+    def setColor(self, color):
+        if color != self._color:
+            self._color = color
+            self.emit(SIGNAL("colorChanged(QColor)"), self._color)
+            pixmap = QPixmap(self.iconSize())
+            pixmap.fill(color)
+            self.setIcon(QIcon(pixmap))
+    
+    color = pyqtProperty("QColor", color, setColor)
+
+
+def text_to_qcolor(text):
+    """
+    Create a QColor from specified string
+    Avoid warning from Qt when an invalid QColor is instantiated
+    """
+    color = QColor()
+    if isinstance(text, QString):
+        text = str(text)
+    if not isinstance(text, (unicode, str)):
+        return color
+    if text.startswith('#') and len(text)==7:
+        correct = '#0123456789abcdef'
+        for char in text:
+            if char.lower() not in correct:
+                return color
+    elif text not in list(QColor.colorNames()):
+        return color
+    color.setNamedColor(text)
+    return color
+
+
+class ColorLayout(QHBoxLayout):
+    """Color-specialized QLineEdit layout"""
+    def __init__(self, color, parent=None):
+        QHBoxLayout.__init__(self)
+        assert isinstance(color, QColor)
+        self.lineedit = QLineEdit(color.name(), parent)
+        self.connect(self.lineedit, SIGNAL("textChanged(QString)"),
+                     self.update_color)
+        self.addWidget(self.lineedit)
+        self.colorbtn = ColorButton(parent)
+        self.colorbtn.color = color
+        self.connect(self.colorbtn, SIGNAL("colorChanged(QColor)"),
+                     self.update_text)
+        self.addWidget(self.colorbtn)
+
+    def update_color(self, text):
+        color = text_to_qcolor(text)
+        if color.isValid():
+            self.colorbtn.color = color
+
+    def update_text(self, color):
+        self.lineedit.setText(color.name())
+        
+    def text(self):
+        return self.lineedit.text()
+    
+    
+def font_is_installed(font):
+    """Check if font is installed"""
+    return [fam for fam in QFontDatabase().families() if unicode(fam)==font]
+
+def tuple_to_qfont(tup):
+    """
+    Create a QFont from tuple:
+        (family [string], size [int], italic [bool], bold [bool])
+    """
+    if not isinstance(tup, tuple) or len(tup) != 4 \
+       or not font_is_installed(tup[0]) \
+       or not isinstance(tup[1], int) \
+       or not isinstance(tup[2], bool) \
+       or not isinstance(tup[3], bool):
+        return None
+    font = QFont()
+    family, size, italic, bold = tup
+    font.setFamily(family)
+    font.setPointSize(size)
+    font.setItalic(italic)
+    font.setBold(bold)
+    return font
+
+def qfont_to_tuple(font):
+    return (unicode(font.family()), int(font.pointSize()),
+            font.italic(), font.bold())
+
+
+class FontLayout(QGridLayout):
+    """Font selection"""
+    def __init__(self, value, parent=None):
+        QGridLayout.__init__(self)
+        font = tuple_to_qfont(value)
+        assert font is not None
+        
+        # Font family
+        self.family = QFontComboBox(parent)
+        self.family.setCurrentFont(font)
+        self.addWidget(self.family, 0, 0, 1, -1)
+        
+        # Font size
+        self.size = QComboBox(parent)
+        self.size.setEditable(True)
+        sizelist = range(6, 12) + range(12, 30, 2) + [36, 48, 72]
+        size = font.pointSize()
+        if size not in sizelist:
+            sizelist.append(size)
+            sizelist.sort()
+        self.size.addItems([str(s) for s in sizelist])
+        self.size.setCurrentIndex(sizelist.index(size))
+        self.addWidget(self.size, 1, 0)
+        
+        # Italic or not
+        self.italic = QCheckBox(self.tr("Italic"), parent)
+        self.italic.setChecked(font.italic())
+        self.addWidget(self.italic, 1, 1)
+        
+        # Bold or not
+        self.bold = QCheckBox(self.tr("Bold"), parent)
+        self.bold.setChecked(font.bold())
+        self.addWidget(self.bold, 1, 2)
+        
+    def get_font(self):
+        font = self.family.currentFont()
+        font.setItalic(self.italic.isChecked())
+        font.setBold(self.bold.isChecked())
+        font.setPointSize(int(self.size.currentText()))
+        return qfont_to_tuple(font)
+
+
+class FormWidget(QWidget):
+    def __init__(self, data, comment="", parent=None):
+        super(FormWidget, self).__init__(parent)
+        from copy import deepcopy
+        self.data = deepcopy(data)
+        self.widgets = []
+        self.formlayout = QFormLayout(self)
+        if comment:
+            self.formlayout.addRow(QLabel(comment))
+            self.formlayout.addRow(QLabel(" "))
+        if DEBUG:
+            print "\n"+("*"*80)
+            print "DATA:", self.data
+            print "*"*80
+            print "COMMENT:", comment
+            print "*"*80
+        self.setup()
+
+    def setup(self):
+        for label, value in self.data:
+            if DEBUG:
+                print "value:", value
+            if label is None and value is None:
+                # Separator: (None, None)
+                self.formlayout.addRow(QLabel(" "), QLabel(" "))
+                self.widgets.append(None)
+                continue
+            elif label is None:
+                # Comment
+                self.formlayout.addRow(QLabel(value))
+                self.widgets.append(None)
+                continue
+            elif tuple_to_qfont(value) is not None:
+                field = FontLayout(value, self)
+            elif text_to_qcolor(value).isValid():
+                field = ColorLayout(QColor(value), self)
+            elif isinstance(value, (str, unicode)):
+                field = QLineEdit(value, self)
+            elif isinstance(value, (list, tuple)):
+                selindex = value.pop(0)
+                field = QComboBox(self)
+                if isinstance(value[0], (list, tuple)):
+                    keys = [ key for key, _val in value ]
+                    value = [ val for _key, val in value ]
+                else:
+                    keys = value
+                field.addItems(value)
+                if selindex in value:
+                    selindex = value.index(selindex)
+                elif selindex in keys:
+                    selindex = keys.index(selindex)
+                elif not isinstance(selindex, int):
+                    print >>STDERR, "Warning: '%s' index is invalid (label: " \
+                                    "%s, value: %s)" % (selindex, label, value)
+                    selindex = 0
+                field.setCurrentIndex(selindex)
+            elif isinstance(value, bool):
+                field = QCheckBox(self)
+                field.setCheckState(Qt.Checked if value else Qt.Unchecked)
+            elif isinstance(value, float):
+                field = QLineEdit(repr(value), self)
+            elif isinstance(value, int):
+                field = QSpinBox(self)
+                field.setValue(value)
+                field.setMaximum(1e9)
+            elif isinstance(value, date):
+                if hasattr(value, 'hour'):
+                    field = QDateTimeEdit(self)
+                    field.setDateTime(value)
+                else:
+                    field = QDateEdit(self)
+                    field.setDate(value)
+            else:
+                field = QLineEdit(repr(value), self)
+            self.formlayout.addRow(label, field)
+            self.widgets.append(field)
+            
+    def get(self):
+        valuelist = []
+        for index, (label, value) in enumerate(self.data):
+            field = self.widgets[index]
+            if label is None:
+                # Separator / Comment
+                continue
+            elif tuple_to_qfont(value) is not None:
+                value = field.get_font()
+            elif isinstance(value, (str, unicode)):
+                value = unicode(field.text())
+            elif isinstance(value, (list, tuple)):
+                index = int(field.currentIndex())
+                if isinstance(value[0], (list, tuple)):
+                    value = value[index][0]
+                else:
+                    value = value[index]
+            elif isinstance(value, bool):
+                value = field.checkState() == Qt.Checked
+            elif isinstance(value, float):
+                value = float(field.text())
+            elif isinstance(value, int):
+                value = int(field.value())
+            elif isinstance(value, date):
+                if hasattr(value, 'hour'):
+                    value = field.dateTime().toPyDateTime()
+                else:
+                    value = field.date().toPyDate()
+            else:
+                value = eval(str(field.text()))
+            valuelist.append(value)
+        return valuelist
+
+
+class FormComboWidget(QWidget):
+    def __init__(self, datalist, comment="", parent=None):
+        super(FormComboWidget, self).__init__(parent)
+        layout = QVBoxLayout()
+        self.setLayout(layout)
+        self.combobox = QComboBox()
+        layout.addWidget(self.combobox)
+        
+        self.stackwidget = QStackedWidget(self)
+        layout.addWidget(self.stackwidget)
+        self.connect(self.combobox, SIGNAL("currentIndexChanged(int)"),
+                     self.stackwidget, SLOT("setCurrentIndex(int)"))
+        
+        self.widgetlist = []
+        for data, title, comment in datalist:
+            self.combobox.addItem(title)
+            widget = FormWidget(data, comment=comment, parent=self)
+            self.stackwidget.addWidget(widget)
+            self.widgetlist.append(widget)
+
+    def get(self):
+        return [ widget.get() for widget in self.widgetlist]
+        
+
+class FormTabWidget(QWidget):
+    def __init__(self, datalist, comment="", parent=None):
+        super(FormTabWidget, self).__init__(parent)
+        layout = QVBoxLayout()
+        self.tabwidget = QTabWidget()
+        layout.addWidget(self.tabwidget)
+        self.setLayout(layout)
+        self.widgetlist = []
+        for data, title, comment in datalist:
+            if len(data[0])==3:
+                widget = FormComboWidget(data, comment=comment, parent=self)
+            else:
+                widget = FormWidget(data, comment=comment, parent=self)
+            index = self.tabwidget.addTab(widget, title)
+            self.tabwidget.setTabToolTip(index, comment)
+            self.widgetlist.append(widget)
+            
+    def get(self):
+        return [ widget.get() for widget in self.widgetlist]
+
+
+class FormDialog(QDialog):
+    """Form Dialog"""
+    def __init__(self, data, title="", comment="",
+                 icon=None, parent=None):
+        super(FormDialog, self).__init__(parent)
+        
+        # Form
+        if isinstance(data[0][0], (list, tuple)):
+            self.formwidget = FormTabWidget(data, comment=comment,
+                                            parent=self)
+        elif len(data[0])==3:
+            self.formwidget = FormComboWidget(data, comment=comment,
+                                              parent=self)
+        else:
+            self.formwidget = FormWidget(data, comment=comment, 
+                                         parent=self)
+        layout = QVBoxLayout()
+        layout.addWidget(self.formwidget)
+        
+        # Button box
+        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
+        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
+        layout.addWidget(bbox)
+
+        self.setLayout(layout)
+        
+        self.setWindowTitle(title)
+        if not isinstance(icon, QIcon):
+            icon = QWidget().style().standardIcon(QStyle.SP_MessageBoxQuestion)
+        self.setWindowIcon(icon)
+        
+    def accept(self):
+        self.data = self.formwidget.get()
+        QDialog.accept(self)
+        
+    def reject(self):
+        self.data = None
+        QDialog.reject(self)
+        
+    def get(self):
+        """Return form result"""
+        return self.data
+
+
+def fedit(data, title="", comment="", icon=None, parent=None):
+    """
+    Create form dialog and return result
+    (if Cancel button is pressed, return None)
+    
+    data: datalist, datagroup
+    
+    datalist: list/tuple of (field_name, field_value)
+    datagroup: list/tuple of (datalist *or* datagroup, title, comment)
+    
+    -> one field for each member of a datalist
+    -> one tab for each member of a top-level datagroup
+    -> one page (of a multipage widget, each page can be selected with a combo
+       box) for each member of a datagroup inside a datagroup
+       
+    Supported types for field_value:
+      - int, float, str, unicode, bool
+      - colors: in Qt-compatible text form, i.e. in hex format or name 
(red,...)
+                (automatically detected from a string)
+      - list/tuple:
+          * the first element will be the selected index (or value)
+          * the other elements can be couples (key, value) or only values
+    """
+    
+    # Create a QApplication instance if no instance currently exists
+    # (e.g. if the module is used directly from the interpreter)
+    if QApplication.startingUp():
+        QApplication([])
+        
+    dialog = FormDialog(data, title, comment, icon, parent)
+    if dialog.exec_():
+        return dialog.get()
+
+
+
+if __name__ == "__main__":
+
+    def create_datalist_example():
+        return [('str', 'this is a string'),
+                ('list', [0, '1', '3', '4']),
+                ('list2', ['--', ('none', 'None'), ('--', 'Dashed'),
+                           ('-.', 'DashDot'), ('-', 'Solid'),
+                           ('steps', 'Steps'), (':', 'Dotted')]),
+                ('float', 1.2),
+                (None, 'Other:'),
+                ('int', 12),
+                ('font', ('Arial', 10, False, True)),
+                ('color', '#123409'),
+                ('bool', True),
+                ('datetime', date(2010, 10, 10)),
+                ]
+        
+    def create_datagroup_example():
+        datalist = create_datalist_example()
+        return ((datalist, "Category 1", "Category 1 comment"),
+                (datalist, "Category 2", "Category 2 comment"),
+                (datalist, "Category 3", "Category 3 comment"))
+    
+    #--------- datalist example
+    datalist = create_datalist_example()
+    print "result:", fedit(datalist, title="Example",
+                           comment="This is just an <b>example</b>.")
+    
+    #--------- datagroup example
+    datagroup = create_datagroup_example()
+    print "result:", fedit(datagroup, "Global title")
+        
+    #--------- datagroup inside a datagroup example
+    datalist = create_datalist_example()
+    datagroup = create_datagroup_example()
+    print "result:", fedit(((datagroup, "Title 1", "Tab 1 comment"),
+                            (datalist, "Title 2", "Tab 2 comment"),
+                            (datalist, "Title 3", "Tab 3 comment")),
+                            "Global title")

Added: trunk/matplotlib/license/LICENSE_QT4_EDITOR
===================================================================
--- trunk/matplotlib/license/LICENSE_QT4_EDITOR                         (rev 0)
+++ trunk/matplotlib/license/LICENSE_QT4_EDITOR 2010-01-03 18:30:04 UTC (rev 
8064)
@@ -0,0 +1,30 @@
+
+Module creating PyQt4 form dialogs/layouts to edit various type of parameters
+
+
+formlayout License Agreement (MIT License)
+------------------------------------------
+
+Copyright (c) 2009 Pierre Raybaut
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"""

Modified: trunk/matplotlib/setup.py
===================================================================
--- trunk/matplotlib/setup.py   2010-01-02 06:30:15 UTC (rev 8063)
+++ trunk/matplotlib/setup.py   2010-01-03 18:30:04 UTC (rev 8064)
@@ -49,6 +49,7 @@
 packages = [
     'matplotlib',
     'matplotlib.backends',
+    'matplotlib.backends.qt4_editor',
     'matplotlib.projections',
     'matplotlib.testing',
     'matplotlib.testing.jpl_units',


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to