File 0686-shortcut-configuration.patch of Package OpenBoard

From d0f5b8299122654592db9e6ac7ac6578b154ff76 Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Tue, 2 Mar 2021 10:57:06 +0100
Subject: [PATCH 1/8] Feature: configurable keyboard and mouse/tablet button
 shortcuts

- recording of key sequences amd mouse/stylus buttons
- collect actions, filtering, collision detection
- persist shortcut settings
- group actions instead of buttons in UBActionPalette
- associate actions with MainWindow
- add option to ignore Ctrl key
- implement Reset to default for Shortcut tab
- add built-in actions (read-only) to detect conflicts
---
 resources/forms/preferences.ui       | 169 ++++++
 src/core/UBApplication.cpp           |  33 +-
 src/core/UBPreferencesController.cpp | 252 ++++++++-
 src/core/UBPreferencesController.h   |  12 +
 src/core/UBSettings.cpp              |  19 +-
 src/core/UBShortcutManager.cpp       | 738 +++++++++++++++++++++++++++
 src/core/UBShortcutManager.h         |  94 ++++
 src/core/core.pri                    |   2 +
 src/gui/UBActionPalette.cpp          |  22 +-
 src/gui/UBActionPalette.h            |   6 +-
 src/gui/UBBackgroundPalette.cpp      |   4 +-
 src/gui/UBMainWindow.cpp             |   3 +
 src/gui/UBStylusPalette.cpp          |  12 +-
 13 files changed, 1339 insertions(+), 27 deletions(-)
 create mode 100644 src/core/UBShortcutManager.cpp
 create mode 100644 src/core/UBShortcutManager.h

diff --git a/resources/forms/preferences.ui b/resources/forms/preferences.ui
index 24e68040c..9d039e18b 100644
--- a/resources/forms/preferences.ui
+++ b/resources/forms/preferences.ui
@@ -1108,6 +1108,175 @@
        </item>
       </layout>
      </widget>
+     <widget class="QWidget" name="shortcutTab">
+      <attribute name="title">
+       <string>Shortcut</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <item>
+        <widget class="QLineEdit" name="filter">
+         <property name="placeholderText">
+          <string>Filter</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QScrollArea" name="shortcutScrollArea">
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>789</width>
+            <height>447</height>
+           </rect>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_41">
+           <item>
+            <widget class="QTableView" name="shortcutTableView">
+             <property name="editTriggers">
+              <set>QAbstractItemView::NoEditTriggers</set>
+             </property>
+             <property name="showDropIndicator" stdset="0">
+              <bool>false</bool>
+             </property>
+             <property name="selectionMode">
+              <enum>QAbstractItemView::SingleSelection</enum>
+             </property>
+             <property name="selectionBehavior">
+              <enum>QAbstractItemView::SelectRows</enum>
+             </property>
+             <property name="showGrid">
+              <bool>false</bool>
+             </property>
+             <property name="wordWrap">
+              <bool>false</bool>
+             </property>
+             <attribute name="horizontalHeaderCascadingSectionResizes">
+              <bool>true</bool>
+             </attribute>
+             <attribute name="verticalHeaderVisible">
+              <bool>false</bool>
+             </attribute>
+             <attribute name="verticalHeaderMinimumSectionSize">
+              <number>25</number>
+             </attribute>
+             <attribute name="verticalHeaderDefaultSectionSize">
+              <number>25</number>
+             </attribute>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_11">
+         <item>
+          <widget class="QCheckBox" name="noCtrl">
+           <property name="text">
+            <string>Active keyboard shortcuts without pressing Ctrl key</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="shortcutsGroupBox">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="title">
+          <string>Shortcuts</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+         <layout class="QGridLayout" name="gridLayout_20">
+          <item row="3" column="0" colspan="2">
+           <widget class="QLabel" name="report">
+            <property name="styleSheet">
+             <string notr="true">color: red;</string>
+            </property>
+            <property name="textFormat">
+             <enum>Qt::PlainText</enum>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="stylusButton">
+            <property name="readOnly">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="2">
+           <widget class="QPushButton" name="abortButton">
+            <property name="text">
+             <string>Abort</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="2">
+           <widget class="QPushButton" name="recordButton">
+            <property name="text">
+             <string>Record</string>
+            </property>
+            <property name="checkable">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="label_5">
+            <property name="text">
+             <string>Stylus Button</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_2">
+            <property name="text">
+             <string>Mouse Button</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="mouseButton">
+            <property name="readOnly">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="keySequence">
+            <property name="readOnly">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="2">
+           <widget class="QPushButton" name="resetButton">
+            <property name="text">
+             <string>Reset</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0">
+           <widget class="QLabel" name="label_4">
+            <property name="text">
+             <string>Key Sequence</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
      <widget class="QWidget" name="thirdPartyLicence">
       <property name="enabled">
        <bool>true</bool>
diff --git a/src/core/UBApplication.cpp b/src/core/UBApplication.cpp
index c076241df..c33473485 100644
--- a/src/core/UBApplication.cpp
+++ b/src/core/UBApplication.cpp
@@ -45,6 +45,7 @@
 #include "UBPreferencesController.h"
 #include "UBIdleTimer.h"
 #include "UBApplicationController.h"
+#include "UBShortcutManager.h"
 
 #include "board/UBBoardController.h"
 #include "board/UBDrawingController.h"
@@ -634,14 +635,14 @@ bool UBApplication::eventFilter(QObject *obj, QEvent *event)
         }
     }
 
-    if (event->type() == QEvent::TabletLeaveProximity)
+    else if (event->type() == QEvent::TabletLeaveProximity)
     {
         if (boardController && boardController->controlView())
             boardController->controlView()->forcedTabletRelease();
     }
 
 
-    if (event->type() == QEvent::ApplicationActivate)
+    else if (event->type() == QEvent::ApplicationActivate)
     {
         boardController->controlView()->setMultiselection(false);
 
@@ -659,6 +660,34 @@ bool UBApplication::eventFilter(QObject *obj, QEvent *event)
 #endif
     }
 
+    else if (event->type() == QEvent::MouseButtonPress)
+    {
+        // intercept special mouse buttons for shortcut handler
+        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+        Qt::MouseButton button = mouseEvent->button();
+
+        if (button != Qt::LeftButton && button != Qt::RightButton)
+        {
+            return mPreferencesController->handleMouseEvent(mouseEvent)
+                    || UBShortcutManager::shortcutManager()->handleMouseEvent(mouseEvent)
+                    || result;
+        }
+    }
+
+    else if (event->type() == QEvent::TabletPress)
+    {
+        // intercept special tablet buttons for shortcut handler
+        QTabletEvent *tabletEvent = static_cast<QTabletEvent *>(event);
+        Qt::MouseButton button = tabletEvent->button();
+
+        if (button != Qt::LeftButton)
+        {
+            return mPreferencesController->handleTabletEvent(tabletEvent)
+                    || UBShortcutManager::shortcutManager()->handleTabletEvent(tabletEvent)
+                    || result;
+        }
+    }
+
     return result;
 }
 
diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp
index 6fcbcf491..9a9e83de2 100644
--- a/src/core/UBPreferencesController.cpp
+++ b/src/core/UBPreferencesController.cpp
@@ -37,6 +37,7 @@
 #include "core/UBSetting.h"
 #include "core/UBApplicationController.h"
 #include "core/UBDisplayManager.h"
+#include "core/UBShortcutManager.h"
 
 #include "frameworks/UBStringUtils.h"
 
@@ -77,7 +78,6 @@ void UBPreferencesDialog::closeEvent(QCloseEvent* e)
 }
 
 
-
 UBPreferencesController::UBPreferencesController(QWidget *parent)
     : QObject(parent)
     , mPreferencesWindow(0)
@@ -92,6 +92,8 @@ UBPreferencesController::UBPreferencesController(QWidget *parent)
     mPreferencesUI->setupUi(mPreferencesWindow);
     adjustScreens();
     connect(UBApplication::displayManager, &UBDisplayManager::availableScreenCountChanged, this, &UBPreferencesController::adjustScreens);
+    mPreferencesUI->shortcutTab->installEventFilter(this);
+
     wire();
 }
 
@@ -107,6 +109,90 @@ UBPreferencesController::~UBPreferencesController()
     delete mMarkerProperties;
 }
 
+bool UBPreferencesController::handleKeyEvent(QKeyEvent *event)
+{
+    if (!mPreferencesUI->recordButton->isChecked()
+            || mPreferencesUI->mainTabWidget->currentWidget() != mPreferencesUI->shortcutTab)
+    {
+        return false;
+    }
+
+    int key = event->key();
+    Qt::KeyboardModifiers mods = event->modifiers();
+    QString text = event->text();
+
+    int keys = mods;
+
+    if (key < Qt::Key_Shift || key > Qt::Key_Alt)
+    {
+        keys += key;
+    }
+
+    // compose key sequence from active modifiers and key
+    QKeySequence keySequence(keys);
+    QString keyString = keySequence.toString();
+    mPreferencesUI->keySequence->setText(keyString);
+
+    if (currentIndex.isValid())
+    {
+        bool ok = UBShortcutManager::shortcutManager()->checkData(currentIndex.siblingAtColumn(2), keyString);
+        applyShortcutFilter(ok ? mPreferencesUI->filter->text() : keyString, ok ? -1 : 2);
+        mPreferencesUI->recordButton->setEnabled(ok);
+        mPreferencesUI->report->setText(ok ? "" : tr("Key sequence already in use"));
+        mPreferencesUI->noCtrl->setEnabled(!UBShortcutManager::shortcutManager()->hasCtrlConflicts(keySequence));
+    }
+
+    return true;
+}
+
+bool UBPreferencesController::handleMouseEvent(QMouseEvent *event)
+{
+    if (!mPreferencesUI->recordButton->isChecked()
+            || mPreferencesUI->mainTabWidget->currentWidget() != mPreferencesUI->shortcutTab)
+    {
+        return false;
+    }
+
+    Qt::MouseButton button = event->button();
+
+    if (currentIndex.isValid())
+    {
+        QString buttonName = UBShortcutManager::buttonName(button);
+        mPreferencesUI->mouseButton->setText(buttonName);
+        bool ok = UBShortcutManager::shortcutManager()->checkData(currentIndex.siblingAtColumn(3), buttonName);
+        applyShortcutFilter(ok ? mPreferencesUI->filter->text() : buttonName, ok ? -1 : 3);
+        mPreferencesUI->recordButton->setEnabled(ok);
+        mPreferencesUI->report->setText(ok ? "" : tr("Mouse button already in use"));
+        return true;
+    }
+
+    return false;
+}
+
+bool UBPreferencesController::handleTabletEvent(QTabletEvent *event)
+{
+    if (!mPreferencesUI->recordButton->isChecked()
+            || mPreferencesUI->mainTabWidget->currentWidget() != mPreferencesUI->shortcutTab)
+    {
+        return false;
+    }
+
+    Qt::MouseButton button = event->button();
+
+    if (currentIndex.isValid())
+    {
+        QString buttonName = UBShortcutManager::buttonName(button);
+        mPreferencesUI->stylusButton->setText(buttonName);
+        bool ok = UBShortcutManager::shortcutManager()->checkData(currentIndex.siblingAtColumn(4), buttonName);
+        applyShortcutFilter(ok ? mPreferencesUI->filter->text() : buttonName, ok ? -1 : 4);
+        mPreferencesUI->recordButton->setEnabled(ok);
+        mPreferencesUI->report->setText(ok ? "" : tr("Stylus button already in use"));
+        return true;
+    }
+
+    return false;
+}
+
 void UBPreferencesController::adjustScreens()
 {
     bool enabled = UBApplication::displayManager->numScreens() > 1;
@@ -143,6 +229,50 @@ void UBPreferencesController::adjustScreens()
     }
 }
 
+void UBPreferencesController::applyShortcutFilter(const QString &filter, int filterCol)
+{
+    // go throug rows in reverse direction
+    QAbstractItemModel* model = mPreferencesUI->shortcutTableView->model();
+    QModelIndex index = model->index(0, 0);
+    bool groupVisible = false;
+    int minCol = filterCol < 0 ? 0 : filterCol;
+    int maxCol = filterCol < 0 ? model->columnCount() : filterCol + 1;
+
+    for (int row = model->rowCount() - 1; row >= 0; --row)
+    {
+        QModelIndex rowIndex = index.siblingAtRow(row);
+        bool match = false;
+        bool header = model->data(rowIndex, UBShortcutManager::GroupHeaderRole).toBool();
+
+        if (header)
+        {
+            match = groupVisible;
+            groupVisible = false;
+        }
+        else if (currentIndex.isValid() && currentIndex.row() == row)
+        {
+            match = true;
+            groupVisible = true;
+        }
+        else
+        {
+            for (int col = minCol; col < maxCol; ++col)
+            {
+                QModelIndex colIndex = rowIndex.siblingAtColumn(col);
+
+                if (model->data(colIndex).toString().contains(filter, Qt::CaseInsensitive))
+                {
+                    match = true;
+                    groupVisible = true;
+                    break;
+                }
+            }
+        }
+
+        mPreferencesUI->shortcutTableView->setRowHidden(row, !match);
+    }
+}
+
 void UBPreferencesController::show()
 {
     init();
@@ -301,6 +431,21 @@ void UBPreferencesController::wire()
     connect(mPreferencesUI->checkSoftwareUpdateAtLaunchCheckBox, SIGNAL(clicked(bool)), settings->appEnableAutomaticSoftwareUpdates, SLOT(setBool(bool)));
 
     connect(mPreferencesUI->checkOpenSankoreAtStartup, SIGNAL(clicked(bool)), settings->appLookForOpenSankoreInstall, SLOT(setBool(bool)));
+
+    // shortcut tab
+    connect(mPreferencesUI->shortcutTableView, SIGNAL(activated(const QModelIndex&)), this, SLOT(actionSelected(const QModelIndex&)));
+    connect(mPreferencesUI->filter, SIGNAL(textChanged(const QString&)), this, SLOT(applyShortcutFilter(const QString&)));
+    connect(mPreferencesUI->recordButton, SIGNAL(clicked(bool)), this, SLOT(recordingClicked(bool)));
+    connect(mPreferencesUI->abortButton, SIGNAL(clicked()), this, SLOT(abortClicked()));
+    connect(mPreferencesUI->resetButton, SIGNAL(clicked()), this, SLOT(resetClicked()));
+    connect(mPreferencesUI->noCtrl, &QCheckBox::toggled, UBShortcutManager::shortcutManager(), &UBShortcutManager::ignoreCtrl);
+    connect(mPreferencesUI->mainTabWidget, &QTabWidget::currentChanged, [this](int tab){
+        auto shortcutTab = mPreferencesUI->mainTabWidget->indexOf(mPreferencesUI->shortcutTab);
+
+        if (tab != shortcutTab) {
+            abortClicked();
+        }
+    });
 }
 
 void UBPreferencesController::init()
@@ -361,6 +506,27 @@ void UBPreferencesController::init()
 
     mMarkerProperties->opacitySlider->setValue(settings->boardMarkerAlpha->get().toDouble() * 100);
 
+    // shortcut tab
+    mPreferencesUI->shortcutTableView->setModel(UBShortcutManager::shortcutManager());
+    mPreferencesUI->shortcutTableView->horizontalHeader()->setModel(UBShortcutManager::shortcutManager());
+    mPreferencesUI->shortcutTableView->horizontalHeader()->resizeSection(0, 150);
+    mPreferencesUI->shortcutTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
+    mPreferencesUI->noCtrl->setChecked(settings->value("Shortcut/IgnoreCtrl").toBool());
+    mPreferencesUI->noCtrl->setEnabled(!UBShortcutManager::shortcutManager()->hasCtrlConflicts());
+}
+
+bool UBPreferencesController::eventFilter(QObject *obj, QEvent *event)
+{
+    if (event->type() == QEvent::KeyPress)
+    {
+        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+        return handleKeyEvent(keyEvent);
+    }
+    else
+    {
+        // standard event processing
+        return QObject::eventFilter(obj, event);
+    }
 }
 
 void UBPreferencesController::close()
@@ -459,7 +625,8 @@ void UBPreferencesController::defaultSettings()
         mPreferencesUI->checkOpenSankoreAtStartup->setChecked(defaultValue);
 
     }
-    else if(mPreferencesUI->mainTabWidget->currentWidget() == mPreferencesUI->networkTab){
+    else if(mPreferencesUI->mainTabWidget->currentWidget() == mPreferencesUI->networkTab)
+    {
         bool defaultValue = settings->webUseExternalBrowser->reset().toBool();
         mPreferencesUI->useExternalBrowserCheckBox->setChecked(defaultValue);
         defaultValue = settings->webShowPageImmediatelyOnMirroredScreen->reset().toBool();
@@ -494,6 +661,23 @@ void UBPreferencesController::defaultSettings()
         lightBackgroundCrossOpacityValueChanged(lightBackgroundOpacity);
 
     }
+    else if(mPreferencesUI->mainTabWidget->currentWidget() == mPreferencesUI->shortcutTab)
+    {
+        if (mPreferencesUI->recordButton->isChecked())
+        {
+            abortClicked();
+        }
+
+        UBShortcutManager* sm = UBShortcutManager::shortcutManager();
+
+        for (int row = 0; row < sm->rowCount(); ++row)
+        {
+            QModelIndex rowIndex = sm->index(row, 0);
+            sm->resetData(rowIndex);
+        }
+
+        resetClicked();
+    }
 }
 
 void UBPreferencesController::darkBackgroundCrossOpacityValueChanged(int value)
@@ -716,6 +900,70 @@ void UBPreferencesController::setPdfZoomBehavior(bool checked)
     }
 }
 
+void UBPreferencesController::actionSelected(const QModelIndex &index)
+{
+    currentIndex = index;
+    UBShortcutManager* sm = UBShortcutManager::shortcutManager();
+    mPreferencesUI->keySequence->setText(sm->data(index.siblingAtColumn(2), UBShortcutManager::PrimaryShortcutRole).toString());
+    mPreferencesUI->mouseButton->setText(sm->data(index.siblingAtColumn(3)).toString());
+    mPreferencesUI->stylusButton->setText(sm->data(index.siblingAtColumn(4)).toString());
+
+    bool isAction = sm->data(index, UBShortcutManager::ActionRole).toBool();
+    mPreferencesUI->recordButton->setEnabled(true);
+    mPreferencesUI->shortcutsGroupBox->setEnabled(isAction);
+}
+
+void UBPreferencesController::recordingClicked(bool checked)
+{
+    if (!checked && currentIndex.isValid())
+    {
+        UBShortcutManager* sm = UBShortcutManager::shortcutManager();
+        sm->setData(currentIndex.siblingAtColumn(2), mPreferencesUI->keySequence->text());
+        sm->setData(currentIndex.siblingAtColumn(3), sm->buttonIndex(mPreferencesUI->mouseButton->text()));
+        sm->setData(currentIndex.siblingAtColumn(4), sm->buttonIndex(mPreferencesUI->stylusButton->text()));
+    }
+
+    mPreferencesUI->shortcutTableView->setSelectionMode(checked ? QTableView::NoSelection : QTableView::SingleSelection);
+    mPreferencesUI->recordButton->setText(checked ? tr("Accept", "preferencesDialog") : tr("Record", "preferencesDialog"));
+}
+
+void UBPreferencesController::abortClicked()
+{
+    applyShortcutFilter(mPreferencesUI->filter->text());
+
+    mPreferencesUI->recordButton->setEnabled(true);
+    mPreferencesUI->recordButton->setChecked(false);
+    mPreferencesUI->recordButton->setText(tr("Record", "preferencesDialog"));
+    mPreferencesUI->shortcutTableView->setSelectionMode(QTableView::SingleSelection);
+    mPreferencesUI->shortcutTableView->clearSelection();
+    mPreferencesUI->report->setText("");
+    mPreferencesUI->noCtrl->setEnabled(!UBShortcutManager::shortcutManager()->hasCtrlConflicts());
+    actionSelected(mPreferencesUI->shortcutTableView->model()->index(0, 0));
+}
+
+void UBPreferencesController::resetClicked()
+{
+    if (mPreferencesUI->recordButton->isChecked())
+    {
+        abortClicked();
+    }
+
+    if (currentIndex.isValid())
+    {
+        UBShortcutManager* sm = UBShortcutManager::shortcutManager();
+
+        sm->resetData(currentIndex);
+        applyShortcutFilter(mPreferencesUI->filter->text());
+
+        mPreferencesUI->keySequence->setText(sm->data(currentIndex.siblingAtColumn(2)).toString());
+        mPreferencesUI->mouseButton->setText(sm->data(currentIndex.siblingAtColumn(3)).toString());
+        mPreferencesUI->stylusButton->setText(sm->data(currentIndex.siblingAtColumn(4)).toString());
+    }
+
+    mPreferencesUI->report->setText("");
+    mPreferencesUI->noCtrl->setEnabled(!UBShortcutManager::shortcutManager()->hasCtrlConflicts());
+}
+
 UBBrushPropertiesFrame::UBBrushPropertiesFrame(QFrame* owner, const QList<QColor>& lightBackgroundColors,
                                                const QList<QColor>& darkBackgroundColors, const QList<QColor>& lightBackgroundSelectedColors,
                                                const QList<QColor>& darkBackgroundSelectedColors, UBPreferencesController* controller)
diff --git a/src/core/UBPreferencesController.h b/src/core/UBPreferencesController.h
index 6f0522a73..708cef47b 100644
--- a/src/core/UBPreferencesController.h
+++ b/src/core/UBPreferencesController.h
@@ -70,6 +70,9 @@ class UBPreferencesController : public QObject
         UBPreferencesController(QWidget *parent);
         virtual ~UBPreferencesController();
 
+        bool handleKeyEvent(QKeyEvent *event);
+        bool handleMouseEvent(QMouseEvent *event);
+        bool handleTabletEvent(QTabletEvent *event);
 
     public slots:
 
@@ -80,6 +83,8 @@ class UBPreferencesController : public QObject
         void wire();
         void init();
 
+        virtual bool eventFilter(QObject* obj, QEvent* event) Q_DECL_OVERRIDE;
+
         UBPreferencesDialog* mPreferencesWindow;
         Ui::preferencesDialog* mPreferencesUI;
         UBBrushPropertiesFrame* mPenProperties;
@@ -105,14 +110,21 @@ class UBPreferencesController : public QObject
         void toolbarOrientationHorizontal(bool checked);
         void systemOSKCheckBoxToggled(bool checked);
         void setPdfZoomBehavior(bool checked);
+        void actionSelected(const QModelIndex& index);
+        void recordingClicked(bool checked);
+        void abortClicked();
+        void resetClicked();
 
     private slots:
         void adjustScreens();
+        void applyShortcutFilter(const QString& filter, int filterCol = -1);
+
 
     private:
         static qreal sSliderRatio;
         static qreal sMinPenWidth;
         static qreal sMaxPenWidth;
+        QModelIndex currentIndex;
 };
 
 class UBBrushPropertiesFrame : public Ui::brushProperties
diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp
index 9a7a6f691..9fda51dd2 100644
--- a/src/core/UBSettings.cpp
+++ b/src/core/UBSettings.cpp
@@ -544,17 +544,32 @@ void UBSettings::save()
          * We save the setting to the user settings if
          * a) it is different from the (non-null) value stored in the user settings, or
          * b) it doesn't currently exist in the user settings AND has changed from the app settings
+         * An invalid value indicates removal of the setting
         */
         if (mUserSettings->contains(it.key())
                 && it.value() != mUserSettings->value(it.key()))
         {
-            mUserSettings->setValue(it.key(), it.value());
+            if (it.value().isValid())
+            {
+                mUserSettings->setValue(it.key(), it.value());
+            }
+            else
+            {
+                mUserSettings->remove(it.key());
+            }
         }
 
         else if (!mUserSettings->contains(it.key())
                  && it.value() != mAppSettings->value(it.key()))
         {
-            mUserSettings->setValue(it.key(), it.value());
+            if (it.value().isValid())
+            {
+                mUserSettings->setValue(it.key(), it.value());
+            }
+            else
+            {
+                mUserSettings->remove(it.key());
+            }
         }
 
         ++it;
diff --git a/src/core/UBShortcutManager.cpp b/src/core/UBShortcutManager.cpp
new file mode 100644
index 000000000..a03691ecf
--- /dev/null
+++ b/src/core/UBShortcutManager.cpp
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM)
+ *
+ * Copyright (C) 2013 Open Education Foundation
+ *
+ * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
+ * l'Education Numérique en Afrique (GIP ENA)
+ *
+ * This file is part of OpenBoard.
+ *
+ * OpenBoard is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License,
+ * with a specific linking exception for the OpenSSL project's
+ * "OpenSSL" library (or with modified versions of it that use the
+ * same license as the "OpenSSL" library).
+ *
+ * OpenBoard is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "UBShortcutManager.h"
+#include "core/UBSettings.h"
+#include "frameworks/UBPlatformUtils.h"
+#include "gui/UBMainWindow.h"
+
+#include <QAction>
+#include <QDebug>
+#include <QWidget>
+
+// property names
+static const char* defaultShortcutProperty("defaultShortcut");
+static const char* descriptionProperty("description");
+static const char* mouseButtonProperty("mouseButton");
+static const char* tabletButtonProperty("tabletButton");
+
+UBShortcutManager* UBShortcutManager::sShortcutManager = nullptr;
+
+UBShortcutManager::UBShortcutManager()
+{
+    actionsOfGroup(QObject::tr("Common"));
+}
+
+UBShortcutManager *UBShortcutManager::shortcutManager()
+{
+    if (!sShortcutManager)
+    {
+        sShortcutManager = new UBShortcutManager;
+    }
+
+    return sShortcutManager;
+}
+
+void UBShortcutManager::addActions(const QString& group, const QList<QAction*> actions, QWidget *widget)
+{
+    // save default shortcuts for later
+    for (QAction* action : actions)
+    {
+        if (!action->isSeparator())
+        {
+            if (widget && !widget->actions().contains(action))
+            {
+                // associate actions with widget to make sure they are triggered when this widget is visible
+                widget->addAction(action);
+            }
+
+            QKeySequence shortcut = action->shortcut();
+
+            if (!shortcut.isEmpty())
+            {
+                action->setProperty(defaultShortcutProperty, shortcut.toString());
+            }
+
+            action->setProperty(descriptionProperty, action->toolTip());
+
+            QStringList settings = UBSettings::settings()->value("Shortcut/" + action->objectName()).toStringList();
+
+            if (settings.size() == 3)
+            {
+                if (!settings[0].isEmpty())
+                {
+                    action->setShortcut(settings[0]);
+                }
+
+                if (int button = settings[1].toInt())
+                {
+                    action->setProperty(mouseButtonProperty, button);
+                    mMouseActions[static_cast<Qt::MouseButton>(button)] = action;
+                }
+
+                if (int button = settings[2].toInt())
+                {
+                    action->setProperty(tabletButtonProperty, button);
+                    mTabletActions[static_cast<Qt::MouseButton>(button)] = action;
+                }
+            }
+
+            QString oldGroup = groupOfAction(action);
+
+            if (oldGroup.isEmpty()) {
+                actionsOfGroup(group) << action;
+            }
+            else
+            {
+                // remove from oldGroup, add to Common, which is always first group
+                actionsOfGroup(oldGroup).removeAll(action);
+                mActionGroups[0].second << action;
+            }
+        }
+    }
+}
+
+void UBShortcutManager::addMainActions(UBMainWindow *mainWindow)
+{
+    addActions(tr("Common"), {
+                   mainWindow->actionStylus,
+                   mainWindow->actionBoard,
+                   mainWindow->actionWeb,
+                   mainWindow->actionDocument,
+                   mainWindow->actionDesktop,
+                   mainWindow->actionLibrary,
+                   mainWindow->actionVirtualKeyboard,
+                   mainWindow->actionOpenTutorial,
+                   mainWindow->actionHideApplication
+               }, mainWindow);
+
+    addActions(tr("Board"), {
+                   mainWindow->actionUndo,
+                   mainWindow->actionRedo,
+                   mainWindow->actionNewPage,
+                   mainWindow->actionDuplicatePage,
+                   mainWindow->actionImportPage,
+                   mainWindow->actionBack,
+                   mainWindow->actionForward,
+                   mainWindow->actionAdd,
+                   mainWindow->actionClearPage,
+                   mainWindow->actionEraseItems,
+                   mainWindow->actionEraseAnnotations,
+                   mainWindow->actionEraseBackground
+               }, mainWindow);
+
+    addActions(tr("Stylus Palette"),{
+                   mainWindow->actionPen,
+                   mainWindow->actionEraser,
+                   mainWindow->actionMarker,
+                   mainWindow->actionSelector,
+                   mainWindow->actionPlay,
+
+                   mainWindow->actionHand,
+                   mainWindow->actionZoomIn,
+                   mainWindow->actionZoomOut,
+
+                   mainWindow->actionPointer,
+                   mainWindow->actionLine,
+                   mainWindow->actionText,
+                   mainWindow->actionCapture
+               }, mainWindow);
+
+    if(UBPlatformUtils::hasVirtualKeyboard())
+    {
+        addActions(tr("Stylus Palette"),{ mainWindow->actionVirtualKeyboard }, mainWindow);
+    }
+
+    addActions(tr("Lines and colours"), {
+                   mainWindow->actionLineSmall,
+                   mainWindow->actionLineMedium,
+                   mainWindow->actionLineLarge,
+                   mainWindow->actionEraserSmall,
+                   mainWindow->actionEraserMedium,
+                   mainWindow->actionEraserLarge,
+                   mainWindow->actionColor0,
+                   mainWindow->actionColor1,
+                   mainWindow->actionColor2,
+                   mainWindow->actionColor3,
+                   mainWindow->actionColor4
+               }, mainWindow);
+
+    addActions(tr("Background"), {
+                   mainWindow->actionBackgrounds,
+                   mainWindow->actionPlainLightBackground,
+                   mainWindow->actionCrossedLightBackground,
+                   mainWindow->actionRuledLightBackground,
+                   mainWindow->actionPlainDarkBackground,
+                   mainWindow->actionCrossedDarkBackground,
+                   mainWindow->actionRuledDarkBackground,
+                   mainWindow->actionDefaultGridSize,
+                   mainWindow->actionDrawIntermediateGridLines
+               }, mainWindow);
+
+    addActions(tr("Podcast"), {
+                   mainWindow->actionPodcastRecord,
+                   mainWindow->actionPodcastPause
+               }, mainWindow);
+
+    // add builtIn actions
+    QList<QAction*> actions;
+
+    QAction* action = new QAction(this);
+    action->setText(mainWindow->actionBack->text());
+    action->setToolTip(mainWindow->actionBack->toolTip());
+    action->setShortcuts( { QKeySequence(Qt::Key_Up), QKeySequence(Qt::Key_PageUp), QKeySequence(Qt::Key_Left) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(mainWindow->actionForward->text());
+    action->setToolTip(mainWindow->actionForward->toolTip());
+    action->setShortcuts( { QKeySequence(Qt::Key_Down), QKeySequence(Qt::Key_PageDown), QKeySequence(Qt::Key_Right), QKeySequence(Qt::Key_Space) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("First scene"));
+    action->setToolTip(tr("Show first scene"));
+    action->setShortcuts( { QKeySequence(Qt::Key_Home) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("Last scene"));
+    action->setToolTip(tr("Show last scene"));
+    action->setShortcuts( { QKeySequence(Qt::Key_End) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(mainWindow->actionNewPage->text());
+    action->setToolTip(mainWindow->actionNewPage->toolTip());
+    action->setShortcuts( { QKeySequence(Qt::Key_Insert) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(mainWindow->actionZoomIn->text());
+    action->setToolTip(mainWindow->actionZoomIn->toolTip());
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_Plus) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(mainWindow->actionZoomOut->text());
+    action->setToolTip(mainWindow->actionZoomOut->toolTip());
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_Minus) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("Zoom reset"));
+    action->setToolTip(tr("Reset zoom factor"));
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_0) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("Scroll left"));
+    action->setToolTip(tr("Scroll page left"));
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_Left) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("Scroll right"));
+    action->setToolTip(tr("Scroll page right"));
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_Right) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("Scroll up"));
+    action->setToolTip(tr("Scroll page up"));
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_Up) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    action = new QAction(this);
+    action->setText(tr("Scroll down"));
+    action->setToolTip(tr("Scroll page down"));
+    action->setShortcuts( { QKeySequence(Qt::CTRL | Qt::Key_Down) } );
+    action->setProperty("builtIn", true);
+    actions << action;
+
+    addActions(tr("Built-in (not editable)"), actions);
+}
+
+bool UBShortcutManager::handleMouseEvent(QMouseEvent *event)
+{
+    if (mMouseActions.contains(event->button()))
+    {
+        QAction* action = mMouseActions[event->button()];
+
+        if (!action->isCheckable() || !action->actionGroup() || !action->isChecked())
+        {
+            action->trigger();
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+bool UBShortcutManager::handleTabletEvent(QTabletEvent *event)
+{
+    if (mTabletActions.contains(event->button()))
+    {
+        QAction* action = mTabletActions[event->button()];
+
+        if (!action->isCheckable() || !action->actionGroup() || !action->isChecked())
+        {
+            action->trigger();
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+int UBShortcutManager::rowCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+
+    int rows = 0;
+
+    for (auto& actionGroup : mActionGroups)
+    {
+        ++rows;
+        rows += actionGroup.second.size();
+    }
+
+    return rows;
+}
+
+int UBShortcutManager::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return 5;
+}
+
+QVariant UBShortcutManager::data(const QModelIndex &index, int role) const
+{
+    QString group;
+    QAction* action = getAction(index, &group);
+
+    switch (role)
+    {
+    case Qt::DisplayRole:
+    case Qt::ToolTipRole:
+        switch (index.column())
+        {
+        case 0:
+            return action ? action->text() : group;
+
+        case 1:
+            return action ? action->property(descriptionProperty) : "";
+
+        case 2:
+        {
+            if (!action)
+            {
+                return "";
+            }
+
+            QStringList result;
+
+            for (const QKeySequence& shortcut : action->shortcuts())
+            {
+                result << shortcut.toString();
+            }
+
+            return result.join(", ");
+        }
+
+        case 3:
+            return action ? buttonName(static_cast<Qt::MouseButton>(action->property(mouseButtonProperty).toInt())) : QVariant();
+
+        case 4:
+            return action ? buttonName(static_cast<Qt::MouseButton>(action->property(tabletButtonProperty).toInt())) : QVariant();
+        }
+        break;
+
+    case Qt::FontRole:
+    {
+        QFont groupFont;
+        groupFont.setBold(true);
+        groupFont.setItalic(true);
+
+        QFont disabledFont;
+        disabledFont.setItalic(true);
+
+        return action ? (action->property("builtIn").toBool() ? disabledFont : QVariant()) : groupFont;
+    }
+
+    case UBShortcutManager::ActionRole:
+        return action && !action->property("builtIn").toBool();
+
+    case UBShortcutManager::GroupHeaderRole:
+        return !action;
+
+    case UBShortcutManager::PrimaryShortcutRole:
+        return (index.column() == 2 && action) ? action->shortcut().toString() : QVariant();
+
+    case Qt::DecorationRole:
+    case Qt::EditRole:
+    case Qt::StatusTipRole:
+    case Qt::WhatsThisRole:
+    case Qt::SizeHintRole:
+    case Qt::TextAlignmentRole:
+    case Qt::BackgroundRole:
+    case Qt::ForegroundRole:
+    case Qt::CheckStateRole:
+    case Qt::InitialSortOrderRole:
+        return QVariant();
+    }
+
+    return QVariant();
+}
+
+QVariant UBShortcutManager::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if (orientation == Qt::Orientation::Horizontal && role == Qt::DisplayRole)
+    {
+        switch (section)
+        {
+        case 0:
+            return tr("Command");
+
+        case 1:
+            return tr("Description");
+
+        case 2:
+            return tr("Key Sequence");
+
+        case 3:
+            return tr("Mouse Button");
+
+        case 4:
+            return tr("Tablet Button");
+        }
+    }
+
+    return QVariant();
+}
+
+bool UBShortcutManager::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    Q_UNUSED(role)
+
+    if (!index.isValid())
+    {
+        return false;
+    }
+
+    QAction* action = getAction(index);
+
+    switch (index.column())
+    {
+    case 2:
+    {
+        QKeySequence keySequence(value.toString());
+
+        action->setShortcut(keySequence);
+        updateSettings(action);
+        emit dataChanged(index, index);
+        return true;
+    }
+
+    case 3:
+        action->setProperty(mouseButtonProperty, value);
+        mMouseActions[static_cast<Qt::MouseButton>(value.toInt())] = action;
+        updateSettings(action);
+        emit dataChanged(index, index);
+        return true;
+
+    case 4:
+        action->setProperty(tabletButtonProperty, value);
+        mTabletActions[static_cast<Qt::MouseButton>(value.toInt())] = action;
+        updateSettings(action);
+        emit dataChanged(index, index);
+        return true;
+    }
+
+    return false;
+}
+
+bool UBShortcutManager::resetData(const QModelIndex &index)
+{
+    QAction* action = getAction(index);
+
+    if (action)
+    {
+        QKeySequence shortcut(action->property(defaultShortcutProperty).toString());
+        action->setShortcut(shortcut);
+        mMouseActions.remove(static_cast<Qt::MouseButton>(action->property(mouseButtonProperty).toInt()));
+        mTabletActions.remove(static_cast<Qt::MouseButton>(action->property(tabletButtonProperty).toInt()));
+        action->setProperty(mouseButtonProperty, QVariant());
+        action->setProperty(tabletButtonProperty, QVariant());
+        updateSettings(action);
+        emit dataChanged(index.siblingAtColumn(2), index.siblingAtColumn(4));
+        return true;
+    }
+
+    return false;
+}
+
+bool UBShortcutManager::checkData(const QModelIndex &index, const QVariant &value) const
+{
+    int col = index.column();
+
+    if (col < 2)
+    {
+        return true;
+    }
+
+    for (int row = 0; row < rowCount(); ++row)
+    {
+        if (data(index.siblingAtRow(row)).toString().split(", ").contains(value.toString()))
+        {
+            // duplicate value
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool UBShortcutManager::hasCtrlConflicts(const QKeySequence &additionalShortcut) const
+{
+    QSet<QKeySequence> shortcuts;
+    QSet<QKeySequence> ctrlShortcuts;
+
+    for (int row = 1; row < rowCount(); ++row)
+    {
+        QAction* action = getAction(index(row, 0));
+
+        if (!action)
+        {
+            continue;
+        }
+
+        if (action->property("builtIn").toBool())
+        {
+            for (const QKeySequence& shortcut : action->shortcuts())
+            {
+                shortcuts << shortcut;
+            }
+        }
+        else
+        {
+            shortcuts << action->shortcut();
+            ctrlShortcuts << QKeySequence(action->shortcut()[0] ^ Qt::CTRL);
+        }
+
+    }
+
+    if (!additionalShortcut.isEmpty())
+    {
+        shortcuts << additionalShortcut;
+        ctrlShortcuts << QKeySequence(additionalShortcut[0] ^ Qt::CTRL);
+    }
+
+    return shortcuts.intersects(ctrlShortcuts);
+}
+
+QString UBShortcutManager::buttonName(Qt::MouseButton button)
+{
+    switch (button)
+    {
+    case Qt::LeftButton: return tr("Left", "MouseButton");
+    case Qt::RightButton: return tr("Right", "MouseButton");
+    case Qt::MiddleButton: return tr("Middle", "MouseButton");
+    case Qt::BackButton: return tr("Back", "MouseButton");
+    case Qt::ForwardButton: return tr("Forward", "MouseButton");
+    case Qt::TaskButton: return tr("Task", "MouseButton");
+    case Qt::ExtraButton4: return tr("Extra", "MouseButton") + "4";
+    case Qt::ExtraButton5: return tr("Extra", "MouseButton") + "5";
+    case Qt::ExtraButton6: return tr("Extra", "MouseButton") + "6";
+    case Qt::ExtraButton7: return tr("Extra", "MouseButton") + "7";
+    case Qt::ExtraButton8: return tr("Extra", "MouseButton") + "8";
+    case Qt::ExtraButton9: return tr("Extra", "MouseButton") + "9";
+    case Qt::ExtraButton10: return tr("Extra", "MouseButton") + "10";
+    case Qt::ExtraButton11: return tr("Extra", "MouseButton") + "11";
+    case Qt::ExtraButton12: return tr("Extra", "MouseButton") + "12";
+    case Qt::ExtraButton13: return tr("Extra", "MouseButton") + "13";
+    case Qt::ExtraButton14: return tr("Extra", "MouseButton") + "14";
+    case Qt::ExtraButton15: return tr("Extra", "MouseButton") + "15";
+    case Qt::ExtraButton16: return tr("Extra", "MouseButton") + "16";
+    case Qt::ExtraButton17: return tr("Extra", "MouseButton") + "17";
+    case Qt::ExtraButton18: return tr("Extra", "MouseButton") + "18";
+    case Qt::ExtraButton19: return tr("Extra", "MouseButton") + "19";
+    case Qt::ExtraButton20: return tr("Extra", "MouseButton") + "20";
+    case Qt::ExtraButton21: return tr("Extra", "MouseButton") + "21";
+    case Qt::ExtraButton22: return tr("Extra", "MouseButton") + "22";
+    case Qt::ExtraButton23: return tr("Extra", "MouseButton") + "23";
+    case Qt::ExtraButton24: return tr("Extra", "MouseButton") + "24";
+    default: return "";
+    }
+}
+
+Qt::MouseButton UBShortcutManager::buttonIndex(QString button)
+{
+    for (unsigned int index = Qt::LeftButton; index < Qt::AllButtons; index <<= 1)
+    {
+        Qt::MouseButton but = static_cast<Qt::MouseButton>(index);
+
+        if (button == buttonName(but))
+        {
+            return but;
+        }
+    }
+
+    return Qt::NoButton;
+}
+
+void UBShortcutManager::ignoreCtrl(bool ignore)
+{
+    for (auto& actionGroup : mActionGroups)
+    {
+        for (QAction* action : actionGroup.second)
+        {
+            if (!action->property("builtIn").toBool())
+            {
+                QList<QKeySequence> shortcuts = action->shortcuts();
+
+                if (ignore && !shortcuts.empty() && shortcuts[0][0] & Qt::CTRL) {
+                    QKeySequence noCtrl(shortcuts[0][0] ^ Qt::CTRL);
+                    shortcuts << noCtrl;
+                    action->setShortcuts(shortcuts);
+                }
+                else if (!ignore && shortcuts.size() > 1)
+                {
+                    action->setShortcuts( { shortcuts[0] } );
+                }
+            }
+        }
+    }
+
+    UBSettings::settings()->setValue("Shortcut/IgnoreCtrl", ignore);
+    emit dataChanged(index(0, 2), index(rowCount(), 2));
+}
+
+QString UBShortcutManager::groupOfAction(const QAction *action) const
+{
+    for (auto& actionGroup : mActionGroups)
+    {
+        for (QAction* actionInGroup : actionGroup.second)
+        {
+            if (action == actionInGroup)
+            {
+                return actionGroup.first;
+            }
+        }
+    }
+
+    return QString();
+}
+
+QList<QAction *> &UBShortcutManager::actionsOfGroup(const QString &group)
+{
+    for (auto& actionGroup : mActionGroups)
+    {
+        if (actionGroup.first == group) {
+            return actionGroup.second;
+        }
+    }
+
+    QPair<QString,QList<QAction*>> actionGroup;
+    actionGroup.first = group;
+    mActionGroups << actionGroup;
+
+    return mActionGroups.last().second;
+}
+
+QAction *UBShortcutManager::getAction(const QModelIndex &index, QString *group) const
+{
+    int row = index.row();
+
+    for (auto& actionGroup : mActionGroups)
+    {
+        if (row == 0)
+        {
+            if (group)
+            {
+                *group = actionGroup.first;
+            }
+
+            return nullptr;
+        }
+
+        if (row <= actionGroup.second.size())
+        {
+            if (group)
+            {
+                *group = actionGroup.first;
+            }
+
+            return actionGroup.second[row - 1];
+        }
+
+        --row;
+        row -= actionGroup.second.size();
+    }
+
+    if (group)
+    {
+        group->clear();
+    }
+
+    return nullptr;
+}
+
+void UBShortcutManager::updateSettings(const QAction *action) const
+{
+    QString key = "Shortcut/" + action->objectName();
+    QString keySequence = action->shortcut().toString();
+    QString defaultSequence = action->property(defaultShortcutProperty).toString();
+    int mouseButton = action->property(mouseButtonProperty).toInt();
+    int tabletButton = action->property(tabletButtonProperty).toInt();
+
+    if (keySequence == defaultSequence && mouseButton == 0 && tabletButton == 0)
+    {
+        // back to default, delete settings
+        UBSettings::settings()->setValue(key, QVariant());
+    }
+    else
+    {
+        QStringList list;
+        list << keySequence;
+        list << QString("%1").arg(mouseButton);
+        list << QString("%1").arg(tabletButton);
+        UBSettings::settings()->setValue(key, list);
+    }
+}
diff --git a/src/core/UBShortcutManager.h b/src/core/UBShortcutManager.h
new file mode 100644
index 000000000..9e90f7346
--- /dev/null
+++ b/src/core/UBShortcutManager.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM)
+ *
+ * Copyright (C) 2013 Open Education Foundation
+ *
+ * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
+ * l'Education Numérique en Afrique (GIP ENA)
+ *
+ * This file is part of OpenBoard.
+ *
+ * OpenBoard is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License,
+ * with a specific linking exception for the OpenSSL project's
+ * "OpenSSL" library (or with modified versions of it that use the
+ * same license as the "OpenSSL" library).
+ *
+ * OpenBoard is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef UBSHORTCUTMANAGER_H
+#define UBSHORTCUTMANAGER_H
+
+#include <QAbstractTableModel>
+#include <QList>
+#include <QMap>
+#include <QMouseEvent>
+#include <QPair>
+#include <QTabletEvent>
+
+class QAction;
+class UBMainWindow;
+
+class UBShortcutManager : public QAbstractTableModel
+{
+    Q_OBJECT;
+
+private:
+    UBShortcutManager();
+
+public:
+    static UBShortcutManager* shortcutManager();
+
+    enum {
+        ActionRole = Qt::UserRole,      // bool, true if row contains editable action
+        GroupHeaderRole,                // bool, true if row is group header
+        PrimaryShortcutRole             // QString, primary shortcut, only valid on column 2
+    };
+
+    void addActions(const QString& group, const QList<QAction*> actions, QWidget* widget = nullptr);
+    void addMainActions(UBMainWindow* mainWindow);
+
+    bool handleMouseEvent(QMouseEvent* event);
+    bool handleTabletEvent(QTabletEvent* event);
+
+    // QAbstractTableModel overrides
+    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
+    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
+    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
+    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
+    virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE;
+
+    bool resetData(const QModelIndex &index);
+    bool checkData(const QModelIndex &index, const QVariant &value) const;
+    bool hasCtrlConflicts(const QKeySequence& additionalShortcut = QKeySequence()) const;
+
+    static QString buttonName(Qt::MouseButton button);
+    static Qt::MouseButton buttonIndex(QString button);
+
+public slots:
+    void ignoreCtrl(bool ignore);
+
+private:
+    QString groupOfAction(const QAction* action) const;
+    QList<QAction*>& actionsOfGroup(const QString& group);
+    QAction* getAction(const QModelIndex& index, QString* group = nullptr) const;
+    void updateSettings(const QAction* action) const;
+
+private:
+    QList<QPair<QString,QList<QAction*>>> mActionGroups;
+    QMap<Qt::MouseButton, QAction*> mMouseActions;
+    QMap<Qt::MouseButton, QAction*> mTabletActions;
+
+    static UBShortcutManager* sShortcutManager;
+};
+
+#endif // UBSHORTCUTMANAGER_H
diff --git a/src/core/core.pri b/src/core/core.pri
index 3ad1846bb..d4c4f9ddc 100644
--- a/src/core/core.pri
+++ b/src/core/core.pri
@@ -1,5 +1,6 @@
 
 HEADERS      += src/core/UB.h \
+                src/core/UBShortcutManager.h \
                 src/core/UBApplication.h \
                 src/core/UBSettings.h \
                 src/core/UBSetting.h \
@@ -19,6 +20,7 @@ HEADERS      += src/core/UB.h \
     $$PWD/UBForeignObjectsHandler.h
 
 SOURCES      += src/core/main.cpp \
+                src/core/UBShortcutManager.cpp \
                 src/core/UBApplication.cpp \
                 src/core/UBSettings.cpp \
                 src/core/UBSetting.cpp \
diff --git a/src/gui/UBActionPalette.cpp b/src/gui/UBActionPalette.cpp
index c4bfe25d0..6196a6b07 100644
--- a/src/gui/UBActionPalette.cpp
+++ b/src/gui/UBActionPalette.cpp
@@ -68,7 +68,7 @@ void UBActionPalette::init(Qt::Orientation orientation)
     mButtonSize = QSize(32, 32);
     mIsClosable = false;
     mAutoClose = false;
-    mButtonGroup = 0;
+    mActionGroup = 0;
     mToolButtonStyle = Qt::ToolButtonIconOnly;
     mButtons.clear();
 
@@ -98,9 +98,10 @@ UBActionPaletteButton* UBActionPalette::createPaletteButton(QAction* action, QWi
     UBActionPaletteButton* button = new UBActionPaletteButton(action, parent);
     button->setIconSize(mButtonSize);
     button->setToolButtonStyle(mToolButtonStyle);
+    action->setProperty("id", mButtons.length());
 
-    if (mButtonGroup)
-        mButtonGroup->addButton(button, mButtons.length());
+    if (mActionGroup)
+        mActionGroup->addAction(action);
 
     mButtons << button;
 
@@ -155,16 +156,19 @@ void UBActionPalette::setButtonIconSize(const QSize& size)
 
 void UBActionPalette::groupActions()
 {
-    mButtonGroup = new QButtonGroup(this);
+    mActionGroup = new QActionGroup(this);
     int i = 0;
-    foreach(QToolButton* button, mButtons)
+    foreach(QAction* action, mActions)
     {
-        mButtonGroup->addButton(button, i);
-        ++i;
+        if (!action->property("ungrouped").toBool())
+        {
+            action->setProperty("id", i);
+            mActionGroup->addAction(action);
+            ++i;
+        }
     }
 
-    connect(mButtonGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked),
-            this, &UBActionPalette::buttonGroupClicked);
+    connect(mActionGroup, SIGNAL(triggered(QAction*)), this, SIGNAL(buttonGroupClicked(QAction*)));
 }
 
 
diff --git a/src/gui/UBActionPalette.h b/src/gui/UBActionPalette.h
index 55d3e6284..9c1859be5 100644
--- a/src/gui/UBActionPalette.h
+++ b/src/gui/UBActionPalette.h
@@ -32,7 +32,7 @@
 
 #include <QtGui>
 #include <QPoint>
-#include <QButtonGroup>
+#include <QActionGroup>
 #include <QToolButton>
 
 #include "UBFloatingPalette.h"
@@ -83,7 +83,7 @@ class UBActionPalette : public UBFloatingPalette
 
     signals:
         void closed();
-        void buttonGroupClicked(QAbstractButton *button);
+        void buttonGroupClicked(QAction* action);
         void customMouseReleased();
 
     protected:
@@ -94,7 +94,7 @@ class UBActionPalette : public UBFloatingPalette
         virtual void updateLayout();
 
         QList<UBActionPaletteButton*> mButtons;
-        QButtonGroup* mButtonGroup;
+        QActionGroup* mActionGroup;
         QList<QAction*> mActions;
         QMap<QAction*, UBActionPaletteButton*> mMapActionToButton;
 
diff --git a/src/gui/UBBackgroundPalette.cpp b/src/gui/UBBackgroundPalette.cpp
index 4f8d8ebf6..6ba4af7ea 100644
--- a/src/gui/UBBackgroundPalette.cpp
+++ b/src/gui/UBBackgroundPalette.cpp
@@ -29,7 +29,6 @@ void UBBackgroundPalette::init()
     mButtonSize = QSize(32, 32);
     mIsClosable = false;
     mAutoClose = false;
-    mButtonGroup = 0;
     mToolButtonStyle = Qt::ToolButtonIconOnly;
     mButtons.clear();
 
@@ -60,8 +59,7 @@ void UBBackgroundPalette::init()
     mDrawIntermediateLinesCheckBox->setFixedSize(24,24);
     mDrawIntermediateLinesCheckBox->setCheckable(true);
     mActions << UBApplication::mainWindow->actionDrawIntermediateGridLines;
-    mButtons.removeLast(); // don't add to button group
-
+    UBApplication::mainWindow->actionDrawIntermediateGridLines->setProperty("ungrouped", true);
     connect(UBApplication::mainWindow->actionDrawIntermediateGridLines, SIGNAL(toggled(bool)), this, SLOT(toggleIntermediateLines(bool)));
 
     mBottomLayout->addSpacing(16);
diff --git a/src/gui/UBMainWindow.cpp b/src/gui/UBMainWindow.cpp
index 5b3f24094..4dceca7a8 100644
--- a/src/gui/UBMainWindow.cpp
+++ b/src/gui/UBMainWindow.cpp
@@ -36,6 +36,7 @@
 #include "core/UBApplicationController.h"
 #include "board/UBBoardController.h"
 #include "core/UBDisplayManager.h"
+#include "core/UBShortcutManager.h"
 
 // work around for handling tablet events on MAC OS with Qt 4.8.0 and above
 #if defined(Q_OS_OSX)
@@ -76,6 +77,8 @@ UBMainWindow::UBMainWindow(QWidget *parent, Qt::WindowFlags flags)
 #else
     actionQuit->setShortcut(QKeySequence(Qt::ALT + Qt::Key_F4));
 #endif
+
+    UBShortcutManager::shortcutManager()->addMainActions(this);
 }
 
 UBMainWindow::~UBMainWindow()
diff --git a/src/gui/UBStylusPalette.cpp b/src/gui/UBStylusPalette.cpp
index 2c09e718a..cac047991 100644
--- a/src/gui/UBStylusPalette.cpp
+++ b/src/gui/UBStylusPalette.cpp
@@ -78,13 +78,13 @@ UBStylusPalette::UBStylusPalette(QWidget *parent, Qt::Orientation orient)
     {
         // VirtualKeyboard action is not in group
         // So, groupping all buttons, except last
-        mButtonGroup = new QButtonGroup(this);
-        for(int i=0; i < mButtons.size()-1; i++)
+        mActionGroup = new QActionGroup(this);
+        for(int i=0; i < mActions.size()-1; i++)
         {
-            mButtonGroup->addButton(mButtons[i], i);
+            mActions[i]->setProperty("id", i);
+            mActionGroup->addAction(mActions[i]);
         }
-        connect(mButtonGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked),
-                this, &UBActionPalette::buttonGroupClicked);
+        connect(mActionGroup, SIGNAL(triggered(QAction*)), this, SIGNAL(buttonGroupClicked(QAction*)));
     }
 
     adjustSizeAndPosition();
@@ -131,7 +131,7 @@ UBStylusPalette::~UBStylusPalette()
 
 void UBStylusPalette::stylusToolDoubleClicked()
 {
-    emit stylusToolDoubleClicked(mButtonGroup->checkedId());
+    emit stylusToolDoubleClicked(mActionGroup->checkedAction()->property("id").toInt());
 }
 
 

From fcd39d519fa01968298a73b31915ff229607c743 Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Sat, 20 Mar 2021 08:28:35 +0100
Subject: [PATCH 2/8] update translation files, add German translation for
 shortcut settings

---
 resources/i18n/OpenBoard_ar.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_bg.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_ca.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_cs.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_da.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_de.ts    | 216 +++++++++++++++++++++++++++++-
 resources/i18n/OpenBoard_el.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_en.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_en_UK.ts | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_es.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_fr.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_fr_CH.ts | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_gl.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_hu.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_it.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_iw.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_ja.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_ko.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_mg.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_nb.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_nl.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_pl.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_pt.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_ro.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_ru.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_sk.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_sv.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_tr.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_uk.ts    | 208 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_zh.ts    | 207 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_zh_CN.ts | 207 ++++++++++++++++++++++++++++
 resources/i18n/OpenBoard_zh_TW.ts | 208 ++++++++++++++++++++++++++++
 32 files changed, 6658 insertions(+), 4 deletions(-)

diff --git a/resources/i18n/OpenBoard_ar.ts b/resources/i18n/OpenBoard_ar.ts
index c5992155d..225c5afdb 100644
--- a/resources/i18n/OpenBoard_ar.ts
+++ b/resources/i18n/OpenBoard_ar.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>هل تريدون حقا إزالة صفحة واحدة من الوثيقة &apos;%0&apos; المختارة؟</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2086,6 +2090,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>العلامة حساسة للضغط</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">موافقة</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">تسجيل</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2094,6 +2120,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>أفلامي</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">لوحة</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">لوح الرسم</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">بودكاست</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">الوصف</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">يسار</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">يمين </translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">العودة</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">أمام</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2751,6 +2919,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">تسجيل</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_bg.ts b/resources/i18n/OpenBoard_bg.ts
index ea528bc21..be2937ca1 100644
--- a/resources/i18n/OpenBoard_bg.ts
+++ b/resources/i18n/OpenBoard_bg.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Сигурни ли сте ,че искате да премахнете 1 страница от избрания документ &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Чувствителен на натиск маркер</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Приеми</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Запиши</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Моите филми</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Дъска</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Палитна на стилуса</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Подкаст</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Описание</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">На ляво</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">На дясно</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Назад</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Напред</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2741,6 +2909,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Запиши</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_ca.ts b/resources/i18n/OpenBoard_ca.ts
index b363e9a11..741f67337 100644
--- a/resources/i18n/OpenBoard_ca.ts
+++ b/resources/i18n/OpenBoard_ca.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Esteu segur que voleu eliminar 1 pàgina del document seleccionat &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Voleu ignorar aquests errors per a aquest amfitrió?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>El marcador és sensible a la pressió</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">D&apos;acord</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Enregistra</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Voleu ignorar aquests errors per a aquest amfitrió?</translation>
         <translation>Les meves pel·lícules</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tauler</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Barra d&apos;estris</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Descripció</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Esquerra</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Dreta</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Enrere</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Cap endavant</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBThumbnailAdaptor</name>
     <message>
@@ -2735,6 +2903,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Enregistra</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_cs.ts b/resources/i18n/OpenBoard_cs.ts
index 77834ee6a..de6ea037a 100644
--- a/resources/i18n/OpenBoard_cs.ts
+++ b/resources/i18n/OpenBoard_cs.ts
@@ -942,6 +942,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Opravdu chcete odstranit 1 stránku z vybraného dokumentu &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2083,6 +2087,28 @@ Chcete ignorovat tyto chyby na tomto serveru?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>Zvýrazňovač je citlivý na tlak</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Přijmout</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Nahrávat</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2091,6 +2117,148 @@ Chcete ignorovat tyto chyby na tomto serveru?</translation>
         <translation>Moje filmy</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paleta pro stylus</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Popis</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Vlevo</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Vpravo</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Zpět</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Vpřed</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2746,6 +2914,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Nahrávat</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_da.ts b/resources/i18n/OpenBoard_da.ts
index e30d9b3a0..3f267470e 100644
--- a/resources/i18n/OpenBoard_da.ts
+++ b/resources/i18n/OpenBoard_da.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Er du sikker på, at du vil fjerne 1 side fra det valgte dokument&apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Markøren er tryksensitiv</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Accepter</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Optag</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Mine Film</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tavle</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Penpalette</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Beskrivelse</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Venstre</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Højre</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Tilbage</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Fremad</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2738,6 +2906,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Optag</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_de.ts b/resources/i18n/OpenBoard_de.ts
index 5abf0c3ca..b30b36a0f 100644
--- a/resources/i18n/OpenBoard_de.ts
+++ b/resources/i18n/OpenBoard_de.ts
@@ -355,7 +355,7 @@ Möchten Sie die Sicherheitsüberprüfung außer Kraft setzen und fortfahren?
     </message>
     <message>
         <source>Ctrl++</source>
-        <translation>Strg ++</translation>
+        <translation>Strg++</translation>
     </message>
     <message>
         <source>Smaller</source>
@@ -367,7 +367,7 @@ Möchten Sie die Sicherheitsüberprüfung außer Kraft setzen und fortfahren?
     </message>
     <message>
         <source>Ctrl+-</source>
-        <translation>Strg +-</translation>
+        <translation>Strg+-</translation>
     </message>
     <message>
         <source>New Folder</source>
@@ -943,6 +943,10 @@ Möchten Sie die Sicherheitsüberprüfung außer Kraft setzen und fortfahren?
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Wollen Sie wirklich die ausgewählte Seite des Dokuments &apos;%0&apos; entfernen?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation>Laden der Szene (%1/%2)</translation>
@@ -2088,6 +2092,28 @@ Möchten Sie diese Fehler für diesen Computer ignorieren?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>Der Marker ist druckempfindlich</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation>Tastenkombination wird bereits benutzt</translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation>Maustaste wird bereits benutzt</translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation>Stifttaste wird bereits benutzt</translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation>Übernehmen</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation>Aufnehmen</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2096,6 +2122,148 @@ Möchten Sie diese Fehler für diesen Computer ignorieren?</translation>
         <translation>Meine Filme</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation>Allgemein</translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation>Board</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation>Stylus-Palette</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation>Linien und Farben</translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation>Hintergrund</translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation>Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation>Erste Seite</translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation>Erste Seite anzeigen</translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation>Letzte Seite</translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation>Letzte Seite anzeigen</translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation>Originalgröße</translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation>Zoom-Faktor zurücksetzen</translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation>Links</translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation>Seite nach links verschieben</translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation>Rechts</translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation>Seite nach rechts verschieben</translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation>Oben</translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation>Seite nach oben verschieben</translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation>Unten</translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation>Seite nach unten verschieben</translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation>Eingebaut (nicht änderbar)</translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation>Befehl</translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation>Beschreibung</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation>Tasten</translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation>Maustaste</translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation>Stifttaste</translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation>Links</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation>Rechts</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation>Mitte</translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation>Zurück</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation>Weiter</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation>Aufgabe</translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation>Extre</translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2687,7 +2855,7 @@ p, li { white-space: pre-wrap; }
     </message>
     <message>
         <source>Desktop</source>
-        <translation>Schreibtisch</translation>
+        <translation>Desktop</translation>
     </message>
     <message>
         <source>Proxy User:</source>
@@ -2757,9 +2925,49 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation>PDF-Wiedergabe</translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation>Kurzbefehl</translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation>Filter</translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation>Aktiviere Kurzbefehle auch ohne Strg Taste</translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation>Kurzbefehle</translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation>Abbrechen</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation>Aufnehmen</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation>Stifttaste</translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation>Maustaste</translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation>Zurücksetzen</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation>Tasten</translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
-        <translation>Die Zoomgeschwindigkeit verbessern (kann die Renderqualität geringfügig beeinträchtigen)</translation>
+        <translation>Zoom beschleunigen (kann Qualität geringfügig beeinträchtigen)</translation>
     </message>
 </context>
 <context>
diff --git a/resources/i18n/OpenBoard_el.ts b/resources/i18n/OpenBoard_el.ts
index a0d876e71..2be67b587 100644
--- a/resources/i18n/OpenBoard_el.ts
+++ b/resources/i18n/OpenBoard_el.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Είστε βέβαιος ότι θέλετε να αφαιρέσετε μια σελίδα από το επιλεγμένο έγγραφο &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Ο μαρκαδόρος είναι ευαίσθητος στην πίεση</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Αποδοχή</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Εγγραφή</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Οι ταινίες μου</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Εφαρμογή</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Παλέτα εργαλείων</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Βίντεο</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Περιγραφή</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Αριστερά</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Δεξιά</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Πίσω</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Μπροστά</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Εγγραφή</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_en.ts b/resources/i18n/OpenBoard_en.ts
index 09faf32d6..f864cc2cd 100644
--- a/resources/i18n/OpenBoard_en.ts
+++ b/resources/i18n/OpenBoard_en.ts
@@ -964,6 +964,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>(Untitled)</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2062,6 +2066,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2070,6 +2096,148 @@ Do you want to ignore these errors for this host?</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2720,6 +2888,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_en_UK.ts b/resources/i18n/OpenBoard_en_UK.ts
index 09faf32d6..f864cc2cd 100644
--- a/resources/i18n/OpenBoard_en_UK.ts
+++ b/resources/i18n/OpenBoard_en_UK.ts
@@ -964,6 +964,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>(Untitled)</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2062,6 +2066,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2070,6 +2096,148 @@ Do you want to ignore these errors for this host?</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2720,6 +2888,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_es.ts b/resources/i18n/OpenBoard_es.ts
index 77b6f80a5..5eb26c8ed 100644
--- a/resources/i18n/OpenBoard_es.ts
+++ b/resources/i18n/OpenBoard_es.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>¿Está seguro de que quiere eliminar 1 página del documento seleccionado.&apos;%0?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>El marcador es sensible a la presión</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Aceptar</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Grabar</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Mis películas</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Pizarra</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paleta del lápiz</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Descripción</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Izquierda</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Derecha</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Atrás</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Hacia delante</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Grabar</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_fr.ts b/resources/i18n/OpenBoard_fr.ts
index 8db8960a0..08974d643 100644
--- a/resources/i18n/OpenBoard_fr.ts
+++ b/resources/i18n/OpenBoard_fr.ts
@@ -942,6 +942,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Voulez-vous vraiment effacer 1 page de ce document &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation>Chargement de la scène (%1/%2)</translation>
@@ -2093,6 +2097,28 @@ Voulez-vous ignorer les erreurs pour ce serveur ?</translation>
         <source>version: </source>
         <translation>version : </translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Accepter</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Enregistrer</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2101,6 +2127,148 @@ Voulez-vous ignorer les erreurs pour ce serveur ?</translation>
         <translation>Mes films</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tableau</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Barre du stylet</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Description</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Gauche</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Droite</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Précédente</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Suivante</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2761,6 +2929,46 @@ p, li { white-space: pre-wrap; }
         <translation>Rendu PDF</translation>
     </message>
     <message>
+    </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Enregistrer</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation>Améliorer la vitesse d&apos;exécution du zoom (peut légèrement affecter la qualité du rendu)</translation>
     </message>
diff --git a/resources/i18n/OpenBoard_fr_CH.ts b/resources/i18n/OpenBoard_fr_CH.ts
index 29285a2f0..e0afde789 100644
--- a/resources/i18n/OpenBoard_fr_CH.ts
+++ b/resources/i18n/OpenBoard_fr_CH.ts
@@ -942,6 +942,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Voulez-vous vraiment effacer 1 page de ce document &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation>Chargement de la scène (%1/%2)</translation>
@@ -2093,6 +2097,28 @@ Voulez-vous ignorer les erreurs pour ce serveur ?</translation>
         <source>version: </source>
         <translation>version : </translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Accepter</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Enregistrer</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2101,6 +2127,148 @@ Voulez-vous ignorer les erreurs pour ce serveur ?</translation>
         <translation>Mes films</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tableau</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Barre du stylet</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Description</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Gauche</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Droite</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Précédente</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Suivante</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2761,6 +2929,46 @@ p, li { white-space: pre-wrap; }
         <translation>Rendu PDF</translation>
     </message>
     <message>
+    </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Enregistrer</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation>Améliorer la vitesse d&apos;exécution du zoom (peut légèrement affecter la qualité du rendu)</translation>
     </message>
diff --git a/resources/i18n/OpenBoard_gl.ts b/resources/i18n/OpenBoard_gl.ts
index f2ae77c21..618595d11 100644
--- a/resources/i18n/OpenBoard_gl.ts
+++ b/resources/i18n/OpenBoard_gl.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>¿Está seguro de que quere eliminar 1 páxina do documento seleccionado.&apos;%0?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>O marcador é sensible á presión</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Aceptar</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Grabar</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>As miñas películas</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Encerado</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paleta do lápiz</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Esquerda</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Dereita</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Atrás</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Cara a diante</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2734,6 +2902,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Grabar</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_hu.ts b/resources/i18n/OpenBoard_hu.ts
index 368afe75d..e9f1f8c95 100644
--- a/resources/i18n/OpenBoard_hu.ts
+++ b/resources/i18n/OpenBoard_hu.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Content is not supported in destination format.</source>
         <translation>A tartalom nem támogatott célformátumban.</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2153,6 +2157,28 @@ Figyelmen kívül hagyja ezeket a hibákat ennél a hosztnál?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>A jelölőtoll nyomásérzékeny</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Elfogad</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Felvétel</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2161,6 +2187,148 @@ Figyelmen kívül hagyja ezeket a hibákat ennél a hosztnál?</translation>
         <translation>Videóim</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tábla</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Képernyő eszköztár</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Leírás</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Bal</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Jobb</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Vissza</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Előre</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2811,6 +2979,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation>PDF-megjelenítő</translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Felvétel</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation>Nagyitás végrehajtási idő csökkentése (némileg befolyásolhatja a renderelés minőségét)</translation>
diff --git a/resources/i18n/OpenBoard_it.ts b/resources/i18n/OpenBoard_it.ts
index e9b23112f..a29189b26 100644
--- a/resources/i18n/OpenBoard_it.ts
+++ b/resources/i18n/OpenBoard_it.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Sei sicuro di voler rimuovere 1 pagina dal documento selezionato &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation>Caricamento della scena (%1/%2)</translation>
@@ -2081,6 +2085,28 @@ Vuoi ignorare gli errori per questo host?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>L&apos;evidenziatore è sensibile alla pressione</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Accetta</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Registra</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2089,6 +2115,148 @@ Vuoi ignorare gli errori per questo host?</translation>
         <translation>I miei film</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Lavagna</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Palette stilo</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Descrizione</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Sinistra</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Destra</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Indietro</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Avanti</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2749,6 +2917,46 @@ p, li { white-space: pre-wrap; }
         <translation>rendering PDF</translation>
     </message>
     <message>
+    </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Registra</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation>Migliorare la velocità dello zoom (può influire leggermente sulla qualità del rendering)</translation>
     </message>
diff --git a/resources/i18n/OpenBoard_iw.ts b/resources/i18n/OpenBoard_iw.ts
index fbf8fd6e2..e12f6e19a 100644
--- a/resources/i18n/OpenBoard_iw.ts
+++ b/resources/i18n/OpenBoard_iw.ts
@@ -942,6 +942,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>האם אתה בטוח שברצונך למחוק דף 1 מהמסמך שנבחר %0?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>הסמן רגיש ללחץ</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">קבל</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">הקלט</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>הסרטים שלי</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">לוח</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">סרגל הכלים הגראפיים</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">פודקסט</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">תיאור</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">שמאל</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">ימין</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">חזרה</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">קדימה</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2734,6 +2902,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">הקלט</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_ja.ts b/resources/i18n/OpenBoard_ja.ts
index a1834d11a..214735f31 100644
--- a/resources/i18n/OpenBoard_ja.ts
+++ b/resources/i18n/OpenBoard_ja.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2077,6 +2081,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>感圧性マーカー</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">記録</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2085,6 +2111,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>マイ・ムービー </translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">ボード</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">スタイラスパレット </translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">ポッドキャスト </translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">説明</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">左</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">右</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">戻る</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">前へ</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2736,6 +2904,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">記録</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_ko.ts b/resources/i18n/OpenBoard_ko.ts
index cfb4e3c95..15730ad63 100644
--- a/resources/i18n/OpenBoard_ko.ts
+++ b/resources/i18n/OpenBoard_ko.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation type="unfinished">선택한 문서 &apos;%0&apos;에서 1페이지를 제거하시겠습니까?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2082,6 +2086,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>마커는 압력 감지식입니다</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">적용</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">레코딩</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2090,6 +2116,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>내 동영상</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">보드</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">스타일러스 팔레트</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">팟캐스트</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">설명</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">왼쪽</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">오른쪽</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">뒤로</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">앞으로</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2745,6 +2913,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">레코딩</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_mg.ts b/resources/i18n/OpenBoard_mg.ts
index f878bbcbd..77181144f 100644
--- a/resources/i18n/OpenBoard_mg.ts
+++ b/resources/i18n/OpenBoard_mg.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Tena te hamafa pejy iray avy amin&apos;ilay rakitra &apos;%0&apos; voafidy ve ianao ?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Tena tsy te hiraharaha an&apos;ireo tsy mety ho an&apos;ilay milina ve ianao?</t
         <source>Marker is pressure sensitive</source>
         <translation>Ny penina lehibe dia sarotiny amin&apos;ny fitsindrina</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Ekena</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Raiketo</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Tena tsy te hiraharaha an&apos;ireo tsy mety ho an&apos;ilay milina ve ianao?</t
         <translation>Ny sarimietsiko</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Solaitra</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Fanovana haingony</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Fanazavana</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Havia</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Havanana</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Miverina</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Manaraka</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Raiketo</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_nb.ts b/resources/i18n/OpenBoard_nb.ts
index a1d116a73..525773cd7 100644
--- a/resources/i18n/OpenBoard_nb.ts
+++ b/resources/i18n/OpenBoard_nb.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Er du sikker på at du vil fjerne side 1 fra det valgte dokumentet &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Markøren er trykksensitiv</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Godta</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Ta opp</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Mine filmer</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tavle</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Stilpalett</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Beskrivelse</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Venstre</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Høyre</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Tilbake</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Forover</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2739,6 +2907,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Ta opp</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_nl.ts b/resources/i18n/OpenBoard_nl.ts
index 1331f11c5..f266d552a 100644
--- a/resources/i18n/OpenBoard_nl.ts
+++ b/resources/i18n/OpenBoard_nl.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2073,6 +2077,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Markeerstift is druk gevoelig</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Opnemen</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2081,6 +2107,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Mijn films</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Bord</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Pen palet</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Beschrijving</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Links</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Rechts</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Terug</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Vooruit</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2735,6 +2903,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Opnemen</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_pl.ts b/resources/i18n/OpenBoard_pl.ts
index 4ff6ff623..1fe204425 100644
--- a/resources/i18n/OpenBoard_pl.ts
+++ b/resources/i18n/OpenBoard_pl.ts
@@ -944,6 +944,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Czy na pewno chcesz usunąć 1 stronę z wybranego dokumentu „%0”?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2087,6 +2091,28 @@ Czy chcesz ignorować te błędy dla tego hosta?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>Marker jest czuły na nacisk</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Akceptuj</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Nagraj</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2095,6 +2121,148 @@ Czy chcesz ignorować te błędy dla tego hosta?</translation>
         <translation>Moje filmy</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tablica</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paleta piórka</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podkast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Opis</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Lewo</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Prawo</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Powrót</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Do przodu</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2750,6 +2918,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation>Renderowanie PDF</translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Nagraj</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation>Usprawnij wykonywanie przybliżania (może nieco pogorszyć jakość renderowania)</translation>
diff --git a/resources/i18n/OpenBoard_pt.ts b/resources/i18n/OpenBoard_pt.ts
index 8b0f25334..a42154338 100644
--- a/resources/i18n/OpenBoard_pt.ts
+++ b/resources/i18n/OpenBoard_pt.ts
@@ -943,6 +943,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Tem a certeza que quer remover 1 página do documento selecionado &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2082,6 +2086,28 @@ Quer ignorar estes erros, deste servidor?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>O marcador é sensível à pressão</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Aceitar</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Gravar</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2090,6 +2116,148 @@ Quer ignorar estes erros, deste servidor?</translation>
         <translation>Os meus filmes</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Quadro</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paleta</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Descrição</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Esquerda</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Direita</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Recuar</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Avançar</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBThumbnailAdaptor</name>
     <message>
@@ -2740,6 +2908,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Gravar</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_ro.ts b/resources/i18n/OpenBoard_ro.ts
index 72f1a4965..def38a48e 100644
--- a/resources/i18n/OpenBoard_ro.ts
+++ b/resources/i18n/OpenBoard_ro.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Sunteți sigur că doriți să eliminați 1 pagină din documentul selectat &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Doriţi să ignoraţi aceste erori pentru acest host?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>Markerul este sensibil la apăsare</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Acceptare</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Înregistrare</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Doriţi să ignoraţi aceste erori pentru acest host?</translation>
         <translation>Filmele mele</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tablă</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paletă stilou</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Descriere</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Stânga</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Dreapta</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Înapoi</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Înainte</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Înregistrare</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_ru.ts b/resources/i18n/OpenBoard_ru.ts
index f82aeba37..9171f8695 100644
--- a/resources/i18n/OpenBoard_ru.ts
+++ b/resources/i18n/OpenBoard_ru.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Вы уверены, что хотите удалить 1 страницу из документа &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2081,6 +2085,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Маркер чувствителен к нажиму</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Принять</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Запись</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2089,6 +2115,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Мои видеофайлы</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Доска</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Инструменты</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Подкаст</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Описание</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Влево</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Вправо</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Назад</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Вперед</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2744,6 +2912,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Запись</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_sk.ts b/resources/i18n/OpenBoard_sk.ts
index 8bd3ee266..4b2dadf6a 100644
--- a/resources/i18n/OpenBoard_sk.ts
+++ b/resources/i18n/OpenBoard_sk.ts
@@ -944,6 +944,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Určite chcete odstrániť 1 stránku z vybraného dokumentu &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2087,6 +2091,28 @@ Chcete ignorovať tieto chyby na tomto serveri?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>Zvýrazňovač je citlivý na tlak</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Prijať</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Nahrávať</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2095,6 +2121,148 @@ Chcete ignorovať tieto chyby na tomto serveri?</translation>
         <translation>Moje filmy</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tabuľa</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Paleta pre interaktívne pero</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Popis</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Doľava</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Doprava</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Predošlá</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Ďalšia</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2751,6 +2919,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Nahrávať</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_sv.ts b/resources/i18n/OpenBoard_sv.ts
index d4150b304..97bc675f7 100644
--- a/resources/i18n/OpenBoard_sv.ts
+++ b/resources/i18n/OpenBoard_sv.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Är du säker på att du vill ta bort 1 sida från det valda dokumentet &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2080,6 +2084,28 @@ Vill du ignorera felen för den här värden?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>Markören är tryckkänslig</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Acceptera</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Spela in</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2088,6 +2114,148 @@ Vill du ignorera felen för den här värden?</translation>
         <translation>Mina filmer</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tavla</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Pekpennans palett</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Beskrivning</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Vänster</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Höger</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Backa</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Framåt</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2743,6 +2911,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Spela in</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_tr.ts b/resources/i18n/OpenBoard_tr.ts
index 7237a34df..71dd54b1e 100644
--- a/resources/i18n/OpenBoard_tr.ts
+++ b/resources/i18n/OpenBoard_tr.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Seçili olan &apos;%0&apos; adlı dökümandan 1 sayfayı kaldırmak üzeresiniz. Bu işlemi yapmak istediğinizden eminmisiniz?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2075,6 +2079,28 @@ Bu host için yukarıdaki hatalar yok sayılsın mı?</translation>
         <source>Marker is pressure sensitive</source>
         <translation>İşaretçi basınca duyarlıdır</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Kabul Et</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Kayıt</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2083,6 +2109,148 @@ Bu host için yukarıdaki hatalar yok sayılsın mı?</translation>
         <translation>Filimlerim</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Tahta</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Stylus Paleti</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Ekran Kaydı</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Açıklama</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Sol</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Sağ</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Geri</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">İleri</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2738,6 +2906,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Kayıt</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_uk.ts b/resources/i18n/OpenBoard_uk.ts
index 7a592caa0..bc812e76b 100644
--- a/resources/i18n/OpenBoard_uk.ts
+++ b/resources/i18n/OpenBoard_uk.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>Ви впевнені, що хочете видалити 1 сторінку з документа &apos;%0&apos;?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>Маркер чутливий до тиску</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Прийняти</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">Запис</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>Мої відеофайли</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">Дошка</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">Інструменти</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Подкаст</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">Опис</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Вліво</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Вправо</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Назад</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">Вперед</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">Запис</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>
diff --git a/resources/i18n/OpenBoard_zh.ts b/resources/i18n/OpenBoard_zh.ts
index 805c71509..86d9430e8 100644
--- a/resources/i18n/OpenBoard_zh.ts
+++ b/resources/i18n/OpenBoard_zh.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
       <source>Are you sure you want to remove 1 page from the selected document '%0'?</source>
       <translation>确定要删除选中文件“%0”中的1页?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
       <source>Loading scene (%1/%2)</source>
       <translation type="unfinished">加载场景 (%1/%2)</translation>
@@ -2072,6 +2076,28 @@ Do you want to ignore these errors for this host?</source>
       <source>Marker is pressure sensitive</source>
       <translation>使用压感记号笔</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">接受</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">录制</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2080,6 +2106,148 @@ Do you want to ignore these errors for this host?</source>
       <translation>我的视频</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">演示板</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">工具面板</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">播客</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">描述</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">向左</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">向右</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">后退</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">前进</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2735,6 +2903,45 @@ p, li { white-space: pre-wrap; }
       <source>PDF Rendering</source>
       <translation type="unfinished">PDF 渲染</translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">录制</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+    </message>
     <message>
       <source>Improve zoom execution time (can slightly affect rendering quality)</source>
       <translation type="unfinished">提高缩放执行时间(可能会略微影响渲染质量)</translation>
diff --git a/resources/i18n/OpenBoard_zh_CN.ts b/resources/i18n/OpenBoard_zh_CN.ts
index 805c71509..86d9430e8 100644
--- a/resources/i18n/OpenBoard_zh_CN.ts
+++ b/resources/i18n/OpenBoard_zh_CN.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
       <source>Are you sure you want to remove 1 page from the selected document '%0'?</source>
       <translation>确定要删除选中文件“%0”中的1页?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
       <source>Loading scene (%1/%2)</source>
       <translation type="unfinished">加载场景 (%1/%2)</translation>
@@ -2072,6 +2076,28 @@ Do you want to ignore these errors for this host?</source>
       <source>Marker is pressure sensitive</source>
       <translation>使用压感记号笔</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">接受</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">录制</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2080,6 +2106,148 @@ Do you want to ignore these errors for this host?</source>
       <translation>我的视频</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished">演示板</translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">工具面板</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">播客</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">描述</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">向左</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">向右</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">后退</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">前进</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBTeacherBarWidget</name>
     <message>
@@ -2735,6 +2903,45 @@ p, li { white-space: pre-wrap; }
       <source>PDF Rendering</source>
       <translation type="unfinished">PDF 渲染</translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">录制</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+    </message>
     <message>
       <source>Improve zoom execution time (can slightly affect rendering quality)</source>
       <translation type="unfinished">提高缩放执行时间(可能会略微影响渲染质量)</translation>
diff --git a/resources/i18n/OpenBoard_zh_TW.ts b/resources/i18n/OpenBoard_zh_TW.ts
index b2d45e269..835afebe3 100644
--- a/resources/i18n/OpenBoard_zh_TW.ts
+++ b/resources/i18n/OpenBoard_zh_TW.ts
@@ -941,6 +941,10 @@ Do you wish to override the security check and continue ?   </source>
         <source>Are you sure you want to remove 1 page from the selected document &apos;%0&apos;?</source>
         <translation>確定要移除所選文件 &apos;%0&apos; 的一個頁面?</translation>
     </message>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Loading scene (%1/%2)</source>
         <translation type="unfinished"></translation>
@@ -2070,6 +2074,28 @@ Do you want to ignore these errors for this host?</source>
         <source>Marker is pressure sensitive</source>
         <translation>感壓型提示筆</translation>
     </message>
+    <message>
+        <source>Key sequence already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus button already in use</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Accept</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">接受</translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <comment>preferencesDialog</comment>
+        <translation type="unfinished">錄製</translation>
+    </message>
 </context>
 <context>
     <name>UBSettings</name>
@@ -2078,6 +2104,148 @@ Do you want to ignore these errors for this host?</source>
         <translation>我的影片</translation>
     </message>
 </context>
+<context>
+    <name>UBShortcutManager</name>
+    <message>
+        <source>Common</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Board</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Stylus Palette</source>
+        <translation type="unfinished">桌面工具</translation>
+    </message>
+    <message>
+        <source>Lines and colours</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Background</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Podcast</source>
+        <translation type="unfinished">Podcast</translation>
+    </message>
+    <message>
+        <source>First scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show first scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Show last scene</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Zoom reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset zoom factor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page left</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page right</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page up</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Scroll page down</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Built-in (not editable)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation type="unfinished">描述</translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Tablet Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">向左</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">向右</translation>
+    </message>
+    <message>
+        <source>Middle</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Back</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">退回</translation>
+    </message>
+    <message>
+        <source>Forward</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished">前進</translation>
+    </message>
+    <message>
+        <source>Task</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Extra</source>
+        <comment>MouseButton</comment>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>UBThumbnailAdaptor</name>
     <message>
@@ -2726,6 +2894,46 @@ p, li { white-space: pre-wrap; }
         <source>PDF Rendering</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Shortcut</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Active keyboard shortcuts without pressing Ctrl key</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Shortcuts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Abort</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Record</source>
+        <translation type="unfinished">錄製</translation>
+    </message>
+    <message>
+        <source>Stylus Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mouse Button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Key Sequence</source>
+        <translation type="unfinished"></translation>
+    </message>
     <message>
         <source>Improve zoom execution time (can slightly affect rendering quality)</source>
         <translation type="unfinished"></translation>

From 39456c6e853186b45b395f693f9b251d4d8f3456 Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Wed, 24 Mar 2021 17:58:24 +0100
Subject: [PATCH 3/8] additional fixes

- deactivated actionPodcastPause because currently not activated
  in UBPodcastRecordingPalette
---
 src/core/UBShortcutManager.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/UBShortcutManager.cpp b/src/core/UBShortcutManager.cpp
index a03691ecf..94328abc2 100644
--- a/src/core/UBShortcutManager.cpp
+++ b/src/core/UBShortcutManager.cpp
@@ -193,8 +193,8 @@ void UBShortcutManager::addMainActions(UBMainWindow *mainWindow)
                }, mainWindow);
 
     addActions(tr("Podcast"), {
-                   mainWindow->actionPodcastRecord,
-                   mainWindow->actionPodcastPause
+                   mainWindow->actionPodcastRecord //,
+                   // mainWindow->actionPodcastPause currently not activated in UBPodcastRecordingPalette
                }, mainWindow);
 
     // add builtIn actions

From c2db115607c7baa274a5bb0cbdc19239c20c2d2e Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Wed, 20 Oct 2021 18:28:41 +0200
Subject: [PATCH 4/8] add more shortcuts, fix conflicts

- add the shortcuts for cut/copy/paste/quit
---
 src/board/UBBoardView.cpp       | 5 +++--
 src/core/UBShortcutManager.cpp  | 6 +++++-
 src/gui/UBDocumentNavigator.cpp | 5 +++--
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp
index 817d8c4e7..c52a5c6ae 100644
--- a/src/board/UBBoardView.cpp
+++ b/src/board/UBBoardView.cpp
@@ -245,14 +245,15 @@ void UBBoardView::keyPressEvent (QKeyEvent *event)
             switch (event->key ())
             {
             case Qt::Key_Plus:
-            case Qt::Key_I:
+// conflicts with pen selection shortcut
+//            case Qt::Key_I:
             {
                 mController->zoomIn ();
                 event->accept ();
                 break;
             }
             case Qt::Key_Minus:
-            case Qt::Key_O:
+//            case Qt::Key_O:
             {
                 mController->zoomOut ();
                 event->accept ();
diff --git a/src/core/UBShortcutManager.cpp b/src/core/UBShortcutManager.cpp
index 94328abc2..0275899cf 100644
--- a/src/core/UBShortcutManager.cpp
+++ b/src/core/UBShortcutManager.cpp
@@ -126,7 +126,11 @@ void UBShortcutManager::addMainActions(UBMainWindow *mainWindow)
                    mainWindow->actionLibrary,
                    mainWindow->actionVirtualKeyboard,
                    mainWindow->actionOpenTutorial,
-                   mainWindow->actionHideApplication
+                   mainWindow->actionHideApplication,
+                   mainWindow->actionCut,
+                   mainWindow->actionCopy,
+                   mainWindow->actionPaste,
+                   mainWindow->actionQuit
                }, mainWindow);
 
     addActions(tr("Board"), {
diff --git a/src/gui/UBDocumentNavigator.cpp b/src/gui/UBDocumentNavigator.cpp
index 6ae25b974..61c06b75f 100644
--- a/src/gui/UBDocumentNavigator.cpp
+++ b/src/gui/UBDocumentNavigator.cpp
@@ -509,14 +509,15 @@ void UBDocumentNavigator::keyPressEvent(QKeyEvent *event)
             switch (event->key ())
             {
             case Qt::Key_Plus:
-            case Qt::Key_I:
+// conflicts with pen selection shortcut
+//            case Qt::Key_I:
             {
                 controller->zoomIn ();
                 event->accept ();
                 break;
             }
             case Qt::Key_Minus:
-            case Qt::Key_O:
+//            case Qt::Key_O:
             {
                 controller->zoomOut ();
                 event->accept ();

From b3617480ced3d4decc4e473226723d430229a2ec Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Sat, 23 Oct 2021 11:02:23 +0200
Subject: [PATCH 5/8] seamless switching between tools

- switch between tools in board mode even if pen down
- new tool starts at current position
- fix conflict between panning and page change
---
 src/board/UBBoardView.cpp         | 69 +++++++++++++++++--------------
 src/board/UBDrawingController.cpp | 13 ++++--
 src/board/UBDrawingController.h   |  2 +-
 src/domain/UBGraphicsScene.cpp    | 27 +++++++-----
 src/domain/UBGraphicsScene.h      |  1 +
 5 files changed, 64 insertions(+), 48 deletions(-)

diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp
index c52a5c6ae..a711cfdd5 100644
--- a/src/board/UBBoardView.cpp
+++ b/src/board/UBBoardView.cpp
@@ -198,48 +198,53 @@ void UBBoardView::keyPressEvent (QKeyEvent *event)
 
     if (!event->isAccepted ())
     {
-        switch (event->key ())
-        {
-        case Qt::Key_Up:
-        case Qt::Key_PageUp:
-        case Qt::Key_Left:
+        if (event->modifiers () == 0)
         {
-            mController->previousScene ();
-            break;
-        }
+            switch (event->key ())
+            {
+            case Qt::Key_Up:
+            case Qt::Key_PageUp:
+            case Qt::Key_Left:
+            {
+                mController->previousScene ();
+                break;
+            }
 
-        case Qt::Key_Down:
-        case Qt::Key_PageDown:
-        case Qt::Key_Right:
-        case Qt::Key_Space:
-        {
-            mController->nextScene ();
-            break;
-        }
+            case Qt::Key_Down:
+            case Qt::Key_PageDown:
+            case Qt::Key_Right:
+            case Qt::Key_Space:
+            {
+                mController->nextScene ();
+                break;
+            }
 
-        case Qt::Key_Home:
-        {
-            mController->firstScene ();
-            break;
-        }
-        case Qt::Key_End:
-        {
-            mController->lastScene ();
-            break;
+            case Qt::Key_Home:
+            {
+                mController->firstScene ();
+                break;
+            }
+            case Qt::Key_End:
+            {
+                mController->lastScene ();
+                break;
+            }
+            case Qt::Key_Insert:
+            {
+                mController->addScene ();
+                break;
+            }
+            }
         }
-        case Qt::Key_Insert:
+
+        switch (event->key ())
         {
-            mController->addScene ();
-            break;
-        }
         case Qt::Key_Control:
         case Qt::Key_Shift:
-        {
             setMultiselection(true);
-        }break;
+            break;
         }
 
-
         if (event->modifiers () & Qt::ControlModifier) // keep only ctrl/cmd keys
         {
             switch (event->key ())
diff --git a/src/board/UBDrawingController.cpp b/src/board/UBDrawingController.cpp
index b1843eb6e..f244a201d 100644
--- a/src/board/UBDrawingController.cpp
+++ b/src/board/UBDrawingController.cpp
@@ -156,11 +156,16 @@ void UBDrawingController::setStylusTool(int tool)
 }
 
 
-bool UBDrawingController::isDrawingTool()
+bool UBDrawingController::isDrawingTool(int tool)
 {
-    return (stylusTool() == UBStylusTool::Pen)
-            || (stylusTool() == UBStylusTool::Marker)
-            || (stylusTool() == UBStylusTool::Line);
+    if (tool < 0)
+    {
+        tool = stylusTool();
+    }
+
+    return (tool == UBStylusTool::Pen)
+            || (tool == UBStylusTool::Marker)
+            || (tool == UBStylusTool::Line);
 }
 
 
diff --git a/src/board/UBDrawingController.h b/src/board/UBDrawingController.h
index 61d4ad827..b44fe980b 100644
--- a/src/board/UBDrawingController.h
+++ b/src/board/UBDrawingController.h
@@ -52,7 +52,7 @@ class UBDrawingController : public QObject
         int stylusTool();
         int latestDrawingTool();
 
-        bool isDrawingTool();
+        bool isDrawingTool(int tool = -1);
 
         int currentToolWidthIndex();
         qreal currentToolWidth();
diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp
index aa6734dfe..7273d9249 100644
--- a/src/domain/UBGraphicsScene.cpp
+++ b/src/domain/UBGraphicsScene.cpp
@@ -500,6 +500,7 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres
     UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool();
 
     QPointF position = QPointF(scenePos);
+    mCurrentPoint = position;
 
     if (currentTool == UBStylusTool::Eraser)
     {
@@ -667,14 +668,9 @@ bool UBGraphicsScene::inputDeviceRelease(int tool)
     }
 
     UBStylusTool::Enum currentTool = (UBStylusTool::Enum)tool;
-
-    if (currentTool == UBStylusTool::Eraser)
-        hideEraser();
-
-
     UBDrawingController *dc = UBDrawingController::drawingController();
 
-    if (dc->isDrawingTool() || mDrawWithCompass)
+    if (dc->isDrawingTool(tool) || mDrawWithCompass)
     {
         if(mArcPolygonItem){
 
@@ -2398,12 +2394,21 @@ void UBGraphicsScene::resizedMagnifier(qreal newPercent)
 
 void UBGraphicsScene::stylusToolChanged(int tool, int previousTool)
 {
-    if (mInputDeviceIsPressed && tool != previousTool)
+    if (tool != previousTool)
     {
-        // tool was changed while input device is pressed
-        // simulate release and press to terminate pervious strokes
-        inputDeviceRelease(previousTool);
-        inputDevicePress(mPreviousPoint);
+        hideTool();
+
+        if (mInputDeviceIsPressed)
+        {
+            // tool was changed while input device is pressed
+            // simulate release and press to terminate previous strokes
+            inputDeviceRelease(previousTool);
+            inputDevicePress(mCurrentPoint);
+        }
+        else if (previousTool >= 0)
+        {
+            inputDeviceMove(mCurrentPoint);
+        }
     }
 }
 
diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h
index e824e555f..7bbb9d1a0 100644
--- a/src/domain/UBGraphicsScene.h
+++ b/src/domain/UBGraphicsScene.h
@@ -460,6 +460,7 @@ public slots:
         QPointF mPreviousPoint;
         qreal mPreviousWidth;
         qreal mDistanceFromLastStrokePoint;
+        QPointF mCurrentPoint;
 
         QList<UBGraphicsPolygonItem*> mPreviousPolygonItems;
 

From 7db64f65e3824c3b09ef1618425901404b133ddc Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Mon, 29 Nov 2021 19:56:42 +0100
Subject: [PATCH 6/8] fix: load ignoreCtrl setting during startup

---
 src/core/UBShortcutManager.cpp | 11 ++++++++++-
 src/core/UBShortcutManager.h   |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/core/UBShortcutManager.cpp b/src/core/UBShortcutManager.cpp
index 0275899cf..9e74e9c2b 100644
--- a/src/core/UBShortcutManager.cpp
+++ b/src/core/UBShortcutManager.cpp
@@ -41,7 +41,7 @@ static const char* tabletButtonProperty("tabletButton");
 
 UBShortcutManager* UBShortcutManager::sShortcutManager = nullptr;
 
-UBShortcutManager::UBShortcutManager()
+UBShortcutManager::UBShortcutManager() : mIgnoreCtrl(false)
 {
     actionsOfGroup(QObject::tr("Common"));
 }
@@ -289,6 +289,9 @@ void UBShortcutManager::addMainActions(UBMainWindow *mainWindow)
     actions << action;
 
     addActions(tr("Built-in (not editable)"), actions);
+
+    // load ignoreCtrl setting
+    ignoreCtrl(UBSettings::settings()->value("Shortcut/IgnoreCtrl").toBool());
 }
 
 bool UBShortcutManager::handleMouseEvent(QMouseEvent *event)
@@ -623,6 +626,12 @@ Qt::MouseButton UBShortcutManager::buttonIndex(QString button)
 
 void UBShortcutManager::ignoreCtrl(bool ignore)
 {
+    if (ignore == mIgnoreCtrl) {
+        return;
+    }
+
+    mIgnoreCtrl = ignore;
+
     for (auto& actionGroup : mActionGroups)
     {
         for (QAction* action : actionGroup.second)
diff --git a/src/core/UBShortcutManager.h b/src/core/UBShortcutManager.h
index 9e90f7346..e1e6a28bc 100644
--- a/src/core/UBShortcutManager.h
+++ b/src/core/UBShortcutManager.h
@@ -87,6 +87,7 @@ public slots:
     QList<QPair<QString,QList<QAction*>>> mActionGroups;
     QMap<Qt::MouseButton, QAction*> mMouseActions;
     QMap<Qt::MouseButton, QAction*> mTabletActions;
+    bool mIgnoreCtrl;
 
     static UBShortcutManager* sShortcutManager;
 };

From 89885f7e4aa32134c0c1c5109af5beb24d541154 Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Sun, 12 Dec 2021 11:04:56 +0100
Subject: [PATCH 7/8] feat: activate tool while a key is pressed

- add UBActionGroupHistory
- listen for key release events to return to previous tool
---
 src/core/UBApplication.cpp           |   9 +++
 src/core/UBPreferencesController.cpp |   2 +-
 src/core/UBShortcutManager.cpp       | 102 +++++++++++++++++++++++++++
 src/core/UBShortcutManager.h         |  27 ++++++-
 src/gui/UBStylusPalette.cpp          |   9 ++-
 5 files changed, 146 insertions(+), 3 deletions(-)

diff --git a/src/core/UBApplication.cpp b/src/core/UBApplication.cpp
index c33473485..c3cfd5b25 100644
--- a/src/core/UBApplication.cpp
+++ b/src/core/UBApplication.cpp
@@ -688,6 +688,15 @@ bool UBApplication::eventFilter(QObject *obj, QEvent *event)
         }
     }
 
+    else if (event->type() == QEvent::KeyRelease)
+    {
+        // intercept key release events for shortcut handler
+        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+
+        return UBShortcutManager::shortcutManager()->handleKeyReleaseEvent(keyEvent)
+                    || result;
+    }
+
     return result;
 }
 
diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp
index 9a9e83de2..b9d93d7f7 100644
--- a/src/core/UBPreferencesController.cpp
+++ b/src/core/UBPreferencesController.cpp
@@ -123,7 +123,7 @@ bool UBPreferencesController::handleKeyEvent(QKeyEvent *event)
 
     int keys = mods;
 
-    if (key < Qt::Key_Shift || key > Qt::Key_Alt)
+    if (key < Qt::Key_Shift || key > Qt::Key_ScrollLock)
     {
         keys += key;
     }
diff --git a/src/core/UBShortcutManager.cpp b/src/core/UBShortcutManager.cpp
index 9e74e9c2b..e4afaa55c 100644
--- a/src/core/UBShortcutManager.cpp
+++ b/src/core/UBShortcutManager.cpp
@@ -294,6 +294,20 @@ void UBShortcutManager::addMainActions(UBMainWindow *mainWindow)
     ignoreCtrl(UBSettings::settings()->value("Shortcut/IgnoreCtrl").toBool());
 }
 
+void UBShortcutManager::addActionGroup(QActionGroup *actionGroup)
+{
+    mActionGroupHistoryMap[actionGroup] = new UBActionGroupHistory(actionGroup);
+}
+
+void UBShortcutManager::removeActionGroup(QActionGroup *actionGroup)
+{
+    if (mActionGroupHistoryMap.contains(actionGroup))
+    {
+        delete mActionGroupHistoryMap[actionGroup];
+        mActionGroupHistoryMap.remove(actionGroup);
+    }
+}
+
 bool UBShortcutManager::handleMouseEvent(QMouseEvent *event)
 {
     if (mMouseActions.contains(event->button()))
@@ -328,6 +342,18 @@ bool UBShortcutManager::handleTabletEvent(QTabletEvent *event)
     return false;
 }
 
+bool UBShortcutManager::handleKeyReleaseEvent(QKeyEvent *event)
+{
+    for (UBActionGroupHistory* actionGroupHistory : mActionGroupHistoryMap.values())
+    {
+        if (actionGroupHistory->keyReleased(event)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 int UBShortcutManager::rowCount(const QModelIndex &parent) const
 {
     Q_UNUSED(parent);
@@ -479,6 +505,16 @@ bool UBShortcutManager::setData(const QModelIndex &index, const QVariant &value,
 
     case 3:
         action->setProperty(mouseButtonProperty, value);
+
+        for (Qt::MouseButton key : mMouseActions.keys())
+        {
+            if (mMouseActions[key] == action)
+            {
+                mMouseActions.remove(key);
+                break;
+            }
+        }
+
         mMouseActions[static_cast<Qt::MouseButton>(value.toInt())] = action;
         updateSettings(action);
         emit dataChanged(index, index);
@@ -486,6 +522,16 @@ bool UBShortcutManager::setData(const QModelIndex &index, const QVariant &value,
 
     case 4:
         action->setProperty(tabletButtonProperty, value);
+
+        for (Qt::MouseButton key : mTabletActions.keys())
+        {
+            if (mTabletActions[key] == action)
+            {
+                mTabletActions.remove(key);
+                break;
+            }
+        }
+
         mTabletActions[static_cast<Qt::MouseButton>(value.toInt())] = action;
         updateSettings(action);
         emit dataChanged(index, index);
@@ -749,3 +795,59 @@ void UBShortcutManager::updateSettings(const QAction *action) const
         UBSettings::settings()->setValue(key, list);
     }
 }
+
+// ---------- UBActionGroupHistory ----------
+
+UBActionGroupHistory::UBActionGroupHistory(QActionGroup *parent)
+    : QObject(parent)
+    , mActionGroup(parent)
+    , mCurrentAction(parent->checkedAction())
+    , mPreviousAction(nullptr)
+    , mRevertingAction(nullptr)
+{
+    connect(parent, &QActionGroup::triggered, this, &UBActionGroupHistory::triggered);
+}
+
+void UBActionGroupHistory::triggered(QAction *action)
+{
+    if (mCurrentAction != action)
+    {
+        mPreviousAction = mCurrentAction;
+        mCurrentAction = action;
+    }
+}
+
+bool UBActionGroupHistory::keyReleased(QKeyEvent *event)
+{
+    int key = event->key() & ~Qt::KeyboardModifierMask;
+
+    for (QAction* action : mActionGroup->actions())
+    {
+        QKeySequence keySequence = action->shortcut();
+
+        if (keySequence.count() > 0)
+        {
+            int actionKey = action->shortcut()[0] & ~Qt::KeyboardModifierMask;
+
+            if (key == actionKey)
+            {
+                if (event->isAutoRepeat())
+                {
+                    if (!mRevertingAction)
+                    {
+                        mRevertingAction = mPreviousAction;;
+                    }
+                }
+                else if (mRevertingAction)
+                {
+                    mRevertingAction->trigger();
+                    mRevertingAction = nullptr;
+                }
+
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
diff --git a/src/core/UBShortcutManager.h b/src/core/UBShortcutManager.h
index e1e6a28bc..c6878fea2 100644
--- a/src/core/UBShortcutManager.h
+++ b/src/core/UBShortcutManager.h
@@ -36,11 +36,13 @@
 #include <QTabletEvent>
 
 class QAction;
+class QActionGroup;
 class UBMainWindow;
+class UBActionGroupHistory;
 
 class UBShortcutManager : public QAbstractTableModel
 {
-    Q_OBJECT;
+    Q_OBJECT
 
 private:
     UBShortcutManager();
@@ -57,8 +59,12 @@ class UBShortcutManager : public QAbstractTableModel
     void addActions(const QString& group, const QList<QAction*> actions, QWidget* widget = nullptr);
     void addMainActions(UBMainWindow* mainWindow);
 
+    void addActionGroup(QActionGroup* actionGroup);
+    void removeActionGroup(QActionGroup* actionGroup);
+
     bool handleMouseEvent(QMouseEvent* event);
     bool handleTabletEvent(QTabletEvent* event);
+    bool handleKeyReleaseEvent(QKeyEvent* event);
 
     // QAbstractTableModel overrides
     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
@@ -87,9 +93,28 @@ public slots:
     QList<QPair<QString,QList<QAction*>>> mActionGroups;
     QMap<Qt::MouseButton, QAction*> mMouseActions;
     QMap<Qt::MouseButton, QAction*> mTabletActions;
+    QMap<QActionGroup*, UBActionGroupHistory*> mActionGroupHistoryMap;
     bool mIgnoreCtrl;
 
     static UBShortcutManager* sShortcutManager;
 };
 
+class UBActionGroupHistory : public QObject
+{
+    Q_OBJECT
+
+public:
+    UBActionGroupHistory(QActionGroup* parent);
+
+public slots:
+    void triggered(QAction* action);
+    bool keyReleased(QKeyEvent* event);
+
+private:
+    QActionGroup* mActionGroup;
+    QAction* mCurrentAction;
+    QAction* mPreviousAction;
+    QAction* mRevertingAction;
+};
+
 #endif // UBSHORTCUTMANAGER_H
diff --git a/src/gui/UBStylusPalette.cpp b/src/gui/UBStylusPalette.cpp
index cac047991..611fc59e3 100644
--- a/src/gui/UBStylusPalette.cpp
+++ b/src/gui/UBStylusPalette.cpp
@@ -36,6 +36,8 @@
 #include "core/UBApplication.h"
 #include "core/UBSettings.h"
 #include "core/UBApplicationController.h"
+#include "core/UBShortcutManager.h"
+
 
 #include "board/UBDrawingController.h"
 
@@ -87,6 +89,8 @@ UBStylusPalette::UBStylusPalette(QWidget *parent, Qt::Orientation orient)
         connect(mActionGroup, SIGNAL(triggered(QAction*)), this, SIGNAL(buttonGroupClicked(QAction*)));
     }
 
+    UBShortcutManager::shortcutManager()->addActionGroup(mActionGroup);
+
     adjustSizeAndPosition();
 
     initPosition();
@@ -126,7 +130,10 @@ void UBStylusPalette::initPosition()
 
 UBStylusPalette::~UBStylusPalette()
 {
-
+    if (mActionGroup)
+    {
+        UBShortcutManager::shortcutManager()->removeActionGroup(mActionGroup);
+    }
 }
 
 void UBStylusPalette::stylusToolDoubleClicked()

From 1f090911a9c69c1c8ec20a2f9ada6c008e868430 Mon Sep 17 00:00:00 2001
From: letsfindaway <me@letsfindaway.de>
Date: Fri, 18 Mar 2022 18:48:39 +0100
Subject: [PATCH 8/8] fix: set icon on action instead of button

- assigning a shortcut in the UBShortcutManager changes actions
- changing an action re-assignes the action's icon to the button
- a previously set buutton icon is overwritten
- setting the icon at the action avoids this
---
 src/gui/UBToolbarButtonGroup.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/gui/UBToolbarButtonGroup.cpp b/src/gui/UBToolbarButtonGroup.cpp
index 30f697e5e..fe17a5f31 100644
--- a/src/gui/UBToolbarButtonGroup.cpp
+++ b/src/gui/UBToolbarButtonGroup.cpp
@@ -116,7 +116,11 @@ void UBToolbarButtonGroup::setIcon(const QIcon &icon, int index)
         QToolButton *button = qobject_cast<QToolButton*>(widget);
         if (button)
         {
-            button->setIcon(icon);
+            // change icon at action, so that updates of action do not overwrite the icon
+            for (QAction* action : button->actions())
+            {
+                action->setIcon(icon);
+            }
         }
     }
 }
openSUSE Build Service is sponsored by