def __init__(self): super(ColorChooser, self).__init__(None) self.colors = KColorCells(self, 1, 1) self.colors.setAcceptDrags(False) self.colors.setEditTriggers(self.colors.NoEditTriggers) self.otherBtn = KPushButton(self) self.otherBtn.setText(i18nc('@action:button', '&Other...')) layout = QVBoxLayout(self) layout.addWidget(self.colors) layout.addWidget(self.otherBtn) self.setFocusPolicy(Qt.StrongFocus) self.setFrameShape(QFrame.Panel) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) # Set default value for last used #color if not configured yet if ColorChooser._INSERT_COLOR_LCC not in kate.sessionConfiguration: kate.sessionConfiguration[ColorChooser._INSERT_COLOR_LCC] = '#ffffff' # Subscribe to observe widget events # - open KColorDialog on 'Other...' button click self.otherBtn.clicked.connect(self._show_color_dialog) # - select color by RMB click or ENTER on keyboard self.colors.cellActivated.connect(self._color_selected) # - self.colorSelected.connect(self._insert_color_into_active_document) self.installEventFilter(self)
def __init__(self, parent): super(PaletteView, self).__init__(parent) self.toolView = kate.mainInterfaceWindow().createToolView( "color_tools_pate_plugin", kate.Kate.MainWindow.Bottom, kate.gui.loadIcon('color'), i18n("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 :( self.colorCellsWidget.setAcceptDrags(False) interior.verticalLayout.addWidget(self.colorCellsWidget) self.colorCellsWidget.colorSelected.connect(self.colorSelected) self.colorCellsWidget.colorDoubleClicked.connect( self.colorDoubleClicked)
def __init__(self, parent): super(ColorChooser, self).__init__(parent) self.colors = KColorCells(self, 1, 1) self.colors.setAcceptDrags(False) self.colors.setEditTriggers(self.colors.NoEditTriggers) self.otherBtn = KPushButton(self) self.otherBtn.setText(i18nc('@action:button', '&Other...')) layout = QVBoxLayout(self) layout.addWidget(self.colors) layout.addWidget(self.otherBtn) self.setFocusPolicy(Qt.StrongFocus) self.setFrameShape(QFrame.Panel) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup); # Subscribe to observe widget events # - open KColorDialog on 'Other...' button click self.otherBtn.clicked.connect(self.show_color_dialog) # - select color by RMB click or ENTER on keyboard self.colors.cellActivated.connect(self.color_selected) self.installEventFilter(self)
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 __init__(self, parent=None): KVBox.__init__(self, parent) self.help = QLabel(helpText, self) self.layout().setAlignment(self.help, Qt.AlignHCenter) hBox1 = KHBox(self) hBox1.setSpacing(10) hBox1.setMargin(40) colorButtonLabel = QLabel("KColorButton", hBox1) colorButton = KColorButton(hBox1) colorCellsLabel = QLabel("KColorCells", hBox1) colorCells = KColorCells(hBox1, 1, 8) colorCells.setMaximumSize(160, 20) colorCells.setColor(0, Qt.black) colorCells.setColor(1, Qt.red) colorCells.setColor(2, Qt.yellow) colorCells.setColor(3, Qt.blue) colorCells.setColor(4, Qt.darkGreen) colorCells.setColor(5, Qt.magenta) colorCells.setColor(6, Qt.gray) colorCells.setColor(7, Qt.white) colorComboLabel = QLabel("KColorCombo", hBox1) colorCombo = KColorCombo(hBox1) colorList = [ Qt.black, Qt.red, Qt.yellow, Qt.blue, Qt.darkGreen, Qt.magenta, Qt.gray, Qt.white ] colorCombo.setColors(colorList) colorCombo.setMaximumWidth(80) hBox2 = KHBox(self) hBox2.setSpacing(10) self.layout().setAlignment(hBox2, Qt.AlignHCenter | Qt.AlignTop) self.setStretchFactor(hBox2, 1) colorPatchLabel = QLabel("KColorPatch", hBox2) hBox2.layout().setAlignment(colorPatchLabel, Qt.AlignHCenter) self.colorPatch = KColorPatch(hBox2) self.colorPatch.setFixedSize(40, 40) hBox2.layout().setAlignment(self.colorPatch, Qt.AlignHCenter) self.colorPatch.setColor(Qt.red) self.colorPatch.show() self.connect(colorButton, SIGNAL("changed (const QColor&)"), self.colorPatch.setColor) self.connect(colorCells, SIGNAL("colorSelected (int, const QColor&)"), self.colorCellSelected) self.connect(colorCombo, SIGNAL("activated (const QColor&)"), self.colorPatch.setColor)
class PaletteView(QObject): """A toolvide 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, kate.gui.loadIcon('color'), i18n("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 :( self.colorCellsWidget.setAcceptDrags(False) 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""" self.colors = list() # 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 or c in string.ascii_letters): 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)) print('PALETTE VIEW: Found %s' % 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(math.sqrt(len(self.colors))) rows = int(len(self.colors) / columns) + int( bool(len(self.colors) % 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) @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()
class ColorChooser(QFrame): ''' Completion-like widget to quick select hexadecimal colors used in a document TODO Make cell/widget size configurable? ''' colorSelected = pyqtSignal(QColor) def __init__(self, parent): super(ColorChooser, self).__init__(parent) self.colors = KColorCells(self, 1, 1) self.colors.setAcceptDrags(False) self.colors.setEditTriggers(self.colors.NoEditTriggers) self.otherBtn = KPushButton(self) self.otherBtn.setText(i18nc('@action:button', '&Other...')) layout = QVBoxLayout(self) layout.addWidget(self.colors) layout.addWidget(self.otherBtn) self.setFocusPolicy(Qt.StrongFocus) self.setFrameShape(QFrame.Panel) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup); # Subscribe to observe widget events # - open KColorDialog on 'Other...' button click self.otherBtn.clicked.connect(self.show_color_dialog) # - select color by RMB click or ENTER on keyboard self.colors.cellActivated.connect(self.color_selected) self.installEventFilter(self) def setColors(self, colors): if len(colors): rows, columns = _calc_dimensions_for_items_count(len(colors)) else: self.hide() self.show_color_dialog(True) return self.colors.setColumnCount(columns) self.colors.setRowCount(rows) self.colors.setMinimumSize(20 * columns, 25 * rows) self.updateGeometry() self.adjustSize() self.colors.resizeColumnsToContents() self.colors.resizeRowsToContents() # Fill color cells for i, color in enumerate(colors): self.colors.setColor(i, color) _set_tooltips(rows, columns, self.colors) # Set tooltips for all valid color cells self.colors.setFocus() # Give a focus to widget self.show() # Show it! @pyqtSlot(bool) def show_color_dialog(self, f): '''Get color using KColorDialog''' # Preselect last used color color = QColor(kate.sessionConfiguration[_INSERT_COLOR_LCC]) result = KColorDialog.getColor(color) if result == KColorDialog.Accepted: # Did user press OK? self.emitSelectedColorHideSelf(color) @pyqtSlot(int, int) def color_selected(self, row, column): '''Smth has selected in KColorCells''' color = self.colors.item(row, column).data(Qt.BackgroundRole) #kate.kDebug('ColorUtils: activated row={}, column={}, color={}'.format(row, column, color)) self.emitSelectedColorHideSelf(color) def emitSelectedColorHideSelf(self, color): # Remember last selected color for future preselect kate.sessionConfiguration[_INSERT_COLOR_LCC] = color.name() self.colorSelected.emit(color) self.hide() def eventFilter(self, obj, event): '''Hide self on Esc key''' if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Escape: self.hide() return True return super(ColorChooser, self).eventFilter(obj, event) def moveAround(self, position): '''Smart positioning self around cursor''' self.colors.resizeColumnsToContents() self.colors.resizeRowsToContents() mwg = kate.mainWindow().geometry() wc = mwg.center() pos = mwg.topLeft() + position pos.setY(pos.y() + 40) if wc.y() < pos.y(): pos.setY(pos.y() - self.height()) if wc.x() < pos.x(): pos.setX(pos.x() - self.width()) self.move(pos)
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()
def __init__(self, parent=None): KVBox.__init__(self, parent) self.help = QLabel (helpText, self) self.layout ().setAlignment (self.help, Qt.AlignHCenter) hBox1 = KHBox (self) hBox1.setSpacing (10) hBox1.setMargin (40) colorButtonLabel = QLabel ("KColorButton", hBox1) colorButton = KColorButton (hBox1) colorCellsLabel = QLabel ("KColorCells", hBox1) colorCells = KColorCells (hBox1, 1, 8) colorCells.setMaximumSize (160, 20) colorCells.setColor (0, Qt.black) colorCells.setColor (1, Qt.red) colorCells.setColor (2, Qt.yellow) colorCells.setColor (3, Qt.blue) colorCells.setColor (4, Qt.darkGreen) colorCells.setColor (5, Qt.magenta) colorCells.setColor (6, Qt.gray) colorCells.setColor (7, Qt.white) colorComboLabel = QLabel ("KColorCombo", hBox1) colorCombo = KColorCombo (hBox1) colorList = [Qt.black, Qt.red, Qt.yellow, Qt.blue, Qt.darkGreen, Qt.magenta, Qt.gray, Qt.white] colorCombo.setColors (colorList) colorCombo.setMaximumWidth (80) hBox2 = KHBox (self) hBox2.setSpacing (10) self.layout ().setAlignment (hBox2, Qt.AlignHCenter | Qt.AlignTop) self.setStretchFactor (hBox2, 1) colorPatchLabel = QLabel ("KColorPatch", hBox2) hBox2.layout ().setAlignment (colorPatchLabel, Qt.AlignHCenter) self.colorPatch = KColorPatch (hBox2) self.colorPatch.setFixedSize (40, 40) hBox2.layout ().setAlignment (self.colorPatch, Qt.AlignHCenter) self.colorPatch.setColor (Qt.red) self.colorPatch.show () self.connect (colorButton, SIGNAL ("changed (const QColor&)"), self.colorPatch.setColor) self.connect (colorCells, SIGNAL ("colorSelected (int, const QColor&)"), self.colorCellSelected) self.connect (colorCombo, SIGNAL ("activated (const QColor&)"), self.colorPatch.setColor)
class ColorChooser(QFrame): ''' Completion-like widget to quick select hexadecimal colors used in a document TODO Make cell/widget size configurable? ''' _INSERT_COLOR_LCC = 'insertColor:lastUsedColor' colorSelected = pyqtSignal(QColor) def __init__(self): super(ColorChooser, self).__init__(None) self.colors = KColorCells(self, 1, 1) self.colors.setAcceptDrags(False) self.colors.setEditTriggers(self.colors.NoEditTriggers) self.otherBtn = KPushButton(self) self.otherBtn.setText(i18nc('@action:button', '&Other...')) layout = QVBoxLayout(self) layout.addWidget(self.colors) layout.addWidget(self.otherBtn) self.setFocusPolicy(Qt.StrongFocus) self.setFrameShape(QFrame.Panel) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) # Set default value for last used #color if not configured yet if ColorChooser._INSERT_COLOR_LCC not in kate.sessionConfiguration: kate.sessionConfiguration[ColorChooser._INSERT_COLOR_LCC] = '#ffffff' # Subscribe to observe widget events # - open KColorDialog on 'Other...' button click self.otherBtn.clicked.connect(self._show_color_dialog) # - select color by RMB click or ENTER on keyboard self.colors.cellActivated.connect(self._color_selected) # - self.colorSelected.connect(self._insert_color_into_active_document) self.installEventFilter(self) def __del__(self): mw = kate.mainInterfaceWindow() if mw: self.blockSignals(True) self.removeEventFilter(self) def updateColors(self, document): '''Scan a given document and collect unique colors Returns a list of QColor objects. ''' result = [] # 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 or c in string.ascii_letters): break end += 1 color_range = KTextEditor.Range(l, start, l, end) color_str = document.text(color_range) color = QColor(color_str) if color.isValid() and color not in result: result.append(color) kate.kDebug('ColorUtils: scan for #colors found {}'.format(color_str)) start = end self._set_colors(result) def moveAround(self, position): '''Smart positioning self around cursor''' self.colors.resizeColumnsToContents() self.colors.resizeRowsToContents() mwg = kate.mainWindow().geometry() wc = mwg.center() pos = mwg.topLeft() + position pos.setY(pos.y() + 40) if wc.y() < pos.y(): pos.setY(pos.y() - self.height()) if wc.x() < pos.x(): pos.setX(pos.x() - self.width()) self.move(pos) def emitSelectedColorHideSelf(self, color): # Remember last selected color for future preselect kate.sessionConfiguration[ColorChooser._INSERT_COLOR_LCC] = color.name() self.colorSelected.emit(color) self.hide() def eventFilter(self, obj, event): '''Hide self on Esc key''' if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Escape: self.hide() return True return super(ColorChooser, self).eventFilter(obj, event) def _set_colors(self, colors): if len(colors): rows, columns = ColorChooser._calc_dimensions_for_items_count(len(colors)) else: self.hide() self._show_color_dialog(True) return self.colors.setColumnCount(columns) self.colors.setRowCount(rows) self.colors.setMinimumSize(20 * columns, 25 * rows) self.updateGeometry() self.adjustSize() self.colors.resizeColumnsToContents() self.colors.resizeRowsToContents() # Fill color cells for i, color in enumerate(colors): self.colors.setColor(i, color) setTooltips(rows, columns, self.colors) # Set tooltips for all valid color cells self.colors.setFocus() # Give a focus to widget self.show() # Show it! @pyqtSlot(bool) def _show_color_dialog(self, f): '''Get color using KColorDialog''' # Preselect last used color color = QColor(kate.sessionConfiguration[ColorChooser._INSERT_COLOR_LCC]) result = KColorDialog.getColor(color) if result == KColorDialog.Accepted: # Did user press OK? self.emitSelectedColorHideSelf(color) @pyqtSlot(int, int) def _color_selected(self, row, column): '''Smth has selected in KColorCells''' color = self.colors.item(row, column).data(Qt.BackgroundRole) #kate.kDebug('ColorUtils: activated row={}, column={}, color={}'.format(row, column, color)) self.emitSelectedColorHideSelf(color) @pyqtSlot(QColor) def _insert_color_into_active_document(self, color): color_str = color.name() # Get it as color string #kate.kDebug('ColorUtils: selected color: {}'.format(color_str)) document = kate.activeDocument() view = kate.activeView() has_selection = view.selection() # Remember current selection state color_range = ColorChooser._get_color_range_under_cursor(view) document.startEditing() document.replaceText(color_range, color_str) # Replace selected/found range w/ a new text document.endEditing() # Select just entered #color, if something was selected before if has_selection: start_pos = color_range.start() view.setSelection(KTextEditor.Range(start_pos, len(color_str))) @staticmethod def _calc_dimensions_for_items_count(count): '''Recalculate rows/columns of table view for given items count''' rows = int(math.sqrt(count)) columns = int(count / rows) + int(bool(count % rows)) return (rows, columns) @staticmethod def _get_color_range_under_cursor(view): assert(view is not None) if view.selection(): # Some text selected, just use it as input... color_range = view.selectionRange() else: # If no selection, try to get a #color under cursor color_range = common.getBoundTextRangeSL( common.IDENTIFIER_BOUNDARIES - {'#'} , common.IDENTIFIER_BOUNDARIES , view.cursorPosition() , view.document() ) # Check if a word under cursor is a valid #color color = QColor(view.document().text(color_range)) if not color.isValid(): color_range = KTextEditor.Range(view.cursorPosition(), view.cursorPosition()) return color_range
def setupUi(self): self.centralwidget = QtGui.QWidget(self) self.scanButton = KPushButton() self.nColorLabel = QtGui.QLabel() self.numColorSlider = QtGui.QSlider(Qt.Horizontal) self.numColorSlider.setMinimum(2) self.numColorSlider.setTracking(False) self.resetColorsButton = KPushButton() scanSettingsLayout = QtGui.QHBoxLayout() scanSettingsLayout.addWidget(self.scanButton) scanSettingsLayout.addWidget(self.numColorSlider) scanSettingsLayout.addWidget(self.nColorLabel) scanSettingsLayout.addWidget(self.resetColorsButton) colorSpacerLeft = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.colorEditorCells = KColorCells(self.centralwidget, 16, 16) colorSpacerRight = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) colorEditorLayout = QtGui.QHBoxLayout() colorEditorLayout.addItem(colorSpacerLeft) colorEditorLayout.addWidget(self.colorEditorCells, 0) colorEditorLayout.addItem(colorSpacerRight) self.previewView = ResizableImageLabel(self.centralwidget) self.previewView.setMinimumSize(QtCore.QSize(400, 400)) self.baseFileNameRequester = KUrlRequester(self.centralwidget) self.FileSeqSpinBox = KIntSpinBox(self.centralwidget) filenameLayout = QtGui.QHBoxLayout() filenameLayout.addWidget(self.baseFileNameRequester) filenameLayout.addWidget(self.FileSeqSpinBox) self.generatedOutputNameTextLabel = QtGui.QLabel(self.centralwidget) self.generatedOutputNameLabel = QtGui.QLabel(self.centralwidget) outputNameLayout = QtGui.QHBoxLayout() outputNameLayout.addWidget(self.generatedOutputNameLabel) outputNameLayout.addWidget(self.generatedOutputNameTextLabel) spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.saveButton = KPushButton(self.centralwidget) saveButtonLayout = QtGui.QHBoxLayout() saveButtonLayout.addItem(spacerItem1) saveButtonLayout.addWidget(self.saveButton) verticalLayout = QtGui.QVBoxLayout(self.centralwidget) verticalLayout.setMargin(0) verticalLayout.addLayout(scanSettingsLayout, 0) verticalLayout.addLayout(colorEditorLayout, 0) verticalLayout.addWidget(self.previewView, 1) verticalLayout.addLayout(filenameLayout, 0) verticalLayout.addLayout(outputNameLayout, 0) verticalLayout.addLayout(saveButtonLayout, 0) self.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(self) self.menubar.setGeometry(QtCore.QRect(0, 0, 474, 20)) self.menuFile = QtGui.QMenu(self.menubar) self.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(self) self.statusbar.setMinimumSize(QtCore.QSize(0, 20)) self.setStatusBar(self.statusbar) self.actionQuit = QtGui.QAction(self) self.menuFile.addAction(self.actionQuit) self.menubar.addAction(self.menuFile.menuAction()) self.retranslateUi()
class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.scanned_image = None self.scanned_pil = None self.colors = None self.setupUi() self.saveButton.clicked.connect(self.close) self.actionQuit.activated.connect(self.close) self.scanButton.clicked.connect(self.scan) self.resetColorsButton.clicked.connect(self.resetColors) self.numColorSlider.valueChanged.connect(self.updateNumColors) self.connect(self.previewView, SIGNAL("resize()"), self.updatePreview) def setupUi(self): self.centralwidget = QtGui.QWidget(self) self.scanButton = KPushButton() self.nColorLabel = QtGui.QLabel() self.numColorSlider = QtGui.QSlider(Qt.Horizontal) self.numColorSlider.setMinimum(2) self.numColorSlider.setTracking(False) self.resetColorsButton = KPushButton() scanSettingsLayout = QtGui.QHBoxLayout() scanSettingsLayout.addWidget(self.scanButton) scanSettingsLayout.addWidget(self.numColorSlider) scanSettingsLayout.addWidget(self.nColorLabel) scanSettingsLayout.addWidget(self.resetColorsButton) colorSpacerLeft = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.colorEditorCells = KColorCells(self.centralwidget, 16, 16) colorSpacerRight = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) colorEditorLayout = QtGui.QHBoxLayout() colorEditorLayout.addItem(colorSpacerLeft) colorEditorLayout.addWidget(self.colorEditorCells, 0) colorEditorLayout.addItem(colorSpacerRight) self.previewView = ResizableImageLabel(self.centralwidget) self.previewView.setMinimumSize(QtCore.QSize(400, 400)) self.baseFileNameRequester = KUrlRequester(self.centralwidget) self.FileSeqSpinBox = KIntSpinBox(self.centralwidget) filenameLayout = QtGui.QHBoxLayout() filenameLayout.addWidget(self.baseFileNameRequester) filenameLayout.addWidget(self.FileSeqSpinBox) self.generatedOutputNameTextLabel = QtGui.QLabel(self.centralwidget) self.generatedOutputNameLabel = QtGui.QLabel(self.centralwidget) outputNameLayout = QtGui.QHBoxLayout() outputNameLayout.addWidget(self.generatedOutputNameLabel) outputNameLayout.addWidget(self.generatedOutputNameTextLabel) spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.saveButton = KPushButton(self.centralwidget) saveButtonLayout = QtGui.QHBoxLayout() saveButtonLayout.addItem(spacerItem1) saveButtonLayout.addWidget(self.saveButton) verticalLayout = QtGui.QVBoxLayout(self.centralwidget) verticalLayout.setMargin(0) verticalLayout.addLayout(scanSettingsLayout, 0) verticalLayout.addLayout(colorEditorLayout, 0) verticalLayout.addWidget(self.previewView, 1) verticalLayout.addLayout(filenameLayout, 0) verticalLayout.addLayout(outputNameLayout, 0) verticalLayout.addLayout(saveButtonLayout, 0) self.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(self) self.menubar.setGeometry(QtCore.QRect(0, 0, 474, 20)) self.menuFile = QtGui.QMenu(self.menubar) self.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(self) self.statusbar.setMinimumSize(QtCore.QSize(0, 20)) self.setStatusBar(self.statusbar) self.actionQuit = QtGui.QAction(self) self.menuFile.addAction(self.actionQuit) self.menubar.addAction(self.menuFile.menuAction()) self.retranslateUi() def retranslateUi(self): self.setWindowTitle(kdecore.i18n(_fromUtf8("MainWindow"))) self.scanButton.setText(kdecore.i18n(_fromUtf8("Scan"))) self.resetColorsButton.setText(kdecore.i18n(_fromUtf8("Reset"))) self.generatedOutputNameTextLabel.setText(kdecore.i18n(_fromUtf8("Output:"))) self.generatedOutputNameLabel.setText(kdecore.i18n(_fromUtf8("generated_output_file_name"))) self.saveButton.setText(kdecore.i18n(_fromUtf8("Save"))) self.menuFile.setTitle(kdecore.i18n(_fromUtf8("File"))) self.actionQuit.setText(kdecore.i18n(_fromUtf8("Quit"))) def showInfo(self): size = self.scanned_pil.size mode = self.scanned_pil.mode info = self.scanned_pil.info self.statusbar.showMessage('Size: "%dx%d", Mode: "%s, Info: "%s"' % (size[0], size[1], mode, info)) def scan(self): self.scanned_pil = self.device.scan() self.scanned_pil = crop(self.scanned_pil) self.scanned_pil = self.scanned_pil.convert("L") self.scanned_image = ImageQt.ImageQt(self.scanned_pil) self.showInfo() self.colors = grayscale() self.colors_orig = deepcopy(self.colors) n_color, self.histo = self.createHistogram() for i, c in enumerate(self.colors): self.scanned_image.setColor(i, c.rgba()) self.numColorSlider.setMaximum(n_color) self.numColorSlider.setValue(n_color) self.showImage() def showImage(self): self.updateColorCells() self.updatePreview() def updatePreview(self): if self.scanned_image: for i, c in enumerate(self.colors): self.scanned_image.setColor(i, c.rgba()) scaled_image = self.scanned_image.scaled(self.previewView.size(), aspectRatioMode=QtCore.Qt.KeepAspectRatio) pm = QtGui.QPixmap.fromImage(scaled_image) self.previewView.setPixmap(pm) def updateColorCells(self): for i, (ci, freq) in enumerate(self.histo): c = self.colors[ci] if freq else QtGui.QColor() self.colorEditorCells.setColor(i, c) def updateColorCells_flat(self): for i in range(256): c = self.colors[i] self.colorEditorCells.setColor(i, c) def updateNumColors(self): self.reduceColors(self.numColorSlider.value()) self.nColorLabel.setText("%3d" % self.numColorSlider.value()) self.updateColorCells() def createHistogram(self): histo = self.scanned_pil.histogram()[:256] log.debug("Histogram (%d entries): %s" % (len(histo), histo)) histo = zip(range(len(histo)), histo) histo.sort(key=lambda x: -x[1]) log.debug("Histogram zipped and sorted: %s" % histo) return len([ci for (ci, frequency) in histo if frequency > 0]), histo def reduceColors(self, num): if self.scanned_pil: log.info("Removing unimportant colors down to %3d" % num) self.colors = deepcopy(self.colors_orig) color_steps = self.numColorSlider.value() - 1 ref_colors = [QtGui.QColor(c, c, c) for c in range(0, 255, 256 / color_steps)] ref_colors.append(QtGui.QColor(255, 255, 255)) log.debug("Reference colors are: %s" % [str(c.name()) for c in ref_colors]) for color_index, dummy_frequency in self.histo: color = self.colors[color_index] distances = [] for ref_color in ref_colors: distances.append(dist(ref_color, color)) nearest = min(range(len(distances)), key=distances.__getitem__) nearest_color = ref_colors[nearest] self.colors[color_index] = nearest_color log.debug("Colors now %d: %s" % (len(self.colors), ",".join([str(c.name()) for c in self.colors]))) self.updateColorCells() self.updatePreview() def resetColors(self): log.info("resetColors") self.numColorSlider.setValue(self.numColorSlider.maximum()) self.colors = deepcopy(self.colors_orig) self.updateColorCells() self.updatePreview()