Esempio n. 1
0
    def on_change(self):
        text = self.txt_entry.text()
        value = err = None
        try:
            value = Keycode.deserialize(text, reraise=True)
        except Exception as e:
            err = str(e)

        if not text:
            self.value = -1
            self.lbl_computed.setText(
                tr("AnyKeycodeDialog", "Enter an expression"))
        elif err:
            self.value = -1
            self.lbl_computed.setText(
                tr("AnyKeycodeDialog", "Invalid input: {}").format(err))
        elif isinstance(value, int):
            self.value = value
            self.lbl_computed.setText(
                tr("AnyKeycodeDialog", "Computed value: 0x{:X}").format(value))
        else:
            self.value = -1
            self.lbl_computed.setText(tr("AnyKeycodeDialog", "Invalid input"))

        self.buttons.button(
            QDialogButtonBox.Ok).setEnabled(0 <= self.value < 2**16)
Esempio n. 2
0
    def __init__(self):
        super(BoardWidget, self).__init__()


        self.cursor = None
        self.squares = BoardItem()
        self.palette = PaletteWidget(PaletteItem())

        self._selected_square = None
        self._editable = True

        # FIXME: cannot set editable until we the board is set from setFen becuase
        # we do not have a cursor yet
        #self.editable = True

        self.squares.setParentItem(self)
        self.palette.setParentItem(self)
        self.palette.setPos(settings.boardSize()+ self.spacing, 0)

        #fen
        self.fen = FenWidget(self.squares)
        self.fen.setParentItem(self)
        self.fen.setPos(settings.boardSize()+ self.spacing + self.palette.size().width(), 0)
        self.fen.setOrientation(QtCore.Qt.Vertical)

        actions = [
            Action(self, "New Board", settings.keys['board_new'], tr("reset to starting"), self._onNewBoard, 'document-new'),
            Action(self, "Clear Board", settings.keys['board_clear'], tr("remove pieces"), self._onClearBoard, 'edit-clear'),
            Action(self, "Flip Board", settings.keys['board_flip'], tr("flip board"), self._onFlipBoard, 'edit-clear'),
        ]
        self.addActions(actions)
        new, clear, flip = [a.graphics_button for a in self.actions()]
        new.setParentItem(self.palette)
        clear.setParentItem(self.palette)
        clear.setPos(new.size().width(), 0)
Esempio n. 3
0
    def __init__(self, container):
        super().__init__(container)

        row = container.rowCount()

        self.lbl_backlight_brightness = QLabel(
            tr("RGBConfigurator", "Backlight Brightness"))
        container.addWidget(self.lbl_backlight_brightness, row, 0)
        self.backlight_brightness = QSlider(QtCore.Qt.Horizontal)
        self.backlight_brightness.setMinimum(0)
        self.backlight_brightness.setMaximum(255)
        self.backlight_brightness.valueChanged.connect(
            self.on_backlight_brightness_changed)
        container.addWidget(self.backlight_brightness, row, 1)

        self.lbl_backlight_breathing = QLabel(
            tr("RGBConfigurator", "Backlight Breathing"))
        container.addWidget(self.lbl_backlight_breathing, row + 1, 0)
        self.backlight_breathing = QCheckBox()
        self.backlight_breathing.stateChanged.connect(
            self.on_backlight_breathing_changed)
        container.addWidget(self.backlight_breathing, row + 1, 1)

        self.widgets = [
            self.lbl_backlight_brightness, self.backlight_brightness,
            self.lbl_backlight_breathing, self.backlight_breathing
        ]
Esempio n. 4
0
    def __init__(self,
                 text="",
                 file_extension="txt",
                 file_type="Text file",
                 encoding="utf-8"):
        super().__init__()

        self.text = text
        self.file_extension = file_extension
        self.file_type = file_type
        self.encoding = encoding

        self.control_held = False

        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)

        vbox = QVBoxLayout()

        self.macrotext = QPlainTextEdit()
        self.macrotext.setPlainText(text)
        self.macrotext.selectAll()

        self.btn_apply = QToolButton()
        self.btn_apply.setText(tr("TextboxWindow", "Apply"))
        self.btn_apply.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_apply.clicked.connect(self.on_apply)

        self.btn_cancel = QToolButton()
        self.btn_cancel.setText(tr("TextboxWindow", "Cancel"))
        self.btn_cancel.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_cancel.clicked.connect(self.on_cancel)

        self.btn_copy = QToolButton()
        self.btn_copy.setText(tr("TextboxWindow", "Copy"))
        self.btn_copy.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_copy.clicked.connect(self.on_copy)

        self.btn_paste = QToolButton()
        self.btn_paste.setText(tr("TextboxWindow", "Paste"))
        self.btn_paste.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_paste.clicked.connect(self.on_paste)

        bottom_buttons = QHBoxLayout()
        bottom_buttons.setContentsMargins(0, 0, 0, 0)
        bottom_buttons.addWidget(self.btn_copy)
        bottom_buttons.addWidget(self.btn_paste)
        bottom_buttons.addSpacing(15)
        bottom_buttons.addStretch()
        bottom_buttons.addWidget(self.btn_apply)
        bottom_buttons.addWidget(self.btn_cancel)

        self.bottom_widget = QWidget()
        self.bottom_widget.setLayout(bottom_buttons)

        vbox.addWidget(self.macrotext, stretch=1)
        vbox.addWidget(self.bottom_widget)

        self.setLayout(vbox)
        self.setWindowFlags(self.windowFlags())
Esempio n. 5
0
    def __init__(self):
        super(ChessWidget, self).__init__()

        #scene
        game_engine = NewGameEngine()
        self.scene = ChessScene(game_engine)

        #side_bar
        #FIXME bad rect / geometry
        side = settings.boardSize()
        side = self.scene.board.squares.rect().width()
        x = side + self.scene.board.spacing - 2
        w = self.scene.board.palette.item.rect().width()
        h = self.scene.board.palette.item.rect().height()
        rect = QtCore.QRectF(x, 0, w, h)

        sidebar = FocusingView(self.scene, self.scene.board.palette, rect)
        #sidebar.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

        #actions
        actions = [
            Action(self, "Play", settings.keys['mode_play'], tr("play game"), self.onShowMoves, 'media-playback-start'),
            Action(self, "Edit", settings.keys['mode_edit'], tr("set board position"), self.onShowPallete, 'document-edit')
        ]

        self.addActions(actions)
        group = QtGui.QActionGroup(sidebar.toolbar)
        group.setExclusive(True)
        for action in actions:
            action.setCheckable(True)
            group.addAction(action)
        actions[0].activate(QtGui.QAction.Trigger)
        sidebar.toolbar.addActions(self.actions())

        #board
        side = settings.boardSize()
        rect = QtCore.QRectF(0, 0, side, side)
        board = FocusingView(self.scene, self.scene.board.squares, rect)

        board.toolbar.addActions(self.scene.moves.actions())
        board.toolbar.addActions(self.scene.board.actions())

        b = self.scene.board
        actions = [
            Action(self, "Guides", settings.keys['board_guides'], tr("toggle guides"), b.toggleGuides, ''),
            Action(self, "Labels", settings.keys['board_labels'], tr("toggle square labels"), b.toggleLabels, ''),
        ]
        board.toolbar.addActions(actions)
        
        #layout
        layout = QtGui.QHBoxLayout()
        layout.addWidget(board)
        layout.addWidget(sidebar)
        layout.setContentsMargins(0,0,0,0)
        layout.setAlignment(sidebar, QtCore.Qt.AlignRight)
        self.setLayout(layout)
Esempio n. 6
0
    def __init__(self):
        super().__init__()

        self.keyboard = None
        self.suppress_change = False

        self.keystrokes = []
        self.macro_tabs = []
        self.macro_tab_w = []

        self.recorder = None

        if sys.platform.startswith("linux"):
            from macro_recorder_linux import LinuxRecorder

            self.recorder = LinuxRecorder()
        elif sys.platform.startswith("win"):
            from macro_recorder_windows import WindowsRecorder

            self.recorder = WindowsRecorder()

        if self.recorder:
            self.recorder.keystroke.connect(self.on_keystroke)
            self.recorder.stopped.connect(self.on_stop)
        self.recording = False

        self.recording_tab = None
        self.recording_append = False

        self.tabs = QTabWidget()
        for x in range(32):
            tab = MacroTab(self, self.recorder is not None)
            tab.changed.connect(self.on_change)
            tab.record.connect(self.on_record)
            tab.record_stop.connect(self.on_tab_stop)
            self.macro_tabs.append(tab)
            w = QWidget()
            w.setLayout(tab)
            self.macro_tab_w.append(w)

        self.lbl_memory = QLabel()

        buttons = QHBoxLayout()
        buttons.addWidget(self.lbl_memory)
        buttons.addStretch()
        self.btn_save = QPushButton(tr("MacroRecorder", "Save"))
        self.btn_save.clicked.connect(self.on_save)
        btn_revert = QPushButton(tr("MacroRecorder", "Revert"))
        btn_revert.clicked.connect(self.on_revert)
        buttons.addWidget(self.btn_save)
        buttons.addWidget(btn_revert)

        self.addWidget(self.tabs)
        self.addLayout(buttons)
Esempio n. 7
0
    def __init__(self):

        super(ChessGameWidget, self).__init__()

        # board
        self.board = BoardWidget()
        self.board.setParentItem(self)

        # moves
        game_engine = ChessLibGameEngine()
        self.moves = MovesWidget(self.board, game_engine)
        self.moves.newGame()

        self.fen = self.board.fen.text
        self.fen.setParentItem(self.board)
        self.fen.setPos(0, -40)

        # actions
        actions = [
            Action(self, "Play", settings.keys["mode_play"], tr("play game"), self.onShowMoves, "media-playback-start"),
            Action(
                self, "Edit", settings.keys["mode_edit"], tr("set board position"), self.onShowPallete, "document-edit"
            ),
            Action(
                self,
                "Analyze",
                settings.keys["mode_analyze"],
                tr("analyze position"),
                self.onShowAnalyze,
                "games-solve",
            ),
        ]
        self._buttons = [b.graphics_button for b in actions]
        for button in self._buttons:
            button._checkable = True
            button._radio = True
        self.addActions(actions)

        size = self.moves.preferredSize()
        x, y = self.board.squares.size().width() + self.board.spacing, size.height()
        self._pack_actions(self.moves.actions(), x + 10, y + 10, False)

        self.onShowMoves()

        layout = QtGui.QGraphicsLinearLayout()
        buttons = self.getGraphicsButtonLayout()
        layout.addItem(buttons)
        layout.setAlignment(buttons, QtCore.Qt.AlignRight)
        layout.addItem(self.moves)
        layout.addItem(self.board)
        layout.setOrientation(QtCore.Qt.Vertical)
        self.setLayout(layout)
Esempio n. 8
0
	def __init__(self, board, game_engine):
		super(MoveTable, self).__init__()

		self.board = board
		self.game_engine = game_engine
		self.move_list = None

		self.board.newMove.connect(self.onNewMove)

		self.toolbar.addAction("|<", 'first_move', tr("first move"), self.firstMove, 'go-first')
		self.toolbar.addAction("<", 'previous_move', tr("previous move"), self.previousMove, 'go-previous')
		self.toolbar.addAction(">", 'next_move', tr("next move"), self.nextMove, 'go-next')
		self.toolbar.addAction(">|", 'last_move', tr("last move"), self.lastMove, 'go-last')
		self.toolbar.addAction("R", 'reload_board', tr("reload board"), self.reload, 'edit-redo')
Esempio n. 9
0
    def __init__(self):
        super().__init__()

        self.addStretch()

        w = QWidget()
        w.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        self.container = QGridLayout()
        w.setLayout(self.container)
        self.addWidget(w)
        self.setAlignment(w, QtCore.Qt.AlignHCenter)

        self.handler_backlight = QmkBacklightHandler(self.container)
        self.handler_backlight.update.connect(self.update_from_keyboard)
        self.handler_rgblight = QmkRgblightHandler(self.container)
        self.handler_rgblight.update.connect(self.update_from_keyboard)
        self.handler_vialrgb = VialRGBHandler(self.container)
        self.handler_vialrgb.update.connect(self.update_from_keyboard)
        self.handlers = [
            self.handler_backlight, self.handler_rgblight, self.handler_vialrgb
        ]

        self.addStretch()
        buttons = QHBoxLayout()
        buttons.addStretch()
        save_btn = QPushButton(tr("RGBConfigurator", "Save"))
        buttons.addWidget(save_btn)
        save_btn.clicked.connect(self.on_save)
        self.addLayout(buttons)
Esempio n. 10
0
 def reset_settings(self):
     if QMessageBox.question(
             self.widget(), "",
             tr("QmkSettings", "Reset all settings to default values?"),
             QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
         self.keyboard.qmk_settings_reset()
         self.reload_settings()
Esempio n. 11
0
    def __init__(self, initial):
        super().__init__()

        self.setWindowTitle(tr("AnyKeycodeDialog", "Enter an arbitrary keycode"))

        self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        self.lbl_computed = QLabel()
        self.txt_entry = QLineEdit()
        self.txt_entry.textChanged.connect(self.on_change)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.txt_entry)
        self.layout.addWidget(self.lbl_computed)
        self.layout.addWidget(self.buttons)
        self.setLayout(self.layout)

        self.value = initial
        ser = Keycode.serialize(initial)
        if isinstance(ser, int):
            ser = hex(ser)
        self.txt_entry.setText(ser)
        self.on_change()
Esempio n. 12
0
    def __init__(self, layout_editor):
        super().__init__()

        self.layout_editor = layout_editor

        self.layout_layers = QHBoxLayout()
        layer_label = QLabel(tr("KeyboardContainer", "Layer"))

        layout_labels_container = QHBoxLayout()
        layout_labels_container.addWidget(layer_label)
        layout_labels_container.addLayout(self.layout_layers)
        layout_labels_container.addStretch()

        # contains the actual keyboard
        self.container = KeyboardWidget(layout_editor)
        self.container.clicked.connect(self.on_key_clicked)

        layout = QVBoxLayout()
        layout.addLayout(layout_labels_container)
        layout.addWidget(self.container)
        layout.setAlignment(self.container, Qt.AlignHCenter)
        self.setLayout(layout)

        self.layer_buttons = []
        self.keyboard = None
        self.current_layer = 0

        layout_editor.changed.connect(self.on_layout_changed)

        self.keymap_override = KEYMAPS[0][1]
Esempio n. 13
0
    def refresh_tabs(self):
        self.tabs.clear()
        for container, lbl in self.editors:
            if not container.valid():
                continue

            c = EditorContainer(container)
            self.tabs.addTab(c, tr("MainWindow", lbl))
Esempio n. 14
0
    def __init__(self, container):
        super().__init__(container)

        row = container.rowCount()

        self.lbl_rgb_effect = QLabel(tr("RGBConfigurator", "RGB Effect"))
        container.addWidget(self.lbl_rgb_effect, row, 0)
        self.rgb_effect = QComboBox()
        self.rgb_effect.addItem("0")
        self.rgb_effect.addItem("1")
        self.rgb_effect.addItem("2")
        self.rgb_effect.addItem("3")
        self.rgb_effect.currentIndexChanged.connect(self.on_rgb_effect_changed)
        container.addWidget(self.rgb_effect, row, 1)

        self.lbl_rgb_color = QLabel(tr("RGBConfigurator", "RGB Color"))
        container.addWidget(self.lbl_rgb_color, row + 1, 0)
        self.rgb_color = ClickableLabel(" ")
        self.rgb_color.clicked.connect(self.on_rgb_color)
        container.addWidget(self.rgb_color, row + 1, 1)

        self.lbl_rgb_brightness = QLabel(
            tr("RGBConfigurator", "RGB Brightness"))
        container.addWidget(self.lbl_rgb_brightness, row + 2, 0)
        self.rgb_brightness = QSlider(QtCore.Qt.Horizontal)
        self.rgb_brightness.setMinimum(0)
        self.rgb_brightness.setMaximum(255)
        self.rgb_brightness.valueChanged.connect(
            self.on_rgb_brightness_changed)
        container.addWidget(self.rgb_brightness, row + 2, 1)

        self.lbl_rgb_speed = QLabel(tr("RGBConfigurator", "RGB Speed"))
        container.addWidget(self.lbl_rgb_speed, row + 3, 0)
        self.rgb_speed = QSlider(QtCore.Qt.Horizontal)
        self.rgb_speed.setMinimum(0)
        self.rgb_speed.setMaximum(255)
        self.rgb_speed.valueChanged.connect(self.on_rgb_speed_changed)
        container.addWidget(self.rgb_speed, row + 3, 1)

        self.widgets = [
            self.lbl_rgb_effect, self.rgb_effect, self.lbl_rgb_brightness,
            self.rgb_brightness, self.lbl_rgb_color, self.rgb_color,
            self.lbl_rgb_speed, self.rgb_speed
        ]

        self.effects = []
Esempio n. 15
0
    def recreate_keycode_buttons(self):
        while self.count() > 0:
            self.removeTab(0)

        for tab in self.tabs:
            tab.recreate_buttons()
            if tab.buttons:
                self.addTab(tab.container, tr("TabbedKeycodes", tab.label))
Esempio n. 16
0
    def __init__(self, layout_editor, keyboard):
        super().__init__()

        self.keyboard = keyboard

        layout = QVBoxLayout()

        self.progress = QProgressBar()

        layout.addWidget(
            QLabel(
                tr(
                    "Unlocker",
                    "In order to proceed, the keyboard must be set into unlocked mode.\n"
                    "You should only perform this operation on computers that you trust."
                )))
        layout.addWidget(
            QLabel(
                tr(
                    "Unlocker",
                    "To exit this mode, you will need to replug the keyboard\n"
                    "or select Security->Lock from the menu.")))
        layout.addWidget(
            QLabel(
                tr(
                    "Unlocker",
                    "Press and hold the following keys until the progress bar "
                    "below fills up:")))

        self.keyboard_reference = KeyboardWidget(layout_editor)
        self.keyboard_reference.set_enabled(False)
        self.keyboard_reference.set_scale(0.5)
        layout.addWidget(self.keyboard_reference)
        layout.setAlignment(self.keyboard_reference, Qt.AlignHCenter)

        layout.addWidget(self.progress)

        self.setLayout(layout)
        self.setWindowFlags(Qt.Dialog | Qt.WindowTitleHint
                            | Qt.CustomizeWindowHint)

        self.update_reference()
        self.timer = QTimer()
        self.timer.timeout.connect(self.unlock_poller)
        self.perform_unlock()
Esempio n. 17
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.keymap_override = None

        self.tab_basic = QScrollArea()
        self.tab_iso = QScrollArea()
        self.tab_layers = QScrollArea()
        self.tab_quantum = QScrollArea()
        self.tab_backlight = QScrollArea()
        self.tab_media = QScrollArea()
        self.tab_user = QScrollArea()
        self.tab_macro = QScrollArea()

        self.widgets = []

        for (tab, label, keycodes) in [
            (self.tab_basic, "Basic",
             KEYCODES_SPECIAL + KEYCODES_BASIC + KEYCODES_SHIFTED),
            (self.tab_iso, "ISO/JIS", KEYCODES_ISO),
            (self.tab_layers, "Layers", KEYCODES_LAYERS),
            (self.tab_quantum, "Quantum", KEYCODES_QUANTUM),
            (self.tab_backlight, "Backlight", KEYCODES_BACKLIGHT),
            (self.tab_media, "App, Media and Mouse", KEYCODES_MEDIA),
            (self.tab_user, "User", KEYCODES_USER),
            (self.tab_macro, "Macro", KEYCODES_MACRO),
        ]:
            layout = FlowLayout()
            if tab == self.tab_layers:
                self.layout_layers = layout
            elif tab == self.tab_macro:
                self.layout_macro = layout
            elif tab == self.tab_user:
                self.layout_user = layout
            elif tab == self.tab_basic:
                # create the "Any" keycode button
                btn = SquareButton()
                btn.setText("Any")
                btn.setRelSize(KEYCODE_BTN_RATIO)
                btn.clicked.connect(lambda: self.anykey.emit())
                layout.addWidget(btn)

            self.widgets += self.create_buttons(layout, keycodes)

            tab.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            tab.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            tab.setWidgetResizable(True)

            w = QWidget()
            w.setLayout(layout)
            tab.setWidget(w)
            self.addTab(tab, tr("TabbedKeycodes", label))

        self.layer_keycode_buttons = []
        self.macro_keycode_buttons = []
        self.user_keycode_buttons = []
        self.set_keymap_override(KEYMAPS[0][1])
Esempio n. 18
0
    def refresh_tabs(self):
        self.tabs.clear()
        for container, lbl in self.editors:
            if not container.valid():
                continue

            w = QWidget()
            w.setLayout(container)
            self.tabs.addTab(w, tr("MainWindow", lbl))
Esempio n. 19
0
    def __init__(self, main, parent=None):
        super().__init__(parent)

        self.main = main

        self.log_signal.connect(self._on_log)
        self.progress_signal.connect(self._on_progress)
        self.complete_signal.connect(self._on_complete)
        self.error_signal.connect(self._on_error)

        self.selected_firmware_path = ""

        file_selector = QHBoxLayout()
        self.txt_file_selector = QLineEdit()
        self.txt_file_selector.setReadOnly(True)
        file_selector.addWidget(self.txt_file_selector)
        self.btn_select_file = QToolButton()
        self.btn_select_file.setText(tr("Flasher", "Select file..."))
        self.btn_select_file.clicked.connect(self.on_click_select_file)
        file_selector.addWidget(self.btn_select_file)
        self.addLayout(file_selector)
        self.txt_logger = QPlainTextEdit()
        self.txt_logger.setReadOnly(True)
        self.txt_logger.setFont(
            QFontDatabase.systemFont(QFontDatabase.FixedFont))
        self.addWidget(self.txt_logger)
        progress_flash = QHBoxLayout()
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        progress_flash.addWidget(self.progress_bar)
        self.btn_flash = QToolButton()
        self.btn_flash.setText(tr("Flasher", "Flash"))
        self.btn_flash.clicked.connect(self.on_click_flash)
        progress_flash.addWidget(self.btn_flash)
        self.chk_restore_keymap = QCheckBox(
            tr("Flasher", "Restore current layout after flashing"))
        self.chk_restore_keymap.setChecked(True)
        self.addWidget(self.chk_restore_keymap)
        self.addLayout(progress_flash)

        self.device = None

        self.layout_restore = self.uid_restore = None
Esempio n. 20
0
 def set_theme(self, theme):
     themes.set_theme(theme)
     self.settings.setValue("theme", theme)
     msg = QMessageBox()
     msg.setText(
         tr(
             "MainWindow",
             "In order to fully apply the theme you should restart the application."
         ))
     msg.exec_()
Esempio n. 21
0
    def __init__(self, game_engine):

        super(ChessScene, self).__init__()

        #board
        self.board = BoardWidget()
        self.addItem(self.board)

        #moves
        self.moves = MovesWidget(self.board, game_engine)
        self.board.boardChanged.connect(self.moves.resetEngine)
        self.addItem(self.moves)

        #fen
        self.addItem(self.board.fen)

        self.moves.setPos(0, 0)
        size = self.moves.preferredSize()
        self.board.setPos(0, size.height())

        #opening_table
        #self.opening_table = OpeningTable()
        #self.move_table.moveMade.connect(self.opening_table.onMoveMade)

        #game engine
        self.setEngine(game_engine)
        self.newGame()

        #actions
        actions = [
            Action(self, "Play", settings.keys['mode_play'], tr("play game"), self.onShowMoves, 'media-playback-start'),
            Action(self, "Edit", settings.keys['mode_edit'], tr("set board position"), self.onShowPallete, 'document-open')
        ]
        #FIXME
        #self.addActions(actions)

        play, edit = [a.graphics_button for a in actions]
        self.addItem(play)
        self.addItem(edit)
        rect = self.board.squares.boundingRect()
        play.setPos(rect.width(), 0)
        edit.setPos(rect.width() + play.size().width(), 0)
        self.onShowMoves()
Esempio n. 22
0
    def __init__(self, getsquare_callback, algsquare):
        super(CursorWidget, self).__init__()
        self.item = CursorItem(algsquare)
        self.item.setParentItem(self)
        self.getsquare_callback = getsquare_callback

        self._use_palette = True

        direcs = ['north', 'northeast', 'east', 'southeast', 'south', 'southwest', 'west', 'northwest']
        for direc in direcs:
            action = Action(
                self, direc, 
                settings.keys['cursor_%s' % direc], 
                tr("cursor %s"), 
                getattr(self, 'on%s' % direc.capitalize()),
                ''
            )
            self.addAction(action)
        action = Action(self, 'Cursor Select', settings.keys['cursor_select'], tr("select cursor square"), self.onCursorSelect, '')
        self.addAction(action)
Esempio n. 23
0
    def __init__(self):
        super().__init__()
        self.keyboard = None

        self.tabs_widget = QTabWidget()
        self.addWidget(self.tabs_widget)
        buttons = QHBoxLayout()
        buttons.addStretch()
        self.btn_save = QPushButton(tr("QmkSettings", "Save"))
        self.btn_save.clicked.connect(self.save_settings)
        buttons.addWidget(self.btn_save)
        self.btn_undo = QPushButton(tr("QmkSettings", "Undo"))
        self.btn_undo.clicked.connect(self.reload_settings)
        buttons.addWidget(self.btn_undo)
        btn_reset = QPushButton(tr("QmkSettings", "Reset"))
        btn_reset.clicked.connect(self.reset_settings)
        buttons.addWidget(btn_reset)
        self.addLayout(buttons)

        self.tabs = []
        self.misc_widgets = []
Esempio n. 24
0
    def __init__(self, board=tr('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')):

        cls = self.__class__
        self.string = (str(board).split()[0].replace('/','').
                replace('8', cls.EMPTY_SQUARE * 8).
                replace('7', cls.EMPTY_SQUARE * 7).
                replace('6', cls.EMPTY_SQUARE * 6).
                replace('5', cls.EMPTY_SQUARE * 5).
                replace('4', cls.EMPTY_SQUARE * 4).
                replace('3', cls.EMPTY_SQUARE * 3).
                replace('2', cls.EMPTY_SQUARE * 2).
                replace('1', cls.EMPTY_SQUARE * 1)
        )
Esempio n. 25
0
    def __init__(self, container):
        super().__init__(container)

        row = container.rowCount()

        self.lbl_underglow_effect = QLabel(
            tr("RGBConfigurator", "Underglow Effect"))
        container.addWidget(self.lbl_underglow_effect, row, 0)
        self.underglow_effect = QComboBox()
        for ef in QMK_RGBLIGHT_EFFECTS:
            self.underglow_effect.addItem(ef.name)
        container.addWidget(self.underglow_effect, row, 1)

        self.lbl_underglow_brightness = QLabel(
            tr("RGBConfigurator", "Underglow Brightness"))
        container.addWidget(self.lbl_underglow_brightness, row + 1, 0)
        self.underglow_brightness = QSlider(QtCore.Qt.Horizontal)
        self.underglow_brightness.setMinimum(0)
        self.underglow_brightness.setMaximum(255)
        self.underglow_brightness.valueChanged.connect(
            self.on_underglow_brightness_changed)
        container.addWidget(self.underglow_brightness, row + 1, 1)

        self.lbl_underglow_color = QLabel(
            tr("RGBConfigurator", "Underglow Color"))
        container.addWidget(self.lbl_underglow_color, row + 2, 0)
        self.underglow_color = ClickableLabel(" ")
        self.underglow_color.clicked.connect(self.on_underglow_color)
        container.addWidget(self.underglow_color, row + 2, 1)

        self.underglow_effect.currentIndexChanged.connect(
            self.on_underglow_effect_changed)

        self.widgets = [
            self.lbl_underglow_effect, self.underglow_effect,
            self.lbl_underglow_brightness, self.underglow_brightness,
            self.lbl_underglow_color, self.underglow_color
        ]
Esempio n. 26
0
 def restore_layout(self, data):
     if json.loads(
             data.decode("utf-8")).get("uid") != self.keyboard.keyboard_id:
         ret = QMessageBox.question(
             self.widget(), "",
             tr(
                 "KeymapEditor",
                 "Saved keymap belongs to a different keyboard,"
                 " are you sure you want to continue?"),
             QMessageBox.Yes | QMessageBox.No)
         if ret != QMessageBox.Yes:
             return
     self.keyboard.restore_layout(data)
     self.refresh_layer_display()
Esempio n. 27
0
    def __init__(self):
        super().__init__()
        self.keyboard = None

        self.tap_dance_entries = []
        self.tap_dance_entries_available = []
        self.tabs = CustomTabWidget()
        for x in range(128):
            entry = TapDanceEntryUI(x)
            entry.key_changed.connect(self.on_key_changed)
            entry.timing_changed.connect(self.on_timing_changed)
            self.tap_dance_entries_available.append(entry)

        self.addWidget(self.tabs)
        buttons = QHBoxLayout()
        buttons.addStretch()
        self.btn_save = QPushButton(tr("TapDance", "Save"))
        self.btn_save.clicked.connect(self.on_save)
        btn_revert = QPushButton(tr("TapDance", "Revert"))
        btn_revert.clicked.connect(self.on_revert)
        buttons.addWidget(self.btn_save)
        buttons.addWidget(btn_revert)
        self.addLayout(buttons)
Esempio n. 28
0
    def __init__(self, parent, enable_recorder):
        super().__init__()

        self.parent = parent

        self.lines = []

        self.container = QGridLayout()

        menu_record = QMenu()
        menu_record.addAction(tr("MacroRecorder", "Append to current"))\
            .triggered.connect(lambda: self.record.emit(self, True))
        menu_record.addAction(tr("MacroRecorder", "Replace everything"))\
            .triggered.connect(lambda: self.record.emit(self, False))

        self.btn_record = QPushButton(tr("MacroRecorder", "Record macro"))
        self.btn_record.setMenu(menu_record)
        if not enable_recorder:
            self.btn_record.hide()

        self.btn_record_stop = QPushButton(tr("MacroRecorder", "Stop recording"))
        self.btn_record_stop.clicked.connect(lambda: self.record_stop.emit())
        self.btn_record_stop.hide()

        self.btn_add = QToolButton()
        self.btn_add.setText(tr("MacroRecorder", "Add action"))
        self.btn_add.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_add.clicked.connect(self.on_add)

        self.btn_tap_enter = QToolButton()
        self.btn_tap_enter.setText(tr("MacroRecorder", "Tap Enter"))
        self.btn_tap_enter.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_tap_enter.clicked.connect(self.on_tap_enter)

        layout_buttons = QHBoxLayout()
        layout_buttons.addStretch()
        layout_buttons.addWidget(self.btn_add)
        layout_buttons.addWidget(self.btn_tap_enter)
        layout_buttons.addWidget(self.btn_record)
        layout_buttons.addWidget(self.btn_record_stop)

        vbox = QVBoxLayout()
        vbox.addLayout(self.container)
        vbox.addStretch()

        w = QWidget()
        w.setLayout(vbox)
        w.setObjectName("w")
        scroll = QScrollArea()
        scroll.setFrameShape(QFrame.NoFrame)
        scroll.setStyleSheet("QScrollArea { background-color:transparent; }")
        w.setStyleSheet("#w { background-color:transparent; }")
        scroll.setWidgetResizable(True)
        scroll.setWidget(w)

        self.addWidget(scroll)
        self.addLayout(layout_buttons)
Esempio n. 29
0
    def __init__(self):
        super().__init__()

        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.on_output)

        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint
                            | QtCore.Qt.X11BypassWindowManagerHint)

        layout = QVBoxLayout()
        btn = QPushButton(tr("MacroRecorder", "Stop recording"))
        btn.clicked.connect(self.on_stop)
        layout.addWidget(btn)

        self.setLayout(layout)
Esempio n. 30
0
    def __init__(self, width):
        super(MovePagingList, self).__init__(width)

        self._last_selected = None

        #TODO: investigate / add bug report for this behavior.
        #XXX
        # Move these out of MovePaginList because they add unwanted arguments in a nasty black magic way.
        # I thnk triggered action calls the callback something like:
        #
        # def onTriggered(self, calling_widget)
        #   try:
        #       self.callback(calling_widget)
        #   except:
        #       self.callback()
        # 
        # so if you have default keyword args they are happily overwritten with the calling widget.
        actions = [
            Action(self, "|<", settings.keys['move_first'], tr("first move"), self._onFirst , 'go-first'),
            Action(self, "<", settings.keys['move_previous'], tr("previous move"), self._onPrevious , 'go-previous'),
            Action(self, ">", settings.keys['move_next'], tr("next move"), self._onNext , 'go-next'),
            Action(self, ">|", settings.keys['move_last'], tr("last move"), self._onLast, 'go-last'),
        ]
        self.addActions(actions)
Esempio n. 31
0
    def __init__(self):
        super().__init__()

        # have to wrap it because apparently there's no other way to get non-shifted key name
        self.old_get_event_names = keyboard._winkeyboard.get_event_names
        keyboard._winkeyboard.get_event_names = self.wrap_get_event_names

        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint
                            | QtCore.Qt.FramelessWindowHint)

        layout = QVBoxLayout()
        btn = QPushButton(tr("MacroRecorder", "Stop recording"))
        btn.clicked.connect(self.on_stop)
        layout.addWidget(btn)

        self.setLayout(layout)
Esempio n. 32
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.keymap_override = None

        self.tab_basic = QScrollArea()
        self.tab_iso = QScrollArea()
        self.tab_layers = QScrollArea()
        self.tab_quantum = QScrollArea()
        self.tab_backlight = QScrollArea()
        self.tab_media = QScrollArea()
        self.tab_macro = QScrollArea()

        self.widgets = []

        for (tab, label, keycodes) in [
            (self.tab_basic, "Basic",
             KEYCODES_SPECIAL + KEYCODES_BASIC + KEYCODES_SHIFTED),
            (self.tab_iso, "ISO/JIS", KEYCODES_ISO),
            (self.tab_layers, "Layers", KEYCODES_LAYERS),
            (self.tab_quantum, "Quantum", KEYCODES_QUANTUM),
            (self.tab_backlight, "Backlight", KEYCODES_BACKLIGHT),
            (self.tab_media, "App, Media and Mouse", KEYCODES_MEDIA),
            (self.tab_macro, "Macro", KEYCODES_MACRO),
        ]:
            layout = FlowLayout()
            if tab == self.tab_layers:
                self.layout_layers = layout
            elif tab == self.tab_macro:
                self.layout_macro = layout

            self.widgets += self.create_buttons(layout, keycodes)

            tab.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            tab.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            tab.setWidgetResizable(True)

            w = QWidget()
            w.setLayout(layout)
            tab.setWidget(w)
            self.addTab(tab, tr("TabbedKeycodes", label))

        self.layer_keycode_buttons = []
        self.macro_keycode_buttons = []
        self.set_keymap_override(KEYMAPS[0][1])
Esempio n. 33
0
	def __init__(self, engine, scene, view):
		super(MainWindow, self).__init__()

		layout = QtGui.QHBoxLayout()

		self.view = view
		self.scene = scene

		layout.addWidget(self.view)

		self.widget = QtGui.QWidget()
		self.widget.setLayout(layout)

		self.setCentralWidget(self.widget)
		self.setWindowTitle(tr("ChessJay"))

		self.createActions()
		self.createMenus()
		self.createDocks()
Esempio n. 34
0
	def __init__(self):
		super(TableWidget, self).__init__()

		self.setColumnCount(len(self.labels))
		labels = []
		for idx, label in enumerate(self.labels):
			labels.append(tr(label))
			#self.setColumnWidth(idx, self.COLUMN_WIDTH)

		self.setHorizontalHeaderLabels(labels)
		self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
		self.currentCellChanged.connect(self.onCellChanged)

		self.toolbar = ToolBar()
		'''
		self.container = QtGui.QGraphicsWidget()

		layout = QtGui.QGraphicsLinearLayout()
		layout.setOrientation(QtCore.Qt.Vertical)

		proxy = QtGui.QGraphicsProxyWidget()
		proxy.setWidget(self.toolbar)
		layout.addItem(proxy)

		proxy = QtGui.QGraphicsProxyWidget()
		proxy.setWidget(self)
		layout.addItem(proxy)

		layout.setContentsMargins(0,0,0,0)
		layout.setSpacing(0)
		self.container.setLayout(layout)
		'''

		layout = QtGui.QVBoxLayout()

		layout.addWidget(self.toolbar)
		layout.addWidget(self)
		layout.setContentsMargins(0,0,0,0)
		layout.setSpacing(0)

		self.container = QtGui.QWidget()
		self.container.setLayout(layout)
Esempio n. 35
0
    def recreate_sequence(self):
        self.layout.removeWidget(self.btn_plus)
        for w in self.widgets:
            self.layout.removeWidget(w)
            w.deleteLater()
        self.widgets.clear()

        for item in self.act.sequence:
            w = QComboBox()
            w.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            w.setStyleSheet("QComboBox { combobox-popup: 0; }")
            w.addItem(tr("MacroEditor", "Remove"))
            w.insertSeparator(1)
            for k in MACRO_SEQUENCE_KEYCODES:
                w.addItem(k.label.replace("\n", ""))
            w.setCurrentIndex(2 + MACRO_SEQUENCE_KEYCODES.index(item))
            w.currentIndexChanged.connect(self.on_change)
            self.layout.addWidget(w)
            self.widgets.append(w)
        self.layout.addWidget(self.btn_plus)
Esempio n. 36
0
    def __init__(self, layout_editor):
        super().__init__()

        self.layout_editor = layout_editor

        self.layout_layers = QHBoxLayout()
        self.layout_size = QVBoxLayout()
        layer_label = QLabel(tr("KeymapEditor", "Layer"))

        layout_labels_container = QHBoxLayout()
        layout_labels_container.addWidget(layer_label)
        layout_labels_container.addLayout(self.layout_layers)
        layout_labels_container.addStretch()
        layout_labels_container.addLayout(self.layout_size)

        # contains the actual keyboard
        self.container = KeyboardWidget(layout_editor)
        self.container.clicked.connect(self.on_key_clicked)

        layout = QVBoxLayout()
        layout.addLayout(layout_labels_container)
        layout.addWidget(self.container)
        layout.setAlignment(self.container, Qt.AlignHCenter)

        self.layer_buttons = []
        self.keyboard = None
        self.current_layer = 0

        layout_editor.changed.connect(self.on_layout_changed)

        self.container.anykey.connect(self.on_any_keycode)

        self.tabbed_keycodes = TabbedKeycodes()
        self.tabbed_keycodes.keycode_changed.connect(self.on_keycode_changed)
        self.tabbed_keycodes.anykey.connect(self.on_any_keycode)

        self.addLayout(layout)
        self.addWidget(self.tabbed_keycodes)

        self.device = None
        KeycodeDisplay.notify_keymap_override(self)
Esempio n. 37
0
    def __init__(self, layout_editor):
        super().__init__()

        self.layout_editor = layout_editor

        self.keyboardWidget = KeyboardWidget(layout_editor)
        self.keyboardWidget.set_enabled(False)

        self.unlock_btn = QPushButton("Unlock")
        self.reset_btn = QPushButton("Reset")

        layout = QVBoxLayout()
        layout.addWidget(self.keyboardWidget)
        layout.setAlignment(self.keyboardWidget, Qt.AlignCenter)

        self.addLayout(layout)

        btn_layout = QHBoxLayout()
        btn_layout.addStretch()
        self.unlock_lbl = QLabel(tr("MatrixTest", "Unlock the keyboard before testing:"))
        btn_layout.addWidget(self.unlock_lbl)
        btn_layout.addWidget(self.unlock_btn)
        btn_layout.addWidget(self.reset_btn)
        self.addLayout(btn_layout)

        self.keyboard = None
        self.device = None
        self.polling = False

        self.timer = QTimer()
        self.timer.timeout.connect(self.matrix_poller)

        self.unlock_btn.clicked.connect(self.unlock)
        self.reset_btn.clicked.connect(self.reset_keyboard_widget)

        self.grabber = QWidget()
Esempio n. 38
0
    def __init__(self, appctx):
        super().__init__()
        self.appctx = appctx

        self.settings = QSettings("Vial", "Vial")
        if self.settings.value("size", None) and self.settings.value(
                "pos", None):
            self.resize(self.settings.value("size"))
            self.move(self.settings.value("pos"))
        else:
            self.resize(WINDOW_WIDTH, WINDOW_HEIGHT)
        themes.set_theme(self.get_theme())

        self.combobox_devices = QComboBox()
        self.combobox_devices.currentIndexChanged.connect(
            self.on_device_selected)

        self.btn_refresh_devices = QToolButton()
        self.btn_refresh_devices.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_refresh_devices.setText(tr("MainWindow", "Refresh"))
        self.btn_refresh_devices.clicked.connect(self.on_click_refresh)

        layout_combobox = QHBoxLayout()
        layout_combobox.addWidget(self.combobox_devices)
        layout_combobox.addWidget(self.btn_refresh_devices)

        self.layout_editor = LayoutEditor()
        self.keymap_editor = KeymapEditor(self.layout_editor)
        self.firmware_flasher = FirmwareFlasher(self)
        self.macro_recorder = MacroRecorder()
        self.tap_dance = TapDance()
        self.combos = Combos()
        QmkSettings.initialize(appctx)
        self.qmk_settings = QmkSettings()
        self.matrix_tester = MatrixTest(self.layout_editor)
        self.rgb_configurator = RGBConfigurator()

        self.editors = [(self.keymap_editor, "Keymap"),
                        (self.layout_editor, "Layout"),
                        (self.macro_recorder, "Macros"),
                        (self.rgb_configurator, "Lighting"),
                        (self.tap_dance, "Tap Dance"), (self.combos, "Combos"),
                        (self.qmk_settings, "QMK Settings"),
                        (self.matrix_tester, "Matrix tester"),
                        (self.firmware_flasher, "Firmware updater")]

        Unlocker.global_layout_editor = self.layout_editor

        self.current_tab = None
        self.tabs = QTabWidget()
        self.tabs.currentChanged.connect(self.on_tab_changed)
        self.refresh_tabs()

        no_devices = 'No devices detected. Connect a Vial-compatible device and press "Refresh"<br>' \
                     'or select "File" → "Download VIA definitions" in order to enable support for VIA keyboards.'
        if sys.platform.startswith("linux"):
            no_devices += '<br><br>On Linux you need to set up a custom udev rule for keyboards to be detected. ' \
                          'Follow the instructions linked below:<br>' \
                          '<a href="https://get.vial.today/manual/linux-udev.html">https://get.vial.today/manual/linux-udev.html</a>'
        self.lbl_no_devices = QLabel(tr("MainWindow", no_devices))
        self.lbl_no_devices.setTextFormat(Qt.RichText)
        self.lbl_no_devices.setAlignment(Qt.AlignCenter)

        layout = QVBoxLayout()
        layout.addLayout(layout_combobox)
        layout.addWidget(self.tabs)
        layout.addWidget(self.lbl_no_devices)
        layout.setAlignment(self.lbl_no_devices, Qt.AlignHCenter)
        self.tray_keycodes = TabbedKeycodes()
        self.tray_keycodes.make_tray()
        layout.addWidget(self.tray_keycodes)
        self.tray_keycodes.hide()
        w = QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)

        self.init_menu()

        self.autorefresh = Autorefresh()
        self.autorefresh.devices_updated.connect(self.on_devices_updated)

        # cache for via definition files
        self.cache_path = QStandardPaths.writableLocation(
            QStandardPaths.CacheLocation)
        if not os.path.exists(self.cache_path):
            os.makedirs(self.cache_path)

        # check if the via defitions already exist
        if os.path.isfile(os.path.join(self.cache_path, "via_keyboards.json")):
            with open(os.path.join(self.cache_path,
                                   "via_keyboards.json")) as vf:
                data = vf.read()
            try:
                self.autorefresh.load_via_stack(data)
            except JSONDecodeError as e:
                # the saved file is invalid - just ignore this
                logging.warning(
                    "Failed to parse stored via_keyboards.json: {}".format(e))

        # make sure initial state is valid
        self.on_click_refresh()
Esempio n. 39
0
    def __init__(self):
        super().__init__()

        self.settings = QSettings("Vial", "Vial")
        themes.set_theme(self.get_theme())

        self.current_device = None
        self.devices = []
        # create empty VIA definitions. Easier than setting it to none and handling a bunch of exceptions
        self.via_stack_json = {"definitions": {}}
        self.sideload_json = None
        self.sideload_vid = self.sideload_pid = -1

        self.combobox_devices = QComboBox()
        self.combobox_devices.currentIndexChanged.connect(
            self.on_device_selected)

        self.btn_refresh_devices = QToolButton()
        self.btn_refresh_devices.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_refresh_devices.setText(tr("MainWindow", "Refresh"))
        self.btn_refresh_devices.clicked.connect(self.on_click_refresh)

        layout_combobox = QHBoxLayout()
        layout_combobox.addWidget(self.combobox_devices)
        layout_combobox.addWidget(self.btn_refresh_devices)

        self.layout_editor = LayoutEditor()
        self.keymap_editor = KeymapEditor(self.layout_editor)
        self.firmware_flasher = FirmwareFlasher(self)
        self.macro_recorder = MacroRecorder()
        self.matrix_tester = MatrixTest(self.layout_editor)

        self.editors = [(self.keymap_editor, "Keymap"),
                        (self.layout_editor, "Layout"),
                        (self.macro_recorder, "Macros"),
                        (self.matrix_tester, "Matrix tester"),
                        (self.firmware_flasher, "Firmware updater")]
        Unlocker.global_layout_editor = self.layout_editor

        self.tabs = QTabWidget()
        self.refresh_tabs()

        self.lbl_no_devices = QLabel(
            tr(
                "MainWindow",
                'No devices detected. Connect a Vial-compatible device and press '
                '"Refresh"\n'
                'or select "File" → "Download VIA definitions" in order to enable'
                ' support for VIA keyboards.'))
        self.lbl_no_devices.setAlignment(Qt.AlignCenter)

        layout = QVBoxLayout()
        layout.addLayout(layout_combobox)
        layout.addWidget(self.tabs)
        layout.addWidget(self.lbl_no_devices)
        layout.setAlignment(self.lbl_no_devices, Qt.AlignHCenter)
        w = QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)

        self.init_menu()

        # cache for via definition files
        self.cache_path = QStandardPaths.writableLocation(
            QStandardPaths.CacheLocation)
        if not os.path.exists(self.cache_path):
            os.makedirs(self.cache_path)
        # check if the via defitions already exist
        if os.path.isfile(os.path.join(self.cache_path, "via_keyboards.json")):
            with open(os.path.join(self.cache_path,
                                   "via_keyboards.json")) as vf:
                self.via_stack_json = json.load(vf)
                vf.close()

        # make sure initial state is valid
        self.on_click_refresh()
Esempio n. 40
0
    def init_menu(self):
        layout_load_act = QAction(tr("MenuFile", "Load saved layout..."), self)
        layout_load_act.setShortcut("Ctrl+O")
        layout_load_act.triggered.connect(self.on_layout_load)

        layout_save_act = QAction(tr("MenuFile", "Save current layout..."),
                                  self)
        layout_save_act.setShortcut("Ctrl+S")
        layout_save_act.triggered.connect(self.on_layout_save)

        sideload_json_act = QAction(tr("MenuFile", "Sideload VIA JSON..."),
                                    self)
        sideload_json_act.triggered.connect(self.on_sideload_json)

        download_via_stack_act = QAction(
            tr("MenuFile", "Download VIA definitions"), self)
        download_via_stack_act.triggered.connect(self.load_via_stack_json)

        load_dummy_act = QAction(tr("MenuFile", "Load dummy JSON..."), self)
        load_dummy_act.triggered.connect(self.on_load_dummy)

        exit_act = QAction(tr("MenuFile", "Exit"), self)
        exit_act.setShortcut("Ctrl+Q")
        exit_act.triggered.connect(qApp.exit)

        file_menu = self.menuBar().addMenu(tr("Menu", "File"))
        file_menu.addAction(layout_load_act)
        file_menu.addAction(layout_save_act)
        file_menu.addSeparator()
        file_menu.addAction(sideload_json_act)
        file_menu.addAction(download_via_stack_act)
        file_menu.addAction(load_dummy_act)
        file_menu.addSeparator()
        file_menu.addAction(exit_act)

        keyboard_unlock_act = QAction(tr("MenuSecurity", "Unlock"), self)
        keyboard_unlock_act.triggered.connect(self.unlock_keyboard)

        keyboard_lock_act = QAction(tr("MenuSecurity", "Lock"), self)
        keyboard_lock_act.triggered.connect(self.lock_keyboard)

        keyboard_reset_act = QAction(
            tr("MenuSecurity", "Reboot to bootloader"), self)
        keyboard_reset_act.triggered.connect(self.reboot_to_bootloader)

        keyboard_layout_menu = self.menuBar().addMenu(
            tr("Menu", "Keyboard layout"))
        keymap_group = QActionGroup(self)
        selected_keymap = self.settings.value("keymap")
        for idx, keymap in enumerate(KEYMAPS):
            act = QAction(tr("KeyboardLayout", keymap[0]), self)
            act.triggered.connect(
                lambda checked, x=idx: self.change_keyboard_layout(x))
            act.setCheckable(True)
            if selected_keymap == keymap[0]:
                self.change_keyboard_layout(idx)
                act.setChecked(True)
            keymap_group.addAction(act)
            keyboard_layout_menu.addAction(act)
        # check "QWERTY" if nothing else is selected
        if keymap_group.checkedAction() is None:
            keymap_group.actions()[0].setChecked(True)

        self.security_menu = self.menuBar().addMenu(tr("Menu", "Security"))
        self.security_menu.addAction(keyboard_unlock_act)
        self.security_menu.addAction(keyboard_lock_act)
        self.security_menu.addSeparator()
        self.security_menu.addAction(keyboard_reset_act)

        self.theme_menu = self.menuBar().addMenu(tr("Menu", "Theme"))
        theme_group = QActionGroup(self)
        selected_theme = self.get_theme()
        for name, _ in [("System", None)] + themes.themes:
            act = QAction(tr("MenuTheme", name), self)
            act.triggered.connect(lambda x, name=name: self.set_theme(name))
            act.setCheckable(True)
            act.setChecked(selected_theme == name)
            theme_group.addAction(act)
            self.theme_menu.addAction(act)
        # check "System" if nothing else is selected
        if theme_group.checkedAction() is None:
            theme_group.actions()[0].setChecked(True)