Python PyQt5.QtWidgets.QActionGroup() Examples

The following are 14 code examples for showing how to use PyQt5.QtWidgets.QActionGroup(). These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.

You may check out the related API usage on the sidebar.

You may also want to check out all available functions/classes of the module PyQt5.QtWidgets , or try the search function .

Example 1
Project: urh   Author: jopohl   File: ProtocolLabelTableView.py    License: GNU General Public License v3.0 6 votes vote down vote up
def create_context_menu(self):
        menu = QMenu(self)
        if self.model().rowCount() == 0:
            return menu

        if isinstance(self.model(), SimulatorMessageFieldModel):
            value_type_group = QActionGroup(self)
            value_type_menu = menu.addMenu("Set value type")
            labels = [self.model().message_type[i] for i in self.selected_rows
                      if not self.model().message_type[i].is_checksum_label]

            for i, value_type in enumerate(SimulatorProtocolLabel.VALUE_TYPES):
                va = value_type_menu.addAction(value_type)
                va.setCheckable(True)
                va.setActionGroup(value_type_group)
                va.setData(i)

                if all(lbl.value_type_index == i for lbl in labels):
                    va.setChecked(True)

                va.triggered.connect(self.on_set_value_type_action_triggered)

        menu.addAction(self.delete_action)
        return menu 
Example 2
Project: chinese-support-redux   Author: luoliyan   File: gui.py    License: GNU General Public License v3.0 5 votes vote down vote up
def add_menu_item(path, text, func, keys=None, checkable=False, checked=False):
    action = QAction(text, mw)

    if keys:
        action.setShortcut(QKeySequence(keys))

    if checkable:
        action.setCheckable(checkable)
        action.toggled.connect(func)
        if not hasattr(mw, 'action_groups'):
            mw.action_groups = {}
        if path not in mw.action_groups:
            mw.action_groups[path] = QActionGroup(None)
        mw.action_groups[path].addAction(action)
        action.setChecked(checked)
    else:
        action.triggered.connect(func)

    if path == 'File':
        mw.form.menuCol.addAction(action)
    elif path == 'Edit':
        mw.form.menuEdit.addAction(action)
    elif path == 'Tools':
        mw.form.menuTools.addAction(action)
    elif path == 'Help':
        mw.form.menuHelp.addAction(action)
    else:
        add_menu(path)
        mw.custom_menus[path].addAction(action) 
Example 3
Project: imperialism-remake   Author: Trilarion   File: lobby.py    License: GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, *args, **kwargs):
        """
        Create toolbar.
        """
        super().__init__(*args, **kwargs)

        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # create tool bar
        toolbar = QtWidgets.QToolBar()
        action_group = QtWidgets.QActionGroup(toolbar)

        # actions single player new/load
        a = qt.create_action(tools.load_ui_icon('icon.lobby.single.new.png'),
                             'Start new single player scenario', action_group,
                             toggle_connection=self.toggled_single_player_scenario_selection, checkable=True)
        toolbar.addAction(a)
        a = qt.create_action(tools.load_ui_icon('icon.lobby.single.load.png'),
                             'Continue saved single player scenario', action_group,
                             toggle_connection=self.toggled_single_player_load_scenario, checkable=True)
        toolbar.addAction(a)

        toolbar.addSeparator()

        # actions multi player
        a = qt.create_action(tools.load_ui_icon('icon.lobby.network.png'),
                             'Show server lobby', action_group,
                             toggle_connection=self.toggled_server_lobby, checkable=True)
        toolbar.addAction(a)
        a = qt.create_action(tools.load_ui_icon('icon.lobby.multiplayer-game.png'),
                             'Start or continue multiplayer scenario', action_group,
                             toggle_connection=self.toggled_multiplayer_scenario_selection, checkable=True)
        toolbar.addAction(a)

        self.layout.addWidget(toolbar, alignment=QtCore.Qt.AlignTop)

        self.content = None 
Example 4
Project: nanovna-saver   Author: NanoVNA-Saver   File: VSWR.py    License: GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, name=""):
        super().__init__(name)
        self.leftMargin = 30
        self.chartWidth = 250
        self.chartHeight = 250
        self.fstart = 0
        self.fstop = 0
        self.maxDisplayValue = 25
        self.minDisplayValue = 1

        self.setMinimumSize(self.chartWidth + self.rightMargin + self.leftMargin,
                            self.chartHeight + self.topMargin + self.bottomMargin)
        self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding,
                                                 QtWidgets.QSizePolicy.MinimumExpanding))
        pal = QtGui.QPalette()
        pal.setColor(QtGui.QPalette.Background, self.backgroundColor)
        self.setPalette(pal)
        self.setAutoFillBackground(True)
        self.y_menu.addSeparator()
        self.y_log_lin_group = QtWidgets.QActionGroup(self.y_menu)
        self.y_action_linear = QtWidgets.QAction("Linear")
        self.y_action_linear.setCheckable(True)
        self.y_action_linear.setChecked(True)
        self.y_action_logarithmic = QtWidgets.QAction("Logarithmic")
        self.y_action_logarithmic.setCheckable(True)
        self.y_action_linear.triggered.connect(lambda: self.setLogarithmicY(False))
        self.y_action_logarithmic.triggered.connect(lambda: self.setLogarithmicY(True))
        self.y_log_lin_group.addAction(self.y_action_linear)
        self.y_log_lin_group.addAction(self.y_action_logarithmic)
        self.y_menu.addAction(self.y_action_linear)
        self.y_menu.addAction(self.y_action_logarithmic) 
Example 5
Project: deepin-remote-assistance   Author: linuxdeepin   File: preferencesmenu.py    License: GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, parent=None):
        super().__init__(parent)

        group = QtWidgets.QActionGroup(self)

        balancedAction = QtWidgets.QAction(_('Balance'), self)
        balancedAction.setCheckable(True)
        balancedAction.setChecked(True)
        balancedAction.triggered.connect(self.balancedChecked)
        balancedAction.setActionGroup(group)

        speedAction = QtWidgets.QAction(_('Optimize Speed'), self)
        speedAction.setCheckable(True)
        speedAction.triggered.connect(self.speedChecked)
        speedAction.setActionGroup(group)

        qualityAction = QtWidgets.QAction(_('Optimize Quality'), self)
        qualityAction.setCheckable(True)
        qualityAction.triggered.connect(self.qualityChecked)
        qualityAction.setActionGroup(group)

        fullscreenAction = QtWidgets.QAction(_('Fullscreen'), self)
        fullscreenAction.toggled.connect(self.fullscreenToggled)
        fullscreenAction.setCheckable(True)

        self.addAction(balancedAction)
        self.addAction(speedAction)
        self.addAction(qualityAction)
        self.addSeparator()
        self.addAction(fullscreenAction)

        self.setStyleSheet(MENU_STYLE) 
Example 6
Project: Artemis   Author: AresValley   File: themesmanager.py    License: GNU General Public License v3.0 5 votes vote down vote up
def _detect_themes(self):
        """Detect all available themes.

        Connect all the actions to change the theme.
        Display a QMessageBox if the theme folder is not found."""
        themes = []
        ag = QActionGroup(self._owner)
        themes_menu = self._owner.settings_menu.addMenu("Themes")
        if not os.path.exists(ThemeConstants.FOLDER):
            pop_up(self._owner, title=ThemeConstants.THEME_FOLDER_NOT_FOUND,
                   text=ThemeConstants.MISSING_THEME_FOLDER).show()
            return
        for theme_folder in sorted(os.listdir(ThemeConstants.FOLDER)):
            relative_folder = os.path.join(ThemeConstants.FOLDER, theme_folder)
            if os.path.isdir(os.path.abspath(relative_folder)):
                relative_folder = os.path.join(ThemeConstants.FOLDER, theme_folder)
                themes.append(relative_folder)
        for theme_path in themes:
            theme_name = '&' + self._pretty_name(os.path.basename(theme_path))
            new_theme = ag.addAction(
                QAction(
                    theme_name,
                    self._owner,
                    checkable=True
                )
            )
            themes_menu.addAction(new_theme)
            self._theme_names[theme_name.lstrip('&')] = new_theme
            new_theme.triggered.connect(partial(self._apply, theme_path)) 
Example 7
Project: imperialism-remake   Author: Trilarion   File: game.py    License: GNU General Public License v3.0 4 votes vote down vote up
def __init__(self, *args, **kwargs):
        """
        Sets up the graphics view.
        """
        super().__init__(*args, **kwargs)
        self.setObjectName('mini-map-widget')

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # the content is a scene
        self.scene = QtWidgets.QGraphicsScene()

        # tracker rectangle that tracks the view of the map, initially hidden
        self.tracker = QtWidgets.QGraphicsRectItem()
        self.tracker.setCursor(QtCore.Qt.PointingHandCursor)
        self.tracker.setZValue(1000)
        self.tracker.hide()
        self.scene.addItem(self.tracker)

        # the view on the scene (no scroll bars)
        self.view = QtWidgets.QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        layout.addWidget(self.view)

        # the width and height (fixed width throughout the game)
        # TODO make this adjustable
        self.view.setFixedWidth(self.VIEW_WIDTH)
        view_height = math.floor(0.6 * self.VIEW_WIDTH)
        self.view.setFixedHeight(view_height)

        # tool bar below the mini map
        self.toolbar = QtWidgets.QToolBar()
        self.toolbar.setIconSize(QtCore.QSize(20, 20))

        # action group (only one of them can be checked at each time)
        action_group = QtWidgets.QActionGroup(self.toolbar)
        # political view in the beginning
        a = qt.create_action(tools.load_ui_icon('icon.mini.political.png'), 'Show political view', action_group,
                             toggle_connection=self.switch_to_political_view, checkable=True)
        self.toolbar.addAction(a)
        # geographical view
        a = qt.create_action(tools.load_ui_icon('icon.mini.geographical.png'), 'Show geographical view', action_group,
                             toggle_connection=self.switch_to_geographical_view, checkable=True)
        self.toolbar.addAction(a)
        self.mode = constants.OverviewMapMode.POLITICAL

        # wrap tool bar into horizontal layout with stretch
        l = QtWidgets.QHBoxLayout()
        l.setContentsMargins(0, 0, 0, 0)
        l.addWidget(self.toolbar)
        l.addStretch()

        # add layout containing tool bar
        layout.addLayout(l)

        # graphics items in scene (except the tracker)
        self.scene_items = [] 
Example 8
Project: imperialism-remake   Author: Trilarion   File: editor.py    License: GNU General Public License v3.0 4 votes vote down vote up
def __init__(self, *args, **kwargs):
        """
        Sets up the graphics view, the toolbar and the tracker rectangle.
        """
        super().__init__(*args, **kwargs)
        self.setObjectName('mini-map-widget')

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # the content is a scene
        self.scene = QtWidgets.QGraphicsScene()

        # tracker rectangle that tracks the view of the map, initially hidden
        self.tracker = QtWidgets.QGraphicsRectItem()
        self.tracker.setCursor(QtCore.Qt.PointingHandCursor)
        self.tracker.setZValue(1000)
        self.tracker.hide()
        self.scene.addItem(self.tracker)

        # the view on the scene (no scroll bars)
        self.view = QtWidgets.QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        layout.addWidget(self.view)

        # the width and height (fixed width throughout the game)
        # TODO make this adjustable
        self.view.setFixedWidth(self.VIEW_WIDTH)
        view_height = math.floor(0.6 * self.VIEW_WIDTH)
        self.view.setFixedHeight(view_height)

        # tool bar below the mini map
        self.toolbar = QtWidgets.QToolBar()
        self.toolbar.setIconSize(QtCore.QSize(20, 20))

        # action group (only one of them can be checked at each time)
        action_group = QtWidgets.QActionGroup(self.toolbar)
        # political view in the beginning
        a = qt.create_action(tools.load_ui_icon('icon.mini.political.png'), 'Show political view', action_group,
                             toggle_connection=self.switch_to_political_view, checkable=True)
        self.toolbar.addAction(a)
        # geographical view
        a = qt.create_action(tools.load_ui_icon('icon.mini.geographical.png'), 'Show geographical view', action_group,
                             toggle_connection=self.switch_to_geographical_view, checkable=True)
        self.toolbar.addAction(a)
        self.mode = constants.OverviewMapMode.POLITICAL

        # wrap tool bar into horizontal layout with stretch
        l = QtWidgets.QHBoxLayout()
        l.setContentsMargins(0, 0, 0, 0)
        l.addWidget(self.toolbar)
        l.addStretch()

        # add layout containing tool bar
        layout.addLayout(l)

        # graphics items in scene (except the tracker)
        self.scene_items = [] 
Example 9
Project: nanovna-saver   Author: NanoVNA-Saver   File: Permeability.py    License: GNU General Public License v3.0 4 votes vote down vote up
def __init__(self, name=""):
        super().__init__(name)
        self.leftMargin = 40
        self.rightMargin = 30
        self.chartWidth = 230
        self.chartHeight = 250
        self.fstart = 0
        self.fstop = 0
        self.span = 0.01
        self.max = 0
        self.logarithmicY = True

        self.maxDisplayValue = 100
        self.minDisplayValue = -100

        #
        # Set up size policy and palette
        #

        self.setMinimumSize(self.chartWidth + self.leftMargin +
                            self.rightMargin, self.chartHeight + 40)
        self.setSizePolicy(QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.MinimumExpanding,
            QtWidgets.QSizePolicy.MinimumExpanding))
        pal = QtGui.QPalette()
        pal.setColor(QtGui.QPalette.Background, self.backgroundColor)
        self.setPalette(pal)
        self.setAutoFillBackground(True)

        self.y_menu.addSeparator()
        self.y_log_lin_group = QtWidgets.QActionGroup(self.y_menu)
        self.y_action_linear = QtWidgets.QAction("Linear")
        self.y_action_linear.setCheckable(True)
        self.y_action_logarithmic = QtWidgets.QAction("Logarithmic")
        self.y_action_logarithmic.setCheckable(True)
        self.y_action_logarithmic.setChecked(True)
        self.y_action_linear.triggered.connect(lambda: self.setLogarithmicY(False))
        self.y_action_logarithmic.triggered.connect(lambda: self.setLogarithmicY(True))
        self.y_log_lin_group.addAction(self.y_action_linear)
        self.y_log_lin_group.addAction(self.y_action_logarithmic)
        self.y_menu.addAction(self.y_action_linear)
        self.y_menu.addAction(self.y_action_logarithmic) 
Example 10
Project: DownloaderForReddit   Author: MalloyDelacroix   File: UserFinderGUI_Obsolete.py    License: GNU General Public License v3.0 4 votes vote down vote up
def content_display_list_right_click(self):
        self.menu = QtWidgets.QMenu()
        try:
            position = self.content_display_list.currentRow()
            open_picture = self.menu.addAction('Open In Default Picture Viewer')
            open_folder = self.menu.addAction('Open Folder')

            self.menu.addSeparator()
            self.icons_full_width = self.menu.addAction('Icons Full List Width')
            self.icons_full_width.setCheckable(True)
            self.icon_size_menu = self.menu.addMenu('Icon Size')
            self.icon_size_group = QtWidgets.QActionGroup(self)
            self.icon_size_group.setExclusive(True)

            self.icon_size_extra_small = self.icon_size_menu.addAction('Extra Small')
            self.icon_size_extra_small.setCheckable(True)
            self.icon_size_group.addAction(self.icon_size_extra_small)
            self.icon_size_small = self.icon_size_menu.addAction('Small')
            self.icon_size_small.setCheckable(True)
            self.icon_size_group.addAction(self.icon_size_small)
            self.icon_size_medium = self.icon_size_menu.addAction('Medium')
            self.icon_size_medium.setCheckable(True)
            self.icon_size_group.addAction(self.icon_size_medium)
            self.icon_size_large = self.icon_size_menu.addAction('Large')
            self.icon_size_large.setCheckable(True)
            self.icon_size_group.addAction(self.icon_size_large)
            self.icon_size_extra_large = self.icon_size_menu.addAction('Extra Large')
            self.icon_size_extra_large.setCheckable(True)
            self.icon_size_group.addAction(self.icon_size_extra_large)
            self.set_context_menu_items_checked()

            open_picture.triggered.connect(self.open_file)
            open_folder.triggered.connect(self.open_folder)
            self.icons_full_width.triggered.connect(self.set_icons_full_width)
            self.icon_size_extra_small.triggered.connect(lambda: self.set_icon_size(48))
            self.icon_size_small.triggered.connect(lambda: self.set_icon_size(72))
            self.icon_size_medium.triggered.connect(lambda: self.set_icon_size(110))
            self.icon_size_large.triggered.connect(lambda: self.set_icon_size(176))
            self.icon_size_extra_large.triggered.connect(lambda: self.set_icon_size(256))
        except AttributeError:
            print('Exception at line 238')
        self.menu.exec(QtGui.QCursor.pos()) 
Example 11
Project: DownloaderForReddit   Author: MalloyDelacroix   File: RedditObjectSettingsDialog.py    License: GNU General Public License v3.0 4 votes vote down vote up
def content_list_right_click(self):
        """Displays a context menu for the content list."""
        menu = QtWidgets.QMenu()
        try:
            position = self.content_list.currentRow()
            open_file = menu.addAction('Open File')
            menu.addSeparator()
            icons_full_width = menu.addAction('Icons Full List Width')
            icons_full_width.setCheckable(True)
            icon_size_menu = menu.addMenu('Icon Size')
            icon_size_group = QtWidgets.QActionGroup(self)
            icon_size_group.setExclusive(True)

            icon_size_extra_small = icon_size_menu.addAction('Extra Small')
            icon_size_extra_small.setCheckable(True)
            icon_size_group.addAction(icon_size_extra_small)
            icon_size_small = icon_size_menu.addAction('Small')
            icon_size_small.setCheckable(True)
            icon_size_group.addAction(icon_size_small)
            icon_size_medium = icon_size_menu.addAction('Medium')
            icon_size_medium.setCheckable(True)
            icon_size_group.addAction(icon_size_medium)
            icon_size_large = icon_size_menu.addAction('Large')
            icon_size_large.setCheckable(True)
            icon_size_group.addAction(icon_size_large)
            icon_size_extra_large = icon_size_menu.addAction('Extra Large')
            icon_size_extra_large.setCheckable(True)
            icon_size_group.addAction(icon_size_extra_large)

            check_dict = {
                48: icon_size_extra_small,
                72: icon_size_small,
                110: icon_size_medium,
                176: icon_size_large,
                256: icon_size_extra_large
            }

            if self.content_icons_full_width:
                icons_full_width.setChecked(True)
            else:
                icons_full_width.setChecked(False)
                check_dict[self.content_icon_size].setChecked(True)

            open_file.triggered.connect(self.open_file)
            icons_full_width.triggered.connect(self.set_icons_full_width)
            icon_size_extra_small.triggered.connect(lambda: self.set_icon_size(48))
            icon_size_small.triggered.connect(lambda: self.set_icon_size(72))
            icon_size_medium.triggered.connect(lambda: self.set_icon_size(110))
            icon_size_large.triggered.connect(lambda: self.set_icon_size(176))
            icon_size_extra_large.triggered.connect(lambda: self.set_icon_size(256))

        except AttributeError:
            self.logger.error('Failed to display content list context menu', exc_info=True)
        menu.exec(QtGui.QCursor.pos()) 
Example 12
Project: pandasgui   Author: adamerose   File: gui.py    License: MIT License 4 votes vote down vote up
def make_menu_bar(self):
        '''
        Make the menubar and add it to the QMainWindow
        '''
        # Create a menu for setting the GUI style.
        # Uses radio-style buttons in a QActionGroup.
        menubar = self.menuBar()

        # Creates an edit menu
        editMenu = menubar.addMenu('&Edit')
        findAction = QtWidgets.QAction('&Find', self)
        findAction.setShortcut('Ctrl+F')
        findAction.triggered.connect(self.findBar.show_find_bar)
        editMenu.addAction(findAction)

        styleMenu = menubar.addMenu('&Set Style')
        styleGroup = QtWidgets.QActionGroup(styleMenu)

        # Add an option to the menu for each GUI style that exist for the user's system
        for style in QtWidgets.QStyleFactory.keys():
            styleAction = QtWidgets.QAction(f'&{style}', self, checkable=True)
            styleAction.triggered.connect(
                lambda state, style=style: self.app.setStyle(style) and self.app.setStyleSheet(""))
            styleGroup.addAction(styleAction)
            styleMenu.addAction(styleAction)
        # Set the default style
        styleAction.trigger()

        # Creates a debug menu.
        debugMenu = menubar.addMenu('&Debug')
        testDialogAction = QtWidgets.QAction('&Test', self)
        testDialogAction.triggered.connect(self.test)
        debugMenu.addAction(testDialogAction)

        '''
        # Creates a chart menu.
        chartMenu = menubar.addMenu('&Plot Charts')
        scatterDialogAction = QtWidgets.QAction('&Scatter Dialog', self)
        scatterDialogAction.triggered.connect(self.scatter_dialog)
        chartMenu.addAction(scatterDialogAction)

        # Creates a reshaping menu.
        chartMenu = menubar.addMenu('&Reshape Data')
        pivotDialogAction = QtWidgets.QAction('&Pivot Dialog', self)
        pivotDialogAction.triggered.connect(self.pivot_dialog)
        chartMenu.addAction(pivotDialogAction)
        '''

    # I just use this function for printing various things to console while the GUI is running 
Example 13
Project: urh   Author: jopohl   File: SimulatorMessageTableView.py    License: GNU General Public License v3.0 4 votes vote down vote up
def create_context_menu(self) -> QMenu:
        menu = super().create_context_menu()

        if self.selection_is_empty:
            return menu

        menu.addSeparator()
        self._add_insert_column_menu(menu)
        menu.addSeparator()

        selected_encoding = self.selected_message.decoder

        if not all(self.model().protocol.messages[i].decoder is selected_encoding
                   for i in self.selected_rows):
            selected_encoding = None

        encoding_group = QActionGroup(self)
        encoding_menu = menu.addMenu("Enforce encoding")

        for decoding in self.model().project_manager.decodings:
            ea = encoding_menu.addAction(decoding.name)
            ea.setCheckable(True)
            ea.setActionGroup(encoding_group)

            if selected_encoding == decoding:
                ea.setChecked(True)

            ea.setData(decoding)
            ea.triggered.connect(self.on_encoding_action_triggered)

        if settings.read("multiple_modulations", False, bool):
            selected_modulation = self.model().protocol.messages[self.selected_rows[0]].modulator_index

            if not all(self.model().protocol.messages[i].modulator_index == selected_modulation
                       for i in self.selected_rows):
                selected_modulation = -1

            modulation_group = QActionGroup(self)
            modulation_menu = menu.addMenu("Modulation")

            for i, modulator in enumerate(self.model().project_manager.modulators):
                ma = modulation_menu.addAction(modulator.name)
                ma.setCheckable(True)
                ma.setActionGroup(modulation_group)

                if selected_modulation == i:
                    ma.setChecked(True)

                ma.setData(i)
                ma.triggered.connect(self.on_modulation_action_triggered)

            open_modulator_dialog_action = modulation_menu.addAction(self.tr("..."))
            open_modulator_dialog_action.triggered.connect(self.on_open_modulator_dialog_action_triggered)

        return menu 
Example 14
Project: urh   Author: jopohl   File: GeneratorTableView.py    License: GNU General Public License v3.0 4 votes vote down vote up
def create_context_menu(self) -> QMenu:
        menu = super().create_context_menu()

        add_message_action = menu.addAction("Add empty message...")
        add_message_action.setIcon(QIcon.fromTheme("edit-table-insert-row-below"))
        add_message_action.triggered.connect(self.on_add_message_action_triggered)

        if not self.selection_is_empty:
            menu.addAction(self.copy_action)

        if self.model().row_count > 0:
            duplicate_action = menu.addAction("Duplicate selected lines")
            duplicate_action.setIcon(QIcon.fromTheme("edit-table-insert-row-under"))
            duplicate_action.triggered.connect(self.on_duplicate_action_triggered)

            self._add_insert_column_menu(menu)

            menu.addSeparator()
            clear_action = menu.addAction("Clear table")
            clear_action.triggered.connect(self.on_clear_action_triggered)
            clear_action.setIcon(QIcon.fromTheme("edit-clear"))

        self.encoding_actions = {}

        if not self.selection_is_empty:
            selected_encoding = self.model().protocol.messages[self.selected_rows[0]].decoder
            for i in self.selected_rows:
                if self.model().protocol.messages[i].decoder != selected_encoding:
                    selected_encoding = None
                    break

            menu.addSeparator()
            encoding_group = QActionGroup(self)
            encoding_menu = menu.addMenu("Enforce encoding")

            for decoding in self.model().decodings:
                ea = encoding_menu.addAction(decoding.name)
                ea.setCheckable(True)
                ea.setActionGroup(encoding_group)
                if selected_encoding == decoding:
                    ea.setChecked(True)

                self.encoding_actions[ea] = decoding
                ea.triggered.connect(self.on_encoding_action_triggered)

            menu.addSeparator()
            de_bruijn_action = menu.addAction("Generate De Bruijn Sequence from Selection")
            de_bruijn_action.triggered.connect(self.on_de_bruijn_action_triggered)

        return menu