Esempio n. 1
0
    def __init__(self, parent):
        QStackedWidget.__init__(self, parent)
        SpyderPluginMixin.__init__(self, parent)
        self.shellwidgets = {}

        # Initialize plugin
        self.initialize_plugin()
Esempio n. 2
0
    def __init__(self, parent):
        QStackedWidget.__init__(self, parent)
        SpyderPluginMixin.__init__(self, parent)
        self.shellwidgets = {}

        # Initialize plugin
        self.initialize_plugin()
Esempio n. 3
0
    def setup(self, fname):
        """Setup Run Configuration dialog with filename *fname*"""
        combo_label = QLabel(_("Select a run configuration:"))
        self.combo = QComboBox()
        self.combo.setMaxVisibleItems(20)
        self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        
        self.stack = QStackedWidget()

        configurations = _get_run_configurations()
        for index, (filename, options) in enumerate(configurations):
            if fname == filename:
                break
        else:
            # There is no run configuration for script *fname*:
            # creating a temporary configuration that will be kept only if
            # dialog changes are accepted by the user
            configurations.insert(0, (fname, RunConfiguration(fname).get()))
            index = 0
        for filename, options in configurations:
            widget = RunConfigOptions(self)
            widget.set(options)
            self.combo.addItem(filename)
            self.stack.addWidget(widget)
        self.combo.currentIndexChanged.connect(self.stack.setCurrentIndex)
        self.combo.setCurrentIndex(index)

        self.add_widgets(combo_label, self.combo, 10, self.stack)
        self.add_button_box(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)

        self.setWindowTitle(_("Run Settings"))
Esempio n. 4
0
class FormComboWidget(QWidget):
    update_buttons = Signal()
    
    def __init__(self, datalist, comment="", parent=None):
        QWidget.__init__(self, parent)
        layout = QVBoxLayout()
        self.setLayout(layout)
        self.combobox = QComboBox()
        layout.addWidget(self.combobox)
        
        self.stackwidget = QStackedWidget(self)
        layout.addWidget(self.stackwidget)
        self.combobox.currentIndexChanged.connect(
                                              self.stackwidget.setCurrentIndex)
        
        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 setup(self):
        for widget in self.widgetlist:
            widget.setup()

    def get(self):
        return [ widget.get() for widget in self.widgetlist]
Esempio n. 5
0
class RunConfigDialog(BaseRunConfigDialog):
    """Run configuration dialog box: multiple file version"""
    def __init__(self, parent=None):
        BaseRunConfigDialog.__init__(self, parent)
        self.file_to_run = None
        self.combo = None
        self.stack = None
        
    def run_btn_clicked(self):
        """Run button was just clicked"""
        self.file_to_run = to_text_string(self.combo.currentText())
        
    def setup(self, fname):
        """Setup Run Configuration dialog with filename *fname*"""
        combo_label = QLabel(_("Select a run configuration:"))
        self.combo = QComboBox()
        self.combo.setMaxVisibleItems(20)
        self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        
        self.stack = QStackedWidget()

        configurations = _get_run_configurations()
        for index, (filename, options) in enumerate(configurations):
            if fname == filename:
                break
        else:
            # There is no run configuration for script *fname*:
            # creating a temporary configuration that will be kept only if
            # dialog changes are accepted by the user
            configurations.insert(0, (fname, RunConfiguration(fname).get()))
            index = 0
        for filename, options in configurations:
            widget = RunConfigOptions(self)
            widget.set(options)
            self.combo.addItem(filename)
            self.stack.addWidget(widget)
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
                     self.stack.setCurrentIndex)
        self.combo.setCurrentIndex(index)

        self.add_widgets(combo_label, self.combo, 10, self.stack)
        self.add_button_box(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)

        self.setWindowTitle(_("Run Settings"))
        
    def accept(self):
        """Reimplement Qt method"""
        configurations = []
        for index in range(self.stack.count()):
            filename = to_text_string(self.combo.itemText(index))
            runconfigoptions = self.stack.widget(index)
            if index == self.stack.currentIndex() and\
               not runconfigoptions.is_valid():
                return
            options = runconfigoptions.get()
            configurations.append( (filename, options) )
        _set_run_configurations(configurations)
        QDialog.accept(self)
Esempio n. 6
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.main = parent

        # Widgets
        self.pages_widget = QStackedWidget()
        self.contents_widget = QListWidget()
        self.button_reset = QPushButton(_('Reset to defaults'))

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply
                                | QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)

        # Widgets setup
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle(_('Preferences'))
        self.setWindowIcon(ima.icon('configure'))
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)
        self.contents_widget.setCurrentRow(0)

        # Layout
        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addWidget(self.button_reset)
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        # Signals and slots
        self.button_reset.clicked.connect(self.main.reset_spyder)
        self.pages_widget.currentChanged.connect(self.current_page_changed)
        self.contents_widget.currentRowChanged.connect(
            self.pages_widget.setCurrentIndex)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        bbox.clicked.connect(self.button_clicked)

        # Ensures that the config is present on spyder first run
        CONF.set('main', 'interface_language', load_lang_conf())
Esempio n. 7
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        SpyderPluginMixin.__init__(self, parent)

        # Widgets
        self.stack = QStackedWidget(self)
        self.shellwidgets = {}

        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.stack)
        self.setLayout(layout)

        # Initialize plugin
        self.initialize_plugin()
Esempio n. 8
0
    def setup(self, fname):
        """Setup Run Configuration dialog with filename *fname*"""
        combo_label = QLabel(_("Select a run configuration:"))
        self.combo = QComboBox()
        self.combo.setMaxVisibleItems(20)
        self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        
        self.stack = QStackedWidget()

        configurations = _get_run_configurations()
        for index, (filename, options) in enumerate(configurations):
            if fname == filename:
                break
        else:
            # There is no run configuration for script *fname*:
            # creating a temporary configuration that will be kept only if
            # dialog changes are accepted by the user
            configurations.insert(0, (fname, RunConfiguration(fname).get()))
            index = 0
        for filename, options in configurations:
            widget = RunConfigOptions(self)
            widget.set(options)
            self.combo.addItem(filename)
            self.stack.addWidget(widget)
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
                     self.stack.setCurrentIndex)
        self.combo.setCurrentIndex(index)

        self.add_widgets(combo_label, self.combo, 10, self.stack)
        self.add_button_box(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)

        self.setWindowTitle(_("Run Settings"))
Esempio n. 9
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply
                                | QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle(_("Preferences"))
        self.setWindowIcon(get_icon("configure.png"))
Esempio n. 10
0
 def __init__(self, datalist, comment="", parent=None):
     QWidget.__init__(self, parent)
     layout = QVBoxLayout()
     self.setLayout(layout)
     self.combobox = QComboBox()
     layout.addWidget(self.combobox)
     
     self.stackwidget = QStackedWidget(self)
     layout.addWidget(self.stackwidget)
     self.combobox.currentIndexChanged.connect(
                                           self.stackwidget.setCurrentIndex)
     
     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)
Esempio n. 11
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.main = parent

        # Widgets
        self.pages_widget = QStackedWidget()
        self.contents_widget = QListWidget()
        self.button_reset = QPushButton(_('Reset to defaults'))

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply |
                                QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)

        # Widgets setup
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle(_('Preferences'))
        self.setWindowIcon(ima.icon('configure'))
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)
        self.contents_widget.setCurrentRow(0)

        # Layout
        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addWidget(self.button_reset)
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        # Signals and slots
        self.button_reset.clicked.connect(self.main.reset_spyder)
        self.pages_widget.currentChanged.connect(self.current_page_changed)
        self.contents_widget.currentRowChanged.connect(
                                             self.pages_widget.setCurrentIndex)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        bbox.clicked.connect(self.button_clicked)

        # Ensures that the config is present on spyder first run
        CONF.set('main', 'interface_language', load_lang_conf())
Esempio n. 12
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        SpyderPluginMixin.__init__(self, parent)

        # Widgets
        self.stack = QStackedWidget(self)
        self.shellwidgets = {}

        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.stack)
        self.setLayout(layout)

        # Initialize plugin
        self.initialize_plugin()
Esempio n. 13
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply
                                |QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle(_("Preferences"))
        self.setWindowIcon(get_icon("configure.png"))
Esempio n. 14
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        SizeMixin.__init__(self)

        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.file_to_run = None

        combo_label = QLabel(_("Select a run configuration:"))
        self.combo = QComboBox()
        self.combo.setMaxVisibleItems(20)
        self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.stack = QStackedWidget()

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        run_btn = bbox.addButton(_("Run"), QDialogButtonBox.AcceptRole)
        self.connect(run_btn, SIGNAL("clicked()"), self.run_btn_clicked)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        layout = QVBoxLayout()
        layout.addWidget(combo_label)
        layout.addWidget(self.combo)
        layout.addSpacing(10)
        layout.addWidget(self.stack)
        layout.addLayout(btnlayout)
        self.setLayout(layout)

        self.setWindowTitle(_("Run configurations"))
        self.setWindowIcon(get_icon("run.png"))
Esempio n. 15
0
 def __init__(self, parent, max_entries=100):
     
     "Initialize Various list objects before assignment"
     displaylist = []
     displaynamelist = []
     infixmod = []
     infixlist = []
     desclist = []
     
     parameternamelist = []
     parameterdesclist = []
     parameterstringlist = []
     paramcountlist = []
     
     
     
     buttonlist  = []
     xmldoc = minidom.parse('C:\\Users\\Jayit\\.spyder2\\ratelaw2_0_3.xml')
     #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml')
     
     lawlistxml = xmldoc.getElementsByTagName('law')
     
     o = 0
     for s in lawlistxml:
         o = o + 1
     
     parameternamelistlist = [0 for x in range(o)]
     parameterdesclistlist = [0 for x in range(o)]
     
     """i is the number of laws currently in the xml file"""
     i = 0
     
     """
     Parsing xml: Acquiring rate law name, description, and list of parameter information
     """
     for s in lawlistxml:
         #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n"
         """Gets Latec Expression"""
         displaylist.append(s.getAttribute('display'))
         
         """Gets Rate-Law Name"""
         displaynamelist.append(s.getAttribute('displayName'))
         
         """"Gets Raw Rate-Law expression"""
         infixlist.append(s.getAttribute('infixExpression'))
         
         """Gets description statement"""
         desclist.append(s.getAttribute('description'))
         
         """Gets listOfParameters Object"""
         parameterlist = s.getElementsByTagName('listOfParameters')[0]
         
         """Gets a list of parameters within ListOfParameters object"""    
         parameters = parameterlist.getElementsByTagName('parameter')
         
         for param in parameters:
             parameternamelist.append(param.attributes['name'].value)
             #print(param.attributes['name'].value)
             parameterdesclist.append(param.attributes['description'].value)  
         
         parameternamelistlist[i] = parameternamelist
         #print("break")
         parameterdesclistlist[i] = parameterdesclist
         
         parameternamelist = []
         parameterdesclist = []
         i = i + 1
     
     SLElistlist = [ 0 for x in range(i)]
     PLElistlist = [ 0 for x in range(i)]
     ILElistlist = [ 0 for x in range(i)]
     paramLElistlist = [ 0 for x in range(i)]
     numlistlist = [ 0 for x in range(i)]
     
     QWidget.__init__(self, parent)
     
     self.setWindowTitle("Rate Law Library")
     
     self.output = None
     self.error_output = None
     self._last_wdir = None
     self._last_args = None
     self._last_pythonpath = None
     
     #self.textlabel = QLabel(RATE_LAW_MESSAGE)
     
     self.lawlist = QListWidget()
     self.lawpage = QStackedWidget()
     index = 0
     for j in range(i):            
         item = QListWidgetItem(displaynamelist[j])
         self.lawlist.addItem(item)
         self.lawdetailpage = QWidget()
         setup_group = QGroupBox(displaynamelist[j])
         infixmod.append(infixlist[j].replace("___"," "))      
         setup_label = QLabel(infixmod[j])
         setup_label.setWordWrap(True)
         
         desc_group = QGroupBox("Description")
         desc_label = QLabel(desclist[j])
         desc_label.setWordWrap(True)
                     
         param_label = QGridLayout()
         nm = QLabel("Name:")
         des = QLabel("Description:")
         repl = QLabel("Replace with:")
         param_label.addWidget(nm,0,0)
         param_label.addWidget(des,0,1)
         param_label.addWidget(repl,0,2)
         """g is the total number of alterable values"""
         g = 0
         """t is the total number of alterable non-parameters"""
         t = 1
         
         snum = 0
         pnum = 0
         inum = 0
         
         """range of N is the max number of possible substrates OR products"""
         N = 5
         for n in range(N):
             nl = n+1
             if (infixmod[j].find('S%s' % nl) > -1):
                 z = QLabel('S%s is present' % nl)
                 param_label.addWidget(z,t,0)
                 snum = snum + 1
                 t = t + 1
         
         for n in range(N):
             nl = n+1    
             if (infixmod[j].find('P%s' % nl) > -1):
                 z = QLabel('P%s is present' % nl)
                 param_label.addWidget(z,t,0)
                 pnum = pnum + 1
                 t = t + 1
                 
         for n in range(N):
             nl = n+1
             if (infixmod[j].find('I%s' % nl) > -1):
                 z = QLabel('I%s is present' % nl)
                 param_label.addWidget(z,t,0)
                 inum = inum + 1
                 t = t + 1
         
         """Initialize lists of list of parameter lineedit"""    
         length = len(parameternamelistlist[j])
         for b in range(length):
             p = QLabel("%s :" % parameternamelistlist[j][b])
             param_label.addWidget(p,b+t,0)
             d = QLabel("'%s'" % parameterdesclistlist[j][b])
             param_label.addWidget(d,b+t,1)
         
         g = t + length
         
         Slineeditlist = [0 for x in range(snum)]
         Plineeditlist = [0 for x in range(pnum)]
         Ilineeditlist = [0 for x in range(inum)]
         paramlineeditlist = [0 for x in range(length)]
         
         editcount = 1
         
         """Place lineedit widgets for parameters"""
         for s in range(snum):
             Slineeditlist[s] = QLineEdit()
             param_label.addWidget(Slineeditlist[s],editcount,2)
             editcount = editcount + 1
         
         SLElistlist[j] = Slineeditlist
         
         for s in range(pnum):
             Plineeditlist[s] = QLineEdit()
             param_label.addWidget(Plineeditlist[s],editcount,2)
             editcount = editcount + 1
         
         PLElistlist[j] = Plineeditlist
         
         for s in range(inum):
             Ilineeditlist[s] = QLineEdit()
             param_label.addWidget(Ilineeditlist[s],editcount,2)
             editcount = editcount + 1
            
         ILElistlist[j] = Ilineeditlist   
         
         for s in range(length):
             paramlineeditlist[s] = QLineEdit()
             param_label.addWidget(paramlineeditlist[s],editcount,2)
             editcount = editcount + 1
         
         paramLElistlist[j] = paramlineeditlist
         
         """Necessary lists for editable parameters. Housekeeping essentially."""
         stuff = paramlineeditlist[0].text()            
         numlistlist[j] = [snum, pnum, inum, length]
         charlist = ["S","P","I"]
         
         
         
         buttonlist.append(QPushButton(self))
         buttonlist[j].setText("Insert Rate Law: %s" % displaynamelist[j])
         
         
     # Warning: do not try to regroup the following QLabel contents with 
     # widgets above -- this string was isolated here in a single QLabel
     # on purpose: to fix Issue 863
         """Page formatting"""
         setup_layout = QVBoxLayout()
         setup_layout.addWidget(setup_label)
         setup_group.setLayout(setup_layout)
        
         desc_group.setLayout(param_label)
         
         vlayout = QVBoxLayout()
         vlayout.addWidget(setup_group)
         vlayout.addWidget(desc_group)
         vlayout.addWidget(buttonlist[j])
         vlayout.addStretch(1)
         self.lawdetailpage.setLayout(vlayout)
         self.lawpage.addWidget(self.lawdetailpage)
     
     """Set up button functionality"""
     for k in range(47):
         buttonlist[k].clicked.connect(pressbutton(self, infixmod[k], SLElistlist[k], PLElistlist[k],ILElistlist[k], paramLElistlist[k], parameternamelistlist[k], numlistlist[k], charlist,k))
         
     self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex)
     self.lawlist.setCurrentRow(0)
     
     
     """Set up high-level widget formatting."""
     hsplitter = QSplitter()
     hsplitter.addWidget(self.lawlist)
     hsplitter.addWidget(self.lawpage)
     
     layout = QVBoxLayout()
     layout.addWidget(hsplitter)
     self.setLayout(layout)
Esempio n. 16
0
class RunConfigDialog(QDialog, SizeMixin):
    """Run configuration dialog box: multiple file version"""

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        SizeMixin.__init__(self)

        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.file_to_run = None

        combo_label = QLabel(_("Select a run configuration:"))
        self.combo = QComboBox()
        self.combo.setMaxVisibleItems(20)
        self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.stack = QStackedWidget()

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        run_btn = bbox.addButton(_("Run"), QDialogButtonBox.AcceptRole)
        self.connect(run_btn, SIGNAL("clicked()"), self.run_btn_clicked)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        layout = QVBoxLayout()
        layout.addWidget(combo_label)
        layout.addWidget(self.combo)
        layout.addSpacing(10)
        layout.addWidget(self.stack)
        layout.addLayout(btnlayout)
        self.setLayout(layout)

        self.setWindowTitle(_("Run configurations"))
        self.setWindowIcon(get_icon("run.png"))

    def setup(self, fname):
        configurations = _get_run_configurations()
        for index, (filename, options) in enumerate(configurations):
            if fname == filename:
                break
        else:
            # There is no run configuration for script *fname*:
            # creating a temporary configuration that will be kept only if
            # dialog changes are accepted by the user
            configurations.insert(0, (fname, RunConfiguration(fname).get()))
            index = 0
        for filename, options in configurations:
            widget = RunConfigOptions(self)
            widget.set(options)
            self.combo.addItem(filename)
            self.stack.addWidget(widget)
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.stack.setCurrentIndex)
        self.combo.setCurrentIndex(index)

    def accept(self):
        """Reimplement Qt method"""
        configurations = []
        for index in range(self.stack.count()):
            filename = unicode(self.combo.itemText(index))
            runconfigoptions = self.stack.widget(index)
            if not runconfigoptions.is_valid():
                return
            options = runconfigoptions.get()
            configurations.append((filename, options))
        _set_run_configurations(configurations)
        QDialog.accept(self)

    def run_btn_clicked(self):
        self.file_to_run = unicode(self.combo.currentText())
Esempio n. 17
0
class ConfigDialog(QDialog):
    """Spyder configuration ('Preferences') dialog box"""
    
    # Signals
    check_settings = Signal()
    size_change = Signal(QSize)
    
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.main = parent

        # Widgets
        self.pages_widget = QStackedWidget()
        self.contents_widget = QListWidget()
        self.button_reset = QPushButton(_('Reset to defaults'))

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply |
                                QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)

        # Widgets setup
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle(_('Preferences'))
        self.setWindowIcon(ima.icon('configure'))
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)
        self.contents_widget.setCurrentRow(0)

        # Layout
        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addWidget(self.button_reset)
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        # Signals and slots
        self.button_reset.clicked.connect(self.main.reset_spyder)
        self.pages_widget.currentChanged.connect(self.current_page_changed)
        self.contents_widget.currentRowChanged.connect(
                                             self.pages_widget.setCurrentIndex)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        bbox.clicked.connect(self.button_clicked)

        # Ensures that the config is present on spyder first run
        CONF.set('main', 'interface_language', load_lang_conf())

    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()
        
    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)
        
    def get_page(self, index=None):
        """Return page widget"""
        if index is None:
            widget = self.pages_widget.currentWidget()
        else:
            widget = self.pages_widget.widget(index)
        return widget.widget()
    
    @Slot()
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.get_page(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)
        
    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.get_page()
            if not configpage.is_valid():
                return
            configpage.apply_changes()
            
    def current_page_changed(self, index):
        widget = self.get_page(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)
        
    def add_page(self, widget):
        self.check_settings.connect(widget.check_settings)
        widget.show_this_page.connect(lambda row=self.contents_widget.count():
                                      self.contents_widget.setCurrentRow(row))
        widget.apply_button_enabled.connect(self.apply_btn.setEnabled)
        scrollarea = QScrollArea(self)
        scrollarea.setWidgetResizable(True)
        scrollarea.setWidget(widget)
        self.pages_widget.addWidget(scrollarea)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))
        
    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.check_settings.emit()
    
    def resizeEvent(self, event):
        """
        Reimplement Qt method to be able to save the widget's size from the
        main application
        """
        QDialog.resizeEvent(self, event)
        self.size_change.emit(self.size())
Esempio n. 18
0
class VariableExplorer(QWidget, SpyderPluginMixin):
    """
    Variable Explorer Plugin
    """
    CONF_SECTION = 'variable_explorer'
    CONFIGWIDGET_CLASS = VariableExplorerConfigPage
    sig_option_changed = Signal(str, object)

    def __init__(self, parent):
        QWidget.__init__(self, parent)
        SpyderPluginMixin.__init__(self, parent)

        # Widgets
        self.stack = QStackedWidget(self)
        self.shellwidgets = {}

        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.stack)
        self.setLayout(layout)

        # Initialize plugin
        self.initialize_plugin()

    @staticmethod
    def get_settings():
        """
        Return Variable Explorer settings dictionary
        (i.e. namespace browser settings according to Spyder's configuration file)
        """
        settings = {}
#        CONF.load_from_ini() # necessary only when called from another process
        for name in REMOTE_SETTINGS:
            settings[name] = CONF.get(VariableExplorer.CONF_SECTION, name)
        return settings

    # ----- Stack accesors ----------------------------------------------------
    def set_current_widget(self, nsb):
        self.stack.setCurrentWidget(nsb)

    def current_widget(self):
        return self.stack.currentWidget()

    def count(self):
        return self.stack.count()

    def remove_widget(self, nsb):
        self.stack.removeWidget(nsb)

    def add_widget(self, nsb):
        self.stack.addWidget(nsb)

    # ----- Public API --------------------------------------------------------
    def add_shellwidget(self, shellwidget):
        shellwidget_id = id(shellwidget)
        # Add shell only once: this method may be called two times in a row
        # by the External console plugin (dev. convenience)
        from spyderlib.widgets.externalshell import systemshell
        if isinstance(shellwidget, systemshell.ExternalSystemShell):
            return
        if shellwidget_id not in self.shellwidgets:
            nsb = NamespaceBrowser(self)
            nsb.set_shellwidget(shellwidget)
            nsb.setup(**VariableExplorer.get_settings())
            nsb.sig_option_changed.connect(self.sig_option_changed.emit)
            self.add_widget(nsb)
            self.shellwidgets[shellwidget_id] = nsb
            self.set_shellwidget_from_id(shellwidget_id)
            return nsb
        
    def remove_shellwidget(self, shellwidget_id):
        # If shellwidget_id is not in self.shellwidgets, it simply means
        # that shell was not a Python-based console (it was a terminal)
        if shellwidget_id in self.shellwidgets:
            nsb = self.shellwidgets.pop(shellwidget_id)
            self.remove_widget(nsb)
            nsb.close()
    
    def set_shellwidget_from_id(self, shellwidget_id):
        if shellwidget_id in self.shellwidgets:
            nsb = self.shellwidgets[shellwidget_id]
            self.set_current_widget(nsb)
            if self.isvisible:
                nsb.visibility_changed(True)

    def import_data(self, fname):
        """Import data in current namespace"""
        if self.count():
            nsb = self.current_widget()
            nsb.refresh_table()
            nsb.import_data(filename=fname)
            if self.dockwidget and not self.ismaximized:
                self.dockwidget.setVisible(True)
                self.dockwidget.raise_()

    #------ SpyderPluginMixin API ---------------------------------------------
    def visibility_changed(self, enable):
        """DockWidget visibility has changed"""
        SpyderPluginMixin.visibility_changed(self, enable)
        for nsb in list(self.shellwidgets.values()):
            nsb.visibility_changed(enable and nsb is self.current_widget())
    
    #------ SpyderPluginWidget API ---------------------------------------------
    def get_plugin_title(self):
        """Return widget title"""
        return _('Variable explorer')

    def get_plugin_icon(self):
        """Return plugin icon"""
        return ima.icon('dictedit')
    
    def get_focus_widget(self):
        """
        Return the widget to give focus to when
        this plugin's dockwidget is raised on top-level
        """
        return self.current_widget()
        
    def closing_plugin(self, cancelable=False):
        """Perform actions before parent main window is closed"""
        return True
        
    def refresh_plugin(self):
        """Refresh widget"""
        pass
    
    def get_plugin_actions(self):
        """Return a list of actions related to plugin"""
        return []
    
    def register_plugin(self):
        """Register plugin in Spyder's main window"""
        self.main.extconsole.set_variableexplorer(self)
        self.main.add_dockwidget(self)
        
    def apply_plugin_settings(self, options):
        """Apply configuration file's plugin settings"""
        for nsb in list(self.shellwidgets.values()):
            nsb.setup(**VariableExplorer.get_settings())
        ar_timeout = self.get_option('autorefresh/timeout')
        for shellwidget in self.main.extconsole.shellwidgets:
            shellwidget.set_autorefresh_timeout(ar_timeout)
Esempio n. 19
0
class ConfigDialog(QDialog):
    """Spyder configuration ('Preferences') dialog box"""

    # Signals
    check_settings = Signal()
    size_change = Signal(QSize)

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.main = parent

        # Widgets
        self.pages_widget = QStackedWidget()
        self.contents_widget = QListWidget()
        self.button_reset = QPushButton(_('Reset to defaults'))

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply
                                | QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)

        # Widgets setup
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle(_('Preferences'))
        self.setWindowIcon(ima.icon('configure'))
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)
        self.contents_widget.setCurrentRow(0)

        # Layout
        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addWidget(self.button_reset)
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        # Signals and slots
        self.button_reset.clicked.connect(self.main.reset_spyder)
        self.pages_widget.currentChanged.connect(self.current_page_changed)
        self.contents_widget.currentRowChanged.connect(
            self.pages_widget.setCurrentIndex)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        bbox.clicked.connect(self.button_clicked)

        # Ensures that the config is present on spyder first run
        CONF.set('main', 'interface_language', load_lang_conf())

    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()

    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)

    def get_page(self, index=None):
        """Return page widget"""
        if index is None:
            widget = self.pages_widget.currentWidget()
        else:
            widget = self.pages_widget.widget(index)
        return widget.widget()

    @Slot()
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.get_page(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)

    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.get_page()
            if not configpage.is_valid():
                return
            configpage.apply_changes()

    def current_page_changed(self, index):
        widget = self.get_page(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)

    def add_page(self, widget):
        self.check_settings.connect(widget.check_settings)
        widget.show_this_page.connect(lambda row=self.contents_widget.count():
                                      self.contents_widget.setCurrentRow(row))
        widget.apply_button_enabled.connect(self.apply_btn.setEnabled)
        scrollarea = QScrollArea(self)
        scrollarea.setWidgetResizable(True)
        scrollarea.setWidget(widget)
        self.pages_widget.addWidget(scrollarea)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))

    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.check_settings.emit()

    def resizeEvent(self, event):
        """
        Reimplement Qt method to be able to save the widget's size from the
        main application
        """
        QDialog.resizeEvent(self, event)
        self.size_change.emit(self.size())
Esempio n. 20
0
class ConfigDialog(QDialog):
    """Spyder configuration ('Preferences') dialog box"""
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply
                                | QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle(_("Preferences"))
        self.setWindowIcon(get_icon("configure.png"))

    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()

    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)

    def get_page(self, index=None):
        """Return page widget"""
        if index is None:
            widget = self.pages_widget.currentWidget()
        else:
            widget = self.pages_widget.widget(index)
        return widget.widget()

    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.get_page(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)

    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.get_page()
            if not configpage.is_valid():
                return
            configpage.apply_changes()

    def current_page_changed(self, index):
        widget = self.get_page(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)

    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget,
                     SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count(): self.
                     contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        scrollarea = QScrollArea(self)
        scrollarea.setWidgetResizable(True)
        scrollarea.setWidget(widget)
        self.pages_widget.addWidget(scrollarea)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))

    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))

    def resizeEvent(self, event):
        """
        Reimplement Qt method to be able to save the widget's size from the
        main application
        """
        QDialog.resizeEvent(self, event)
        self.emit(SIGNAL("size_change(QSize)"), self.size())
Esempio n. 21
0
    def setup_and_check(self, data, title='', readonly=False,
                        xlabels=None, ylabels=None):
        """
        Setup ArrayEditor:
        return False if data is not supported, True otherwise
        """
        self.data = data
        is_record_array = data.dtype.names is not None
        is_masked_array = isinstance(data, np.ma.MaskedArray)
        if data.size == 0:
            self.error(_("Array is empty"))
            return False
        if data.ndim > 2:
            self.error(_("Arrays with more than 2 dimensions "
                               "are not supported"))
            return False
        if xlabels is not None and len(xlabels) != self.data.shape[1]:
            self.error(_("The 'xlabels' argument length "
						 	   "do no match array column number"))
            return False
        if ylabels is not None and len(ylabels) != self.data.shape[0]:
            self.error(_("The 'ylabels' argument length "
							   "do no match array row number"))
            return False
        if not is_record_array:
            dtn = data.dtype.name
            if dtn not in SUPPORTED_FORMATS and not dtn.startswith('string') \
               and not dtn.startswith('unicode'):
                arr = _("%s arrays") % data.dtype.name
                self.error(_("%s are currently not supported") % arr)
                return False
        
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setWindowIcon(get_icon('arredit.png'))
        if title:
            title = to_text_string(title) # in case title is not a string
        else:
            title = _("Array editor")
        if readonly:
            title += ' (' + _('read only') + ')'
        self.setWindowTitle(title)
        self.resize(600, 500)
        
        # Stack widget
        self.stack = QStackedWidget(self)
        if is_record_array:
            for name in data.dtype.names:
                self.stack.addWidget(ArrayEditorWidget(self, data[name],
                                                   readonly, xlabels, ylabels))
        elif is_masked_array:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly,
                                                   xlabels, ylabels))
        else:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
        self.arraywidget = self.stack.currentWidget()
        self.connect(self.stack, SIGNAL('currentChanged(int)'),
                     self.current_widget_changed)
        self.layout.addWidget(self.stack, 1, 0)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        if is_record_array or is_masked_array:
            if is_record_array:
                btn_layout.addWidget(QLabel(_("Record array fields:")))
                names = []
                for name in data.dtype.names:
                    field = data.dtype.fields[name]
                    text = name
                    if len(field) >= 3:
                        title = field[2]
                        if not is_text_string(title):
                            title = repr(title)
                        text += ' - '+title
                    names.append(text)
            else:
                names = [_('Masked data'), _('Data'), _('Mask')]
            ra_combo = QComboBox(self)
            self.connect(ra_combo, SIGNAL('currentIndexChanged(int)'),
                         self.stack.setCurrentIndex)
            ra_combo.addItems(names)
            btn_layout.addWidget(ra_combo)
            if is_masked_array:
                label = QLabel(_("<u>Warning</u>: changes are applied separately"))
                label.setToolTip(_("For performance reasons, changes applied "\
                                   "to masked array won't be reflected in "\
                                   "array's data (and vice-versa)."))
                btn_layout.addWidget(label)
            btn_layout.addStretch()
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        btn_layout.addWidget(bbox)
        self.layout.addLayout(btn_layout, 2, 0)
        
        self.setMinimumSize(400, 300)
        
        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)
        
        return True
Esempio n. 22
0
class ArrayEditor(QDialog):
    """Array Editor Dialog"""    
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        
        self.data = None
        self.arraywidget = None
        self.stack = None
        self.layout = None
        # Values for 3d array editor
        self.dim_indexes = [{}, {}, {}]
        self.last_dim = 0  # Adjust this for changing the startup dimension
        
    def setup_and_check(self, data, title='', readonly=False,
                        xlabels=None, ylabels=None):
        """
        Setup ArrayEditor:
        return False if data is not supported, True otherwise
        """
        self.data = data
        is_record_array = data.dtype.names is not None
        is_masked_array = isinstance(data, np.ma.MaskedArray)
        if data.size == 0:
            self.error(_("Array is empty"))
            return False
        if data.ndim > 3:
            self.error(_("Arrays with more than 3 dimensions are not supported"))
            return False
        if xlabels is not None and len(xlabels) != self.data.shape[1]:
            self.error(_("The 'xlabels' argument length do no match array "
                         "column number"))
            return False
        if ylabels is not None and len(ylabels) != self.data.shape[0]:
            self.error(_("The 'ylabels' argument length do no match array row "
                         "number"))
            return False
        if not is_record_array:
            dtn = data.dtype.name
            if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \
               and not dtn.startswith('unicode'):
                arr = _("%s arrays") % data.dtype.name
                self.error(_("%s are currently not supported") % arr)
                return False
        
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setWindowIcon(ima.icon('arredit'))
        if title:
            title = to_text_string(title) + " - " + _("NumPy array")
        else:
            title = _("Array editor")
        if readonly:
            title += ' (' + _('read only') + ')'
        self.setWindowTitle(title)
        self.resize(600, 500)
        
        # Stack widget
        self.stack = QStackedWidget(self)
        if is_record_array:
            for name in data.dtype.names:
                self.stack.addWidget(ArrayEditorWidget(self, data[name],
                                                   readonly, xlabels, ylabels))
        elif is_masked_array:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly,
                                                   xlabels, ylabels))
        elif data.ndim == 3:
            pass
        else:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
        self.arraywidget = self.stack.currentWidget()
        self.stack.currentChanged.connect(self.current_widget_changed)
        self.layout.addWidget(self.stack, 1, 0)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        if is_record_array or is_masked_array or data.ndim == 3:
            if is_record_array:
                btn_layout.addWidget(QLabel(_("Record array fields:")))
                names = []
                for name in data.dtype.names:
                    field = data.dtype.fields[name]
                    text = name
                    if len(field) >= 3:
                        title = field[2]
                        if not is_text_string(title):
                            title = repr(title)
                        text += ' - '+title
                    names.append(text)
            else:
                names = [_('Masked data'), _('Data'), _('Mask')]
            if data.ndim == 3:
                # QSpinBox
                self.index_spin = QSpinBox(self, keyboardTracking=False)
                self.index_spin.valueChanged.connect(self.change_active_widget)
                # QComboBox
                names = [str(i) for i in range(3)]
                ra_combo = QComboBox(self)
                ra_combo.addItems(names)
                ra_combo.currentIndexChanged.connect(self.current_dim_changed)    
                # Adding the widgets to layout
                label = QLabel(_("Axis:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(ra_combo)
                self.shape_label = QLabel()
                btn_layout.addWidget(self.shape_label)
                label = QLabel(_("Index:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(self.index_spin)
                self.slicing_label = QLabel()
                btn_layout.addWidget(self.slicing_label)
                # set the widget to display when launched
                self.current_dim_changed(self.last_dim)
            else:
                ra_combo = QComboBox(self)
                ra_combo.currentIndexChanged.connect(self.stack.setCurrentIndex)
                ra_combo.addItems(names)
                btn_layout.addWidget(ra_combo)
            if is_masked_array:
                label = QLabel(_("<u>Warning</u>: changes are applied separately"))
                label.setToolTip(_("For performance reasons, changes applied "\
                                   "to masked array won't be reflected in "\
                                   "array's data (and vice-versa)."))
                btn_layout.addWidget(label)
            btn_layout.addStretch()
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        btn_layout.addWidget(bbox)
        self.layout.addLayout(btn_layout, 2, 0)

        self.setMinimumSize(400, 300)
        
        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)
        
        return True
            
    def current_widget_changed(self, index):
        self.arraywidget = self.stack.widget(index)     
            
    def change_active_widget(self, index):
        """
        This is implemented for handling negative values in index for
        3d arrays, to give the same behavior as slicing
        """
        string_index = [':']*3
        string_index[self.last_dim] = '<font color=red>%i</font>'
        self.slicing_label.setText((r"Slicing: [" + ", ".join(string_index) +
                                "]") % index)
        if index < 0:
            data_index = self.data.shape[self.last_dim] + index
        else:
            data_index = index
        slice_index = [slice(None)]*3
        slice_index[self.last_dim] = data_index

        stack_index = self.dim_indexes[self.last_dim].get(data_index)
        if stack_index == None:
            stack_index = self.stack.count()
            self.stack.addWidget(ArrayEditorWidget(self,
                                                   self.data[slice_index]))
            self.dim_indexes[self.last_dim][data_index] = stack_index
            self.stack.update()
        self.stack.setCurrentIndex(stack_index)

    def current_dim_changed(self, index):
        """
        This change the active axis the array editor is plotting over
        in 3D
        """
        self.last_dim = index
        string_size = ['%i']*3
        string_size[index] = '<font color=red>%i</font>'
        self.shape_label.setText(('Shape: (' + ', '.join(string_size) +
                                 ')    ') % self.data.shape)
        if self.index_spin.value() != 0:
            self.index_spin.setValue(0)
        else:
            # this is done since if the value is currently 0 it does not emit
            # currentIndexChanged(int)
            self.change_active_widget(0)
        self.index_spin.setRange(-self.data.shape[index],
                                 self.data.shape[index]-1)

    @Slot()
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.stack.count()):
            self.stack.widget(index).accept_changes()
        QDialog.accept(self)
        
    def get_value(self):
        """Return modified array -- this is *not* a copy"""
        # It is import to avoid accessing Qt C++ object as it has probably
        # already been destroyed, due to the Qt.WA_DeleteOnClose attribute
        return self.data

    def error(self, message):
        """An error occured, closing the dialog box"""
        QMessageBox.critical(self, _("Array editor"), message)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.reject()

    @Slot()
    def reject(self):
        """Reimplement Qt method"""
        if self.arraywidget is not None:
            for index in range(self.stack.count()):
                self.stack.widget(index).reject_changes()
        QDialog.reject(self)
Esempio n. 23
0
    def setup_and_check(self,
                        data,
                        title='',
                        readonly=False,
                        xlabels=None,
                        ylabels=None):
        """
        Setup ArrayEditor:
        return False if data is not supported, True otherwise
        """
        self.data = data
        is_record_array = data.dtype.names is not None
        is_masked_array = isinstance(data, np.ma.MaskedArray)
        if data.size == 0:
            self.error(_("Array is empty"))
            return False
        if data.ndim > 3:
            self.error(
                _("Arrays with more than 3 dimensions "
                  "are not supported"))
            return False
        if xlabels is not None and len(xlabels) != self.data.shape[1]:
            self.error(
                _("The 'xlabels' argument length "
                  "do no match array column number"))
            return False
        if ylabels is not None and len(ylabels) != self.data.shape[0]:
            self.error(
                _("The 'ylabels' argument length "
                  "do no match array row number"))
            return False
        if not is_record_array:
            dtn = data.dtype.name
            if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \
               and not dtn.startswith('unicode'):
                arr = _("%s arrays") % data.dtype.name
                self.error(_("%s are currently not supported") % arr)
                return False

        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setWindowIcon(get_icon('arredit.png'))
        if title:
            title = to_text_string(title)  # in case title is not a string
        else:
            title = _("Array editor")
        if readonly:
            title += ' (' + _('read only') + ')'
        self.setWindowTitle(title)
        self.resize(600, 500)

        # Stack widget
        self.stack = QStackedWidget(self)
        if is_record_array:
            for name in data.dtype.names:
                self.stack.addWidget(
                    ArrayEditorWidget(self, data[name], readonly, xlabels,
                                      ylabels))
        elif is_masked_array:
            self.stack.addWidget(
                ArrayEditorWidget(self, data, readonly, xlabels, ylabels))
            self.stack.addWidget(
                ArrayEditorWidget(self, data.data, readonly, xlabels, ylabels))
            self.stack.addWidget(
                ArrayEditorWidget(self, data.mask, readonly, xlabels, ylabels))
        elif data.ndim == 3:
            pass
        else:
            self.stack.addWidget(
                ArrayEditorWidget(self, data, readonly, xlabels, ylabels))
        self.arraywidget = self.stack.currentWidget()
        self.stack.currentChanged.connect(self.current_widget_changed)
        self.layout.addWidget(self.stack, 1, 0)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        if is_record_array or is_masked_array or data.ndim == 3:
            if is_record_array:
                btn_layout.addWidget(QLabel(_("Record array fields:")))
                names = []
                for name in data.dtype.names:
                    field = data.dtype.fields[name]
                    text = name
                    if len(field) >= 3:
                        title = field[2]
                        if not is_text_string(title):
                            title = repr(title)
                        text += ' - ' + title
                    names.append(text)
            else:
                names = [_('Masked data'), _('Data'), _('Mask')]
            if data.ndim == 3:
                # QSpinBox
                self.index_spin = QSpinBox(self, keyboardTracking=False)
                self.index_spin.valueChanged.connect(self.change_active_widget)
                # QComboBox
                names = [str(i) for i in range(3)]
                ra_combo = QComboBox(self)
                ra_combo.addItems(names)
                ra_combo.currentIndexChanged.connect(self.current_dim_changed)
                # Adding the widgets to layout
                label = QLabel(_("Axis:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(ra_combo)
                self.shape_label = QLabel()
                btn_layout.addWidget(self.shape_label)
                label = QLabel(_("Index:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(self.index_spin)
                self.slicing_label = QLabel()
                btn_layout.addWidget(self.slicing_label)
                # set the widget to display when launched
                self.current_dim_changed(self.last_dim)
            else:
                ra_combo = QComboBox(self)
                ra_combo.currentIndexChanged.connect(
                    self.stack.setCurrentIndex)
                ra_combo.addItems(names)
                btn_layout.addWidget(ra_combo)
            if is_masked_array:
                label = QLabel(
                    _("<u>Warning</u>: changes are applied separately"))
                label.setToolTip(_("For performance reasons, changes applied "\
                                   "to masked array won't be reflected in "\
                                   "array's data (and vice-versa)."))
                btn_layout.addWidget(label)
            btn_layout.addStretch()
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        btn_layout.addWidget(bbox)
        self.layout.addLayout(btn_layout, 2, 0)

        self.setMinimumSize(400, 300)

        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)

        return True
Esempio n. 24
0
class VariableExplorer(QWidget, SpyderPluginMixin):
    """
    Variable Explorer Plugin
    """
    CONF_SECTION = 'variable_explorer'
    CONFIGWIDGET_CLASS = VariableExplorerConfigPage
    sig_option_changed = Signal(str, object)

    def __init__(self, parent):
        QWidget.__init__(self, parent)
        SpyderPluginMixin.__init__(self, parent)

        # Widgets
        self.stack = QStackedWidget(self)
        self.shellwidgets = {}

        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.stack)
        self.setLayout(layout)

        # Initialize plugin
        self.initialize_plugin()

    @staticmethod
    def get_settings():
        """
        Return Variable Explorer settings dictionary
        (i.e. namespace browser settings according to Spyder's configuration file)
        """
        settings = {}
        #        CONF.load_from_ini() # necessary only when called from another process
        for name in REMOTE_SETTINGS:
            settings[name] = CONF.get(VariableExplorer.CONF_SECTION, name)
        return settings

    # ----- Stack accesors ----------------------------------------------------
    def set_current_widget(self, nsb):
        self.stack.setCurrentWidget(nsb)

    def current_widget(self):
        return self.stack.currentWidget()

    def count(self):
        return self.stack.count()

    def remove_widget(self, nsb):
        self.stack.removeWidget(nsb)

    def add_widget(self, nsb):
        self.stack.addWidget(nsb)

    # ----- Public API --------------------------------------------------------
    def add_shellwidget(self, shellwidget):
        shellwidget_id = id(shellwidget)
        # Add shell only once: this method may be called two times in a row
        # by the External console plugin (dev. convenience)
        from spyderlib.widgets.externalshell import systemshell
        if isinstance(shellwidget, systemshell.ExternalSystemShell):
            return
        if shellwidget_id not in self.shellwidgets:
            nsb = NamespaceBrowser(self)
            nsb.set_shellwidget(shellwidget)
            nsb.setup(**VariableExplorer.get_settings())
            nsb.sig_option_changed.connect(self.sig_option_changed.emit)
            self.add_widget(nsb)
            self.shellwidgets[shellwidget_id] = nsb
            self.set_shellwidget_from_id(shellwidget_id)
            return nsb

    def remove_shellwidget(self, shellwidget_id):
        # If shellwidget_id is not in self.shellwidgets, it simply means
        # that shell was not a Python-based console (it was a terminal)
        if shellwidget_id in self.shellwidgets:
            nsb = self.shellwidgets.pop(shellwidget_id)
            self.remove_widget(nsb)
            nsb.close()

    def set_shellwidget_from_id(self, shellwidget_id):
        if shellwidget_id in self.shellwidgets:
            nsb = self.shellwidgets[shellwidget_id]
            self.set_current_widget(nsb)
            if self.isvisible:
                nsb.visibility_changed(True)

    def import_data(self, fname):
        """Import data in current namespace"""
        if self.count():
            nsb = self.current_widget()
            nsb.refresh_table()
            nsb.import_data(filename=fname)
            if self.dockwidget and not self.ismaximized:
                self.dockwidget.setVisible(True)
                self.dockwidget.raise_()

    #------ SpyderPluginMixin API ---------------------------------------------
    def visibility_changed(self, enable):
        """DockWidget visibility has changed"""
        SpyderPluginMixin.visibility_changed(self, enable)
        for nsb in list(self.shellwidgets.values()):
            nsb.visibility_changed(enable and nsb is self.current_widget())

    #------ SpyderPluginWidget API ---------------------------------------------
    def get_plugin_title(self):
        """Return widget title"""
        return _('Variable explorer')

    def get_plugin_icon(self):
        """Return plugin icon"""
        return ima.icon('dictedit')

    def get_focus_widget(self):
        """
        Return the widget to give focus to when
        this plugin's dockwidget is raised on top-level
        """
        return self.current_widget()

    def closing_plugin(self, cancelable=False):
        """Perform actions before parent main window is closed"""
        return True

    def refresh_plugin(self):
        """Refresh widget"""
        pass

    def get_plugin_actions(self):
        """Return a list of actions related to plugin"""
        return []

    def register_plugin(self):
        """Register plugin in Spyder's main window"""
        self.main.extconsole.set_variableexplorer(self)
        self.main.add_dockwidget(self)

    def apply_plugin_settings(self, options):
        """Apply configuration file's plugin settings"""
        for nsb in list(self.shellwidgets.values()):
            nsb.setup(**VariableExplorer.get_settings())
        ar_timeout = self.get_option('autorefresh/timeout')
        for shellwidget in self.main.extconsole.shellwidgets:
            shellwidget.set_autorefresh_timeout(ar_timeout)
Esempio n. 25
0
class ArrayEditor(QDialog):
    """Array Editor Dialog"""
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.data = None
        self.arraywidget = None
        self.stack = None
        self.layout = None
        # Values for 3d array editor
        self.dim_indexes = [{}, {}, {}]
        self.last_dim = 0  # Adjust this for changing the startup dimension

    def setup_and_check(self,
                        data,
                        title='',
                        readonly=False,
                        xlabels=None,
                        ylabels=None):
        """
        Setup ArrayEditor:
        return False if data is not supported, True otherwise
        """
        self.data = data
        is_record_array = data.dtype.names is not None
        is_masked_array = isinstance(data, np.ma.MaskedArray)
        if data.size == 0:
            self.error(_("Array is empty"))
            return False
        if data.ndim > 3:
            self.error(
                _("Arrays with more than 3 dimensions "
                  "are not supported"))
            return False
        if xlabels is not None and len(xlabels) != self.data.shape[1]:
            self.error(
                _("The 'xlabels' argument length "
                  "do no match array column number"))
            return False
        if ylabels is not None and len(ylabels) != self.data.shape[0]:
            self.error(
                _("The 'ylabels' argument length "
                  "do no match array row number"))
            return False
        if not is_record_array:
            dtn = data.dtype.name
            if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \
               and not dtn.startswith('unicode'):
                arr = _("%s arrays") % data.dtype.name
                self.error(_("%s are currently not supported") % arr)
                return False

        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setWindowIcon(get_icon('arredit.png'))
        if title:
            title = to_text_string(title)  # in case title is not a string
        else:
            title = _("Array editor")
        if readonly:
            title += ' (' + _('read only') + ')'
        self.setWindowTitle(title)
        self.resize(600, 500)

        # Stack widget
        self.stack = QStackedWidget(self)
        if is_record_array:
            for name in data.dtype.names:
                self.stack.addWidget(
                    ArrayEditorWidget(self, data[name], readonly, xlabels,
                                      ylabels))
        elif is_masked_array:
            self.stack.addWidget(
                ArrayEditorWidget(self, data, readonly, xlabels, ylabels))
            self.stack.addWidget(
                ArrayEditorWidget(self, data.data, readonly, xlabels, ylabels))
            self.stack.addWidget(
                ArrayEditorWidget(self, data.mask, readonly, xlabels, ylabels))
        elif data.ndim == 3:
            pass
        else:
            self.stack.addWidget(
                ArrayEditorWidget(self, data, readonly, xlabels, ylabels))
        self.arraywidget = self.stack.currentWidget()
        self.stack.currentChanged.connect(self.current_widget_changed)
        self.layout.addWidget(self.stack, 1, 0)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        if is_record_array or is_masked_array or data.ndim == 3:
            if is_record_array:
                btn_layout.addWidget(QLabel(_("Record array fields:")))
                names = []
                for name in data.dtype.names:
                    field = data.dtype.fields[name]
                    text = name
                    if len(field) >= 3:
                        title = field[2]
                        if not is_text_string(title):
                            title = repr(title)
                        text += ' - ' + title
                    names.append(text)
            else:
                names = [_('Masked data'), _('Data'), _('Mask')]
            if data.ndim == 3:
                # QSpinBox
                self.index_spin = QSpinBox(self, keyboardTracking=False)
                self.index_spin.valueChanged.connect(self.change_active_widget)
                # QComboBox
                names = [str(i) for i in range(3)]
                ra_combo = QComboBox(self)
                ra_combo.addItems(names)
                ra_combo.currentIndexChanged.connect(self.current_dim_changed)
                # Adding the widgets to layout
                label = QLabel(_("Axis:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(ra_combo)
                self.shape_label = QLabel()
                btn_layout.addWidget(self.shape_label)
                label = QLabel(_("Index:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(self.index_spin)
                self.slicing_label = QLabel()
                btn_layout.addWidget(self.slicing_label)
                # set the widget to display when launched
                self.current_dim_changed(self.last_dim)
            else:
                ra_combo = QComboBox(self)
                ra_combo.currentIndexChanged.connect(
                    self.stack.setCurrentIndex)
                ra_combo.addItems(names)
                btn_layout.addWidget(ra_combo)
            if is_masked_array:
                label = QLabel(
                    _("<u>Warning</u>: changes are applied separately"))
                label.setToolTip(_("For performance reasons, changes applied "\
                                   "to masked array won't be reflected in "\
                                   "array's data (and vice-versa)."))
                btn_layout.addWidget(label)
            btn_layout.addStretch()
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        btn_layout.addWidget(bbox)
        self.layout.addLayout(btn_layout, 2, 0)

        self.setMinimumSize(400, 300)

        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)

        return True

    def current_widget_changed(self, index):
        self.arraywidget = self.stack.widget(index)

    def change_active_widget(self, index):
        """
        This is implemented for handling negative values in index for
        3d arrays, to give the same behavior as slicing
        """
        string_index = [':'] * 3
        string_index[self.last_dim] = '<font color=red>%i</font>'
        self.slicing_label.setText(
            (r"Slicing: [" + ", ".join(string_index) + "]") % index)
        if index < 0:
            data_index = self.data.shape[self.last_dim] + index
        else:
            data_index = index
        slice_index = [slice(None)] * 3
        slice_index[self.last_dim] = data_index

        stack_index = self.dim_indexes[self.last_dim].get(data_index)
        if stack_index == None:
            stack_index = self.stack.count()
            self.stack.addWidget(
                ArrayEditorWidget(self, self.data[slice_index]))
            self.dim_indexes[self.last_dim][data_index] = stack_index
            self.stack.update()
        self.stack.setCurrentIndex(stack_index)

    def current_dim_changed(self, index):
        """
        This change the active axis the array editor is plotting over
        in 3D
        """
        self.last_dim = index
        string_size = ['%i'] * 3
        string_size[index] = '<font color=red>%i</font>'
        self.shape_label.setText(
            ('Shape: (' + ', '.join(string_size) + ')    ') % self.data.shape)
        if self.index_spin.value() != 0:
            self.index_spin.setValue(0)
        else:
            # this is done since if the value is currently 0 it does not emit
            # currentIndexChanged(int)
            self.change_active_widget(0)
        self.index_spin.setRange(-self.data.shape[index],
                                 self.data.shape[index] - 1)

    @Slot()
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.stack.count()):
            self.stack.widget(index).accept_changes()
        QDialog.accept(self)

    def get_value(self):
        """Return modified array -- this is *not* a copy"""
        # It is import to avoid accessing Qt C++ object as it has probably
        # already been destroyed, due to the Qt.WA_DeleteOnClose attribute
        return self.data

    def error(self, message):
        """An error occured, closing the dialog box"""
        QMessageBox.critical(self, _("Array editor"), message)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.reject()

    @Slot()
    def reject(self):
        """Reimplement Qt method"""
        if self.arraywidget is not None:
            for index in range(self.stack.count()):
                self.stack.widget(index).reject_changes()
        QDialog.reject(self)
Esempio n. 26
0
    def __init__(self, parent, max_entries=100):

        "Initialize Various list objects before assignment"
        displaylist = []
        displaynamelist = []
        infixmod = []
        infixlist = []
        desclist = []

        parameternamelist = []
        parameterdesclist = []
        parameterstringlist = []
        paramcountlist = []

        buttonlist = []
        xmldoc = minidom.parse('C:\\Users\\Jayit\\.spyder2\\ratelaw2_0_3.xml')
        #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml')

        lawlistxml = xmldoc.getElementsByTagName('law')

        o = 0
        for s in lawlistxml:
            o = o + 1

        parameternamelistlist = [0 for x in range(o)]
        parameterdesclistlist = [0 for x in range(o)]
        """i is the number of laws currently in the xml file"""
        i = 0
        """
        Parsing xml: Acquiring rate law name, description, and list of parameter information
        """
        for s in lawlistxml:
            #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n"
            """Gets Latec Expression"""
            displaylist.append(s.getAttribute('display'))
            """Gets Rate-Law Name"""
            displaynamelist.append(s.getAttribute('displayName'))
            """"Gets Raw Rate-Law expression"""
            infixlist.append(s.getAttribute('infixExpression'))
            """Gets description statement"""
            desclist.append(s.getAttribute('description'))
            """Gets listOfParameters Object"""
            parameterlist = s.getElementsByTagName('listOfParameters')[0]
            """Gets a list of parameters within ListOfParameters object"""
            parameters = parameterlist.getElementsByTagName('parameter')

            for param in parameters:
                parameternamelist.append(param.attributes['name'].value)
                #print(param.attributes['name'].value)
                parameterdesclist.append(param.attributes['description'].value)

            parameternamelistlist[i] = parameternamelist
            #print("break")
            parameterdesclistlist[i] = parameterdesclist

            parameternamelist = []
            parameterdesclist = []
            i = i + 1

        SLElistlist = [0 for x in range(i)]
        PLElistlist = [0 for x in range(i)]
        ILElistlist = [0 for x in range(i)]
        paramLElistlist = [0 for x in range(i)]
        numlistlist = [0 for x in range(i)]

        QWidget.__init__(self, parent)

        self.setWindowTitle("Rate Law Library")

        self.output = None
        self.error_output = None
        self._last_wdir = None
        self._last_args = None
        self._last_pythonpath = None

        #self.textlabel = QLabel(RATE_LAW_MESSAGE)

        self.lawlist = QListWidget()
        self.lawpage = QStackedWidget()
        index = 0
        for j in range(i):
            item = QListWidgetItem(displaynamelist[j])
            self.lawlist.addItem(item)
            self.lawdetailpage = QWidget()
            setup_group = QGroupBox(displaynamelist[j])
            infixmod.append(infixlist[j].replace("___", " "))
            setup_label = QLabel(infixmod[j])
            setup_label.setWordWrap(True)

            desc_group = QGroupBox("Description")
            desc_label = QLabel(desclist[j])
            desc_label.setWordWrap(True)

            param_label = QGridLayout()
            nm = QLabel("Name:")
            des = QLabel("Description:")
            repl = QLabel("Replace with:")
            param_label.addWidget(nm, 0, 0)
            param_label.addWidget(des, 0, 1)
            param_label.addWidget(repl, 0, 2)
            """g is the total number of alterable values"""
            g = 0
            """t is the total number of alterable non-parameters"""
            t = 1

            snum = 0
            pnum = 0
            inum = 0
            """range of N is the max number of possible substrates OR products"""
            N = 5
            for n in range(N):
                nl = n + 1
                if (infixmod[j].find('S%s' % nl) > -1):
                    z = QLabel('S%s is present' % nl)
                    param_label.addWidget(z, t, 0)
                    snum = snum + 1
                    t = t + 1

            for n in range(N):
                nl = n + 1
                if (infixmod[j].find('P%s' % nl) > -1):
                    z = QLabel('P%s is present' % nl)
                    param_label.addWidget(z, t, 0)
                    pnum = pnum + 1
                    t = t + 1

            for n in range(N):
                nl = n + 1
                if (infixmod[j].find('I%s' % nl) > -1):
                    z = QLabel('I%s is present' % nl)
                    param_label.addWidget(z, t, 0)
                    inum = inum + 1
                    t = t + 1
            """Initialize lists of list of parameter lineedit"""
            length = len(parameternamelistlist[j])
            for b in range(length):
                p = QLabel("%s :" % parameternamelistlist[j][b])
                param_label.addWidget(p, b + t, 0)
                d = QLabel("'%s'" % parameterdesclistlist[j][b])
                param_label.addWidget(d, b + t, 1)

            g = t + length

            Slineeditlist = [0 for x in range(snum)]
            Plineeditlist = [0 for x in range(pnum)]
            Ilineeditlist = [0 for x in range(inum)]
            paramlineeditlist = [0 for x in range(length)]

            editcount = 1
            """Place lineedit widgets for parameters"""
            for s in range(snum):
                Slineeditlist[s] = QLineEdit()
                param_label.addWidget(Slineeditlist[s], editcount, 2)
                editcount = editcount + 1

            SLElistlist[j] = Slineeditlist

            for s in range(pnum):
                Plineeditlist[s] = QLineEdit()
                param_label.addWidget(Plineeditlist[s], editcount, 2)
                editcount = editcount + 1

            PLElistlist[j] = Plineeditlist

            for s in range(inum):
                Ilineeditlist[s] = QLineEdit()
                param_label.addWidget(Ilineeditlist[s], editcount, 2)
                editcount = editcount + 1

            ILElistlist[j] = Ilineeditlist

            for s in range(length):
                paramlineeditlist[s] = QLineEdit()
                param_label.addWidget(paramlineeditlist[s], editcount, 2)
                editcount = editcount + 1

            paramLElistlist[j] = paramlineeditlist
            """Necessary lists for editable parameters. Housekeeping essentially."""
            stuff = paramlineeditlist[0].text()
            numlistlist[j] = [snum, pnum, inum, length]
            charlist = ["S", "P", "I"]

            buttonlist.append(QPushButton(self))
            buttonlist[j].setText("Insert Rate Law: %s" % displaynamelist[j])

            # Warning: do not try to regroup the following QLabel contents with
            # widgets above -- this string was isolated here in a single QLabel
            # on purpose: to fix Issue 863
            """Page formatting"""
            setup_layout = QVBoxLayout()
            setup_layout.addWidget(setup_label)
            setup_group.setLayout(setup_layout)

            desc_group.setLayout(param_label)

            vlayout = QVBoxLayout()
            vlayout.addWidget(setup_group)
            vlayout.addWidget(desc_group)
            vlayout.addWidget(buttonlist[j])
            vlayout.addStretch(1)
            self.lawdetailpage.setLayout(vlayout)
            self.lawpage.addWidget(self.lawdetailpage)
        """Set up button functionality"""
        for k in range(47):
            buttonlist[k].clicked.connect(
                pressbutton(self, infixmod[k], SLElistlist[k], PLElistlist[k],
                            ILElistlist[k], paramLElistlist[k],
                            parameternamelistlist[k], numlistlist[k], charlist,
                            k))

        self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex)
        self.lawlist.setCurrentRow(0)
        """Set up high-level widget formatting."""
        hsplitter = QSplitter()
        hsplitter.addWidget(self.lawlist)
        hsplitter.addWidget(self.lawpage)

        layout = QVBoxLayout()
        layout.addWidget(hsplitter)
        self.setLayout(layout)
Esempio n. 27
0
    def __init__(self, parent, max_entries=100):
        """ Creates a very basic window with some text """
        """
        RATE_LAW_MESSAGE = \
            "The Plugins for Spyder consists out of three main classes: \n\n" \
            "1. HelloWorld\n\n" \
            "\tThe HelloWorld class inherits all its methods from\n" \
            "\tSpyderPluginMixin and the HelloWorldWidget and performs all\n" \
            "\tthe processing required by the GU. \n\n" \
            "2. HelloWorldConfigPage\n\n" \
            "\tThe HelloWorldConfig class inherits all its methods from\n" \
            "\tPluginConfigPage to create a configuration page that can be\n" \
            "\tfound under Tools -> Preferences\n\n" \
            "3. HelloWorldWidget\n\n" \
            "\tThe HelloWorldWidget class inherits all its methods from\n" \
            "\tQWidget to create the actual plugin GUI interface that \n" \
            "\tdisplays this message on screen\n\n"
        """
        #Testing access editor on plugin initialization
        
        
        RATE_LAW_MESSAGE = ""
        displaynamelist = []
        #displaylist = []
        infixlist = []
        desclist = []
        parameterstringlist = []
        xmldoc = minidom.parse('\\.spyder2\\ratelaw2_0_3.xml')
        #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml')
        
        lawlistxml = xmldoc.getElementsByTagName('law')
        #i is the number of laws currently in the xml file
        i = 0
        
        """
        Parsing xml: Acquiring rate law name, description, and list of parameter information
        """
        for s in lawlistxml:
            #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n"
            RATE_LAW_MESSAGE += s.getAttribute('display') + "\n"
            #displaynamelist[i] = s.getAttribute('displayName')
            #displaylist[i] = s.getAttribute('display')
            displaynamelist.append(s.getAttribute('displayName'))
            #displaylist.append(s.getAttribute('display'))
            infixlist.append(s.getAttribute('infixExpression'))
            desclist.append(s.getAttribute('description'))
            parameterlist = s.getElementsByTagName('listOfParameters')[0]
            #for p in parameterlist    
            parameters = parameterlist.getElementsByTagName('parameter')
            parameterstring = ""
            for param in parameters:
                parametername = param.attributes['name'].value
                parameterdesc = param.attributes['description'].value
                parameterstring = parameterstring + '\t' + parametername + ":" + '\t' + "  " + parameterdesc + "\n"
                """Creates "description" string"""
                #print('\t' + parametername + ":" + '\t' + parameterdesc)
            parameterstringlist.append(parameterstring)    
            i = i + 1
            
        
        QWidget.__init__(self, parent)
        
        self.setWindowTitle("Rate Law Library")
        
        self.output = None
        self.error_output = None
        
        self._last_wdir = None
        self._last_args = None
        self._last_pythonpath = None
        
        self.textlabel = QLabel(RATE_LAW_MESSAGE)        

        self.lawlist = QListWidget()
        self.lawpage = QStackedWidget()
        #Adding displayName items to lawlist
        for j in range(i):
            item = QListWidgetItem(displaynamelist[j])      """Creates list entry for each rate law"""
            self.lawlist.addItem(item)                      """Adds rate law to list"""
            self.lawdetailpage = QWidget()                  """Creates page for each rate law"""
            # Page layout will become its own function
            setup_group = QGroupBox(displaynamelist[j])     """Creates box with rate law name as title"""
            infixmod = infixlist[j].replace("___"," ")      
            setup_label = QLabel(infixmod)
            setup_label.setWordWrap(True)                   """types rate law expression, removing underscores"""
            
            desc_group = QGroupBox("Description")           """creates box for description"""
            desc_label = QLabel(desclist[j])
            desc_label.setWordWrap(True)
            param_label = QLabel(parameterstringlist[j])
            param_label.setWordWrap(True)

        # Warning: do not try to regroup the following QLabel contents with 
        # widgets above -- this string was isolated here in a single QLabel
        # on purpose: to fix Issue 863
            setup_layout = QVBoxLayout()
            setup_layout.addWidget(setup_label)
            setup_group.setLayout(setup_layout)
            
            desc_layout = QVBoxLayout()
            desc_layout.addWidget(desc_label)
            desc_layout.addWidget(param_label)
            desc_group.setLayout(desc_layout)

            vlayout = QVBoxLayout()
            vlayout.addWidget(setup_group)
            vlayout.addWidget(desc_group)
            vlayout.addStretch(1)
            self.lawdetailpage.setLayout(vlayout)
            
            self.lawpage.addWidget(self.lawdetailpage)      """Formats the page shown when a rate law is selected"""
        
        #self.connect(self.lawlist, SIGNAL(self.lawlist.currentRowChanged(int)),self.lawpage,SLOT(self.lawpage.setCurrentIndex(int)))
        self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex)     """When a rate law in the list is clicked, its corresponding page is shown"""       
        '''
        self.lawpage = QWidget()
        '''
        self.lawlist.setCurrentRow(0)
        
        hsplitter = QSplitter()
        hsplitter.addWidget(self.lawlist)                   "Adds list to left side of window"
        
        
        
        
        hlayout1 = QHBoxLayout()
        hlayout1.addWidget(self.textlabel)
        hlayout1.addStretch()
        self.lawpage.setLayout(hlayout1)
        
        hsplitter.addWidget(self.lawpage)                   """Adds law page to left side of window"""
        
        layout = QVBoxLayout()
        layout.addWidget(hsplitter)
        self.setLayout(layout)
Esempio n. 28
0
class ConfigDialog(QDialog):
    """Spyder configuration ('Preferences') dialog box"""
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply
                                |QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle(_("Preferences"))
        self.setWindowIcon(get_icon("configure.png"))
        
    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()
        
    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)
        
    def get_page(self, index=None):
        """Return page widget"""
        if index is None:
            widget = self.pages_widget.currentWidget()
        else:
            widget = self.pages_widget.widget(index)
        return widget.widget()
        
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.get_page(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)
        
    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.get_page()
            if not configpage.is_valid():
                return
            configpage.apply_changes()
            
    def current_page_changed(self, index):
        widget = self.get_page(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)
        
    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget, SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count():
                     self.contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        scrollarea = QScrollArea(self)
        scrollarea.setWidgetResizable(True)
        scrollarea.setWidget(widget)
        self.pages_widget.addWidget(scrollarea)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))
        
    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))
    
    def resizeEvent(self, event):
        """
        Reimplement Qt method to be able to save the widget's size from the
        main application
        """
        QDialog.resizeEvent(self, event)
        self.emit(SIGNAL("size_change(QSize)"), self.size())
Esempio n. 29
0
    def __init__(self, parent, max_entries=100):
        """ Creates a very basic window with some text """
        """
        RATE_LAW_MESSAGE = \
            "The Plugins for Spyder consists out of three main classes: \n\n" \
            "1. HelloWorld\n\n" \
            "\tThe HelloWorld class inherits all its methods from\n" \
            "\tSpyderPluginMixin and the HelloWorldWidget and performs all\n" \
            "\tthe processing required by the GU. \n\n" \
            "2. HelloWorldConfigPage\n\n" \
            "\tThe HelloWorldConfig class inherits all its methods from\n" \
            "\tPluginConfigPage to create a configuration page that can be\n" \
            "\tfound under Tools -> Preferences\n\n" \
            "3. HelloWorldWidget\n\n" \
            "\tThe HelloWorldWidget class inherits all its methods from\n" \
            "\tQWidget to create the actual plugin GUI interface that \n" \
            "\tdisplays this message on screen\n\n"
        """
        #Testing access editor on plugin initialization
        
        
        RATE_LAW_MESSAGE = ""
        displaynamelist = []
        #displaylist = []
        infixlist = []
        desclist = []
        parameterstringlist = []
        xmldoc = minidom.parse('\\.spyder2\\ratelaw2_0_3.xml')
        #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml')
        
        lawlistxml = xmldoc.getElementsByTagName('law')
        #i is the number of laws currently in the xml file
        i = 0
        for s in lawlistxml:
            #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n"
            RATE_LAW_MESSAGE += s.getAttribute('display') + "\n"
            #displaynamelist[i] = s.getAttribute('displayName')
            #displaylist[i] = s.getAttribute('display')
            displaynamelist.append(s.getAttribute('displayName'))
            #displaylist.append(s.getAttribute('display'))
            infixlist.append(s.getAttribute('infixExpression'))
            desclist.append(s.getAttribute('description'))
            parameterlist = s.getElementsByTagName('listOfParameters')[0]
            #for p in parameterlist    
            parameters = parameterlist.getElementsByTagName('parameter')
            parameterstring = ""
            for param in parameters:
                parametername = param.attributes['name'].value
                parameterdesc = param.attributes['description'].value
                parameterstring = parameterstring + '\t' + parametername + ":" + '\t' + "  " + parameterdesc + "\n"
                #print('\t' + parametername + ":" + '\t' + parameterdesc)
            parameterstringlist.append(parameterstring)    
            i = i + 1
            
        
        QWidget.__init__(self, parent)
        
        self.setWindowTitle("Rate Law Library")
        
        self.output = None
        self.error_output = None
        
        self._last_wdir = None
        self._last_args = None
        self._last_pythonpath = None
        
        self.textlabel = QLabel(RATE_LAW_MESSAGE)        

        self.lawlist = QListWidget()
        self.lawpage = QStackedWidget()
        #Adding displayName items to lawlist
        for j in range(i):
            item = QListWidgetItem(displaynamelist[j])
            self.lawlist.addItem(item)
            self.lawdetailpage = QWidget()
            # Page layout will become its own function
            setup_group = QGroupBox(displaynamelist[j])
            infixmod = infixlist[j].replace("___"," ")
            setup_label = QLabel(infixmod)
            setup_label.setWordWrap(True)
            
            desc_group = QGroupBox("Description")
            desc_label = QLabel(desclist[j])
            desc_label.setWordWrap(True)
            param_label = QLabel(parameterstringlist[j])
            param_label.setWordWrap(True)

        # Warning: do not try to regroup the following QLabel contents with 
        # widgets above -- this string was isolated here in a single QLabel
        # on purpose: to fix Issue 863
            setup_layout = QVBoxLayout()
            setup_layout.addWidget(setup_label)
            setup_group.setLayout(setup_layout)
            
            desc_layout = QVBoxLayout()
            desc_layout.addWidget(desc_label)
            desc_layout.addWidget(param_label)
            desc_group.setLayout(desc_layout)

            vlayout = QVBoxLayout()
            vlayout.addWidget(setup_group)
            vlayout.addWidget(desc_group)
            vlayout.addStretch(1)
            self.lawdetailpage.setLayout(vlayout)
            
            self.lawpage.addWidget(self.lawdetailpage)
        
        #self.connect(self.lawlist, SIGNAL(self.lawlist.currentRowChanged(int)),self.lawpage,SLOT(self.lawpage.setCurrentIndex(int)))
        self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex)            
        '''
        self.lawpage = QWidget()
        '''
        self.lawlist.setCurrentRow(0)
        
        hsplitter = QSplitter()
        hsplitter.addWidget(self.lawlist)
        
        
        
        
        hlayout1 = QHBoxLayout()
        hlayout1.addWidget(self.textlabel)
        hlayout1.addStretch()
        self.lawpage.setLayout(hlayout1)
        
        hsplitter.addWidget(self.lawpage)
        
        layout = QVBoxLayout()
        layout.addWidget(hsplitter)
        self.setLayout(layout)
Esempio n. 30
0
    def setup_and_check(self, data, title='', readonly=False,
                        xlabels=None, ylabels=None):
        """
        Setup ArrayEditor:
        return False if data is not supported, True otherwise
        """
        self.data = data
        is_record_array = data.dtype.names is not None
        is_masked_array = isinstance(data, np.ma.MaskedArray)
        if data.size == 0:
            self.error(_("Array is empty"))
            return False
        if data.ndim > 3:
            self.error(_("Arrays with more than 3 dimensions are not supported"))
            return False
        if xlabels is not None and len(xlabels) != self.data.shape[1]:
            self.error(_("The 'xlabels' argument length do no match array "
                         "column number"))
            return False
        if ylabels is not None and len(ylabels) != self.data.shape[0]:
            self.error(_("The 'ylabels' argument length do no match array row "
                         "number"))
            return False
        if not is_record_array:
            dtn = data.dtype.name
            if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \
               and not dtn.startswith('unicode'):
                arr = _("%s arrays") % data.dtype.name
                self.error(_("%s are currently not supported") % arr)
                return False
        
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setWindowIcon(ima.icon('arredit'))
        if title:
            title = to_text_string(title) + " - " + _("NumPy array")
        else:
            title = _("Array editor")
        if readonly:
            title += ' (' + _('read only') + ')'
        self.setWindowTitle(title)
        self.resize(600, 500)
        
        # Stack widget
        self.stack = QStackedWidget(self)
        if is_record_array:
            for name in data.dtype.names:
                self.stack.addWidget(ArrayEditorWidget(self, data[name],
                                                   readonly, xlabels, ylabels))
        elif is_masked_array:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly,
                                                   xlabels, ylabels))
        elif data.ndim == 3:
            pass
        else:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
        self.arraywidget = self.stack.currentWidget()
        self.stack.currentChanged.connect(self.current_widget_changed)
        self.layout.addWidget(self.stack, 1, 0)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        if is_record_array or is_masked_array or data.ndim == 3:
            if is_record_array:
                btn_layout.addWidget(QLabel(_("Record array fields:")))
                names = []
                for name in data.dtype.names:
                    field = data.dtype.fields[name]
                    text = name
                    if len(field) >= 3:
                        title = field[2]
                        if not is_text_string(title):
                            title = repr(title)
                        text += ' - '+title
                    names.append(text)
            else:
                names = [_('Masked data'), _('Data'), _('Mask')]
            if data.ndim == 3:
                # QSpinBox
                self.index_spin = QSpinBox(self, keyboardTracking=False)
                self.index_spin.valueChanged.connect(self.change_active_widget)
                # QComboBox
                names = [str(i) for i in range(3)]
                ra_combo = QComboBox(self)
                ra_combo.addItems(names)
                ra_combo.currentIndexChanged.connect(self.current_dim_changed)    
                # Adding the widgets to layout
                label = QLabel(_("Axis:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(ra_combo)
                self.shape_label = QLabel()
                btn_layout.addWidget(self.shape_label)
                label = QLabel(_("Index:"))
                btn_layout.addWidget(label)
                btn_layout.addWidget(self.index_spin)
                self.slicing_label = QLabel()
                btn_layout.addWidget(self.slicing_label)
                # set the widget to display when launched
                self.current_dim_changed(self.last_dim)
            else:
                ra_combo = QComboBox(self)
                ra_combo.currentIndexChanged.connect(self.stack.setCurrentIndex)
                ra_combo.addItems(names)
                btn_layout.addWidget(ra_combo)
            if is_masked_array:
                label = QLabel(_("<u>Warning</u>: changes are applied separately"))
                label.setToolTip(_("For performance reasons, changes applied "\
                                   "to masked array won't be reflected in "\
                                   "array's data (and vice-versa)."))
                btn_layout.addWidget(label)
            btn_layout.addStretch()
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        btn_layout.addWidget(bbox)
        self.layout.addLayout(btn_layout, 2, 0)

        self.setMinimumSize(400, 300)
        
        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)
        
        return True
Esempio n. 31
0
class ArrayEditor(QDialog):
    """Array Editor Dialog"""    
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        
        self.data = None
        self.arraywidget = None
        self.stack = None
        self.layout = None
    
    def setup_and_check(self, data, title='', readonly=False,
                        xlabels=None, ylabels=None):
        """
        Setup ArrayEditor:
        return False if data is not supported, True otherwise
        """
        self.data = data
        is_record_array = data.dtype.names is not None
        is_masked_array = isinstance(data, np.ma.MaskedArray)
        if data.size == 0:
            self.error(_("Array is empty"))
            return False
        if data.ndim > 2:
            self.error(_("Arrays with more than 2 dimensions "
                               "are not supported"))
            return False
        if xlabels is not None and len(xlabels) != self.data.shape[1]:
            self.error(_("The 'xlabels' argument length "
						 	   "do no match array column number"))
            return False
        if ylabels is not None and len(ylabels) != self.data.shape[0]:
            self.error(_("The 'ylabels' argument length "
							   "do no match array row number"))
            return False
        if not is_record_array:
            dtn = data.dtype.name
            if dtn not in SUPPORTED_FORMATS and not dtn.startswith('string') \
               and not dtn.startswith('unicode'):
                arr = _("%s arrays") % data.dtype.name
                self.error(_("%s are currently not supported") % arr)
                return False
        
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setWindowIcon(get_icon('arredit.png'))
        if title:
            title = to_text_string(title) # in case title is not a string
        else:
            title = _("Array editor")
        if readonly:
            title += ' (' + _('read only') + ')'
        self.setWindowTitle(title)
        self.resize(600, 500)
        
        # Stack widget
        self.stack = QStackedWidget(self)
        if is_record_array:
            for name in data.dtype.names:
                self.stack.addWidget(ArrayEditorWidget(self, data[name],
                                                   readonly, xlabels, ylabels))
        elif is_masked_array:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly,
                                                   xlabels, ylabels))
            self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly,
                                                   xlabels, ylabels))
        else:
            self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
        self.arraywidget = self.stack.currentWidget()
        self.connect(self.stack, SIGNAL('currentChanged(int)'),
                     self.current_widget_changed)
        self.layout.addWidget(self.stack, 1, 0)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        if is_record_array or is_masked_array:
            if is_record_array:
                btn_layout.addWidget(QLabel(_("Record array fields:")))
                names = []
                for name in data.dtype.names:
                    field = data.dtype.fields[name]
                    text = name
                    if len(field) >= 3:
                        title = field[2]
                        if not is_text_string(title):
                            title = repr(title)
                        text += ' - '+title
                    names.append(text)
            else:
                names = [_('Masked data'), _('Data'), _('Mask')]
            ra_combo = QComboBox(self)
            self.connect(ra_combo, SIGNAL('currentIndexChanged(int)'),
                         self.stack.setCurrentIndex)
            ra_combo.addItems(names)
            btn_layout.addWidget(ra_combo)
            if is_masked_array:
                label = QLabel(_("<u>Warning</u>: changes are applied separately"))
                label.setToolTip(_("For performance reasons, changes applied "\
                                   "to masked array won't be reflected in "\
                                   "array's data (and vice-versa)."))
                btn_layout.addWidget(label)
            btn_layout.addStretch()
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        btn_layout.addWidget(bbox)
        self.layout.addLayout(btn_layout, 2, 0)
        
        self.setMinimumSize(400, 300)
        
        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)
        
        return True
        
    def current_widget_changed(self, index):
        self.arraywidget = self.stack.widget(index)
        
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.stack.count()):
            self.stack.widget(index).accept_changes()
        QDialog.accept(self)
        
    def get_value(self):
        """Return modified array -- this is *not* a copy"""
        # It is import to avoid accessing Qt C++ object as it has probably
        # already been destroyed, due to the Qt.WA_DeleteOnClose attribute
        return self.data

    def error(self, message):
        """An error occured, closing the dialog box"""
        QMessageBox.critical(self, _("Array editor"), message)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.reject()

    def reject(self):
        """Reimplement Qt method"""
        if self.arraywidget is not None:
            for index in range(self.stack.count()):
                self.stack.widget(index).reject_changes()
        QDialog.reject(self)