qa: Replace deprecated QString::sprintf() by QString::asprintf()
[quassel.git] / src / uisupport / actioncollection.cpp
index a20d918..765d7f8 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   Copyright (C) 2005-2019 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************
  * Parts of this implementation are based on KDE's KActionCollection.      *
  ***************************************************************************/
 
-#include <QAction>
-
 #include "actioncollection.h"
 
+#include <QAction>
+#include <QDebug>
+#include <QMetaMethod>
+
 #include "action.h"
+#include "uisettings.h"
 
-ActionCollection::ActionCollection(QObject *parent) : QObject(parent) {
-  _connectTriggered = _connectHovered = false;
+void ActionCollection::addActions(const std::vector<std::pair<QString, Action*>>& actions)
+{
+    for (auto&& p : actions) {
+        addAction(p.first, p.second);
+    }
 }
 
-ActionCollection::~ActionCollection() {
+#ifndef HAVE_KDE
 
+int ActionCollection::count() const
+{
+    return actions().count();
 }
 
-void ActionCollection::clear() {
-  _actionByName.clear();
-  qDeleteAll(_actions);
-  _actions.clear();
+bool ActionCollection::isEmpty() const
+{
+    return actions().count();
 }
 
-QAction *ActionCollection::action(const QString &name) const {
-  return _actionByName.value(name, 0);
+void ActionCollection::clear()
+{
+    _actionByName.clear();
+    qDeleteAll(_actions);
+    _actions.clear();
 }
 
-QList<QAction *> ActionCollection::actions() const {
-  return _actions;
+QAction* ActionCollection::action(const QString& name) const
+{
+    return _actionByName.value(name, 0);
 }
 
-Action *ActionCollection::addAction(const QString &name, Action *action) {
-  QAction *act = addAction(name, action);
-  Q_ASSERT(act == action);
-  return action;
+QList<QAction*> ActionCollection::actions() const
+{
+    return _actions;
 }
 
-Action *ActionCollection::addAction(const QString &name, const QObject *receiver, const char *member) {
-  Action *a = new Action(this);
-  if(receiver && member)
-    connect(a, SIGNAL(triggered(bool)), receiver, member);
-  return addAction(name, a);
-}
+QAction* ActionCollection::addAction(const QString& name, QAction* action)
+{
+    if (!action)
+        return action;
+
+    const QString origName = action->objectName();
+    QString indexName = name;
+
+    if (indexName.isEmpty())
+        indexName = action->objectName();
+    else
+        action->setObjectName(indexName);
+    if (indexName.isEmpty())
+        indexName = indexName.asprintf("unnamed-%p", (void*)action);
+
+    // do we already have this action?
+    if (_actionByName.value(indexName, 0) == action)
+        return action;
+    // or maybe another action under this name?
+    if (QAction* oldAction = _actionByName.value(indexName))
+        takeAction(oldAction);
+
+    // do we already have this action under a different name?
+    int oldIndex = _actions.indexOf(action);
+    if (oldIndex != -1) {
+        _actionByName.remove(origName);
+        _actions.removeAt(oldIndex);
+    }
 
-QAction *ActionCollection::addAction(const QString &name, QAction *action) {
-  if(!action)
-    return action;
+    // add action
+    _actionByName.insert(indexName, action);
+    _actions.append(action);
 
-  const QString origName = action->objectName();
-  QString indexName = name;
+    foreach (QWidget* widget, _associatedWidgets) {
+        widget->addAction(action);
+    }
 
-  if(indexName.isEmpty())
-    indexName = action->objectName();
-  else
-    action->setObjectName(indexName);
-  if(indexName.isEmpty())
-    indexName = QString("unnamed-%1").arg((int)action, 16);
+    connect(action, &QObject::destroyed, this, &ActionCollection::actionDestroyed);
+    if (_connectHovered)
+        connect(action, &QAction::hovered, this, &ActionCollection::slotActionHovered);
+    if (_connectTriggered)
+        connect(action, &QAction::triggered, this, &ActionCollection::slotActionTriggered);
 
-  // do we already have this action?
-  if(_actionByName.value(indexName, 0) == action)
+    emit inserted(action);
     return action;
-  // or maybe another action under this name?
-  if(QAction *oldAction = _actionByName.value(indexName))
-    takeAction(oldAction);
-
-  // do we already have this action under a different name?
-  int oldIndex = _actions.indexOf(action);
-  if(oldIndex != -1) {
-    _actionByName.remove(origName);
-    _actions.removeAt(oldIndex);
-  }
-
-  // add action
-  _actionByName.insert(indexName, action);
-  _actions.append(action);
-
-  foreach(QWidget *widget, _associatedWidgets) {
-    widget->addAction(action);
-  }
-
-  connect(action, SIGNAL(destroyed(QObject *)), SLOT(actionDestroyed(QObject *)));
-  if(_connectHovered)
-    connect(action, SIGNAL(hovered()), SLOT(slotActionHovered()));
-  if(_connectTriggered)
-    connect(action, SIGNAL(triggered(bool)), SLOT(slotActionTriggered()));
-
-  emit inserted(action);
-  return action;
 }
 
-void ActionCollection::removeAction(QAction *action) {
-  delete takeAction(action);
+void ActionCollection::removeAction(QAction* action)
+{
+    delete takeAction(action);
 }
 
-QAction *ActionCollection::takeAction(QAction *action) {
-  if(!unlistAction(action))
-    return 0;
+QAction* ActionCollection::takeAction(QAction* action)
+{
+    if (!unlistAction(action))
+        return nullptr;
 
-  foreach(QWidget *widget, _associatedWidgets) {
-    widget->removeAction(action);
-  }
+    foreach (QWidget* widget, _associatedWidgets) {
+        widget->removeAction(action);
+    }
 
-  action->disconnect(this);
-  return action;
+    action->disconnect(this);
+    return action;
 }
 
-void ActionCollection::readSettings() {
-
+void ActionCollection::readSettings()
+{
+    ShortcutSettings s;
+    QStringList savedShortcuts = s.savedShortcuts();
+
+    foreach (const QString& name, _actionByName.keys()) {
+        if (!savedShortcuts.contains(name))
+            continue;
+        auto* action = qobject_cast<Action*>(_actionByName.value(name));
+        if (action)
+            action->setShortcut(s.loadShortcut(name), Action::ActiveShortcut);
+    }
 }
 
-void ActionCollection::writeSettings() const {
-
-
+void ActionCollection::writeSettings() const
+{
+    ShortcutSettings s;
+    foreach (const QString& name, _actionByName.keys()) {
+        auto* action = qobject_cast<Action*>(_actionByName.value(name));
+        if (!action)
+            continue;
+        if (!action->isShortcutConfigurable())
+            continue;
+        if (action->shortcut(Action::ActiveShortcut) == action->shortcut(Action::DefaultShortcut))
+            continue;
+        s.saveShortcut(name, action->shortcut(Action::ActiveShortcut));
+    }
 }
 
-void ActionCollection::slotActionTriggered() {
-  QAction *action = qobject_cast<QAction *>(sender());
-  if(action)
-    emit actionTriggered(action);
+void ActionCollection::slotActionTriggered()
+{
+    auto* action = qobject_cast<QAction*>(sender());
+    if (action)
+        emit actionTriggered(action);
 }
 
-void ActionCollection::slotActionHovered() {
-  QAction *action = qobject_cast<QAction *>(sender());
-  if(action)
-    emit actionHovered(action);
+void ActionCollection::slotActionHovered()
+{
+    auto* action = qobject_cast<QAction*>(sender());
+    if (action)
+        emit actionHovered(action);
 }
 
-void ActionCollection::actionDestroyed(QObject *obj) {
-  // remember that this is not an QAction anymore at this point
-  QAction *action = static_cast<QAction *>(obj);
+void ActionCollection::actionDestroyed(QObject* obj)
+{
+    // remember that this is not an QAction anymore at this point
+    auto* action = static_cast<QAction*>(obj);
 
-  unlistAction(action);
+    unlistAction(action);
 }
 
-void ActionCollection::connectNotify(const char *signal) {
-  if(_connectHovered && _connectTriggered)
-    return;
-
-  if(QMetaObject::normalizedSignature(SIGNAL(actionHovered(QAction*))) == signal) {
-    if(!_connectHovered) {
-      _connectHovered = true;
-      foreach (QAction* action, actions())
-        connect(action, SIGNAL(hovered()), SLOT(slotActionHovered()));
+void ActionCollection::connectNotify(const QMetaMethod& signal)
+{
+    if (_connectHovered && _connectTriggered)
+        return;
+
+    if (QMetaMethod::fromSignal(&ActionCollection::actionHovered) == signal) {
+        if (!_connectHovered) {
+            _connectHovered = true;
+            foreach (QAction* action, actions())
+                connect(action, &QAction::hovered, this, &ActionCollection::slotActionHovered);
+        }
     }
-  } else if(QMetaObject::normalizedSignature(SIGNAL(actionTriggered(QAction*))) == signal) {
-    if(!_connectTriggered) {
-      _connectTriggered = true;
-      foreach (QAction* action, actions())
-        connect(action, SIGNAL(triggered(bool)), SLOT(slotActionTriggered()));
+    else if (QMetaMethod::fromSignal(&ActionCollection::actionTriggered) == signal) {
+        if (!_connectTriggered) {
+            _connectTriggered = true;
+            foreach (QAction* action, actions())
+                connect(action, &QAction::triggered, this, &ActionCollection::slotActionTriggered);
+        }
     }
-  }
 
-  QObject::connectNotify(signal);
+    QObject::connectNotify(signal);
 }
 
-void ActionCollection::associateWidget(QWidget *widget) const {
-  foreach(QAction *action, actions()) {
-    if(!widget->actions().contains(action))
-      widget->addAction(action);
-  }
+void ActionCollection::associateWidget(QWidget* widget) const
+{
+    foreach (QAction* action, actions()) {
+        if (!widget->actions().contains(action))
+            widget->addAction(action);
+    }
 }
 
-void ActionCollection::addAssociatedWidget(QWidget *widget) {
-  if(!_associatedWidgets.contains(widget)) {
-    widget->addActions(actions());
-    _associatedWidgets.append(widget);
-    connect(widget, SIGNAL(destroyed(QObject *)), SLOT(associatedWidgetDestroyed(QObject *)));
-  }
+void ActionCollection::addAssociatedWidget(QWidget* widget)
+{
+    if (!_associatedWidgets.contains(widget)) {
+        widget->addActions(actions());
+        _associatedWidgets.append(widget);
+        connect(widget, &QObject::destroyed, this, &ActionCollection::associatedWidgetDestroyed);
+    }
 }
 
-void ActionCollection::removeAssociatedWidget(QWidget *widget) {
-  foreach(QAction *action, actions())
-    widget->removeAction(action);
-  _associatedWidgets.removeAll(widget);
-  disconnect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(associatedWidgetDestroyed(QObject *)));
+void ActionCollection::removeAssociatedWidget(QWidget* widget)
+{
+    foreach (QAction* action, actions())
+        widget->removeAction(action);
+    _associatedWidgets.removeAll(widget);
+    disconnect(widget, &QObject::destroyed, this, &ActionCollection::associatedWidgetDestroyed);
 }
 
-QList<QWidget *> ActionCollection::associatedWidgets() const {
-  return _associatedWidgets;
+QList<QWidget*> ActionCollection::associatedWidgets() const
+{
+    return _associatedWidgets;
 }
 
-void ActionCollection::clearAssociatedWidgets() {
-  foreach(QWidget *widget, _associatedWidgets)
-    foreach(QAction *action, actions())
-      widget->removeAction(action);
+void ActionCollection::clearAssociatedWidgets()
+{
+    foreach (QWidget* widget, _associatedWidgets)
+        foreach (QAction* action, actions())
+            widget->removeAction(action);
 
-  _associatedWidgets.clear();
+    _associatedWidgets.clear();
 }
 
-bool ActionCollection::unlistAction(QAction *action) {
-  // This might be called with a partly destroyed QAction!
+void ActionCollection::associatedWidgetDestroyed(QObject* obj)
+{
+    _associatedWidgets.removeAll(static_cast<QWidget*>(obj));
+}
+
+bool ActionCollection::unlistAction(QAction* action)
+{
+    // This might be called with a partly destroyed QAction!
 
-  int index = _actions.indexOf(action);
-  if(index == -1) return false;
+    int index = _actions.indexOf(action);
+    if (index == -1)
+        return false;
 
-  QString name = action->objectName();
-  _actionByName.remove(name);
-  _actions.removeAt(index);
+    QString name = action->objectName();
+    _actionByName.remove(name);
+    _actions.removeAt(index);
 
-  // TODO: remove from ActionCategory if we ever get that
+    // TODO: remove from ActionCategory if we ever get that
 
-  return true;
+    return true;
 }
+
+#endif /* HAVE_KDE */