commit fbe36e330ddc838352ac54fea6e4feb3c997614f Author: tigro Date: Mon Sep 11 17:05:29 2023 +0300 import openboard-1.7.0-1.20221129git9de37af.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..928ef78 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/openboard-9de37af2df1a7c0d88f71c94ab2db1815d082862.tar.gz diff --git a/.openboard.metadata b/.openboard.metadata new file mode 100644 index 0000000..63f4cf2 --- /dev/null +++ b/.openboard.metadata @@ -0,0 +1 @@ +2e7fff009140daa634e44b895f4ceb5c8353eddb SOURCES/openboard-9de37af2df1a7c0d88f71c94ab2db1815d082862.tar.gz diff --git a/SOURCES/0551-common-background-drawing.patch b/SOURCES/0551-common-background-drawing.patch new file mode 100644 index 0000000..d74cb51 --- /dev/null +++ b/SOURCES/0551-common-background-drawing.patch @@ -0,0 +1,589 @@ +From 31456152d403e57cdd56f6b1dd54d94d930a3029 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Wed, 5 Jan 2022 11:15:54 +0100 +Subject: [PATCH 1/3] refactor: drawBackground mostly in scene + +- move all drawing of background grid to UBGraphicsScene +- only add document border in UBBoardView +- avoid some compiler warnings +--- + src/board/UBBoardView.cpp | 101 ++++----------------------------- + src/domain/UBGraphicsScene.cpp | 48 +++++++++++++--- + 2 files changed, 51 insertions(+), 98 deletions(-) + +diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp +index 817d8c4e7..c968f17d7 100644 +--- a/src/board/UBBoardView.cpp ++++ b/src/board/UBBoardView.cpp +@@ -29,6 +29,7 @@ + + #include "UBBoardView.h" + ++#include + #include + #include + #include +@@ -92,11 +93,11 @@ UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent, bool + , mIsCreatingTextZone (false) + , mIsCreatingSceneGrabZone (false) + , mOkOnWidget(false) ++ , _movingItem(nullptr) + , suspendedMousePressEvent(NULL) + , mLongPressInterval(1000) + , mIsDragInProgress(false) + , mMultipleSelectionIsEnabled(false) +- , _movingItem(nullptr) + , bIsControl(isControl) + , bIsDesktop(isDesktop) + { +@@ -117,11 +118,11 @@ UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent, bool + UBBoardView::UBBoardView (UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent, bool isControl, bool isDesktop) + : QGraphicsView (pParent) + , mController (pController) ++ , _movingItem(nullptr) + , suspendedMousePressEvent(NULL) + , mLongPressInterval(1000) + , mIsDragInProgress(false) + , mMultipleSelectionIsEnabled(false) +- , _movingItem(nullptr) + , bIsControl(isControl) + , bIsDesktop(isDesktop) + { +@@ -685,6 +686,7 @@ bool UBBoardView::itemShouldBeMoved(QGraphicsItem *item) + return false; + if(currentTool == UBStylusTool::Play) + return false; ++ Q_FALLTHROUGH(); + + case UBGraphicsSvgItem::Type: + case UBGraphicsPixmapItem::Type: +@@ -692,10 +694,13 @@ bool UBBoardView::itemShouldBeMoved(QGraphicsItem *item) + return true; + if (item->isSelected()) + return false; ++ Q_FALLTHROUGH(); ++ + case UBGraphicsMediaItem::Type: + case UBGraphicsVideoItem::Type: + case UBGraphicsAudioItem::Type: + return true; ++ + case UBGraphicsStrokesGroup::Type: + case UBGraphicsTextItem::Type: + if (currentTool == UBStylusTool::Play) +@@ -1714,98 +1719,14 @@ void UBBoardView::paintEvent(QPaintEvent *event) + + void UBBoardView::drawBackground (QPainter *painter, const QRectF &rect) + { ++ // draw the background of the QGraphicsScene ++ QGraphicsView::drawBackground(painter, rect); ++ + if (testAttribute (Qt::WA_TranslucentBackground)) + { +- QGraphicsView::drawBackground (painter, rect); + return; + } + +- bool darkBackground = scene () && scene ()->isDarkBackground (); +- +- if (darkBackground) +- { +- painter->fillRect (rect, QBrush (QColor (Qt::black))); +- } +- else +- { +- painter->fillRect (rect, QBrush (QColor (Qt::white))); +- } +- +- if (transform ().m11 () > 0.5) +- { +- QColor bgCrossColor; +- +- if (darkBackground) +- bgCrossColor = QColor(UBSettings::settings()->boardCrossColorDarkBackground->get().toString()); +- else +- bgCrossColor = QColor(UBSettings::settings()->boardCrossColorLightBackground->get().toString()); +- +- if (transform ().m11 () < 0.7) +- { +- int alpha = 255 * transform ().m11 () / 2; +- bgCrossColor.setAlpha (alpha); // fade the crossing on small zooms +- } +- +- qreal gridSize = scene()->backgroundGridSize(); +- bool intermediateLines = scene()->intermediateLines(); +- +- painter->setPen (bgCrossColor); +- +- if (scene () && scene ()->pageBackground() == UBPageBackground::crossed) +- { +- qreal firstY = ((int) (rect.y () / gridSize)) * gridSize; +- +- for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += gridSize) +- { +- painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); +- } +- +- qreal firstX = ((int) (rect.x () / gridSize)) * gridSize; +- +- for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += gridSize) +- { +- painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); +- } +- +- if (intermediateLines) { +- QColor intermediateColor = bgCrossColor; +- intermediateColor.setAlphaF(0.5 * bgCrossColor.alphaF()); +- painter->setPen(intermediateColor); +- +- for (qreal yPos = firstY - gridSize/2; yPos < rect.y () + rect.height (); yPos += gridSize) +- { +- painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); +- } +- +- for (qreal xPos = firstX - gridSize/2; xPos < rect.x () + rect.width (); xPos += gridSize) +- { +- painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); +- } +- } +- } +- +- if (scene() && scene()->pageBackground() == UBPageBackground::ruled) +- { +- qreal firstY = ((int) (rect.y () / gridSize)) * gridSize; +- +- for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += gridSize) +- { +- painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); +- } +- +- if (intermediateLines) { +- QColor intermediateColor = bgCrossColor; +- intermediateColor.setAlphaF(0.5 * bgCrossColor.alphaF()); +- painter->setPen(intermediateColor); +- +- for (qreal yPos = firstY - gridSize/2; yPos < rect.y () + rect.height (); yPos += gridSize) +- { +- painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); +- } +- } +- } +- } +- + if (!mFilterZIndex && scene ()) + { + QSize pageNominalSize = scene ()->nominalSize (); +@@ -1821,7 +1742,7 @@ void UBBoardView::drawBackground (QPainter *painter, const QRectF &rect) + + QColor docSizeColor; + +- if (darkBackground) ++ if (scene ()->isDarkBackground ()) + docSizeColor = UBSettings::documentSizeMarkColorDarkBackground; + else + docSizeColor = UBSettings::documentSizeMarkColorLightBackground; +diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp +index aa6734dfe..48850d7e8 100644 +--- a/src/domain/UBGraphicsScene.cpp ++++ b/src/domain/UBGraphicsScene.cpp +@@ -2690,15 +2690,16 @@ void UBGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) + QGraphicsScene::drawBackground (painter, rect); + return; + } ++ + bool darkBackground = isDarkBackground (); + + if (darkBackground) + { +- painter->fillRect (rect, QBrush (QColor (Qt::black))); ++ painter->fillRect (rect, QBrush (QColor (Qt::black))); + } + else + { +- painter->fillRect (rect, QBrush (QColor (Qt::white))); ++ painter->fillRect (rect, QBrush (QColor (Qt::white))); + } + + if (mZoomFactor > 0.5) +@@ -2709,39 +2710,70 @@ void UBGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) + bgCrossColor = QColor(UBSettings::settings()->boardCrossColorDarkBackground->get().toString()); + else + bgCrossColor = QColor(UBSettings::settings()->boardCrossColorLightBackground->get().toString()); ++ + if (mZoomFactor < 0.7) + { + int alpha = 255 * mZoomFactor / 2; + bgCrossColor.setAlpha (alpha); // fade the crossing on small zooms + } + ++ qreal gridSize = backgroundGridSize(); + painter->setPen (bgCrossColor); + + if (mPageBackground == UBPageBackground::crossed) + { +- qreal firstY = ((int) (rect.y () / backgroundGridSize())) * backgroundGridSize(); ++ qreal firstY = ((int) (rect.y () / gridSize)) * gridSize; + +- for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += backgroundGridSize()) ++ for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += gridSize) + { + painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); + } + +- qreal firstX = ((int) (rect.x () / backgroundGridSize())) * backgroundGridSize(); ++ qreal firstX = ((int) (rect.x () / gridSize)) * gridSize; + +- for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += backgroundGridSize()) ++ for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += gridSize) + { + painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); + } ++ ++ if (mIntermediateLines) ++ { ++ QColor intermediateColor = bgCrossColor; ++ intermediateColor.setAlphaF(0.5 * bgCrossColor.alphaF()); ++ painter->setPen(intermediateColor); ++ ++ for (qreal yPos = firstY - gridSize/2; yPos < rect.y () + rect.height (); yPos += gridSize) ++ { ++ painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); ++ } ++ ++ for (qreal xPos = firstX - gridSize/2; xPos < rect.x () + rect.width (); xPos += gridSize) ++ { ++ painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); ++ } ++ } + } + + else if (mPageBackground == UBPageBackground::ruled) + { +- qreal firstY = ((int) (rect.y () / backgroundGridSize())) * backgroundGridSize(); ++ qreal firstY = ((int) (rect.y () / gridSize)) * gridSize; + +- for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += backgroundGridSize()) ++ for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += gridSize) + { + painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); + } ++ ++ if (mIntermediateLines) ++ { ++ QColor intermediateColor = bgCrossColor; ++ intermediateColor.setAlphaF(0.5 * bgCrossColor.alphaF()); ++ painter->setPen(intermediateColor); ++ ++ for (qreal yPos = firstY - gridSize/2; yPos < rect.y () + rect.height (); yPos += gridSize) ++ { ++ painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); ++ } ++ } + } + } + } + +From 95021acc1dbb5ab7c65fb04b7ff543fd064f41a4 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Tue, 29 Nov 2022 08:49:36 +0100 +Subject: [PATCH 2/3] fix: set document modified when changing page size + +- make sure page size change is persisted +- refactor code to refresh background in common function +--- + src/domain/UBGraphicsScene.cpp | 29 +++++++++++++++-------------- + src/domain/UBGraphicsScene.h | 1 + + 2 files changed, 16 insertions(+), 14 deletions(-) + +diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp +index 48850d7e8..25760d0bd 100644 +--- a/src/domain/UBGraphicsScene.cpp ++++ b/src/domain/UBGraphicsScene.cpp +@@ -1136,22 +1136,17 @@ void UBGraphicsScene::setBackground(bool pIsDark, UBPageBackground pBackground) + recolorAllItems(); + + needRepaint = true; +- setModified(true); + } + + if (mPageBackground != pBackground) + { + mPageBackground = pBackground; + needRepaint = true; +- setModified(true); + } + + if (needRepaint) + { +- foreach(QGraphicsView* view, views()) +- { +- view->resetCachedContent(); +- } ++ updateBackground(); + } + } + +@@ -1165,20 +1160,14 @@ void UBGraphicsScene::setBackgroundGridSize(int pSize) + { + if (pSize > 0) { + mBackgroundGridSize = pSize; +- setModified(true); +- +- foreach(QGraphicsView* view, views()) +- view->resetCachedContent(); ++ updateBackground(); + } + } + + void UBGraphicsScene::setIntermediateLines(bool checked) + { + mIntermediateLines = checked; +- setModified(true); +- +- foreach(QGraphicsView* view, views()) +- view->resetCachedContent(); ++ updateBackground(); + } + + void UBGraphicsScene::setDrawingMode(bool bModeDesktop) +@@ -2570,6 +2559,7 @@ void UBGraphicsScene::setNominalSize(const QSize& pSize) + if (nominalSize() != pSize) + { + mNominalSize = pSize; ++ updateBackground(); + + if(mDocument) + mDocument->setDefaultDocumentSize(pSize); +@@ -2918,6 +2908,17 @@ void UBGraphicsScene::setDocumentUpdated() + } + } + ++void UBGraphicsScene::updateBackground() ++{ ++ setModified(true); ++ ++ foreach(QGraphicsView* view, views()) ++ { ++ view->resetCachedContent(); ++ } ++ ++} ++ + void UBGraphicsScene::createEraiser() + { + if (UBSettings::settings()->showEraserPreviewCircle->get().toBool()) { +diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h +index e824e555f..80bad3d89 100644 +--- a/src/domain/UBGraphicsScene.h ++++ b/src/domain/UBGraphicsScene.h +@@ -427,6 +427,7 @@ public slots: + + private: + void setDocumentUpdated(); ++ void updateBackground(); + void createEraiser(); + void createPointer(); + void createMarkerCircle(); + +From 1eafb49db2e03b0b878d7d90e621136a6bce1374 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Tue, 29 Nov 2022 09:12:05 +0100 +Subject: [PATCH 3/3] refactor: avoid clang warnings + +- unneeded temporary container allocations +- reference to temporary +- possible memory leak +- unused variable +- use QHash for pointers instead of QMap +- possible nullptr reference +- not normalized signal/slot signatures +- detached container +- call to virtual function during construction +--- + src/domain/UBGraphicsScene.cpp | 65 ++++++++++++++++++---------------- + 1 file changed, 34 insertions(+), 31 deletions(-) + +diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp +index 25760d0bd..f3fed4b6f 100644 +--- a/src/domain/UBGraphicsScene.cpp ++++ b/src/domain/UBGraphicsScene.cpp +@@ -164,7 +164,7 @@ qreal UBZLayerController::changeZLevelTo(QGraphicsItem *item, moveDestination de + } + + //If only one item itself - do nothing, return it's z-value +- if (sortedItems.count() == 1 && sortedItems.values().first() == item) { ++ if (sortedItems.count() == 1 && sortedItems.first() == item) { + qDebug() << "only one item exists in layer. Have nothing to change"; + return item->data(UBGraphicsItemData::ItemOwnZValue).toReal(); + } +@@ -385,8 +385,8 @@ UBGraphicsScene::~UBGraphicsScene() + void UBGraphicsScene::selectionChangedProcessing() + { + if (selectedItems().count()){ +- UBApplication::showMessage("ZValue is " + QString::number(selectedItems().first()->zValue(), 'f') + "own z value is " +- + QString::number(selectedItems().first()->data(UBGraphicsItemData::ItemOwnZValue).toReal(), 'f')); ++ UBApplication::showMessage("ZValue is " + QString::number(selectedItems().constFirst()->zValue(), 'f') + "own z value is " ++ + QString::number(selectedItems().constFirst()->data(UBGraphicsItemData::ItemOwnZValue).toReal(), 'f')); + + } + } +@@ -749,10 +749,11 @@ bool UBGraphicsScene::inputDeviceRelease(int tool) + { + + if (mUndoRedoStackEnabled) { //should be deleted after scene own undo stack implemented +- UBGraphicsItemUndoCommand* udcmd = new UBGraphicsItemUndoCommand(this, mRemovedItems, mAddedItems); //deleted by the undoStack +- +- if(UBApplication::undoStack) ++ if (UBApplication::undoStack) ++ { ++ UBGraphicsItemUndoCommand* udcmd = new UBGraphicsItemUndoCommand(this, mRemovedItems, mAddedItems); //deleted by the undoStack + UBApplication::undoStack->push(udcmd); ++ } + } + + mRemovedItems.clear(); +@@ -1177,7 +1178,7 @@ void UBGraphicsScene::setDrawingMode(bool bModeDesktop) + + void UBGraphicsScene::recolorAllItems() + { +- QMap previousUpdateModes; ++ QHash previousUpdateModes; + foreach(QGraphicsView* view, views()) + { + previousUpdateModes.insert(view, view->viewportUpdateMode()); +@@ -1383,7 +1384,7 @@ UBGraphicsScene* UBGraphicsScene::sceneDeepCopy() const + copy->setNominalSize(this->mNominalSize); + + QListIterator itItems(this->mFastAccessItems); +- QMap groupClone; ++ QHash groupClone; + + while (itItems.hasNext()) + { +@@ -1507,8 +1508,8 @@ void UBGraphicsScene::clearContent(clearCase pCase) + + groupsMap.insert(itemGroup, UBGraphicsItem::getOwnUuid(item)); + if (itemGroup->childItems().count() == 1) { +- groupsMap.insert(itemGroup, UBGraphicsItem::getOwnUuid(itemGroup->childItems().first())); +- QGraphicsItem *lastItem = itemGroup->childItems().first(); ++ groupsMap.insert(itemGroup, UBGraphicsItem::getOwnUuid(itemGroup->childItems().constFirst())); ++ QGraphicsItem *lastItem = itemGroup->childItems().constFirst(); + bool isSelected = itemGroup->isSelected(); + itemGroup->destroy(false); + lastItem->setSelected(isSelected); +@@ -1626,25 +1627,27 @@ UBGraphicsMediaItem* UBGraphicsScene::addMedia(const QUrl& pMediaFileUrl, bool s + + UBGraphicsMediaItem * mediaItem = UBGraphicsMediaItem::createMediaItem(pMediaFileUrl); + +- if(mediaItem) ++ if (mediaItem) ++ { + connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), mediaItem, SLOT(activeSceneChanged())); + +- mediaItem->setPos(pPos); ++ mediaItem->setPos(pPos); + +- mediaItem->setFlag(QGraphicsItem::ItemIsMovable, true); +- mediaItem->setFlag(QGraphicsItem::ItemIsSelectable, true); ++ mediaItem->setFlag(QGraphicsItem::ItemIsMovable, true); ++ mediaItem->setFlag(QGraphicsItem::ItemIsSelectable, true); + +- addItem(mediaItem); ++ addItem(mediaItem); + +- mediaItem->show(); ++ mediaItem->show(); + +- if (mUndoRedoStackEnabled) { //should be deleted after scene own undo stack implemented +- UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(this, 0, mediaItem); +- UBApplication::undoStack->push(uc); +- } ++ if (mUndoRedoStackEnabled) { //should be deleted after scene own undo stack implemented ++ UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(this, 0, mediaItem); ++ UBApplication::undoStack->push(uc); ++ } + +- if (shouldPlayAsap) +- mediaItem->play(); ++ if (shouldPlayAsap) ++ mediaItem->play(); ++ } + + setDocumentUpdated(); + +@@ -1904,7 +1907,7 @@ UBGraphicsTextItem* UBGraphicsScene::addTextWithFont(const QString& pString, con + UBApplication::undoStack->push(uc); + } + +- connect(textItem, SIGNAL(textUndoCommandAdded(UBGraphicsTextItem *)), this, SLOT(textUndoCommandAdded(UBGraphicsTextItem *))); ++ connect(textItem, SIGNAL(textUndoCommandAdded(UBGraphicsTextItem*)), this, SLOT(textUndoCommandAdded(UBGraphicsTextItem*))); + + textItem->setSelected(true); + textItem->setFocus(); +@@ -1931,7 +1934,7 @@ UBGraphicsTextItem *UBGraphicsScene::addTextHtml(const QString &pString, const Q + UBApplication::undoStack->push(uc); + } + +- connect(textItem, SIGNAL(textUndoCommandAdded(UBGraphicsTextItem *)), this, SLOT(textUndoCommandAdded(UBGraphicsTextItem *))); ++ connect(textItem, SIGNAL(textUndoCommandAdded(UBGraphicsTextItem*)), this, SLOT(textUndoCommandAdded(UBGraphicsTextItem*))); + + textItem->setFocus(); + +@@ -2140,10 +2143,10 @@ QRectF UBGraphicsScene::normalizedSceneRect(qreal ratio) + QGraphicsItem *UBGraphicsScene::itemForUuid(QUuid uuid) + { + QGraphicsItem *result = 0; +- QString ui = uuid.toString(); + + //simple search before implementing container for fast access +- foreach (QGraphicsItem *item, items()) { ++ foreach (QGraphicsItem *item, items()) ++ { + if (UBGraphicsScene::getPersonalUuid(item) == uuid && !uuid.isNull()) { + result = item; + } +@@ -2514,7 +2517,7 @@ QList UBGraphicsScene::relativeDependencies() const + UBGraphicsGroupContainerItem* groupItem = dynamic_cast(item); + if(groupItem) + { +- for (auto child : groupItem->childItems()) ++ foreach (QGraphicsItem* child, groupItem->childItems()) + { + relativePaths << relativeDependenciesOfItem(child); + } +@@ -2932,7 +2935,7 @@ void UBGraphicsScene::createEraiser() + mEraser->setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::Eraiser)); //Necessary to set if we want z value to be assigned correctly + + mTools << mEraser; +- addItem(mEraser); ++ UBGraphicsScene::addItem(mEraser); + } + } + +@@ -2949,7 +2952,7 @@ void UBGraphicsScene::createPointer() + mPointer->setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::Pointer)); //Necessary to set if we want z value to be assigned correctly + + mTools << mPointer; +- addItem(mPointer); ++ UBGraphicsScene::addItem(mPointer); + } + + void UBGraphicsScene::createMarkerCircle() +@@ -2967,7 +2970,7 @@ void UBGraphicsScene::createMarkerCircle() + mMarkerCircle->setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::Eraiser)); + + mTools << mMarkerCircle; +- addItem(mMarkerCircle); ++ UBGraphicsScene::addItem(mMarkerCircle); + } + } + +@@ -2986,7 +2989,7 @@ void UBGraphicsScene::createPenCircle() + mPenCircle->setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::Eraiser)); + + mTools << mPenCircle; +- addItem(mPenCircle); ++ UBGraphicsScene::addItem(mPenCircle); + } + } + diff --git a/SOURCES/0569-scale-mirror-pixmap.patch b/SOURCES/0569-scale-mirror-pixmap.patch new file mode 100644 index 0000000..7c29f90 --- /dev/null +++ b/SOURCES/0569-scale-mirror-pixmap.patch @@ -0,0 +1,41 @@ +From d835e5ef719356c3840c11aade9e671a26d5c6ce Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Sun, 9 Jan 2022 10:40:12 +0100 +Subject: [PATCH] fix: scaling of mirror pixmap + +- when scaling the pixmap take the devicePixelRatio into account +- do not scale the already scaled pixmap when drawing in UBScreenMirror +- use device independent coordinates when positioning the pixmap +--- + src/gui/UBScreenMirror.cpp | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/gui/UBScreenMirror.cpp b/src/gui/UBScreenMirror.cpp +index db5b65116..ff9810862 100644 +--- a/src/gui/UBScreenMirror.cpp ++++ b/src/gui/UBScreenMirror.cpp +@@ -66,10 +66,12 @@ void UBScreenMirror::paintEvent(QPaintEvent *event) + + if (!mLastPixmap.isNull()) + { +- int x = (width() - mLastPixmap.width()) / 2; +- int y = (height() - mLastPixmap.height()) / 2; ++ // compute size and offset in device independent coordinates ++ QSizeF pixmapSize = mLastPixmap.size() / mLastPixmap.devicePixelRatioF(); ++ int x = (width() - pixmapSize.width()) / 2; ++ int y = (height() - pixmapSize.height()) / 2; + +- painter.drawPixmap(x, y, width(), height(), mLastPixmap); ++ painter.drawPixmap(x, y, mLastPixmap); + } + } + +@@ -95,7 +97,7 @@ void UBScreenMirror::grabPixmap() + } + + if (!mLastPixmap.isNull()) +- mLastPixmap = mLastPixmap.scaled(width(), height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); ++ mLastPixmap = mLastPixmap.scaled(size() * mLastPixmap.devicePixelRatioF(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + + diff --git a/SOURCES/0677-pdf-export-page-size.patch b/SOURCES/0677-pdf-export-page-size.patch new file mode 100644 index 0000000..9369cfb --- /dev/null +++ b/SOURCES/0677-pdf-export-page-size.patch @@ -0,0 +1,274 @@ +From 2f6394ce1f085285c5c0a44857bb6ea2c79b8769 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Wed, 28 Sep 2022 16:12:50 +0200 +Subject: [PATCH] fix: size of exported PDF page + +- add functions to retrieve original PDF page size in Points +- make output pages the same size +- align page sizes between overlay and base PDF +- use QSizeF where necessary to improve accuracy +- compute sceneBoundingRect only once +- catch exception by const reference (best practice) +--- + src/adaptors/UBExportFullPDF.cpp | 50 +++++++++++++++++--------------- + src/domain/UBGraphicsScene.cpp | 19 ++++++++++++ + src/domain/UBGraphicsScene.h | 1 + + src/pdf/GraphicsPDFItem.h | 1 + + src/pdf/PDFRenderer.h | 2 ++ + src/pdf/XPDFRenderer.cpp | 32 +++++++++++--------- + src/pdf/XPDFRenderer.h | 1 + + 7 files changed, 68 insertions(+), 38 deletions(-) + +diff --git a/src/adaptors/UBExportFullPDF.cpp b/src/adaptors/UBExportFullPDF.cpp +index 5aaa93b45..4b11517ae 100644 +--- a/src/adaptors/UBExportFullPDF.cpp ++++ b/src/adaptors/UBExportFullPDF.cpp +@@ -122,7 +122,7 @@ void UBExportFullPDF::saveOverlayPdf(UBDocumentProxy* pDocumentProxy, const QStr + + // pageSize is the output PDF page size; it is set to equal the scene's boundary size; if the contents + // of the scene overflow from the boundaries, they will be scaled down. +- QSize pageSize = scene->sceneSize(); ++ QSizeF pageSize = scene->sceneSizeF() * mScaleFactor; // points + + UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast(scene->backgroundObject()); + +@@ -130,13 +130,14 @@ void UBExportFullPDF::saveOverlayPdf(UBDocumentProxy* pDocumentProxy, const QStr + { + mHasPDFBackgrounds = true; + sceneHasPDFBackground = true; ++ pageSize = pdfItem->pageSize(); // original PDF document page size + } + else + { + sceneHasPDFBackground = false; + } + +- QPageSize size(QSizeF(pageSize.width()*mScaleFactor, pageSize.height()*mScaleFactor), QPageSize::Point); ++ QPageSize size(pageSize, QPageSize::Point); + pdfPrinter.setPageSize(size); + + if (!pdfPainter) pdfPainter = new QPainter(&pdfPrinter); +@@ -222,47 +223,46 @@ bool UBExportFullPDF::persistsDocument(UBDocumentProxy* pDocumentProxy, const QS + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, pageIndex); + UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast(scene->backgroundObject()); + +- QSize pageSize = scene->nominalSize(); +- + if (pdfItem) + { ++ QRectF pdfSceneRect = pdfItem->sceneBoundingRect(); + QString pdfName = UBPersistenceManager::objectDirectory + "/" + pdfItem->fileUuid().toString() + ".pdf"; + QString backgroundPath = pDocumentProxy->persistencePath() + "/" + pdfName; + QRectF annotationsRect = scene->annotationsBoundingRect(); + +- // Original datas +- double xAnnotation = qRound(annotationsRect.x()); +- double yAnnotation = qRound(annotationsRect.y()); +- double xPdf = qRound(pdfItem->sceneBoundingRect().x()); +- double yPdf = qRound(pdfItem->sceneBoundingRect().y()); +- double hPdf = qRound(pdfItem->sceneBoundingRect().height()); ++ // Original data ++ double xAnnotation = annotationsRect.x(); ++ double yAnnotation = annotationsRect.y(); ++ double xPdf = pdfSceneRect.x(); ++ double yPdf = pdfSceneRect.y(); ++ double hPdf = pdfSceneRect.height(); + +- // Exportation-transformed datas +- double hScaleFactor = pageSize.width()/annotationsRect.width(); +- double vScaleFactor = pageSize.height()/annotationsRect.height(); ++ // Exportation-transformed data ++ double hScaleFactor = pdfSceneRect.width() / annotationsRect.width(); ++ double vScaleFactor = pdfSceneRect.height() / annotationsRect.height(); + double scaleFactor = qMin(hScaleFactor, vScaleFactor); + + double xAnnotationsOffset = 0; + double yAnnotationsOffset = 0; +- double hPdfTransformed = qRound(hPdf * scaleFactor); ++ double hPdfTransformed = hPdf * scaleFactor; + + // Here, we force the PDF page to be on the topleft corner of the page + double xPdfOffset = 0; +- double yPdfOffset = (hPdf - hPdfTransformed) * mScaleFactor; ++ double yPdfOffset = (hPdf - hPdfTransformed); + + // Now we align the items +- xPdfOffset += (xPdf - xAnnotation) * scaleFactor * mScaleFactor; +- yPdfOffset -= (yPdf - yAnnotation) * scaleFactor * mScaleFactor; ++ xPdfOffset += (xPdf - xAnnotation) * scaleFactor; ++ yPdfOffset -= (yPdf - yAnnotation) * scaleFactor; + + // If the PDF was scaled when added to the scene (e.g if it was loaded from a document with a different DPI + // than the current one), it should also be scaled here. +- qreal pdfScale = pdfItem->sceneTransform().m11(); + +- TransformationDescription pdfTransform(xPdfOffset, yPdfOffset, scaleFactor * pdfScale, 0); ++ TransformationDescription pdfTransform(xPdfOffset, yPdfOffset, scaleFactor, 0); + TransformationDescription annotationTransform(xAnnotationsOffset, yAnnotationsOffset, 1, 0); + +- MergePageDescription pageDescription(pageSize.width() * mScaleFactor, +- pageSize.height() * mScaleFactor, ++ QSizeF pageSize = pdfItem->pageSize(); ++ MergePageDescription pageDescription(pageSize.width(), ++ pageSize.height(), + pdfItem->pageNumber(), + QFile::encodeName(backgroundPath).constData(), + pdfTransform, +@@ -276,8 +276,10 @@ bool UBExportFullPDF::persistsDocument(UBDocumentProxy* pDocumentProxy, const QS + } + else + { +- MergePageDescription pageDescription(pageSize.width() * mScaleFactor, +- pageSize.height() * mScaleFactor, ++ QSizeF pageSize = scene->nominalSize() * mScaleFactor; ++ ++ MergePageDescription pageDescription(pageSize.width(), ++ pageSize.height(), + 0, + "", + TransformationDescription(), +@@ -294,7 +296,7 @@ bool UBExportFullPDF::persistsDocument(UBDocumentProxy* pDocumentProxy, const QS + merger.saveMergedDocumentsAs(QFile::encodeName(filename).constData()); + + } +- catch(Exception e) ++ catch(const Exception& e) + { + qDebug() << "PdfMerger failed to merge documents to " << filename << " - Exception : " << e.what(); + +diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp +index 51995ade2..74cb3e9db 100644 +--- a/src/domain/UBGraphicsScene.cpp ++++ b/src/domain/UBGraphicsScene.cpp +@@ -2565,6 +2565,25 @@ QSize UBGraphicsScene::sceneSize() + return nominalSize(); + } + ++QSizeF UBGraphicsScene::sceneSizeF() const ++{ ++ UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast(backgroundObject()); ++ ++ if (pdfItem) ++ { ++ QRectF targetRect = pdfItem->sceneBoundingRect(); ++ return targetRect.size(); ++ } ++ else if (mDocument && !mNominalSize.isValid()) ++ { ++ return mDocument->defaultDocumentSize(); ++ } ++ else ++ { ++ return mNominalSize; ++ } ++} ++ + void UBGraphicsScene::setNominalSize(const QSize& pSize) + { + if (nominalSize() != pSize) +diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h +index e824e555f..7723880a8 100644 +--- a/src/domain/UBGraphicsScene.h ++++ b/src/domain/UBGraphicsScene.h +@@ -308,6 +308,7 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem + QSize nominalSize(); + + QSize sceneSize(); ++ QSizeF sceneSizeF() const; + + void setNominalSize(const QSize& pSize); + +diff --git a/src/pdf/GraphicsPDFItem.h b/src/pdf/GraphicsPDFItem.h +index 44858e53c..0eb9ed5cd 100644 +--- a/src/pdf/GraphicsPDFItem.h ++++ b/src/pdf/GraphicsPDFItem.h +@@ -52,6 +52,7 @@ class GraphicsPDFItem : public QObject, public QGraphicsItem + QUuid fileUuid() const { return mRenderer->fileUuid(); } + QByteArray fileData() const { return mRenderer->fileData(); } + void setCacheAllowed(bool const value) { mIsCacheAllowed = value; } ++ QSizeF pageSize() const { return mRenderer->pointSizeF(mPageNumber); } + virtual void updateChild() = 0; + protected: + PDFRenderer *mRenderer; +diff --git a/src/pdf/PDFRenderer.h b/src/pdf/PDFRenderer.h +index f3b0bf268..8f0cb93e0 100644 +--- a/src/pdf/PDFRenderer.h ++++ b/src/pdf/PDFRenderer.h +@@ -56,6 +56,8 @@ class PDFRenderer : public QObject + + virtual int pageRotation(int pageNumber) const = 0; + ++ virtual QSizeF pointSizeF(int pageNumber) const = 0; ++ + virtual QString title() const = 0; + + void attach(); +diff --git a/src/pdf/XPDFRenderer.cpp b/src/pdf/XPDFRenderer.cpp +index 27291dda9..97e258bfd 100644 +--- a/src/pdf/XPDFRenderer.cpp ++++ b/src/pdf/XPDFRenderer.cpp +@@ -195,6 +195,20 @@ QString XPDFRenderer::title() const + + + QSizeF XPDFRenderer::pageSizeF(int pageNumber) const ++{ ++ return pointSizeF(pageNumber) * this->dpiForRendering / 72.0; ++} ++ ++ ++int XPDFRenderer::pageRotation(int pageNumber) const ++{ ++ if (mDocument) ++ return mDocument->getPageRotate(pageNumber); ++ else ++ return 0; ++} ++ ++QSizeF XPDFRenderer::pointSizeF(int pageNumber) const + { + qreal cropWidth = 0; + qreal cropHeight = 0; +@@ -203,27 +217,17 @@ QSizeF XPDFRenderer::pageSizeF(int pageNumber) const + { + int rotate = mDocument->getPageRotate(pageNumber); + +- cropWidth = mDocument->getPageCropWidth(pageNumber) * this->dpiForRendering / 72.0; +- cropHeight = mDocument->getPageCropHeight(pageNumber) * this->dpiForRendering / 72.0; ++ cropWidth = mDocument->getPageCropWidth(pageNumber); ++ cropHeight = mDocument->getPageCropHeight(pageNumber); + + if (rotate == 90 || rotate == 270) + { + //switching width and height +- qreal tmpVar = cropWidth; +- cropWidth = cropHeight; +- cropHeight = tmpVar; ++ std::swap(cropWidth, cropHeight); + } + } +- return QSizeF(cropWidth, cropHeight); +-} + +- +-int XPDFRenderer::pageRotation(int pageNumber) const +-{ +- if (mDocument) +- return mDocument->getPageRotate(pageNumber); +- else +- return 0; ++ return QSizeF(cropWidth, cropHeight); + } + + +diff --git a/src/pdf/XPDFRenderer.h b/src/pdf/XPDFRenderer.h +index 919c2ad1c..5ae48ff48 100644 +--- a/src/pdf/XPDFRenderer.h ++++ b/src/pdf/XPDFRenderer.h +@@ -85,6 +85,7 @@ class XPDFRenderer : public PDFRenderer + virtual int pageCount() const override; + virtual QSizeF pageSizeF(int pageNumber) const override; + virtual int pageRotation(int pageNumber) const override; ++ virtual QSizeF pointSizeF(int pageNumber) const override; + virtual QString title() const override; + virtual void render(QPainter *p, int pageNumber, const bool cacheAllowed, const QRectF &bounds = QRectF()) override; + diff --git a/SOURCES/0686-shortcut-configuration.patch b/SOURCES/0686-shortcut-configuration.patch new file mode 100644 index 0000000..84af69d --- /dev/null +++ b/SOURCES/0686-shortcut-configuration.patch @@ -0,0 +1,10143 @@ +From d0f5b8299122654592db9e6ac7ac6578b154ff76 Mon Sep 17 00:00:00 2001 +From: letsfindaway +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 @@ + + + ++ ++ ++ Shortcut ++ ++ ++ ++ ++ ++ Filter ++ ++ ++ ++ ++ ++ ++ true ++ ++ ++ ++ ++ 0 ++ 0 ++ 789 ++ 447 ++ ++ ++ ++ ++ ++ ++ QAbstractItemView::NoEditTriggers ++ ++ ++ false ++ ++ ++ QAbstractItemView::SingleSelection ++ ++ ++ QAbstractItemView::SelectRows ++ ++ ++ false ++ ++ ++ false ++ ++ ++ true ++ ++ ++ false ++ ++ ++ 25 ++ ++ ++ 25 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ ++ ++ ++ ++ ++ false ++ ++ ++ Shortcuts ++ ++ ++ Qt::AlignCenter ++ ++ ++ ++ ++ ++ color: red; ++ ++ ++ Qt::PlainText ++ ++ ++ ++ ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ Abort ++ ++ ++ ++ ++ ++ ++ Record ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ Stylus Button ++ ++ ++ ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ Reset ++ ++ ++ ++ ++ ++ ++ Key Sequence ++ ++ ++ ++ ++ ++ ++ ++ + + + true +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(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(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(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& lightBackgroundColors, + const QList& darkBackgroundColors, const QList& lightBackgroundSelectedColors, + const QList& 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 . ++ */ ++ ++#include "UBShortcutManager.h" ++#include "core/UBSettings.h" ++#include "frameworks/UBPlatformUtils.h" ++#include "gui/UBMainWindow.h" ++ ++#include ++#include ++#include ++ ++// 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 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(button)] = action; ++ } ++ ++ if (int button = settings[2].toInt()) ++ { ++ action->setProperty(tabletButtonProperty, button); ++ mTabletActions[static_cast(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 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(action->property(mouseButtonProperty).toInt())) : QVariant(); ++ ++ case 4: ++ return action ? buttonName(static_cast(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(value.toInt())] = action; ++ updateSettings(action); ++ emit dataChanged(index, index); ++ return true; ++ ++ case 4: ++ action->setProperty(tabletButtonProperty, value); ++ mTabletActions[static_cast(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(action->property(mouseButtonProperty).toInt())); ++ mTabletActions.remove(static_cast(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 shortcuts; ++ QSet 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(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 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 &UBShortcutManager::actionsOfGroup(const QString &group) ++{ ++ for (auto& actionGroup : mActionGroups) ++ { ++ if (actionGroup.first == group) { ++ return actionGroup.second; ++ } ++ } ++ ++ QPair> 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 . ++ */ ++ ++ ++#ifndef UBSHORTCUTMANAGER_H ++#define UBSHORTCUTMANAGER_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 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& actionsOfGroup(const QString& group); ++ QAction* getAction(const QModelIndex& index, QString* group = nullptr) const; ++ void updateSettings(const QAction* action) const; ++ ++private: ++ QList>> mActionGroups; ++ QMap mMouseActions; ++ QMap 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(&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 + #include +-#include ++#include + #include + + #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 mButtons; +- QButtonGroup* mButtonGroup; ++ QActionGroup* mActionGroup; + QList mActions; + QMap 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(&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 +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + هل تريدون حقا إزالة صفحة واحدة من الوثيقة '%0' المختارة؟ + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2086,6 +2090,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + العلامة حساسة للضغط + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ موافقة ++ ++ ++ Record ++ preferencesDialog ++ تسجيل ++ + + + UBSettings +@@ -2094,6 +2120,148 @@ Do you want to ignore these errors for this host? + أفلامي + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ لوحة ++ ++ ++ Stylus Palette ++ لوح الرسم ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ بودكاست ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ الوصف ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ يسار ++ ++ ++ Right ++ MouseButton ++ يمين ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ العودة ++ ++ ++ Forward ++ MouseButton ++ أمام ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2751,6 +2919,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ تسجيل ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Сигурни ли сте ,че искате да премахнете 1 страница от избрания документ '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Чувствителен на натиск маркер + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Приеми ++ ++ ++ Record ++ preferencesDialog ++ Запиши ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host? + Моите филми + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Дъска ++ ++ ++ Stylus Palette ++ Палитна на стилуса ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Подкаст ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Описание ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ На ляво ++ ++ ++ Right ++ MouseButton ++ На дясно ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Назад ++ ++ ++ Forward ++ MouseButton ++ Напред ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2741,6 +2909,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Запиши ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Esteu segur que voleu eliminar 1 pàgina del document seleccionat '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Voleu ignorar aquests errors per a aquest amfitrió? + Marker is pressure sensitive + El marcador és sensible a la pressió + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ D'acord ++ ++ ++ Record ++ preferencesDialog ++ Enregistra ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Voleu ignorar aquests errors per a aquest amfitrió? + Les meves pel·lícules + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tauler ++ ++ ++ Stylus Palette ++ Barra d'estris ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Descripció ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Esquerra ++ ++ ++ Right ++ MouseButton ++ Dreta ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Enrere ++ ++ ++ Forward ++ MouseButton ++ Cap endavant ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBThumbnailAdaptor + +@@ -2735,6 +2903,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Enregistra ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Opravdu chcete odstranit 1 stránku z vybraného dokumentu '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2083,6 +2087,28 @@ Chcete ignorovat tyto chyby na tomto serveru? + Marker is pressure sensitive + Zvýrazňovač je citlivý na tlak + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Přijmout ++ ++ ++ Record ++ preferencesDialog ++ Nahrávat ++ + + + UBSettings +@@ -2091,6 +2117,148 @@ Chcete ignorovat tyto chyby na tomto serveru? + Moje filmy + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ ++ ++ ++ Stylus Palette ++ Paleta pro stylus ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Popis ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Vlevo ++ ++ ++ Right ++ MouseButton ++ Vpravo ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Zpět ++ ++ ++ Forward ++ MouseButton ++ Vpřed ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2746,6 +2914,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Nahrávat ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Er du sikker på, at du vil fjerne 1 side fra det valgte dokument'%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Markøren er tryksensitiv + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Accepter ++ ++ ++ Record ++ preferencesDialog ++ Optag ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host? + Mine Film + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tavle ++ ++ ++ Stylus Palette ++ Penpalette ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Beskrivelse ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Venstre ++ ++ ++ Right ++ MouseButton ++ Højre ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Tilbage ++ ++ ++ Forward ++ MouseButton ++ Fremad ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2738,6 +2906,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Optag ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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? + + + Ctrl++ +- Strg ++ ++ Strg++ + + + Smaller +@@ -367,7 +367,7 @@ Möchten Sie die Sicherheitsüberprüfung außer Kraft setzen und fortfahren? + + + Ctrl+- +- Strg +- ++ Strg+- + + + New Folder +@@ -943,6 +943,10 @@ Möchten Sie die Sicherheitsüberprüfung außer Kraft setzen und fortfahren? + Are you sure you want to remove 1 page from the selected document '%0'? + Wollen Sie wirklich die ausgewählte Seite des Dokuments '%0' entfernen? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + Laden der Szene (%1/%2) +@@ -2088,6 +2092,28 @@ Möchten Sie diese Fehler für diesen Computer ignorieren? + Marker is pressure sensitive + Der Marker ist druckempfindlich + ++ ++ Key sequence already in use ++ Tastenkombination wird bereits benutzt ++ ++ ++ Mouse button already in use ++ Maustaste wird bereits benutzt ++ ++ ++ Stylus button already in use ++ Stifttaste wird bereits benutzt ++ ++ ++ Accept ++ preferencesDialog ++ Übernehmen ++ ++ ++ Record ++ preferencesDialog ++ Aufnehmen ++ + + + UBSettings +@@ -2096,6 +2122,148 @@ Möchten Sie diese Fehler für diesen Computer ignorieren? + Meine Filme + + ++ ++ UBShortcutManager ++ ++ Common ++ Allgemein ++ ++ ++ Board ++ Board ++ ++ ++ Stylus Palette ++ Stylus-Palette ++ ++ ++ Lines and colours ++ Linien und Farben ++ ++ ++ Background ++ Hintergrund ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ Erste Seite ++ ++ ++ Show first scene ++ Erste Seite anzeigen ++ ++ ++ Last scene ++ Letzte Seite ++ ++ ++ Show last scene ++ Letzte Seite anzeigen ++ ++ ++ Zoom reset ++ Originalgröße ++ ++ ++ Reset zoom factor ++ Zoom-Faktor zurücksetzen ++ ++ ++ Scroll left ++ Links ++ ++ ++ Scroll page left ++ Seite nach links verschieben ++ ++ ++ Scroll right ++ Rechts ++ ++ ++ Scroll page right ++ Seite nach rechts verschieben ++ ++ ++ Scroll up ++ Oben ++ ++ ++ Scroll page up ++ Seite nach oben verschieben ++ ++ ++ Scroll down ++ Unten ++ ++ ++ Scroll page down ++ Seite nach unten verschieben ++ ++ ++ Built-in (not editable) ++ Eingebaut (nicht änderbar) ++ ++ ++ Command ++ Befehl ++ ++ ++ Description ++ Beschreibung ++ ++ ++ Key Sequence ++ Tasten ++ ++ ++ Mouse Button ++ Maustaste ++ ++ ++ Tablet Button ++ Stifttaste ++ ++ ++ Left ++ MouseButton ++ Links ++ ++ ++ Right ++ MouseButton ++ Rechts ++ ++ ++ Middle ++ MouseButton ++ Mitte ++ ++ ++ Back ++ MouseButton ++ Zurück ++ ++ ++ Forward ++ MouseButton ++ Weiter ++ ++ ++ Task ++ MouseButton ++ Aufgabe ++ ++ ++ Extra ++ MouseButton ++ Extre ++ ++ + + UBTeacherBarWidget + +@@ -2687,7 +2855,7 @@ p, li { white-space: pre-wrap; } + + + Desktop +- Schreibtisch ++ Desktop + + + Proxy User: +@@ -2757,9 +2925,49 @@ p, li { white-space: pre-wrap; } + PDF Rendering + PDF-Wiedergabe + ++ ++ Shortcut ++ Kurzbefehl ++ ++ ++ Filter ++ Filter ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ Aktiviere Kurzbefehle auch ohne Strg Taste ++ ++ ++ Shortcuts ++ Kurzbefehle ++ ++ ++ Abort ++ Abbrechen ++ ++ ++ Record ++ Aufnehmen ++ ++ ++ Stylus Button ++ Stifttaste ++ ++ ++ Mouse Button ++ Maustaste ++ ++ ++ Reset ++ Zurücksetzen ++ ++ ++ Key Sequence ++ Tasten ++ + + Improve zoom execution time (can slightly affect rendering quality) +- Die Zoomgeschwindigkeit verbessern (kann die Renderqualität geringfügig beeinträchtigen) ++ Zoom beschleunigen (kann Qualität geringfügig beeinträchtigen) + + + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Είστε βέβαιος ότι θέλετε να αφαιρέσετε μια σελίδα από το επιλεγμένο έγγραφο '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Ο μαρκαδόρος είναι ευαίσθητος στην πίεση + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Αποδοχή ++ ++ ++ Record ++ preferencesDialog ++ Εγγραφή ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host? + Οι ταινίες μου + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Εφαρμογή ++ ++ ++ Stylus Palette ++ Παλέτα εργαλείων ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Βίντεο ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Περιγραφή ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Αριστερά ++ ++ ++ Right ++ MouseButton ++ Δεξιά ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Πίσω ++ ++ ++ Forward ++ MouseButton ++ Μπροστά ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Εγγραφή ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + (Untitled) + + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2062,6 +2066,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ ++ ++ ++ Record ++ preferencesDialog ++ ++ + + + UBSettings +@@ -2070,6 +2096,148 @@ Do you want to ignore these errors for this host? + + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ ++ ++ ++ Stylus Palette ++ ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ ++ ++ ++ Right ++ MouseButton ++ ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ ++ ++ ++ Forward ++ MouseButton ++ ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2720,6 +2888,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + (Untitled) + + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2062,6 +2066,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ ++ ++ ++ Record ++ preferencesDialog ++ ++ + + + UBSettings +@@ -2070,6 +2096,148 @@ Do you want to ignore these errors for this host? + + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ ++ ++ ++ Stylus Palette ++ ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ ++ ++ ++ Right ++ MouseButton ++ ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ ++ ++ ++ Forward ++ MouseButton ++ ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2720,6 +2888,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + ¿Está seguro de que quiere eliminar 1 página del documento seleccionado.'%0? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + El marcador es sensible a la presión + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Aceptar ++ ++ ++ Record ++ preferencesDialog ++ Grabar ++ + + + UBSettings +@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host? + Mis películas + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Pizarra ++ ++ ++ Stylus Palette ++ Paleta del lápiz ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Descripción ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Izquierda ++ ++ ++ Right ++ MouseButton ++ Derecha ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Atrás ++ ++ ++ Forward ++ MouseButton ++ Hacia delante ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Grabar ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Voulez-vous vraiment effacer 1 page de ce document '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + Chargement de la scène (%1/%2) +@@ -2093,6 +2097,28 @@ Voulez-vous ignorer les erreurs pour ce serveur ? + version: + version : + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Accepter ++ ++ ++ Record ++ preferencesDialog ++ Enregistrer ++ + + + UBSettings +@@ -2101,6 +2127,148 @@ Voulez-vous ignorer les erreurs pour ce serveur ? + Mes films + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tableau ++ ++ ++ Stylus Palette ++ Barre du stylet ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Description ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Gauche ++ ++ ++ Right ++ MouseButton ++ Droite ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Précédente ++ ++ ++ Forward ++ MouseButton ++ Suivante ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2761,6 +2929,46 @@ p, li { white-space: pre-wrap; } + Rendu PDF + + ++ ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Enregistrer ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ + Improve zoom execution time (can slightly affect rendering quality) + Améliorer la vitesse d'exécution du zoom (peut légèrement affecter la qualité du rendu) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Voulez-vous vraiment effacer 1 page de ce document '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + Chargement de la scène (%1/%2) +@@ -2093,6 +2097,28 @@ Voulez-vous ignorer les erreurs pour ce serveur ? + version: + version : + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Accepter ++ ++ ++ Record ++ preferencesDialog ++ Enregistrer ++ + + + UBSettings +@@ -2101,6 +2127,148 @@ Voulez-vous ignorer les erreurs pour ce serveur ? + Mes films + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tableau ++ ++ ++ Stylus Palette ++ Barre du stylet ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Description ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Gauche ++ ++ ++ Right ++ MouseButton ++ Droite ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Précédente ++ ++ ++ Forward ++ MouseButton ++ Suivante ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2761,6 +2929,46 @@ p, li { white-space: pre-wrap; } + Rendu PDF + + ++ ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Enregistrer ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ + Improve zoom execution time (can slightly affect rendering quality) + Améliorer la vitesse d'exécution du zoom (peut légèrement affecter la qualité du rendu) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + ¿Está seguro de que quere eliminar 1 páxina do documento seleccionado.'%0? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + O marcador é sensible á presión + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Aceptar ++ ++ ++ Record ++ preferencesDialog ++ Grabar ++ + + + UBSettings +@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host? + As miñas películas + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Encerado ++ ++ ++ Stylus Palette ++ Paleta do lápiz ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Esquerda ++ ++ ++ Right ++ MouseButton ++ Dereita ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Atrás ++ ++ ++ Forward ++ MouseButton ++ Cara a diante ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2734,6 +2902,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Grabar ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Content is not supported in destination format. + A tartalom nem támogatott célformátumban. + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2153,6 +2157,28 @@ Figyelmen kívül hagyja ezeket a hibákat ennél a hosztnál? + Marker is pressure sensitive + A jelölőtoll nyomásérzékeny + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Elfogad ++ ++ ++ Record ++ preferencesDialog ++ Felvétel ++ + + + UBSettings +@@ -2161,6 +2187,148 @@ Figyelmen kívül hagyja ezeket a hibákat ennél a hosztnál? + Videóim + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tábla ++ ++ ++ Stylus Palette ++ Képernyő eszköztár ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Leírás ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Bal ++ ++ ++ Right ++ MouseButton ++ Jobb ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Vissza ++ ++ ++ Forward ++ MouseButton ++ Előre ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2811,6 +2979,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + PDF-megjelenítő + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Felvétel ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + Nagyitás végrehajtási idő csökkentése (némileg befolyásolhatja a renderelés minőségét) +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Sei sicuro di voler rimuovere 1 pagina dal documento selezionato '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + Caricamento della scena (%1/%2) +@@ -2081,6 +2085,28 @@ Vuoi ignorare gli errori per questo host? + Marker is pressure sensitive + L'evidenziatore è sensibile alla pressione + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Accetta ++ ++ ++ Record ++ preferencesDialog ++ Registra ++ + + + UBSettings +@@ -2089,6 +2115,148 @@ Vuoi ignorare gli errori per questo host? + I miei film + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Lavagna ++ ++ ++ Stylus Palette ++ Palette stilo ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Descrizione ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Sinistra ++ ++ ++ Right ++ MouseButton ++ Destra ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Indietro ++ ++ ++ Forward ++ MouseButton ++ Avanti ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2749,6 +2917,46 @@ p, li { white-space: pre-wrap; } + rendering PDF + + ++ ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Registra ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ + Improve zoom execution time (can slightly affect rendering quality) + Migliorare la velocità dello zoom (può influire leggermente sulla qualità del rendering) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + האם אתה בטוח שברצונך למחוק דף 1 מהמסמך שנבחר %0? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + הסמן רגיש ללחץ + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ קבל ++ ++ ++ Record ++ preferencesDialog ++ הקלט ++ + + + UBSettings +@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host? + הסרטים שלי + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ לוח ++ ++ ++ Stylus Palette ++ סרגל הכלים הגראפיים ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ פודקסט ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ תיאור ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ שמאל ++ ++ ++ Right ++ MouseButton ++ ימין ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ חזרה ++ ++ ++ Forward ++ MouseButton ++ קדימה ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2734,6 +2902,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ הקלט ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2077,6 +2081,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + 感圧性マーカー + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ ++ ++ ++ Record ++ preferencesDialog ++ 記録 ++ + + + UBSettings +@@ -2085,6 +2111,148 @@ Do you want to ignore these errors for this host? + マイ・ムービー + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ ボード ++ ++ ++ Stylus Palette ++ スタイラスパレット ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ ポッドキャスト ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ 説明 ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ ++ ++ ++ Right ++ MouseButton ++ ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ 戻る ++ ++ ++ Forward ++ MouseButton ++ 前へ ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2736,6 +2904,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ 記録 ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + 선택한 문서 '%0'에서 1페이지를 제거하시겠습니까? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2082,6 +2086,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + 마커는 압력 감지식입니다 + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ 적용 ++ ++ ++ Record ++ preferencesDialog ++ 레코딩 ++ + + + UBSettings +@@ -2090,6 +2116,148 @@ Do you want to ignore these errors for this host? + 내 동영상 + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ 보드 ++ ++ ++ Stylus Palette ++ 스타일러스 팔레트 ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ 팟캐스트 ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ 설명 ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ 왼쪽 ++ ++ ++ Right ++ MouseButton ++ 오른쪽 ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ 뒤로 ++ ++ ++ Forward ++ MouseButton ++ 앞으로 ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2745,6 +2913,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ 레코딩 ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Tena te hamafa pejy iray avy amin'ilay rakitra '%0' voafidy ve ianao ? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Tena tsy te hiraharaha an'ireo tsy mety ho an'ilay milina ve ianao?Marker is pressure sensitive + Ny penina lehibe dia sarotiny amin'ny fitsindrina + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Ekena ++ ++ ++ Record ++ preferencesDialog ++ Raiketo ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Tena tsy te hiraharaha an'ireo tsy mety ho an'ilay milina ve ianao?Ny sarimietsiko + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Solaitra ++ ++ ++ Stylus Palette ++ Fanovana haingony ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Fanazavana ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Havia ++ ++ ++ Right ++ MouseButton ++ Havanana ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Miverina ++ ++ ++ Forward ++ MouseButton ++ Manaraka ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Raiketo ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Er du sikker på at du vil fjerne side 1 fra det valgte dokumentet '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2075,6 +2079,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Markøren er trykksensitiv + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Godta ++ ++ ++ Record ++ preferencesDialog ++ Ta opp ++ + + + UBSettings +@@ -2083,6 +2109,148 @@ Do you want to ignore these errors for this host? + Mine filmer + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tavle ++ ++ ++ Stylus Palette ++ Stilpalett ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Beskrivelse ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Venstre ++ ++ ++ Right ++ MouseButton ++ Høyre ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Tilbake ++ ++ ++ Forward ++ MouseButton ++ Forover ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2739,6 +2907,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Ta opp ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2073,6 +2077,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Markeerstift is druk gevoelig + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ ++ ++ ++ Record ++ preferencesDialog ++ Opnemen ++ + + + UBSettings +@@ -2081,6 +2107,148 @@ Do you want to ignore these errors for this host? + Mijn films + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Bord ++ ++ ++ Stylus Palette ++ Pen palet ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Beschrijving ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Links ++ ++ ++ Right ++ MouseButton ++ Rechts ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Terug ++ ++ ++ Forward ++ MouseButton ++ Vooruit ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2735,6 +2903,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Opnemen ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Czy na pewno chcesz usunąć 1 stronę z wybranego dokumentu „%0”? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2087,6 +2091,28 @@ Czy chcesz ignorować te błędy dla tego hosta? + Marker is pressure sensitive + Marker jest czuły na nacisk + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Akceptuj ++ ++ ++ Record ++ preferencesDialog ++ Nagraj ++ + + + UBSettings +@@ -2095,6 +2121,148 @@ Czy chcesz ignorować te błędy dla tego hosta? + Moje filmy + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tablica ++ ++ ++ Stylus Palette ++ Paleta piórka ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podkast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Opis ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Lewo ++ ++ ++ Right ++ MouseButton ++ Prawo ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Powrót ++ ++ ++ Forward ++ MouseButton ++ Do przodu ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2750,6 +2918,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + Renderowanie PDF + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Nagraj ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + Usprawnij wykonywanie przybliżania (może nieco pogorszyć jakość renderowania) +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Tem a certeza que quer remover 1 página do documento selecionado '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2082,6 +2086,28 @@ Quer ignorar estes erros, deste servidor? + Marker is pressure sensitive + O marcador é sensível à pressão + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Aceitar ++ ++ ++ Record ++ preferencesDialog ++ Gravar ++ + + + UBSettings +@@ -2090,6 +2116,148 @@ Quer ignorar estes erros, deste servidor? + Os meus filmes + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Quadro ++ ++ ++ Stylus Palette ++ Paleta ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Descrição ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Esquerda ++ ++ ++ Right ++ MouseButton ++ Direita ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Recuar ++ ++ ++ Forward ++ MouseButton ++ Avançar ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBThumbnailAdaptor + +@@ -2740,6 +2908,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Gravar ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Sunteți sigur că doriți să eliminați 1 pagină din documentul selectat '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Doriţi să ignoraţi aceste erori pentru acest host? + Marker is pressure sensitive + Markerul este sensibil la apăsare + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Acceptare ++ ++ ++ Record ++ preferencesDialog ++ Înregistrare ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Doriţi să ignoraţi aceste erori pentru acest host? + Filmele mele + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tablă ++ ++ ++ Stylus Palette ++ Paletă stilou ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Descriere ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Stânga ++ ++ ++ Right ++ MouseButton ++ Dreapta ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Înapoi ++ ++ ++ Forward ++ MouseButton ++ Înainte ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Înregistrare ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Вы уверены, что хотите удалить 1 страницу из документа '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2081,6 +2085,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Маркер чувствителен к нажиму + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Принять ++ ++ ++ Record ++ preferencesDialog ++ Запись ++ + + + UBSettings +@@ -2089,6 +2115,148 @@ Do you want to ignore these errors for this host? + Мои видеофайлы + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Доска ++ ++ ++ Stylus Palette ++ Инструменты ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Подкаст ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Описание ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Влево ++ ++ ++ Right ++ MouseButton ++ Вправо ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Назад ++ ++ ++ Forward ++ MouseButton ++ Вперед ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2744,6 +2912,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Запись ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Určite chcete odstrániť 1 stránku z vybraného dokumentu '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2087,6 +2091,28 @@ Chcete ignorovať tieto chyby na tomto serveri? + Marker is pressure sensitive + Zvýrazňovač je citlivý na tlak + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Prijať ++ ++ ++ Record ++ preferencesDialog ++ Nahrávať ++ + + + UBSettings +@@ -2095,6 +2121,148 @@ Chcete ignorovať tieto chyby na tomto serveri? + Moje filmy + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tabuľa ++ ++ ++ Stylus Palette ++ Paleta pre interaktívne pero ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Popis ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Doľava ++ ++ ++ Right ++ MouseButton ++ Doprava ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Predošlá ++ ++ ++ Forward ++ MouseButton ++ Ďalšia ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2751,6 +2919,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Nahrávať ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Är du säker på att du vill ta bort 1 sida från det valda dokumentet '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2080,6 +2084,28 @@ Vill du ignorera felen för den här värden? + Marker is pressure sensitive + Markören är tryckkänslig + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Acceptera ++ ++ ++ Record ++ preferencesDialog ++ Spela in ++ + + + UBSettings +@@ -2088,6 +2114,148 @@ Vill du ignorera felen för den här värden? + Mina filmer + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tavla ++ ++ ++ Stylus Palette ++ Pekpennans palett ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Beskrivning ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Vänster ++ ++ ++ Right ++ MouseButton ++ Höger ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Backa ++ ++ ++ Forward ++ MouseButton ++ Framåt ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2743,6 +2911,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Spela in ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Seçili olan '%0' adlı dökümandan 1 sayfayı kaldırmak üzeresiniz. Bu işlemi yapmak istediğinizden eminmisiniz? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2075,6 +2079,28 @@ Bu host için yukarıdaki hatalar yok sayılsın mı? + Marker is pressure sensitive + İşaretçi basınca duyarlıdır + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Kabul Et ++ ++ ++ Record ++ preferencesDialog ++ Kayıt ++ + + + UBSettings +@@ -2083,6 +2109,148 @@ Bu host için yukarıdaki hatalar yok sayılsın mı? + Filimlerim + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Tahta ++ ++ ++ Stylus Palette ++ Stylus Paleti ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Ekran Kaydı ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Açıklama ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Sol ++ ++ ++ Right ++ MouseButton ++ Sağ ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Geri ++ ++ ++ Forward ++ MouseButton ++ İleri ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2738,6 +2906,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Kayıt ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + Ви впевнені, що хочете видалити 1 сторінку з документа '%0'? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2079,6 +2083,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + Маркер чутливий до тиску + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ Прийняти ++ ++ ++ Record ++ preferencesDialog ++ Запис ++ + + + UBSettings +@@ -2087,6 +2113,148 @@ Do you want to ignore these errors for this host? + Мої відеофайли + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ Дошка ++ ++ ++ Stylus Palette ++ Інструменти ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Подкаст ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ Опис ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ Вліво ++ ++ ++ Right ++ MouseButton ++ Вправо ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ Назад ++ ++ ++ Forward ++ MouseButton ++ Вперед ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2742,6 +2910,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ Запис ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + 确定要删除选中文件“%0”中的1页? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + 加载场景 (%1/%2) +@@ -2072,6 +2076,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + 使用压感记号笔 + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ 接受 ++ ++ ++ Record ++ preferencesDialog ++ 录制 ++ + + + UBSettings +@@ -2080,6 +2106,148 @@ Do you want to ignore these errors for this host? + 我的视频 + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ 演示板 ++ ++ ++ Stylus Palette ++ 工具面板 ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ 播客 ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ 描述 ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ 向左 ++ ++ ++ Right ++ MouseButton ++ 向右 ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ 后退 ++ ++ ++ Forward ++ MouseButton ++ 前进 ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2735,6 +2903,45 @@ p, li { white-space: pre-wrap; } + PDF Rendering + PDF 渲染 + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ 录制 ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ + + Improve zoom execution time (can slightly affect rendering quality) + 提高缩放执行时间(可能会略微影响渲染质量) +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + 确定要删除选中文件“%0”中的1页? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + 加载场景 (%1/%2) +@@ -2072,6 +2076,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + 使用压感记号笔 + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ 接受 ++ ++ ++ Record ++ preferencesDialog ++ 录制 ++ + + + UBSettings +@@ -2080,6 +2106,148 @@ Do you want to ignore these errors for this host? + 我的视频 + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ 演示板 ++ ++ ++ Stylus Palette ++ 工具面板 ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ 播客 ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ 描述 ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ 向左 ++ ++ ++ Right ++ MouseButton ++ 向右 ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ 后退 ++ ++ ++ Forward ++ MouseButton ++ 前进 ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBTeacherBarWidget + +@@ -2735,6 +2903,45 @@ p, li { white-space: pre-wrap; } + PDF Rendering + PDF 渲染 + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ 录制 ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ + + Improve zoom execution time (can slightly affect rendering quality) + 提高缩放执行时间(可能会略微影响渲染质量) +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 ? + Are you sure you want to remove 1 page from the selected document '%0'? + 確定要移除所選文件 '%0' 的一個頁面? + ++ ++ Common ++ ++ + + Loading scene (%1/%2) + +@@ -2070,6 +2074,28 @@ Do you want to ignore these errors for this host? + Marker is pressure sensitive + 感壓型提示筆 + ++ ++ Key sequence already in use ++ ++ ++ ++ Mouse button already in use ++ ++ ++ ++ Stylus button already in use ++ ++ ++ ++ Accept ++ preferencesDialog ++ 接受 ++ ++ ++ Record ++ preferencesDialog ++ 錄製 ++ + + + UBSettings +@@ -2078,6 +2104,148 @@ Do you want to ignore these errors for this host? + 我的影片 + + ++ ++ UBShortcutManager ++ ++ Common ++ ++ ++ ++ Board ++ ++ ++ ++ Stylus Palette ++ 桌面工具 ++ ++ ++ Lines and colours ++ ++ ++ ++ Background ++ ++ ++ ++ Podcast ++ Podcast ++ ++ ++ First scene ++ ++ ++ ++ Show first scene ++ ++ ++ ++ Last scene ++ ++ ++ ++ Show last scene ++ ++ ++ ++ Zoom reset ++ ++ ++ ++ Reset zoom factor ++ ++ ++ ++ Scroll left ++ ++ ++ ++ Scroll page left ++ ++ ++ ++ Scroll right ++ ++ ++ ++ Scroll page right ++ ++ ++ ++ Scroll up ++ ++ ++ ++ Scroll page up ++ ++ ++ ++ Scroll down ++ ++ ++ ++ Scroll page down ++ ++ ++ ++ Built-in (not editable) ++ ++ ++ ++ Command ++ ++ ++ ++ Description ++ 描述 ++ ++ ++ Key Sequence ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Tablet Button ++ ++ ++ ++ Left ++ MouseButton ++ 向左 ++ ++ ++ Right ++ MouseButton ++ 向右 ++ ++ ++ Middle ++ MouseButton ++ ++ ++ ++ Back ++ MouseButton ++ 退回 ++ ++ ++ Forward ++ MouseButton ++ 前進 ++ ++ ++ Task ++ MouseButton ++ ++ ++ ++ Extra ++ MouseButton ++ ++ ++ + + UBThumbnailAdaptor + +@@ -2726,6 +2894,46 @@ p, li { white-space: pre-wrap; } + PDF Rendering + + ++ ++ Shortcut ++ ++ ++ ++ Filter ++ ++ ++ ++ Active keyboard shortcuts without pressing Ctrl key ++ ++ ++ ++ Shortcuts ++ ++ ++ ++ Abort ++ ++ ++ ++ Record ++ 錄製 ++ ++ ++ Stylus Button ++ ++ ++ ++ Mouse Button ++ ++ ++ ++ Reset ++ ++ ++ ++ Key Sequence ++ ++ + + Improve zoom execution time (can slightly affect rendering quality) + + +From 39456c6e853186b45b395f693f9b251d4d8f3456 Mon Sep 17 00:00:00 2001 +From: letsfindaway +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 +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 +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 mPreviousPolygonItems; + + +From 7db64f65e3824c3b09ef1618425901404b133ddc Mon Sep 17 00:00:00 2001 +From: letsfindaway +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>> mActionGroups; + QMap mMouseActions; + QMap mTabletActions; ++ bool mIgnoreCtrl; + + static UBShortcutManager* sShortcutManager; + }; + +From 89885f7e4aa32134c0c1c5109af5beb24d541154 Mon Sep 17 00:00:00 2001 +From: letsfindaway +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(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(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(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 + + 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 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>> mActionGroups; + QMap mMouseActions; + QMap mTabletActions; ++ QMap 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 +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(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); ++ } + } + } + } diff --git a/SOURCES/0698-add-cmake-build-system.patch b/SOURCES/0698-add-cmake-build-system.patch new file mode 100644 index 0000000..4c8ae23 --- /dev/null +++ b/SOURCES/0698-add-cmake-build-system.patch @@ -0,0 +1,1762 @@ +From 6830bd54d42446a4d09acc25da39113ecd808a61 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Wed, 10 Aug 2022 10:41:15 +0200 +Subject: [PATCH 1/3] chore: add cmake build system + +- add a cmake based build sytem which is + - easy to understand + - easy to maintain + - covering Linux, Windows and MacOS platforms + - allow to build for Qt5 and Qt6 without modifying the cmake files + - reasonable structure in QtCreator +- create a structure with + - concise root CMakeLists.txt + - separate files for each src subdirectory + - separate files for finding dependencies +- currently missing + - support for Windows only rudimentary (WIP) + - support for MacOS only rudimentary (WIP) +- flexible install locations + - add `UBPlatformUtile::applicationEtcDirectory()` + - use it whenever referencing files in this directory + - allow to configure these directories at build time and runtime + - create complete installation tree + - cover /usr and /opt based installations +- move non-config files out of etc + - move template files from resources/etc to resources/template + - adapt code accessing these resources +--- + .gitignore | 1 + + CMakeLists.txt | 234 ++++++++++++++++++ + cmake/DependencyFFmpeg.cmake | 12 + + cmake/DependencyOpenSSL.cmake | 7 + + cmake/DependencyPoppler.cmake | 20 ++ + cmake/DependencyQt.cmake | 39 +++ + cmake/DependencyQuaZip.cmake | 43 ++++ + cmake/DependencyX11.cmake | 18 ++ + cmake/DependencyZlib.cmake | 6 + + cmake/FetchContentFreetype.cmake | 13 + + cmake/FetchContentPoppler.cmake | 18 ++ + cmake/FetchContentQuaZip.cmake | 23 ++ + cmake/FetchContentXpdf.cmake | 28 +++ + cmake/Platform.cmake | 16 ++ + cmake/Version.cmake | 23 ++ + plugins/cffadaptor/src/CMakeLists.txt | 7 + + resources/forms/CMakeLists.txt | 13 + + resources/images/ch.openboard.OpenBoard.svg | 4 + + .../linux/ch.openboard.OpenBoard.desktop | 11 + + .../linux/ch.openboard.application-ubz.svg | 36 +++ + .../linux/ch.openboard.openboard-ubz.xml | 10 + + resources/{etc => template}/asyncAPI.js | 0 + resources/{etc => template}/img/loading.gif | Bin + .../intranet-podcast-metadata.template | 0 + ...pper.application.x-shockwave-flash.swf.htm | 0 + .../npapi-wrapper.config.xml | 0 + src/adaptors/CMakeLists.txt | 38 +++ + src/adaptors/UBWidgetUpgradeAdaptor.cpp | 2 +- + src/api/CMakeLists.txt | 8 + + src/board/CMakeLists.txt | 12 + + src/core/CMakeLists.txt | 38 +++ + src/core/UBApplication.cpp | 2 +- + src/core/UBSettings.cpp | 2 +- + src/desktop/CMakeLists.txt | 10 + + src/document/CMakeLists.txt | 10 + + src/domain/CMakeLists.txt | 58 +++++ + src/domain/UBGraphicsWidgetItem.cpp | 10 +- + src/frameworks/CMakeLists.txt | 32 +++ + src/frameworks/UBPlatformUtils.h | 1 + + src/frameworks/UBPlatformUtils_linux.cpp | 14 ++ + src/frameworks/UBPlatformUtils_mac.mm | 5 + + src/frameworks/UBPlatformUtils_win.cpp | 4 + + src/globals/CMakeLists.txt | 3 + + src/gui/CMakeLists.txt | 98 ++++++++ + src/network/CMakeLists.txt | 14 ++ + src/pdf-merger/CMakeLists.txt | 50 ++++ + src/pdf/CMakeLists.txt | 8 + + src/podcast/CMakeLists.txt | 30 +++ + .../intranet/UBIntranetPodcastPublisher.cpp | 2 +- + src/tools/CMakeLists.txt | 22 ++ + src/web/CMakeLists.txt | 35 +++ + src/web/UBWebController.cpp | 2 +- + 52 files changed, 1082 insertions(+), 10 deletions(-) + create mode 100644 CMakeLists.txt + create mode 100644 cmake/DependencyFFmpeg.cmake + create mode 100644 cmake/DependencyOpenSSL.cmake + create mode 100644 cmake/DependencyPoppler.cmake + create mode 100644 cmake/DependencyQt.cmake + create mode 100644 cmake/DependencyQuaZip.cmake + create mode 100644 cmake/DependencyX11.cmake + create mode 100644 cmake/DependencyZlib.cmake + create mode 100644 cmake/FetchContentFreetype.cmake + create mode 100644 cmake/FetchContentPoppler.cmake + create mode 100644 cmake/FetchContentQuaZip.cmake + create mode 100644 cmake/FetchContentXpdf.cmake + create mode 100644 cmake/Platform.cmake + create mode 100644 cmake/Version.cmake + create mode 100644 plugins/cffadaptor/src/CMakeLists.txt + create mode 100644 resources/forms/CMakeLists.txt + create mode 100644 resources/images/ch.openboard.OpenBoard.svg + create mode 100644 resources/linux/ch.openboard.OpenBoard.desktop + create mode 100644 resources/linux/ch.openboard.application-ubz.svg + create mode 100644 resources/linux/ch.openboard.openboard-ubz.xml + rename resources/{etc => template}/asyncAPI.js (100%) + rename resources/{etc => template}/img/loading.gif (100%) + rename resources/{etc => template}/intranet-podcast-metadata.template (100%) + rename resources/{etc => template}/npapi-wrapper.application.x-shockwave-flash.swf.htm (100%) + rename resources/{etc => template}/npapi-wrapper.config.xml (100%) + create mode 100644 src/adaptors/CMakeLists.txt + create mode 100644 src/api/CMakeLists.txt + create mode 100644 src/board/CMakeLists.txt + create mode 100644 src/core/CMakeLists.txt + create mode 100644 src/desktop/CMakeLists.txt + create mode 100644 src/document/CMakeLists.txt + create mode 100644 src/domain/CMakeLists.txt + create mode 100644 src/frameworks/CMakeLists.txt + create mode 100644 src/globals/CMakeLists.txt + create mode 100644 src/gui/CMakeLists.txt + create mode 100644 src/network/CMakeLists.txt + create mode 100644 src/pdf-merger/CMakeLists.txt + create mode 100644 src/pdf/CMakeLists.txt + create mode 100644 src/podcast/CMakeLists.txt + create mode 100644 src/tools/CMakeLists.txt + create mode 100644 src/web/CMakeLists.txt + +diff --git a/.gitignore b/.gitignore +index 46f6fb9f5..3b1d44dc8 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -45,6 +45,7 @@ Thumbs.db + *.vcproj* + *.ncb + *.pro.user ++*.txt.user + *.idb + .project + .settings +diff --git a/CMakeLists.txt b/CMakeLists.txt +new file mode 100644 +index 000000000..65b487911 +--- /dev/null ++++ b/CMakeLists.txt +@@ -0,0 +1,234 @@ ++cmake_minimum_required(VERSION 3.16) ++ ++# ========================================================================== ++# OpenBoard cmake build file ++# ++# Configuration variables: ++# CMAKE_INSTALL_PREFIX ++# Path to install prefix, defaults to /usr/local (see cmake documentation) ++# Typically set to /usr or /opt ++# SYSCONF_INSTALL_DIR ++# Path to config file prefix ++# Typically set to /etc, defaults to /opt/openboard/etc if CMAKE_INSTALL_PREFIX is /opt ++# QT_VERSION ++# Qt Version to use ++# Set to 5 or 6, defaults to 5 ++# ++# Typical invocation ++# cmake -S -B -DCMAKE_INSTALL_PREFIX:PATH=/usr -DSYSCONF_INSTALL_DIR:PATH=/etc ++# or ++# cmake -S -B -DCMAKE_INSTALL_PREFIX:PATH=/opt ++# ++# Build and install ++# cmake --build . [-j] ++# DESTDIR= cmake --install . ++# ========================================================================== ++ ++# ========================================================================== ++# Basic project information ++# ++# The project will now be named all lowercase on all platforms ++# ========================================================================== ++ ++project(openboard VERSION 1.7.0 LANGUAGES CXX) ++ ++set(VERSION_TYPE a) # a = alpha, b = beta, rc = release candidate, r = release, other => error ++set(VERSION_BUILD 1027) ++ ++include(cmake/Version.cmake) ++include(cmake/Platform.cmake) ++ ++# ========================================================================== ++# Configuration options ++# ========================================================================== ++ ++set(QT_VERSION 5 CACHE STRING "Qt major version number to use - 5 or 6") ++ ++# Internal setting ++set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication - do not change") ++ ++ ++# ========================================================================== ++# Non-source file locations ++# ========================================================================== ++ ++set(OPENBOARD_QRC_FILE resources/OpenBoard.qrc) ++ ++set(OPENBOARD_FORMS_DIR resources/forms src/web/simplebrowser) ++set(OPENBOARD_TS_DIR resources/i18n) ++set(OPENBOARD_FONT_DIR resources/customizations resources/fonts) ++set(OPENBOARD_ETC_DIR resources/etc) ++set(OPENBOARD_LIBRARY_DIR resources/library) ++set(OPENBOARD_TEMPLATE_DIR resources/template) ++ ++set(OPENBOARD_ICON_FILE resources/images/ch.openboard.OpenBoard.svg) ++ ++if(LINUX) ++ set(OPENBOARD_DESKTOP_FILE resources/linux/ch.openboard.OpenBoard.desktop) ++ set(OPENBOARD_MIMETYPE_FILE resources/linux/ch.openboard.openboard-ubz.xml) ++ set(OPENBOARD_MIMEICON_FILE resources/linux/ch.openboard.application-ubz.svg) ++endif() ++ ++ ++# ========================================================================== ++# Basic compiler settings ++# ========================================================================== ++ ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTOUIC ON) ++ ++list(APPEND CMAKE_AUTOUIC_SEARCH_PATHS ++ ${OPENBOARD_FORMS_DIR} ++) ++ ++# OpenMP support ++include(FindOpenMP) ++ ++if(OPENMP_FOUND) ++ string(APPEND CMAKE_CXX_FLAGS " " ${OpenMP_CXX_FLAGS}) ++endif() ++ ++ ++# ========================================================================== ++# Target and dependencies ++# ++# Note: the executable is using lowercase on all platforms ++# ========================================================================== ++ ++add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE) ++ ++# manage dependencies ++include(cmake/DependencyQt.cmake) ++include(cmake/DependencyOpenSSL.cmake) ++include(cmake/DependencyPoppler.cmake) ++include(cmake/DependencyZlib.cmake) ++ ++if(LINUX) ++ include(cmake/DependencyQuaZip.cmake) ++ include(cmake/DependencyFFmpeg.cmake) ++ include(cmake/DependencyX11.cmake) ++elseif(WIN32) ++ include(cmake/FetchContentFreetype.cmake) ++ include(cmake/FetchContentQuaZip.cmake) ++elseif(MACOS) ++# TODO ++endif() ++ ++# add source path to include directories ++target_include_directories(${PROJECT_NAME} PRIVATE ++ src ++) ++ ++# add sources from subdirectories ++add_subdirectory(src/adaptors) ++add_subdirectory(src/api) ++add_subdirectory(src/board) ++add_subdirectory(src/core) ++add_subdirectory(src/desktop) ++add_subdirectory(src/document) ++add_subdirectory(src/domain) ++add_subdirectory(src/frameworks) ++add_subdirectory(src/globals) ++add_subdirectory(src/gui) ++add_subdirectory(src/network) ++add_subdirectory(src/pdf) ++add_subdirectory(src/pdf-merger) ++add_subdirectory(src/podcast) ++add_subdirectory(src/singleapplication) ++add_subdirectory(src/tools) ++add_subdirectory(src/web) ++add_subdirectory(plugins/cffadaptor/src) ++add_subdirectory(resources/forms) ++ ++# statically link singleapplication ++target_link_libraries(${PROJECT_NAME} ++ SingleApplication::SingleApplication ++) ++ ++# platform specific framework definitions and libraries ++if(WIN32) ++ target_link_libraries(${PROJECT_NAME} ++ User32 ++ Gdi32 ++ AdvApi32 ++ Ole32 ++ ) ++elseif(MACOS) ++ target_compile_definitions(${PROJECT_NAME} PRIVATE ++ Q_WS_MACX ++ ) ++ ++ target_link_libraries(${PROJECT_NAME} ++ "-framework AVFoundation" ++ "-framework Carbon" ++ "-framework Cocoa" ++ "-framework CoreMedia" ++ "-framework Foundation" ++ ) ++endif() ++ ++ ++# ========================================================================== ++# Resources ++# ========================================================================== ++ ++qt_add_resources(OPENBOARD_RESOURCES ${OPENBOARD_QRC_FILE}) ++target_sources(${PROJECT_NAME} PRIVATE ${OPENBOARD_RESOURCES}) ++ ++ ++# ========================================================================== ++# Translations ++# ========================================================================== ++ ++file(GLOB OPENBOARD_TS_FILES ${OPENBOARD_TS_DIR}/*.ts) ++set_source_files_properties(${OPENBOARD_TS_FILES} PROPERTIES OUTPUT_LOCATION ${PROJECT_BINARY_DIR}/i18n) ++qt_add_translation(QM_FILES ${OPENBOARD_TS_FILES}) ++target_sources(${PROJECT_NAME} PRIVATE ${QM_FILES}) ++ ++ ++# ========================================================================== ++# Installation ++# ========================================================================== ++ ++if(LINUX) ++ include(GNUInstallDirs) ++ ++ # set relative install paths ++ if(CMAKE_INSTALL_PREFIX STREQUAL "/opt") ++ set(OPENBOARD_INSTALL_SYSCONFDIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/etc) ++ set(OPENBOARD_INSTALL_DATADIR ${PROJECT_NAME}) ++ set(CMAKE_INSTALL_BINDIR "/usr/bin") ++ set(CMAKE_INSTALL_DATAROOTDIR "/usr/share") ++ else() ++ set(SYSCONF_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR} CACHE PATH ++ "Install directory for system-wide configuration files") ++ set(OPENBOARD_INSTALL_SYSCONFDIR ${SYSCONF_INSTALL_DIR}/${PROJECT_NAME}) ++ set(OPENBOARD_INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}) ++ endif() ++ ++ # set absolute install paths ++ set(OPENBOARD_ETC_PREFIX "${OPENBOARD_INSTALL_SYSCONFDIR}") ++ set(OPENBOARD_APP_PREFIX "${CMAKE_INSTALL_PREFIX}/${OPENBOARD_INSTALL_DATADIR}") ++ ++ message(STATUS "OpenBoard ETC_PREFIX is " ${OPENBOARD_ETC_PREFIX}) ++ message(STATUS "OpenBoard APP_PREFIX is " ${OPENBOARD_APP_PREFIX}) ++ ++ target_compile_definitions(${PROJECT_NAME} PRIVATE ++ ETC_PREFIX="${OPENBOARD_ETC_PREFIX}" ++ APP_PREFIX="${OPENBOARD_APP_PREFIX}" ++ ) ++ ++ # install files ++ install(TARGETS ${PROJECT_NAME} RUNTIME) ++ install(DIRECTORY ${OPENBOARD_FONT_DIR} DESTINATION ${OPENBOARD_INSTALL_DATADIR}) ++ install(DIRECTORY ${OPENBOARD_ETC_DIR}/ DESTINATION ${OPENBOARD_INSTALL_SYSCONFDIR}) ++ install(DIRECTORY ${OPENBOARD_LIBRARY_DIR} DESTINATION ${OPENBOARD_INSTALL_DATADIR}) ++ install(DIRECTORY ${OPENBOARD_TEMPLATE_DIR} DESTINATION ${OPENBOARD_INSTALL_DATADIR}) ++ install(DIRECTORY ${PROJECT_BINARY_DIR}/i18n DESTINATION ${OPENBOARD_INSTALL_DATADIR}) ++ install(FILES ${OPENBOARD_ICON_FILE} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps) ++ install(FILES ${OPENBOARD_DESKTOP_FILE} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) ++ install(FILES ${OPENBOARD_MIMETYPE_FILE} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages) ++ install(FILES ${OPENBOARD_MIMEICON_FILE} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/mimetypes) ++endif() +diff --git a/cmake/DependencyFFmpeg.cmake b/cmake/DependencyFFmpeg.cmake +new file mode 100644 +index 000000000..c652432e0 +--- /dev/null ++++ b/cmake/DependencyFFmpeg.cmake +@@ -0,0 +1,12 @@ ++# Find FFmpeg ++# ++# FFmpeg only supports PkgConfig ++ ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(FFmpeg REQUIRED IMPORTED_TARGET libavcodec libavformat libavutil libswresample libswscale) ++ ++if (FFmpeg_FOUND) ++ target_link_libraries(${PROJECT_NAME} ++ PkgConfig::FFmpeg ++ ) ++endif() +diff --git a/cmake/DependencyOpenSSL.cmake b/cmake/DependencyOpenSSL.cmake +new file mode 100644 +index 000000000..e10ba1672 +--- /dev/null ++++ b/cmake/DependencyOpenSSL.cmake +@@ -0,0 +1,7 @@ ++# Find OpenSSL ++ ++find_package(OpenSSL 1.1 REQUIRED) ++ ++target_link_libraries(${PROJECT_NAME} ++ OpenSSL::Crypto ++) +diff --git a/cmake/DependencyPoppler.cmake b/cmake/DependencyPoppler.cmake +new file mode 100644 +index 000000000..b25d4af20 +--- /dev/null ++++ b/cmake/DependencyPoppler.cmake +@@ -0,0 +1,20 @@ ++# Find poppler ++ ++find_package(Poppler QUIET COMPONENTS Core Cpp) ++ ++if (Poppler_FOUND) ++ target_link_libraries(${PROJECT_NAME} ++ Poppler::Core ++ Poppler::Cpp ++ ) ++else() ++ find_package(PkgConfig REQUIRED) ++ pkg_check_modules(Poppler REQUIRED IMPORTED_TARGET poppler poppler-cpp) ++ ++ if (Poppler_FOUND) ++ target_link_libraries(${PROJECT_NAME} ++ PkgConfig::Poppler ++ ) ++ endif() ++ ++endif() +diff --git a/cmake/DependencyQt.cmake b/cmake/DependencyQt.cmake +new file mode 100644 +index 000000000..d8d0a1339 +--- /dev/null ++++ b/cmake/DependencyQt.cmake +@@ -0,0 +1,39 @@ ++# Find supported Qt version ++ ++set(QT_COMPONENTS ++ Concurrent ++ DBus ++ Multimedia ++ MultimediaWidgets ++ Network ++ PrintSupport ++ Svg ++ UiTools ++ WebEngineWidgets ++ Xml ++) ++ ++if(QT_VERSION STREQUAL "5") ++ find_package(Qt5 5.12 REQUIRED COMPONENTS ++ ${QT_COMPONENTS} ++ LinguistTools ++ ) ++elseif(QT_VERSION STREQUAL "6") ++ find_package(Qt6 6.2 REQUIRED COMPONENTS ++ ${QT_COMPONENTS} ++ SvgWidgets ++ LinguistTools ++ ) ++ ++ target_link_libraries(${PROJECT_NAME} ++ Qt6::SvgWidgets ++ ) ++else() ++ message(FATAL_ERROR "Qt Version ${QT_VERSION} not supported") ++endif() ++ ++list(TRANSFORM QT_COMPONENTS PREPEND Qt::) ++ ++target_link_libraries(${PROJECT_NAME} ++ ${QT_COMPONENTS} ++) +diff --git a/cmake/DependencyQuaZip.cmake b/cmake/DependencyQuaZip.cmake +new file mode 100644 +index 000000000..bd37bac5e +--- /dev/null ++++ b/cmake/DependencyQuaZip.cmake +@@ -0,0 +1,43 @@ ++# Find QuaZip ++ ++find_package(QuaZip-Qt${QT_VERSION} 1.0 QUIET) ++ ++if(QuaZip-Qt${QT_VERSION}_FOUND) ++ target_link_libraries(openboard ++ QuaZip::QuaZip ++ ) ++else() ++ # Try to find the package using pkg-config with several names ++ find_package(PkgConfig REQUIRED) ++ ++ pkg_check_modules(QuaZip QUIET IMPORTED_TARGET quazip-qt${QT_VERSION}) ++ ++ if(NOT QuaZip_FOUND) ++ pkg_check_modules(QuaZip QUIET IMPORTED_TARGET quazip1-qt${QT_VERSION}) ++ endif() ++ ++ if(NOT QuaZip_FOUND) ++ pkg_check_modules(QuaZip QUIET IMPORTED_TARGET libquazip${QT_VERSION}-1) ++ endif() ++ ++ if(NOT QuaZip_FOUND) ++ pkg_check_modules(QuaZip QUIET IMPORTED_TARGET quazip${QT_VERSION}) ++ endif() ++ ++ if(QuaZip_FOUND) ++ message(STATUS "Found QuaZip version " ${QuaZip_VERSION}) ++ target_link_libraries(${PROJECT_NAME} ++ PkgConfig::QuaZip ++ ) ++ else() ++ # Just assume default directories of QuaZip < 1.0 ++ message(STATUS "QuaZip not found, assuming default include directory " /usr/include/quazip${QT_VERSION}) ++ target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ++ /usr/include/quazip${QT_VERSION} ++ ) ++ target_link_libraries(${PROJECT_NAME} ++ quazip${QT_VERSION} ++ ) ++ endif() ++endif() ++ +diff --git a/cmake/DependencyX11.cmake b/cmake/DependencyX11.cmake +new file mode 100644 +index 000000000..f630160b7 +--- /dev/null ++++ b/cmake/DependencyX11.cmake +@@ -0,0 +1,18 @@ ++# Find FFmpeg ++ ++find_package(X11 QUIET) ++ ++if (X11_FOUND) ++ target_link_libraries(${PROJECT_NAME} ++ X11 ++ ) ++else() ++ find_package(PkgConfig REQUIRED) ++ pkg_check_modules(X11 REQUIRED x11) ++ ++ if (X11_FOUND) ++ target_link_libraries(${PROJECT_NAME} ++ PkgConfig::X11 ++ ) ++ endif() ++endif() +diff --git a/cmake/DependencyZlib.cmake b/cmake/DependencyZlib.cmake +new file mode 100644 +index 000000000..d3e8fb651 +--- /dev/null ++++ b/cmake/DependencyZlib.cmake +@@ -0,0 +1,6 @@ ++# Find zlib ++ ++find_package(ZLIB REQUIRED) ++target_link_libraries(${PROJECT_NAME} ++ z ++) +diff --git a/cmake/FetchContentFreetype.cmake b/cmake/FetchContentFreetype.cmake +new file mode 100644 +index 000000000..2aa5e318e +--- /dev/null ++++ b/cmake/FetchContentFreetype.cmake +@@ -0,0 +1,13 @@ ++# Fetch Freetype ++ ++include(FetchContent) ++ ++FetchContent_Declare( ++ Freetype ++ GIT_REPOSITORY https://gitlab.freedesktop.org/freetype/freetype.git ++ GIT_TAG VER-2-12-1 ++) ++ ++FetchContent_MakeAvailable( ++ Freetype ++) +diff --git a/cmake/FetchContentPoppler.cmake b/cmake/FetchContentPoppler.cmake +new file mode 100644 +index 000000000..74097bcf6 +--- /dev/null ++++ b/cmake/FetchContentPoppler.cmake +@@ -0,0 +1,18 @@ ++# Fetch libpoppler ++ ++include(FetchContent) ++ ++FetchContent_Declare( ++ Poppler ++ GIT_REPOSITORY https://gitlab.freedesktop.org/poppler/poppler.git ++ GIT_TAG poppler-22.08.0 ++) ++ ++FetchContent_MakeAvailable( ++ Poppler ++) ++ ++target_link_libraries(${PROJECT_NAME} ++ Poppler::Core ++ Poppler::Cpp ++) +diff --git a/cmake/FetchContentQuaZip.cmake b/cmake/FetchContentQuaZip.cmake +new file mode 100644 +index 000000000..fe529b1b7 +--- /dev/null ++++ b/cmake/FetchContentQuaZip.cmake +@@ -0,0 +1,23 @@ ++# Fetch QuaZip ++ ++include(FetchContent) ++ ++if(QT_VERSION STREQUAL "5") ++ set(QUAZIP_QT_MAJOR_VERSION 5 CACHE STRING "QuaZip Qt version") ++elseif(QT_VERSION STREQUAL "6") ++ set(QUAZIP_QT_MAJOR_VERSION 6) ++endif() ++ ++FetchContent_Declare( ++ QuaZip ++ GIT_REPOSITORY https://github.com/stachenov/quazip.git ++ GIT_TAG v1.3 ++) ++ ++FetchContent_MakeAvailable( ++ QuaZip ++) ++ ++target_link_libraries(${PROJECT_NAME} ++ QuaZip::QuaZip ++) +diff --git a/cmake/FetchContentXpdf.cmake b/cmake/FetchContentXpdf.cmake +new file mode 100644 +index 000000000..6a05b2110 +--- /dev/null ++++ b/cmake/FetchContentXpdf.cmake +@@ -0,0 +1,28 @@ ++# Fetch xpdf ++ ++include(FetchContent) ++ ++if(QT_VERSION STREQUAL "5") ++ set(CMAKE_DISABLE_FIND_PACKAGE_Qt6Widgets TRUE) ++ set(CMAKE_DISABLE_FIND_PACKAGE_Qt4Widgets TRUE) ++elseif(QT_VERSION STREQUAL "6") ++ set(CMAKE_DISABLE_FIND_PACKAGE_Qt5Widgets TRUE) ++ set(CMAKE_DISABLE_FIND_PACKAGE_Qt4Widgets TRUE) ++endif() ++ ++set(CMAKE_POLICY_DEFAULT_CMP0048 NEW) ++ ++FetchContent_Declare( ++ Xpdf ++ URL https://dl.xpdfreader.com/xpdf-4.04.tar.gz ++) ++ ++FetchContent_MakeAvailable( ++ Xpdf ++) ++# this does not work. Xpdf does not build a library for reuse, it only builds executable tools ++target_link_libraries(${PROJECT_NAME} ++ goo ++ fofi ++ splash ++) +diff --git a/cmake/Platform.cmake b/cmake/Platform.cmake +new file mode 100644 +index 000000000..4085b3d5c +--- /dev/null ++++ b/cmake/Platform.cmake +@@ -0,0 +1,16 @@ ++# ++# Define LINUX and MACOS platform specifiers ++# Set platform specific variables ++# ++ ++if(UNIX) ++ if(APPLE) ++ set(MACOS 1) ++ else() ++ set(LINUX 1) ++ endif() ++endif() ++ ++if(MACOS) ++ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13) ++endif() +diff --git a/cmake/Version.cmake b/cmake/Version.cmake +new file mode 100644 +index 000000000..08292aed6 +--- /dev/null ++++ b/cmake/Version.cmake +@@ -0,0 +1,23 @@ ++# ++# Version ++# ++ ++set(VERSION "${${PROJECT_NAME}_VERSION}-${VERSION_TYPE}.${VERSION_BUILD}") ++ ++if(VERSION_TYPE STREQUAL "r") ++ set(VERSION "${${PROJECT_NAME}_VERSION}") ++endif() ++ ++if(WIN32) ++ set(VERSION_RC "${${PROJECT_NAME}_VERSION_MAJOR},${${PROJECT_NAME}_VERSION_MINOR},${${PROJECT_NAME}_VERSION_PATCH},${VERSION_TYPE},${VERSION_BUILD}") ++else() ++ set(VERSION_RC "${${PROJECT_NAME}_VERSION_MAJOR},${${PROJECT_NAME}_VERSION_MINOR},${${PROJECT_NAME}_VERSION_PATCH},${VERSION_TYPE}") ++endif() ++ ++string(REPLACE "a" "160" VERSION_RC ${VERSION_RC}) # 0xA0 ++string(REPLACE "b" "176" VERSION_RC ${VERSION_RC}) # 0xB0 ++string(REPLACE "rc" "192" VERSION_RC ${VERSION_RC}) # 0xC0 ++string(REPLACE "r" "240" VERSION_RC ${VERSION_RC}) # 0xF0 ++ ++add_compile_definitions(UBVERSION="${VERSION}") ++add_compile_definitions(UBVERSION_RC=${VERSION_RC}) +diff --git a/plugins/cffadaptor/src/CMakeLists.txt b/plugins/cffadaptor/src/CMakeLists.txt +new file mode 100644 +index 000000000..6109d8fb2 +--- /dev/null ++++ b/plugins/cffadaptor/src/CMakeLists.txt +@@ -0,0 +1,7 @@ ++target_sources(openboard PRIVATE ++ UBCFFAdaptor.cpp ++) ++ ++target_include_directories(${PROJECT_NAME} PRIVATE ++ . ++) +diff --git a/resources/forms/CMakeLists.txt b/resources/forms/CMakeLists.txt +new file mode 100644 +index 000000000..554b52e93 +--- /dev/null ++++ b/resources/forms/CMakeLists.txt +@@ -0,0 +1,13 @@ ++qt_add_resources(${PROJECT_NAME} ++ blackoutWidget.ui ++ brushProperties.ui ++ capturePublishing.ui ++ CMakeLists.txt ++ documents.ui ++ intranetPodcastPublishingDialog.ui ++ mainWindow.ui ++ preferences.ui ++ preferences.ui.autosave ++ trapFlash.ui ++ youTubePublishingDialog.ui ++) +diff --git a/resources/images/ch.openboard.OpenBoard.svg b/resources/images/ch.openboard.OpenBoard.svg +new file mode 100644 +index 000000000..4eecaaa2b +--- /dev/null ++++ b/resources/images/ch.openboard.OpenBoard.svg +@@ -0,0 +1,4 @@ ++ ++ ++ ++ +diff --git a/resources/linux/ch.openboard.OpenBoard.desktop b/resources/linux/ch.openboard.OpenBoard.desktop +new file mode 100644 +index 000000000..f7da8c44d +--- /dev/null ++++ b/resources/linux/ch.openboard.OpenBoard.desktop +@@ -0,0 +1,11 @@ ++[Desktop Entry] ++Encoding=UTF-8 ++Name=OpenBoard ++Comment=OpenBoard, an interactive white board application ++Exec=openboard %f ++Icon=ch.openboard.OpenBoard ++StartupNotify=true ++Terminal=false ++Type=Application ++MimeType=application/ubz ++Categories=Education; +diff --git a/resources/linux/ch.openboard.application-ubz.svg b/resources/linux/ch.openboard.application-ubz.svg +new file mode 100644 +index 000000000..0320a2c88 +--- /dev/null ++++ b/resources/linux/ch.openboard.application-ubz.svg +@@ -0,0 +1,36 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/resources/linux/ch.openboard.openboard-ubz.xml b/resources/linux/ch.openboard.openboard-ubz.xml +new file mode 100644 +index 000000000..aaa7feaf8 +--- /dev/null ++++ b/resources/linux/ch.openboard.openboard-ubz.xml +@@ -0,0 +1,10 @@ ++ ++ ++ ++ ++ OpenBoard document file ++ Document OpenBoard ++ OpenBoard Dokument ++ ++ ++ +diff --git a/resources/etc/asyncAPI.js b/resources/template/asyncAPI.js +similarity index 100% +rename from resources/etc/asyncAPI.js +rename to resources/template/asyncAPI.js +diff --git a/resources/etc/img/loading.gif b/resources/template/img/loading.gif +similarity index 100% +rename from resources/etc/img/loading.gif +rename to resources/template/img/loading.gif +diff --git a/resources/etc/intranet-podcast-metadata.template b/resources/template/intranet-podcast-metadata.template +similarity index 100% +rename from resources/etc/intranet-podcast-metadata.template +rename to resources/template/intranet-podcast-metadata.template +diff --git a/resources/etc/npapi-wrapper.application.x-shockwave-flash.swf.htm b/resources/template/npapi-wrapper.application.x-shockwave-flash.swf.htm +similarity index 100% +rename from resources/etc/npapi-wrapper.application.x-shockwave-flash.swf.htm +rename to resources/template/npapi-wrapper.application.x-shockwave-flash.swf.htm +diff --git a/resources/etc/npapi-wrapper.config.xml b/resources/template/npapi-wrapper.config.xml +similarity index 100% +rename from resources/etc/npapi-wrapper.config.xml +rename to resources/template/npapi-wrapper.config.xml +diff --git a/src/adaptors/CMakeLists.txt b/src/adaptors/CMakeLists.txt +new file mode 100644 +index 000000000..ef91e1096 +--- /dev/null ++++ b/src/adaptors/CMakeLists.txt +@@ -0,0 +1,38 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBCFFSubsetAdaptor.cpp ++ UBCFFSubsetAdaptor.h ++ UBExportAdaptor.cpp ++ UBExportAdaptor.h ++ UBExportCFF.cpp ++ UBExportCFF.h ++ UBExportDocument.cpp ++ UBExportDocument.h ++ UBExportDocumentSetAdaptor.cpp ++ UBExportDocumentSetAdaptor.h ++ UBExportFullPDF.cpp ++ UBExportFullPDF.h ++ UBExportPDF.cpp ++ UBExportPDF.h ++ UBExportWeb.cpp ++ UBExportWeb.h ++ UBImportAdaptor.cpp ++ UBImportAdaptor.h ++ UBImportCFF.cpp ++ UBImportCFF.h ++ UBImportDocument.cpp ++ UBImportDocument.h ++ UBImportDocumentSetAdaptor.cpp ++ UBImportDocumentSetAdaptor.h ++ UBImportImage.cpp ++ UBImportImage.h ++ UBImportPDF.cpp ++ UBImportPDF.h ++ UBMetadataDcSubsetAdaptor.cpp ++ UBMetadataDcSubsetAdaptor.h ++ UBSvgSubsetAdaptor.cpp ++ UBSvgSubsetAdaptor.h ++ UBThumbnailAdaptor.cpp ++ UBThumbnailAdaptor.h ++ UBWidgetUpgradeAdaptor.cpp ++ UBWidgetUpgradeAdaptor.h ++) +diff --git a/src/adaptors/UBWidgetUpgradeAdaptor.cpp b/src/adaptors/UBWidgetUpgradeAdaptor.cpp +index 503897c15..cb9c98f18 100644 +--- a/src/adaptors/UBWidgetUpgradeAdaptor.cpp ++++ b/src/adaptors/UBWidgetUpgradeAdaptor.cpp +@@ -206,7 +206,7 @@ UBWidgetUpgradeAdaptor::Widget::Widget(const QString &dir) : m_path(dir), m_hasU + + if (widgetHashes.empty()) + { +- QFile widgetsMd5sum(UBPlatformUtils::applicationResourcesDirectory() + "/etc/widgets.md5sum"); ++ QFile widgetsMd5sum(UBPlatformUtils::applicationEtcDirectory() + "/widgets.md5sum"); + + if (widgetsMd5sum.open(QIODevice::ReadOnly)) + { +diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt +new file mode 100644 +index 000000000..0e2636097 +--- /dev/null ++++ b/src/api/CMakeLists.txt +@@ -0,0 +1,8 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBW3CWidgetAPI.cpp ++ UBW3CWidgetAPI.h ++ UBWidgetMessageAPI.cpp ++ UBWidgetMessageAPI.h ++ UBWidgetUniboardAPI.cpp ++ UBWidgetUniboardAPI.h ++) +diff --git a/src/board/CMakeLists.txt b/src/board/CMakeLists.txt +new file mode 100644 +index 000000000..8e20f849e +--- /dev/null ++++ b/src/board/CMakeLists.txt +@@ -0,0 +1,12 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBBoardController.cpp ++ UBBoardController.h ++ UBBoardPaletteManager.cpp ++ UBBoardPaletteManager.h ++ UBBoardView.cpp ++ UBBoardView.h ++ UBDrawingController.cpp ++ UBDrawingController.h ++ UBFeaturesController.cpp ++ UBFeaturesController.h ++) +diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt +new file mode 100644 +index 000000000..eda1052a9 +--- /dev/null ++++ b/src/core/CMakeLists.txt +@@ -0,0 +1,38 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ main.cpp ++ UB.h ++ UBApplication.cpp ++ UBApplication.h ++ UBApplicationController.cpp ++ UBApplicationController.h ++ UBDisplayManager.cpp ++ UBDisplayManager.h ++ UBDocumentManager.cpp ++ UBDocumentManager.h ++ UBDownloadManager.cpp ++ UBDownloadManager.h ++ UBDownloadThread.cpp ++ UBDownloadThread.h ++ UBForeignObjectsHandler.cpp ++ UBForeignObjectsHandler.h ++ UBIdleTimer.cpp ++ UBIdleTimer.h ++ UBMimeData.cpp ++ UBMimeData.h ++ UBOpenSankoreImporter.cpp ++ UBOpenSankoreImporter.h ++ UBPersistenceManager.cpp ++ UBPersistenceManager.h ++ UBPersistenceWorker.cpp ++ UBPersistenceWorker.h ++ UBPreferencesController.cpp ++ UBPreferencesController.h ++ UBSceneCache.cpp ++ UBSceneCache.h ++ UBSetting.cpp ++ UBSetting.h ++ UBSettings.cpp ++ UBSettings.h ++ UBTextTools.cpp ++ UBTextTools.h ++) +diff --git a/src/core/UBApplication.cpp b/src/core/UBApplication.cpp +index c076241df..c1b0f6236 100644 +--- a/src/core/UBApplication.cpp ++++ b/src/core/UBApplication.cpp +@@ -139,7 +139,7 @@ UBApplication::UBApplication(const QString &id, int &argc, char **argv) : Single + + setStyle("fusion"); + +- QString css = UBFileSystemUtils::readTextFile(UBPlatformUtils::applicationResourcesDirectory() + "/etc/"+ qApp->applicationName()+".css"); ++ QString css = UBFileSystemUtils::readTextFile(UBPlatformUtils::applicationEtcDirectory() + "/"+ qApp->applicationName()+".css"); + if (css.length() > 0) + setStyleSheet(css); + +diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp +index 9a7a6f691..c07c9b7a1 100644 +--- a/src/core/UBSettings.cpp ++++ b/src/core/UBSettings.cpp +@@ -158,7 +158,7 @@ QSettings* UBSettings::getAppSettings() + if (!UBSettings::sAppSettings) + { + QString tmpSettings = QDir::tempPath() + "/" + qApp->applicationName() + ".config"; +- QString appSettings = UBPlatformUtils::applicationResourcesDirectory() + "/etc/" + qApp->applicationName() + ".config"; ++ QString appSettings = UBPlatformUtils::applicationEtcDirectory() + "/" + qApp->applicationName() + ".config"; + + // tmpSettings exists when upgrading Uniboard on Mac (see UBPlatformUtils_mac.mm updater:willInstallUpdate:) + if (QFile::exists(tmpSettings)) +diff --git a/src/desktop/CMakeLists.txt b/src/desktop/CMakeLists.txt +new file mode 100644 +index 000000000..6721aca8a +--- /dev/null ++++ b/src/desktop/CMakeLists.txt +@@ -0,0 +1,10 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBCustomCaptureWindow.cpp ++ UBCustomCaptureWindow.h ++ UBDesktopAnnotationController.cpp ++ UBDesktopAnnotationController.h ++ UBDesktopPalette.cpp ++ UBDesktopPalette.h ++ UBDesktopPropertyPalette.cpp ++ UBDesktopPropertyPalette.h ++) +diff --git a/src/document/CMakeLists.txt b/src/document/CMakeLists.txt +new file mode 100644 +index 000000000..01211a908 +--- /dev/null ++++ b/src/document/CMakeLists.txt +@@ -0,0 +1,10 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBDocumentContainer.cpp ++ UBDocumentContainer.h ++ UBDocumentController.cpp ++ UBDocumentController.h ++ UBDocumentProxy.cpp ++ UBDocumentProxy.h ++ UBSortFilterProxyModel.cpp ++ UBSortFilterProxyModel.h ++) +diff --git a/src/domain/CMakeLists.txt b/src/domain/CMakeLists.txt +new file mode 100644 +index 000000000..15bcab6b5 +--- /dev/null ++++ b/src/domain/CMakeLists.txt +@@ -0,0 +1,58 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBGraphicsDelegateFrame.cpp ++ UBGraphicsDelegateFrame.h ++ UBGraphicsGroupContainerItem.cpp ++ UBGraphicsGroupContainerItem.h ++ UBGraphicsGroupContainerItemDelegate.cpp ++ UBGraphicsGroupContainerItemDelegate.h ++ UBGraphicsItemDelegate.cpp ++ UBGraphicsItemDelegate.h ++ UBGraphicsItemGroupUndoCommand.cpp ++ UBGraphicsItemGroupUndoCommand.h ++ UBGraphicsItemTransformUndoCommand.cpp ++ UBGraphicsItemTransformUndoCommand.h ++ UBGraphicsItemUndoCommand.cpp ++ UBGraphicsItemUndoCommand.h ++ UBGraphicsItemZLevelUndoCommand.cpp ++ UBGraphicsItemZLevelUndoCommand.h ++ UBGraphicsMediaItem.cpp ++ UBGraphicsMediaItem.h ++ UBGraphicsMediaItemDelegate.cpp ++ UBGraphicsMediaItemDelegate.h ++ UBGraphicsPDFItem.cpp ++ UBGraphicsPDFItem.h ++ UBGraphicsPixmapItem.cpp ++ UBGraphicsPixmapItem.h ++ UBGraphicsPolygonItem.cpp ++ UBGraphicsPolygonItem.h ++ UBGraphicsScene.cpp ++ UBGraphicsScene.h ++ UBGraphicsStroke.cpp ++ UBGraphicsStroke.h ++ UBGraphicsStrokesGroup.cpp ++ UBGraphicsStrokesGroup.h ++ UBGraphicsSvgItem.cpp ++ UBGraphicsSvgItem.h ++ UBGraphicsTextItem.cpp ++ UBGraphicsTextItem.h ++ UBGraphicsTextItemDelegate.cpp ++ UBGraphicsTextItemDelegate.h ++ UBGraphicsTextItemUndoCommand.cpp ++ UBGraphicsTextItemUndoCommand.h ++ UBGraphicsWidgetItem.cpp ++ UBGraphicsWidgetItem.h ++ UBGraphicsWidgetItemDelegate.cpp ++ UBGraphicsWidgetItemDelegate.h ++ UBItem.cpp ++ UBItem.h ++ UBPageSizeUndoCommand.cpp ++ UBPageSizeUndoCommand.h ++ UBResizableGraphicsItem.cpp ++ UBResizableGraphicsItem.h ++ UBSelectionFrame.cpp ++ UBSelectionFrame.h ++ UBUndoCommand.cpp ++ UBUndoCommand.h ++ UBWebEngineView.cpp ++ UBWebEngineView.h ++) +diff --git a/src/domain/UBGraphicsWidgetItem.cpp b/src/domain/UBGraphicsWidgetItem.cpp +index 2ecad9587..53c01e9c8 100644 +--- a/src/domain/UBGraphicsWidgetItem.cpp ++++ b/src/domain/UBGraphicsWidgetItem.cpp +@@ -1279,14 +1279,14 @@ void UBGraphicsW3CWidgetItem::loadNPAPIWrappersTemplates() + if (!sTemplateLoaded) { + sNPAPIWrapperTemplates.clear(); + +- QString etcPath = UBPlatformUtils::applicationResourcesDirectory() + "/etc/"; ++ QString templatePath = UBPlatformUtils::applicationResourcesDirectory() + "/template/"; + +- QDir etcDir(etcPath); ++ QDir templateDir(templatePath); + +- foreach(QString fileName, etcDir.entryList()) { ++ foreach(QString fileName, templateDir.entryList()) { + if (fileName.startsWith("npapi-wrapper") && (fileName.endsWith(".htm") || fileName.endsWith(".html"))) { + +- QString htmlContent = UBFileSystemUtils::readTextFile(etcPath + fileName); ++ QString htmlContent = UBFileSystemUtils::readTextFile(templatePath + fileName); + + if (htmlContent.length() > 0) { + QStringList tokens = fileName.split("."); +@@ -1303,7 +1303,7 @@ void UBGraphicsW3CWidgetItem::loadNPAPIWrappersTemplates() + } + } + } +- sNPAPIWrappperConfigTemplate = UBFileSystemUtils::readTextFile(etcPath + "npapi-wrapper.config.xml"); ++ sNPAPIWrappperConfigTemplate = UBFileSystemUtils::readTextFile(templatePath + "npapi-wrapper.config.xml"); + sTemplateLoaded = true; + } + } +diff --git a/src/frameworks/CMakeLists.txt b/src/frameworks/CMakeLists.txt +new file mode 100644 +index 000000000..3bb0d7766 +--- /dev/null ++++ b/src/frameworks/CMakeLists.txt +@@ -0,0 +1,32 @@ ++target_sources(openboard PRIVATE ++ UBBase32.cpp ++ UBBase32.h ++ UBCoreGraphicsScene.cpp ++ UBCoreGraphicsScene.h ++ UBCryptoUtils.cpp ++ UBCryptoUtils.h ++ UBFileSystemUtils.cpp ++ UBFileSystemUtils.h ++ UBGeometryUtils.cpp ++ UBGeometryUtils.h ++ UBPlatformUtils.cpp ++ UBPlatformUtils.h ++ UBStringUtils.cpp ++ UBStringUtils.h ++ UBVersion.cpp ++ UBVersion.h ++) ++ ++if(LINUX) ++ target_sources(openboard PRIVATE ++ UBPlatformUtils_linux.cpp ++ ) ++elseif(WIN32) ++ target_sources(openboard PRIVATE ++ UBPlatformUtils_win.cpp ++ ) ++elseif(MACOS) ++ target_sources(openboard PRIVATE ++ UBPlatformUtils_mac.mm ++ ) ++endif() +diff --git a/src/frameworks/UBPlatformUtils.h b/src/frameworks/UBPlatformUtils.h +index da9fd1295..2c9515a5d 100644 +--- a/src/frameworks/UBPlatformUtils.h ++++ b/src/frameworks/UBPlatformUtils.h +@@ -191,6 +191,7 @@ class UBPlatformUtils + static void init(); + static void destroy(); + static QString applicationResourcesDirectory(); ++ static QString applicationEtcDirectory(); + static void hideFile(const QString &filePath); + static void setFileType(const QString &filePath, unsigned long fileType); + static void fadeDisplayOut(); +diff --git a/src/frameworks/UBPlatformUtils_linux.cpp b/src/frameworks/UBPlatformUtils_linux.cpp +index cff17b1d3..61a2d0aad 100644 +--- a/src/frameworks/UBPlatformUtils_linux.cpp ++++ b/src/frameworks/UBPlatformUtils_linux.cpp +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -50,7 +51,20 @@ void UBPlatformUtils::init() + + QString UBPlatformUtils::applicationResourcesDirectory() + { ++#ifdef APP_PREFIX ++ return QProcessEnvironment::systemEnvironment().value("APP_PREFIX", APP_PREFIX); ++#else + return QApplication::applicationDirPath(); ++#endif ++} ++ ++QString UBPlatformUtils::applicationEtcDirectory() ++{ ++#ifdef ETC_PREFIX ++ return QProcessEnvironment::systemEnvironment().value("ETC_PREFIX", ETC_PREFIX); ++#else ++ return applicationResourcesDirectory() + "/etc"; ++#endif + } + + void UBPlatformUtils::hideFile(const QString &filePath) +diff --git a/src/frameworks/UBPlatformUtils_mac.mm b/src/frameworks/UBPlatformUtils_mac.mm +index 4ecb705a6..14c6ed303 100644 +--- a/src/frameworks/UBPlatformUtils_mac.mm ++++ b/src/frameworks/UBPlatformUtils_mac.mm +@@ -123,6 +123,11 @@ OSStatus emptySetSystemUIMode ( + return path; + } + ++QString UBPlatformUtils::applicationEtcDirectory() ++{ ++ return applicationResourcesDirectory() + "/etc"; ++} ++ + void UBPlatformUtils::hideFile(const QString &filePath) + { + FSRef ref; +diff --git a/src/frameworks/UBPlatformUtils_win.cpp b/src/frameworks/UBPlatformUtils_win.cpp +index c85dafa75..bb6f4c68f 100644 +--- a/src/frameworks/UBPlatformUtils_win.cpp ++++ b/src/frameworks/UBPlatformUtils_win.cpp +@@ -51,6 +51,10 @@ QString UBPlatformUtils::applicationResourcesDirectory() + return QApplication::applicationDirPath(); + } + ++QString UBPlatformUtils::applicationEtcDirectory() ++{ ++ return applicationResourcesDirectory() + "/etc"; ++} + + void UBPlatformUtils::hideFile(const QString &filePath) + { +diff --git a/src/globals/CMakeLists.txt b/src/globals/CMakeLists.txt +new file mode 100644 +index 000000000..f49f865ec +--- /dev/null ++++ b/src/globals/CMakeLists.txt +@@ -0,0 +1,3 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBGlobals.h ++) +diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt +new file mode 100644 +index 000000000..524041d07 +--- /dev/null ++++ b/src/gui/CMakeLists.txt +@@ -0,0 +1,98 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBActionPalette.cpp ++ UBActionPalette.h ++ UBBackgroundPalette.cpp ++ UBBackgroundPalette.h ++ UBBlackoutWidget.cpp ++ UBBlackoutWidget.h ++ UBBoardThumbnailsView.cpp ++ UBBoardThumbnailsView.h ++ UBCachePropertiesWidget.cpp ++ UBCachePropertiesWidget.h ++ UBCircleFrame.cpp ++ UBCircleFrame.h ++ UBColorPicker.cpp ++ UBColorPicker.h ++ UBDockDownloadWidget.cpp ++ UBDockDownloadWidget.h ++ UBDockPalette.cpp ++ UBDockPalette.h ++ UBDockPaletteWidget.cpp ++ UBDockPaletteWidget.h ++ UBDocumentThumbnailWidget.cpp ++ UBDocumentThumbnailWidget.h ++ UBDocumentToolsPalette.cpp ++ UBDocumentToolsPalette.h ++ UBDownloadWidget.cpp ++ UBDownloadWidget.h ++ UBFavoriteToolPalette.cpp ++ UBFavoriteToolPalette.h ++ UBFeaturesActionBar.cpp ++ UBFeaturesActionBar.h ++ UBFeaturesWidget.cpp ++ UBFeaturesWidget.h ++ UBFloatingPalette.cpp ++ UBFloatingPalette.h ++ UBIconButton.cpp ++ UBIconButton.h ++ UBKeyboardPalette.cpp ++ UBKeyboardPalette.h ++ UBLeftPalette.cpp ++ UBLeftPalette.h ++ UBMagnifer.cpp ++ UBMagnifer.h ++ UBMainWindow.cpp ++ UBMainWindow.h ++ UBMessageWindow.cpp ++ UBMessageWindow.h ++ UBMessagesDialog.cpp ++ UBMessagesDialog.h ++ UBMousePressFilter.cpp ++ UBMousePressFilter.h ++ UBOpenSankoreImporterWidget.cpp ++ UBOpenSankoreImporterWidget.h ++ UBPageNavigationWidget.cpp ++ UBPageNavigationWidget.h ++ UBPropertyPalette.cpp ++ UBPropertyPalette.h ++ UBResources.cpp ++ UBResources.h ++ UBRightPalette.cpp ++ UBRightPalette.h ++ UBRubberBand.cpp ++ UBRubberBand.h ++ UBScreenMirror.cpp ++ UBScreenMirror.h ++ UBSpinningWheel.cpp ++ UBSpinningWheel.h ++ UBStartupHintsPalette.cpp ++ UBStartupHintsPalette.h ++ UBStylusPalette.cpp ++ UBStylusPalette.h ++ UBThumbnailView.cpp ++ UBThumbnailView.h ++ UBThumbnailWidget.cpp ++ UBThumbnailWidget.h ++ UBToolWidget.cpp ++ UBToolWidget.h ++ UBToolbarButtonGroup.cpp ++ UBToolbarButtonGroup.h ++ UBUpdateDlg.cpp ++ UBUpdateDlg.h ++ UBWebToolsPalette.cpp ++ UBWebToolsPalette.h ++ UBWidgetMirror.cpp ++ UBWidgetMirror.h ++ UBZoomPalette.cpp ++ UBZoomPalette.h ++) ++ ++if(LINUX) ++ target_sources(openboard PRIVATE ++ UBKeyboardPalette_linux.cpp ++ ) ++elseif(WIN32) ++ target_sources(openboard PRIVATE ++ UBKeyboardPalette_win.cpp ++ ) ++endif() +diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt +new file mode 100644 +index 000000000..c8a76aa13 +--- /dev/null ++++ b/src/network/CMakeLists.txt +@@ -0,0 +1,14 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBAutoSaver.cpp ++ UBAutoSaver.h ++ UBCookieJar.cpp ++ UBCookieJar.h ++ UBHttpFileDownloader.cpp ++ UBHttpFileDownloader.h ++ UBHttpGet.cpp ++ UBHttpGet.h ++ UBNetworkAccessManager.cpp ++ UBNetworkAccessManager.h ++ UBServerXMLHttpRequest.cpp ++ UBServerXMLHttpRequest.h ++) +diff --git a/src/pdf-merger/CMakeLists.txt b/src/pdf-merger/CMakeLists.txt +new file mode 100644 +index 000000000..e70903075 +--- /dev/null ++++ b/src/pdf-merger/CMakeLists.txt +@@ -0,0 +1,50 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ ASCII85Decode.cpp ++ ASCII85Decode.h ++ ASCIIHexDecode.cpp ++ ASCIIHexDecode.h ++ AnnotsHandler.cpp ++ AnnotsHandler.h ++ CCITTFaxDecode.cpp ++ CCITTFaxDecode.h ++ ContentHandler.cpp ++ ContentHandler.h ++ DCTDecode.cpp ++ DCTDecode.h ++ Document.cpp ++ Document.h ++ Filter.cpp ++ Filter.h ++ FilterPredictor.cpp ++ FilterPredictor.h ++ FlateDecode.cpp ++ FlateDecode.h ++ JBIG2Decode.cpp ++ JBIG2Decode.h ++ LZWDecode.cpp ++ LZWDecode.h ++ Merger.cpp ++ Merger.h ++ Object.cpp ++ Object.h ++ OverlayDocumentParser.cpp ++ OverlayDocumentParser.h ++ Page.cpp ++ Page.h ++ PageElementHandler.cpp ++ PageElementHandler.h ++ Parser.cpp ++ Parser.h ++ Rectangle.cpp ++ Rectangle.h ++ RemoveHimselfHandler.cpp ++ RemoveHimSelfHandler.h ++ RunLengthDecode.cpp ++ RunLengthDecode.h ++ Utils.cpp ++ Utils.h ++) ++ ++target_include_directories(${PROJECT_NAME} PRIVATE ++ . ++) +diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt +new file mode 100644 +index 000000000..278eb64d2 +--- /dev/null ++++ b/src/pdf/CMakeLists.txt +@@ -0,0 +1,8 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ GraphicsPDFItem.cpp ++ GraphicsPDFItem.h ++ PDFRenderer.cpp ++ PDFRenderer.h ++ XPDFRenderer.cpp ++ XPDFRenderer.h ++) +diff --git a/src/podcast/CMakeLists.txt b/src/podcast/CMakeLists.txt +new file mode 100644 +index 000000000..ca7087809 +--- /dev/null ++++ b/src/podcast/CMakeLists.txt +@@ -0,0 +1,30 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBAbstractVideoEncoder.cpp ++ UBAbstractVideoEncoder.h ++ UBPodcastController.cpp ++ UBPodcastController.h ++ UBPodcastRecordingPalette.cpp ++ UBPodcastRecordingPalette.h ++ intranet/UBIntranetPodcastPublisher.cpp ++ intranet/UBIntranetPodcastPublisher.h ++ youtube/UBYouTubePublisher.cpp ++ youtube/UBYouTubePublisher.h ++) ++ ++if(WIN32) ++ target_sources(${PROJECT_NAME} PRIVATE ++ windowsmedia/UBWindowsMediaVideoEncoder.cpp ++ windowsmedia/UBWindowsMediaVideoEncoder.h ++ windowsmedia/UBWindowsMediaFile.cpp ++ windowsmedia/UBWindowsMediaFile.h ++ windowsmedia/UBWaveRecorder.cpp ++ windowsmedia/UBWaveRecorder.h ++ ) ++else() ++ target_sources(${PROJECT_NAME} PRIVATE ++ ffmpeg/UBFFmpegVideoEncoder.cpp ++ ffmpeg/UBFFmpegVideoEncoder.h ++ ffmpeg/UBMicrophoneInput.cpp ++ ffmpeg/UBMicrophoneInput.h ++ ) ++endif() +diff --git a/src/podcast/intranet/UBIntranetPodcastPublisher.cpp b/src/podcast/intranet/UBIntranetPodcastPublisher.cpp +index 3f9a96f40..d7a107b64 100644 +--- a/src/podcast/intranet/UBIntranetPodcastPublisher.cpp ++++ b/src/podcast/intranet/UBIntranetPodcastPublisher.cpp +@@ -154,7 +154,7 @@ QString UBIntranetPodcastPublisher::metadata() + QString computerName = UBPlatformUtils::computerName(); + QString fileSize = QString("%1").arg(fi.size()); + +- QString templatePath = UBPlatformUtils::applicationResourcesDirectory() + "/etc/intranet-podcast-metadata.template"; ++ QString templatePath = UBPlatformUtils::applicationResourcesDirectory() + "/template/intranet-podcast-metadata.template"; + QString templateContent = UBFileSystemUtils::readTextFile(templatePath); + + return templateContent.replace("{title}", mTitle) +diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt +new file mode 100644 +index 000000000..3886d6963 +--- /dev/null ++++ b/src/tools/CMakeLists.txt +@@ -0,0 +1,22 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBAbstractDrawRuler.cpp ++ UBAbstractDrawRuler.h ++ UBGraphicsAxes.cpp ++ UBGraphicsAxes.h ++ UBGraphicsCache.cpp ++ UBGraphicsCache.h ++ UBGraphicsCompass.cpp ++ UBGraphicsCompass.h ++ UBGraphicsCurtainItem.cpp ++ UBGraphicsCurtainItem.h ++ UBGraphicsCurtainItemDelegate.cpp ++ UBGraphicsCurtainItemDelegate.h ++ UBGraphicsProtractor.cpp ++ UBGraphicsProtractor.h ++ UBGraphicsRuler.cpp ++ UBGraphicsRuler.h ++ UBGraphicsTriangle.cpp ++ UBGraphicsTriangle.h ++ UBToolsManager.cpp ++ UBToolsManager.h ++) +diff --git a/src/web/CMakeLists.txt b/src/web/CMakeLists.txt +new file mode 100644 +index 000000000..45277ec12 +--- /dev/null ++++ b/src/web/CMakeLists.txt +@@ -0,0 +1,35 @@ ++target_sources(${PROJECT_NAME} PRIVATE ++ UBEmbedContent.cpp ++ UBEmbedContent.h ++ UBEmbedController.cpp ++ UBEmbedController.h ++ UBEmbedParser.cpp ++ UBEmbedParser.h ++ UBWebController.cpp ++ UBWebController.h ++ simplebrowser/WBHistory.cpp ++ simplebrowser/WBHistory.h ++ simplebrowser/WBModelMenu.cpp ++ simplebrowser/WBModelMenu.h ++ simplebrowser/browserwindow.cpp ++ simplebrowser/browserwindow.h ++ simplebrowser/downloadmanagerwidget.cpp ++ simplebrowser/downloadmanagerwidget.h ++ simplebrowser/downloadwidget.cpp ++ simplebrowser/downloadwidget.h ++ simplebrowser/tabwidget.cpp ++ simplebrowser/tabwidget.h ++ simplebrowser/webpage.cpp ++ simplebrowser/webpage.h ++ simplebrowser/webpopupwindow.cpp ++ simplebrowser/webpopupwindow.h ++ simplebrowser/webview.cpp ++ simplebrowser/webview.h ++) ++ ++qt_add_resources(${PROJECT_NAME} ++ simplebrowser/certificateerrordialog.ui ++ simplebrowser/downloadmanagerwidget.ui ++ simplebrowser/downloadwidget.ui ++ simplebrowser/passworddialog.ui ++) +diff --git a/src/web/UBWebController.cpp b/src/web/UBWebController.cpp +index df3bffba5..31e4e8616 100644 +--- a/src/web/UBWebController.cpp ++++ b/src/web/UBWebController.cpp +@@ -415,7 +415,7 @@ void UBWebController::injectScripts(QWebEngineView *view) + qDebug() << "Injecting qwebchannel.js"; + QString src = js.readAll(); + +- QFile asyncwrapper(UBPlatformUtils::applicationResourcesDirectory() + "/etc/asyncAPI.js"); ++ QFile asyncwrapper(UBPlatformUtils::applicationResourcesDirectory() + "/template/asyncAPI.js"); + + if (asyncwrapper.open(QIODevice::ReadOnly)) + { + +From 5ed9d68afc52d071135640e8da5c35308cd5d318 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Sun, 30 Oct 2022 08:09:24 +0100 +Subject: [PATCH 2/3] fix: compatibility with Qt 5.12 and Qt 6 + +- use qt5_add_resources and qt5_add_translation for Qt 5.12 +- add .ui and .ts files using target_sources +- add QT_VERSION when linking to Qt libraries (needed for Qt 5.12) +--- + CMakeLists.txt | 18 +++++++++++++++--- + cmake/DependencyQt.cmake | 2 +- + resources/forms/CMakeLists.txt | 3 +-- + src/web/CMakeLists.txt | 2 +- + 4 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 65b487911..f6900ac39 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -20,6 +20,7 @@ cmake_minimum_required(VERSION 3.16) + # cmake -S -B -DCMAKE_INSTALL_PREFIX:PATH=/opt + # + # Build and install ++# cd + # cmake --build . [-j] + # DESTDIR= cmake --install . + # ========================================================================== +@@ -174,7 +175,12 @@ endif() + # Resources + # ========================================================================== + +-qt_add_resources(OPENBOARD_RESOURCES ${OPENBOARD_QRC_FILE}) ++if(Qt5_VERSION AND Qt5_VERSION VERSION_LESS "5.15") ++ qt5_add_resources(OPENBOARD_RESOURCES ${OPENBOARD_QRC_FILE}) ++else() ++ qt_add_resources(OPENBOARD_RESOURCES ${OPENBOARD_QRC_FILE}) ++endif() ++ + target_sources(${PROJECT_NAME} PRIVATE ${OPENBOARD_RESOURCES}) + + +@@ -184,8 +190,14 @@ target_sources(${PROJECT_NAME} PRIVATE ${OPENBOARD_RESOURCES}) + + file(GLOB OPENBOARD_TS_FILES ${OPENBOARD_TS_DIR}/*.ts) + set_source_files_properties(${OPENBOARD_TS_FILES} PROPERTIES OUTPUT_LOCATION ${PROJECT_BINARY_DIR}/i18n) +-qt_add_translation(QM_FILES ${OPENBOARD_TS_FILES}) +-target_sources(${PROJECT_NAME} PRIVATE ${QM_FILES}) ++ ++if(Qt5_VERSION AND Qt5_VERSION VERSION_LESS "5.15") ++ qt5_add_translation(QM_FILES ${OPENBOARD_TS_FILES}) ++else() ++ qt_add_translation(QM_FILES ${OPENBOARD_TS_FILES}) ++endif() ++ ++target_sources(${PROJECT_NAME} PRIVATE ${QM_FILES} ${OPENBOARD_TS_FILES}) + + + # ========================================================================== +diff --git a/cmake/DependencyQt.cmake b/cmake/DependencyQt.cmake +index d8d0a1339..506f12293 100644 +--- a/cmake/DependencyQt.cmake ++++ b/cmake/DependencyQt.cmake +@@ -32,7 +32,7 @@ else() + message(FATAL_ERROR "Qt Version ${QT_VERSION} not supported") + endif() + +-list(TRANSFORM QT_COMPONENTS PREPEND Qt::) ++list(TRANSFORM QT_COMPONENTS PREPEND Qt${QT_VERSION}::) + + target_link_libraries(${PROJECT_NAME} + ${QT_COMPONENTS} +diff --git a/resources/forms/CMakeLists.txt b/resources/forms/CMakeLists.txt +index 554b52e93..547ea5411 100644 +--- a/resources/forms/CMakeLists.txt ++++ b/resources/forms/CMakeLists.txt +@@ -1,4 +1,4 @@ +-qt_add_resources(${PROJECT_NAME} ++target_sources(${PROJECT_NAME} PRIVATE + blackoutWidget.ui + brushProperties.ui + capturePublishing.ui +@@ -7,7 +7,6 @@ qt_add_resources(${PROJECT_NAME} + intranetPodcastPublishingDialog.ui + mainWindow.ui + preferences.ui +- preferences.ui.autosave + trapFlash.ui + youTubePublishingDialog.ui + ) +diff --git a/src/web/CMakeLists.txt b/src/web/CMakeLists.txt +index 45277ec12..590476e34 100644 +--- a/src/web/CMakeLists.txt ++++ b/src/web/CMakeLists.txt +@@ -27,7 +27,7 @@ target_sources(${PROJECT_NAME} PRIVATE + simplebrowser/webview.h + ) + +-qt_add_resources(${PROJECT_NAME} ++target_sources(${PROJECT_NAME} PRIVATE + simplebrowser/certificateerrordialog.ui + simplebrowser/downloadmanagerwidget.ui + simplebrowser/downloadwidget.ui + +From 6ff5d2c7f339e1612a8e6e836061f0d96b03d8fc Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Sat, 5 Nov 2022 08:52:48 +0100 +Subject: [PATCH 3/3] chore: add cpack packaging (by @sebojolais) + +- add cpack packaging instructions +- configure for deb and rpm packages + +based on proposal of @sebojolais +--- + CMakeLists.txt | 32 +++++++++++++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f6900ac39..ebd94ffce 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -23,6 +23,9 @@ cmake_minimum_required(VERSION 3.16) + # cd + # cmake --build . [-j] + # DESTDIR= cmake --install . ++# ++# Package ++# cpack -G + # ========================================================================== + + # ========================================================================== +@@ -31,7 +34,12 @@ cmake_minimum_required(VERSION 3.16) + # The project will now be named all lowercase on all platforms + # ========================================================================== + +-project(openboard VERSION 1.7.0 LANGUAGES CXX) ++project(openboard ++ VERSION 1.7.0 ++ DESCRIPTION "OpenBoard is an open source cross-platform interactive white board application designed primarily for use in schools. It was originally forked from Open-Sankoré, which was itself based on Uniboard." ++ HOMEPAGE_URL "https://www.openboard.org" ++ LANGUAGES CXX ++) + + set(VERSION_TYPE a) # a = alpha, b = beta, rc = release candidate, r = release, other => error + set(VERSION_BUILD 1027) +@@ -244,3 +252,25 @@ if(LINUX) + install(FILES ${OPENBOARD_MIMETYPE_FILE} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages) + install(FILES ${OPENBOARD_MIMEICON_FILE} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/mimetypes) + endif() ++ ++ ++# ========================================================================== ++# Packaging ++# ========================================================================== ++ ++include(InstallRequiredSystemLibraries) ++set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") ++set(CPACK_PACKAGE_VERSION "${VERSION}") ++set(CPACK_PACKAGE_CONTACT "The OpenBoard team") ++set(CPACK_STRIP_FILES TRUE) ++ ++# Debian specific settings ++set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") ++set(CPACK_DEBIAN_PACKAGE_SUGGESTS onboard) ++ ++# RPM specific settings ++set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") ++set(CPACK_RPM_PACKAGE_SUGGESTS onboard) ++ ++# create packager ++include(CPack) diff --git a/SOURCES/9117-disable-software-update.patch b/SOURCES/9117-disable-software-update.patch new file mode 100644 index 0000000..0d20c0d --- /dev/null +++ b/SOURCES/9117-disable-software-update.patch @@ -0,0 +1,47 @@ +From 8868eacdd913c1c5bd3040425c507fb8ef527e71 Mon Sep 17 00:00:00 2001 +From: letsfindaway +Date: Wed, 16 Nov 2022 08:31:29 +0100 +Subject: [PATCH] feat: disable software and document update check + +- for packages maintained by a Linux distribution, + a software update check is not relevant +- also the import of ancient OpenSankore documents is not necessary +- disable the checks in the settings +- hide the associated checkboxes in the preferences +--- + resources/etc/OpenBoard.config | 7 +++---- + src/core/UBPreferencesController.cpp | 2 ++ + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/resources/etc/OpenBoard.config b/resources/etc/OpenBoard.config +index 0120f922d..09c11a6dc 100644 +--- a/resources/etc/OpenBoard.config ++++ b/resources/etc/OpenBoard.config +@@ -1,15 +1,14 @@ + [App] + AngleTolerance=4 +-HideCheckForSoftwareUpdate=false ++HideCheckForSoftwareUpdate=true + HideSwapDisplayScreens=true +-EnableAutomaticSoftwareUpdates=true +-EnableSoftwareUpdates=true ++EnableAutomaticSoftwareUpdates=false + EnableStartupHints=false + FavoriteToolURIs=openboardtool://openboard/mask, openboardtool://ruler, openboardtool://compass, openboardtool://protractor, openboardtool://triangle, openboardtool://magnifier, openboardtool://cache + IsInSoftwareUpdateProcess=false + LastSessionDocumentUUID= + LastSessionPageIndex=0 +-LookForOpenSankoreInstall=true ++LookForOpenSankoreInstall=false + PageCacheSize=20 + PreferredLanguage=fr_CH + ProductWebAddress=http://www.openboard.ch +diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp +index 4e7c5612a..a5bec7b9b 100644 +--- a/src/core/UBPreferencesController.cpp ++++ b/src/core/UBPreferencesController.cpp +@@ -92,2 +92,4 @@ UBPreferencesController::UBPreferencesController(QWidget *parent) + mPreferencesUI->setupUi(mPreferencesWindow); ++ mPreferencesUI->softwareUpdateGroupBox->hide(); // disable check for software update ++ mPreferencesUI->sankoreImporterGroupBox->hide(); // disable check for OpenSankore documents + adjustScreens(); diff --git a/SOURCES/9686-cmake-add-shortcut-manager.patch b/SOURCES/9686-cmake-add-shortcut-manager.patch new file mode 100644 index 0000000..ff314b3 --- /dev/null +++ b/SOURCES/9686-cmake-add-shortcut-manager.patch @@ -0,0 +1,13 @@ +diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt +index eda1052a..e76d7f92 100644 +--- a/src/core/CMakeLists.txt ++++ b/src/core/CMakeLists.txt +@@ -33,6 +33,8 @@ target_sources(${PROJECT_NAME} PRIVATE + UBSetting.h + UBSettings.cpp + UBSettings.h ++ UBShortcutManager.cpp ++ UBShortcutManager.h + UBTextTools.cpp + UBTextTools.h + ) diff --git a/SPECS/openboard.spec b/SPECS/openboard.spec new file mode 100644 index 0000000..5610479 --- /dev/null +++ b/SPECS/openboard.spec @@ -0,0 +1,306 @@ +%define githash 9de37af2df1a7c0d88f71c94ab2db1815d082862 +%define gitshort 9de37af +%define gitdate 20221129 + +Summary: Interactive whiteboard for schools and universities +Name: openboard +Version: 1.7.0 +Release: 1.%{?gitdate}git%{?gitshort}%{?dist} +License: GPLv3 + +URL: https://openboard.ch +Source0: https://github.com/OpenBoard-org/OpenBoard/archive/%{githash}.tar.gz#/openboard-%{githash}.tar.gz +# https://github.com/OpenBoard-org/OpenBoard/pull/551 +Patch551: 0551-common-background-drawing.patch +# https://github.com/OpenBoard-org/OpenBoard/pull/569 +Patch569: 0569-scale-mirror-pixmap.patch +# https://github.com/OpenBoard-org/OpenBoard/pull/677 +Patch677: 0677-pdf-export-page-size.patch +# https://github.com/OpenBoard-org/OpenBoard/pull/686 +Patch686: 0686-shortcut-configuration.patch +# https://github.com/OpenBoard-org/OpenBoard/pull/698 +Patch698: 0698-add-cmake-build-system.patch +# https://github.com/letsfindaway/OpenBoard/pull/117 +Patch9117: 9117-disable-software-update.patch +# no github url available +Patch9686: 9686-cmake-add-shortcut-manager.patch + +BuildRequires: desktop-file-utils +BuildRequires: fdupes +BuildRequires: pkgconfig +BuildRequires: unzip +BuildRequires: pkgconfig(Qt5Concurrent) +BuildRequires: pkgconfig(Qt5Core) +BuildRequires: pkgconfig(Qt5DBus) +BuildRequires: pkgconfig(Qt5Multimedia) +BuildRequires: pkgconfig(Qt5MultimediaWidgets) +BuildRequires: pkgconfig(Qt5Network) +BuildRequires: pkgconfig(Qt5PrintSupport) +BuildRequires: pkgconfig(Qt5Svg) +BuildRequires: pkgconfig(Qt5UiTools) +BuildRequires: pkgconfig(Qt5WebEngineWidgets) +BuildRequires: pkgconfig(Qt5Xml) +BuildRequires: pkgconfig(Qt5XmlPatterns) +BuildRequires: pkgconfig(freetype2) +BuildRequires: pkgconfig(libavdevice) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(poppler) +BuildRequires: pkgconfig(poppler-cpp) +BuildRequires: pkgconfig(quazip1-qt5) +Recommends: onboard + +%description +OpenBoard is an open source cross-platform interactive white board +application designed primarily for use in schools. It was +originally forked from Open-Sankoré, which was itself based on +Uniboard. + +This build is based on the development branch 1.7-dev and includes +a set of additional patches for features and bug fixes. + +%prep +%autosetup -p1 -n OpenBoard-%{githash} + +# remove x flag from any resource files +find resources -type f -print0 | xargs -0 chmod a-x + +# remove leftover version control file +rm resources/library/applications/Calculator.wgt/.gitignore + +%build +%cmake +%cmake_build + +%install +%cmake_install +%fdupes -s %{buildroot} + +%files +%license LICENSE +%doc COPYRIGHT +%config %{_sysconfdir}/%{name} +%{_datadir}/applications/*.desktop +%{_datadir}/icons/hicolor/scalable +%{_datadir}/mime/packages/* +%{_datadir}/%{name} +%{_bindir}/%{name} + +%changelog +* Mon Sep 11 2023 Arkady L. Shane - 1.7.0-1.20221129git9de37af +- Rebuilt for MSVSphere 9.2 + +* Mon Sep 11 2023 Arkady L. Shane - 1.7.0-1.20221129git9de37af +- Rebuilt for MSVSphere 9.2 + +* Wed Jan 25 2023 Dominique Leuenberger +- BuildRequire pkgconfig(libavdevice) instead of ffmpeg-devel: let + OBS figure out the right packages that do not conlfict. +* Tue Nov 29 2022 Martin Winter +- update to version 1.7.0~git20221129.9de37af +- feat: user configurable shortcuts + * replace 0460-shortcut-configuration.patch by updated + 0686-shortcut-configuration.patch + * add 9686-cmake-add-shortcut-manager.patch + add new files to CMakeLists.txt +- fix: background drawing when switching page size + * update 0551-common-background-drawing.patch +- fix: mirror pixmap size + * update 0569-scale-mirror-pixmap.patch +- remove upstreamed patches + * remove upstreamed 0604-qt-5.12-compatibility.patch + * remove upstreamed 0629-bug-ruler.patch + * remove upstreamed 0633-improve-displaymanager.patch + * remove upstreamed 0637-fix-pdf-background-export.patch + * remove upstreamed 0641-fix-font-handling.patch + * remove upstreamed 0649-fix-pdf-export-scaling.patch +- chore: replace qmake by cmake build system + * remove 0651-chore-reorganize-linux-build.patch + * add 0698-add-cmake-build-system.patch +- fix: page size for PDF export + * add 0677-pdf-export-page-size.patch +- disable software update from openboard web page + * add 9117-disable-software-update.patch +* Tue Sep 20 2022 Martin Winter +- fix file list in spec file + - do not include /usr/share/mime/packages directory owned by + filesystem +* Wed Sep 14 2022 Martin Winter +- update to version 1.7.0~git20220914.47a96e1 +- feat: user configurable shortcuts + * add 0460-shortcut-configuration.patch +- fix: boxing in single screen mode + * update 0633-improve-displaymanager.patch +- fix: PDF background export + * update 0637-fix-pdf-background-export.patch +- fix: font handling + * update 0641-fix-font-handling.patch +- fix: PDF export scaling + * add 0649-fix-pdf-export-scaling.patch +- refactor: Linux build and installation + * add 0651-chore-reorganize-linux-build.patch + * replaces 0001-Rewrite-libs.pri.patch + * replaces 0002-Install-to-correct-directories-on-linux.patch + * replaces 0003-podcast.pri-port-to-pkgconfig.patch + * replaces 0004-Use-QStandardPaths-to-locate-resources.patch + * replaces 0005-Add-svg-icon.patch + * replaces 0006-pro-Remove-UB_THIRDPARTY_INTERACTIVE.patch + * replaces 0007-Linux-Only-use-onboard-by-default-if-it-s-installed.patch + * replaces 0008-install-fonts.patch + * add mimespec for .ubz files + * also improve handling of onboard on-screen keyboard +- refactor: clean spec file +* Fri Jun 24 2022 Martin Winter +- minor changes in spec file +* Fri Jun 24 2022 Martin Winter +- fix several issues + - add 0008-install-fonts.patch + - add 0637-fix-pdf-background-export.patch + - add 0641-fix-font-handling.patch +* Sun Jun 19 2022 Martin Winter +- update to 1.7.0~git47a96e1 + - use development branch to enable build for Tumbleweed + (switch from QWebKit to QWebEngine) +- add patches fixing known issues according to existing upstream PRs + - 0551-common-background-drawing.patch + - 0569-scale-mirror-pixmap.patch + - 0604-qt-5.12-compatibility.patch + - 0629-bug-ruler.patch + - 0633-improve-displaymanager.patch +- remove unused build dependencies +* Mon Jun 13 2022 Martin Winter +- Update to 1.6.3 + - see https://github.com/OpenBoard-org/OpenBoard/releases/tag/v1.6.3 +* Mon Jun 6 2022 Martin Winter +- Update to 1.6.2 + - see https://github.com/OpenBoard-org/OpenBoard/releases/tag/v1.6.2 + - adapt 0001-Rewrite-libs.pri.patch + - adapt 0002-Install-to-correct-directories-on-linux.patch + - drop 0573-compile-with-poppler-22.03.patch (upstreamed) +* Tue Mar 15 2022 Martin Winter +- add 0573-compile-with-poppler-22.03.patch +* Tue Dec 28 2021 Martin Winter +- update to OpenBoard 1.6.1 + - adapt patches +* Mon Feb 8 2021 Adam Majer +- Compile translations so they are installed (bsc#1181857) +* Mon Nov 23 2020 Adam Majer +- 0001-Rewrite-libs.pri.patch: + + update patch and BR on now weirdly named quazip - pkgconfig(quazip1-qt5) + + continue to function with with pkgconfig(quazip) in Leap 15.2 +- Remove BR on libx264-devel and fdk-aac-devel as these are no longer + available in Factory +* Sat May 23 2020 Frank Schütte +- fixed building with patches from https://github.com/flathub/ch.openboard.OpenBoard +* Fri May 22 2020 Frank Schütte +- update to 1.5.4 +* Mon Jun 10 2019 Frank Schütte +- remove openssl patch +* Mon Jun 10 2019 Frank Schütte +- Update to OpenBoard 1.5.3 +- updated OpenBoard-no-Third-Party patch +* Fri Jan 25 2019 F.Schuette@t-online.de +- Update to OpenBoard 1.5.2 +* Tue Sep 11 2018 F.Schuette@t-online.de +- Update to OpenBoard 1.4.1 + * Add patch for ffmpeg includes. +* Wed Jan 10 2018 antoine.belvire@opensuse.org +- Add compatibility with OpenSSL 1.1 API: + * OpenBoard-1.3.6-add-openssl-1.1-compat.patch. + * Authorize build with OpenSSL 1.1 by removing version constraint + on "BuildRequires". +- Merge quazip_libname.patch with OpenBoard-no_Third-Party.patch. +* Tue Jan 9 2018 antoine.belvire@opensuse.org +- Update to version 1.3.6: + * Fix several issues relating to copy-pasting and + cut-and-pasting elements from one page or document to another. + * Fix an issue where pen strokes that had been erased with the + eraser would reappear after saving and loading. + * Fix an issue where duplicating a pen stroke that had been + moved could cause the new stroke to be placed in the wrong + position. + * Fix an issue where strokes could be badly placed after using + the "undo" and "redo" functions. + * Fix an issue where compass strokes were not saved (when + making several strokes, only the first one was saved). + * Fix an issue where pages could be truncated when exporting to + PDF. + * Fix an issue where locked items could be moved when part of a + multiple selection + * (Document mode) Fix document selection after deleting a + trashed document. + * Tweak the background grid color for the dark background. + * The mask tool can now be resized non-proportionately. + * Re-implemented automatic update checking, which will appear + to users when the next version is released. +- Changes from version 1.3.5: + * Fix detection of "cloned" multi-monitor setups to avoid + multi-screen mode being activated in this configuration. + [Note: some problems remain with multi-monitor setups on some + Linux versions.]. + * Text items: Text can no longer be selected or edited if the + text item is marked as non-editable through its menu. + * Text items: On page load, text items no longer take keyboard + focus. + * Library pane: Fix moving of items (upon moving an item to a + folder, the item would not immediately disappear from its + current location). + * Library pane: Fix nested folder issue in breadcrumbs trail (two + folders that were at the same path and whose names started with + the same characters were considered by the breadcrumbs trail to + be nested). + * Document view: Fix folder names not being saved after renaming + them. + * Fix audio item saving (v1.3.3 bug): Documents containing an + audio item were saved incorrectly, making the audio unplayable + upon page load. + * Desktop mode: Eraser and marker preview circles now disappear + when the cursor hovers over the left or right-hand toolbars, as + in board mode. +- Drop OpenBoard-fix-call-of-overloaded-abs-is-ambiguous.patch + (fixed upstream). +- Fix some rpmlint warnings. +* Tue Jan 9 2018 antoine.belvire@opensuse.org +- Fix build: + * Change OpenBoard-XPDFRenderer_with_poppler.patch to make it + work with libpoppler >= 0.55. + * Force use of OpenSSL 1.0 as build requirement instead of 1.1. + * Use "libquazip-qt5-devel" instead of "quazip-qt5-devel" in + build requirements to fix build on Leap. +* Fri Jun 30 2017 adam.majer@suse.de +- quazip_libname.patch: Use quazip-qt5 instead of quazip as mixing + Qt versions is bad. Qt5 quazip also uses a different library + name. (boo#1042040) +- add missing libpulse BuildRequires +* Mon Feb 13 2017 mrueckert@suse.de +- update to 1.3.4 + - OS X: fixed desktop drop shadow bug: when switching from + desktop mode to board mode and back, shadows were drawn behind + annotations; these persisted even if the annotation was erased + - Windows: Updated bundled Visual C++ runtime library; fixed + installer so that the library installation would be silent (no + more dialog box appearing) + - Linux: fixed detection of "cloned" multi-monitor setups to + avoid multi-screen mode being activated in this configuration. + [Note: some problems remain with multi-monitor setups on some + Linux versions; see Known Issues] + - Text items: text can no longer be selected or edited if the + text item is marked as non-editable through its menu + - Text items: on page load, text items no longer take keyboard + focus + - Library pane: fixed moving of items (upon moving an item to a + folder, the item would not immediately disappear from its + current location) + - Library pane: fixed nested folder issue in breadcrumbs trail + (two folders that were at the same path and whose names started + with the same characters were considered by the breadcrumbs + trail to be nested) + - Document view: fixed folder names not being saved after + renaming them + - Fixed audio item saving (v1.3.3 bug): documents containing an + audio item were saved incorrectly, making the audio unplayable + upon page load + - Desktop mode: eraser and marker preview circles now disappear + when the cursor hovers over the left or right-hand toolbars, as + in board mode +- refreshed OpenBoard-XPDFRenderer_with_poppler.patch to apply + cleanly again