Пример #1
0
    def __init__(self, client, messageQueue, isLightTheme):
        QMainWindow.__init__(self)

        self.client = client
        self.messageQueue = messageQueue
        self.isLightTheme = isLightTheme

        self.__setMenubar()

        self.chatLog = QTextEdit()
        self.chatLog.setReadOnly(True)

        self.chatInput = QTextEdit()
        self.chatInput.textChanged.connect(self.chatInputTextChanged)

        self.sendButton = QPushButton("Send")
        self.sendButton.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chatInputFontMetrics = QFontMetrics(self.chatInput.font())
        self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
        self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)

        hboxLayout = QHBoxLayout()
        hboxLayout.addWidget(self.chatInput)
        hboxLayout.addWidget(self.sendButton)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chatInputWrapper = QWidget()
        chatInputWrapper.setLayout(hboxLayout)
        chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chatLog)
        splitter.addWidget(chatInputWrapper)
        splitter.setSizes([int(self.height()), 1])

        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(splitter)

        # Add the completeted layout to the window
        self.centralWidget = QWidget()
        self.centralWidget.setLayout(vboxLayout)
        self.setCentralWidget(self.centralWidget)

        qtUtils.resizeWindow(self, 700, 400)
        qtUtils.centerWindow(self)

        # Title and icon
        self.setWindowTitle("Cryptully")
        self.setWindowIcon(QIcon(utils.getAbsoluteResourcePath('images/' + ('light' if isLightTheme else 'dark') + '/icon.png')))
        self.statusBar().showMessage("Not Connected")
Пример #2
0
    def __init__(self, connectionManager, parent=None):
        QWidget.__init__(self, parent)

        self.connectionManager = connectionManager
        self.isDisabled = False
        self.wasCleared = False

        self.urlRegex = re.compile(constants.URL_REGEX)

        self.chatLog = QTextBrowser()
        self.chatLog.setOpenExternalLinks(True)

        self.chatInput = QTextEdit()
        self.chatInput.textChanged.connect(self.chatInputTextChanged)

        self.sendButton = QPushButton("Send")
        self.sendButton.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chatInputFontMetrics = QFontMetrics(self.chatInput.font())
        self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
        self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)

        hbox = QHBoxLayout()
        hbox.addWidget(self.chatInput)
        hbox.addWidget(self.sendButton)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chatInputWrapper = QWidget()
        chatInputWrapper.setLayout(hbox)
        chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() *
                                          3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chatLog)
        splitter.addWidget(chatInputWrapper)
        splitter.setSizes([int(parent.height()), 1])

        hbox = QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.typingTimer = QTimer()
        self.typingTimer.setSingleShot(True)
        self.typingTimer.timeout.connect(self.stoppedTyping)
Пример #3
0
    def __init__(self, connectionManager, parent=None):
        QWidget.__init__(self, parent)

        self.connectionManager = connectionManager
        self.isDisabled = False
        self.wasCleared = False

        self.urlRegex = re.compile(constants.URL_REGEX)

        self.chatLog = QTextBrowser()
        self.chatLog.setOpenExternalLinks(True)

        self.chatInput = QTextEdit()
        self.chatInput.textChanged.connect(self.chatInputTextChanged)

        self.sendButton = QPushButton("Send")
        self.sendButton.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chatInputFontMetrics = QFontMetrics(self.chatInput.font())
        self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
        self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)

        hbox = QHBoxLayout()
        hbox.addWidget(self.chatInput)
        hbox.addWidget(self.sendButton)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chatInputWrapper = QWidget()
        chatInputWrapper.setLayout(hbox)
        chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chatLog)
        splitter.addWidget(chatInputWrapper)
        splitter.setSizes([int(parent.height()), 1])

        hbox = QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.typingTimer = QTimer()
        self.typingTimer.setSingleShot(True)
        self.typingTimer.timeout.connect(self.stoppedTyping)
Пример #4
0
 def update_contents(self):
     self.prepareGeometryChange()
     self.setTextWidth(-1)
     self.setTextWidth(self.document().idealWidth())
     self.droplet.setPos(self.rect().center().x(), self.rect().height())
     self.droplet.setVisible(bool(self.branches))
     fm = QFontMetrics(self.document().defaultFont())
     attr = self.node_inst.attr
     self.attr_text_w = fm.width(attr.name if attr else "")
     self.attr_text_h = fm.lineSpacing()
     self.line_descent = fm.descent()
     if self.pie is not None:
         self.pie.setPos(self.rect().right(), self.rect().center().y())
Пример #5
0
    def defaultTextGeometry(self, point):
        """
        Return the default text geometry. Used in case the user single
        clicked in the scene.

        """
        font = self.annotation_item.font()
        metrics = QFontMetrics(font)
        spacing = metrics.lineSpacing()
        margin = self.annotation_item.document().documentMargin()

        rect = QRectF(QPointF(point.x(), point.y() - spacing - margin),
                      QSizeF(150, spacing + 2 * margin))
        return rect
Пример #6
0
    def defaultTextGeometry(self, point):
        """
        Return the default text geometry. Used in case the user single
        clicked in the scene.

        """
        font = self.annotation_item.font()
        metrics = QFontMetrics(font)
        spacing = metrics.lineSpacing()
        margin = self.annotation_item.document().documentMargin()

        rect = QRectF(QPointF(point.x(), point.y() - spacing - margin),
                      QSizeF(150, spacing + 2 * margin))
        return rect
Пример #7
0
    def __init__(self, model, node_inst, parent=None):
        super().__init__(parent)
        self.model = model
        self.node_inst = node_inst

        fm = QFontMetrics(self.document().defaultFont())
        attr = node_inst.attr
        self.attr_text_w = fm.width(attr.name if attr else "")
        self.attr_text_h = fm.lineSpacing()
        self.line_descent = fm.descent()
        self._rect = None

        if model.domain.class_var.is_discrete:
            self.pie = PieChart(node_inst.value, 8, self)
        else:
            self.pie = None
Пример #8
0
    def mousePressEvent(self, event):
        if self.foldArea > 0:
            xofs = self.width() - self.foldArea
            font_metrics = QFontMetrics(self.edit.document().defaultFont())
            fh = font_metrics.lineSpacing()
            ys = event.posF().y()
            lineNumber = 0

            if event.pos().x() > xofs:
                pattern = self.pat
                if self.edit.lang != "python":
                    pattern = self.patNotPython
                block = self.edit.firstVisibleBlock()
                viewport_offset = self.edit.contentOffset()
                page_bottom = self.edit.viewport().height()
                while block.isValid():
                    position = self.edit.blockBoundingGeometry(
                        block).topLeft() + viewport_offset
                    if position.y() > page_bottom:
                        break
                    if position.y() < ys and (position.y() + fh) > ys and \
                      pattern.match(str(block.text())):
                        if not block.blockNumber() in self._endDocstringBlocks:
                            lineNumber = block.blockNumber() + 1
                            break
                    if position.y() < ys and (position.y() + fh) > ys and \
                      event.button() == Qt.LeftButton:
                        line = block.blockNumber()
                        if line in self._breakpoints:
                            self._breakpoints.remove(line)
                        else:
                            self._breakpoints.append(line)
                        self.update()
                        break
                    elif position.y() < ys and (position.y() + fh) > ys and \
                      event.button() == Qt.RightButton:
                        line = block.blockNumber()
                        if line in self._bookmarks:
                            self._bookmarks.remove(line)
                        else:
                            self._bookmarks.append(line)
                        self.update()
                        break
                    block = block.next()
                self._save_breakpoints_bookmarks()
            if lineNumber > 0:
                self.code_folding_event(lineNumber)
Пример #9
0
    def mousePressEvent(self, event):
        if self.foldArea > 0:
            xofs = self.width() - self.foldArea
            font_metrics = QFontMetrics(self.edit.document().defaultFont())
            fh = font_metrics.lineSpacing()
            ys = event.posF().y()
            lineNumber = 0

            if event.pos().x() > xofs:
                pattern = self.pat
                if self.edit.lang != "python":
                    pattern = self.patNotPython
                block = self.edit.firstVisibleBlock()
                viewport_offset = self.edit.contentOffset()
                page_bottom = self.edit.viewport().height()
                while block.isValid():
                    position = self.edit.blockBoundingGeometry(
                        block).topLeft() + viewport_offset
                    if position.y() > page_bottom:
                        break
                    if position.y() < ys and (position.y() + fh) > ys and \
                      pattern.match(str(block.text())):
                        lineNumber = block.blockNumber() + 1
                        break
                    elif position.y() < ys and (position.y() + fh) > ys and \
                      event.button() == Qt.LeftButton:
                        line = block.blockNumber()
                        if line in self._breakpoints:
                            self._breakpoints.remove(line)
                        else:
                            self._breakpoints.append(line)
                        self.update()
                        break
                    elif position.y() < ys and (position.y() + fh) > ys and \
                      event.button() == Qt.RightButton:
                        line = block.blockNumber()
                        if line in self._bookmarks:
                            self._bookmarks.remove(line)
                        else:
                            self._bookmarks.append(line)
                        self.update()
                        break
                    block = block.next()
                self._save_breakpoints_bookmarks()
            if lineNumber > 0:
                self.code_folding_event(lineNumber)
Пример #10
0
    def sizeHint(self, which, constraint=QSizeF()):
        fm = QFontMetrics(self.font())
        spacing = fm.lineSpacing()
        mleft, mtop, mright, mbottom = self.getContentsMargins()

        if self._root and which == Qt.PreferredSize:
            nleaves = len([node for node in self._items.keys() if not node.branches])

            if self.orientation in [self.Left, self.Right]:
                return QSizeF(250, spacing * nleaves + mleft + mright)
            else:
                return QSizeF(spacing * nleaves + mtop + mbottom, 250)

        elif which == Qt.MinimumSize:
            return QSizeF(mleft + mright + 10, mtop + mbottom + 10)
        else:
            return QSizeF()
Пример #11
0
    def sizeHint(self, which, constraint=QSizeF()):
        fm = QFontMetrics(self.font())
        spacing = fm.lineSpacing()
        mleft, mtop, mright, mbottom = self.getContentsMargins()

        if self._root and which == Qt.PreferredSize:
            nleaves = len(
                [node for node in self._items.keys() if not node.branches])

            if self.orientation in [self.Left, self.Right]:
                return QSizeF(250, spacing * nleaves + mleft + mright)
            else:
                return QSizeF(spacing * nleaves + mtop + mbottom, 250)

        elif which == Qt.MinimumSize:
            return QSizeF(mleft + mright + 10, mtop + mbottom + 10)
        else:
            return QSizeF()
Пример #12
0
 def setText(self, msg):
     """set the text of self"""
     self.msg = '%s  ' % msg
     metrics = QFontMetrics(self.font)
     self.width = metrics.width(self.msg)
     self.height = metrics.lineSpacing() * 1.1
     self.setRect(0, 0, self.width, self.height)
     self.resetTransform()
     rotation = self.side.rotation()
     rotateCenter(self, -rotation)
     if rotation % 180 == 0:
         yOffset = self.rect().height()
         if rotation == 0:
             yOffset = 2 * -yOffset
         if rotation == 180:
             self.translate(self.rect().width()/2, yOffset)
         else:
             self.translate(-self.rect().width()/2, yOffset)
     else:
         self.translate(-self.rect().width()/2, -self.rect().height()/2)
Пример #13
0
 def setText(self, msg):
     """set the text of self"""
     self.msg = '%s  ' % msg
     metrics = QFontMetrics(self.font)
     self.width = metrics.width(self.msg)
     self.height = metrics.lineSpacing() * 1.1
     self.setRect(0, 0, self.width, self.height)
     self.resetTransform()
     rotation = self.side.rotation()
     rotateCenter(self, -rotation)
     if rotation % 180 == 0:
         yOffset = self.rect().height()
         if rotation == 0:
             yOffset = 2 * -yOffset
         if rotation == 180:
             self.translate(self.rect().width()/2, yOffset)
         else:
             self.translate(-self.rect().width()/2, yOffset)
     else:
         self.translate(-self.rect().width()/2, -self.rect().height()/2)
Пример #14
0
class KhtTextEdit(QPlainTextEdit):
    """ Widget which handle all specifities of implemented in the editor"""

    show_progress = pyqtSignal(bool)

    def __init__(self, parent=None, filename=None):
        """Initialization, can accept a filepath as argument"""
        QPlainTextEdit.__init__(self, parent)

        # Errors
        self.errors = {}

        self.isMAEMO = False
        self.scroller = None

        palette = self.palette()
        palette.setColor(QPalette.Base, Qt.white)
        palette.setColor(QPalette.Text, Qt.black)
        self.setPalette(palette)
        self.setWindowOpacity(0.9)
        self.hl_color = QColor('lightblue').lighter(120)
        self.qt18720 = False

        if ((parent.settings.value("qt18720")) == '2'):
            self.qt18720 = True
        else:
            self.qt18720 = False

        # Brace matching
        self.bracepos = None

        # Init scroller and area which are tricky hack to speed scrolling
        #        try:
        #            scroller = self.property("kineticScroller")
        #            scroller.setEnabled(True)
        #        except:
        #            print 'Cannot instance kineticScroller'

        #Plugin init moved to editor_window.py
        #initialization init of plugin system
        #Maybe be not the best place to do it ...
        #init_plugin_system({'plugin_path': '/home/opt/khteditor/plugins',
        #                    'plugins': ['autoindent']})

        #If we have a filename
        self.filename = filename
        if (self.filename == None) or (self.filename == ''):
            self.filename = u'Unnamed.txt'
        self.document().setModified(False)
        parent.setWindowTitle(self.filename)

        #Set no wrap
        if (bool(parent.settings.value("WrapLine"))):
            self.setLineWrapMode(QPlainTextEdit.NoWrap)
        else:
            self.setLineWrapMode(QPlainTextEdit.WidgetWidth)

        font = QFont()
        try:
            if parent.settings.contains('FontName'):
                font.setFamily(parent.settings.value('FontName'))
            else:
                font.setFamily("Courier")
        except:
            font.setFamily("Courier")

        #Get Font Size
        try:
            if parent.settings.contains('FontSize'):
                font.setPointSize(int(parent.settings.value('FontSize')))
            else:
                font.setPointSize(11)
        except:
            font.setPointSize(11)

        #Set Font
        self.fmetrics = QFontMetrics(font)
        self.document().setDefaultFont(font)

        #Remove auto capitalization
        self.setInputMethodHints(Qt.ImhNoAutoUppercase)

        #Keep threaded plugins references to avoid them to be garbage collected
        self.threaded_plugins = []
        self.enabled_plugins = parent.enabled_plugins

        #Current Line highlight and Bracket matcher
        self.cursorPositionChanged.connect(self.curPositionChanged)
        self.textChanged.connect(self.textEditChanged)
        # Brackets ExtraSelection ...

    def detectLanguage(self, filename):
        for extension, lang in LANGUAGES:
            if filename.endswith(extension.lower()):
                return lang
        return None

    def loadHighlighter(self, filename=None):
        filename = self.filename
        language = self.detectLanguage(filename)
        #Return None if language not yet implemented natively in KhtEditor
        if language == 'python':
            self.show_progress.emit(True)
            QApplication.processEvents()
            from syntax.python_highlighter import Highlighter
            self.highlighter = Highlighter(self.document())
            QApplication.processEvents()
            self.show_progress.emit(False)
        elif (language != None) and (language != 'None'):
            self.show_progress.emit(True)
            QApplication.processEvents()
            from syntax.generic_highlighter import Highlighter
            self.highlighter = Highlighter(self.document(), language)
            QApplication.processEvents()
            self.show_progress.emit(False)
        else:
            self.show_progress.emit(True)
            QApplication.processEvents()
            from syntax import pygments_highlighter
            self.highlighter = \
                pygments_highlighter.Highlighter(self.document(),
                                                 unicode(filename))
            QApplication.processEvents()
            self.show_progress.emit(False)

    def textEditChanged(self):
        if self.scroller:
            #Resize
            doc = self.document()
            s = doc.size().toSize()
            s.setHeight((s.height() + 1) * (self.fmetrics.lineSpacing() + 1))
            fr = self.frameRect()
            cr = self.contentsRect()
            self.setMinimumHeight(
                max(70,
                    s.height() + (fr.height() - cr.height() - 1)))
            self.setMinimumWidth(
                max(240,
                    s.width() + (fr.width() - cr.width()) - 1))

#    Remove ensureVisible Hack which is now fixed in qt 4.7.2
#    def ensureVisible(self,pos,xmargin,ymargin):
#
#        visible = self.area.viewport().size()
#        currentPos =  QPoint(self.area.horizontalScrollBar().value(),
#                      self.area.verticalScrollBar().value())
#        posRect =  QRect(pos.x()-xmargin, pos.y()-ymargin,2*xmargin,2*ymargin)
#        visibleRect =  QRect(currentPos, visible)
#
#        if (visibleRect.contains(posRect)):
#            return
#
#        newPos = currentPos
#        if (posRect.top() < visibleRect.top()):
#            newPos.setY(posRect.top())
#        elif (posRect.bottom() > visibleRect.bottom()):
#            newPos.setY(posRect.bottom() - visible.height())
#        if (posRect.left() < visibleRect.left()):
#            newPos.setX(posRect.left())
#        elif (posRect.right() > visibleRect.right()):
#            newPos.setX(posRect.right() - visible.width())
#        self.scroller.scrollTo(newPos)

    def curPositionChanged(self):
        #Plugin hook
        for plugin in filter_plugins_by_capability(
                'beforeCursorPositionChanged', self.enabled_plugins):
            plugin.do_beforeCursorPositionChanged(self)

        #Hilight current line
        #Workarround QTBUG-18720
        self.highlightCurrentLine()

        #Make sure cursor is visible
        #self.ensureCursorVisible()
        cursor = self.cursorRect()
        pos = cursor.center()
        #self.ensureVisible(pos.x(),pos.y(), 2*cursor.width()+20, 2*cursor.height())
        if self.scroller:
            self.scroller.ensureVisible(pos.x(), pos.y(),
                                        2 * cursor.width() + 20,
                                        2 * cursor.height())

    def match_left(self, block, character, start, found):
        map = {'{': '}', '(': ')', '[': ']'}
        block_jump = 0

        while block.isValid() and (block_jump < 20):
            data = block.userData()
            if data is not None:
                braces = data.braces
                N = len(braces)

                for k in range(start, N):
                    if braces[k].character == character:
                        found += 1

                    if braces[k].character == map[character]:
                        if not found:
                            return braces[k].position + block.position()
                        else:
                            found -= 1

                block = block.next()
                block_jump += 1
                start = 0

    def match_right(self, block, character, start, found):
        map = {'}': '{', ')': '(', ']': '['}
        block_jump = 0

        while block.isValid() and (block_jump < 20):
            data = block.userData()

            if data is not None:
                braces = data.braces

                if start is None:
                    start = len(braces)
                for k in range(start - 1, -1, -1):
                    if braces[k].character == character:
                        found += 1
                    if braces[k].character == map[character]:
                        if found == 0:
                            return braces[k].position + block.position()
                        else:
                            found -= 1
            block = block.previous()
            block_jump += 1
            start = None

    def check_brackets(self):
        left, right = QTextEdit.ExtraSelection(),\
                      QTextEdit.ExtraSelection()

        cursor = self.textCursor()
        block = cursor.block()
        data = block.userData()
        previous, next = None, None

        if data is not None:
            position = cursor.position()
            block_position = cursor.block().position()
            braces = data.braces
            N = len(braces)

            for k in range(0, N):
                if braces[k].position == position - block_position or\
                   braces[k].position == position - block_position - 1:
                    previous = braces[k].position + block_position
                    if braces[k].character in ['{', '(', '[']:
                        next = self.match_left(block, braces[k].character,
                                               k + 1, 0)
                    elif braces[k].character in ['}', ')', ']']:
                        next = self.match_right(block, braces[k].character, k,
                                                0)
#                    if next is None:
#                        next = -1
        if (next is not None and next > 0) \
            and (previous is not None and previous > 0):

            format = QTextCharFormat()

            cursor.setPosition(previous)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('blue'))
            left.format = format
            left.cursor = cursor

            cursor.setPosition(next)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('blue'))
            right.format = format
            right.cursor = cursor

            return left, right

        elif previous is not None:
            format = QTextCharFormat()

            cursor.setPosition(previous)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('red'))
            left.format = format
            left.cursor = cursor
            return (left, )
        elif next is not None:
            format = QTextCharFormat()

            cursor.setPosition(next)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('red'))
            left.format = format
            left.cursor = cursor
            return (left, )

    #PySide Bug : The type of e is QEvent instead of QKeyEvent
    def keyPressEvent(self, event):
        """Intercept the key event to lets plugin do something if they want"""
        if event.type() == QEvent.KeyPress:
            for plugin in filter_plugins_by_capability('beforeKeyPressEvent',
                                                       self.enabled_plugins):
                plugin.do_beforeKeyPressEvent(self, event)
            QPlainTextEdit.keyPressEvent(self, event)
            for plugin in filter_plugins_by_capability('afterKeyPressEvent',
                                                       self.enabled_plugins):
                plugin.do_afterKeyPressEvent(self, event)

    def closeEvent(self, event):
        """Catch the close event and ask to save if document is modified"""
        answer = self.document().isModified() and \
        QMessageBox.question(self,
               "Text Editor - Unsaved Changes",
               "Save unsaved changes in %s?" % self.filename,
               QMessageBox.Yes| QMessageBox.No| QMessageBox.Close)
        if answer == QMessageBox.Yes:
            try:
                self.save()
                event.accept()
            except (IOError, OSError), ioError:
                QMessageBox.warning(
                    self, "Text Editor -- Save Error",
                    "Failed to save %s: %s" % (self.filename, ioError))
                event.ignore()
        elif answer == QMessageBox.Close:
            return event.ignore()
Пример #15
0
class PortraitSpecificDelegate(QObject):

    def __init__(self, viewDelegate):
        QObject.__init__(self)
        self.viewDelegate = viewDelegate
        self.nameFont = self.viewDelegate.configureTextFont(16, QFont.Normal)
        self.tickerFont = self.viewDelegate.configureTextFont(14, QFont.Normal)
        self.currentPriceFont = self.viewDelegate.configureTextFont(32, QFont.Bold)
        self.changeFont = self.viewDelegate.configureTextFont(24, QFont.Normal)
        self.rightColFont = self.viewDelegate.configureTextFont(14, QFont.Normal)
        self.fontMetricsRightCol = QFontMetrics(self.rightColFont)
        self.lineSpRightCol = self.fontMetricsRightCol.lineSpacing()

    def getNameFont(self):
        return self.nameFont

    def getTickerFont(self):
        return self.tickerFont

    def getCurrentPriceFont(self):
        return self.currentPriceFont

    def getChangeFont(self):
        return self.changeFont
        
    def sizeHint(self, option, index):
        '''
        Portrait mode - Left column
          Name (Symbol)
          --------------
          Current Price
          Change
        '''
        textHeightLCol = self.viewDelegate.MARGIN + \
                         QFontMetrics(self.nameFont).lineSpacing() + \
                         self.viewDelegate.MARGIN + \
                         QFontMetrics(self.currentPriceFont).lineSpacing() + \
                         self.viewDelegate.MARGIN + \
                         QFontMetrics(self.changeFont).lineSpacing() + \
                         self.viewDelegate.MARGIN

        '''
        Portrait mode - Right column
          Name (Symbol)
          --------------
          PE ratio
          Market Cap
          Daily volume
          Average volume
          Delay
        '''
        textHeightRCol = self.viewDelegate.MARGIN_RCOL + \
                         QFontMetrics(self.nameFont).lineSpacing() + \
                         self.viewDelegate.MARGIN_RCOL + \
                         QFontMetrics(self.rightColFont).lineSpacing() + \
                         self.viewDelegate.MARGIN_RCOL + \
                         QFontMetrics(self.rightColFont).lineSpacing() + \
                         self.viewDelegate.MARGIN_RCOL + \
                         QFontMetrics(self.rightColFont).lineSpacing() + \
                         self.viewDelegate.MARGIN_RCOL + \
                         QFontMetrics(self.rightColFont).lineSpacing() + \
                         self.viewDelegate.MARGIN_RCOL + \
                         QFontMetrics(self.rightColFont).lineSpacing() + \
                         self.viewDelegate.MARGIN

        hint = QSize(0, max(textHeightLCol, textHeightRCol))
        return hint

    def paintRightCol(self, index, painter, rightColRect):
        '''
        @param QModelIndex index
        @param QPainter painter
        @param QRect rightColRect
        '''
        
        painter.setFont(self.rightColFont)
        painter.setPen(QPen(Qt.gray))

        m = index.model()
        lineSp = self.lineSpRightCol + self.viewDelegate.MARGIN_RCOL

        # PE ratio
        pe = m.data(index, PositionsModel.ROLE_PE)
        peStr = self.tr("PE ratio: ") + pe
        painter.drawText(rightColRect, Qt.AlignTop | Qt.AlignRight, peStr)
        # Market cap
        mktCap = m.data(index, PositionsModel.ROLE_MKT_CAP)
        mktCapStr = self.tr("Mkt Cap: ") + mktCap
        rightColRect.adjust(0, lineSp, 0, lineSp)
        painter.drawText(rightColRect, Qt.AlignTop | Qt.AlignRight, mktCapStr)
        # Daily Volume
        vol = m.data(index, PositionsModel.ROLE_DAILY_VOL)
        volStr = self.tr("Vol: ") + QString(vol)
        rightColRect.adjust(0, lineSp, 0, lineSp)
        painter.drawText(rightColRect, Qt.AlignTop | Qt.AlignRight, volStr)
        # Average Volume
        avgVol = m.data(index, PositionsModel.ROLE_AVG_VOL)
        avgVolStr = self.tr("Avg Vol: ") + QString(avgVol)
        rightColRect.adjust(0, lineSp, 0, lineSp)
        painter.drawText(rightColRect, Qt.AlignTop | Qt.AlignRight, avgVolStr)
        # Delay
        delay = m.data(index, PositionsModel.ROLE_DELAY)
        if delay == "":
            delayStr = self.tr("Realtime data")
        else:
            delayStr = self.tr("Delay: ") + delay + self.tr(" mins")
        rightColRect.adjust(0, lineSp, 0, lineSp)
        painter.drawText(rightColRect, Qt.AlignTop | Qt.AlignRight, delayStr)
Пример #16
0
class KhtTextEdit(QPlainTextEdit):
    """ Widget which handle all specifities of implemented in the editor"""

    show_progress = pyqtSignal(bool)

    def __init__(self, parent=None, filename=None):
        """Initialization, can accept a filepath as argument"""
        QPlainTextEdit.__init__(self, parent)

        # Errors
        self.errors = {}

        self.isMAEMO = False
        self.scroller = None

        palette = self.palette();
        palette.setColor(QPalette.Base, Qt.white)
        palette.setColor(QPalette.Text, Qt.black)
        self.setPalette(palette)
        self.setWindowOpacity(0.9)
        self.hl_color =  QColor('lightblue').lighter(120)
        self.qt18720 = False

        if ((parent.settings.value("qt18720"))=='2'):
            self.qt18720 = True
        else:
            self.qt18720 = False

        # Brace matching
        self.bracepos = None




        # Init scroller and area which are tricky hack to speed scrolling
#        try:
#            scroller = self.property("kineticScroller")
#            scroller.setEnabled(True)
#        except:
#            print 'Cannot instance kineticScroller'


        #Plugin init moved to editor_window.py
        #initialization init of plugin system
        #Maybe be not the best place to do it ...
        #init_plugin_system({'plugin_path': '/home/opt/khteditor/plugins',
        #                    'plugins': ['autoindent']})

        #If we have a filename
        self.filename = filename
        if (self.filename == None) or (self.filename == ''):
            self.filename = u'Unnamed.txt'
        self.document().setModified(False)
        parent.setWindowTitle(self.filename)

        #Set no wrap
        if (bool(parent.settings.value("WrapLine"))):
            self.setLineWrapMode( QPlainTextEdit.NoWrap)
        else:
            self.setLineWrapMode( QPlainTextEdit.WidgetWidth)

        font =  QFont()
        try:
            if parent.settings.contains('FontName'):
                font.setFamily(parent.settings.value('FontName'))
            else:
                font.setFamily("Courier")
        except:
            font.setFamily("Courier")

        #Get Font Size
        try:
            if parent.settings.contains('FontSize'):
                font.setPointSize(int(parent.settings.value('FontSize')))
            else:
                font.setPointSize(11)
        except:
            font.setPointSize(11)

        #Set Font
        self.fmetrics = QFontMetrics(font)
        self.document().setDefaultFont(font)

        #Remove auto capitalization
        self.setInputMethodHints(Qt.ImhNoAutoUppercase)

        #Keep threaded plugins references to avoid them to be garbage collected
        self.threaded_plugins = []
        self.enabled_plugins = parent.enabled_plugins

        #Current Line highlight and Bracket matcher
        self.cursorPositionChanged.connect(self.curPositionChanged)
        self.textChanged.connect(self.textEditChanged)
        # Brackets ExtraSelection ...

    def detectLanguage(self,filename):
        for extension,lang in LANGUAGES:
            if filename.endswith(extension.lower()):
                return lang
        return None

    def loadHighlighter(self,filename=None):
        filename = self.filename
        language = self.detectLanguage(filename)
        #Return None if language not yet implemented natively in KhtEditor
        if language == 'python':
            self.show_progress.emit(True)
            QApplication.processEvents()
            from syntax.python_highlighter import Highlighter
            self.highlighter = Highlighter(self.document())
            QApplication.processEvents()
            self.show_progress.emit(False)
        elif (language != None) and (language != 'None'):
            self.show_progress.emit(True)
            QApplication.processEvents()
            from syntax.generic_highlighter import Highlighter
            self.highlighter = Highlighter(self.document(),language)
            QApplication.processEvents()
            self.show_progress.emit(False)
        else:
            self.show_progress.emit(True)
            QApplication.processEvents()
            from syntax import pygments_highlighter
            self.highlighter = \
                pygments_highlighter.Highlighter(self.document(),
                                                 unicode(filename))
            QApplication.processEvents()
            self.show_progress.emit(False)

    def textEditChanged(self):
        if self.scroller:
            #Resize
            doc = self.document()
            s = doc.size().toSize()
            s.setHeight((s.height() + 1) * (self.fmetrics.lineSpacing()+1) )
            fr = self.frameRect()
            cr = self.contentsRect()
            self.setMinimumHeight(max(70, s.height() +  (fr.height() - cr.height() - 1)))
            self.setMinimumWidth(max(240,s.width() + (fr.width()-cr.width()) - 1))

#    Remove ensureVisible Hack which is now fixed in qt 4.7.2
#    def ensureVisible(self,pos,xmargin,ymargin):
#
#        visible = self.area.viewport().size()
#        currentPos =  QPoint(self.area.horizontalScrollBar().value(),
#                      self.area.verticalScrollBar().value())
#        posRect =  QRect(pos.x()-xmargin, pos.y()-ymargin,2*xmargin,2*ymargin)
#        visibleRect =  QRect(currentPos, visible)
#
#        if (visibleRect.contains(posRect)):
#            return
#
#        newPos = currentPos
#        if (posRect.top() < visibleRect.top()):
#            newPos.setY(posRect.top())
#        elif (posRect.bottom() > visibleRect.bottom()):
#            newPos.setY(posRect.bottom() - visible.height())
#        if (posRect.left() < visibleRect.left()):
#            newPos.setX(posRect.left())
#        elif (posRect.right() > visibleRect.right()):
#            newPos.setX(posRect.right() - visible.width())
#        self.scroller.scrollTo(newPos)


    def curPositionChanged(self):
        #Plugin hook
        for plugin in filter_plugins_by_capability('beforeCursorPositionChanged',self.enabled_plugins):
            plugin.do_beforeCursorPositionChanged(self)

        #Hilight current line
        #Workarround QTBUG-18720
        self.highlightCurrentLine()

        #Make sure cursor is visible
        #self.ensureCursorVisible()
        cursor = self.cursorRect()
        pos = cursor.center()
        #self.ensureVisible(pos.x(),pos.y(), 2*cursor.width()+20, 2*cursor.height())
        if self.scroller:
            self.scroller.ensureVisible(pos.x(),pos.y(),2*cursor.width()+20, 2*cursor.height())

    def match_left(self, block, character, start, found):
        map = {'{': '}', '(': ')', '[': ']'}
        block_jump = 0

        while block.isValid() and (block_jump < 20):
            data = block.userData()
            if data is not None:
                braces = data.braces
                N = len(braces)

                for k in range(start, N):
                    if braces[k].character == character:
                        found += 1

                    if braces[k].character == map[character]:
                        if not found:
                            return braces[k].position + block.position()
                        else:
                            found -= 1

                block = block.next()
                block_jump += 1
                start = 0

    def match_right(self, block, character, start, found):
        map = {'}': '{', ')': '(', ']': '['}
        block_jump = 0

        while block.isValid() and (block_jump < 20):
            data = block.userData()

            if data is not None:
                braces = data.braces

                if start is None:
                    start = len(braces)
                for k in range(start - 1, -1, -1):
                    if braces[k].character == character:
                        found += 1
                    if braces[k].character == map[character]:
                        if found == 0:
                            return braces[k].position + block.position()
                        else:
                            found -= 1
            block = block.previous()
            block_jump += 1
            start = None

    def check_brackets(self):
        left, right = QTextEdit.ExtraSelection(),\
                      QTextEdit.ExtraSelection()

        cursor = self.textCursor()
        block = cursor.block()
        data = block.userData()
        previous, next = None, None

        if data is not None:
            position = cursor.position()
            block_position = cursor.block().position()
            braces = data.braces
            N = len(braces)

            for k in range(0, N):
                if braces[k].position == position - block_position or\
                   braces[k].position == position - block_position - 1:
                    previous = braces[k].position + block_position
                    if braces[k].character in ['{', '(', '[']:
                        next = self.match_left(block,
                                               braces[k].character,
                                               k + 1, 0)
                    elif braces[k].character in ['}', ')', ']']:
                        next = self.match_right(block,
                                                braces[k].character,
                                                k, 0)
#                    if next is None:
#                        next = -1
        if (next is not None and next > 0) \
            and (previous is not None and previous > 0):

            format = QTextCharFormat()

            cursor.setPosition(previous)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('blue'))
            left.format = format
            left.cursor = cursor

            cursor.setPosition(next)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('blue'))
            right.format = format
            right.cursor = cursor

            return left, right

        elif previous is not None:
            format = QTextCharFormat()

            cursor.setPosition(previous)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('red'))
            left.format = format
            left.cursor = cursor
            return (left,)
        elif next is not None:
            format = QTextCharFormat()

            cursor.setPosition(next)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setForeground(QColor('white'))
            format.setBackground(QColor('red'))
            left.format = format
            left.cursor = cursor
            return (left,)

    #PySide Bug : The type of e is QEvent instead of QKeyEvent
    def keyPressEvent(self, event):
        """Intercept the key event to lets plugin do something if they want"""
        if event.type() ==  QEvent.KeyPress:
            for plugin in filter_plugins_by_capability('beforeKeyPressEvent',self.enabled_plugins):
                plugin.do_beforeKeyPressEvent(self,event)
            QPlainTextEdit.keyPressEvent(self, event)
            for plugin in filter_plugins_by_capability('afterKeyPressEvent',self.enabled_plugins):
                plugin.do_afterKeyPressEvent(self,event)

    def closeEvent(self,event):
        """Catch the close event and ask to save if document is modified"""
        answer = self.document().isModified() and \
        QMessageBox.question(self,
               "Text Editor - Unsaved Changes",
               "Save unsaved changes in %s?" % self.filename,
               QMessageBox.Yes| QMessageBox.No| QMessageBox.Close)
        if answer ==  QMessageBox.Yes:
            try:
                self.save()
                event.accept()
            except (IOError, OSError), ioError:
                QMessageBox.warning(self, "Text Editor -- Save Error",
                        "Failed to save %s: %s" % (self.filename, ioError))
                event.ignore()
        elif answer ==  QMessageBox.Close:
            return event.ignore()
Пример #17
0
    def paint (self, painter, option, index):
        '''
        QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index
        '''

        orntnDelegate = self.chooseOrientationDelegate()
        
        painter.save()

        if option.state & QStyle.State_Selected:
            borderPen = QPen(Qt.blue)
            borderPen.setWidth(3)
            nameBgColors = [Qt.white, Qt.yellow]
        else:
            borderPen = QPen(Qt.lightGray)
            lightBlue = QColor(0, 0, 255).lighter(180)
            nameBgColors = [Qt.white, lightBlue]

        # Set default font and color
        itemRect = option.rect
        painter.fillRect(itemRect, Qt.white)
        painter.setFont(orntnDelegate.getNameFont())
        painter.setPen(Qt.black)

        m = index.model()

        ticker = m.data(index, PositionsModel.ROLE_TICKER)
        companyName = m.data(index, Qt.DisplayRole)
        line2 = m.data(index, PositionsModel.ROLE_CURRENT_PRICE)
        line3 = m.data(index, PositionsModel.ROLE_CHANGE)

        fontMetricsCompanyName = QFontMetrics(orntnDelegate.getNameFont())
        fontMetricsTicker = QFontMetrics(orntnDelegate.getTickerFont())
        fontMetricsCurrentPrice = QFontMetrics(orntnDelegate.getCurrentPriceFont())
        fontMetricsChange = QFontMetrics(orntnDelegate.getChangeFont())
        lineSp1 = fontMetricsCompanyName.lineSpacing()
        lineSp2 = fontMetricsCurrentPrice.lineSpacing()
        lineSp3 = fontMetricsChange.lineSpacing()

        # Company Name    (EXCHANGE:SYMBOL)
        textRectShade = QRect(itemRect.left(),
                              itemRect.top(),
                              itemRect.width(),
                              self.MARGIN + lineSp1 + self.MARGIN)
        gradient = self.createLinearGradient(textRectShade,
                                             nameBgColors[0],
                                             nameBgColors[1])
        painter.fillRect(textRectShade, gradient)
        textRect = QRect(itemRect.left() + self.MARGIN, itemRect.top() + self.MARGIN,
                         itemRect.width() - 2 * self.MARGIN, lineSp1 + self.MARGIN)
        painter.setFont(orntnDelegate.getNameFont())
        # Shorten the company name such that long company names are not written on top of the ticker
        tickerTextW = fontMetricsTicker.width(ticker)
        companyNameTextW = textRect.width() - tickerTextW - 2 * self.MARGIN
        companyName = fontMetricsCompanyName.elidedText(companyName, Qt.ElideRight, companyNameTextW)
        painter.drawText(textRect, Qt.AlignVCenter | Qt.AlignLeft, companyName)
        painter.setFont(orntnDelegate.getTickerFont())
        painter.drawText(textRect, Qt.AlignVCenter | Qt.AlignRight, "(%s)" % (ticker))

        # Current price
        painter.setFont(orntnDelegate.getCurrentPriceFont())
        textRect.adjust(0, lineSp1 + self.MARGIN, 0, lineSp2 + self.MARGIN)
        painter.drawText(textRect, Qt.AlignTop | Qt.AlignLeft, line2)

        rightColRect = QRect(textRect.left(), textRect.top(),
                             textRect.width(), textRect.height())

        # Change
        ccol = m.data(index, PositionsModel.ROLE_CHANGE_COLOR)
        if ccol == "chg":
            painter.setPen(QPen(Qt.darkGreen))
        elif ccol == "chr":
            painter.setPen(QPen(Qt.red))
        painter.setFont(orntnDelegate.getChangeFont())
        textRect.adjust(0, lineSp2 + self.MARGIN, 0, lineSp3 + self.MARGIN)
        painter.drawText(textRect, Qt.AlignTop | Qt.AlignLeft, line3)

        '''
        Right Column
        '''

        orntnDelegate.paintRightCol(index, painter, rightColRect)

        painter.setPen(borderPen)
        painter.drawRect(itemRect)

        painter.restore()