Пример #1
0
class PaletteView(QObject):
    '''A toolview to display palette of the current document'''
    colors = []
    toolView = None
    colorCellsWidget = None

    def __init__(self, parent):
        super(PaletteView, self).__init__(parent)
        self.toolView = kate.mainInterfaceWindow().createToolView(
            'color_tools_pate_plugin'
          , kate.Kate.MainWindow.Bottom
          , KIcon('color').pixmap(32, 32)
          , i18nc('@title:tab', 'Palette')
          )
        self.toolView.installEventFilter(self)
        # By default, the toolview has box layout, which is not easy to delete.
        # For now, just add an extra widget.
        top = QWidget(self.toolView)
        # Set up the user interface from Designer.
        interior = uic.loadUi(os.path.join(os.path.dirname(__file__), 'color_tools_toolview.ui'), top)
        interior.update.clicked.connect(self.update)
        self.colorCellsWidget = KColorCells(interior, 1, 1)
        # TODO Don't know how to deal w/ drag-n-drops :(
        # It seems there is no signal to realize that some item has changed :(
        # (at lieast I didn't find it)
        self.colorCellsWidget.setAcceptDrags(False)
        self.colorCellsWidget.setEditTriggers(self.colorCellsWidget.NoEditTriggers)
        interior.verticalLayout.addWidget(self.colorCellsWidget)
        self.colorCellsWidget.colorSelected.connect(self.colorSelected)
        self.colorCellsWidget.colorDoubleClicked.connect(self.colorDoubleClicked)

    #def __del__(self):
        #'''Plugins that use a toolview need to delete it for reloading to work.'''
        #if self.toolView:
            #self.toolView.deleteLater()
            #self.toolView = None

    def eventFilter(self, obj, event):
        '''Hide the Palette tool view on ESCAPE key'''
        if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Escape:
            kate.mainInterfaceWindow().hideToolView(self.toolView)
            return True
        return self.toolView.eventFilter(obj, event)

    def updateColors(self, view=None):
        '''Scan a document for #colors

            Returns a list of tuples: QColor and range in a document
            TODO Some refactoring needed to reduce code duplication
            (@sa _get_color_range_under_cursor())
        '''
        self.colors = []                                    # Clear previous colors
        if view:
            document = view.document()
        else:
            try:
                document = kate.activeDocument()
            except kate.NoActiveView:
                return                                      # Do nothing if we can't get a current document
        # Iterate over document's lines trying to find #colors
        for l in range(0, document.lines()):
            line = document.line(l)                         # Get the current line
            start = 0                                       # Set initial position to 0 (line start)
            while start < len(line):                        # Repeat 'till the line end
                start = line.find('#', start)               # Try to find a '#' character (start of #color)
                if start == -1:                             # Did we found smth?
                    break                                   # No! Nothing to do...
                # Try to get a word right after the '#' char
                end = start + 1
                for c in line[end:]:
                    if not (c in string.hexdigits):
                        break
                    end += 1
                color_range = KTextEditor.Range(l, start, l, end)
                color_str = document.text(color_range)
                color = QColor(color_str)
                if color.isValid():
                    self.colors.append(ColorRangePair(color, color_range))
                    kate.kDebug('ColorUtilsToolView: scan for #colors found {}'.format(color_str))
                start = end

    def updateColorCells(self):
        '''Calculate rows*columns and fill the cells w/ #colors'''
        if len(self.colors):
            # Recalculate rows/columns
            columns = int(self.colorCellsWidget.width() / 30)
            visible_rows = int(self.colorCellsWidget.height() / 25)
            if len(self.colors) < (columns * visible_rows):
                rows = visible_rows
            else:
                visible_cells = columns * visible_rows
                rest = len(self.colors) - visible_cells
                rows = visible_rows + int(rest / columns) + int(bool(rest % columns))
        else:
            columns = 1
            rows = 1
            self.colors.append(ColorRangePair(QColor(), KTextEditor.Range()))
        self.colorCellsWidget.setColumnCount(columns)
        self.colorCellsWidget.setRowCount(rows)
        self.colorCellsWidget.resizeColumnsToContents()
        self.colorCellsWidget.resizeRowsToContents()
        # Fill color cells
        for i, crp in enumerate(self.colors):
            self.colorCellsWidget.setColor(i, crp.color)
        for i in range(len(self.colors), columns * rows):
            self.colorCellsWidget.setColor(i, QColor())
        _set_tooltips(rows, columns, self.colorCellsWidget)


    @pyqtSlot()
    def update(self, view=None):
        self.updateColors(view)
        self.updateColorCells()


    @pyqtSlot(int, QColor)
    def colorSelected(self, idx, color):
        '''Move cursor to the position of the selected #color and select the range'''
        view = kate.activeView()
        view.setCursorPosition(self.colors[idx].color_range.start())
        view.setSelection(self.colors[idx].color_range)


    @pyqtSlot(int, QColor)
    def colorDoubleClicked(self, idx, color):
        '''Edit selected color on double click'''
        insertColor()
        self.update()