Beispiel #1
0
class CaseList(QWidget):

    def __init__(self):
        QWidget.__init__(self)

        addHelpToWidget(self, "init/case_list")

        layout = QVBoxLayout()

        self._list = QListWidget(self)
        self._list.setMinimumHeight(100)
        self._list.setMaximumHeight(250)
        self._default_selection_mode = self._list.selectionMode()
        self.setSelectable(False)

        layout.addWidget(QLabel("Available Cases:"))
        layout.addWidget(self._list)

        self._addRemoveWidget = AddRemoveWidget(self.addItem, self.removeItem, horizontal=True)
        self._addRemoveWidget.enableRemoveButton(False)
        layout.addWidget(self._addRemoveWidget)

        self._title = "New keyword"
        self._description = "Enter name of keyword:"

        self.setLayout(layout)

        ERT.ertChanged.connect(self.updateList)
        self.updateList()

    def setSelectable(self, selectable):
        if selectable:
            self._list.setSelectionMode(self._default_selection_mode)
        else:
            self._list.setSelectionMode(QAbstractItemView.NoSelection)


    def addItem(self):
        dialog = ValidatedDialog("New case", "Enter name of new case:", getAllCases())
        new_case_name = dialog.showAndTell()
        if not new_case_name == "":
            selectOrCreateNewCase(new_case_name)

    def removeItem(self):
        message = "Support for removal of items has not been implemented!"
        QMessageBox.information(self, "Not implemented!", message)


    def updateList(self):
        """Retrieves data from the model and inserts it into the list"""
        case_list = getAllCases()

        self._list.clear()

        for case in case_list:
            self._list.addItem(case)
Beispiel #2
0
    def createListOption(self):
        def addItem(label, icon_pixmap, width, height):
            item = QListWidgetItem(list_option)
            item.setText(label)
            item.setTextAlignment(Qt.AlignHCenter)
            item.setIcon(QIcon(icon_pixmap))
            item.setSizeHint(QSize(width, height))

        list_option = QListWidget()
        list_option.setAutoFillBackground(True)
        list_option.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        list_option.setTextElideMode(Qt.ElideNone)
        list_option.setMovement(QListView.Static)
        list_option.setFlow(QListView.TopToBottom)
        list_option.setProperty("isWrapping", QVariant(False))
        list_option.setSpacing(3)
        list_option.setViewMode(QListView.IconMode)

        items = []
        items.append((QApplication.translate("option", "Connections"), "connections.png"))
        items.append((QApplication.translate("option", "Accounts"), "accounts.png"))
        items.append((QApplication.translate("option", "Aliases"), "aliases.png"))
        items.append((QApplication.translate("option", "Macros"), "macros.png"))
        items.append((QApplication.translate("option", "Keypad"), "keypad.png"))
        items.append((QApplication.translate("option", "Triggers"), "triggers.png"))
        items.append((QApplication.translate("option", "Preferences"), "preferences.png"))

        max_width = 0
        for label, icon_name in items:
            w = list_option.fontMetrics().boundingRect(label).width()
            if w > max_width:
                max_width = w

        # An empiric method to align element in the center of the QListWidget
        max_width += 15
        total_height = 0

        for label, icon_name in items:
            icon_pixmap = QPixmap(":/images/" + icon_name)
            height = icon_pixmap.height() + list_option.fontMetrics().height() + 3
            total_height += height + 5
            addItem(label, icon_pixmap, max_width, height)

        list_option.setUniformItemSizes(True)
        list_option.setFixedWidth(max_width + 10)
        list_option.setMinimumHeight(total_height)
        return list_option
Beispiel #3
0
class CodeCompletionWidget(QFrame):

    def __init__(self, editor):
        super(CodeCompletionWidget, self).__init__(
            None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self._revision = 0
        self._block = 0
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {'a': resources.IMAGES['attribute'],
            'f': resources.IMAGES['function'],
            'c': resources.IMAGES['class'],
            'm': resources.IMAGES['module']}

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = u''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        self.desktop = QApplication.instance().desktop()

        self.connect(self.completion_list,
            SIGNAL("itemClicked(QListWidgetItem*)"),
            self.pre_key_insert_completion)
        self.connect(self._editor.document(),
            SIGNAL("cursorPositionChanged(QTextCursor)"),
            self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(
                self.completion_list.count() - move)
        return True

    def update_metadata(self, cursor):
        if settings.CODE_COMPLETION:
            if self._editor.document().revision() != self._revision and \
               cursor.block().blockNumber() != self._block:
                source = self._editor.get_text()
                source = source.encode(self._editor.encoding)
                self.cc.analyze_file(self._editor.ID, source)
                self._revision = self._editor.document().revision()
                self._block = cursor.block().blockNumber()

    def insert_completion(self, insert, type_=ord('a')):
        if insert != self._prefix:
            closing = ''
            if type_ in (ord('f'), ord('c')):
                closing = '()'
            extra = len(self._prefix) - len(insert)
            insertion = '%s%s' % (insert[extra:], closing)
            self._editor.textCursor().insertText(insertion)
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        desktop_geometry = self.desktop.availableGeometry(self._editor)
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) +
            self.completion_list.verticalScrollBar().sizeHint().width() + 10)
        height = 200
        orientation = (point.y() + height) < desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(
                QIcon(self._icons.get(p[0], resources.IMAGES['attribute'])),
                p[1], type=ord(p[0])))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item)
            for item in self._completion_results.get('modules', [])
            if item.startswith(prefix)]
        proposals += [('c', item)
            for item in self._completion_results.get('classes', [])
            if item.startswith(prefix)]
        proposals += [('a', item)
            for item in self._completion_results.get('attributes', [])
            if item.startswith(prefix)]
        proposals += [('f', item)
            for item in self._completion_results.get('functions', [])
            if item.startswith(prefix)]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def _invalid_completion_position(self):
        result = False
        cursor = self._editor.textCursor()
        cursor.movePosition(QTextCursor.StartOfLine,
            QTextCursor.KeepAnchor)
        selection = unicode(cursor.selectedText())[:-1].split(' ')
        if len(selection) == 0 or selection[-1] == '' or \
           selection[-1].isdigit():
            result = True
        return result

    def fill_completer(self, force_completion=False):
        if not force_completion and (self._editor.cursor_inside_string() or
           self._editor.cursor_inside_comment() or
           self._invalid_completion_position()):
            return
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        if force_completion:
            cursor = self._editor.textCursor()
            cursor.movePosition(QTextCursor.StartOfWord,
                QTextCursor.KeepAnchor)
            prefix = cursor.selectedText()
        else:
            prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        type_ = ord('a')
        current = self.completion_list.currentItem()
        insert = unicode(current.text())
        if not insert.endswith(')'):
            type_ = current.type()
        self.insert_completion(insert, type_)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        force_completion = (event.key() == Qt.Key_Space and
                            event.modifiers() == Qt.ControlModifier)
        if event.key() == Qt.Key_Period or force_completion:
            self.fill_completer(force_completion)
Beispiel #4
0
class CodeCompletionWidget(QFrame):
    def __init__(self, editor):
        super(CodeCompletionWidget,
              self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self._revision = 0
        self._block = 0
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {
            'a': resources.IMAGES['attribute'],
            'f': resources.IMAGES['function'],
            'c': resources.IMAGES['class'],
            'm': resources.IMAGES['module']
        }

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = ''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        self.desktop = QApplication.instance().desktop()

        self.connect(self.completion_list,
                     SIGNAL("itemClicked(QListWidgetItem*)"),
                     self.pre_key_insert_completion)
        self.connect(self._editor.document(),
                     SIGNAL("cursorPositionChanged(QTextCursor)"),
                     self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(self.completion_list.count() -
                                               move)
        return True

    def update_metadata(self, cursor):
        if settings.CODE_COMPLETION:
            if self._editor.document().revision() != self._revision and \
               cursor.block().blockNumber() != self._block:
                source = self._editor.get_text()
                source = source.encode(self._editor.encoding)
                self.cc.analyze_file(self._editor.ID, source,
                                     self._editor.indent, self._editor.useTabs)
                self._revision = self._editor.document().revision()
                self._block = cursor.block().blockNumber()

    def insert_completion(self, insert, type_=ord('a')):
        if insert != self._prefix:
            closing = ''
            if type_ in (ord('f'), ord('c')):
                closing = '()'
            extra = len(self._prefix) - len(insert)
            insertion = '%s%s' % (insert[extra:], closing)
            self._editor.textCursor().insertText(insertion)
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        desktop_geometry = self.desktop.availableGeometry(self._editor)
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) +
                 self.completion_list.verticalScrollBar().sizeHint().width() +
                 10)
        height = 200
        orientation = (point.y() + height) < desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(QIcon(
                    self._icons.get(p[0], resources.IMAGES['attribute'])),
                                p[1],
                                type=ord(p[0])))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item)
                      for item in self._completion_results.get('modules', [])
                      if item.startswith(prefix)]
        proposals += [('c', item)
                      for item in self._completion_results.get('classes', [])
                      if item.startswith(prefix)]
        proposals += [
            ('a', item)
            for item in self._completion_results.get('attributes', [])
            if item.startswith(prefix)
        ]
        proposals += [
            ('f', item)
            for item in self._completion_results.get('functions', [])
            if item.startswith(prefix)
        ]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def _invalid_completion_position(self):
        result = False
        cursor = self._editor.textCursor()
        cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor)
        selection = cursor.selectedText()[:-1].split(' ')
        if len(selection) == 0 or selection[-1] == '' or \
           selection[-1].isdigit():
            result = True
        return result

    def fill_completer(self, force_completion=False):
        if not force_completion and (self._editor.cursor_inside_string()
                                     or self._editor.cursor_inside_comment()
                                     or self._invalid_completion_position()):
            return
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        if force_completion:
            cursor = self._editor.textCursor()
            cursor.movePosition(QTextCursor.StartOfWord,
                                QTextCursor.KeepAnchor)
            prefix = cursor.selectedText()
        else:
            prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        type_ = ord('a')
        current = self.completion_list.currentItem()
        insert = current.text()
        if not insert.endswith(')'):
            type_ = current.type()
        self.insert_completion(insert, type_)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        force_completion = (event.key() == Qt.Key_Space
                            and event.modifiers() == Qt.ControlModifier)
        if event.key() == Qt.Key_Period or force_completion:
            self.fill_completer(force_completion)
Beispiel #5
0
class PopupCompleter(QFrame):
    def __init__(self):
        QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.listWidget = QListWidget()
        self.listWidget.setMinimumHeight(350)
        vbox.addWidget(self.listWidget)

        self.listWidget.currentItemChanged.connect(self._repaint_items)

    def _repaint_items(self, current, previous):
        if current is not None:
            widget = self.listWidget.itemWidget(current)
            if widget is not None:
                widget.set_selected()
        if previous is not None:
            widget = self.listWidget.itemWidget(previous)
            if widget is not None:
                widget.set_not_selected()

    def reload(self, model):
        """Reload the data of the Popup Completer, and restart the state."""
        self.listWidget.clear()
        self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        self.listWidget.setCurrentRow(8)

    def clear(self):
        """Remove all the items of the list (deleted), and reload the help."""
        self.listWidget.clear()

    def refresh(self, model, has_text=True):
        """Refresh the list when the user search for some word."""
        self.listWidget.clear()
        if not has_text:
            self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        if model:
            self.listWidget.setCurrentItem(model[0][0])
        else:
            self.add_no_found()

    def fetch_more(self, model):
        """Add more items to the list on user scroll."""
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])

    def add_no_found(self):
        """Load no results found message"""
        noFoundItem = self._create_help_item(resources.IMAGES['delete'],
                                             translations.TR_NO_RESULTS)
        self.listWidget.addItem(noFoundItem)

    def add_help(self):
        #Load help
        fileItem = self._create_help_item(resources.IMAGES['locate-file'],
                                          translations.TR_ONLY_FILES)
        self.listWidget.addItem(fileItem)
        classItem = self._create_help_item(resources.IMAGES['locate-class'],
                                           translations.TR_ONLY_CLASSES)
        self.listWidget.addItem(classItem)
        methodItem = self._create_help_item(
            resources.IMAGES['locate-function'], translations.TR_ONLY_METHODS)
        self.listWidget.addItem(methodItem)
        attributeItem = self._create_help_item(
            resources.IMAGES['locate-attributes'],
            translations.TR_ONLY_ATRIBUTES)
        self.listWidget.addItem(attributeItem)
        thisFileItem = self._create_help_item(
            resources.IMAGES['locate-on-this-file'],
            translations.TR_ONLY_CLASSES_METHODS)
        self.listWidget.addItem(thisFileItem)
        tabsItem = self._create_help_item(resources.IMAGES['locate-tab'],
                                          translations.TR_ONLY_CURRENT_TABS)
        self.listWidget.addItem(tabsItem)
        lineItem = self._create_help_item(resources.IMAGES['locate-line'],
                                          translations.TR_GO_TO_LINE)
        self.listWidget.addItem(lineItem)
        nonPythonItem = self._create_help_item(
            resources.IMAGES['locate-nonpython'],
            translations.TR_ONLY_NON_PYTHON)
        self.listWidget.addItem(nonPythonItem)

    def _create_help_item(self, image, text):
        Item = QListWidgetItem(QIcon(image), text)
        font = Item.font()
        font.setBold(True)
        Item.setSizeHint(QSize(20, 30))
        Item.setBackground(QBrush(Qt.lightGray))
        Item.setForeground(QBrush(Qt.black))
        Item.setFont(font)
        return Item
Beispiel #6
0
class PopupCompleter(QFrame):
    def __init__(self):
        QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.listWidget = QListWidget()
        self.listWidget.setMinimumHeight(300)
        vbox.addWidget(self.listWidget)

    def reload(self, model):
        """Reload the data of the Popup Completer, and restart the state."""
        self.listWidget.clear()
        self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        self.listWidget.setCurrentRow(6)

    def clear(self):
        """Remove all the items of the list (deleted), and reload the help."""
        self.listWidget.clear()

    def refresh(self, model):
        """Refresh the list when the user search for some word."""
        self.listWidget.clear()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        if model:
            self.listWidget.setCurrentItem(model[0][0])

    def fetch_more(self, model):
        """Add more items to the list on user scroll."""
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])

    def add_help(self):
        #Load help
        fileItem = QListWidgetItem(QIcon(resources.IMAGES['locate-file']),
                                   '@\t(Filter only by Files)')
        font = fileItem.font()
        font.setBold(True)
        fileItem.setSizeHint(QSize(20, 30))
        fileItem.setBackground(QBrush(Qt.lightGray))
        fileItem.setForeground(QBrush(Qt.black))
        fileItem.setFont(font)
        self.listWidget.addItem(fileItem)
        classItem = QListWidgetItem(QIcon(resources.IMAGES['locate-class']),
                                    '<\t(Filter only by Classes)')
        self.listWidget.addItem(classItem)
        classItem.setSizeHint(QSize(20, 30))
        classItem.setBackground(QBrush(Qt.lightGray))
        classItem.setForeground(QBrush(Qt.black))
        classItem.setFont(font)
        methodItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-function']),
            '>\t(Filter only by Methods)')
        self.listWidget.addItem(methodItem)
        methodItem.setSizeHint(QSize(20, 30))
        methodItem.setBackground(QBrush(Qt.lightGray))
        methodItem.setForeground(QBrush(Qt.black))
        methodItem.setFont(font)
        attributeItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-attributes']),
            '-\t(Filter only by Attributes)')
        self.listWidget.addItem(attributeItem)
        attributeItem.setSizeHint(QSize(20, 30))
        attributeItem.setBackground(QBrush(Qt.lightGray))
        attributeItem.setForeground(QBrush(Qt.black))
        attributeItem.setFont(font)
        thisFileItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-on-this-file']),
            '.\t(Filter only by Classes and Methods in this File)')
        font = thisFileItem.font()
        font.setBold(True)
        thisFileItem.setSizeHint(QSize(20, 30))
        thisFileItem.setBackground(QBrush(Qt.lightGray))
        thisFileItem.setForeground(QBrush(Qt.black))
        thisFileItem.setFont(font)
        self.listWidget.addItem(thisFileItem)
        nonPythonItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-nonpython']),
            '!\t(Filter only by Non Python Files)')
        self.listWidget.addItem(nonPythonItem)
        nonPythonItem.setSizeHint(QSize(20, 30))
        nonPythonItem.setBackground(QBrush(Qt.lightGray))
        nonPythonItem.setForeground(QBrush(Qt.black))
        nonPythonItem.setFont(font)
Beispiel #7
0
class PopupCompleter(QFrame):

    def __init__(self):
        QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.listWidget = QListWidget()
        self.listWidget.setMinimumHeight(300)
        vbox.addWidget(self.listWidget)

    def reload(self, model):
        """Reload the data of the Popup Completer, and restart the state."""
        self.listWidget.clear()
        self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        self.listWidget.setCurrentRow(6)

    def clear(self):
        """Remove all the items of the list (deleted), and reload the help."""
        self.listWidget.clear()

    def refresh(self, model):
        """Refresh the list when the user search for some word."""
        self.listWidget.clear()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        if model:
            self.listWidget.setCurrentItem(model[0][0])

    def fetch_more(self, model):
        """Add more items to the list on user scroll."""
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])

    def add_help(self):
        #Load help
        fileItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-file']),
                '@\t(Filter only by Files)')
        font = fileItem.font()
        font.setBold(True)
        fileItem.setSizeHint(QSize(20, 30))
        fileItem.setBackground(QBrush(Qt.lightGray))
        fileItem.setForeground(QBrush(Qt.black))
        fileItem.setFont(font)
        self.listWidget.addItem(fileItem)
        classItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-class']),
                '<\t(Filter only by Classes)')
        self.listWidget.addItem(classItem)
        classItem.setSizeHint(QSize(20, 30))
        classItem.setBackground(QBrush(Qt.lightGray))
        classItem.setForeground(QBrush(Qt.black))
        classItem.setFont(font)
        methodItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-function']),
                '>\t(Filter only by Methods)')
        self.listWidget.addItem(methodItem)
        methodItem.setSizeHint(QSize(20, 30))
        methodItem.setBackground(QBrush(Qt.lightGray))
        methodItem.setForeground(QBrush(Qt.black))
        methodItem.setFont(font)
        attributeItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-attributes']),
                '-\t(Filter only by Attributes)')
        self.listWidget.addItem(attributeItem)
        attributeItem.setSizeHint(QSize(20, 30))
        attributeItem.setBackground(QBrush(Qt.lightGray))
        attributeItem.setForeground(QBrush(Qt.black))
        attributeItem.setFont(font)
        thisFileItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-on-this-file']),
                '.\t(Filter only by Classes and Methods in this File)')
        font = thisFileItem.font()
        font.setBold(True)
        thisFileItem.setSizeHint(QSize(20, 30))
        thisFileItem.setBackground(QBrush(Qt.lightGray))
        thisFileItem.setForeground(QBrush(Qt.black))
        thisFileItem.setFont(font)
        self.listWidget.addItem(thisFileItem)
        nonPythonItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-nonpython']),
                '!\t(Filter only by Non Python Files)')
        self.listWidget.addItem(nonPythonItem)
        nonPythonItem.setSizeHint(QSize(20, 30))
        nonPythonItem.setBackground(QBrush(Qt.lightGray))
        nonPythonItem.setForeground(QBrush(Qt.black))
        nonPythonItem.setFont(font)
Beispiel #8
0
class PopupCompleter(QFrame):

    def __init__(self):
        QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.listWidget = QListWidget()
        self.listWidget.setMinimumHeight(350)
        vbox.addWidget(self.listWidget)

        self.listWidget.currentItemChanged.connect(self._repaint_items)

    def _repaint_items(self, current, previous):
        if current is not None:
            widget = self.listWidget.itemWidget(current)
            if widget is not None:
                widget.set_selected()
        if previous is not None:
            widget = self.listWidget.itemWidget(previous)
            if widget is not None:
                widget.set_not_selected()

    def reload(self, model):
        """Reload the data of the Popup Completer, and restart the state."""
        self.listWidget.clear()
        self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        self.listWidget.setCurrentRow(8)

    def clear(self):
        """Remove all the items of the list (deleted), and reload the help."""
        self.listWidget.clear()

    def refresh(self, model, has_text=True):
        """Refresh the list when the user search for some word."""
        self.listWidget.clear()
        if not has_text:
            self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        if model:
            self.listWidget.setCurrentItem(model[0][0])
        else:
            self.add_no_found()

    def fetch_more(self, model):
        """Add more items to the list on user scroll."""
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])

    def add_no_found(self):
        """Load no results found message"""
        noFoundItem = self._create_help_item(resources.IMAGES['delete'],
                translations.TR_NO_RESULTS)
        self.listWidget.addItem(noFoundItem)

    def add_help(self):
        #Load help
        fileItem = self._create_help_item(resources.IMAGES['locate-file'],
                         translations.TR_ONLY_FILES)
        self.listWidget.addItem(fileItem)
        classItem = self._create_help_item(resources.IMAGES['locate-class'],
                        translations.TR_ONLY_CLASSES)
        self.listWidget.addItem(classItem)
        methodItem = self._create_help_item(
                        resources.IMAGES['locate-function'],
                        translations.TR_ONLY_METHODS)
        self.listWidget.addItem(methodItem)
        attributeItem = self._create_help_item(
                            resources.IMAGES['locate-attributes'],
                            translations.TR_ONLY_ATRIBUTES)
        self.listWidget.addItem(attributeItem)
        thisFileItem = self._create_help_item(
                    resources.IMAGES['locate-on-this-file'],
                    translations.TR_ONLY_CLASSES_METHODS)
        self.listWidget.addItem(thisFileItem)
        tabsItem = self._create_help_item(resources.IMAGES['locate-tab'],
                translations.TR_ONLY_CURRENT_TABS)
        self.listWidget.addItem(tabsItem)
        lineItem = self._create_help_item(resources.IMAGES['locate-line'],
                translations.TR_GO_TO_LINE)
        self.listWidget.addItem(lineItem)
        nonPythonItem = self._create_help_item(
                resources.IMAGES['locate-nonpython'],
                translations.TR_ONLY_NON_PYTHON)
        self.listWidget.addItem(nonPythonItem)

    def _create_help_item(self, image, text):
        Item = QListWidgetItem(QIcon(image), text)
        font = Item.font()
        font.setBold(True)
        Item.setSizeHint(QSize(20, 30))
        Item.setBackground(QBrush(Qt.lightGray))
        Item.setForeground(QBrush(Qt.black))
        Item.setFont(font)
        return Item
Beispiel #9
0
class CodeCompletionWidget(QFrame):
    def __init__(self, editor):
        super(CodeCompletionWidget,
              self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {
            'a': resources.IMAGES['attribute'],
            'f': resources.IMAGES['function'],
            'c': resources.IMAGES['class'],
            'm': resources.IMAGES['module']
        }

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = u''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        desktop = QApplication.instance().desktop()
        self._desktop_geometry = desktop.availableGeometry()

        self.connect(self._editor.document(), SIGNAL("blockCountChanged(int)"),
                     self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(self.completion_list.count() -
                                               move)
        return True

    def update_metadata(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        self.cc.analyze_file('', source)

    def insert_completion(self, insert):
        if insert != self._prefix:
            extra = len(self._prefix) - len(insert)
            self._editor.textCursor().insertText(insert[extra:])
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) + \
            self.completion_list.verticalScrollBar().sizeHint().width() + 10)
        height = 200
        orientation = (point.y() + height) < self._desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = self._desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(
                    QIcon(self._icons.get(p[0],
                                          resources.IMAGES['attribute'])),
                    p[1]))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item) \
            for item in self._completion_results.get('modules', []) \
            if item.startswith(prefix)]
        proposals += [('c', item) \
            for item in self._completion_results.get('classes', []) \
            if item.startswith(prefix)]
        proposals += [('a', item) \
            for item in self._completion_results.get('attributes', []) \
            if item.startswith(prefix)]
        proposals += [('f', item) \
            for item in self._completion_results.get('functions', []) \
            if item.startswith(prefix)]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def fill_completer(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        insert = unicode(self.completion_list.currentItem().text())
        self.insert_completion(insert)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        if event.key() == Qt.Key_Period  or (event.key() == Qt.Key_Space and \
           event.modifiers() == Qt.ControlModifier):
            self.fill_completer()
Beispiel #10
0
class CodeCompletionWidget(QFrame):
    def __init__(self, editor):
        super(CodeCompletionWidget, self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {
            "a": resources.IMAGES["attribute"],
            "f": resources.IMAGES["function"],
            "c": resources.IMAGES["class"],
        }

        self.cc = code_completion.CodeCompletion()
        self._completion_results = []
        self._prefix = u""
        self.setVisible(False)
        self.source = ""
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        desktop = QApplication.instance().desktop()
        self._desktop_geometry = desktop.availableGeometry()

        self.connect(self._editor.document(), SIGNAL("blockCountChanged(int)"), self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(self.completion_list.count() - move)
        return True

    def update_metadata(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        self.cc.analyze_file("", source)

    def insert_completion(self, insert):
        if insert != self._prefix:
            extra = len(self._prefix) - len(insert)
            self._editor.textCursor().insertText(insert[extra:])
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        # Check new position according desktop geometry
        width = (
            self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10
        )
        height = 200
        orientation = (point.y() + height) < self._desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = self._desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(QIcon(self._icons.get(p[0], resources.IMAGES["attribute"])), p[1])
            )

    def set_completion_prefix(self, prefix):
        self._prefix = prefix
        proposals = []
        proposals += [("c", item) for item in self.completion_results.get("classes", []) if item.startswith(prefix)]
        proposals += [("a", item) for item in self.completion_results.get("attributes", []) if item.startswith(prefix)]
        proposals += [("f", item) for item in self.completion_results.get("functions", []) if item.startswith(prefix)]
        if proposals:
            self.complete(proposals)
        else:
            self.hide_completer()

    def fill_completer(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self.completion_results = results
        prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ""
        self.hide()

    def pre_key_insert_completion(self):
        insert = unicode(self.completion_list.currentItem().text())
        self.insert_completion(insert)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible():
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix)
            self.completion_list.setCurrentRow(0)
        if event.key() == Qt.Key_Period or (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier):
            self.fill_completer()
Beispiel #11
0
class MainWindow(QMainWindow):
    """The main window widget for the program.

    """

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        #### 1 CREATE AND INITIALIZE DATA STRUCTURES ####

        self.xLabel = None
        self.xSelection = DEFAULTX
        self.xSelection_old = None
        self.xArray = None

        self.yLabel = None
        self.ySelection = DEFAULTY
        self.ySelection_old = None

        self.yArray = None

        self.filename = None

        self.tdms_file_object = None

        self.channel_registry = {}

        # Y selector on Left
        self.ySelector = QListWidget()
        ySelectorLabel = QLabel("y axis channel")
        self.ySelector.setMaximumWidth(ySelectorLabel.sizeHint().width())

        # File name and plot in the middle
        self.sourceFileName = QLabel("None")
        self.sourceFileName.setSizePolicy(QSizePolicy.Expanding,
                                          QSizePolicy.Fixed)
        sourceFileLabel = QLabel("current file")
        sourceFileLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        # Matplotlib canvas
        fig = Figure(dpi=100)
        self.canvas = FigureCanvas(fig)
        self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        mpl_toolbar = NavigationToolbar(self.canvas, self.canvas)

        self.axes = fig.add_subplot(111)

        # X selector on bottom
        self.xSelector = QListWidget()
        self.xSelector.addItem("Time")
        self.xSelector.setFlow(0)
        xSelectorLabel = QLabel("x axis channel")
        self.xSelector.setMaximumHeight(self.xSelector.sizeHintForColumn(0))

        # Offset and parameter widgets on the right top
        self.offsetThing = OffsetWidget()
        self.attributesThing = AttributesWidget()

        # Save channel on right bottom
        self.save_chan_chkbx = QCheckBox()
        save_chan_label = QLabel("Save Channel")

        # Status bar at the bottom

        self.fileSizeLabel = QLabel("File Size: {f_size:0>7.3f} MB".format(f_size=0.0))
        self.fileSizeLabel.setFixedWidth(self.fileSizeLabel.sizeHint().width()+10)
        self.fileSizeLabel.setFrameStyle(QFrame.Panel|QFrame.Sunken)

        self.yChanLength = QLabel("Y Channel Length: {y_len:0>7.0f}".format(y_len=0.0))
        self.yChanLength.setFixedWidth(self.yChanLength.sizeHint().width()+10)
        self.yChanLength.setFrameStyle(QFrame.Panel|QFrame.Sunken)
        
        self.xChanLength = QLabel("X Channel Length: {x_len:0>7.0f}".format(x_len=0.0))
        self.xChanLength.setFixedWidth(self.xChanLength.sizeHint().width()+10)
        self.xChanLength.setFrameStyle(QFrame.Panel|QFrame.Sunken)

        status = self.statusBar()
        status.setSizeGripEnabled(False)
        status.addPermanentWidget(self.fileSizeLabel)
        status.addPermanentWidget(self.yChanLength)
        status.addPermanentWidget(self.xChanLength)

        status.showMessage("Ready", 5000)
        
        #2 Create the central widget
        self.centralWidget = QWidget()

        # Left Side
        selectorLayout = QVBoxLayout()
        #selectorLayout.addWidget(xSelectorLabel)
        #selectorLayout.addWidget(self.xSelector)
        selectorLayout.addWidget(ySelectorLabel)
        selectorLayout.addWidget(self.ySelector)
        selectorLayout.addStretch()

        # Center
        centralLayout = QVBoxLayout()
        fileNameLayout = QHBoxLayout()
        xSelectorLayout = QHBoxLayout()
        fileNameLayout.addWidget(sourceFileLabel)
        fileNameLayout.addWidget(self.sourceFileName)
        xSelectorLayout.addWidget(xSelectorLabel)
        xSelectorLayout.addWidget(self.xSelector)
        centralLayout.addLayout(fileNameLayout)
        centralLayout.addWidget(self.canvas)
        centralLayout.addWidget(mpl_toolbar)
        centralLayout.addLayout(xSelectorLayout)

        # Right bottom
        save_chan_layout = QHBoxLayout()
        save_chan_layout.addWidget(self.save_chan_chkbx)
        save_chan_layout.addWidget(save_chan_label)

        # Right Side
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.offsetThing)
        rightLayout.addWidget(self.attributesThing)
        rightLayout.addStretch()
        rightLayout.addLayout(save_chan_layout)

        layout = QHBoxLayout()
        layout.addLayout(selectorLayout)
        layout.addLayout(centralLayout)
        layout.addLayout(rightLayout)

        self.centralWidget.setLayout(layout)
        self.setCentralWidget(self.centralWidget)

        self.resize(self.sizeHint())

        #3 Create and set up any dock windows

        #4 Create actions and insert them into menus and toolbars
        fileQuitAction = self.createAction("&Quit", self.close, "Ctrl+Q",
                                           "exit", "Close the application")
        fileOpenAction = self.createAction("&Open TDMS File", self.fileOpen,
                                           QKeySequence.Open, "fileopen",
                                           "Open an existing TDMS file")
        fileExportAction = self.createAction("&Export", self.exprtToHDF5,
                                             "Ctrl+E",
                                             tip="Export the TDMS data to HDF5")

        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenuActions = (fileOpenAction, fileExportAction,
                                fileQuitAction)
        #self.addActions(self.fileMenu, self.fileMenuActions)

        self.xSelector.itemSelectionChanged.connect(self.make_x_selection)
        self.ySelector.itemSelectionChanged.connect(self.make_y_selection)
        self.offsetThing.new_offset.connect(self.subtract_offset)
        self.fileMenu.triggered.connect(self.update_file_menu)

        self.save_chan_chkbx.stateChanged.connect(self.toggle_save)

        #5 Read in application's settings
        settings = QSettings()

        # Restore the geometry and state of the main window from last use
        #self.restoreGeometry(settings.value("MainWindow/Geometry"))
        #self.restoreState(settings.value("MainWindow/State"))

        self.setWindowTitle("TDMS to HDF5 Converter")
        self.recentFiles = settings.value("RecentFiles")
        if not self.recentFiles:
            self.recentFiles = []

        self.update_file_menu()

    def update_ui(self):
        pass

    def initVariables(self):
        self.xLabel = None
        self.xSelection = DEFAULTX
        self.xSelection_old = None
        self.xArray = None

        self.yLabel = None
        self.ySelection = DEFAULTY
        self.ySelection_old = None

        self.yArray = None

        self.filename = None

        self.tdms_file_object = None

        self.channel_registry = {}

    def createAction(self, text, slot=None, shortcut=None, icon=None,
                     tip=None, checkable=False, signal="triggered()"):
        # Create the action
        action = QAction(text, self)
        # Give it its icon
        if icon is not None:
            action.setIcon(QIcon(":/{icon}.png".format(icon=icon)))
        # Give it its shortcut
        if shortcut is not None:
            action.setShortcut(shortcut)
        # Set up its help/tip text
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        # Connect it to a signal
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        # Make it checkable
        if checkable:
            action.setCheckable(True)
        return action

    def addActions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def update_file_menu(self):
        self.fileMenu.clear()
        self.addActions(self.fileMenu, self.fileMenuActions[:-1])
        current = self.filename if self.filename is not None else None
        recentFiles = []
        for fname in self.recentFiles:
            if fname != current and QFile.exists(fname):
                recentFiles.append(fname)
        if recentFiles:
            self.fileMenu.addSeparator()
            for i, fname in enumerate(recentFiles):
                action = QAction("&{num} {name}".format(num=i+1, name=QFileInfo(fname).fileName()), self)
                action.setData(fname)
                action.triggered.connect(lambda: self.loadFile(fname))
                self.fileMenu.addAction(action)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.fileMenuActions[-1])

    def fileOpen(self): # Process 1
        self.initVariables()
        basedir = os.path.dirname(self.filename) if self.filename is not None \
          else "~/Documents/PhD/root/raw-data/sio2al149/CryoMeasurement"
        formats = "TDMS files (*.tdms)"
        fname = QFileDialog.getOpenFileName(self, "Open a TDMS File",
                                            basedir, formats)

        # Process 1.1 Collect file name
        if fname and QFile.exists(fname):
            self.loadFile(fname)

    def loadFile(self, fname): # Process 1.2 Generate TDMS file object
        self.add_recent_file(fname)
        self.tdms_file_object = TdmsFile(fname)
        self.filename = fname

         # Process 1.3 Read data into local structure
        if self.tdms_file_object:

            # Process 1.3.0 Generate group list
            group_list = self.tdms_file_object.groups()

            # Processes 1.3.1 through 1.3.3 Sort TDMS data
            for group in group_list:
                self.sortTDMSGroupData(group)

            message = "Loaded {f_name}".format(f_name=os.path.basename(fname))
            self.sourceFileName.setText(os.path.basename(fname))

            # Process 2.1 Populate channel selection lists
            self.update_selectors()

        else:
            message = "Failed to load {f_name}".format(f_name=os.path.
                                                       basename(fname))

        self.statusBar().showMessage(message, 5000)

        fsize = os.path.getsize(self.filename)
        self.fileSizeLabel.setText("File Size: {file_size:>7.3f} MB".format(file_size=fsize/1E6))
        #TODO self.updateStatus(message) # see Rapid GUI ch06.pyw

    def add_recent_file(self, fname):
        if fname is None:
            return
        if not fname in self.recentFiles:
            self.recentFiles.insert(0, fname)
            while len(self.recentFiles) > 9:
                self.recentFiles.pop()

    def sortTDMSGroupData(self, group): # Process 1.3 Sort Group data

        # Process 1.3.1 Get <Group> Channels
        group_props = self.tdms_file_object.object(group).properties

        # Process 1.3.2 Get <Group> Properties
        group_chans = self.tdms_file_object.group_channels(group)

        # Process 1.3.3 Create a new channel in the registry for each channel
        # in the group
        for chan in group_chans:
            chan_name = chan.path.split('/')[-1].strip("'")

            # Process 1.3.3.1 Generate new channel object and fill with data
            # Some of the TDMS channels were created, but never populated with
            # data. The following weeds those out.
            try:
                new_chan = Channel(chan_name,
                                device=group,
                                meas_array=chan.data)
            except TypeError:
                self.statusBar().showMessage("Channel {chan} in {dev} has no data"
                                             .format(chan=chan_name, dev=group),
                                             5000)

            try:
                new_chan.set_start_time(chan.property("wf_start_time"))

                new_chan.set_delta_time(chan.property("wf_increment"))

                new_chan.set_location('raw/{c2_name}'.format(c2_name=chan_name))

                if chan_name not in ['TCap', 'xMagnet']:
                    new_chan.set_write()

                # Some of the channel-specific properties were actually
                # saved in the group object's properties list.
                # We retrieve those here.
                # Process 1.3.3.2 Resort the group properties of TDMS ADWin
                if group == "ADWin":
                    for atr_name in ADWIN_DICT[chan_name]:
                        try:
                            new_chan.attributes[atr_name] = \
                              group_props[atr_name]
                        except KeyError:
                            #print('The key {a_name} was not found.'
                            #      .format(a_name=atr_name))
                            #print('The keys available are\n')
                            #print(group_props)
                            pass

                # Process 1.3.3.3 Add new channel to the registry
                self.channel_registry[chan_name] = new_chan

                #print('\tChannel name:\t{ch_name}'.format(ch_name=chan_name))

            except (KeyError, UnboundLocalError):
                pass
                #print('Error: Was unable to load {c3_name}'
                #      .format(c3_name=chan_name))

    def update_selectors(self):

        # Clear the selectors
        self.xSelector.clear()
        self.ySelector.clear()

        # Add the names of the channels in the registry to both selectors
        for key in self.channel_registry.keys():
            self.xSelector.addItem(key)
            self.ySelector.addItem(key)

        # Add the time "channel" to the x selector
        self.xSelector.addItem('Time')

        # Sort the lists (alphabetically) otherwise the order constantly changes
        self.xSelector.sortItems()
        self.ySelector.sortItems()

        # Set the current x selector default
        default_x_item = self.xSelector.findItems(DEFAULTX, Qt.MatchExactly)
        self.xSelector.setCurrentItem(default_x_item[0])

        # Set the current y selector default
        try:
            default_y_item = self.ySelector.findItems(DEFAULTY,
                                                      Qt.MatchExactly)
            self.ySelector.setCurrentItem(default_y_item[0])
        except IndexError:
            self.ySelector.setCurrentRow(0)

        self.xSelector.setMinimumHeight(self.xSelector.sizeHintForRow(0)*3)
        self.ySelector.setMinimumWidth(self.ySelector.sizeHintForColumn(0)+10)

    def exprtToHDF5(self): # Process 5 Save to HDF5
        fname = self.filename.split('.')[0] + '.hdf5'
        basedir = "/home/chris/Documents/PhD/root/data/sio2al149/cryo_measurement"

        if not os.path.exists(basedir):
            os.makedirs(basedir)

        formats = "TDMS files (*.hdf5 *.h5 *.he5 *.hdf)"
    
        dialog = QFileDialog()
        dialog.setFilter(formats)
        dialog.setDefaultSuffix("*.hdf5")
        dialog.selectFile(os.path.join(basedir, fname))
        dialog.setDirectory(basedir)
        if dialog.exec_():
            fname = dialog.selectedFiles()
        else:
            return

        # Process 5.1 Create HDF5 file object
        hdf5_file_object = h5py.File(fname[0])

        # Process 5.2 Create channels at their locations
        for chan in self.channel_registry:

            chan_obj = self.channel_registry[chan]
            chan_name = chan

            #print(chan, self.channel_registry[chan].location,
            #      self.channel_registry[chan].write_to_file)

            # Process 5.2.1 Write channel data
            if self.channel_registry[chan].write_to_file:

                dset = hdf5_file_object.create_dataset(chan_obj.location,
                                                            data=chan_obj.data)

            # Process 5.2.2 Write channel attributes
            for attr_name in self.channel_registry[chan].attributes:
                attr_value = self.channel_registry[chan].attributes[attr_name]

                # Convert the datetime format to a string
                if type(attr_value) is datetime:
                    attr_value = attr_value.isoformat()

                # There's currently a wierd bug when dealing with python3
                # strings.
                # This gets around that
                if type(attr_value) is str:
                    #attr_value = attr_value.encode('utf-8')
                    #attr_value = np.string_(attr_value, dtype="S10")
                    attr_value = np.string_(attr_value)

                dset.attrs.create(attr_name, attr_value)

        # Process 5.3 Write data to file
        hdf5_file_object.flush()
        hdf5_file_object.close()

    def make_x_selection(self):

        self.x_change = True

        # Get the name of the newly selected channel
        self.xSelection = self.xSelector.currentItem().text()

        # Get the axis label
        self.xLabel = self.gen_axis_label(self.xSelection)

        # If the xSelection is time, use the time data instead of measurement
        # data
        if self.xSelection == 'Time':
            try:
                self.xArray = self.channel_registry[self.ySelection].time
            except KeyError:
                self.xArray = np.array([])
        else:
            self.xArray = self.channel_registry[self.xSelection].data

        if self.yLabel:
            self.plotData()

        self.xSelection_old = self.xSelector.currentItem()

        self.x_change = False

        self.xChanLength.setText("X Channel Length: {x_len:>7.0f}".format(x_len=len(self.xArray)))

    def make_y_selection(self, offset=0.0):

        self.y_change = True

        # Get the names of the selected channels from the selectors
        try:
            self.ySelection = self.ySelector.currentItem().text()
        except AttributeError:
            self.ySelection = DEFAULTY

        # Set save channel checkbox state
        self.save_chan_chkbx.setChecked(self.channel_registry[self.ySelection]
                                        .write_to_file)

        # Get the axis label
        self.yLabel = self.gen_axis_label(self.ySelection)

        # Generate the y-channel array to be plotted
        self.yArray = self.channel_registry[self.ySelection].data - offset

        # Update the attributes view
        self.attributesThing.clear_attributes()

        self.attributesThing.select_chan(self.channel_registry[self.ySelection])

        if self.xSelection == 'Time':
            self.make_x_selection()
        else:
            self.plotData()

        self.ySelection_old = self.ySelector.currentItem()

        self.y_change = False

        self.yChanLength.setText("Y Channel Length: {y_len:>7.0f}".format(y_len=len(self.yArray)))

    def gen_axis_label(self, chan_name):

        # Generate the axis labels based on the selected channels
        # Cycle through the labes in the AXESLABELS dictionary
        for axlbl in AXESLABELS.keys():

            # Cycle through the channel names in each label's dictionary entry
            for cn in AXESLABELS[axlbl]:

                # If a channel equals one of the selections, save the label 
                if chan_name == cn:
                    label = axlbl

        return label

    def plotData(self):

        # Clear the plot
        self.axes.cla()

        # Turn on the grid
        self.axes.grid(True)

        # Set the labels
        try: 
            self.axes.set_xlabel(self.xLabel)
        except UnboundLocalError:
            self.statusBar().showMessage("Could not generate an axis label for {chan}"
                                         .format(chan=self.xSelection), 5000)
        try:
            self.axes.set_ylabel(self.yLabel)
        except UnboundLocalError:
            self.statusBar().showMessage("Could not generate an axis label for {chan}"
                                         .format(chan=self.ySelection), 5000)

        # Try plotting the data. There are still no checks in place to make sure
        # the arrays are of the same length.
        try:
            # Plot the data and label it
            self.axes.plot(self.xArray, self.yArray, label=self.ySelection)

            # Show the legend
            self.axes.legend(loc=0)

            # Draw everything
            self.canvas.draw()
        except ValueError:

            QMessageBox.warning(self, "Unequal Arrays", "{y_chan} and {x_chan} "
                                .format(y_chan=self.ySelection,
                                        x_chan=self.xSelection) + \
                                        "are not the same length!")

            if self.x_change:
                self.xSelector.setCurrentItem(self.xSelection_old)
            elif self.y_change:
                self.ySelector.setCurrentItem(self.ySelection_old)

    def subtract_offset(self):
        "Subtract the offset entered from the currently selected y channel."

        offset = self.offsetThing.offset_entry.value()

        self.make_y_selection(offset=offset)

    def toggle_save(self):

        self.channel_registry[self.ySelection].write_to_file = \
          self.save_chan_chkbx.isChecked()

    def create_new_channel(self, ch_name):
        "Create a new channel in the registry."

        #print(ch_name)
        pass

    def closeEvent(self, event):
        """Reimplementation of the close even handler.

        We have to reimplement this because not all close actions, e.g. clicking
        the X button, call the close() method.  We want to catch this so we can
        give the user the opportunity to save unsaved changes before the program
        exits.

        """
        settings = QSettings()
        #settings.setValue("MainWindow/Geometry", QVariant(
        #    self.saveGeometry()))
        #settings.setValue("MainWindow/State", QVariant(
        #    self.saveState()))
        if self.recentFiles:
            recentFiles = self.recentFiles
        else:
            recentFiles = []
        settings.setValue("RecentFiles", recentFiles)
Beispiel #12
0
class PopupCompleter(QFrame):

    def __init__(self):
        QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.listWidget = QListWidget()
        self.listWidget.setMinimumHeight(350)
        vbox.addWidget(self.listWidget)

        self.listWidget.currentItemChanged.connect(self._repaint_items)

    def _repaint_items(self, current, previous):
        if current is not None:
            widget = self.listWidget.itemWidget(current)
            if widget is not None:
                widget.set_selected()
        if previous is not None:
            widget = self.listWidget.itemWidget(previous)
            if widget is not None:
                widget.set_not_selected()

    def reload(self, model):
        """Reload the data of the Popup Completer, and restart the state."""
        self.listWidget.clear()
        self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        self.listWidget.setCurrentRow(8)

    def clear(self):
        """Remove all the items of the list (deleted), and reload the help."""
        self.listWidget.clear()

    def refresh(self, model, has_text=True):
        """Refresh the list when the user search for some word."""
        self.listWidget.clear()
        if not has_text:
            self.add_help()
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])
        if model:
            self.listWidget.setCurrentItem(model[0][0])
        else:
            self.add_no_found()

    def fetch_more(self, model):
        """Add more items to the list on user scroll."""
        for item in model:
            self.listWidget.addItem(item[0])
            self.listWidget.setItemWidget(item[0], item[1])

    def add_no_found(self):
        #Load no results found message
        noFoundItem = QListWidgetItem(
            QIcon(resources.IMAGES['delete']),
                'No results were found!')
        font = noFoundItem.font()
        font.setBold(True)
        noFoundItem.setSizeHint(QSize(20, 30))
        noFoundItem.setBackground(QBrush(Qt.lightGray))
        noFoundItem.setForeground(QBrush(Qt.black))
        noFoundItem.setFont(font)
        self.listWidget.addItem(noFoundItem)

    def add_help(self):
        #Load help
        fileItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-file']),
            '@\t(Filter only by Files)')
        font = fileItem.font()
        font.setBold(True)
        fileItem.setSizeHint(QSize(20, 30))
        fileItem.setBackground(QBrush(Qt.lightGray))
        fileItem.setForeground(QBrush(Qt.black))
        fileItem.setFont(font)
        self.listWidget.addItem(fileItem)
        classItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-class']),
            '<\t(Filter only by Classes)')
        self.listWidget.addItem(classItem)
        classItem.setSizeHint(QSize(20, 30))
        classItem.setBackground(QBrush(Qt.lightGray))
        classItem.setForeground(QBrush(Qt.black))
        classItem.setFont(font)
        methodItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-function']),
            '>\t(Filter only by Methods)')
        self.listWidget.addItem(methodItem)
        methodItem.setSizeHint(QSize(20, 30))
        methodItem.setBackground(QBrush(Qt.lightGray))
        methodItem.setForeground(QBrush(Qt.black))
        methodItem.setFont(font)
        attributeItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-attributes']),
            '-\t(Filter only by Attributes)')
        self.listWidget.addItem(attributeItem)
        attributeItem.setSizeHint(QSize(20, 30))
        attributeItem.setBackground(QBrush(Qt.lightGray))
        attributeItem.setForeground(QBrush(Qt.black))
        attributeItem.setFont(font)
        thisFileItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-on-this-file']),
            '.\t(Filter only by Classes and Methods in this File)')
        font = thisFileItem.font()
        font.setBold(True)
        thisFileItem.setSizeHint(QSize(20, 30))
        thisFileItem.setBackground(QBrush(Qt.lightGray))
        thisFileItem.setForeground(QBrush(Qt.black))
        thisFileItem.setFont(font)
        self.listWidget.addItem(thisFileItem)
        tabsItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-tab']),
            '/\t(Filter only by the current Tabs)')
        font = tabsItem.font()
        font.setBold(True)
        tabsItem.setSizeHint(QSize(20, 30))
        tabsItem.setBackground(QBrush(Qt.lightGray))
        tabsItem.setForeground(QBrush(Qt.black))
        tabsItem.setFont(font)
        self.listWidget.addItem(tabsItem)
        lineItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-line']),
            ':\t(Go to Line)')
        font = lineItem.font()
        font.setBold(True)
        lineItem.setSizeHint(QSize(20, 30))
        lineItem.setBackground(QBrush(Qt.lightGray))
        lineItem.setForeground(QBrush(Qt.black))
        lineItem.setFont(font)
        self.listWidget.addItem(lineItem)
        nonPythonItem = QListWidgetItem(
            QIcon(resources.IMAGES['locate-nonpython']),
            '!\t(Filter only by Non Python Files)')
        self.listWidget.addItem(nonPythonItem)
        nonPythonItem.setSizeHint(QSize(20, 30))
        nonPythonItem.setBackground(QBrush(Qt.lightGray))
        nonPythonItem.setForeground(QBrush(Qt.black))
        nonPythonItem.setFont(font)
Beispiel #13
0
class KeywordList(HelpedWidget):
    """Shows a list of keywords. The data structure expected and sent to the getter and setter is an array of values."""
    def __init__(self, model, list_label="", help_link=""):
        HelpedWidget.__init__(self, list_label, help_link)

        assert isinstance(model, ListModelMixin)
        self.model = model
        self.keyword_list = []

        self.list = QListWidget(self)
        self.list.setMinimumHeight(100)
        self.list.setMaximumHeight(150)
        self.default_selection_mode = self.list.selectionMode()


        self.addWidget(self.list)

        self.addRemoveWidget = AddRemoveWidget(self.addItem, self.removeItem)
        self.addWidget(self.addRemoveWidget)

        self.title = "New keyword"
        self.description = "Enter name of keyword:"

        self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged)

        self.modelChanged()

    def setSelectable(self, selectable):
        if selectable:
            self.list.setSelectionMode(self.default_selection_mode)
        else:
            self.list.setSelectionMode(QAbstractItemView.NoSelection)

    def setPopupLabels(self, title, description):
        """Change the labels of the default popup."""
        self.title = title
        self.description = description

    def newKeywordPopup(self, keyword_list):
        """
        Pops up a message box asking for a new keyword.
        Override this and return a string to customize the input dialog - Empty string equals canceled.
        The provided list are the already defined keywords
        """
        new_keyword, ok = QInputDialog.getText(self, self.tr(self.title), self.tr(self.description), QLineEdit.Normal)

        if ok:
            return str(new_keyword).strip()
        else:
            return ""

    def addItem(self):
        """Called by the add button to insert a new keyword"""
        new_keyword = self.newKeywordPopup(self.keyword_list)
        if not new_keyword == "":
            self.model.addItem(new_keyword)


    def removeItem(self):
        """Called by the remove button to remove a selected keyword"""
        if not self.list.currentItem() is None:
            row = self.list.currentRow()
            try:
                self.model.removeItem(self.keyword_list[row])
            except NotImplementedError:
                message = "Support for removal of items has not been implemented!"
                QMessageBox.information(self, "Not implemented!", message)


    def modelChanged(self):
        """Retrieves data from the model and inserts it into the list"""
        keywords = self.model.getList()

        self.list.clear()

        self.keyword_list = keywords

        for keyword in keywords:
            self.list.addItem(keyword)
Beispiel #14
0
class KeywordList(HelpedWidget):
    """Shows a list of keywords. The data structure expected and sent to the getter and setter is an array of values."""
    def __init__(self, model, list_label="", help_link=""):
        HelpedWidget.__init__(self, list_label, help_link)

        assert isinstance(model, ListModelMixin)
        self.model = model
        self.keyword_list = []

        self.list = QListWidget(self)
        self.list.setMinimumHeight(100)
        self.list.setMaximumHeight(150)
        self.default_selection_mode = self.list.selectionMode()

        self.addWidget(self.list)

        self.addRemoveWidget = AddRemoveWidget(self.addItem, self.removeItem)
        self.addWidget(self.addRemoveWidget)

        self.title = "New keyword"
        self.description = "Enter name of keyword:"

        self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT,
                                       self.modelChanged)

        self.modelChanged()

    def setSelectable(self, selectable):
        if selectable:
            self.list.setSelectionMode(self.default_selection_mode)
        else:
            self.list.setSelectionMode(QAbstractItemView.NoSelection)

    def setPopupLabels(self, title, description):
        """Change the labels of the default popup."""
        self.title = title
        self.description = description

    def newKeywordPopup(self, keyword_list):
        """
        Pops up a message box asking for a new keyword.
        Override this and return a string to customize the input dialog - Empty string equals canceled.
        The provided list are the already defined keywords
        """
        new_keyword, ok = QInputDialog.getText(self, self.tr(self.title),
                                               self.tr(self.description),
                                               QLineEdit.Normal)

        if ok:
            return str(new_keyword).strip()
        else:
            return ""

    def addItem(self):
        """Called by the add button to insert a new keyword"""
        new_keyword = self.newKeywordPopup(self.keyword_list)
        if not new_keyword == "":
            self.model.addItem(new_keyword)

    def removeItem(self):
        """Called by the remove button to remove a selected keyword"""
        if not self.list.currentItem() is None:
            row = self.list.currentRow()
            try:
                self.model.removeItem(self.keyword_list[row])
            except NotImplementedError:
                message = "Support for removal of items has not been implemented!"
                QMessageBox.information(self, "Not implemented!", message)

    def modelChanged(self):
        """Retrieves data from the model and inserts it into the list"""
        keywords = self.model.getList()

        self.list.clear()

        self.keyword_list = keywords

        for keyword in keywords:
            self.list.addItem(keyword)

    def cleanup(self):
        self.model.observable().detach(ListModelMixin.LIST_CHANGED_EVENT,
                                       self.modelChanged)
Beispiel #15
0
class LayerImportBrowser(QDialog):

    class VectorPage(QWidget):
        def __init__(self, parent=None, filters="", encodings=[]):
            QWidget.__init__(self, parent)
            self.filters = filters
            self.layerLineEdit = QLineEdit()
            self.browseToolButton = QToolButton()
            self.browseToolButton.setAutoRaise(True)
            self.browseToolButton.setIcon(QIcon(":document-open"))
            layerLabel = QLabel("&Dataset:")
            layerLabel.setBuddy(self.layerLineEdit)

            self.encodingComboBox = QComboBox()
            self.encodingComboBox.addItems(encodings)
            encodingLabel = QLabel("&Encoding:")
            encodingLabel.setBuddy(self.encodingComboBox)

            hbox = QHBoxLayout()
            hbox.addWidget(layerLabel)
            hbox.addWidget(self.layerLineEdit)
            hbox.addWidget(self.browseToolButton)
            vbox = QVBoxLayout()
            vbox.addLayout(hbox)
            hbox = QHBoxLayout()
            hbox.addWidget(encodingLabel)
            hbox.addWidget(self.encodingComboBox)
            vbox.addLayout(hbox)
            self.setLayout(vbox)
            self.encodingComboBox.setCurrentIndex(self.encodingComboBox.findText("System"))

            self.connect(self.browseToolButton,
                SIGNAL("clicked()"), self.browseToFile)
            self.connect(self.encodingComboBox,
                SIGNAL("currentIndexChanged(QString)"), self.changeEncoding)

        def browseToFile(self):
            dialog = QFileDialog(self, "manageR - Open Vector File",
                unicode(robjects.r.getwd()[0]), self.filters)
            if not dialog.exec_() == QDialog.Accepted:
                return
            files = dialog.selectedFiles()
            file = files.first().trimmed()
            self.layerLineEdit.setText(file)
            self.emit(SIGNAL("filePathChanged(QString)"), file)

        def changeEncoding(self, text):
            self.emit(SIGNAL("encodingChanged(QString)"), text)

    class RasterPage(QWidget):
        def __init__(self, parent=None, filters=""):
            QWidget.__init__(self, parent)
            self.parent = parent
            self.filters = filters
            self.layerLineEdit = QLineEdit()
            self.browseToolButton = QToolButton()
            self.browseToolButton.setAutoRaise(True)
            self.browseToolButton.setIcon(QIcon(":document-open"))
            layerLabel = QLabel("&Dataset:")
            layerLabel.setBuddy(self.layerLineEdit)

            hbox = QHBoxLayout()
            hbox.addWidget(layerLabel)
            hbox.addWidget(self.layerLineEdit)
            hbox.addWidget(self.browseToolButton)
            vbox = QVBoxLayout()
            vbox.addLayout(hbox)
            self.setLayout(vbox)

            self.connect(self.browseToolButton, SIGNAL("clicked()"), self.browseToFile)

        def browseToFile(self):
            dialog = QFileDialog(self, "manageR - Open Raster File",
                unicode(robjects.r.getwd()[0]), self.filters)
            if not dialog.exec_() == QDialog.Accepted:
                return
            files = dialog.selectedFiles()
            file = files.first().trimmed()
            self.layerLineEdit.setText(file)
            self.emit(SIGNAL("filePathChanged(QString)"), file)

    def __init__(self, parent=None, vectors="", rasters="", encodings=[]):
        QDialog.__init__(self, parent)
        self.contentsWidget = QListWidget()
        self.setWindowIcon(QIcon(":icon"))
        self.contentsWidget.setViewMode(QListView.IconMode)
        self.contentsWidget.setIconSize(QSize(76, 66))
        self.contentsWidget.setMovement(QListView.Static)
        self.contentsWidget.setMaximumWidth(106)
        self.contentsWidget.setMinimumWidth(106)
        self.contentsWidget.setMinimumHeight(220)
        self.contentsWidget.setSpacing(12)
        self.__filePath = ""
        self.__encoding = "System"
        self.__type = 0

        self.pagesWidget = QStackedWidget()
        vectorPage = self.VectorPage(self, vectors, encodings)
        self.pagesWidget.addWidget(vectorPage)
        rasterPage = self.RasterPage(self, rasters)
        self.pagesWidget.addWidget(rasterPage)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,
            Qt.Horizontal, self)

        self.connect(buttons, SIGNAL("accepted()"), self.accept)
        self.connect(buttons, SIGNAL("rejected()"), self.reject)
        self.connect(vectorPage, SIGNAL("filePathChanged(QString)"), self.setFilePath)
        self.connect(vectorPage, SIGNAL("encodingChanged(QString)"), self.setEncoding)
        self.connect(rasterPage, SIGNAL("filePathChanged(QString)"), self.setFilePath)

        self.createIcons()
        self.contentsWidget.setCurrentRow(0)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.addWidget(self.contentsWidget)
        horizontalLayout.addWidget(self.pagesWidget, 1)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(horizontalLayout)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(12)
        mainLayout.addWidget(buttons)
        self.setLayout(mainLayout)
        self.setWindowTitle("manageR - Import Layer")

    def createIcons(self):
        vectorButton = QListWidgetItem(self.contentsWidget)
        vectorButton.setIcon(QIcon(":custom-vector.svg"))
        vectorButton.setText("Vector Layer")
        vectorButton.setTextAlignment(Qt.AlignHCenter)
        vectorButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        rasterButton = QListWidgetItem(self.contentsWidget)
        rasterButton.setIcon(QIcon(":custom-raster.svg"))
        rasterButton.setText("Raster Layer")
        rasterButton.setTextAlignment(Qt.AlignHCenter)
        rasterButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

        self.connect(self.contentsWidget,
            SIGNAL("currentItemChanged(QListWidgetItem*, QListWidgetItem*)"),
            self.changePage)

    def changePage(self, current, previous):
        if not current:
            current = previous
        self.pagesWidget.setCurrentIndex(self.contentsWidget.row(current))

    def filePath(self):
        return self.__filePath
        
    def setFilePath(self, filePath):
        self.__filePath = filePath

    def encoding(self):
        return self.__encoding
    
    def setEncoding(self, encoding):
        self.__encoding = encoding
        
    def layerType(self):
        return self.__type
        
    def setLayerType(self, type):
        self.__type = type

    def accept(self):
        self.__type = self.pagesWidget.currentIndex()
        QDialog.accept(self)