Beispiel #1
0
    def comment_toggle(self):
        """
        Toggles commenting out selected lines,
        or lines with cursor.
        """
        blocks = self.get_selected_blocks()

        # iterate through lines in doc commenting or uncommenting
        # based on whether everything is commented or not
        commentAllOut = any([
            not str(block.text()).lstrip().startswith('#') for block in blocks
        ])
        if commentAllOut:
            for block in blocks:
                cursor = QtGui.QTextCursor(block)
                cursor.select(QtGui.QTextCursor.LineUnderCursor)
                selectedText = cursor.selectedText()
                right_split = len(selectedText.lstrip())
                count = len(selectedText)
                split_index = count - right_split
                split_text = selectedText[split_index:]
                newText = ' ' * split_index + '#' + split_text
                cursor.insertText(newText)
        else:
            for block in blocks:
                cursor = QtGui.QTextCursor(block)
                cursor.select(QtGui.QTextCursor.LineUnderCursor)
                selectedText = cursor.selectedText()
                newText = str(selectedText).replace('#', '', 1)
                cursor.insertText(newText)
Beispiel #2
0
    def lineNumberAreaPaintEvent(self, event):
        mypainter = QtGui.QPainter(self)

        block = self.editor.firstVisibleBlock()
        blockNumber = block.blockNumber()
        blockGeo = self.editor.blockBoundingGeometry(block)
        top = blockGeo.translated(self.editor.contentOffset()).top()
        bottom = top + self.editor.blockBoundingRect(block).height()

        p = self.editor.textCursor().position()
        doc = self.editor.document()
        current_block = doc.findBlock(p).blockNumber()

        height = self.editor.fontMetrics().height()
        while block.isValid() and (top <= event.rect().bottom()):
            if not block.isVisible():
                continue
            if block.isVisible() and (bottom >= event.rect().top()):
                number = str(blockNumber + 1)
                colour = QtCore.Qt.darkGray
                font = self.font()
                if blockNumber == current_block:
                    colour = QtCore.Qt.yellow
                    font = QtGui.QFont(font)
                    font.setBold(True)
                mypainter.setFont(font)
                mypainter.setPen(colour)
                mypainter.drawText(0, top, self.width(), height,
                                   QtCore.Qt.AlignRight, number)

            block = block.next()
            top = bottom
            bottom = top + self.editor.blockBoundingRect(block).height()
            blockNumber += 1
Beispiel #3
0
    def __init__(self, shortcuthandler):
        super(ShortcutEditor, self).__init__()
        self.shortcuthandler = shortcuthandler
        self.shortcut_dict = shortcuthandler.shortcut_dict

        model = QtGui.QStandardItemModel()
        self.setModel(model)
        root = model.invisibleRootItem()
        model.setHorizontalHeaderLabels(['Shortcut', 'Description'])

        for item in self.shortcut_dict.items():
            row = [QtGui.QStandardItem(val) for val in item]
            root.appendRow(row)

        self.header().setStretchLastSection(False)
        rtc = QtWidgets.QHeaderView.ResizeToContents
        try:
            self.header().setResizeMode(rtc)
        except AttributeError:
            # 'PySide2.QtWidgets.QHeaderView' object has no attribute 'setResizeMode'
            # TODO: Find compatible way to resize header.
            pass

        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.setUniformRowHeights(True)
        self.resize(500, 400)
Beispiel #4
0
 def update_icon(self, tab_index=None, size=(10, 10)):
     """
     Represent the document's save state
     by setting an icon on the tab.
     """
     if tab_index is None:
         tab_index = self.tabs.currentIndex()
     px = QtGui.QPixmap(*size)
     ico = QtGui.QIcon(px)
     self.tabs.setTabIcon(tab_index, ico)
Beispiel #5
0
 def add_rows(self, rows):
     root = self.invisibleRootItem()
     for name, shortcut, about, action in rows:
         name_item = QtGui.QStandardItem(name)
         shortcut_item = QtGui.QStandardItem(shortcut)
         shortcut_item.setData(action, ACTION_ROLE)
         about = self.single_line_description(about)
         # print(about)
         about_item = QtGui.QStandardItem(about)
         # about_item.setData(about, QtCore.Qt.DecorationRole)
         row = [name_item, shortcut_item, about_item]
         root.appendRow(row)
Beispiel #6
0
    def format(self, rgb, style=''):
        """
        Return a QtGui.QTextCharFormat with the given attributes.
        """
        color = QtGui.QColor(*rgb)
        textFormat = QtGui.QTextCharFormat()
        textFormat.setForeground(color)

        if 'bold' in style:
            textFormat.setFontWeight(QtGui.QFont.Bold)
        if 'italic' in style:
            textFormat.setFontItalic(True)

        return textFormat
Beispiel #7
0
def key_to_sequence(key):
    """
    Convert the given QtCore.Qt.Key type to a
    QKeySequence including currently held
    modifiers. The only downside to this being
    that, for keys that require shift to be held,
    the sequence Shift+Key will be returned.
    """
    QT = QtCore.Qt
    modifier_map = {
        QT.Key_Control: QT.ControlModifier,
        QT.Key_Shift: QT.ShiftModifier,
        QT.Key_Alt: QT.AltModifier,
        QT.Key_Meta: QT.MetaModifier,
    }
    app = QtWidgets.QApplication
    held = app.keyboardModifiers()
    combo = 0
    for mod in modifier_map.values():
        if held & mod == mod:
            combo |= mod
    combo |= key

    combo = QtGui.QKeySequence(combo)
    return combo
Beispiel #8
0
def test_app(qtbot):
    app = qt_api.QApplication.instance()

    # add the package path to sys.path
    FOLDER = os.path.dirname(__file__)
    PACKAGE_PATH = os.path.dirname(FOLDER)

    # set the application icon
    ICON_PATH = os.path.join(PACKAGE_PATH, 'icons', 'PythonEditor.png')
    icon = QtGui.QIcon(ICON_PATH)
    app.setWindowIcon(icon)

    # set style (makes palette work on linux)
    # Plastique isn't available on Windows, so try multiple styles.
    styles = QtWidgets.QStyleFactory.keys()
    for style_name in ['Plastique', 'Fusion']:
        if style_name not in styles:
            continue
        print('Setting style to:', style_name)
        style = QtWidgets.QStyleFactory.create(style_name)
        QtWidgets.QApplication.setStyle(style)
        break

    app.setPalette(nukepalette.getNukePalette())

    _ide = ide.IDE()
Beispiel #9
0
    def __init__(self):
        super(VisualDebug, self).__init__()
        self.layout = QtWidgets.QGridLayout(self)

        self.setMinimumWidth(900)
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

        self.treeview = WidgetTreeView()
        self.treemodel = QtGui.QStandardItemModel()
        self.treeview.setModel(self.treemodel)
        self.treeview.setUniformRowHeights(True)

        self.layout.addWidget(self.treeview)
        self.treemodel.setHorizontalHeaderLabels([
            'metaObject className',
            'objectName',
            'windowTitle',
            'text',
            'title',
            '__repr__',
        ])

        self.treeview.header().setStretchLastSection(False)
        mode = QtWidgets.QHeaderView.ResizeToContents
        try:
            self.treeview.header().setResizeMode(mode)
        except AttributeError:  # setResizeMode not supported in PyQt
            pass

        rootItem = self.treemodel.invisibleRootItem()
        qApp = QtWidgets.QApplication.instance()
        for w in qApp.topLevelWidgets():  # extra stuff
            self.recurseWidgets(w, rootItem)
Beispiel #10
0
    def __init__(self, handle_shortcuts=True, uid=None, init_features=True):
        super(Editor, self).__init__()
        self.setObjectName('Editor')
        self.setAcceptDrops(True)
        font = QtGui.QFont(DEFAULT_FONT)
        font.setPointSize(10)
        self.setFont(font)
        self.setMouseTracking(True)
        self.setStyleSheet("""
        QToolTip {
        color: #F6F6F6;
        background-color: rgb(45, 42, 46);
        }
        """)
        self.shortcut_overrode_keyevent = False

        if uid is None:
            uid = str(uuid.uuid4())
        self._uuid = uid

        self._changed = False
        self.wait_for_autocomplete = False
        self._handle_shortcuts = handle_shortcuts
        self._features_initialised = False

        self.emit_text_changed = True
        self.textChanged.connect(self._handle_textChanged)

        linenumberarea.LineNumberArea(self)

        if init_features:
            self.init_features()
    def __init__(self, editor=None, tabeditor=None, terminal=None):
        super(ShortcutEditor, self).__init__()
        self.setWindowTitle('Shortcuts')

        model = QtGui.QStandardItemModel()
        self.setModel(model)
        root = model.invisibleRootItem()
        model.setHorizontalHeaderLabels(['Description', 'Shortcut', 'About'])

        self.header().setStretchLastSection(False)
        rtc = QtWidgets.QHeaderView.ResizeToContents
        try:
            self.header().setResizeMode(rtc)
        except AttributeError:
            # for PySide2:
            self.header().setSectionResizeMode(rtc)

        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.setUniformRowHeights(True)
        self.resize(800, 600)

        widgets = []
        if editor is not None:
            widgets.append(editor)
        if terminal is not None:
            widgets.append(terminal)
        if tabeditor is not None:
            widgets.append(tabeditor)

        for widget in widgets:
            for action in widget.actions():
                name = action.text()
                # TODO: put shortcut in a keycatcher widget.
                shortcut = action.shortcut().toString()
                # if not shortcut.strip():
                #     continue
                if 'Placeholder' in action.toolTip():
                    continue
                about = ' '.join([
                    line.strip() for line in action.toolTip().splitlines()
                ]).strip()
                row = [
                    QtGui.QStandardItem(val)
                    for val in [name, shortcut, about]
                ]
                root.appendRow(row)
Beispiel #12
0
 def indent(self):
     """
     Indent Selected Text
     """
     blocks = self.get_selected_blocks()
     for block in blocks:
         cursor = QtGui.QTextCursor(block)
         cursor.movePosition(QtGui.QTextCursor.StartOfLine)
         cursor.insertText('    ')
Beispiel #13
0
 def recursion(widget, parent):
     for child in widget.children():
         infoList = self.getObjectInfo(child)
         items = [QtGui.QStandardItem(info) for info in infoList]
         parent.appendRow(items)
         childItem = items[0]
         childItem.setData(child, QtCore.Qt.UserRole)
         # childItem = QtGui.QStandardItem(', '.join(info))
         recursion(child, childItem)
Beispiel #14
0
 def mousePressEvent(self, event):
     if event.button() == QtCore.Qt.LeftButton:
         super(FileTree, self).mousePressEvent(event)
     if event.button() == QtCore.Qt.RightButton:
         menu = QtWidgets.QMenu()
         menu.addAction('New', 'print "does nothing"')
         menu.addAction('Delete', 'print "does nothing"')
         cursor = QtGui.QCursor()
         pos = cursor.pos()
         menu.exec_(pos)
Beispiel #15
0
    def __init__(self):
        super(Terminal, self).__init__()

        self.setObjectName('Terminal')
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.setReadOnly(True)
        self.setup()
        self.destroyed.connect(self.stop)
        font = QtGui.QFont(DEFAULT_FONT)
        font.setPointSize(10)
        self.setFont(font)
Beispiel #16
0
 def copy_tab_file_path(self, index):
     """
     Copy the current tab's file path
     (if it has one) to the clipboard.
     """
     data = self.tabData(index)
     path = data.get('path')
     if path is None or not path.strip():
         print('No file path for "{0}".'.format(data['name']))
         return
     clipboard = QtGui.QClipboard()
     clipboard.setText(path)
     print('Path copied to clipboard:')
     print(path)
Beispiel #17
0
    def copy_block_or_selection(self):
        """
        If there's no text selected,
        copy the current block.
        """
        textCursor = self.editor.textCursor()
        selection = textCursor.selection()
        text = selection.toPlainText()
        if not text:
            textCursor.select(QtGui.QTextCursor.BlockUnderCursor)
            selection = textCursor.selection()
            text = selection.toPlainText()

        QtGui.QClipboard().setText(text)
Beispiel #18
0
 def unindent(self):
     """
     Unindent Selected Text
     TODO: Maintain original selection
     and cursor position.
     """
     blocks = self.get_selected_blocks(ignoreEmpty=False)
     for block in blocks:
         cursor = QtGui.QTextCursor(block)
         cursor.select(QtGui.QTextCursor.LineUnderCursor)
         lineText = cursor.selectedText()
         if lineText.startswith(' '):
             newText = str(lineText[:4]).replace(' ', '') + lineText[4:]
             cursor.insertText(newText)
Beispiel #19
0
    def cut_line(self):
        """
        If no text selected, cut whole
        current line to clipboard.
        """
        textCursor = self.editor.textCursor()
        if textCursor.hasSelection():
            return

        textCursor.select(QtGui.QTextCursor.LineUnderCursor)
        text = textCursor.selectedText()
        textCursor.insertText('')

        QtGui.QClipboard().setText(text)
Beispiel #20
0
    def keyPressEvent(self, event):
        event.accept()
        key = event.key()
        if key in [
                QtCore.Qt.Key_Control, QtCore.Qt.Key_Alt, QtCore.Qt.Key_Meta,
                QtCore.Qt.Key_Shift
        ]:
            key = int(event.modifiers())
        else:
            key += int(event.modifiers())

        keyseq = QtGui.QKeySequence(key)
        text = keyseq.toString()

        self.setText(text)
Beispiel #21
0
 def show_tab_menu(self):
     """
     Show a list of tabs and go to the tab clicked.
     """
     menu = QtWidgets.QMenu()
     from functools import partial
     for i in range(self.count()):
         tab_name = self.tabText(i)
         if not tab_name.strip():
             button = self.tabBar().tabButton(i, QtWidgets.QTabBar.LeftSide)
             if not isinstance(button, TabButton):
                 continue
             tab_name = button.text()
         action = partial(self.setCurrentIndex, i)
         menu.addAction(tab_name, action)
     menu.exec_(QtGui.QCursor().pos())
Beispiel #22
0
        def add_action(action, widget, shortcut, func):
            """
            Add action to widget with a shortcut that
            triggers the given function.

            :action: QtWidgets.QAction
            :widget: QtWidgets.QWidget
            :shortcut: str (e.g. 'Ctrl+S') or Qt Key
            :func: a callable that gets executed
                   when triggering the action.
            """
            key_seq = QtGui.QKeySequence(shortcut)
            a.setShortcut(key_seq)
            a.setShortcutContext(QtCore.Qt.WidgetShortcut)
            a.triggered.connect(func)
            widget.addAction(a)
Beispiel #23
0
    def load_globals(self):
        """
        Load globals into Tree
        """
        self.treemodel.removeRows(0, self.treemodel.rowCount())

        self.names = __dict__.copy()

        rootItem = self.treemodel.invisibleRootItem()
        for key, value in __dict__.iteritems():
            # if hasattr(value, '__repr__'):
            try:
                items = [
                    QtGui.QStandardItem(i.__repr__()) for i in [key, value]
                ]
                rootItem.appendRow(items)
            except Exception, e:
                print(key, value, e)
Beispiel #24
0
    def register_shortcuts(self, action_dict=None):
        """
        Use the shortcut register to apply
        shortcuts to actions that exist
        on the widget.
        """
        if action_dict is None:
            a = actions.load_actions_from_json
            action_dict = a()

        widgacts = action_dict.items()
        for widget_name, widget_actions in widgacts:
            if not hasattr(self, widget_name):
                continue

            widget = getattr(self, widget_name)
            if widget is None:
                continue

            acts = widget_actions.items()
            for action_name, attributes in acts:
                shortcuts = attributes['Shortcuts']
                if len(shortcuts) == 0:
                    continue
                for action in widget.actions():
                    if action.text() != action_name:
                        continue
                    break
                else:
                    continue
                key_seqs = []
                for shortcut in shortcuts:
                    key_seq = QtGui.QKeySequence(shortcut)

                    # convert to unicode again
                    # to make sure the format
                    # stays the same
                    s = key_seq.toString()
                    self.shortcut_dict[s] = action
                    key_seqs.append(key_seq)

                action.setShortcuts(key_seqs)
                action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
Beispiel #25
0
    def mouseReleaseEvent(self, event):
        self.tab_pressed = False
        i = self.tabAt(event.pos())
        if event.button() == QtCore.Qt.LeftButton:
            if i == -1:
                i = self.currentIndex()
            if (i != self.start_move_index):
                self.tab_repositioned_signal.emit(i, self.start_move_index)
            self.handle_close_button_display(event)

        elif event.button() == QtCore.Qt.RightButton:
            menu = QtWidgets.QMenu()

            rename = partial(self._show_name_edit, i)
            menu.addAction('Rename', rename)

            move_to_first = partial(self.move_to_first, i)
            menu.addAction('Move Tab to First', move_to_first)

            move_to_last = partial(self.move_to_last, i)
            menu.addAction('Move Tab to Last', move_to_last)

            close_tab_func = partial(self.removeTab, i)
            menu.addAction('Close Tab', close_tab_func)

            copy_file_path = partial(self.copy_tab_file_path, i)
            menu.addAction('Copy File Path', copy_file_path)

            # Other ideas (TODO)
            """
            menu.addAction('Close Other Tabs', )
            menu.addAction('Close Tabs to Right', )
            menu.addAction('Close Tabs to Left', )
            menu.addAction('Pin Tab', )
            """

            menu.exec_(QtGui.QCursor().pos())

        elif event.button() == QtCore.Qt.MiddleButton:
            if i != -1:
                self.removeTab(i)

        return super(Tabs, self).mouseReleaseEvent(event)
Beispiel #26
0
    def recurseWidgets(self, widget, parent):
        # TODO: later try and turn this into a generator pushed by a QTimer
        # treeInfo = {}
        def recursion(widget, parent):
            for child in widget.children():
                infoList = self.getObjectInfo(child)
                items = [QtGui.QStandardItem(info) for info in infoList]
                parent.appendRow(items)
                childItem = items[0]
                childItem.setData(child, QtCore.Qt.UserRole)
                # childItem = QtGui.QStandardItem(', '.join(info))
                recursion(child, childItem)

        infoList = self.getObjectInfo(widget)
        items = [QtGui.QStandardItem(info) for info in infoList]
        # parentItem = QtGui.QStandardItem(', '.join(info)) #later setData adding widget object
        parent.appendRow(items)
        firstParent = items[0]
        firstParent.setData(widget, QtCore.Qt.UserRole)
        # parent.appendRow(parentItem)
        recursion(widget, firstParent)
Beispiel #27
0
 def show_tab_menu(self):
     """
     Show a list of tabs and go to
     the tab clicked.
     """
     menu = QtWidgets.QMenu()
     current_index = self.tabs.currentIndex()
     from functools import partial
     for i in range(self.tabs.count()):
         tab_name = self.tabs.tabText(i)
         if not tab_name.strip():
             continue
         func = partial(self.tabs.setCurrentIndex, i)
         action = menu.addAction(tab_name, func)
         if i == current_index:
             font = action.font()
             font.setBold(True)
             font.setUnderline(True)
             action.setFont(font)
             menu.setActiveAction(action)
     menu.exec_(QtGui.QCursor().pos())
def main():
    app = QtWidgets.QApplication.instance()
    if not app:
        app = QtWidgets.QApplication(sys.argv)

    for widget in app.allWidgets():
        if widget.objectName() == 'IDE':
            widget.close()

    PDF = 'PYTHONEDITOR_DEFAULT_FONT'
    fontbase = QtGui.QFontDatabase()
    current_folder = os.path.dirname(__file__)
    user_font_file = os.path.join(current_folder, 'scripts', 'fonts',
                                  'DejaVu Sans Mono for Powerline.ttf')
    fontbase.addApplicationFont(user_font_file)

    os.environ[PDF] = 'DejaVu Sans Mono for Powerline'
    _ide = ide.IDE()
    _ide.setParent(app.activeWindow())
    _ide.setWindowFlags(QtCore.Qt.Window)
    _ide.setPalette(ui_palette.get_palette_style())

    # Plastique isn't available on Windows, so try multiple styles.
    styles = QtWidgets.QStyleFactory.keys()
    style_found = False
    for style_name in ['Plastique', 'Fusion']:
        if style_name in styles:
            print('Setting style to:', style_name)
            style_found = True
            break

    if style_found:
        style = QtWidgets.QStyleFactory.create(style_name)
        _ide.setStyle(style)

    print('PythonEditor import time: %.04f seconds' % (time.time() - start))
    #_ide.showMaximized()
    _ide.show()
    if app.applicationName() in ['python', 'mayapy', 'UE4Editor']:
        sys.exit(app.exec_())
Beispiel #29
0
    def set_shortcut(self, index, value, role=QtCore.Qt.DisplayRole):
        if (index.column() != 1) or (role != QtCore.Qt.EditRole):
            # not a shortcut
            return

        self.setData(index, value, role)

        # unassign shortcut if it was previously assigned
        if value in self._shortcut_handler.shortcut_dict.keys():
            old_action = self._shortcut_handler.shortcut_dict[value]
            old_action.setShortcut(QtGui.QKeySequence())

            # remove it from the shortcuts dict and
            # add it to the unassigned list
            del self._shortcut_handler.shortcut_dict[value]
            if old_action not in self._shortcut_handler.unassigned:
                self._shortcut_handler.unassigned.append(old_action)

            print('Removed shortcut %r from %r' % (value, old_action.text()))

        new_action = index.data(ACTION_ROLE)
        # remove any existing shortcuts associated with this action
        for shortcut in new_action.shortcuts():
            s = shortcut.toString()
            if s in self._shortcut_handler.shortcut_dict:
                del self._shortcut_handler.shortcut_dict[s]

        key_seq = QtGui.QKeySequence.fromString(value)
        new_action.setShortcut(key_seq)

        # set the shortcut on the handler, so it'll be caught by the eventFilter.
        self._shortcut_handler.shortcut_dict[value] = new_action

        # remove action from the unassigned list
        if new_action in self._shortcut_handler.unassigned:
            self._shortcut_handler.unassigned.remove(new_action)

        print('Set shortcut for %r to %r' %
              (new_action.text(), key_seq.toString()))
Beispiel #30
0
    def __init__(self):
        super(ObjectInspector, self).__init__()
        self.layout = QtWidgets.QGridLayout(self)

        self.setMinimumWidth(900)
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

        self.treeview = QtWidgets.QTreeView()
        self.treemodel = QtGui.QStandardItemModel()
        self.treeview.setModel(self.treemodel)
        self.treeview.setUniformRowHeights(True)

        self.layout.addWidget(self.treeview)

        self.treemodel.setHorizontalHeaderLabels(['object name', 'object'])

        self.treeview.header().setStretchLastSection(False)
        mode = QtWidgets.QHeaderView.ResizeToContents
        self.treeview.header().setResizeMode(mode)

        self.load_globals()
        self.start_timer()