def __init__(self, document, parentwin): """Initialise dock given document and parent widget.""" qt4.QDockWidget.__init__(self, parentwin) self.parentwin = parentwin self.setWindowTitle(_("Editing - Veusz")) self.setObjectName("veuszeditingwindow") self.selwidgets = [] self.document = document self.connect( self.document, qt4.SIGNAL("sigWiped"), self.slotDocumentWiped ) # construct tree self.treemodel = WidgetTreeModel(document) self.treeview = WidgetTreeView(self.treemodel) # receive change in selection self.connect(self.treeview.selectionModel(), qt4.SIGNAL('selectionChanged(const QItemSelection &,' ' const QItemSelection &)'), self.slotTreeItemsSelected) # set tree as main widget self.setWidget(self.treeview) # toolbar to create widgets self.addtoolbar = qt4.QToolBar(_("Insert toolbar - Veusz"), parentwin) # note wrong description!: backwards compatibility self.addtoolbar.setObjectName("veuszeditingtoolbar") # toolbar for editting widgets self.edittoolbar = qt4.QToolBar(_("Edit toolbar - Veusz"), parentwin) self.edittoolbar.setObjectName("veuszedittoolbar") self._constructToolbarMenu() parentwin.addToolBarBreak(qt4.Qt.TopToolBarArea) parentwin.addToolBar(qt4.Qt.TopToolBarArea, self.addtoolbar) parentwin.addToolBar(qt4.Qt.TopToolBarArea, self.edittoolbar) # this sets various things up self.selectWidget(document.basewidget) # update paste button when clipboard changes self.connect(qt4.QApplication.clipboard(), qt4.SIGNAL('dataChanged()'), self.updatePasteButton) self.updatePasteButton()
def __init__(self, document, parent): """Initialise dock given document and parent widget.""" qt4.QDockWidget.__init__(self, parent) self.parent = parent self.setWindowTitle("Editing - Veusz") self.setObjectName("veuszeditingwindow") self.selwidgets = [] self.document = document self.connect( self.document, qt4.SIGNAL("sigWiped"), self.slotDocumentWiped ) # construct tree self.treemodel = WidgetTreeModel(document) self.treeview = WidgetTreeView(self.treemodel) # receive change in selection self.connect(self.treeview.selectionModel(), qt4.SIGNAL('selectionChanged(const QItemSelection &,' ' const QItemSelection &)'), self.slotTreeItemsSelected) # set tree as main widget self.setWidget(self.treeview) # toolbar to create widgets self.addtoolbar = qt4.QToolBar("Insert toolbar - Veusz", parent) # note wrong description!: backwards compatibility self.addtoolbar.setObjectName("veuszeditingtoolbar") # toolbar for editting widgets self.edittoolbar = qt4.QToolBar("Edit toolbar - Veusz", parent) self.edittoolbar.setObjectName("veuszedittoolbar") self._constructToolbarMenu() parent.addToolBarBreak(qt4.Qt.TopToolBarArea) parent.addToolBar(qt4.Qt.TopToolBarArea, self.addtoolbar) parent.addToolBar(qt4.Qt.TopToolBarArea, self.edittoolbar) # this sets various things up self.selectWidget(document.basewidget) # update paste button when clipboard changes self.connect(qt4.QApplication.clipboard(), qt4.SIGNAL('dataChanged()'), self.updatePasteButton) self.updatePasteButton()
class TreeEditDock(qt4.QDockWidget): """A dock window presenting widgets as a tree.""" def __init__(self, document, parent): """Initialise dock given document and parent widget.""" qt4.QDockWidget.__init__(self, parent) self.parent = parent self.setWindowTitle("Editing - Veusz") self.setObjectName("veuszeditingwindow") self.selwidgets = [] self.document = document self.connect( self.document, qt4.SIGNAL("sigWiped"), self.slotDocumentWiped ) # construct tree self.treemodel = WidgetTreeModel(document) self.treeview = WidgetTreeView(self.treemodel) # receive change in selection self.connect(self.treeview.selectionModel(), qt4.SIGNAL('selectionChanged(const QItemSelection &,' ' const QItemSelection &)'), self.slotTreeItemsSelected) # set tree as main widget self.setWidget(self.treeview) # toolbar to create widgets self.addtoolbar = qt4.QToolBar("Insert toolbar - Veusz", parent) # note wrong description!: backwards compatibility self.addtoolbar.setObjectName("veuszeditingtoolbar") # toolbar for editting widgets self.edittoolbar = qt4.QToolBar("Edit toolbar - Veusz", parent) self.edittoolbar.setObjectName("veuszedittoolbar") self._constructToolbarMenu() parent.addToolBarBreak(qt4.Qt.TopToolBarArea) parent.addToolBar(qt4.Qt.TopToolBarArea, self.addtoolbar) parent.addToolBar(qt4.Qt.TopToolBarArea, self.edittoolbar) # this sets various things up self.selectWidget(document.basewidget) # update paste button when clipboard changes self.connect(qt4.QApplication.clipboard(), qt4.SIGNAL('dataChanged()'), self.updatePasteButton) self.updatePasteButton() def slotDocumentWiped(self): """If the document is wiped, reselect root widget.""" self.selectWidget(self.document.basewidget) def slotTreeItemsSelected(self, current, previous): """New item selected in tree. This updates the list of properties """ # get selected widgets self.selwidgets = widgets = [ self.treemodel.getWidget(idx) for idx in self.treeview.selectionModel().selectedRows() ] if len(widgets) == 0: setnsproxy = None elif len(widgets) == 1: setnsproxy = SettingsProxySingle(self.document, widgets[0].settings, actions=widgets[0].actions) else: setnsproxy = SettingsProxyMulti(self.document, widgets) self._enableCorrectButtons() self._checkPageChange() self.emit( qt4.SIGNAL('widgetsSelected'), self.selwidgets, setnsproxy ) def contextMenuEvent(self, event): """Bring up context menu.""" # no widgets selected if not self.selwidgets: return m = qt4.QMenu(self) # selection m.addMenu(self.parent.menus['edit.select']) m.addSeparator() # actions on widget(s) for act in ('edit.cut', 'edit.copy', 'edit.paste', 'edit.moveup', 'edit.movedown', 'edit.delete', 'edit.rename'): m.addAction(self.vzactions[act]) # allow show or hides of selected widget anyhide = False anyshow = False for w in self.selwidgets: if 'hide' in w.settings: if w.settings.hide: anyshow = True else: anyhide = True for (enabled, menutext, showhide) in ( (anyhide, 'Hide', True), (anyshow, 'Show', False) ): if enabled: m.addSeparator() act = qt4.QAction(menutext, self) self.connect(act, qt4.SIGNAL('triggered()'), utils.BoundCaller(self.slotWidgetHideShow, self.selwidgets, showhide)) m.addAction(act) m.exec_(self.mapToGlobal(event.pos())) event.accept() def _checkPageChange(self): """Check to see whether page has changed.""" w = None if self.selwidgets: w = self.selwidgets[0] while w is not None and not isinstance(w, widgets.Page): w = w.parent if w is not None: # have page, so check what number we are in basewidget children try: i = self.document.basewidget.children.index(w) self.emit(qt4.SIGNAL("sigPageChanged"), i) except ValueError: pass def _enableCorrectButtons(self): """Make sure the create graph buttons are correctly enabled.""" selw = None if self.selwidgets: selw = self.selwidgets[0] # has to be visible if is to be enabled (yuck) nonorth = self.vzactions['add.nonorthpoint'].setVisible(True) # check whether each button can have this widget # (or a parent) as parent for wc, action in self.addslots.iteritems(): w = selw while w is not None and not wc.willAllowParent(w): w = w.parent self.vzactions['add.%s' % wc.typename].setEnabled(w is not None) # exclusive widgets nonorth = self.vzactions['add.nonorthpoint'].isEnabled() self.vzactions['add.nonorthpoint'].setVisible(nonorth) self.vzactions['add.xy'].setVisible(not nonorth) self.vzactions['add.nonorthfunc'].setVisible(nonorth) self.vzactions['add.function'].setVisible(not nonorth) # certain actions shouldn't work on root isnotroot = not any([isinstance(w, widgets.Root) for w in self.selwidgets]) for act in ('edit.cut', 'edit.copy', 'edit.delete', 'edit.moveup', 'edit.movedown', 'edit.rename'): self.vzactions[act].setEnabled(isnotroot) self.updatePasteButton() def _constructToolbarMenu(self): """Add items to edit/add graph toolbar and menu.""" iconsize = setting.settingdb['toolbar_size'] self.addtoolbar.setIconSize( qt4.QSize(iconsize, iconsize) ) self.edittoolbar.setIconSize( qt4.QSize(iconsize, iconsize) ) self.addslots = {} self.vzactions = actions = self.parent.vzactions for widgettype in ('page', 'grid', 'graph', 'axis', 'xy', 'bar', 'fit', 'function', 'boxplot', 'image', 'contour', 'vectorfield', 'key', 'label', 'colorbar', 'rect', 'ellipse', 'imagefile', 'line', 'polygon', 'polar', 'ternary', 'nonorthpoint', 'nonorthfunc'): wc = document.thefactory.getWidgetClass(widgettype) slot = utils.BoundCaller(self.slotMakeWidgetButton, wc) self.addslots[wc] = slot actionname = 'add.' + widgettype actions[actionname] = utils.makeAction( self, wc.description, 'Add %s' % widgettype, slot, icon='button_%s' % widgettype) a = utils.makeAction actions.update({ 'edit.cut': a(self, 'Cut the selected item', 'Cu&t', self.slotWidgetCut, icon='veusz-edit-cut', key='Ctrl+X'), 'edit.copy': a(self, 'Copy the selected item', '&Copy', self.slotWidgetCopy, icon='kde-edit-copy', key='Ctrl+C'), 'edit.paste': a(self, 'Paste item from the clipboard', '&Paste', self.slotWidgetPaste, icon='kde-edit-paste', key='Ctrl+V'), 'edit.moveup': a(self, 'Move the selected item up', 'Move &up', utils.BoundCaller(self.slotWidgetMove, -1), icon='kde-go-up'), 'edit.movedown': a(self, 'Move the selected item down', 'Move d&own', utils.BoundCaller(self.slotWidgetMove, 1), icon='kde-go-down'), 'edit.delete': a(self, 'Remove the selected item', '&Delete', self.slotWidgetDelete, icon='kde-edit-delete'), 'edit.rename': a(self, 'Renames the selected item', '&Rename', self.slotWidgetRename, icon='kde-edit-rename'), 'add.shapemenu': a(self, 'Add a shape to the plot', 'Shape', self.slotShowShapeMenu, icon='veusz-shape-menu'), }) # add actions to menus for adding widgets and editing addact = [('add.'+w) for w in ('page', 'grid', 'graph', 'axis', 'xy', 'nonorthpoint', 'bar', 'fit', 'function', 'nonorthfunc', 'boxplot', 'image', 'contour', 'vectorfield', 'key', 'label', 'colorbar', 'polar', 'ternary')] menuitems = [ ('insert', '', addact + [ ['insert.shape', 'Add shape', ['add.rect', 'add.ellipse', 'add.line', 'add.imagefile', 'add.polygon'] ]]), ('edit', '', [ 'edit.cut', 'edit.copy', 'edit.paste', 'edit.moveup', 'edit.movedown', 'edit.delete', 'edit.rename' ]), ] utils.constructMenus( self.parent.menuBar(), self.parent.menus, menuitems, actions ) # create shape toolbar button # attach menu to insert shape button actions['add.shapemenu'].setMenu(self.parent.menus['insert.shape']) # add actions to toolbar to create widgets utils.addToolbarActions(self.addtoolbar, actions, addact + ['add.shapemenu']) # add action to toolbar for editing utils.addToolbarActions(self.edittoolbar, actions, ('edit.cut', 'edit.copy', 'edit.paste', 'edit.moveup', 'edit.movedown', 'edit.delete', 'edit.rename')) self.connect( self.parent.menus['edit.select'], qt4.SIGNAL('aboutToShow()'), self.updateSelectMenu ) def slotMakeWidgetButton(self, wc): """User clicks button to make widget.""" self.makeWidget(wc.typename) def slotShowShapeMenu(self): a = self.vzactions['add.shapemenu'] a.menu().popup( qt4.QCursor.pos() ) def makeWidget(self, widgettype, autoadd=True, name=None): """Called when an add widget button is clicked. widgettype is the type of widget autoadd specifies whether to add default children if name is set this name is used if possible (ie no other children have it) """ # if no widget selected, bomb out if not self.selwidgets: return parent = document.getSuitableParent(widgettype, self.selwidgets[0]) assert parent is not None if name in parent.childnames: name = None # make the new widget and update the document w = self.document.applyOperation( document.OperationWidgetAdd(parent, widgettype, autoadd=autoadd, name=name) ) # select the widget self.selectWidget(w) def slotWidgetCut(self): """Cut the selected widget""" self.slotWidgetCopy() self.slotWidgetDelete() def slotWidgetCopy(self): """Copy selected widget to the clipboard.""" if self.selwidgets: mimedata = document.generateWidgetsMime(self.selwidgets) clipboard = qt4.QApplication.clipboard() clipboard.setMimeData(mimedata) def updatePasteButton(self): """Is the data on the clipboard a valid paste at the currently selected widget? If so, enable paste button""" data = document.getClipboardWidgetMime() if len(self.selwidgets) == 0: show = False else: show = document.isMimePastable(self.selwidgets[0], data) self.vzactions['edit.paste'].setEnabled(show) def doInitialWidgetSelect(self): """Select a sensible initial widget.""" w = self.document.basewidget for i in xrange(2): try: c = w.children[0] except IndexError: break if c: w = c self.selectWidget(w) def slotWidgetPaste(self): """Paste something from the clipboard""" data = document.getClipboardWidgetMime() if data: op = document.OperationWidgetPaste(self.selwidgets[0], data) widgets = self.document.applyOperation(op) if widgets: self.selectWidget(widgets[0]) def slotWidgetDelete(self): """Delete the widget selected.""" widgets = self.selwidgets # if no item selected, leave if not widgets: return # get list of widgets in order widgetlist = [] self.document.basewidget.buildFlatWidgetList(widgetlist) # find indices of widgets to be deleted - find one to select after indexes = [widgetlist.index(w) for w in widgets] if -1 in indexes: raise RuntimeError, "Invalid widget in list of selected widgets" minindex = min(indexes) # delete selected widget self.document.applyOperation( document.OperationWidgetsDelete(widgets)) # rebuild list widgetlist = [] self.document.basewidget.buildFlatWidgetList(widgetlist) # find next to select if minindex < len(widgetlist): nextwidget = widgetlist[minindex] else: nextwidget = widgetlist[-1] # select the next widget (we have to select root first!) self.selectWidget(self.document.basewidget) self.selectWidget(nextwidget) def slotWidgetRename(self): """Allows the user to rename the selected widget.""" selected = self.treeview.selectedIndexes() if len(selected) != 0: self.treeview.edit(selected[0]) def selectWidget(self, widget): """Select the associated listviewitem for the widget w in the listview.""" index = self.treemodel.getWidgetIndex(widget) if index is not None: self.treeview.scrollTo(index) self.treeview.selectionModel().select( index, qt4.QItemSelectionModel.Clear | qt4.QItemSelectionModel.Current | qt4.QItemSelectionModel.Rows | qt4.QItemSelectionModel.Select ) def slotWidgetMove(self, direction): """Move the selected widget up/down in the hierarchy. a is the action (unused) direction is -1 for 'up' and +1 for 'down' """ if not self.selwidgets: return # widget to move w = self.selwidgets[0] # actually move the widget self.document.applyOperation( document.OperationWidgetMoveUpDown(w, direction) ) # re-highlight moved widget self.selectWidget(w) def slotWidgetHideShow(self, widgets, hideshow): """Hide or show selected widgets. hideshow is True for hiding, False for showing """ ops = [ document.OperationSettingSet(w.settings.get('hide'), hideshow) for w in widgets ] descr = ('show', 'hide')[hideshow] self.document.applyOperation( document.OperationMultiple(ops, descr=descr)) def checkWidgetSelected(self): """Check widget is selected.""" if len(self.treeview.selectionModel().selectedRows()) == 0: self.selectWidget(self.document.basewidget) def _selectWidgetsTypeAndOrName(self, wtype, wname): """Select widgets with type or name given. Give None if you don't care for either.""" def selectwidget(path, w): """Select widget if of type or name given.""" if ( (wtype is None or w.typename == wtype) and (wname is None or w.name == wname) ): idx = self.treemodel.getWidgetIndex(w) self.treeview.selectionModel().select( idx, qt4.QItemSelectionModel.Select | qt4.QItemSelectionModel.Rows) self.document.walkNodes(selectwidget, nodetypes=('widget',)) def _selectWidgetSiblings(self, w, wtype): """Select siblings of widget given with type.""" for c in w.parent.children: if c is not w and c.typename == wtype: idx = self.treemodel.getWidgetIndex(c) self.treeview.selectionModel().select( idx, qt4.QItemSelectionModel.Select | qt4.QItemSelectionModel.Rows) def updateSelectMenu(self): """Update edit.select menu.""" menu = self.parent.menus['edit.select'] menu.clear() if len(self.selwidgets) == 0: return wtype = self.selwidgets[0].typename name = self.selwidgets[0].name menu.addAction( "All '%s' widgets" % wtype, lambda: self._selectWidgetsTypeAndOrName(wtype, None)) menu.addAction( "Siblings of '%s' with type '%s'" % (name, wtype), lambda: self._selectWidgetSiblings(self.selwidgets[0], wtype)) menu.addAction( "All '%s' widgets called '%s'" % (wtype, name), lambda: self._selectWidgetsTypeAndOrName(wtype, name)) menu.addAction( "All widgets called '%s'" % name, lambda: self._selectWidgetsTypeAndOrName(None, name))
class TreeEditDock(qt4.QDockWidget): """A dock window presenting widgets as a tree.""" def __init__(self, document, parentwin): """Initialise dock given document and parent widget.""" qt4.QDockWidget.__init__(self, parentwin) self.parentwin = parentwin self.setWindowTitle(_("Editing - Veusz")) self.setObjectName("veuszeditingwindow") self.selwidgets = [] self.document = document self.connect( self.document, qt4.SIGNAL("sigWiped"), self.slotDocumentWiped ) # construct tree self.treemodel = WidgetTreeModel(document) self.treeview = WidgetTreeView(self.treemodel) # receive change in selection self.connect(self.treeview.selectionModel(), qt4.SIGNAL('selectionChanged(const QItemSelection &,' ' const QItemSelection &)'), self.slotTreeItemsSelected) # set tree as main widget self.setWidget(self.treeview) # toolbar to create widgets self.addtoolbar = qt4.QToolBar(_("Insert toolbar - Veusz"), parentwin) # note wrong description!: backwards compatibility self.addtoolbar.setObjectName("veuszeditingtoolbar") # toolbar for editting widgets self.edittoolbar = qt4.QToolBar(_("Edit toolbar - Veusz"), parentwin) self.edittoolbar.setObjectName("veuszedittoolbar") self._constructToolbarMenu() parentwin.addToolBarBreak(qt4.Qt.TopToolBarArea) parentwin.addToolBar(qt4.Qt.TopToolBarArea, self.addtoolbar) parentwin.addToolBar(qt4.Qt.TopToolBarArea, self.edittoolbar) # this sets various things up self.selectWidget(document.basewidget) # update paste button when clipboard changes self.connect(qt4.QApplication.clipboard(), qt4.SIGNAL('dataChanged()'), self.updatePasteButton) self.updatePasteButton() def slotDocumentWiped(self): """If the document is wiped, reselect root widget.""" self.selectWidget(self.document.basewidget) def slotTreeItemsSelected(self, current, previous): """New item selected in tree. This updates the list of properties """ # get selected widgets self.selwidgets = swidget = [ self.treemodel.getWidget(idx) for idx in self.treeview.selectionModel().selectedRows() ] if len(swidget) == 0: setnsproxy = None elif len(swidget) == 1: setnsproxy = SettingsProxySingle(self.document, swidget[0].settings, actions=swidget[0].actions) else: setnsproxy = SettingsProxyMulti(self.document, swidget) self._enableCorrectButtons() self._checkPageChange() self.emit( qt4.SIGNAL('widgetsSelected'), swidget, setnsproxy ) def contextMenuEvent(self, event): """Bring up context menu.""" # no widgets selected if not self.selwidgets: return m = qt4.QMenu(self) # selection m.addMenu(self.parentwin.menus['edit.select']) m.addSeparator() # actions on widget(s) for act in ('edit.cut', 'edit.copy', 'edit.paste', 'edit.moveup', 'edit.movedown', 'edit.delete', 'edit.rename'): m.addAction(self.vzactions[act]) # allow show or hides of selected widget anyhide = False anyshow = False for w in self.selwidgets: if 'hide' in w.settings: if w.settings.hide: anyshow = True else: anyhide = True for (enabled, menutext, showhide) in ( (anyhide, 'Hide', True), (anyshow, 'Show', False) ): if enabled: m.addSeparator() act = qt4.QAction(menutext, self) self.connect(act, qt4.SIGNAL('triggered()'), utils.BoundCaller(self.slotWidgetHideShow, self.selwidgets, showhide)) m.addAction(act) m.exec_(self.mapToGlobal(event.pos())) event.accept() def _checkPageChange(self): """Check to see whether page has changed.""" w = None if self.selwidgets: w = self.selwidgets[0] while w is not None and not isinstance(w, widgets.Page): w = w.parent if w is not None: # have page, so check what number we are in basewidget children try: i = self.document.basewidget.children.index(w) self.emit(qt4.SIGNAL("sigPageChanged"), i) except ValueError: pass def _enableCorrectButtons(self): """Make sure the create graph buttons are correctly enabled.""" selw = None if self.selwidgets: selw = self.selwidgets[0] # has to be visible if is to be enabled (yuck) nonorth = self.vzactions['add.nonorthpoint'].setVisible(True) # check whether each button can have this widget # (or a parent) as parent for wc, action in self.addslots.iteritems(): w = selw while w is not None and not wc.willAllowParent(w): w = w.parent self.vzactions['add.%s' % wc.typename].setEnabled(w is not None) # exclusive widgets nonorth = self.vzactions['add.nonorthpoint'].isEnabled() self.vzactions['add.nonorthpoint'].setVisible(nonorth) self.vzactions['add.xy'].setVisible(not nonorth) self.vzactions['add.nonorthfunc'].setVisible(nonorth) self.vzactions['add.function'].setVisible(not nonorth) # certain actions shouldn't work on root isnotroot = not any([isinstance(w, widgets.Root) for w in self.selwidgets]) for act in ('edit.cut', 'edit.copy', 'edit.delete', 'edit.moveup', 'edit.movedown', 'edit.rename'): self.vzactions[act].setEnabled(isnotroot) self.updatePasteButton() def _constructToolbarMenu(self): """Add items to edit/add graph toolbar and menu.""" iconsize = setting.settingdb['toolbar_size'] self.addtoolbar.setIconSize( qt4.QSize(iconsize, iconsize) ) self.edittoolbar.setIconSize( qt4.QSize(iconsize, iconsize) ) self.addslots = {} self.vzactions = actions = self.parentwin.vzactions for widgettype in ('page', 'grid', 'graph', 'axis', 'xy', 'bar', 'fit', 'function', 'boxplot', 'image', 'contour', 'vectorfield', 'key', 'label', 'colorbar', 'rect', 'ellipse', 'imagefile', 'line', 'polygon', 'polar', 'ternary', 'nonorthpoint', 'nonorthfunc'): wc = document.thefactory.getWidgetClass(widgettype) slot = utils.BoundCaller(self.slotMakeWidgetButton, wc) self.addslots[wc] = slot actionname = 'add.' + widgettype actions[actionname] = utils.makeAction( self, wc.description, _('Add %s') % widgettype, slot, icon='button_%s' % widgettype) a = utils.makeAction actions.update({ 'edit.cut': a(self, _('Cut the selected widget'), _('Cu&t'), self.slotWidgetCut, icon='veusz-edit-cut', key='Ctrl+X'), 'edit.copy': a(self, _('Copy the selected widget'), _('&Copy'), self.slotWidgetCopy, icon='kde-edit-copy', key='Ctrl+C'), 'edit.paste': a(self, _('Paste widget from the clipboard'), _('&Paste'), self.slotWidgetPaste, icon='kde-edit-paste', key='Ctrl+V'), 'edit.moveup': a(self, _('Move the selected widget up'), _('Move &up'), utils.BoundCaller(self.slotWidgetMove, -1), icon='kde-go-up'), 'edit.movedown': a(self, _('Move the selected widget down'), _('Move d&own'), utils.BoundCaller(self.slotWidgetMove, 1), icon='kde-go-down'), 'edit.delete': a(self, _('Remove the selected widget'), _('&Delete'), self.slotWidgetDelete, icon='kde-edit-delete'), 'edit.rename': a(self, _('Renames the selected widget'), _('&Rename'), self.slotWidgetRename, icon='kde-edit-rename'), 'add.shapemenu': a(self, _('Add a shape to the plot'), _('Shape'), self.slotShowShapeMenu, icon='veusz-shape-menu'), }) # add actions to menus for adding widgets and editing addact = [('add.'+w) for w in ('page', 'grid', 'graph', 'axis', 'xy', 'nonorthpoint', 'bar', 'fit', 'function', 'nonorthfunc', 'boxplot', 'image', 'contour', 'vectorfield', 'key', 'label', 'colorbar', 'polar', 'ternary')] menuitems = [ ('insert', '', addact + [ ['insert.shape', 'Add shape', ['add.rect', 'add.ellipse', 'add.line', 'add.imagefile', 'add.polygon'] ]]), ('edit', '', [ 'edit.cut', 'edit.copy', 'edit.paste', 'edit.moveup', 'edit.movedown', 'edit.delete', 'edit.rename' ]), ] utils.constructMenus( self.parentwin.menuBar(), self.parentwin.menus, menuitems, actions ) # create shape toolbar button # attach menu to insert shape button actions['add.shapemenu'].setMenu(self.parentwin.menus['insert.shape']) # add actions to toolbar to create widgets utils.addToolbarActions(self.addtoolbar, actions, addact + ['add.shapemenu']) # add action to toolbar for editing utils.addToolbarActions(self.edittoolbar, actions, ('edit.cut', 'edit.copy', 'edit.paste', 'edit.moveup', 'edit.movedown', 'edit.delete', 'edit.rename')) self.connect( self.parentwin.menus['edit.select'], qt4.SIGNAL('aboutToShow()'), self.updateSelectMenu ) def slotMakeWidgetButton(self, wc): """User clicks button to make widget.""" self.makeWidget(wc.typename) def slotShowShapeMenu(self): a = self.vzactions['add.shapemenu'] a.menu().popup( qt4.QCursor.pos() ) def makeWidget(self, widgettype, autoadd=True, name=None): """Called when an add widget button is clicked. widgettype is the type of widget autoadd specifies whether to add default children if name is set this name is used if possible (ie no other children have it) """ # if no widget selected, bomb out if not self.selwidgets: return parent = document.getSuitableParent(widgettype, self.selwidgets[0]) assert parent is not None if name in parent.childnames: name = None # make the new widget and update the document w = self.document.applyOperation( document.OperationWidgetAdd(parent, widgettype, autoadd=autoadd, name=name) ) # select the widget self.selectWidget(w) def slotWidgetCut(self): """Cut the selected widget""" self.slotWidgetCopy() self.slotWidgetDelete() def slotWidgetCopy(self): """Copy selected widget to the clipboard.""" if self.selwidgets: mimedata = document.generateWidgetsMime(self.selwidgets) clipboard = qt4.QApplication.clipboard() clipboard.setMimeData(mimedata) def updatePasteButton(self): """Is the data on the clipboard a valid paste at the currently selected widget? If so, enable paste button""" data = document.getClipboardWidgetMime() if len(self.selwidgets) == 0: show = False else: show = document.isWidgetMimePastable(self.selwidgets[0], data) self.vzactions['edit.paste'].setEnabled(show) def doInitialWidgetSelect(self): """Select a sensible initial widget.""" w = self.document.basewidget for i in xrange(2): try: c = w.children[0] except IndexError: break if c: w = c self.selectWidget(w) def slotWidgetPaste(self): """Paste something from the clipboard""" data = document.getClipboardWidgetMime() if data: op = document.OperationWidgetPaste(self.selwidgets[0], data) widgets = self.document.applyOperation(op) if widgets: self.selectWidget(widgets[0]) def slotWidgetDelete(self): """Delete the widget selected.""" widgets = self.selwidgets # if no item selected, leave if not widgets: return # get list of widgets in order widgetlist = [] self.document.basewidget.buildFlatWidgetList(widgetlist) # find indices of widgets to be deleted - find one to select after indexes = [widgetlist.index(w) for w in widgets] if -1 in indexes: raise RuntimeError, "Invalid widget in list of selected widgets" minindex = min(indexes) # delete selected widget self.document.applyOperation( document.OperationWidgetsDelete(widgets)) # rebuild list widgetlist = [] self.document.basewidget.buildFlatWidgetList(widgetlist) # find next to select if minindex < len(widgetlist): nextwidget = widgetlist[minindex] else: nextwidget = widgetlist[-1] # select the next widget (we have to select root first!) self.selectWidget(self.document.basewidget) self.selectWidget(nextwidget) def slotWidgetRename(self): """Allows the user to rename the selected widget.""" selected = self.treeview.selectedIndexes() if len(selected) != 0: self.treeview.edit(selected[0]) def selectWidget(self, widget): """Select the associated listviewitem for the widget w in the listview.""" index = self.treemodel.getWidgetIndex(widget) if index is not None: self.treeview.scrollTo(index) self.treeview.selectionModel().select( index, qt4.QItemSelectionModel.Clear | qt4.QItemSelectionModel.Current | qt4.QItemSelectionModel.Rows | qt4.QItemSelectionModel.Select ) def slotWidgetMove(self, direction): """Move the selected widget up/down in the hierarchy. a is the action (unused) direction is -1 for 'up' and +1 for 'down' """ if not self.selwidgets: return # widget to move w = self.selwidgets[0] # actually move the widget self.document.applyOperation( document.OperationWidgetMoveUpDown(w, direction) ) # re-highlight moved widget self.selectWidget(w) def slotWidgetHideShow(self, widgets, hideshow): """Hide or show selected widgets. hideshow is True for hiding, False for showing """ ops = [ document.OperationSettingSet(w.settings.get('hide'), hideshow) for w in widgets ] descr = ('show', 'hide')[hideshow] self.document.applyOperation( document.OperationMultiple(ops, descr=descr)) def checkWidgetSelected(self): """Check widget is selected.""" if len(self.treeview.selectionModel().selectedRows()) == 0: self.selectWidget(self.document.basewidget) def _selectWidgetsTypeAndOrName(self, wtype, wname): """Select widgets with type or name given. Give None if you don't care for either.""" def selectwidget(path, w): """Select widget if of type or name given.""" if ( (wtype is None or w.typename == wtype) and (wname is None or w.name == wname) ): idx = self.treemodel.getWidgetIndex(w) self.treeview.selectionModel().select( idx, qt4.QItemSelectionModel.Select | qt4.QItemSelectionModel.Rows) self.document.walkNodes(selectwidget, nodetypes=('widget',)) def _selectWidgetSiblings(self, w, wtype): """Select siblings of widget given with type.""" for c in w.parent.children: if c is not w and c.typename == wtype: idx = self.treemodel.getWidgetIndex(c) self.treeview.selectionModel().select( idx, qt4.QItemSelectionModel.Select | qt4.QItemSelectionModel.Rows) def updateSelectMenu(self): """Update edit.select menu.""" menu = self.parentwin.menus['edit.select'] menu.clear() if len(self.selwidgets) == 0: return wtype = self.selwidgets[0].typename name = self.selwidgets[0].name menu.addAction( _("All '%s' widgets") % wtype, lambda: self._selectWidgetsTypeAndOrName(wtype, None)) menu.addAction( _("Siblings of '%s' with type '%s'") % (name, wtype), lambda: self._selectWidgetSiblings(self.selwidgets[0], wtype)) menu.addAction( _("All '%s' widgets called '%s'") % (wtype, name), lambda: self._selectWidgetsTypeAndOrName(wtype, name)) menu.addAction( _("All widgets called '%s'") % name, lambda: self._selectWidgetsTypeAndOrName(None, name))