From 8bd1969e7f0d5a5809761a05943954f969990fd3 Mon Sep 17 00:00:00 2001 From: Samuel Ghinet Date: Thu, 2 Sep 2021 14:35:41 +0300 Subject: [PATCH] Enhance logging capabilities for wizard classes * Added QDebug operator<< for the Field classes so that they could be inspected during runtime (i.e. logged) * Added optional QDebug operator<< overloads for QVariant (wizarddebug.h) - to better visualize the data parsed from the wizard.json files (QVariant objects), by using a format more in the like of json. Change-Id: I53a729b24e4f2d9c9acf1ed802ac9dc3bb67f373 Reviewed-by: Eike Ziller --- src/libs/utils/wizard.cpp | 31 +++++ src/libs/utils/wizard.h | 7 ++ src/plugins/coreplugin/generatedfile.cpp | 15 +++ src/plugins/coreplugin/generatedfile.h | 4 + src/plugins/projectexplorer/CMakeLists.txt | 1 + .../jsonwizard/jsonfieldpage.cpp | 61 ++++++--- .../jsonwizard/jsonfieldpage.h | 20 +-- .../jsonwizard/jsonfieldpage_p.h | 110 +++++++++++++++- .../projectexplorer/jsonwizard/jsonwizard.h | 20 +++ .../projectexplorer/jsonwizard/jsonwizard.pri | 3 +- .../jsonwizard/jsonwizardfilegenerator.h | 12 ++ .../projectexplorer/jsonwizard/wizarddebug.h | 117 ++++++++++++++++++ .../projectexplorer/projectexplorer.qbs | 3 +- 13 files changed, 373 insertions(+), 31 deletions(-) create mode 100644 src/plugins/projectexplorer/jsonwizard/wizarddebug.h diff --git a/src/libs/utils/wizard.cpp b/src/libs/utils/wizard.cpp index d176137642c..e22aae7a588 100644 --- a/src/libs/utils/wizard.cpp +++ b/src/libs/utils/wizard.cpp @@ -583,6 +583,21 @@ public: WizardProgressItem *m_startItem = nullptr; }; +inline QDebug &operator<<(QDebug &debug, const WizardProgressPrivate &progress) +{ + debug << "items:" << progress.m_items.size() + << "; visited:" << progress.m_visitedItems.size() + << "; reachable:" << progress.m_reachableItems.size(); + + return debug; +} + +QDebug &operator<<(QDebug &debug, const WizardProgress &progress) +{ + debug << "WizardProgress{_: " << *progress.d_ptr << "}"; + return debug; +} + class WizardProgressItemPrivate { WizardProgressItem *q_ptr; @@ -597,6 +612,22 @@ public: WizardProgressItem *m_nextShownItem; }; +inline QDebug &operator<<(QDebug &debug, const WizardProgressItemPrivate &item) +{ + debug << "title:" << item.m_title + << "; word wrap:" << item.m_titleWordWrap + << "; progress:" << *item.m_wizardProgress + << "; pages:" << item.m_pages; + + return debug; +} + +QDebug &operator<<(QDebug &debug, const WizardProgressItem &item) +{ + debug << "WizardProgressItem{_: " << *item.d_ptr << "}"; + return debug; +} + bool WizardProgressPrivate::isNextItem(WizardProgressItem *item, WizardProgressItem *nextItem) { QHash visitedItems; diff --git a/src/libs/utils/wizard.h b/src/libs/utils/wizard.h index 02be18e2276..885406298cb 100644 --- a/src/libs/utils/wizard.h +++ b/src/libs/utils/wizard.h @@ -133,6 +133,8 @@ private: friend class Wizard; friend class WizardProgressItem; + friend QTCREATOR_UTILS_EXPORT QDebug &operator<<(QDebug &debug, const WizardProgress &progress); + Q_DECLARE_PRIVATE(WizardProgress) class WizardProgressPrivate *d_ptr; @@ -163,10 +165,15 @@ protected: private: friend class WizardProgress; + friend QTCREATOR_UTILS_EXPORT QDebug &operator<<(QDebug &d, const WizardProgressItem &item); Q_DECLARE_PRIVATE(WizardProgressItem) class WizardProgressItemPrivate *d_ptr; }; +QTCREATOR_UTILS_EXPORT QDebug &operator<<(QDebug &debug, const WizardProgress &progress); + +QTCREATOR_UTILS_EXPORT QDebug &operator<<(QDebug &debug, const WizardProgressItem &item); + } // namespace Utils diff --git a/src/plugins/coreplugin/generatedfile.cpp b/src/plugins/coreplugin/generatedfile.cpp index 69fe1e85c79..0ddcfdb66c5 100644 --- a/src/plugins/coreplugin/generatedfile.cpp +++ b/src/plugins/coreplugin/generatedfile.cpp @@ -64,6 +64,21 @@ public: GeneratedFile::Attributes attributes; }; +inline QDebug &operator<<(QDebug &debug, const Core::GeneratedFilePrivate &file) +{ + debug << "path: " << file.path + << "; editorId: " << file.editorId.toString() + << "; binary: " << file.binary + << "; contents: " << file.contents.size(); + return debug; +} + +QDebug &operator<<(QDebug &debug, const Core::GeneratedFile &file) +{ + debug << "GeneratedFile{_: " << *file.m_d << "}"; + return debug; +} + GeneratedFilePrivate::GeneratedFilePrivate(const QString &path) : // FIXME Don't use - Remove when possible path(FilePath::fromString(path).cleanPath()), attributes({}) diff --git a/src/plugins/coreplugin/generatedfile.h b/src/plugins/coreplugin/generatedfile.h index de83a1942da..c4d33ecb349 100644 --- a/src/plugins/coreplugin/generatedfile.h +++ b/src/plugins/coreplugin/generatedfile.h @@ -91,8 +91,12 @@ public: private: QSharedDataPointer m_d; + + friend CORE_EXPORT QDebug &operator<<(QDebug &debug, const Core::GeneratedFile &file); }; +CORE_EXPORT QDebug &operator<<(QDebug &debug, const Core::GeneratedFile &file); + using GeneratedFiles = QList; } // namespace Core diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index 6e2970af9ab..a8e63b8f36c 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -102,6 +102,7 @@ add_qtc_plugin(ProjectExplorer jsonwizard/jsonwizardpagefactory.cpp jsonwizard/jsonwizardpagefactory.h jsonwizard/jsonwizardpagefactory_p.cpp jsonwizard/jsonwizardpagefactory_p.h + jsonwizard/wizarddebug.h jsonwizard/jsonwizardscannergenerator.cpp jsonwizard/jsonwizardscannergenerator.h kit.cpp kit.h kitchooser.cpp kitchooser.h diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp index 43e1a01e5a1..daaea5ffbf0 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp @@ -153,7 +153,7 @@ JsonFieldPage::Field::~Field() delete d->m_label; } -QString JsonFieldPage::Field::type() +QString JsonFieldPage::Field::type() const { return d->m_type; } @@ -301,17 +301,17 @@ QWidget *JsonFieldPage::Field::widget(const QString &displayName, JsonFieldPage return d->m_widget; } -QString JsonFieldPage::Field::name() +QString JsonFieldPage::Field::name() const { return d->m_name; } -QString JsonFieldPage::Field::displayName() +QString JsonFieldPage::Field::displayName() const { return d->m_displayName; } -QString JsonFieldPage::Field::toolTip() +QString JsonFieldPage::Field::toolTip() const { return d->m_toolTip; } @@ -321,12 +321,12 @@ QString JsonFieldPage::Field::persistenceKey() const return d->m_persistenceKey; } -bool JsonFieldPage::Field::isMandatory() +bool JsonFieldPage::Field::isMandatory() const { return d->m_isMandatory; } -bool JsonFieldPage::Field::hasSpan() +bool JsonFieldPage::Field::hasSpan() const { return d->m_hasSpan; } @@ -351,11 +351,11 @@ QWidget *JsonFieldPage::Field::widget() const return d->m_widget; } -void JsonFieldPage::Field::setTexts(const QString &n, const QString &dn, const QString &tt) +void JsonFieldPage::Field::setTexts(const QString &name, const QString &displayName, const QString &toolTip) { - d->m_name = n; - d->m_displayName = dn; - d->m_toolTip = tt; + d->m_name = name; + d->m_displayName = displayName; + d->m_toolTip = toolTip; } void JsonFieldPage::Field::setIsMandatory(bool b) @@ -389,6 +389,29 @@ void JsonFieldPage::Field::setPersistenceKey(const QString &key) d->m_persistenceKey = key; } +inline QDebug &operator<<(QDebug &debug, const JsonFieldPage::Field::FieldPrivate &field) +{ + debug << "name:" << field.m_name + << "; displayName:" << field.m_displayName + << "; type:" << field.m_type + << "; mandatory:" << field.m_isMandatory + << "; hasUserChanges:" << field.m_hasUserChanges + << "; visibleExpression:" << field.m_visibleExpression + << "; enabledExpression:" << field.m_enabledExpression + << "; isComplete:" << field.m_isCompleteExpando + << "; isCompleteMessage:" << field.m_isCompleteExpandoMessage + << "; persistenceKey:" << field.m_persistenceKey; + + return debug; +} + +QDebug &operator<<(QDebug &debug, const JsonFieldPage::Field &field) +{ + debug << "Field{_: " << *field.d << "; subclass: " << field.toString() << "}"; + + return debug; +} + // -------------------------------------------------------------------- // LabelFieldData: // -------------------------------------------------------------------- @@ -896,7 +919,7 @@ bool CheckBoxField::parseData(const QVariant &data, QString *errorMessage) m_checkedValue = consumeValue(tmp, "checkedValue", true).toString(); m_uncheckedValue = consumeValue(tmp, "uncheckedValue", false).toString(); if (m_checkedValue == m_uncheckedValue) { - *errorMessage= QCoreApplication::translate("ProjectExplorer::JsonFieldPage", + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", "CheckBox (\"%1\") values for checked and unchecked state are identical.") .arg(name()); return false; @@ -968,8 +991,8 @@ QVariant CheckBoxField::toSettings() const std::unique_ptr createStandardItemFromListItem(const QVariant &item, QString *errorMessage) { if (item.type() == QVariant::List) { - *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "No JSON lists allowed inside List items."); + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", + "No JSON lists allowed inside List items."); return {}; } auto standardItem = std::make_unique(); @@ -1101,7 +1124,7 @@ void ListField::initializeData(MacroExpander *expander) qWarning().noquote() << QString("Icon file \"%1\" not found.").arg(QDir::toNativeSeparators(iconPath)); } } else { - qWarning().noquote() << QString("%1 (\"%2\") has no parentWidget JsonFieldPage to get the icon path.").arg(type(), name()); + qWarning().noquote() << QString("%1 (\"%2\") has no parentWidget JsonFieldPage to get the icon path.").arg(type(), name()); } } expandedValuesItems.append(expandedValuesItem); @@ -1132,7 +1155,7 @@ void ListField::setSelectionModel(QItemSelectionModel *selectionModel) m_selectionModel = selectionModel; } -QSize ListField::maxIconSize() +QSize ListField::maxIconSize() const { return m_maxIconSize; } @@ -1173,7 +1196,7 @@ QVariant ListField::toSettings() const void ComboBoxField::setup(JsonFieldPage *page, const QString &name) { - auto w = qobject_cast(widget()); + auto w = qobject_cast(widget()); QTC_ASSERT(w, return); w->setModel(itemModel()); w->setInsertPolicy(QComboBox::NoInsert); @@ -1217,13 +1240,13 @@ void ComboBoxField::initializeData(MacroExpander *expander) { ListField::initializeData(expander); // refresh also the current text of the combobox - auto w = qobject_cast(widget()); + auto w = qobject_cast(widget()); w->setCurrentIndex(selectionModel()->currentIndex().row()); } QVariant ComboBoxField::toSettings() const { - if (auto w = qobject_cast(widget())) + if (auto w = qobject_cast(widget())) return w->currentData(ValueRole); return {}; } @@ -1269,7 +1292,7 @@ void IconListField::initializeData(MacroExpander *expander) w->setSpacing(spacing); w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - // adding a third hight of the icon to see following items if there are some + // adding 1/3 height of the icon to see following items if there are some w->setMinimumHeight(maxIconSize().height() + maxIconSize().height() / 3); w->setIconSize(maxIconSize()); } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h index 5ef115cfbf1..95b81713eae 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h @@ -74,18 +74,18 @@ public: virtual bool validate(Utils::MacroExpander *expander, QString *message); void initialize(Utils::MacroExpander *expander); - virtual void cleanup(Utils::MacroExpander *expander) { Q_UNUSED(expander) } + virtual void cleanup(Utils::MacroExpander *expander) { Q_UNUSED(expander) } virtual bool suppressName() const { return false; } QWidget *widget(const QString &displayName, JsonFieldPage *page); - QString name(); - QString displayName(); - QString toolTip(); + QString name() const; + QString displayName() const; + QString toolTip() const; QString persistenceKey() const; - bool isMandatory(); - bool hasSpan(); + bool isMandatory() const; + bool hasSpan() const; bool hasUserChanges() const; protected: @@ -96,14 +96,14 @@ public: virtual void setup(JsonFieldPage *page, const QString &name) { Q_UNUSED(page); Q_UNUSED(name) } - QString type(); + QString type() const; void setHasUserChanges(); private: virtual void fromSettings(const QVariant &value); virtual QVariant toSettings() const; - void setTexts(const QString &n, const QString &dn, const QString &tt); + void setTexts(const QString &name, const QString &displayName, const QString &toolTip); void setIsMandatory(bool b); void setHasSpan(bool b); @@ -111,8 +111,10 @@ public: void setEnabledExpression(const QVariant &v); void setIsCompleteExpando(const QVariant &v, const QString &m); void setPersistenceKey(const QString &key); + virtual QString toString() const = 0; friend class JsonFieldPage; + friend PROJECTEXPLORER_EXPORT QDebug &operator<<(QDebug &d, const Field &f); const std::unique_ptr d; }; @@ -153,4 +155,6 @@ private: Utils::MacroExpander *m_expander; }; +PROJECTEXPLORER_EXPORT QDebug &operator<<(QDebug &debug, const JsonFieldPage::Field &field); + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h index c6972505ebc..d41af7f410c 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h @@ -32,13 +32,13 @@ #include #include #include +#include #include #include #include QT_BEGIN_NAMESPACE -class QStandardItem; class QStandardItemModel; class QItemSelectionModel; QT_END_NAMESPACE @@ -78,6 +78,14 @@ public: class LabelField : public JsonFieldPage::Field { private: + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "LabelField{text:" << m_text << "}"; + return result; + } + QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override; bool parseData(const QVariant &data, QString *errorMessage) override; @@ -91,6 +99,14 @@ public: bool suppressName() const override { return true; } private: + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "SpacerField{factor:" << m_factor << "}"; + return result; + } + bool parseData(const QVariant &data, QString *errorMessage) override; QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override; @@ -113,6 +129,22 @@ private: void setupCompletion(Utils::FancyLineEdit *lineEdit); + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "LineEditField{currentText:" << m_currentText + << "; default:" << m_defaultText + << "; placeholder:" << m_placeholderText + << "; history id:" << m_historyId + << "; validator: " << m_validatorRegExp.pattern() + << "; fixupExpando: " << m_fixupExpando + << "; completion: " << QString::number((int)m_completion) + << "}"; + return result; + + } + bool m_isModified = false; bool m_isValidating = false; bool m_restoreLastHistoryItem = false; @@ -143,6 +175,17 @@ private: void fromSettings(const QVariant &value) override; QVariant toSettings() const override; + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "TextEditField{default:" << m_defaultText + << "; rich:" << m_acceptRichText + << "; disabled: " << m_disabledText + << "}"; + return result; + } + QString m_defaultText; bool m_acceptRichText = false; QString m_disabledText; @@ -166,6 +209,19 @@ private: void fromSettings(const QVariant &value) override; QVariant toSettings() const override; + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "PathChooser{path:" << m_path + << "; base:" << m_basePath + << "; historyId:" << m_historyId + << "; kind:" << (int)Utils::PathChooser::ExistingDirectory + << "; currentPath:" << m_currentPath + << "}"; + return result; + } + QString m_path; QString m_basePath; QString m_historyId; @@ -191,6 +247,20 @@ private: void fromSettings(const QVariant &value) override; QVariant toSettings() const override; + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "CheckBoxField{checked:" << m_checkedValue + << "; unchecked: " + m_uncheckedValue + << "; checkedExpression: QVariant(" + << m_checkedExpression.typeName() << ":" << m_checkedExpression.toString() + << ")" + << "; isModified:" << m_isModified + << "}"; + return result; + } + QString m_checkedValue; QString m_uncheckedValue; QVariant m_checkedExpression; @@ -220,7 +290,27 @@ public: QStandardItemModel *itemModel(); QItemSelectionModel *selectionModel() const; void setSelectionModel(QItemSelectionModel *selectionModel); - QSize maxIconSize(); + QSize maxIconSize() const; + + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "ListField{index:" << m_index + << "; disabledIndex:" << m_disabledIndex + << "; savedIndex: " << m_savedIndex + << "; items Count: " << m_itemList.size() + << "; items:"; + + if (m_itemList.empty()) + out << "(empty)"; + else + out << m_itemList.front()->text() << ", ..."; + + out << "}"; + + return result; + } private: void addPossibleIconSize(const QIcon &icon); @@ -246,6 +336,14 @@ private: QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override; void initializeData(Utils::MacroExpander *expander) override; QVariant toSettings() const override; + + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "ComboBox{" << ListField::toString() << "}"; + return result; + } }; class IconListField : public ListField @@ -254,6 +352,14 @@ public: void setup(JsonFieldPage *page, const QString &name) override; QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override; void initializeData(Utils::MacroExpander *expander) override; + + QString toString() const override + { + QString result; + QTextStream out(&result); + out << "IconList{" << ListField::toString()<< "}"; + return result; + } }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.h b/src/plugins/projectexplorer/jsonwizard/jsonwizard.h index 99a9ce49527..cc6e5f5c97c 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.h @@ -105,6 +105,8 @@ public: QVariant m_condition; QVariant m_evaluate; + friend QDebug &operator<<(QDebug &debug, const OptionDefinition &option); + friend class JsonWizard; }; static QList parseOptions(const QVariant &v, QString *errorMessage); @@ -147,4 +149,22 @@ private: Core::JsExpander m_jsExpander; }; +inline QDebug &operator<<(QDebug &debug, const JsonWizard::GeneratorFile &file) +{ + debug << "GeneratorFile{file: " << file.file << "}"; + + return debug; +} + +inline QDebug &operator<<(QDebug &debug, const JsonWizard::OptionDefinition &option) +{ + debug << "Option{" + << "key:" << option.m_key + << "; value:" << option.m_value + << "; evaluate:" << option.m_evaluate + << "; condition:" << option.m_condition + << "}"; + return debug; +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri b/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri index 17be18a3b40..2c9e4ae88a8 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri @@ -10,7 +10,8 @@ HEADERS += $$PWD/jsonfieldpage.h \ $$PWD/jsonwizardgeneratorfactory.h \ $$PWD/jsonwizardpagefactory.h \ $$PWD/jsonwizardpagefactory_p.h \ - $$PWD/jsonwizardscannergenerator.h + $$PWD/jsonwizardscannergenerator.h \ + $$PWD/wizarddebug.h SOURCES += $$PWD/jsonfieldpage.cpp \ $$PWD/jsonfilepage.cpp \ diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h index 3606e43c311..9793eda3d8d 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h @@ -64,7 +64,19 @@ private: QString *errorMessage); QList m_fileList; + friend QDebug &operator<<(QDebug &debug, const File &file); }; +inline QDebug &operator<<(QDebug &debug, const JsonWizardFileGenerator::File &file) +{ + debug << "WizardFile{" + << "source:" << file.source + << "; target:" << file.target + << "; condition:" << file.condition + << "; options:" << file.options + << "}"; + return debug; +} + } // namespace Internal } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/wizarddebug.h b/src/plugins/projectexplorer/jsonwizard/wizarddebug.h new file mode 100644 index 00000000000..724a6472090 --- /dev/null +++ b/src/plugins/projectexplorer/jsonwizard/wizarddebug.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include + +namespace ProjectExplorer { +QDebug &operator<<(QDebug &debug, const QList &container); +QDebug &operator<<(QDebug &debug, const QMap &container); +QDebug &debugString(QDebug &debug, const QString &value); + +inline QDebug &operator<<(QDebug &dbg, const QVariant &var) +{ + switch (var.typeId()) { + case QMetaType::UnknownType: + dbg << "(invalid)"; + break; + case QMetaType::QString: + debugString(dbg, var.toString()); + break; + case QMetaType::QStringList: + dbg << var.toList(); + break; + case QVariant::List: + dbg << var.toList(); + break; + case QVariant::Map: + dbg << var.toMap(); + break; + default: { + QMetaType metaType(var.typeId()); + bool streamed = metaType.debugStream(dbg, var.data()); + if (!streamed && var.canConvert()) + dbg << var.toString(); + } break; + } + + return dbg; +} + +inline QDebug &operator<<(QDebug &dbg, const QList &c) +{ + QDebugStateSaver saver(dbg); + dbg.nospace(); + + dbg << "["; + if (!c.empty()) { + std::for_each(std::cbegin(c), std::cend(c) - 1, [&dbg](auto item) { + dbg << item << ", "; + }); + dbg << c.back(); + } + + dbg << "] "; + + return dbg; +} + +inline QDebug &operator<<(QDebug &dbg, const QMap &m) +{ + QDebugStateSaver saver(dbg); + + dbg.nospace(); + + dbg << "{"; + if (!m.empty()) { + auto keys = m.keys(); + std::for_each(std::cbegin(keys), std::cend(keys) - 1, [&dbg, &m](const QString &k) { + dbg << k << ":" << m[k] << ","; + }); + auto lastKey = keys.back(); + dbg << lastKey << ":" << m[lastKey]; + } + + dbg << "}"; + + return dbg; +} + +inline QDebug &debugString(QDebug &dbg, const QString &value) +{ + QDebugStateSaver saver(dbg); + + dbg.noquote(); + dbg << value; + + return dbg; +} + +} // ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 7967b2a3546..324e3fd3fb2 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -186,7 +186,8 @@ Project { "jsonwizardgeneratorfactory.cpp", "jsonwizardgeneratorfactory.h", "jsonwizardpagefactory.cpp", "jsonwizardpagefactory.h", "jsonwizardpagefactory_p.cpp", "jsonwizardpagefactory_p.h", - "jsonwizardscannergenerator.cpp", "jsonwizardscannergenerator.h" + "jsonwizardscannergenerator.cpp", "jsonwizardscannergenerator.h", + "wizarddebug.h" ] }