def choice_menu(self, button, pos): """build menu on Action button""" menu = QtWidgets.QMenu(self.top()) # #1995 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.pos() global_point = button.mapToGlobal(point) menu.exec_(global_point)
def context_menu(self, event, container=None): """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}, 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 makeButtons(self): c = self.c w = c.frame.iconBar.w if not w: return [] # EKR: can be an empty list when unit testing. icon_l = w.style().standardIcon(StandardPixmap.SP_ArrowLeft) icon_r = w.style().standardIcon(StandardPixmap.SP_ArrowRight) # Create the actions. act_l = QAction(icon_l, 'prev', w) act_r = QAction(icon_r, 'next', w) # Use the new commands. act_l.triggered.connect(lambda checked: c.goToPrevHistory()) act_r.triggered.connect(lambda checked: c.goToNextHistory()) # Don't execute the command twice. self.c.frame.iconBar.add(qaction=act_l) self.c.frame.iconBar.add(qaction=act_r) return act_l, act_r
def createActions(self): self.boldAct = QAction(self.tr("&Bold"), self) self.boldAct.setCheckable(True) self.boldAct.setShortcut(self.tr("Ctrl+B")) self.boldAct.setStatusTip(self.tr("Make the text bold")) self.boldAct.triggered.connect(self.setBold) self.addAction(self.boldAct) boldFont = self.boldAct.font() boldFont.setBold(True) self.boldAct.setFont(boldFont) self.italicAct = QAction(self.tr("&Italic"), self) self.italicAct.setCheckable(True) self.italicAct.setShortcut(self.tr("Ctrl+I")) self.italicAct.setStatusTip(self.tr("Make the text italic")) self.italicAct.triggered.connect(self.setItalic) self.addAction(self.italicAct)
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 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 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 add_item(self, func, menu, name, tooltip=None): """helper for splitter_menu menu building""" act = QAction(name, self) act.setObjectName(name.lower().replace(' ', '-')) act.triggered.connect(lambda checked: func()) if tooltip: act.setToolTip(tooltip) menu.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)
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 popup(self, c, p, menu): """make popup menu entry for tree context menu""" # pylint: disable=function-redefined # several callbacks have the same name. if c != self.c: return # wrong commander for cb, name in reversed(self.recent_moves): a = QAction(name, menu) a.triggered.connect( lambda checked, cb=cb, name=name: self.do_wrap(cb, name)) menu.insertAction(menu.actions()[0], a) pathmenu = menu.addMenu("Move") # copy / cut to other outline cut = None for txt, cut in ("Copy to...", False), ("Move to...", True): sub = pathmenu.addMenu(txt) # global targets for target in g.app.db['_quickmove']['global_targets']: a = sub.addAction(target['name']) def cb(c2=target['unl'], cut=cut): self.to_other(c2, cut=cut) def wrap(checked, cb=cb, name=txt.strip('.') + ' ' + target['name']): self.do_wrap(cb, name) a.triggered.connect(wrap) # top of open outlines for c2 in g.app.commanders(): a = sub.addAction("Top of " + g.os_path_basename(c2.fileName())) def cb(c2=c2, cut=cut): self.to_other(c2, cut=cut) def wrap(checked, cb=cb, name=txt.strip('.') + ' top of ' + g.os_path_basename(c2.fileName())): self.do_wrap(cb, name) a.triggered.connect(wrap) # bookmark to other outline sub = pathmenu.addMenu("Bookmark to...") # global targets for target in g.app.db['_quickmove']['global_targets']: a = sub.addAction(target['name']) def cb(c2=target['unl'], cut=cut): self.bookmark_other(c2) def wrap(checked, cb=cb, name="Bookmark to " + target['name']): self.do_wrap(cb, name) a.triggered.connect(wrap) # top of open outlines for c2 in g.app.commanders(): a = sub.addAction(g.os_path_basename(c2.fileName())) def cb(c2=c2): self.bookmark_other(c2) def wrap(checked, cb=cb, name="Bookmark to top of " + g.os_path_basename(c2.fileName())): self.do_wrap(cb, name) a.triggered.connect(wrap) # actions within this outline need_submenu = 'Move', 'Copy', 'Clone', 'Bookmark', 'Link' current_kind = None current_submenu = None for name, dummy, command in self.local_imps: kind = name.split()[0] if kind in need_submenu: if current_kind != kind: current_submenu = pathmenu.addMenu(kind) current_kind = kind else: current_submenu = pathmenu a = current_submenu.addAction(name) a.triggered.connect(lambda checked, command=command: command()) # add new global target, etc. a = pathmenu.addAction("Add node as target") a.triggered.connect(lambda checked, p=p: self.add_target(p)) a = pathmenu.addAction("Show targets") a.triggered.connect(lambda checked, p=p: self.show_targets()) a = pathmenu.addAction("Read targets") a.triggered.connect(lambda checked, p=p: self.read_targets())
def addButton(self, which, type_="move", v=None, parent=None): """Add a button that creates a target for future moves.""" c = self.c p = c.p if v is None: v = p.v sc = scriptingController(c) mb = quickMoveButton(self, v, which, type_=type_) txt = self.txts[type_] if parent: # find parent button for i in self.buttons: if i[0].target.gnx == parent: parent = i[1] break else: g.es('Move to button parent not found, placing at top level') parent = None header = v.anyAtFileNodeName() or v.h # drop @auto etc. text = txt + ":" + header if txt else header # createButton truncates text. if parent and g.app.gui.guiName().startswith("qt"): pb = parent.button rc = QAction(text, pb) rc.triggered.connect(mb.moveCurrentNodeToTarget) pb.insertAction(pb.actions()[0], rc) # insert at top b = None mb.has_parent = True # New code. t = c.config.getString('mod-scripting-subtext') or '' t2 = pb.text() if not t.endswith(t): pb.setText(t2 + t) else: b = sc.createIconButton( args=None, text=text, command=mb.moveCurrentNodeToTarget, statusLine='%s current node to %s child of %s' % (type_.title(), which, v.h), kind="quick-move") if g.app.gui.guiName() == "qt": def cb_goto_target(checked, c=c, v=v): p = c.vnode2position(v) c.selectPosition(p) c.redraw() def cb_set_parent(checked, c=c, v=v, first=which, type_=type_): c.quickMove.set_parent(v, first, type_) def cb_permanent(checked, c=c, v=v, type_=type_, first=which): c.quickMove.permanentButton(v=v, type_=type_, first=first) # def cb_clear(event=None, c=c, v=v): # c.quickMove.clearButton(v) for cb, txt in [ (cb_goto_target, 'Goto target'), (cb_permanent, 'Make permanent'), # (cb_clear, 'Clear permanent'), (cb_set_parent, 'Set parent'), ]: but = b.button rc = QAction(txt, but) rc.triggered.connect(cb) # insert rc before Remove Button but.insertAction(but.actions()[-1], rc) self.buttons.append((mb, b))
class SimpleRichText(QTextEdit): def __init__(self, focusin, focusout): super().__init__() self.focusin = focusin self.focusout = focusout self.createActions() #self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) def focusOutEvent(self, event): #print "focus out" self.focusout() def focusInEvent(self, event): self.focusin() def closeEvent(self, event): event.accept() def createActions(self): self.boldAct = QAction(self.tr("&Bold"), self) self.boldAct.setCheckable(True) self.boldAct.setShortcut(self.tr("Ctrl+B")) self.boldAct.setStatusTip(self.tr("Make the text bold")) # self.connect(self.boldAct, SIGNAL("triggered()"), self.setBold) self.triggered.connect(self.setBold) self.addAction(self.boldAct) boldFont = self.boldAct.font() boldFont.setBold(True) self.boldAct.setFont(boldFont) self.italicAct = QAction(self.tr("&Italic"), self) self.italicAct.setCheckable(True) self.italicAct.setShortcut(self.tr("Ctrl+I")) self.italicAct.setStatusTip(self.tr("Make the text italic")) # self.connect(self.italicAct, SIGNAL("triggered()"), self.setItalic) self.triggered.connect(self.setItalic) self.addAction(self.italicAct) def setBold(self): format = QTextCharFormat() if self.boldAct.isChecked(): weight = Weight.Bold else: weight = Weight.Normal format.setFontWeight(weight) self.setFormat(format) def setItalic(self): format = QTextCharFormat() #format.setFontItalic(self.__italic.isChecked()) format.setFontItalic(self.italicAct.isChecked()) self.setFormat(format) def setUnderline(self): format = QTextCharFormat() format.setFontUnderline(self.__underline.isChecked()) self.setFormat(format) def setFormat(self, format): self.textCursor().mergeCharFormat(format) self.mergeCurrentCharFormat(format) def bold(self): print("bold") def italic(self): print("italic")
class SimpleRichText(QtWidgets.QTextEdit): # type:ignore # pylint: disable=method-hidden def __init__(self, focusin, focusout): super().__init__() self.focusin = focusin self.focusout = focusout self.createActions() def focusOutEvent(self, event): self.focusout() def focusInEvent(self, event): self.focusin() def closeEvent(self, event): event.accept() def createActions(self): self.boldAct = QAction(self.tr("&Bold"), self) self.boldAct.setCheckable(True) self.boldAct.setShortcut(self.tr("Ctrl+B")) self.boldAct.setStatusTip(self.tr("Make the text bold")) self.boldAct.triggered.connect(self.setBold) self.addAction(self.boldAct) boldFont = self.boldAct.font() boldFont.setBold(True) self.boldAct.setFont(boldFont) self.italicAct = QAction(self.tr("&Italic"), self) self.italicAct.setCheckable(True) self.italicAct.setShortcut(self.tr("Ctrl+I")) self.italicAct.setStatusTip(self.tr("Make the text italic")) self.italicAct.triggered.connect(self.setItalic) self.addAction(self.italicAct) def setBold(self): format = QTextCharFormat() if self.boldAct.isChecked(): weight = Weight.Bold else: weight = Weight.Normal format.setFontWeight(weight) self.setFormat(format) def setItalic(self): format = QTextCharFormat() format.setFontItalic(self.italicAct.isChecked()) self.setFormat(format) def setUnderline(self): format = QTextCharFormat() format.setFontUnderline(self.__underline.isChecked()) self.setFormat(format) def setFormat(self, format): self.textCursor().mergeCharFormat(format) self.mergeCurrentCharFormat(format) def bold(self): print("bold") def italic(self): print("italic")
def splitter_menu(self, pos): """build the context menu for NestedSplitter""" 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' if self.orientation() == Orientation.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. point = pos global_point = self.mapToGlobal(point) menu.exec_(global_point) for i in 0, 1: widget[i].setStyleSheet(sheet[i])