Пример #1
0
    def init_fields(self, data):
        """Prepare and insert fields in the form."""
        self.fields['name'] = TextField(_("Name"), data.get('name', ''))
        self.addRow(self.fields['name'].label, self.fields['name'].widget)
        # Insert the modules table view with its buttons
        table_buttons = QtGui.QHBoxLayout()
        table_buttons.setContentsMargins(0, 0, 0, 0)
        table_buttons.addWidget(self.button_module_add)
        table_buttons.addWidget(self.button_module_rm)
        self.addRow(table_buttons)
        self.addRow(self.table_modules)
        # Insert a separator
        separator = QtGui.QFrame()
        #separator.setFrameShape(QtGui.QFrame.HLine)
        separator.setFrameStyle(QtGui.QFrame.HLine | QtGui.QFrame.Sunken)
        self.addRow(separator)
        # Insert the models table view with its buttons
        table_buttons = QtGui.QHBoxLayout()
        table_buttons.setContentsMargins(0, 0, 0, 0)
        table_buttons.addWidget(self.button_model_add)
        table_buttons.addWidget(self.button_model_rm)
        self.addRow(table_buttons)
        self.addRow(self.table_models)
        # Restrict models checkbox
        self.fields['restrict'] = BoolField(_("Restrict to models"),
                                            data.get('restrict', False))
        self.addRow(self.fields['restrict'].label,
                    self.fields['restrict'].widget)

        # Insert data in fields and tables
        self.set_data(data)
Пример #2
0
 def init_fields(self, data):
     """Prepare and insert fields in the form."""
     self.fields['name'] = TextField(_("Name"), data.get('name', ''))
     self.addRow(
         self.fields['name'].label, self.fields['name'].widget)
     self.fields['maxdepth'] = IntField(
         _(u"Level"), data.get('maxdepth', 1), range_=(0, 42))
     self.fields['autocompletion'] = BoolField(
         _("Autocompletion"), data.get('autocompletion', True))
     # Insert the table view with its buttons
     table_buttons = QtGui.QHBoxLayout()
     table_buttons.setContentsMargins(0, 0, 0, 0)
     table_buttons.addWidget(self.button_add)
     table_buttons.addWidget(self.button_rm)
     label = QtGui.QLabel(self.fields['maxdepth'].label)
     label.setAlignment(QtCore.Qt.AlignCenter)
     table_buttons.addWidget(label)
     table_buttons.addWidget(self.fields['maxdepth'].widget)
     label = QtGui.QLabel(self.fields['autocompletion'].label)
     label.setAlignment(QtCore.Qt.AlignCenter)
     table_buttons.addWidget(label)
     table_buttons.addWidget(self.fields['autocompletion'].widget)
     self.addRow(table_buttons)
     self.addRow(self.table)
     # Insert data in fields and tables
     self.set_data(data)
Пример #3
0
 def setData(self, index, value, role=QtCore.Qt.EditRole):
     """Overloaded to dynamically update other columns accordingly."""
     if index.column() == 0:
         value = value.strip().lower()
         if ' ' in value:
             raise ValueError(
                 _(u"Space characters are not allowed."))
     res = super(RelationTableModel, self).setData(index, value, role)
     if res:
         index_root_ok = self.index(index.row(), 1)
         index_show_ok = self.index(index.row(), 2)
         index_attr_ok = self.index(index.row(), 3)
         # 'name' contains the joker character => 'root_ok' = False
         if index.column() == 0 and '*' in value:
             self.setData(index_root_ok, False)
             self.dataChanged.emit(index_root_ok, index_root_ok)
         # 'root_ok' == True => 'show_ok' = True
         if index.column() == 1:
             if value:
                 self.setData(index_show_ok, True)
             self.dataChanged.emit(index_show_ok, index_show_ok)
         # 'show_ok' updated => update 'attr_ok'
         if index.column() == 2:
             self.dataChanged.emit(index_attr_ok, index_attr_ok)
     return res
Пример #4
0
 def __init__(self, app):
     UI.__init__(self, app)
     QtGui.QToolBar.__init__(self)
     self.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
     self.action_functions = QtGui.QAction(Icons['function'],
                                           _("Functions"), self)
     self.action_functions.setDisabled(True)
     # Add actions to the toolbar
     self.addAction(Action['new_group'])
     self.addAction(Action['new_server'])
     self.addAction(self.action_functions)
     separator = QtGui.QWidget()
     separator.setSizePolicy(QtGui.QSizePolicy.Expanding,
                             QtGui.QSizePolicy.Expanding)
     self.addWidget(separator)
     #self.addAction(self._actions['settings'])
     self.addAction(Action['about'])
     self.addAction(Action['quit'])
     # Add a submenu on the 'functions' tool button
     fmenu = QtGui.QMenu()
     fmenu.addAction(Action['new_relation'])
     fmenu.addAction(Action['new_dependency'])
     self.action_functions.setMenu(fmenu)
     for widget in self.action_functions.associatedWidgets():
         if isinstance(widget, QtGui.QToolButton):
             widget.setPopupMode(QtGui.QToolButton.InstantPopup)
Пример #5
0
 def setData(self, index, value, role=QtCore.Qt.EditRole):
     """Overloaded to dynamically update other columns accordingly."""
     if index.column() == 0:
         value = value.strip().lower()
         if ' ' in value:
             raise ValueError(_(u"Space characters are not allowed."))
     return super(DependencyModelTableModel,
                  self).setData(index, value, role)
Пример #6
0
 def _function_deleted(self, model, id_):
     """Update title of the corresponding tab when a function is deleted."""
     if id_ in self.tabs:
         content = self.tabs.pop(id_)
         self.tabs_tmp[id_] = content
         sdata = Controller['server'].read(content.server_id)
         title = "%s - %s" % (sdata['name'], _(u"New"))
         index = self.indexOf(content)
         self.setTabText(index, title)
Пример #7
0
 def delete_confirm(self, id_):
     """Display a confirmation dialog to the user before delete."""
     data = self.read(id_)
     response = confirm(
         UI['main_window'],
         _(u"Are you sure you want to delete the server "
           u"<strong>%s</strong>?") % (data['name']))
     if response:
         self.delete(id_)
Пример #8
0
 def confirm_quit(self):
     """Return `True` if the application can be closed.
     If there is unsaved work, ask the user to confirm its action.
     """
     # Check unsaved work.
     confirm = True
     for content in UI['workbook'].tabs.itervalues():
         if content.unsaved:
             confirm = False
     for content in UI['workbook'].tabs_tmp.itervalues():
         if content.unsaved:
             confirm = False
     # Ask the user to confirm if unsaved work has been detected
     if not confirm:
         confirm = dialog.confirm(
             UI['main_window'],
             _(u"Unsaved work detected. Quit anyway?"),
             _(u"Unsaved work"))
     return confirm
Пример #9
0
 def close_tab(self, index):
     """Close a tab at the given `index`."""
     widget = self.widget(index)
     close = True
     if widget.unsaved:
         close = dialog.confirm(
             self, _(u"This function has been modified. Close anyway?"),
             _(u"Modified function"))
     if close:
         self.removeTab(index)
         widget.deleteLater()
         for id_, tab_content in self.tabs.iteritems():
             if tab_content == widget:
                 del self.tabs[id_]
                 break
         for id_, tab_content in self.tabs_tmp.iteritems():
             if tab_content == widget:
                 del self.tabs_tmp[id_]
                 break
Пример #10
0
def confirm(parent, message, title=None):
    """Display a confirmation dialog (Yes/No response) and returns the
    boolean response.
    """
    if title is None:
        title = _(u"Confirmation")
    response = QtGui.QMessageBox.question(
        parent, title, message,
        QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No)
    return response == QtGui.QMessageBox.Yes
Пример #11
0
class About(Action):
    """Action to display the 'about' dialog."""
    __metadata__ = {
        'name': 'about',
        'icon': 'about',
        'string': _(u"About"),
    }

    def run(self):
        """Display the 'about' dialog."""
        about.display()
Пример #12
0
class NewGroup(Action):
    """Action to add a new group."""
    __metadata__ = {
        'name': 'new_group',
        'icon': 'group',
        'string': _(u"New group"),
        'shortcut': 'Ctrl+G',
    }

    def run(self):
        """Display the form to add a new group."""
        Controller['group'].display_form()
Пример #13
0
class Quit(Action):
    """Action to quit the application."""
    __metadata__ = {
        'name': 'quit',
        'icon': 'quit',
        'string': _(u"Quit"),
        'shortcut': QtGui.QKeySequence.Quit,
    }

    def run(self):
        """Ask the user to confirm, and quit the application."""
        self.app.confirm_quit() and self.app.quit()
Пример #14
0
 def __init__(self, workarea, id_=None):
     # Table view
     self.table = QtGui.QTableView()
     self.table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
     self.table.setItemDelegateForColumn(1, CheckBoxDelegate(self.table))
     self.table.setItemDelegateForColumn(2, CheckBoxDelegate(self.table))
     self.table.setItemDelegateForColumn(3, CheckBoxDelegate(self.table))
     #self.table.setSizePolicy(
     #    QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
     self.table.verticalHeader().hide()
     #self.table.setSortingEnabled(True)
     #self.table.setSelectionMode(QtGui.QTableWidget.NoSelection)
     self.table.setMinimumHeight(300)
     # Table data model
     table_model = RelationTableModel(
         self.table,
         header=[_(u"Model"), _(u"Base"), _(u"Show"), _(u"Attr.")],
         default=[u"", False, True, True])
     self.table.setModel(table_model)
     # Buttons to add add/remove rows
     self.button_add = QtGui.QPushButton(
         Icons['add'], _(u"Add"))
     self.button_add.clicked.connect(self._button_add_clicked)
     self.button_rm = QtGui.QPushButton(
         Icons['remove'], _(u"Remove"))
     self.button_rm.clicked.connect(self._button_rm_clicked)
     self.button_rm.setEnabled(False)
     # Super first
     super(RelationFormLayout, self).__init__(workarea, id_)
     # Then connect to signals
     table_model.dataChanged.connect(lambda item: self.data_changed.emit())
     table_model.dataChanged.connect(self._function_unsaved)
     table_model.modelReset.connect(self._update_buttons)
     selection_model = self.table.selectionModel()
     selection_model.selectionChanged.connect(self._update_buttons)
Пример #15
0
class RemoveGroup(Action):
    """Action to remove a group."""
    __metadata__ = {
        'name': 'remove_group',
        'icon': 'remove',
        'string': _(u"Remove"),
    }

    def run(self):
        """Remove the group."""
        id_ = UI['tree'].current.get('group')
        if id_:
            Controller['group'].delete_confirm(id_)
Пример #16
0
class RemoveDependency(Action):
    """Action to remove a dependencies graph."""
    __metadata__ = {
        'name': 'remove_dependency',
        'icon': 'remove',
        'string': _(u"Remove"),
    }

    def run(self):
        """Display the form to edit a dependencies graph."""
        id_ = UI['tree'].current.get('dependency')
        if id_:
            Controller['dependency'].delete_confirm(id_)
Пример #17
0
class RemoveServer(Action):
    """Action to remove a server."""
    __metadata__ = {
        'name': 'remove_server',
        'icon': 'remove',
        'string': _(u"Remove"),
    }

    def run(self):
        """Remove the server."""
        id_ = UI['tree'].current.get('server')
        if id_:
            Controller['server'].delete_confirm(id_)
Пример #18
0
class RemoveRelation(Action):
    """Action to remove a relation graph."""
    __metadata__ = {
        'name': 'remove_relation',
        'icon': 'remove',
        'string': _(u"Remove"),
    }

    def run(self):
        """Display the form to edit a relational graph."""
        id_ = UI['tree'].current.get('relation')
        if id_:
            Controller['relation'].delete_confirm(id_)
Пример #19
0
class EditGroup(Action):
    """Action to edit a group."""
    __metadata__ = {
        'name': 'edit_group',
        'icon': 'edit',
        'string': _(u"Modify"),
    }

    def run(self):
        """Display the form to edit a group."""
        id_ = UI['tree'].current.get('group')
        if id_:
            Controller['group'].display_form(id_)
Пример #20
0
class EditRelation(Action):
    """Action to edit a relation graph."""
    __metadata__ = {
        'name': 'edit_relation',
        'icon': 'edit',
        'string': _(u"Modify"),
    }

    def run(self):
        """Display the form to edit a relational graph."""
        id_ = UI['tree'].current.get('relation')
        if id_:
            Controller['relation'].display_form(id_)
Пример #21
0
class EditDependency(Action):
    """Action to edit a dependencies graph."""
    __metadata__ = {
        'name': 'edit_dependency',
        'icon': 'edit',
        'string': _(u"Modify"),
    }

    def run(self):
        """Display the form to edit a dependencies graph."""
        id_ = UI['tree'].current.get('dependency')
        if id_:
            Controller['dependency'].display_form(id_)
Пример #22
0
class EditServer(Action):
    """Action to edit a server."""
    __metadata__ = {
        'name': 'edit_server',
        'icon': 'edit',
        'string': _(u"Modify"),
    }

    def run(self):
        """Display the form to edit a server."""
        id_ = UI['tree'].current.get('server')
        if id_:
            Controller['server'].display_form(id_)
Пример #23
0
 def __init__(self, workarea, id_=None):
     QtGui.QFormLayout.__init__(self)
     self.workarea = workarea
     ctl = self.workarea.ctl
     data = id_ and ctl.read(id_) \
         or ctl.default_get({'server_id': workarea.server_id})
     # Fields
     self.fields = {}
     self.init_fields(data)
     # Buttons
     self.button_save = QtGui.QPushButton(Icons['save'], _(u"Save"))
     self.button_save.clicked.connect(self.workarea.save)
     self.button_save.setEnabled(self.workarea.unsaved)
     self.button_restore = QtGui.QPushButton(Icons['undo'], _(u"Undo"))
     self.button_restore.clicked.connect(self.workarea.restore)
     self.button_restore.setEnabled(False)
     self.button_close = QtGui.QPushButton(Icons['ok'], _(u"Close"))
     self.button_close.clicked.connect(
         lambda: self.workarea.show_panel(False))
     self.button_execute = QtGui.QPushButton(Icons['exe'], _(u"Execute"))
     self.button_execute.clicked.connect(self.workarea.execute)
     self.buttons_box = QtGui.QHBoxLayout()
     self.buttons_box.addWidget(self.button_save)
     self.buttons_box.addWidget(self.button_restore)
     self.buttons_box.addWidget(self.button_close)
     self.buttons_box.addWidget(self.button_execute)
     self.addRow(self.buttons_box)
     # Default focus
     self.fields['name'].widget.setFocus()
     # Connect signals
     for field in self.fields.itervalues():
         field.changed.connect(self.data_changed.emit)
         field.changed.connect(self._function_unsaved)
     ctl.created.connect(self._function_saved)
     ctl.updated.connect(self._function_saved)
     ctl.deleted.connect(self._function_unsaved)
     self.data_restored.connect(self._function_restored)
Пример #24
0
 def new_function(self, model, server_id):
     """Add a new workarea which can be saved later."""
     sdata = Controller['server'].read(server_id)
     title = u"%s - %s" % (sdata['name'], _(u"New"))
     id_tmp = uuid.uuid4().hex
     self.tabs_tmp[id_tmp] = WorkArea[model](self.app,
                                             server_id,
                                             id_tmp,
                                             new=True)
     self.addTab(self.tabs_tmp[id_tmp], Icons[model], title)
     self.tabs_tmp[id_tmp].created.connect(self._function_created)
     self.tabs_tmp[id_tmp].data_changed.connect(self._function_unsaved)
     self.tabs_tmp[id_tmp].data_restored.connect(self._function_restored)
     self.tabs_tmp[id_tmp].show_panel()
     self.setCurrentWidget(self.tabs_tmp[id_tmp])
Пример #25
0
 def __init__(self, app, server_id, parent):
     TreeItem.__init__(self, app)
     parent.addChild(self)
     self.server_id = server_id
     self.setText(0, _("Relations"))
     self.setIcon(0, Icons['group'])
     sdata = Controller['server'].read(self.server_id)
     relations = sdata.get('relations', {})
     for rid in sorted(relations, key=lambda rid: relations[rid]['name']):
         self._add('relation', rid, select=False)
     # Set the visual state
     if self.childCount():
         self.setExpanded(True)
         self.set_icon_expanded(True)
     else:
         self.setHidden(True)
Пример #26
0
 def __init__(self, app, server_id, parent):
     TreeItem.__init__(self, app)
     parent.addChild(self)
     self.server_id = server_id
     self.setText(0, _("Dependencies"))
     self.setIcon(0, Icons['group'])
     sdata = Controller['server'].read(self.server_id)
     dependencies = sdata.get('dependencies', {})
     for did in sorted(dependencies,
                       key=lambda did: dependencies[did]['name']):
         self._add('dependency', did, select=False)
     # Set the visual state
     if self.childCount():
         self.setExpanded(True)
         self.set_icon_expanded(True)
     else:
         self.setHidden(True)
Пример #27
0
class NewServer(Action):
    """Action to add a new server."""
    __metadata__ = {
        'name': 'new_server',
        'icon': 'server',
        'string': _(u"New server"),
        'shortcut': 'Ctrl+H',
    }

    def run(self):
        """Display the form to add a new server."""
        Controller['server'].display_form()

    def __connect__(self):
        UI['tree'].currentItemChanged.connect(self._tree_item_changed)

    def _tree_item_changed(self, current, previous):
        """Enable/disable the action according to the current item selected
        in the main tree.
        """
        self.setDisabled(not current)
Пример #28
0
 def __init__(self, app, id_=None, data=None):
     QtGui.QDialog.__init__(self)
     self.app = app
     self.id_ = id_
     self.data = data
     self.fields = {}
     self.setLayout(QtGui.QFormLayout())
     # Fields
     self.fields['name'] = TextField(_("Name"), data.get('name', ''))
     self.layout().addRow(
         self.fields['name'].label, self.fields['name'].widget)
     # Buttons
     buttons = QtGui.QDialogButtonBox(
         QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel,
         parent=self)
     self.layout().addWidget(buttons)
     # Default focus
     self.fields['name'].widget.setFocus()
     # Responses
     buttons.accepted.connect(self.accept)
     buttons.rejected.connect(self.reject)
Пример #29
0
 def export(self):
     """Export the graph (image) in a format among (some of) those
     supported by Graphviz.
     """
     formats = [
         # images
         (u"%s (*.bmp)" % _(u"Image Windows BMP"), [u'.bmp']),
         (u"%s (*.jpg *.jpeg *.jpe)" % _(u"Image JPEG"), [
             u'.jpg', u'.jpeg', u'jpe']),
         (u"%s (*.gif)" % _(u"Image GIF"), [u'.gif']),
         (u"%s (*.png)" % _(u"Image PNG"), [u'.png']),
         # other
         (u"%s (*.dot)" % (u"DOT"), [u'.dot']),
         (u"%s (*.pdf)" % (u"PDF"), [u'.pdf']),
         (u"%s (*.ps)" % (u"PostScript"), [u'.ps']),
         (u"%s (*.eps)" % (u"Encapsulated PostScript"), [u'.eps']),
         (u"%s (*.svg)" % (u"SVG"), [u'.svg']),
         (u"%s (*.svgz)" % (u"SVGz"), [u'.svgz']),
     ]
     default_format = u"%s (*.png)" % _(u"Image PNG")
     if self.graph:
         data = self.panel.get_data()
         name = data.get('name', u"%s" % self._model).replace('.', '_')
         path, format_ = QtGui.QFileDialog.getSaveFileName(
             self, _(u"Export"), name,
             u';;'.join([fmt[0] for fmt in formats]), default_format)
         if path:
             # Detect the extension from the file name without taking into
             # account the selected extension in the list
             path_ext = None
             for fmt in formats:
                 exts = fmt[1]
                 for ext in exts:
                     if path.endswith(ext):
                         path_ext = ext
                         break
                 if path_ext:
                     break
             # If no extension was typed in the file name, we take the
             # selected one in the list
             if not path_ext:
                 for fmt in formats:
                     if fmt[0] == format_:
                         path_ext = fmt[1][0]
                         path += path_ext
                         break
             # Save the graph (pydot/Graphviz manages that for us)
             self.graph.write(path, format=path_ext[1:])
Пример #30
0
class NewRelation(Action):
    """Action to add a new relation graph."""
    __metadata__ = {
        'name': 'new_relation',
        'icon': 'relation',
        'string': _(u"Add relational graph"),
        'shortcut': 'Ctrl+R',
        'server_menu': True,
    }

    def __connect__(self):
        UI['tree'].itemActivated.connect(self._update_state)

    def _update_state(self, item):
        if UI['tree'].current.get('server'):
            self.setDisabled(False)
        else:
            self.setDisabled(True)

    def run(self):
        """Display the form to add a relational graph."""
        if UI['tree'].current.get('server'):
            Controller['relation'].display_form()