def _paste(self): clipboard = QApplication.clipboard() md = clipboard.mimeData() items = md.instance() if items is not None: editor = self._editor model = editor.model insert_mode = 'after' selection = self.selectedIndexes() if len(selection): offset = 1 if insert_mode == 'after' else 0 idx = selection[-1].row() + offset else: idx = len(editor.value) if self._cut_indices: if not any((ci <= idx for ci in self._cut_indices)): idx += len(self._cut_indices) model = editor.model for ci in self._cut_indices: model.removeRow(ci) self._cut_indices = None # paste_func = self.paste_func # if paste_func is None: # paste_func = lambda x: x.clone_traits() for ri, ci in reversed(items): model.insertRow(idx, obj=ci)
def _copy(self): rows = sorted({ri.row() for ri in self.selectedIndexes()}) copy_object = [(ri, self._editor.value[ri].tocopy()) for ri in rows] # copy_object = [ri.row(), self._editor.value[ri.row()]) for ri in self.selectedIndexes()] mt = self._editor.factory.mime_type try: pdata = dumps(copy_object) except BaseException as e: print('tabular editor copy failed') self._editor.value[rows[0]].tocopy(verbose=True) return qmd = PyMimeData() qmd.MIME_TYPE = mt qmd.setData(six.text_type(mt), dumps(copy_object.__class__) + pdata) clipboard = QApplication.clipboard() clipboard.setMimeData(qmd)
def _paste(self): clipboard = QApplication.clipboard() md = clipboard.mimeData() try: items = md.instance() except AttributeError: return if items is not None: editor = self._editor model = editor.model insert_mode = 'after' selection = self.selectedIndexes() if len(selection): offset = 1 if insert_mode == 'after' else 0 idx = selection[-1].row() + offset else: idx = len(editor.value) if self._cut_indices: if not any((ci <= idx for ci in self._cut_indices)): idx += len(self._cut_indices) model = editor.model for ci in self._cut_indices: model.removeRow(ci) self._cut_indices = None # paste_func = self.paste_func # if paste_func is None: # paste_func = lambda x: x.clone_traits() for ri, ci in reversed(items): model.insertRow(idx, obj=ci)
class _TableView(TableView): """ for drag and drop reference see https://github.com/enthought/traitsui/blob/master/traitsui/qt4/tree_editor.py """ paste_func = None drop_factory = None # link_copyable = True copyable = True # _copy_cache = None # _linked_copy_cache = None _dragging = None _cut_indices = None option_select = False drag_enabled = True def __init__(self, editor, layout=None, *args, **kw): super(_TableView, self).__init__(editor, *args, **kw) # self.setItemDelegate(ItemDelegate(self)) # self.setup_consumer(main=True) editor = self._editor # # reimplement row height vheader = self.verticalHeader() # size = vheader.minimumSectionSize() height = None font = editor.adapter.get_font(editor.object, editor.name, 0) if font is not None: fnt = QtGui.QFont(font) size = QtGui.QFontMetrics(fnt) height = size.height() + 6 vheader.setFont(fnt) hheader = self.horizontalHeader() hheader.setFont(fnt) if editor.factory.row_height: height = editor.factory.row_height if height: vheader.setDefaultSectionSize(height) else: vheader.ResizeMode(QHeaderView.ResizeToContents) def set_bg_color(self, bgcolor): if isinstance(bgcolor, tuple): if len(bgcolor) == 3: bgcolor = 'rgb({},{},{})'.format(*bgcolor) elif len(bgcolor) == 4: bgcolor = 'rgba({},{},{},{})'.format(*bgcolor) elif isinstance(bgcolor, QColor): bgcolor = 'rgba({},{},{},{})'.format(bgcolor.red(), bgcolor.green(), bgcolor.blue(), bgcolor.alpha()) self.setStyleSheet('QTableView {{background-color: {}}}'.format(bgcolor)) def set_vertical_header_font(self, fnt): fnt = QtGui.QFont(fnt) vheader = self.verticalHeader() vheader.setFont(fnt) size = QtGui.QFontMetrics(fnt) vheader.setDefaultSectionSize(size.height() + 6) def set_horizontal_header_font(self, fnt): fnt = QtGui.QFont(fnt) vheader = self.horizontalHeader() vheader.setFont(fnt) def set_drag_enabled(self, d): if d: self.setDragDropMode(QtGui.QAbstractItemView.DragDrop) self.setDragEnabled(True) def startDrag(self, actions): if self._editor.factory.drag_external: idxs = self.selectedIndexes() rows = sorted(list(set([idx.row() for idx in idxs]))) drag_object = [(ri, self._editor.value[ri]) for ri in rows] md = PyMimeData.coerce(drag_object) self._dragging = self.currentIndex() drag = QtGui.QDrag(self) drag.setMimeData(md) drag.exec_(actions) else: super(_TableView, self).startDrag(actions) def dragEnterEvent(self, e): if self.is_external(): # Assume the drag is invalid. e.ignore() # Check what is being dragged. ed = e.mimeData() md = PyMimeData.coerce(ed) if md is None: return else: try: if not hasattr(ed.instance(), '__iter__'): return except AttributeError: return # We might be able to handle it (but it depends on what the final # target is). e.acceptProposedAction() else: super(_TableView, self).dragEnterEvent(e) def dragMoveEvent(self, e): if self.is_external(): e.acceptProposedAction() else: super(_TableView, self).dragMoveEvent(e) def dropEvent(self, e): if self.is_external(): data = PyMimeData.coerce(e.mimeData()).instance() if not hasattr(data, '__iter__'): return df = self.drop_factory if not df: df = lambda x: x row = self.rowAt(e.pos().y()) n = len(self._editor.value) if row == -1: row = n model = self._editor.model if self._dragging: rows = [ri for ri, _ in data] model.moveRows(rows, row) else: data = [di for _, di in data] with no_update(self._editor.object): for i, di in enumerate(reversed(data)): if isinstance(di, tuple): di = di[1] model.insertRow(row=row, obj=df(di)) for i, di in enumerate(reversed(df(data))): model.insertRow(row=row, obj=di) e.accept() self._dragging = None else: super(_TableView, self).dropEvent(e) def is_external(self): # print 'is_external', self._editor.factory.drag_external and not self._dragging return self._editor.factory.drag_external # and not self._dragging def keyPressEvent(self, event): if event.matches(QtGui.QKeySequence.Copy): # self._copy_cache = [self._editor.value[ci.row()] for ci in # self.selectionModel().selectedRows()] # self._copy_cache = self._get_selection() # self._editor.copy_cache = self._copy_cache self._cut_indices = None # add the selected rows to the clipboard self._copy() elif event.matches(QtGui.QKeySequence.Cut): self._cut_indices = [ci.row() for ci in self.selectionModel().selectedRows()] # self._copy_cache = [self._editor.value[ci] for ci in self._cut_indices] # self._copy_cache = self._get_selection(self._cut_indices) # self._editor.copy_cache = self._copy_cache elif event.matches(QtGui.QKeySequence.Paste): if self.pastable: self._paste() else: self._editor.key_pressed = TabularKeyEvent(event) self._key_press_hook(event) # private def _copy(self): rows = sorted({ri.row() for ri in self.selectedIndexes()}) copy_object = [(ri, self._editor.value[ri].tocopy()) for ri in rows] # copy_object = [ri.row(), self._editor.value[ri.row()]) for ri in self.selectedIndexes()] mt = self._editor.factory.mime_type try: pdata = dumps(copy_object) except BaseException, e: print 'tabular editor copy failed' self._editor.value[rows[0]].tocopy(verbose=True) return qmd = PyMimeData() qmd.MIME_TYPE = mt qmd.setData(unicode(mt), dumps(copy_object.__class__) + pdata) clipboard = QApplication.clipboard() clipboard.setMimeData(qmd)