def misc_menu(self): """build menu on Action button""" # info needed to separate edit and view widgets in self.widget_classes name_test_current = [ ("Editor", lambda x: x.lep_type == 'EDITOR', self.edit_widget.__class__), ("Viewer", lambda x: x.lep_type != 'EDITOR', self.view_widget.__class__), ] menu = QtWidgets.QMenu() for name, is_one, current in name_test_current: # list Editor widgets, then Viewer widgets for widget_class in [i for i in self.widget_classes if is_one(i)]: def cb(checked, widget_class=widget_class): self.set_widget(widget_class=widget_class) act = QtWidgets.QAction( "%s: %s" % (name, widget_class.lep_name), self) act.setCheckable(True) act.setChecked(widget_class == current) act.triggered.connect(cb) menu.addAction(act) menu.exec_(self.mapToGlobal(self.control_menu_button.pos()))
def button_menu(self, event, bm, but, up=False): """button_menu - handle a button being right-clicked :Parameters: - `event`: QPushButton event - `bm`: Bookmark associated with button - `but`: button widget """ menu = QtWidgets.QMenu() actions = [ ("Link bookmark to this node", self.update_bookmark), ("Re-name bookmark", self.rename_bookmark), ("Edit bookmark in tree", self.edit_bookmark), ("Delete bookmark", self.delete_bookmark), ("Add this node as child bookmark", self.add_child_bookmark), ] for action in actions: # pylint: disable=cell-var-from-loop act = QtWidgets.QAction(action[0], menu) act.triggered.connect(lambda checked, bm=bm, f=action[1]: f(bm)) menu.addAction(act) def follow(checked, bm=bm, manager=self): manager.current = bm.v manager.second = True manager.upwards = False manager.show_list(manager.get_list(), up=False) act = QtWidgets.QAction("Show child bookmarks", menu) act.triggered.connect(follow) menu.addAction(act) menu.exec_(but.mapToGlobal(event.pos()))
def misc_menu(self): """build menu on Action button""" # info needed to separate edit and view widgets in self.widget_classes name_test_current = [ ("Editor", lambda x: x.lep_type == 'EDITOR', self.edit_widget.__class__), ("Viewer", lambda x: x.lep_type != 'EDITOR', self.view_widget.__class__), ] menu = QtWidgets.QMenu() for name, is_one, current in name_test_current: # list Editor widgets, then Viewer widgets for widget_class in [i for i in self.widget_classes if is_one(i)]: def cb(checked, widget_class=widget_class): self.set_widget(widget_class=widget_class) act = QAction(f"{name}: {widget_class.lep_name}", self) act.setCheckable(True) act.setChecked(widget_class == current) act.triggered.connect(cb) menu.addAction(act) button = self.control_menu_button point = button.position().toPoint() if isQt6 else button.pos( ) # Qt6 documentation is wrong. global_point = button.mapToGlobal(point) menu.exec_(global_point)
def context_menu(self, event, container=None): """context_menu """ menu = QtWidgets.QMenu() QAction = QtGui.QAction if isQt6 else QtWidgets.QAction bm = self.c._bookmarks actions = [ ("Edit bookmarks in tree", self.edit_bookmark), ( "Add bookmark folder", lambda e: cmd_bookmark_organizer(event={'c': bm.v.context}, container=container), ), ] for action in actions: # pylint: disable=cell-var-from-loop # pylint: disable=undefined-variable # weird: bm clearly *is* defined. act = QAction(action[0], menu) act.triggered.connect(lambda checked, bm=bm, f=action[1]: f(bm)) menu.addAction(act) point = event.position().toPoint() if isQt6 else event.pos( ) # Qt6 documentation is wrong. global_point = menu.mapToGlobal(point) menu.exec_(global_point)
def choice_menu(self, button, pos): """build menu on Action button""" menu = QtWidgets.QMenu() QAction = QtGui.QAction if isQt6 else QtWidgets.QAction index = self.indexOf(button) if (self.root.marked and not self.invalid_swap(button, self.root.marked[3]) and self.top().max_count() > 2): act = QAction("Move marked here", self) act.triggered.connect(lambda checked: self.replace_widget( button, self.root.marked[3])) menu.addAction(act) for provider in self.root.providers: if hasattr(provider, 'ns_provides'): for title, id_ in provider.ns_provides(): def cb(checked, id_=id_): self.place_provided(id_, index) act = QAction(title, self) act.triggered.connect(cb) menu.addAction(act) if menu.isEmpty(): act = QAction("Nothing marked, and no options", self) menu.addAction(act) point = button.position().toPoint() if isQt6 else button.pos( ) # Qt6 documentation is wrong. global_point = button.mapToGlobal(point) menu.exec_(global_point)
def createTrayIcon(): g.trayIconMenu = QtWidgets.QMenu() def new_note(): c = g.app.commanders()[0] c.k.simulateCommand('stickynote-new') g.trayIconMenu.addAction("New note", new_note) g.trayIcon = QtWidgets.QSystemTrayIcon() g.trayIcon.setContextMenu(g.trayIconMenu) g.trayIcon.setIcon(QtGui.QIcon(g.app.leoDir + "/Icons/leoapp32.png")) g.trayIcon.setVisible(True)
def mode_menu(self): """build menu on Action button""" menu = QtWidgets.QMenu() for mode in 'edit', 'view', 'split': act = QtWidgets.QAction(mode.title(), self) def cb(checked, self=self, mode=mode): self.set_mode(mode) act.triggered.connect(cb) act.setCheckable(True) act.setChecked(mode == self.mode) menu.addAction(act) menu.exec_(self.mapToGlobal(self.btn_mode.pos()))
def free_layout_load(event): """free_layout_load - load layout from menu """ c = event.get('c') d = g.app.db.get('ns_layouts', {}) menu = QtWidgets.QMenu(c.frame.top) for k in d: menu.addAction(k) pos = c.frame.top.window().frameGeometry().center() action = menu.exec_(pos) if action is None: return name = str(action.text()) c.db['_ns_layout'] = name layout = g.app.db['ns_layouts'][name] c.free_layout.get_top_splitter().load_layout(layout)
def mode_menu(self): """build menu on Action button""" menu = QtWidgets.QMenu() for mode in 'edit', 'view', 'split': act = QAction(mode.title(), self) def cb(checked, self=self, mode=mode): self.set_mode(mode) act.triggered.connect(cb) act.setCheckable(True) act.setChecked(mode == self.mode) menu.addAction(act) button = self.btn_mode point = button.position().toPoint() if isQt6 else button.pos( ) # Qt6 documentation is wrong. global_point = button.mapToGlobal(point) menu.exec_(global_point)
def button_menu(self, event, bm, but, up=False): """button_menu - handle a button being right-clicked :Parameters: - `event`: QPushButton event - `bm`: Bookmark associated with button - `but`: button widget """ menu = QtWidgets.QMenu() QAction = QtGui.QAction if isQt6 else QtWidgets.QAction actions = [ ("Link to this node", self.update_bookmark), ("Promote", self.promote_bookmark), ("Re-name", self.rename_bookmark), ("Edit in tree", self.edit_bookmark), ("Delete", self.delete_bookmark), ("Add this node as child bookmark", lambda e: cmd_bookmark_child(event={'c': bm.v.context})), ("Add bookmark folder", lambda e: cmd_bookmark_organizer(event={'c': bm.v.context})), ] for action in actions: # pylint: disable=cell-var-from-loop act = QAction(action[0], menu) act.triggered.connect(lambda checked, bm=bm, f=action[1]: f(bm)) menu.addAction(act) def follow(checked, bm=bm, manager=self): manager.current = bm.v manager.second = True manager.upwards = False manager.show_list(manager.get_list(), up=False) act = QAction("Show child bookmarks", menu) act.triggered.connect(follow) menu.addAction(act) point = event.position().toPoint() if isQt6 else event.pos( ) # Qt6 documentation is wrong. global_point = but.mapToGlobal(point) menu.exec_(global_point)
def keyboard_popup(self): """Assign a quick move action with the current node as a target, to be triggered with quickmove_keyboard_action """ c = self.c menu = QtWidgets.QMenu(c.frame.top) cmds = {} need_submenu = 'Move', 'Copy', 'Clone', 'Bookmark', 'Link' current_kind = None current_submenu = None todo: Any for name, first_last, long, short in quickMove.flavors: if first_last: todo = 'first child', 'last child', 'next sibling', 'prev sibling' else: todo = [''] for which in todo: if which: which = " " + which.title() k = "Set as " + long + " " + short + which + ' target' cmds[k] = {'first': which, 'type': name} kind = long.split()[0] if kind in need_submenu: if current_kind != kind: current_submenu = menu.addMenu(kind) current_kind = kind else: current_submenu = menu current_submenu.addAction(k) pos = c.frame.top.window().frameGeometry().center() action = menu.exec_(pos) if action is None: return k = str(action.text()) g.es(k) self.keyboard_target = quickMoveButton(self, c.p.v, cmds[k]['first'], type_=cmds[k]['type'])
def context_menu(self, event): """context_menu """ menu = QtWidgets.QMenu() bm = self.c._bookmarks actions = [ ("Edit bookmarks in tree", self.edit_bookmark), ("Add bookmark folder", lambda e: cmd_bookmark_organizer(event={'c': bm.v.context})), ] for action in actions: # pylint: disable=cell-var-from-loop # pylint: disable=undefined-variable # weird: bm clearly *is* defined. act = QtWidgets.QAction(action[0], menu) act.triggered.connect(lambda checked, bm=bm, f=action[1]: f(bm)) menu.addAction(act) menu.exec_(self.w.mapToGlobal(event.pos()))
def free_layout_load(event): """free_layout_load - load layout from menu """ if g.app.dock: # #1216 g.es('free-layout-load works only when') g.es('--no-dock is in effect') return c = event.get('c') d = g.app.db.get('ns_layouts', {}) menu = QtWidgets.QMenu(c.frame.top) for k in d: menu.addAction(k) pos = c.frame.top.window().frameGeometry().center() action = menu.exec_(pos) if action is None: return name = str(action.text()) c.db['_ns_layout'] = name # layout = g.app.db['ns_layouts'][name] layouts = g.app.db.get('ns_layouts', {}) layout = layouts.get(name) if layout: c.free_layout.get_top_splitter().load_layout(layout)
def __init__(self, owner=None): self.owner = owner # a = QtGui.QApplication([]) # argc, argv ); QtWidgets.QWidget.__init__(self) uiPath = g.os_path_join(g.app.leoDir, 'plugins', 'GraphCanvas', 'GraphCanvas.ui') # change directory for this to work old_dir = os.getcwd() try: os.chdir(g.os_path_join(g.computeLeoDir(), "..")) form_class, base_class = uic.loadUiType(uiPath) self.owner.c.frame.log.createTab('Graph', widget=self) self.UI = form_class() self.UI.setupUi(self) finally: os.chdir(old_dir) self.canvas = QtWidgets.QGraphicsScene() self.canvasView = GraphicsView(self.owner, self.canvas) self.canvasView.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag) self.UI.canvasFrame.addWidget(self.canvasView) self.canvasView.setSceneRect(0, 0, 300, 300) self.canvasView.setRenderHints(QtGui.QPainter.Antialiasing) u = self.UI o = self.owner u.btnUpdate.clicked.connect(lambda checked: o.do_update()) u.btnGoto.clicked.connect(lambda checked: o.goto()) u.btnLoad.clicked.connect(lambda checked: o.loadGraph()) u.btnLoadSibs.clicked.connect(lambda checked: o.loadGraph('sibs')) u.btnLoadRecur.clicked.connect(lambda checked: o.loadGraph('recur')) u.btnLoadLinked.clicked.connect(lambda checked: o.loadLinked('linked')) u.btnLoadAll.clicked.connect(lambda checked: o.loadLinked('all')) u.btnUnLoad.clicked.connect(lambda checked: o.unLoad()) u.btnClear.clicked.connect(lambda checked: o.clear()) u.btnLocate.clicked.connect(lambda checked: o.locateNode()) u.btnReset.clicked.connect(lambda checked: o.resetNode()) u.btnColor.clicked.connect(lambda checked: o.setColor()) u.btnTextColor.clicked.connect(lambda checked: o.setTextColor()) u.btnClearFormatting.clicked.connect( lambda checked: o.clearFormatting()) u.btnRect.clicked.connect(lambda checked: o.setNode(nodeRect)) u.btnEllipse.clicked.connect(lambda checked: o.setNode(nodeEllipse)) u.btnDiamond.clicked.connect(lambda checked: o.setNode(nodeDiamond)) u.btnNone.clicked.connect(lambda checked: o.setNode(nodeNone)) u.btnTable.clicked.connect(lambda checked: o.setNode(nodeTable)) u.btnComment.clicked.connect(lambda checked: o.setNode(nodeComment)) u.btnImage.clicked.connect(lambda checked: o.setNode(nodeImage)) u.btnExport.clicked.connect(lambda checked: o.exportGraph()) u.chkHierarchy.clicked.connect(lambda checked: o.do_update()) menu = QtWidgets.QMenu(u.btnLayout) for name, func in o.layouts(): menu.addAction(name, func) u.btnLayout.setMenu(menu)
def splitter_menu(self, pos): """build the context menu for NestedSplitter""" QAction = QtGui.QAction if isQt6 else QtWidgets.QAction splitter = self.splitter() if not splitter.enabled: g.trace('splitter not enabled') return index = splitter.indexOf(self) # get three pairs widget, neighbour, count = splitter.handle_context(index) lr = 'Left', 'Right' ab = 'Above', 'Below' split_dir = 'Vertically' Orientations = QtCore.Qt.Orientations if isQt6 else QtCore.Qt if self.orientation() == Orientations.Vertical: lr, ab = ab, lr split_dir = 'Horizontally' # blue/orange - color-blind friendly color = '#729fcf', '#f57900' sheet = [] for i in 0, 1: sheet.append(widget[i].styleSheet()) widget[i].setStyleSheet(sheet[-1] + f"\nborder: 2px solid {color[i]};") menu = QtWidgets.QMenu() menu.hovered.connect(self.show_tip) def pl(n): return 's' if n > 1 else '' def di(s): return { 'Above': 'above', 'Below': 'below', 'Left': 'left of', 'Right': 'right of', }[s] # Insert. def insert_callback(index=index): splitter.insert(index) self.add_item(insert_callback, menu, 'Insert', "Insert an empty pane here") # Remove, +0/-1 reversed, we need to test the one that remains # First see if a parent has more than two splits # (we could be a sole surviving child). max_parent_splits = 0 up = splitter.parent() while isinstance(up, NestedSplitter): max_parent_splits = max(max_parent_splits, up.count()) up = up.parent() if max_parent_splits >= 2: break # two is enough for i in 0, 1: # keep = splitter.widget(index) # cull = splitter.widget(index - 1) if (max_parent_splits >= 2 or # more splits upstream splitter.count() > 2 or # 3+ splits here, or 2+ downstream neighbour[not i] and neighbour[not i].max_count() >= 2): def remove_callback(i=i, index=index): splitter.remove(index, i) self.add_item( remove_callback, menu, f"Remove {count[i]:d} {lr[i]}", f"Remove the {count[i]} pane{pl(count[i])} {di(lr[i])} here" ) # Swap. def swap_callback(index=index): splitter.swap(index) self.add_item( swap_callback, menu, f"Swap {count[0]:d} {lr[0]} {count[1]:d} {lr[1]}", f"Swap the {count[0]:d} pane{pl(count[0])} {di(lr[0])} here " f"with the {count[1]:d} pane{pl(count[1])} {di(lr[1])} here") # Split: only if not already split. for i in 0, 1: if not neighbour[i] or neighbour[i].count() == 1: def split_callback(i=i, index=index, splitter=splitter): splitter.split(index, i) self.add_item(split_callback, menu, f"Split {lr[i]} {split_dir}") for i in 0, 1: def mark_callback(i=i, index=index): splitter.mark(index, i) self.add_item(mark_callback, menu, f"Mark {count[i]:d} {lr[i]}") # Swap With Marked. if splitter.root.marked: for i in 0, 1: if not splitter.invalid_swap(widget[i], splitter.root.marked[2]): def swap_mark_callback(i=i, index=index, splitter=splitter): splitter.swap_with_marked(index, i) self.add_item(swap_mark_callback, menu, f"Swap {count[i]:d} {lr[i]} With Marked") # Add. for i in 0, 1: if (not isinstance(splitter.parent(), NestedSplitter) or splitter.parent().indexOf(splitter) == [0, splitter.parent().count() - 1][i]): def add_callback(i=i, splitter=splitter): splitter.add(i) self.add_item(add_callback, menu, f"Add {ab[i]}") # Rotate All. self.add_item(splitter.rotate, menu, 'Toggle split direction') def rotate_only_this(index=index): splitter.rotateOne(index) self.add_item(rotate_only_this, menu, 'Toggle split/dir. just this') # equalize panes def eq(splitter=splitter.top()): splitter.equalize_sizes(recurse=True) self.add_item(eq, menu, 'Equalize all') # (un)zoom pane def zoom(splitter=splitter.top()): splitter.zoom_toggle() self.add_item(zoom, menu, ('Un' if splitter.root.zoomed else '') + 'Zoom pane') # open window if splitter.top().parent().__class__ != NestedSplitterTopLevel: # don't open windows from windows, only from main splitter # so owner is not a window which might close. Could instead # set owner to main splitter explicitly. Not sure how right now. submenu = menu.addMenu('Open window') if 1: # pylint: disable=unnecessary-lambda self.add_item(lambda: splitter.open_window(), submenu, "Empty") # adapted from choice_menu() if (splitter.root.marked and splitter.top().max_count() > 1): self.add_item( lambda: splitter.open_window(action="_move_marked_there"), submenu, "Move marked there") for provider in splitter.root.providers: if hasattr(provider, 'ns_provides'): for title, id_ in provider.ns_provides(): def cb(id_=id_): splitter.open_window(action=id_) self.add_item(cb, submenu, title) submenu = menu.addMenu('Debug') act = QAction("Print splitter layout", self) def print_layout_c(checked, splitter=splitter): layout = splitter.top().get_layout() g.printObj(layout) act.triggered.connect(print_layout_c) submenu.addAction(act) def load_items(menu, items): for i in items: if isinstance(i, dict): for k in i: load_items(menu.addMenu(k), i[k]) else: title, id_ = i def cb(checked, id_=id_): splitter.context_cb(id_, index) act = QAction(title, self) act.triggered.connect(cb) menu.addAction(act) for provider in splitter.root.providers: if hasattr(provider, 'ns_context'): load_items(menu, provider.ns_context()) point = pos.toPoint() if isQt6 else pos # Qt6 documentation is wrong. global_point = self.mapToGlobal(point) menu.exec_(global_point) for i in 0, 1: widget[i].setStyleSheet(sheet[i])