Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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
Пример #4
0
    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)
Пример #5
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 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)
Пример #6
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)
Пример #7
0
 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)
Пример #8
0
        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)
Пример #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 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())
Пример #11
0
    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))
Пример #12
0
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")
Пример #13
0
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")
Пример #14
0
    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])