Skip to content

Commit

Permalink
Extend tab context menu to support custom action #96
Browse files Browse the repository at this point in the history
  • Loading branch information
DamirPorobic committed Oct 4, 2020
1 parent dad3c3c commit 265e372
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 1 deletion.
32 changes: 32 additions & 0 deletions src/gui/annotator/tabs/AnnotationTabContextMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ AnnotationTabContextMenu::~AnnotationTabContextMenu()
delete mCloseTab;
delete mClosedOtherTabs;
delete mCloseAllTabs;
qDeleteAll(mCustomActionMap.keys());
}

void AnnotationTabContextMenu::show(int tabIndex, const QPoint &pos)
Expand Down Expand Up @@ -92,4 +93,35 @@ void AnnotationTabContextMenu::closeAllTabsToRightTriggered() const
emit closeAllTabsToRight(mTabIndex);
}

void AnnotationTabContextMenu::addCustomActions(const QList<QAction *> &customActions)
{
addSeparator();
for(auto innerAction : customActions) {
auto outerAction = new QAction(this);
outerAction->setText(innerAction->text());
outerAction->setIcon(innerAction->icon());
outerAction->setToolTip(innerAction->toolTip());
outerAction->setEnabled(innerAction->isEnabled());
mCustomActionMap[outerAction] = innerAction;
connect(innerAction, &QAction::changed, this, &AnnotationTabContextMenu::customActionChanged);
connect(outerAction, &QAction::triggered, this, &AnnotationTabContextMenu::customActionTriggered);
addAction(outerAction);
}
}

void AnnotationTabContextMenu::customActionTriggered()
{
auto outerAction = dynamic_cast<QAction *>(sender());
auto innerAction = mCustomActionMap.value(outerAction);
innerAction->setData(mTabIndex);
innerAction->trigger();
}

void AnnotationTabContextMenu::customActionChanged()
{
auto innerAction = dynamic_cast<QAction *>(sender());
auto outerAction = mCustomActionMap.key(innerAction);
outerAction->setEnabled(innerAction->isEnabled());
}

} // namespace kImageAnnotator
6 changes: 6 additions & 0 deletions src/gui/annotator/tabs/AnnotationTabContextMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class AnnotationTabContextMenu : public QMenu
explicit AnnotationTabContextMenu(QWidget *parent);
~AnnotationTabContextMenu() override;
void show(int tabIndex, const QPoint &pos);
void addCustomActions(const QList<QAction*> & customActions);

signals:
void closeTab(int index) const;
Expand All @@ -46,12 +47,17 @@ class AnnotationTabContextMenu : public QMenu
QAction *mCloseAllTabs;
QAction *mCloseAllTabsToLeft;
QAction *mCloseAllTabsToRight;
QHash<QAction*, QAction*> mCustomActionMap;

void closeTabTriggered() const;
void closeOtherTabsTriggered() const;
void closeAllTabsTriggered() const;
void closeAllTabsToLeftTriggered() const;
void closeAllTabsToRightTriggered() const;

private slots:
void customActionTriggered();
void customActionChanged();
};

} // namespace kImageAnnotator
Expand Down
3 changes: 2 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ set(UNITTEST_SRC
gui/cropper/CropHandlesTest.cpp
gui/scaler/ScaleSizeHandlerTest.cpp
gui/annotator/tabs/AnnotationTabCloserTest.cpp
gui/annotator/tabs/AnnotationTabContextMenuTest.cpp
widgets/ToolPickerTest.cpp
widgets/ColorPickerTest.cpp
widgets/NumberPickerTest.cpp
Expand All @@ -43,7 +44,7 @@ set(UNITTEST_SRC
)

set(TESTUTILS_SRC
mocks/MockZoomValueProvider.cpp
mocks/MockZoomValueProvider.cpp
mocks/MockSettingsProvider.cpp
mocks/MockDevicePixelRatioScaler.cpp
mocks/MockDefaultParameters.h
Expand Down
71 changes: 71 additions & 0 deletions tests/gui/annotator/tabs/AnnotationTabContextMenuTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2020 Damir Porobic <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "AnnotationTabContextMenuTest.h"

void AnnotationTabContextMenuTest::TestCustomActionTriggered_Should_CallInnerActionWithCorrectTabIndexSetInData()
{
auto tabIndex = 22;
QAction customAction;
QSignalSpy spy(&customAction, &QAction::triggered);
QWidget parent;
AnnotationTabContextMenu menu(&parent);
menu.addCustomActions(QList<QAction*>{&customAction});
auto outerAction = menu.actions().last();
QTimer::singleShot(300, outerAction, &QAction::trigger);
QTimer::singleShot(400, &menu, &QMenu::close);

menu.show(tabIndex, {});

QCOMPARE(customAction.data(), tabIndex);
QCOMPARE(spy.count(), 1);
}

void AnnotationTabContextMenuTest::TestAddCustomActions_Should_SetTextIconAndToolTipInOuterAction()
{
QAction customAction;
customAction.setText(QLatin1Literal("LaLa"));
customAction.setToolTip(QLatin1Literal("Hello Hello"));
customAction.setIcon(QIcon());
QWidget parent;
AnnotationTabContextMenu menu(&parent);
menu.addCustomActions(QList<QAction*>{&customAction});
auto outerAction = menu.actions().last();

QCOMPARE(customAction.text(), outerAction->text());
QCOMPARE(customAction.toolTip(), outerAction->toolTip());
QCOMPARE(customAction.icon(), outerAction->icon());
}

void AnnotationTabContextMenuTest::TestCustomActionChanged_Should_UpdateEnabledStateOfOuterAction()
{
QAction customAction;
customAction.setEnabled(false);
QWidget parent;
AnnotationTabContextMenu menu(&parent);
menu.addCustomActions(QList<QAction*>{&customAction});
auto outerAction = menu.actions().last();
QCOMPARE(customAction.isEnabled(), outerAction->isEnabled());

customAction.setEnabled(true);

QCOMPARE(customAction.isEnabled(), outerAction->isEnabled());
}

QTEST_MAIN(AnnotationTabContextMenuTest);
40 changes: 40 additions & 0 deletions tests/gui/annotator/tabs/AnnotationTabContextMenuTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2020 Damir Porobic <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#ifndef KIMAGEANNOTATOR_ANNOTATIONTABCONTEXTMENUTEST_H
#define KIMAGEANNOTATOR_ANNOTATIONTABCONTEXTMENUTEST_H

#include <QtTest>
#include <QTimer>

#include "src/gui/annotator/tabs/AnnotationTabContextMenu.h"

using kImageAnnotator::AnnotationTabContextMenu;

class AnnotationTabContextMenuTest : public QObject
{
Q_OBJECT
private slots:
void TestCustomActionTriggered_Should_CallInnerActionWithCorrectTabIndexSetInData();
void TestAddCustomActions_Should_SetTextIconAndToolTipInOuterAction();
void TestCustomActionChanged_Should_UpdateEnabledStateOfOuterAction();
};


#endif //KIMAGEANNOTATOR_ANNOTATIONTABCONTEXTMENUTEST_H

0 comments on commit 265e372

Please sign in to comment.