QObjects are non-copyable for good reasons. SyncableObject, although
deriving from QObject, was made sort-of copyable by adding custom copy
ctor and copy assignment operator that did not make a full copy of the
underlying QObject, but just copied (most) properties. Several classes
deriving from SyncableObject then implemented their own versions of
those special member functions on top of that. This was not only
rather unexpected and intransparent behavior due to the incomplete
copy functionality, but also a most fragile hack since one had to
remember to update those functions when adding or modifying
properties.
In addition, newer compilers apply a somewhat stricter interpretation
of the C++ standard, basically enforcing the Rule of Three by omitting
implicit generation of copy ctor and/or copy assignment operating
in case certain user-defined special member functions exist. In
particular, Clang 10 started to emit several warnings (and we already
worked around a similar warning from GCC 9+ in
cc21148).
Instead of adding more workarounds further obfuscating matters, remove
the relevant special member functions altogether and thus make
SyncableObject and its derivatives non-copyable as they should be.
Modify affected code to cope with this cleanly, and without abusing
unexpected behavior.
#include "network.h"
-AliasManager& AliasManager::operator=(const AliasManager& other)
-{
- if (this == &other)
- return *this;
-
- SyncableObject::operator=(other);
- _aliases = other._aliases;
- return *this;
-}
-
int AliasManager::indexOf(const QString& name) const
{
for (int i = 0; i < _aliases.count(); i++) {
{
setAllowClientUpdates(true);
}
- AliasManager& operator=(const AliasManager& other);
struct Alias
{
#include "expressionmatch.h"
#include "util.h"
-HighlightRuleManager& HighlightRuleManager::operator=(const HighlightRuleManager& other)
-{
- if (this == &other)
- return *this;
-
- SyncableObject::operator=(other);
- _highlightRuleList = other._highlightRuleList;
- _nicksCaseSensitive = other._nicksCaseSensitive;
- _highlightNick = other._highlightNick;
- return *this;
-}
-
int HighlightRuleManager::indexOf(int id) const
{
for (int i = 0; i < _highlightRuleList.count(); i++) {
{
setAllowClientUpdates(true);
}
- HighlightRuleManager& operator=(const HighlightRuleManager& other);
/**
* Individual highlight rule
#include <QDebug>
#include <QStringList>
-IgnoreListManager& IgnoreListManager::operator=(const IgnoreListManager& other)
-{
- if (this == &other)
- return *this;
-
- SyncableObject::operator=(other);
- _ignoreList = other._ignoreList;
- return *this;
-}
-
int IgnoreListManager::indexOf(const QString& ignore) const
{
for (int i = 0; i < _ignoreList.count(); i++) {
{
setAllowClientUpdates(true);
}
- IgnoreListManager& operator=(const IgnoreListManager& other);
enum IgnoreType
{
});
}
-SyncableObject::SyncableObject(const SyncableObject& other, QObject* parent)
- : SyncableObject(QString{}, parent)
-{
- _initialized = other._initialized;
- _allowClientUpdates = other._allowClientUpdates;
-}
-
SyncableObject::~SyncableObject()
{
QList<SignalProxy*>::iterator proxyIter = _signalProxies.begin();
}
}
-SyncableObject& SyncableObject::operator=(const SyncableObject& other)
-{
- if (this == &other)
- return *this;
-
- _initialized = other._initialized;
- _allowClientUpdates = other._allowClientUpdates;
- return *this;
-}
-
bool SyncableObject::isInitialized() const
{
return _initialized;
public:
SyncableObject(QObject* parent = nullptr);
SyncableObject(const QString& objectName, QObject* parent = nullptr);
- SyncableObject(const SyncableObject& other, QObject* parent = nullptr);
~SyncableObject() override;
//! Stores the object's state into a QVariantMap.
protected:
void sync_call__(SignalProxy::ProxyMode modeType, const char* funcname, ...) const;
- SyncableObject& operator=(const SyncableObject& other);
-
signals:
void initDone();
void updatedRemotely();
const AliasManager& AliasesModel::aliasManager() const
{
- if (_configChanged)
- return _clonedAliasManager;
- else
- return *Client::aliasManager();
+ return _clonedAliasManager ? *_clonedAliasManager : *Client::aliasManager();
}
AliasManager& AliasesModel::aliasManager()
{
- if (_configChanged)
- return _clonedAliasManager;
- else
- return *Client::aliasManager();
+ return _clonedAliasManager ? *_clonedAliasManager : *Client::aliasManager();
}
AliasManager& AliasesModel::cloneAliasManager()
{
- if (!_configChanged) {
- _clonedAliasManager = *Client::aliasManager();
- _configChanged = true;
+ if (!_clonedAliasManager) {
+ _clonedAliasManager = std::make_unique<ClientAliasManager>();
+ _clonedAliasManager->fromVariantMap(Client::aliasManager()->toVariantMap());
emit configChanged(true);
}
- return _clonedAliasManager;
+ return *_clonedAliasManager;
}
void AliasesModel::revert()
{
- if (!_configChanged)
+ if (!_clonedAliasManager)
return;
- _configChanged = false;
- emit configChanged(false);
beginResetModel();
+ _clonedAliasManager.reset();
endResetModel();
+ emit configChanged(false);
}
void AliasesModel::commit()
{
- if (!_configChanged)
+ if (!_clonedAliasManager)
return;
- Client::aliasManager()->requestUpdate(_clonedAliasManager.toVariantMap());
+ Client::aliasManager()->requestUpdate(_clonedAliasManager->toVariantMap());
revert();
}
void AliasesModel::clientDisconnected()
{
- // clear
- _clonedAliasManager = ClientAliasManager();
_modelReady = false;
beginResetModel();
+ _clonedAliasManager.reset();
endResetModel();
emit modelReady(false);
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef ALIASESMODEL_H
-#define ALIASESMODEL_H
+#pragma once
+
+#include <memory>
#include <QAbstractItemModel>
-#include <QPointer>
#include "clientaliasmanager.h"
inline int rowCount(const QModelIndex& parent = QModelIndex()) const override;
inline int columnCount(const QModelIndex& parent = QModelIndex()) const override;
- inline bool hasConfigChanged() const { return _configChanged; }
+ inline bool hasConfigChanged() const { return static_cast<bool>(_clonedAliasManager); }
inline bool isReady() const { return _modelReady; }
public slots:
void modelReady(bool);
private:
- ClientAliasManager _clonedAliasManager;
- bool _configChanged{false};
+ std::unique_ptr<ClientAliasManager> _clonedAliasManager;
bool _modelReady{false};
const AliasManager& aliasManager() const;
Q_UNUSED(parent);
return isReady() ? 2 : 0;
}
-
-#endif // ALIASESMODEL_H
if (ruleManager == nullptr)
return;
- auto clonedManager = HighlightRuleManager();
+ HighlightRuleManager clonedManager;
clonedManager.fromVariantMap(ruleManager->toVariantMap());
clonedManager.clear();
save();
}
- auto clonedManager = HighlightRuleManager();
+ HighlightRuleManager clonedManager;
clonedManager.fromVariantMap(Client::highlightRuleManager()->toVariantMap());
for (const auto& variant : notificationSettings.highlightList()) {
void DccSettingsPage::defaults()
{
- _localConfig = DccConfig();
+ _localConfig.fromVariantMap(DccConfig{}.toVariantMap());
SettingsPage::load();
widgetHasChanged();
}
void DccSettingsPage::load()
{
- _localConfig = isClientConfigValid() ? *_clientConfig : DccConfig{};
+ _localConfig.fromVariantMap(isClientConfigValid() ? _clientConfig->toVariantMap() : DccConfig{}.toVariantMap());
SettingsPage::load();
widgetHasChanged();
}
if (manager.contains(item.contents()))
return false;
beginInsertRows(QModelIndex(), rowCount(), rowCount());
- // manager.addIgnoreListItem(item);
manager.addIgnoreListItem(item.type(), item.contents(), item.isRegEx(), item.strictness(), item.scope(), item.scopeRule(), item.isEnabled());
endInsertRows();
return true;
const IgnoreListManager& IgnoreListModel::ignoreListManager() const
{
- if (_configChanged)
- return _clonedIgnoreListManager;
- else
- return *Client::ignoreListManager();
+ return _clonedIgnoreListManager ? *_clonedIgnoreListManager : *Client::ignoreListManager();
}
IgnoreListManager& IgnoreListModel::ignoreListManager()
{
- if (_configChanged)
- return _clonedIgnoreListManager;
- else
- return *Client::ignoreListManager();
+ return _clonedIgnoreListManager ? *_clonedIgnoreListManager : *Client::ignoreListManager();
}
IgnoreListManager& IgnoreListModel::cloneIgnoreListManager()
{
- if (!_configChanged) {
- _clonedIgnoreListManager = *Client::ignoreListManager();
- _configChanged = true;
+ if (!_clonedIgnoreListManager) {
+ _clonedIgnoreListManager = std::make_unique<ClientIgnoreListManager>();
+ _clonedIgnoreListManager->fromVariantMap(Client::ignoreListManager()->toVariantMap());
emit configChanged(true);
}
- return _clonedIgnoreListManager;
+ return *_clonedIgnoreListManager;
}
void IgnoreListModel::revert()
{
- if (!_configChanged)
+ if (!_clonedIgnoreListManager)
return;
- _configChanged = false;
- emit configChanged(false);
beginResetModel();
+ _clonedIgnoreListManager.reset();
endResetModel();
+ emit configChanged(false);
}
void IgnoreListModel::commit()
{
- if (!_configChanged)
+ if (!_clonedIgnoreListManager)
return;
- Client::ignoreListManager()->requestUpdate(_clonedIgnoreListManager.toVariantMap());
+ Client::ignoreListManager()->requestUpdate(_clonedIgnoreListManager->toVariantMap());
revert();
}
void IgnoreListModel::clientDisconnected()
{
- // clear
- _clonedIgnoreListManager = ClientIgnoreListManager();
_modelReady = false;
beginResetModel();
+ _clonedIgnoreListManager.reset();
endResetModel();
emit modelReady(false);
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef IGNORELISTMODEL_H
-#define IGNORELISTMODEL_H
+#pragma once
+
+#include <memory>
#include <QAbstractItemModel>
-#include <QPointer>
#include "clientignorelistmanager.h"
inline int rowCount(const QModelIndex& parent = QModelIndex()) const override;
inline int columnCount(const QModelIndex& parent = QModelIndex()) const override;
- inline bool hasConfigChanged() const { return _configChanged; }
+ inline bool hasConfigChanged() const { return static_cast<bool>(_clonedIgnoreListManager); }
inline bool isReady() const { return _modelReady; }
const IgnoreListManager::IgnoreListItem& ignoreListItemAt(int row) const;
void modelReady(bool);
private:
- ClientIgnoreListManager _clonedIgnoreListManager;
- bool _configChanged{false};
+ std::unique_ptr<ClientIgnoreListManager> _clonedIgnoreListManager;
bool _modelReady{false};
const IgnoreListManager& ignoreListManager() const;
Q_UNUSED(parent);
return isReady() ? 3 : 0;
}
-
-#endif // IGNORELISTMODEL_H