core: Avoid confusing log message when legacy client connects
[quassel.git] / src / common / quassel.cpp
index 16b8887..c75836a 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-2016 by the Quassel Project                        *
+ *   Copyright (C) 2005-2018 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -20,7 +20,9 @@
 
 #include "quassel.h"
 
+#include <algorithm>
 #include <iostream>
+
 #include <signal.h>
 #if !defined Q_OS_WIN && !defined Q_OS_MAC
 #  include <sys/types.h>
@@ -34,6 +36,7 @@
 #include <QFileInfo>
 #include <QHostAddress>
 #include <QLibraryInfo>
+#include <QMetaEnum>
 #include <QSettings>
 #include <QTranslator>
 #include <QUuid>
@@ -454,19 +457,6 @@ void Quassel::logFatalMessage(const char *msg)
 }
 
 
-Quassel::Features Quassel::features()
-{
-    Features feats = 0;
-    for (int i = 1; i <= NumFeatures; i <<= 1)
-        feats |= (Feature)i;
-
-    // Disable DCC until it is ready
-    feats &= ~Feature::DccFileTransfer;
-
-    return feats;
-}
-
-
 const QString &Quassel::coreDumpFileName()
 {
     if (_coreDumpFileName.isEmpty()) {
@@ -678,3 +668,99 @@ void Quassel::loadTranslation(const QLocale &locale)
     quasselTranslator->load(QString("%1").arg(locale.name()), translationDirPath());
 #endif
 }
+
+
+// ---- Quassel::Features ---------------------------------------------------------------------------------------------
+
+Quassel::Features::Features()
+{
+    QStringList features;
+
+    // TODO Qt5: Use QMetaEnum::fromType()
+    auto featureEnum = Quassel::staticMetaObject.enumerator(Quassel::staticMetaObject.indexOfEnumerator("Feature"));
+    _features.resize(featureEnum.keyCount(), true);  // enable all known features to true
+}
+
+
+Quassel::Features::Features(const QStringList &features, LegacyFeatures legacyFeatures)
+{
+    // TODO Qt5: Use QMetaEnum::fromType()
+    auto featureEnum = Quassel::staticMetaObject.enumerator(Quassel::staticMetaObject.indexOfEnumerator("Feature"));
+    _features.resize(featureEnum.keyCount(), false);
+
+    for (auto &&feature : features) {
+        int i = featureEnum.keyToValue(qPrintable(feature));
+        if (i >= 0) {
+            _features[i] = true;
+        }
+        else {
+            _unknownFeatures << feature;
+        }
+    }
+
+    if (legacyFeatures) {
+        // TODO Qt5: Use QMetaEnum::fromType()
+        auto legacyFeatureEnum = Quassel::staticMetaObject.enumerator(Quassel::staticMetaObject.indexOfEnumerator("LegacyFeature"));
+        for (quint32 mask = 0x0001; mask <= 0x8000; mask <<=1) {
+            if (static_cast<quint32>(legacyFeatures) & mask) {
+                int i = featureEnum.keyToValue(legacyFeatureEnum.valueToKey(mask));
+                if (i >= 0) {
+                    _features[i] = true;
+                }
+            }
+        }
+    }
+}
+
+
+bool Quassel::Features::isEnabled(Feature feature) const
+{
+    size_t i = static_cast<size_t>(feature);
+    return i < _features.size() ? _features[i] : false;
+}
+
+
+QStringList Quassel::Features::toStringList(bool enabled) const
+{
+    // Check if any feature is enabled
+    if (!enabled && std::all_of(_features.cbegin(), _features.cend(), [](bool feature) { return !feature; })) {
+        return QStringList{} << "NoFeatures";
+    }
+
+    QStringList result;
+
+    // TODO Qt5: Use QMetaEnum::fromType()
+    auto featureEnum = Quassel::staticMetaObject.enumerator(Quassel::staticMetaObject.indexOfEnumerator("Feature"));
+    for (quint32 i = 0; i < _features.size(); ++i) {
+        if (_features[i] == enabled) {
+            result << featureEnum.key(i);
+        }
+    }
+    return result;
+}
+
+
+Quassel::LegacyFeatures Quassel::Features::toLegacyFeatures() const
+{
+    // TODO Qt5: Use LegacyFeatures (flag operators for enum classes not supported in Qt4)
+    quint32 result{0};
+    // TODO Qt5: Use QMetaEnum::fromType()
+    auto featureEnum = Quassel::staticMetaObject.enumerator(Quassel::staticMetaObject.indexOfEnumerator("Feature"));
+    auto legacyFeatureEnum = Quassel::staticMetaObject.enumerator(Quassel::staticMetaObject.indexOfEnumerator("LegacyFeature"));
+
+    for (quint32 i = 0; i < _features.size(); ++i) {
+        if (_features[i]) {
+            int v = legacyFeatureEnum.keyToValue(featureEnum.key(i));
+            if (v >= 0) {
+                result |= v;
+            }
+        }
+    }
+    return static_cast<LegacyFeatures>(result);
+}
+
+
+QStringList Quassel::Features::unknownFeatures() const
+{
+    return _unknownFeatures;
+}