Skip to content

Commit

Permalink
Added action button handler to take care of none/all/selection action…
Browse files Browse the repository at this point in the history
…s in toolbar buttons.

albar965/littlenavmap#762
  • Loading branch information
albar965 committed Jul 25, 2022
1 parent 93cb6ea commit b682a14
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 0 deletions.
2 changes: 2 additions & 0 deletions atools.pro
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ HEADERS += \
src/geo/rect.h \
src/geo/spatialindex.h \
src/grib/windquery.h \
src/gui/actionbuttonhandler.h \
src/gui/actionstatesaver.h \
src/gui/actiontextsaver.h \
src/gui/actiontool.h \
Expand Down Expand Up @@ -350,6 +351,7 @@ SOURCES += \
src/geo/rect.cpp \
src/geo/spatialindex.cpp \
src/grib/windquery.cpp \
src/gui/actionbuttonhandler.cpp \
src/gui/actionstatesaver.cpp \
src/gui/actiontextsaver.cpp \
src/gui/actiontool.cpp \
Expand Down
149 changes: 149 additions & 0 deletions src/gui/actionbuttonhandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*****************************************************************************
* Copyright 2015-2022 Alexander Barthel [email protected]
*
* This program 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, either version 3 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

#include "gui/actionbuttonhandler.h"

#include <QAction>
#include <QDebug>

namespace atools {
namespace gui {

ActionButtonHandler::ActionButtonHandler(QObject *parent)
: QObject{parent}
{

}

ActionButtonHandler::~ActionButtonHandler()
{

}

void ActionButtonHandler::setNoneAction(QAction *action)
{
actionNone = action;
connect(actionNone, &QAction::triggered, this, &ActionButtonHandler::noneTriggered);
}

void ActionButtonHandler::setAllAction(QAction *action)
{
actionAll = action;
connect(actionAll, &QAction::triggered, this, &ActionButtonHandler::allTriggered);
}

void ActionButtonHandler::addOtherAction(QAction *action)
{
actionsOther.insert(action, action->isChecked());
connect(action, &QAction::triggered, this, &ActionButtonHandler::otherTriggered);
}

void ActionButtonHandler::noneTriggered()
{
#ifdef DEBUG_INFORMATION
qDebug() << Q_FUNC_INFO << "lastTriggered" << lastTriggered;
#endif

if(lastTriggered == NONE)
// Repeated press - restore state
toggleSavedStateWithActions();
else
// Save state and uncheck all
saveAndSetActionState(false);

lastTriggered = NONE;

emit actionNoneTriggered(actionNone);
}

void ActionButtonHandler::allTriggered()
{
#ifdef DEBUG_INFORMATION
qDebug() << Q_FUNC_INFO << "lastTriggered" << lastTriggered;
#endif

if(lastTriggered == ALL)
// Repeated press - restore state
toggleSavedStateWithActions();
else
// Save state and check all
saveAndSetActionState(true);

lastTriggered = ALL;

emit actionAllTriggered(actionAll);
}

void ActionButtonHandler::otherTriggered()
{
#ifdef DEBUG_INFORMATION
qDebug() << Q_FUNC_INFO << "lastTriggered" << lastTriggered;
#endif

QAction *action = dynamic_cast<QAction *>(sender());
if(action != nullptr)
// Save state for restore
actionsOther[action] = action->isChecked();

lastTriggered = ACTION;

emit actionOtherTriggered(action);
}

void ActionButtonHandler::toggleSavedStateWithActions()
{
#ifdef DEBUG_INFORMATION
qDebug() << Q_FUNC_INFO;
#endif

for(auto it = actionsOther.begin(); it != actionsOther.end(); ++it)
{
QAction *action = it.key();
bool checked = action->isChecked();

// Set new check state
action->blockSignals(true);
action->setChecked(it.value());
action->blockSignals(false);

// Save old check state
it.value() = checked;
}
}

void ActionButtonHandler::saveAndSetActionState(bool checkAction)
{
#ifdef DEBUG_INFORMATION
qDebug() << Q_FUNC_INFO << "actionChecked" << checkAction;
#endif

for(auto it = actionsOther.begin(); it != actionsOther.end(); ++it)
{
QAction *action = it.key();

// Save check state
it.value() = action->isChecked();

// Set new state
action->blockSignals(true);
action->setChecked(checkAction);
action->blockSignals(false);
}
}

} // namespace gui
} // namespace atools
94 changes: 94 additions & 0 deletions src/gui/actionbuttonhandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*****************************************************************************
* Copyright 2015-2022 Alexander Barthel [email protected]
*
* This program 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, either version 3 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

#ifndef ATOOLS_ACTIONBUTTONHANDLER_H
#define ATOOLS_ACTIONBUTTONHANDLER_H

#include <QHash>
#include <QObject>

class QAction;

namespace atools {
namespace gui {

/*
* ZHandler takes care of none/all/selection actions in toolbar buttons.
*
* A press on all/none will show all or no features and a second press on all/none will revert to the selection.
* There is no need to connect actions directly. Use this handlers signals instead.
*
* The handler does not take ownership of actions. All actions have to be checkable.
*/
class ActionButtonHandler :
public QObject
{
Q_OBJECT

public:
explicit ActionButtonHandler(QObject *parent);
virtual ~ActionButtonHandler() override;

/* Set action which will toggle between all and selected features. */
void setAllAction(QAction *action);

/* Set action which will toggle between no and selected features. */
void setNoneAction(QAction *action);

/* Add any action which can be checked or unchecked by all and none actions */
void addOtherAction(QAction *action);

signals:
/* Sent when all is triggered. Other actions will be selected accordingly using blocked signals */
void actionAllTriggered(QAction *action);

/* Sent when none is triggered. Other actions will be selected accordingly using blocked signals */
void actionNoneTriggered(QAction *action);

/* Sent when any but none or all action is triggered */
void actionOtherTriggered(QAction *action);

private:
void noneTriggered();
void allTriggered();
void otherTriggered();

/* Revert action checkstate to saved values */
void toggleSavedStateWithActions();

/* Save state of actions and set state to actionChecked */
void saveAndSetActionState(bool checkAction);

QAction *actionNone, *actionAll;

/* All other actions with their states saved as value before pressing none/all.
* Value is used to restore state when pressing none/all a second time. */
QHash<QAction *, bool> actionsOther;

enum
{
INVALID,
NONE, /* None was last pressed */
ALL, /* None was last time pressed */
ACTION /* Other actions was last pressed */
} lastTriggered = INVALID;
};

} // namespace gui
} // namespace atools

#endif // ATOOLS_ACTIONBUTTONHANDLER_H

0 comments on commit b682a14

Please sign in to comment.