示例#1
0
    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()))
示例#2
0
    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()))
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
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)
示例#7
0
    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()))
示例#8
0
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)
示例#9
0
    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)
示例#10
0
    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)
示例#11
0
    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'])
示例#12
0
    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()))
示例#13
0
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)
示例#14
0
    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)
示例#15
0
    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])