From c6b0c549cc4375b01d0c413075c55f7de147aea0 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 25 Sep 2019 14:36:28 +0300 Subject: Allow setting a keyframe's time in the Edit keyframe dialog - rename keyframe context menu item "Edit Value for keyframe..." to "Edit Keyframe..." - add a field to set the frame, this allows accurately setting a keyframe's frame. - allow showing the dialog by double clicking a keyframe. - several relavant tweaks. Task-number: QDS-1072 Change-Id: I3c6a490c335911b2f6fefd3e788468686e827969 Reviewed-by: Thomas Hartmann --- .../timelineeditor/setframevaluedialog.cpp | 21 +++++-- .../timelineeditor/setframevaluedialog.h | 8 +-- .../timelineeditor/setframevaluedialog.ui | 24 +++++--- .../timelineeditor/timelinemovableabstractitem.cpp | 5 ++ .../timelineeditor/timelinemovableabstractitem.h | 1 + .../timelineeditor/timelinepropertyitem.cpp | 65 ++++++++++++++-------- .../timelineeditor/timelinepropertyitem.h | 2 + .../timelineeditor/timelineselectiontool.cpp | 5 +- .../timelineeditor/timelinetooldelegate.cpp | 4 +- 9 files changed, 93 insertions(+), 42 deletions(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp index 4120aaee21..29c3cd8eed 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp @@ -26,14 +26,24 @@ #include "setframevaluedialog.h" #include "ui_setframevaluedialog.h" +#include + namespace QmlDesigner { -SetFrameValueDialog::SetFrameValueDialog(QWidget *parent) +SetFrameValueDialog::SetFrameValueDialog(qreal frame, const QVariant &value, + const QString &propertyName, QWidget *parent) : QDialog(parent) , ui(new Ui::SetFrameValueDialog) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowTitle(tr("Edit Keyframe")); ui->setupUi(this); + + ui->lineEditFrame->setValidator(new QIntValidator(0, 99999, this)); + + ui->lineEditFrame->setText(QString::number(frame)); + ui->lineEditValue->setText(value.toString()); + ui->labelValue->setText(propertyName); } SetFrameValueDialog::~SetFrameValueDialog() @@ -41,15 +51,14 @@ SetFrameValueDialog::~SetFrameValueDialog() delete ui; } -QLineEdit *SetFrameValueDialog::lineEdit() const +qreal SetFrameValueDialog::frame() const { - return ui->lineEdit; + return ui->lineEditFrame->text().toDouble(); } -void SetFrameValueDialog::setPropertName(const QString &name) +QVariant SetFrameValueDialog::value() const { - setWindowTitle(tr("Change %1").arg(name)); - ui->label->setText(name); + return QVariant(ui->lineEditValue->text()); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h index e7ed226b67..799e3fadc5 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h @@ -40,12 +40,12 @@ class SetFrameValueDialog : public QDialog Q_OBJECT public: - explicit SetFrameValueDialog(QWidget *parent = nullptr); + explicit SetFrameValueDialog(qreal frame, const QVariant &value, const QString &propertyName, + QWidget *parent = nullptr); ~SetFrameValueDialog() override; - QLineEdit *lineEdit() const; - - void setPropertName(const QString &name); + qreal frame() const; + QVariant value() const; private: Ui::SetFrameValueDialog *ui; diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui index 2fa1241e4a..1fe2468a6b 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui @@ -7,7 +7,7 @@ 0 0 184 - 79 + 93 @@ -15,16 +15,13 @@ - + - Value + Frame - - - - + Qt::Horizontal @@ -34,6 +31,19 @@ + + + + + + + + + + Value + + + diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp index 4db4567fd6..1d700cf063 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp @@ -46,6 +46,11 @@ void TimelineMovableAbstractItem::itemMoved(const QPointF & /*start*/, const QPo setPositionInteractive(end); } +void TimelineMovableAbstractItem::itemDoubleClicked() +{ + // to be overridden by child classes if needed +} + int TimelineMovableAbstractItem::scrollOffset() const { return timelineScene()->scrollOffset(); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h index 0830facfbf..cf71397225 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h @@ -57,6 +57,7 @@ public: virtual void setPositionInteractive(const QPointF &point); virtual void commitPosition(const QPointF &point); virtual void itemMoved(const QPointF &start, const QPointF &end); + virtual void itemDoubleClicked(); int xPosScrollOffset(int x) const; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp index beeca23183..920a8b35ca 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp @@ -106,31 +106,40 @@ static void setEasingCurve(TimelineGraphicsScene *scene, const QList EasingCurveDialog::runDialog(keys); } -static void editValue(const ModelNode &frame, const QString &propertyName) +// display and handle the edit keyframe dialog +static void editValue(const ModelNode &frameNode, const std::pair &timelineRange, + const QString &propertyName) { - const QVariant value = frame.variantProperty("value").value(); - auto dialog = new SetFrameValueDialog(Core::ICore::dialogParent()); - - dialog->lineEdit()->setText(value.toString()); - dialog->setPropertName(propertyName); + const qreal frame = frameNode.variantProperty("frame").value().toReal(); + const QVariant value = frameNode.variantProperty("value").value(); + auto dialog = new SetFrameValueDialog(frame, value, propertyName, + Core::ICore::dialogParent()); QObject::connect(dialog, &SetFrameValueDialog::rejected, [dialog]() { dialog->deleteLater(); }); - QObject::connect(dialog, &SetFrameValueDialog::accepted, [dialog, frame, value]() { + QObject::connect(dialog, &SetFrameValueDialog::accepted, [dialog, frameNode, frame, value, + timelineRange]() { dialog->deleteLater(); + + qreal newFrame = qBound(timelineRange.first, dialog->frame(), timelineRange.second); + if (newFrame != frame) + frameNode.variantProperty("frame").setValue(newFrame); + int userType = value.userType(); - const QVariant result = dialog->lineEdit()->text(); - - if (result.canConvert(userType)) { - QVariant newValue = result; - newValue.convert(userType); - // canConvert gives true in case if the result is a double but the usertype was interger - // try to fix that with a workaround to convert it to double if convertion resulted in isNull - if (newValue.isNull()) { - newValue = result; - newValue.convert(QMetaType::Double); + QVariant newValue = dialog->value(); + + if (newValue.canConvert(userType)) { + QVariant newValueConverted = newValue; + bool converted = newValueConverted.convert(userType); + + if (!converted) { + // convert() fails for int to double, so we try this combination + newValueConverted = newValue; + converted = newValueConverted.convert(QMetaType::Double); } - frame.variantProperty("value").setValue(result); + + if (converted) + frameNode.variantProperty("value").setValue(newValueConverted); } }); @@ -431,9 +440,12 @@ void TimelinePropertyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *even setEasingCurve(timelineScene(), {currentFrameNode}); }); - QAction *editValueAction = mainMenu.addAction(tr("Edit Value for Keyframe...")); + QAction *editValueAction = mainMenu.addAction(tr("Edit Keyframe...")); QObject::connect(editValueAction, &QAction::triggered, [this, currentFrameNode]() { - editValue(currentFrameNode, propertyName()); + std::pair timelineRange + = {timelineScene()->currentTimeline().startKeyframe(), + timelineScene()->currentTimeline().endKeyframe()}; + editValue(currentFrameNode, timelineRange, propertyName()); }); const bool hasKeyframe = currentFrameNode.isValid(); @@ -541,6 +553,13 @@ void TimelineKeyframeItem::commitPosition(const QPointF &point) enableUpdates(); } +void TimelineKeyframeItem::itemDoubleClicked() +{ + std::pair timelineRange = {timelineScene()->currentTimeline().startKeyframe(), + timelineScene()->currentTimeline().endKeyframe()}; + editValue(m_frame, timelineRange, propertyItem()->propertyName()); +} + TimelineKeyframeItem *TimelineKeyframeItem::asTimelineKeyframeItem() { return this; @@ -630,9 +649,11 @@ void TimelineKeyframeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *even setEasingCurve(timelineScene(), keys); }); - QAction *editValueAction = mainMenu.addAction(tr("Edit Value for Keyframe...")); + QAction *editValueAction = mainMenu.addAction(tr("Edit Keyframe...")); QObject::connect(editValueAction, &QAction::triggered, [this]() { - editValue(m_frame, propertyItem()->propertyName()); + std::pair timelineRange = {timelineScene()->currentTimeline().startKeyframe(), + timelineScene()->currentTimeline().endKeyframe()}; + editValue(m_frame, timelineRange, propertyItem()->propertyName()); }); mainMenu.exec(event->screenPos()); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h index 2b8c00c59b..4544b40302 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h @@ -63,6 +63,8 @@ public: void commitPosition(const QPointF &point) override; + void itemDoubleClicked() override; + TimelineKeyframeItem *asTimelineKeyframeItem() override; protected: diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp index 987ac4935a..c9ab304497 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp @@ -98,7 +98,6 @@ void TimelineSelectionTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, QGraphicsSceneMouseEvent *event) { Q_UNUSED(item) - Q_UNUSED(event) commitSelection(selectionMode(event)); @@ -108,9 +107,11 @@ void TimelineSelectionTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, void TimelineSelectionTool::mouseDoubleClickEvent(TimelineMovableAbstractItem *item, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(item) Q_UNUSED(event) + if (item) + item->itemDoubleClicked(); + reset(); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp index 51c5a7d088..d84a461999 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp @@ -92,8 +92,10 @@ void TimelineToolDelegate::mouseReleaseEvent(TimelineMovableAbstractItem *item, void TimelineToolDelegate::mouseDoubleClickEvent(TimelineMovableAbstractItem *item, QGraphicsSceneMouseEvent *event) { - if (m_currentTool) + if (hitCanvas(event)) { + m_currentTool = m_selectTool.get(); m_currentTool->mouseDoubleClickEvent(item, event); + } reset(); } -- cgit v1.2.1 From fa0979a626ab3674faa0edd73fb156ed4d2e8eed Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 26 Sep 2019 15:07:37 +0200 Subject: QNX: Add C compiler in the compiler selection dialog QNX compiler can also do C, and it's needed for properly configuring a CMake project. Change-Id: I68edf35d7e288400f48b59c258065e6f82d17fc4 Reviewed-by: Tobias Hunger --- src/plugins/qnx/qnxtoolchain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 0a515287ea..3413b7da1c 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -206,7 +206,8 @@ QnxToolChainFactory::QnxToolChainFactory() { setDisplayName(tr("QCC")); setSupportedToolChainType(Constants::QNX_TOOLCHAIN_ID); - setSupportedLanguages({ProjectExplorer::Constants::CXX_LANGUAGE_ID}); + setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, + ProjectExplorer::Constants::CXX_LANGUAGE_ID}); setToolchainConstructor([] { return new QnxToolChain; }); setUserCreatable(true); } -- cgit v1.2.1 From 9be1caf05f0a32483efc0c29095b820e97473471 Mon Sep 17 00:00:00 2001 From: Sergey Belyashov Date: Fri, 20 Sep 2019 13:00:54 +0300 Subject: Fix Russian translation Fixes: QTCREATORBUG-22978 Fixes: QTCREATORBUG-22996 Change-Id: I93e8426c6efc46b8c749f12d729070052fb4af88 Reviewed-by: Sergey Belyashov Reviewed-by: Viacheslav Tertychnyi Reviewed-by: Anton Kudryavtsev Reviewed-by: Oswald Buddenhagen --- share/qtcreator/translations/qtcreator_ru.ts | 165 +++++++++++++++++++-------- 1 file changed, 118 insertions(+), 47 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 5bffaae635..16a28c2f65 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -130,12 +130,71 @@ Анализатор + + AnchorButtons + + Anchor item to the top. + Привязка элемента к верхнему краю. + + + Anchor item to the bottom. + Привязка элемента к нижнему краю. + + + Anchor item to the left. + Привязка элемента к левому краю. + + + Anchor item to the right. + Привязка элемента к правому краю. + + + Fill parent item. + Заполнить родительский элемент. + + + Anchor item vertically. + Вертикальная привязка элемента. + + + Anchor item horizontally. + Горизонтальная привязка элемента. + + AnchorRow Target Цель + + Margin + Внешний отступ + + + Anchor to the top of the target. + Привязка к верхнему краю цели. + + + Anchor to the left of the target. + Привязка к левому краю цели. + + + Anchor to the vertical center of the target. + Привязка к вертикальному центру цели. + + + Anchor to the horizontal center of the target. + Привязка к горизонтальному центру цели. + + + Anchor to the bottom of the target. + Привязка к нижнему краю цели. + + + Anchor to the right of the target. + Привязка к правому краю цели. + Android::AndroidBuildApkStep @@ -1903,7 +1962,7 @@ Install an SDK of at least API version %1. %1 tests passed. - %1 тестов прошли успешно. + %1 тестов прошло успешно. No errors detected. @@ -3241,7 +3300,7 @@ Warning: this is an experimental feature and might lead to failing to execute th The kit has a Qt version, but no C++ compiler. - У комплекта задан профил Qt, но нет компилятора C++. + У комплекта задан профиль Qt, но нет компилятора C++. Name: @@ -4476,7 +4535,7 @@ For example, "Revision: 15" will leave the branch at revision 15. A seed of 0 means no randomization. A value of 1 uses the current time any other value is used as random seed generator. - 0 отключает случайный порядок. Значение 1 использует текущее время, любой другое используется для генерации случайной последовательности. + 0 отключает случайный порядок. Значение 1 использует текущее время, любое другое используется для генерации случайной последовательности. Catch or ignore system errors. @@ -7116,6 +7175,10 @@ p, li { white-space: pre-wrap; } Recent Недавний + + Open Color Dialog + Открыть выбор цвета + Defines the start angle for the conical gradient. The value is in degrees (0-360). Определяет начальный угол для конического градиента. Значение в градусах от 0 до 360. @@ -9120,11 +9183,11 @@ Do you want to kill it? Cycle Mode Selector Styles - Зациклить стили режима выбора + Зациклить стили режима выбора Mode Selector Style - Стиль режима выбора + Стиль режима выбора Icons and Text @@ -16270,7 +16333,7 @@ You can choose another communication channel here, such as a serial line or cust Creation Time in ms - Время создания в мс + Время создания, мс <empty> @@ -17359,7 +17422,7 @@ Rebuilding the project might help. Drag Margin - Поле перетаскивания + Зона перетаскивания Defines the distance from the screen edge within which drag actions will open the drawer. @@ -18417,6 +18480,10 @@ will also disable the following plugins: Determines whether the Flickable will give a feeling that the edges of the view are soft, rather than a hard physical boundary. Определяет, будет ли Flickable создавать ощущение, что края у вида мягкие, а не жесткие физические границы. + + Describes whether the user can interact with the Flickable. A user cannot drag or flick a Flickable that is not interactive. + Определяет, может ли пользователь влиять на Flickable. Пользователь не может перетягивать или сдвигать Flickable, если он не интерактивен. + Press delay Задержка нажатия @@ -18443,7 +18510,7 @@ will also disable the following plugins: Margins - Отступы + Внешние отступы Flick direction @@ -20499,7 +20566,7 @@ Commit now? DCommit - Дельта фиксация (dcommit) + Дельта фиксация (dcommit) Manage Remotes... @@ -23443,7 +23510,7 @@ Error: %5 Margins - Отступы + Внешние отступы Row span @@ -23954,7 +24021,7 @@ Error: %5 MarginSection Margin - Поле + Внешний отступ Vertical @@ -23998,7 +24065,7 @@ Error: %5 Margins - Отступы + Внешние отступы The margins around the item. @@ -25088,7 +25155,7 @@ Error: %5 Drag margin - Перетаскиваемый край + Зона перетаскивания Flick deceleration @@ -25795,12 +25862,12 @@ Error: %5 Self Samples - Собственных семплов + Собственных семплов Self in Percent х.з. как переводить - Собственное в процентах + Собственное в процентах @@ -26741,7 +26808,7 @@ Error: %5 Build/Deployment canceled - Сборка/разворачивание отменено + Сборка/развёртывание отменено When executing step "%1" @@ -26754,7 +26821,7 @@ Error: %5 Deployment Category for deployment issues listed under 'Issues' - Разворачивание + Развёртывание Autotests @@ -26763,11 +26830,11 @@ Error: %5 Canceled build/deployment. - Сборка/разворачивание было отменено. + Сборка/развёртывание было отменено. Error while building/deploying project %1 (kit: %2) - Ошибка при сборке/разворачивании проекта %1 (комплект: %2) + Ошибка при сборке/развёртывании проекта %1 (комплект: %2) The kit %1 has configuration issues which might be the root cause for this problem. @@ -27022,21 +27089,21 @@ Error: %5 Deploy Display name of the deploy build step list. Used as part of the labels in the project window. - Разваорачивание + Развёртывание Deploy locally Default DeployConfiguration display name - Локальное разворачивание + Локальное развёртывание Deploy Configuration Display name of the default deploy configuration - Конфигурация разворачивания + Конфигурация развёртывания Deploy Settings - Настройки разворачивания + Настройки развёртывания @@ -27054,7 +27121,7 @@ Error: %5 ProjectExplorer::DeploymentDataView Files to deploy: - Разворачиваемые файлы: + Файлы для развёртывания: @@ -27360,11 +27427,11 @@ Error: %5 Append Path... - Добавить после пути... + Добавить после пути... Prepend Path... - Добавить перед путём... + Добавить перед путём... &Batch Edit... @@ -27987,7 +28054,7 @@ Excluding: %2 Synchronize active kit, build, and deploy configuration between projects. - Сихронизировать у проектов текущий комплект и конфигурации сборки и разворачивания. + Сихронизировать у проектов текущий комплект и конфигурации сборки и развёртывания. @@ -28492,7 +28559,7 @@ What should Qt Creator do now? Deploy - Разворачивание + Развёртывание Run @@ -28520,7 +28587,7 @@ What should Qt Creator do now? <b>Deploy:</b> %1 - <b>Разворачивание:</b> %1 + <b>Развёртывание:</b> %1 <b>Run:</b> %1 @@ -28544,7 +28611,7 @@ What should Qt Creator do now? Deploy: <b>%1</b><br/> - Разворачивание: <b>%1</b><br/> + Развёртывание: <b>%1</b><br/> Run: <b>%1</b><br/> @@ -28687,11 +28754,11 @@ What should Qt Creator do now? Always build project before deploying it - Всегда собирать проект перед разворачиванием + Всегда собирать проект перед развёртыванием Always deploy project before running it - Всегда разворачивать проект перед запуском + Всегда развёртывать проект перед запуском Always ask before stopping applications @@ -29053,7 +29120,7 @@ to project "%2". Deployment - Разворачивание + Развёртывание Method: @@ -29082,7 +29149,7 @@ to project "%2". Cancel Build && Remove Deploy Configuration - Отменить сборку и удалить конфигурацию разворачивания + Отменить сборку и удалить конфигурацию развёртывания Do Not Remove @@ -29090,27 +29157,27 @@ to project "%2". Remove Deploy Configuration %1? - Удаление конфигурации разворачивания %1 + Удаление конфигурации развёртывания %1 The deploy configuration <b>%1</b> is currently being built. - В данный момент идёт сборка с использованием конфигурации разворачивания <b>%1</b>. + В данный момент идёт сборка с использованием конфигурации развёртывания <b>%1</b>. Do you want to cancel the build process and remove the Deploy Configuration anyway? - Остановить процесс сборки и удалить конфигурацию разворачивания? + Остановить процесс сборки и удалить конфигурацию развёртывания? Remove Deploy Configuration? - Удаление конфигурации разворачивания + Удаление конфигурации развёртывания Do you really want to delete deploy configuration <b>%1</b>? - Желаете удалить конфигурацию разворачивания <b>%1</b>? + Желаете удалить конфигурацию развёртывания <b>%1</b>? New name for deploy configuration <b>%1</b>: - Новое название конфигурации разворачивания <b>%1</b>: + Новое название конфигурации развёртывания <b>%1</b>: @@ -30027,7 +30094,7 @@ to project "%2". QML File (Qt Quick 2) - Файл QML (Qt Quck 2) + Файл QML (Qt Quick 2) Creates a scratch buffer using a temporary file. @@ -31178,7 +31245,7 @@ Please close all running instances of your application before starting a build.< Deploy configurations: - Конфигурации разворачивания: + Конфигурации развёртывания: Run configurations: @@ -31581,7 +31648,7 @@ Rename %2 to %3 anyway? Run Without Deployment - Запустить без разворачивания + Запустить без развёртывания New Subproject... @@ -33828,7 +33895,7 @@ Neither the path to the library nor the path to its includes is added to the .pr Qmake has subtle bugs that can be triggered if source and build directory are not at the same level. - Qmake содержит ошибку, возникающую при нахождении каталогов сборки и исходников на разных уровнях. + Qmake содержит ошибку, которая может проявляться, если каталоги сборки и исходников находятся на разных уровнях. Run qmake on every build @@ -38341,7 +38408,7 @@ Saving failed. Qnx::Internal::QnxDeployQtLibrariesDialog Qt library to deploy: - Разворачиваемая Qt: + Библиотека Qt для развёртывания: Deploy @@ -38765,6 +38832,10 @@ For more details, see /etc/sysctl.d/10-ptrace.conf Type Тип + + Change the type of this item. + Меняет тип этого элемента. + id идентификатор @@ -42948,7 +43019,7 @@ Specifies how backspace interacts with indentation. Timeout in ms: - Таймаут в мс: + Таймаут, мс: Inserts the common prefix of available completion items. @@ -47925,7 +47996,7 @@ What do you want to do? Multi-paradigm language for creating highly dynamic applications. - Многопарадигмый язый для создания высокодинамичных приложений. + Мультипарадигменный язык для создания высокодинамичных приложений. Run your concepts and prototypes on your final hardware. -- cgit v1.2.1 From 0ffe31bec31d2a9cca9fba59a1ecf3774527bd6f Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 26 Sep 2019 15:04:52 +0300 Subject: Playhead range check and status bar improvements - distinguish between playhead and keyframe value on the status bar. - update the status bar frame value when a keyframe is being moved. - when changing or deleting timelines, update the status bar. - when changing timelines, make sure the playhead is within the new timeline's range. - keep playhead in range after changing timeline's start/end. Task-number: QDS-1071 Change-Id: Id9758e3097d34df9334d6284a6a56ba38b509a31 Reviewed-by: Thomas Hartmann --- .../components/timelineeditor/timelineconstants.h | 3 ++- .../timelineeditor/timelinegraphicsscene.cpp | 8 +++--- .../timelineeditor/timelinegraphicsscene.h | 2 +- .../components/timelineeditor/timelinemovetool.cpp | 30 ++++++++++++++-------- .../components/timelineeditor/timelinemovetool.h | 2 ++ .../components/timelineeditor/timelinewidget.cpp | 21 +++++++++++---- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineconstants.h b/src/plugins/qmldesigner/components/timelineeditor/timelineconstants.h index c2a8137352..622dc366ed 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineconstants.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineconstants.h @@ -54,7 +54,8 @@ const char timelineInsertKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesigner const char timelineDeleteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Delete All Keyframes"); -const char timelineStatusBarFrameNumber[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Frame %1"); +const char statusBarPlayheadFrame[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Playhead frame %1"); +const char statusBarKeyframe[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Keyframe %1"); const char C_QMLTIMELINE[] = "QmlDesigner::Timeline"; const char C_SETTINGS[] = "QmlDesigner.Settings"; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp index 97ebb7e84d..7baa6d4dd4 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp @@ -194,7 +194,7 @@ void TimelineGraphicsScene::setCurrentFrame(int frame) invalidateCurrentValues(); - emitStatusBarFrameMessageChanged(frame); + emitStatusBarPlayheadFrameChanged(frame); } void TimelineGraphicsScene::setStartFrame(int frame) @@ -318,7 +318,7 @@ void TimelineGraphicsScene::commitCurrentFrame(qreal frame) setCurrenFrame(timeline, qRound(frame)); invalidateCurrentValues(); } - emitStatusBarFrameMessageChanged(int(frame)); + emitStatusBarPlayheadFrameChanged(int(frame)); } QList TimelineGraphicsScene::selectedKeyframes() const @@ -700,10 +700,10 @@ void TimelineGraphicsScene::emitScrollOffsetChanged() TimelineMovableAbstractItem::emitScrollOffsetChanged(item); } -void TimelineGraphicsScene::emitStatusBarFrameMessageChanged(int frame) +void TimelineGraphicsScene::emitStatusBarPlayheadFrameChanged(int frame) { emit statusBarMessageChanged( - QString(TimelineConstants::timelineStatusBarFrameNumber).arg(frame)); + tr(TimelineConstants::statusBarPlayheadFrame).arg(frame)); } bool TimelineGraphicsScene::event(QEvent *event) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h index b8f93595c4..d03a6a5824 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h @@ -160,7 +160,7 @@ private: ModelNode timelineModelNode() const; void emitScrollOffsetChanged(); - void emitStatusBarFrameMessageChanged(int frame); + void emitStatusBarPlayheadFrameChanged(int frame); QList itemsAt(const QPointF &pos); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp index 0e68a63ff4..71c76e5f67 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp @@ -100,6 +100,9 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item, current->setPosition(sourceFrame + deltaFrame); + scene()->statusBarMessageChanged(tr(TimelineConstants::statusBarKeyframe) + .arg(sourceFrame + deltaFrame)); + for (auto *keyframe : scene()->selectedKeyframes()) { if (keyframe != current) { qreal pos = std::round(current->mapFromSceneToFrame(keyframe->rect().center().x())); @@ -125,29 +128,36 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, double start = current->mapFromFrameToScene(scene()->startFrame()); double end = current->mapFromFrameToScene(scene()->endFrame()); - if (mousePos < start) { - scene()->setCurrentFrame(scene()->startFrame()); - scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(scene()->startFrame())); - return; - } else if (mousePos > end) { - scene()->setCurrentFrame(scene()->endFrame()); - scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(scene()->endFrame())); + double limitFrame = -999999.; + if (mousePos < start) + limitFrame = scene()->startFrame(); + else if (mousePos > end) + limitFrame = scene()->endFrame(); + + if (limitFrame > -999999.) { + scene()->setCurrentFrame(limitFrame); + scene()->statusBarMessageChanged( + tr(TimelineConstants::statusBarPlayheadFrame).arg(limitFrame)); return; } } - scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent", [this, current](){ + scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent", + [this, current]() { current->commitPosition(mapToItem(current, current->rect().center())); if (current->asTimelineKeyframeItem()) { double frame = std::round( current->mapFromSceneToFrame(current->rect().center().x())); - scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(frame)); + scene()->statusBarMessageChanged( + tr(TimelineConstants::statusBarKeyframe).arg(frame)); - for (auto keyframe : scene()->selectedKeyframes()) + const auto selectedKeyframes = scene()->selectedKeyframes(); + for (auto keyframe : selectedKeyframes) { if (keyframe != current) keyframe->commitPosition(mapToItem(current, keyframe->rect().center())); + } } }); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h index 55b9a39417..b1c1290988 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h @@ -37,6 +37,8 @@ class TimelineMovableAbstractItem; class TimelineMoveTool : public TimelineAbstractTool { + Q_DECLARE_TR_FUNCTIONS(TimelineMoveTool) + public: explicit TimelineMoveTool(TimelineGraphicsScene *scene, TimelineToolDelegate *delegate); void mousePressEvent(TimelineMovableAbstractItem *item, diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp index 522607f615..303c761f3c 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp @@ -405,14 +405,18 @@ void TimelineWidget::contextHelp(const Core::IContext::HelpCallback &callback) c void TimelineWidget::init() { QmlTimeline currentTimeline = m_timelineView->timelineForState(m_timelineView->currentState()); - if (currentTimeline.isValid()) + if (currentTimeline.isValid()) { setTimelineId(currentTimeline.modelNode().id()); - else + m_statusBar->setText(tr(TimelineConstants::statusBarPlayheadFrame) + .arg(getcurrentFrame(currentTimeline))); + } else { setTimelineId({}); + m_statusBar->clear(); + } - invalidateTimelineDuration(graphicsScene()->currentTimeline()); + invalidateTimelineDuration(m_graphicsScene->currentTimeline()); - graphicsScene()->setWidth(m_graphicsView->viewport()->width()); + m_graphicsScene->setWidth(m_graphicsView->viewport()->width()); // setScaleFactor uses QSignalBlocker. m_toolbar->setScaleFactor(0); @@ -442,7 +446,14 @@ void TimelineWidget::invalidateTimelineDuration(const QmlTimeline &timeline) QmlTimeline currentTimeline = graphicsScene()->currentTimeline(); if (currentTimeline.isValid() && currentTimeline == timeline) { graphicsScene()->setTimeline(timeline); - graphicsScene()->setCurrenFrame(timeline, getcurrentFrame(timeline)); + + qreal playHeadFrame = getcurrentFrame(timeline); + if (playHeadFrame < timeline.startKeyframe()) + playHeadFrame = timeline.startKeyframe(); + else if (playHeadFrame > timeline.endKeyframe()) + playHeadFrame = timeline.endKeyframe(); + + graphicsScene()->setCurrentFrame(playHeadFrame); } } } -- cgit v1.2.1 From da39f3d7fc705d52ad42a91a647f8de00e0f7814 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Fri, 27 Sep 2019 10:58:08 +0300 Subject: Correct edit keyframe dialog title and fix its size - Make sure the edit keyframe dialog's title appears correctly. - Disabled resizing of the dialog. Change-Id: I2374e2f71e99b49b00c9600787a798e457b8ec01 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/timelineeditor/setframevaluedialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp index 29c3cd8eed..dbb70ca07a 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp @@ -35,9 +35,10 @@ SetFrameValueDialog::SetFrameValueDialog(qreal frame, const QVariant &value, : QDialog(parent) , ui(new Ui::SetFrameValueDialog) { + ui->setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Edit Keyframe")); - ui->setupUi(this); + setFixedSize(size()); ui->lineEditFrame->setValidator(new QIntValidator(0, 99999, this)); -- cgit v1.2.1 From 05d53c1454bef1e5d3e6aeb46265ae0e219cc90d Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 23 Sep 2019 16:22:24 +0300 Subject: Correct playhead position after releasing out of range When dragging the playhead and releasing it out of the range of the timeline, the playhead took wrong position. This happens if the timeline does not start at frame 0. The value of timeline.startKeyframe() is already taken into account by mapFromFrameToScene() in setPosition(). Therefore the offset was added twice. Task-number: QDS-1074 Change-Id: I72ec13176af473ac9851580e2367117f98ddfc65 Reviewed-by: Thomas Hartmann Reviewed-by: Miikka Heikkinen --- .../qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp index 7baa6d4dd4..a5f6110812 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp @@ -187,7 +187,7 @@ void TimelineGraphicsScene::setCurrentFrame(int frame) if (timeline.isValid()) { timeline.modelNode().setAuxiliaryData("currentFrame@NodeInstance", frame); - m_currentFrameIndicator->setPosition(frame + timeline.startKeyframe()); + m_currentFrameIndicator->setPosition(frame); } else { m_currentFrameIndicator->setPosition(0); } -- cgit v1.2.1 From 3a401f331446e3c6ac314804a8f6699051dad8ee Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 23 Sep 2019 11:45:07 +0200 Subject: macOS: Fix compiler warning The new value is available since SDK 10.12 Change-Id: I2d171680dbf3ae7b7951bfa36990ab52a3b19e9b Reviewed-by: Christian Stenger --- src/libs/utils/touchbar/touchbar_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/touchbar/touchbar_mac.mm b/src/libs/utils/touchbar/touchbar_mac.mm index ee5a45bf72..dfaf670087 100644 --- a/src/libs/utils/touchbar/touchbar_mac.mm +++ b/src/libs/utils/touchbar/touchbar_mac.mm @@ -177,7 +177,7 @@ static NSImage *iconToTemplateNSImage(const QIcon &icon) { self = [super init]; [self setButtonType:NSButtonTypeMomentaryPushIn]; - self.bezelStyle = NSRoundedBezelStyle; + self.bezelStyle = NSBezelStyleRounded; self.target = self; self.action = @selector(trigger:); _qaction = qaction; @@ -208,7 +208,7 @@ static NSImage *iconToTemplateNSImage(const QIcon &icon) { self = [super init]; [self setButtonType:NSButtonTypeMomentaryPushIn]; - self.bezelStyle = NSRoundedBezelStyle; + self.bezelStyle = NSBezelStyleRounded; self.target = self; self.action = @selector(trigger:); _parent = parent; -- cgit v1.2.1 From 2d95c905926f49a660778e6ea45f779343da3fe5 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 24 Sep 2019 11:35:46 +0200 Subject: macOS: Fix window state after going out of fullscreen If you went out of fullscreen with the shortcut or menu item, it would not restore a previous maximized state, but instead resized the window to the smaller non-maximized state. So, 1. open Qt Creator and resize to some non-maximized size 2. double-click window title to maximize 3. Window > Enter Full Screen 4. Window > Exit Full Screen now returns correctly to state 2, not 1. Change-Id: I076321070d011d73bfe888c0a4a5ade24c1057d6 Reviewed-by: Christian Stenger --- src/plugins/coreplugin/windowsupport.cpp | 4 +++- src/plugins/coreplugin/windowsupport.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/windowsupport.cpp b/src/plugins/coreplugin/windowsupport.cpp index 17bab61bcc..26117ba12f 100644 --- a/src/plugins/coreplugin/windowsupport.cpp +++ b/src/plugins/coreplugin/windowsupport.cpp @@ -40,6 +40,7 @@ #include #include #include +#include namespace Core { namespace Internal { @@ -111,6 +112,7 @@ bool WindowSupport::eventFilter(QObject *obj, QEvent *event) m_minimizeAction->setEnabled(!minimized); m_zoomAction->setEnabled(!minimized); } + m_previousWindowState = static_cast(event)->oldState(); updateFullScreenAction(); } else if (event->type() == QEvent::WindowActivate) { m_windowList->setActiveWindow(m_window); @@ -126,7 +128,7 @@ bool WindowSupport::eventFilter(QObject *obj, QEvent *event) void WindowSupport::toggleFullScreen() { if (m_window->isFullScreen()) { - m_window->setWindowState(m_window->windowState() & ~Qt::WindowFullScreen); + m_window->setWindowState(m_previousWindowState & ~Qt::WindowFullScreen); } else { m_window->setWindowState(m_window->windowState() | Qt::WindowFullScreen); } diff --git a/src/plugins/coreplugin/windowsupport.h b/src/plugins/coreplugin/windowsupport.h index 5531306fe0..1e640f6edb 100644 --- a/src/plugins/coreplugin/windowsupport.h +++ b/src/plugins/coreplugin/windowsupport.h @@ -80,6 +80,7 @@ private: QAction *m_zoomAction; QAction *m_closeAction; QAction *m_toggleFullScreenAction; + Qt::WindowStates m_previousWindowState; bool m_shutdown = false; }; -- cgit v1.2.1 From bdea56794fdb43e6eab3daf32012b8e04345a0b7 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 27 Sep 2019 11:17:22 +0200 Subject: Fix build (Q_DECLARE_TR_FUNCTIONS) Change-Id: Ifb2fe780ceaf3accef7ef0e46cf139d38115940e Reviewed-by: hjk --- src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h index b1c1290988..20b9537af9 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.h @@ -27,6 +27,7 @@ #include "timelineabstracttool.h" +#include #include QT_FORWARD_DECLARE_CLASS(QGraphicsRectItem) -- cgit v1.2.1 From 4750969c2b0c5574ed4d4ae23d5c69b5d97e1a87 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 13 Sep 2019 10:49:14 +0200 Subject: ClangTools: Move run settings to projects mode Make the global run settings available per project in project mode and thus remove the diagnostic config selection from the selectable-files-dialog: * Extract the classes RunSettings and RunSettingsWidget instead of duplicating stuff. * Ensure to pick up the old settings * Add some convenience buttons/links in projects mode allowing to restore the global settings, to open the global settings and to navigate (back) to the analyzer mode. Change-Id: I1b91b6f8e58a87a025774e4643c46e176b2a8885 Reviewed-by: Cristian Adam Reviewed-by: Nikolai Kosjar --- src/plugins/clangtools/CMakeLists.txt | 1 + .../clangtools/clangselectablefilesdialog.cpp | 54 ------ .../clangtools/clangselectablefilesdialog.ui | 67 +------- src/plugins/clangtools/clangtidyclazytool.cpp | 28 +--- src/plugins/clangtools/clangtidyclazytool.h | 2 + src/plugins/clangtools/clangtoolruncontrol.cpp | 32 ++-- src/plugins/clangtools/clangtoolruncontrol.h | 13 +- src/plugins/clangtools/clangtools.pro | 3 + src/plugins/clangtools/clangtools.qbs | 3 + src/plugins/clangtools/clangtoolsplugin.cpp | 13 +- .../clangtools/clangtoolsprojectsettings.cpp | 87 ++++++---- src/plugins/clangtools/clangtoolsprojectsettings.h | 16 +- .../clangtools/clangtoolsprojectsettingswidget.cpp | 46 ++++++ .../clangtools/clangtoolsprojectsettingswidget.h | 2 + .../clangtools/clangtoolsprojectsettingswidget.ui | 134 ++++++++++----- src/plugins/clangtools/clangtoolssettings.cpp | 182 ++++++++------------- src/plugins/clangtools/clangtoolssettings.h | 66 ++++---- src/plugins/clangtools/clangtoolsunittests.cpp | 13 +- src/plugins/clangtools/runsettingswidget.cpp | 87 ++++++++++ src/plugins/clangtools/runsettingswidget.h | 58 +++++++ src/plugins/clangtools/runsettingswidget.ui | 93 +++++++++++ src/plugins/clangtools/settingswidget.cpp | 60 ++----- src/plugins/clangtools/settingswidget.h | 3 + src/plugins/clangtools/settingswidget.ui | 61 +------ 24 files changed, 623 insertions(+), 501 deletions(-) create mode 100644 src/plugins/clangtools/runsettingswidget.cpp create mode 100644 src/plugins/clangtools/runsettingswidget.h create mode 100644 src/plugins/clangtools/runsettingswidget.ui diff --git a/src/plugins/clangtools/CMakeLists.txt b/src/plugins/clangtools/CMakeLists.txt index 93195bdfb9..fe34b67948 100644 --- a/src/plugins/clangtools/CMakeLists.txt +++ b/src/plugins/clangtools/CMakeLists.txt @@ -29,6 +29,7 @@ add_qtc_plugin(ClangTools clangtoolsprojectsettingswidget.cpp clangtoolsprojectsettingswidget.h clangtoolsprojectsettingswidget.ui clangtoolssettings.cpp clangtoolssettings.h clangtoolsutils.cpp clangtoolsutils.h + runsettingswidget.cpp runsettingswidget.h runsettingswidget.ui settingswidget.cpp settingswidget.h settingswidget.ui ) diff --git a/src/plugins/clangtools/clangselectablefilesdialog.cpp b/src/plugins/clangtools/clangselectablefilesdialog.cpp index c9fce5552f..6541ca46bc 100644 --- a/src/plugins/clangtools/clangselectablefilesdialog.cpp +++ b/src/plugins/clangtools/clangselectablefilesdialog.cpp @@ -266,16 +266,6 @@ private: } }; -enum { GlobalSettings , CustomSettings }; - -static Core::Id diagnosticConfiguration(ClangToolsProjectSettings *settings) -{ - Core::Id id = settings->diagnosticConfig(); - if (id.isValid()) - return id; - return ClangToolsSettings::instance()->savedDiagnosticConfigId(); -} - SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo, const FileInfos &allFileInfos) : QDialog(nullptr) @@ -292,36 +282,7 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo, m_ui->buttons->setStandardButtons(QDialogButtonBox::Cancel); m_ui->buttons->addButton(m_analyzeButton, QDialogButtonBox::AcceptRole); - CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticWidget = m_ui->diagnosticWidget; - ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); - m_customDiagnosticConfig = diagnosticConfiguration(settings); - - if (settings->useGlobalSettings()) { - m_ui->globalOrCustom->setCurrentIndex(GlobalSettings); - diagnosticWidget->refresh(ClangToolsSettings::instance()->savedDiagnosticConfigId()); - diagnosticWidget->setEnabled(false); - } else { - m_ui->globalOrCustom->setCurrentIndex(CustomSettings); - diagnosticWidget->refresh(m_customDiagnosticConfig); - diagnosticWidget->setEnabled(true); - } - - connect(m_ui->globalOrCustom, - QOverload::of(&QComboBox::currentIndexChanged), - [=](int index){ - diagnosticWidget->setEnabled(index == CustomSettings); - if (index == CustomSettings) - diagnosticWidget->refresh(m_customDiagnosticConfig); - else - diagnosticWidget->refresh(ClangToolsSettings::instance()->savedDiagnosticConfigId()); - }); - connect(diagnosticWidget, - &ClangDiagnosticConfigsSelectionWidget::currentConfigChanged, - [this](const Core::Id ¤tConfigId) { - if (m_ui->globalOrCustom->currentIndex() == CustomSettings) - m_customDiagnosticConfig = currentConfigId; - }); // Restore selection if (settings->selectedDirs().isEmpty() && settings->selectedFiles().isEmpty()) @@ -333,16 +294,6 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo, connect(m_filesModel.get(), &QAbstractItemModel::dataChanged, [this]() { m_analyzeButton->setEnabled(m_filesModel->hasCheckedFiles()); }); - - connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed, - this, [=]() { - if (m_ui->globalOrCustom->currentIndex() == CustomSettings) { - diagnosticWidget->refresh(m_customDiagnosticConfig); - } else { - diagnosticWidget->refresh( - ClangToolsSettings::instance()->savedDiagnosticConfigId()); - } - }); } SelectableFilesDialog::~SelectableFilesDialog() = default; @@ -356,11 +307,6 @@ void SelectableFilesDialog::accept() { ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); - // Save diagnostic configuration - settings->setUseGlobalSettings(m_ui->globalOrCustom->currentIndex() == GlobalSettings); - settings->setDiagnosticConfig(m_customDiagnosticConfig); - - // Save file selection QSet checkedDirs; QSet checkedFiles; m_filesModel->minimalSelection(checkedDirs, checkedFiles); diff --git a/src/plugins/clangtools/clangselectablefilesdialog.ui b/src/plugins/clangtools/clangselectablefilesdialog.ui index 267b36364a..834f3fc189 100644 --- a/src/plugins/clangtools/clangselectablefilesdialog.ui +++ b/src/plugins/clangtools/clangselectablefilesdialog.ui @@ -11,66 +11,14 @@ - Analyzer Configuration + Files to Analyze - - - General + + + true - - - - - - - - Global Settings - - - - - Custom Settings - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - Files to Analyze - - - - - - true - - - - @@ -85,13 +33,6 @@ - - - CppTools::ClangDiagnosticConfigsSelectionWidget - QWidget -
cpptools/clangdiagnosticconfigsselectionwidget.h
-
-
diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp index 85be64da49..a5196765c6 100644 --- a/src/plugins/clangtools/clangtidyclazytool.cpp +++ b/src/plugins/clangtools/clangtidyclazytool.cpp @@ -40,11 +40,6 @@ #include #include -#include -#include -#include -#include - #include #include @@ -362,22 +357,17 @@ ClangTidyClazyTool *ClangTidyClazyTool::instance() return s_instance; } -static ClangDiagnosticConfig getDiagnosticConfig(Project *project) +void ClangTidyClazyTool::selectPerspective() { - ClangToolsProjectSettings *projectSettings = ClangToolsProjectSettingsManager::getSettings( - project); + m_perspective.select(); +} - Core::Id diagnosticConfigId; +static RunSettings runSettings(Project *project) +{ + auto *projectSettings = ClangToolsProjectSettingsManager::getSettings(project); if (projectSettings->useGlobalSettings()) - diagnosticConfigId = ClangToolsSettings::instance()->savedDiagnosticConfigId(); - else - diagnosticConfigId = projectSettings->diagnosticConfig(); - - const ClangDiagnosticConfigsModel configsModel( - CppTools::codeModelSettings()->clangCustomDiagnosticConfigs()); - - QTC_ASSERT(configsModel.hasConfigWithId(diagnosticConfigId), return ClangDiagnosticConfig()); - return configsModel.configWithId(diagnosticConfigId); + return ClangToolsSettings::instance()->runSettings(); + return projectSettings->runSettings(); } void ClangTidyClazyTool::startTool(FileSelection fileSelection) @@ -397,7 +387,7 @@ void ClangTidyClazyTool::startTool(FileSelection fileSelection) const bool preventBuild = fileSelection == FileSelection::CurrentFile; auto clangTool = new ClangToolRunWorker(runControl, - getDiagnosticConfig(project), + runSettings(project), fileInfos, preventBuild); diff --git a/src/plugins/clangtools/clangtidyclazytool.h b/src/plugins/clangtools/clangtidyclazytool.h index be96438117..5ae11ff440 100644 --- a/src/plugins/clangtools/clangtidyclazytool.h +++ b/src/plugins/clangtools/clangtidyclazytool.h @@ -51,6 +51,8 @@ public: static ClangTidyClazyTool *instance(); + void selectPerspective(); + void startTool(FileSelection fileSelection) final; Diagnostics read(OutputFileFormat outputFileFormat, diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index dc22e7a39b..9581fef4eb 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -29,6 +29,7 @@ #include "clangtidyclazytool.h" #include "clangtool.h" #include "clangtoolslogfilereader.h" +#include "clangtoolsprojectsettings.h" #include "clangtoolssettings.h" #include "clangtoolsutils.h" @@ -40,7 +41,9 @@ #include #include +#include #include +#include #include #include #include @@ -219,19 +222,28 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits) return debug; } +static ClangDiagnosticConfig diagnosticConfig(const Core::Id &diagConfigId) +{ + const ClangDiagnosticConfigsModel configsModel( + CppTools::codeModelSettings()->clangCustomDiagnosticConfigs()); + + QTC_ASSERT(configsModel.hasConfigWithId(diagConfigId), return ClangDiagnosticConfig()); + return configsModel.configWithId(diagConfigId); +} + ClangToolRunWorker::ClangToolRunWorker(RunControl *runControl, - const ClangDiagnosticConfig &diagnosticConfig, + const RunSettings &runSettings, const FileInfos &fileInfos, bool preventBuild) : RunWorker(runControl) - , m_temporaryDir("clangtools-XXXXXX") - , m_diagnosticConfig(diagnosticConfig) + , m_diagnosticConfig(diagnosticConfig(runSettings.diagnosticConfigId())) , m_fileInfos(fileInfos) + , m_temporaryDir("clangtools-XXXXXX") { setId("ClangTidyClazyRunner"); setSupportsReRunning(false); - if (!preventBuild && ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) { + if (!preventBuild && runSettings.buildBeforeAnalysis()) { m_projectBuilder = new ProjectBuilder(runControl); addStartDependency(m_projectBuilder); } @@ -272,11 +284,9 @@ void ClangToolRunWorker::start() TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID); ProjectExplorerPlugin::saveModifiedFiles(); - if (ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) { - if (m_projectBuilder && !m_projectBuilder->success()) { - reportFailure(); - return; - } + if (m_projectBuilder && !m_projectBuilder->success()) { + reportFailure(); + return; } const QString &toolName = tool()->name(); @@ -337,7 +347,7 @@ void ClangToolRunWorker::start() // Start process(es) qCDebug(LOG) << "Environment:" << m_environment; m_runners.clear(); - const int parallelRuns = ClangToolsSettings::instance()->savedSimultaneousProcesses(); + const int parallelRuns = m_runSettings.parallelJobs(); QTC_ASSERT(parallelRuns >= 1, reportFailure(); return); m_success = true; @@ -491,7 +501,7 @@ void ClangToolRunWorker::finalize() TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); Target *target = runControl()->target(); if (target && !target->activeBuildConfiguration()->buildDirectory().exists() - && !ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) { + && !m_runSettings.buildBeforeAnalysis()) { msg = tr("%1: You might need to build the project to generate or update source " "files. To build automatically, enable \"Build the project before starting " "analysis\".") diff --git a/src/plugins/clangtools/clangtoolruncontrol.h b/src/plugins/clangtools/clangtoolruncontrol.h index 842350a7f4..bfada9e502 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.h +++ b/src/plugins/clangtools/clangtoolruncontrol.h @@ -26,6 +26,7 @@ #pragma once #include "clangfileinfo.h" +#include "clangtoolssettings.h" #include #include @@ -66,7 +67,7 @@ class ClangToolRunWorker : public ProjectExplorer::RunWorker public: ClangToolRunWorker(ProjectExplorer::RunControl *runControl, - const CppTools::ClangDiagnosticConfig &diagnosticConfig, + const RunSettings &runSettings, const FileInfos &fileInfos, bool preventBuild); @@ -93,15 +94,15 @@ private: void finalize(); -protected: - ProjectBuilder *m_projectBuilder = nullptr; - Utils::Environment m_environment; - Utils::TemporaryDirectory m_temporaryDir; - private: + RunSettings m_runSettings; CppTools::ClangDiagnosticConfig m_diagnosticConfig; FileInfos m_fileInfos; + ProjectBuilder *m_projectBuilder = nullptr; + Utils::Environment m_environment; + Utils::TemporaryDirectory m_temporaryDir; + CppTools::ProjectInfo m_projectInfoBeforeBuild; CppTools::ProjectInfo m_projectInfo; QString m_targetTriple; diff --git a/src/plugins/clangtools/clangtools.pro b/src/plugins/clangtools/clangtools.pro index a089f1edb7..49d4cf83a5 100644 --- a/src/plugins/clangtools/clangtools.pro +++ b/src/plugins/clangtools/clangtools.pro @@ -32,6 +32,7 @@ SOURCES += \ clangtoolsprojectsettings.cpp \ clangtoolssettings.cpp \ clangtoolsutils.cpp \ + runsettingswidget.cpp \ settingswidget.cpp \ HEADERS += \ @@ -54,11 +55,13 @@ HEADERS += \ clangtoolsprojectsettings.h \ clangtoolssettings.h \ clangtoolsutils.h \ + runsettingswidget.h \ settingswidget.h \ FORMS += \ clangselectablefilesdialog.ui \ clangtoolsprojectsettingswidget.ui \ + runsettingswidget.ui \ settingswidget.ui \ equals(TEST, 1) { diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs index 32146f87c0..e0742256d5 100644 --- a/src/plugins/clangtools/clangtools.qbs +++ b/src/plugins/clangtools/clangtools.qbs @@ -68,6 +68,9 @@ QtcPlugin { "clangtoolsutils.h", "clangtoolsplugin.cpp", "clangtoolsplugin.h", + "runsettingswidget.cpp", + "runsettingswidget.h", + "runsettingswidget.ui", "settingswidget.cpp", "settingswidget.h", "settingswidget.ui", diff --git a/src/plugins/clangtools/clangtoolsplugin.cpp b/src/plugins/clangtools/clangtoolsplugin.cpp index fed9cb2150..b432891110 100644 --- a/src/plugins/clangtools/clangtoolsplugin.cpp +++ b/src/plugins/clangtools/clangtoolsplugin.cpp @@ -88,18 +88,11 @@ public: return m_widget; } - void apply() override - { - ClangToolsSettings::instance()->writeSettings(); - } - - void finish() override - { - delete m_widget; - } + void apply() override { m_widget->apply(); } + void finish() override { delete m_widget; } private: - QPointer m_widget; + QPointer m_widget; }; class ClangToolsPluginPrivate diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.cpp b/src/plugins/clangtools/clangtoolsprojectsettings.cpp index 6c2597789d..005897b49c 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettings.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettings.cpp @@ -34,8 +34,9 @@ namespace ClangTools { namespace Internal { +static const char SETTINGS_KEY_MAIN[] = "ClangTools"; +static const char SETTINGS_PREFIX[] = "ClangTools."; static const char SETTINGS_KEY_USE_GLOBAL_SETTINGS[] = "ClangTools.UseGlobalSettings"; -static const char SETTINGS_KEY_DIAGNOSTIC_CONFIG[] = "ClangTools.DiagnosticConfig"; static const char SETTINGS_KEY_SELECTED_DIRS[] = "ClangTools.SelectedDirs"; static const char SETTINGS_KEY_SELECTED_FILES[] = "ClangTools.SelectedFiles"; static const char SETTINGS_KEY_SUPPRESSED_DIAGS[] = "ClangTools.SuppressedDiagnostics"; @@ -78,22 +79,53 @@ void ClangToolsProjectSettings::removeAllSuppressedDiagnostics() emit suppressedDiagnosticsChanged(); } +static QVariantMap convertToMapFromVersionBefore410(ProjectExplorer::Project *p) +{ + // These keys haven't changed. + const QStringList keys = { + SETTINGS_KEY_SELECTED_DIRS, + SETTINGS_KEY_SELECTED_FILES, + SETTINGS_KEY_SUPPRESSED_DIAGS, + SETTINGS_KEY_USE_GLOBAL_SETTINGS, + "ClangTools.BuildBeforeAnalysis", + }; + + QVariantMap map; + for (const QString &key : keys) + map.insert(key, p->namedSettings(key)); + + map.insert(SETTINGS_PREFIX + QString(diagnosticConfigIdKey), + p->namedSettings("ClangTools.DiagnosticConfig")); + + return map; +} + void ClangToolsProjectSettings::load() { - const QVariant useGlobalVariant = m_project->namedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS); - m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true; - m_diagnosticConfig = Core::Id::fromSetting( - m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG)); + // Load map + QVariantMap map = m_project->namedSettings(SETTINGS_KEY_MAIN).toMap(); + + bool write; + if (map.isEmpty()) { + if (!m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).isNull()) { + map = convertToMapFromVersionBefore410(m_project); + write = true; + } else { + return; // Use defaults + } + } - auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); }; + // Read map + m_useGlobalSettings = map.value(SETTINGS_KEY_USE_GLOBAL_SETTINGS).toBool(); - const QStringList dirs = m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).toStringList(); + auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); }; + const QStringList dirs = map.value(SETTINGS_KEY_SELECTED_DIRS).toStringList(); m_selectedDirs = Utils::transform(dirs, toFileName); - const QStringList files = m_project->namedSettings(SETTINGS_KEY_SELECTED_FILES).toStringList(); + const QStringList files = map.value(SETTINGS_KEY_SELECTED_FILES).toStringList(); m_selectedFiles = Utils::transform(files, toFileName); - const QVariantList list = m_project->namedSettings(SETTINGS_KEY_SUPPRESSED_DIAGS).toList(); + const QVariantList list = map.value(SETTINGS_KEY_SUPPRESSED_DIAGS).toList(); foreach (const QVariant &v, list) { const QVariantMap diag = v.toMap(); const QString fp = diag.value(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH).toString(); @@ -113,48 +145,37 @@ void ClangToolsProjectSettings::load() uniquifier); } emit suppressedDiagnosticsChanged(); + + m_runSettings.fromMap(map, SETTINGS_PREFIX); + + if (write) + store(); // Store new settings format } void ClangToolsProjectSettings::store() { - m_project->setNamedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS, m_useGlobalSettings); - m_project->setNamedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG, m_diagnosticConfig.toSetting()); + QVariantMap map; + map.insert(SETTINGS_KEY_USE_GLOBAL_SETTINGS, m_useGlobalSettings); const QStringList dirs = Utils::transform(m_selectedDirs, &Utils::FilePath::toString); - m_project->setNamedSettings(SETTINGS_KEY_SELECTED_DIRS, dirs); + map.insert(SETTINGS_KEY_SELECTED_DIRS, dirs); const QStringList files = Utils::transform(m_selectedFiles, &Utils::FilePath::toString); - m_project->setNamedSettings(SETTINGS_KEY_SELECTED_FILES, files); + map.insert(SETTINGS_KEY_SELECTED_FILES, files); QVariantList list; - foreach (const SuppressedDiagnostic &diag, m_suppressedDiagnostics) { + for (const SuppressedDiagnostic &diag : m_suppressedDiagnostics) { QVariantMap diagMap; diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH, diag.filePath.toString()); diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_MESSAGE, diag.description); diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_UNIQIFIER, diag.uniquifier); list << diagMap; } - m_project->setNamedSettings(SETTINGS_KEY_SUPPRESSED_DIAGS, list); -} + map.insert(SETTINGS_KEY_SUPPRESSED_DIAGS, list); -bool ClangToolsProjectSettings::useGlobalSettings() const -{ - return m_useGlobalSettings; -} - -void ClangToolsProjectSettings::setUseGlobalSettings(bool useGlobalSettings) -{ - m_useGlobalSettings = useGlobalSettings; -} + m_runSettings.toMap(map, SETTINGS_PREFIX); -Core::Id ClangToolsProjectSettings::diagnosticConfig() const -{ - return m_diagnosticConfig; -} - -void ClangToolsProjectSettings::setDiagnosticConfig(const Core::Id &diagnosticConfig) -{ - m_diagnosticConfig = diagnosticConfig; + m_project->setNamedSettings(SETTINGS_KEY_MAIN, map); } ClangToolsProjectSettingsManager::ClangToolsProjectSettingsManager() diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.h b/src/plugins/clangtools/clangtoolsprojectsettings.h index 0a6aa477d3..aaf045f056 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettings.h +++ b/src/plugins/clangtools/clangtoolsprojectsettings.h @@ -25,7 +25,7 @@ #pragma once -#include +#include "clangtoolssettings.h" #include #include @@ -70,11 +70,11 @@ public: ClangToolsProjectSettings(ProjectExplorer::Project *project); ~ClangToolsProjectSettings() override; - bool useGlobalSettings() const; - void setUseGlobalSettings(bool useGlobalSettings); + bool useGlobalSettings() const { return m_useGlobalSettings; } + void setUseGlobalSettings(bool useGlobalSettings) { m_useGlobalSettings = useGlobalSettings; } - Core::Id diagnosticConfig() const; - void setDiagnosticConfig(const Core::Id &diagnosticConfig); + RunSettings runSettings() const { return m_runSettings; } + void setRunSettings(const RunSettings &settings) { m_runSettings = settings; } QSet selectedDirs() const { return m_selectedDirs; } void setSelectedDirs(const QSet &value) { m_selectedDirs = value; } @@ -95,10 +95,14 @@ private: void store(); ProjectExplorer::Project *m_project; + bool m_useGlobalSettings = true; - Core::Id m_diagnosticConfig; + + RunSettings m_runSettings; + QSet m_selectedDirs; QSet m_selectedFiles; + SuppressedDiagnosticsList m_suppressedDiagnostics; }; diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp index 3e380aa9af..765cd34012 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp @@ -26,8 +26,12 @@ #include "clangtoolsprojectsettingswidget.h" #include "ui_clangtoolsprojectsettingswidget.h" +#include "clangtidyclazytool.h" +#include "clangtoolsconstants.h" #include "clangtoolsprojectsettings.h" +#include + #include #include @@ -56,12 +60,46 @@ private: SuppressedDiagnosticsList m_diagnostics; }; +enum { UseGlobalSettings, UseCustomSettings }; // Values in sync with m_ui->globalCustomComboBox + ProjectSettingsWidget::ProjectSettingsWidget(ProjectExplorer::Project *project, QWidget *parent) : QWidget(parent), m_ui(new Ui::ProjectSettingsWidget) , m_projectSettings(ClangToolsProjectSettingsManager::getSettings(project)) { m_ui->setupUi(this); + + // Use global/custom settings + const int globalOrCustomIndex = m_projectSettings->useGlobalSettings() ? UseGlobalSettings + : UseCustomSettings; + m_ui->globalCustomComboBox->setCurrentIndex(globalOrCustomIndex); + onGlobalCustomChanged(globalOrCustomIndex); + connect(m_ui->globalCustomComboBox, + QOverload::of(&QComboBox::currentIndexChanged), + this, + &ProjectSettingsWidget::onGlobalCustomChanged); + + // Restore global settings + connect(m_ui->restoreGlobal, &QPushButton::clicked, this, [this]() { + m_ui->runSettingsWidget->fromSettings(ClangToolsSettings::instance()->runSettings()); + }); + + // Links + connect(m_ui->gotoGlobalSettingsLabel, &QLabel::linkActivated, [](const QString &){ + Core::ICore::showOptionsDialog(ClangTools::Constants::SETTINGS_PAGE_ID); + }); + + connect(m_ui->gotoAnalyzerModeLabel, &QLabel::linkActivated, [](const QString &){ + ClangTidyClazyTool::instance()->selectPerspective(); + }); + + // Run options + m_ui->runSettingsWidget->fromSettings(m_projectSettings->runSettings()); + connect(m_ui->runSettingsWidget, &RunSettingsWidget::changed, [this]() { + m_projectSettings->setRunSettings(m_ui->runSettingsWidget->toSettings()); + }); + + // Suppressed diagnostics auto * const model = new SuppressedDiagnosticsModel(this); model->setDiagnostics(m_projectSettings->suppressedDiagnostics()); connect(m_projectSettings, &ClangToolsProjectSettings::suppressedDiagnosticsChanged, @@ -86,6 +124,14 @@ ProjectSettingsWidget::~ProjectSettingsWidget() delete m_ui; } +void ProjectSettingsWidget::onGlobalCustomChanged(int index) +{ + const bool useGlobal = index == UseGlobalSettings; + m_ui->runSettingsWidget->setEnabled(!useGlobal); + m_ui->restoreGlobal->setEnabled(!useGlobal); + m_projectSettings->setUseGlobalSettings(useGlobal); +} + void ProjectSettingsWidget::updateButtonStates() { updateButtonStateRemoveSelected(); diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.h b/src/plugins/clangtools/clangtoolsprojectsettingswidget.h index f9153f75a6..680431cc6e 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.h +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.h @@ -44,6 +44,8 @@ public: ~ProjectSettingsWidget() override; private: + void onGlobalCustomChanged(int index); + void updateButtonStates(); void updateButtonStateRemoveSelected(); void updateButtonStateRemoveAll(); diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.ui b/src/plugins/clangtools/clangtoolsprojectsettingswidget.ui index c120d3bb95..b8263a450a 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.ui +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.ui @@ -6,20 +6,41 @@ 0 0 - 400 - 300 + 615 + 399 - + - + + + + Use Global Settings + + + + + Use Customized Settings + + + + + + - Suppressed diagnostics: + Restore Global Settings + + + + + + + <a href="target">Show Global Settings</a> @@ -36,52 +57,79 @@ - - - - - - - QAbstractItemView::SingleSelection + + + <a href="target">Go to Analyzer</a> - - - - - - Remove Selected - - - - - - - Remove All - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + + + + + + Suppressed diagnostics + + + + + + + + QAbstractItemView::SingleSelection + + + + + + + + + Remove Selected + + + + + + + Remove All + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + ClangTools::Internal::RunSettingsWidget + QWidget +
clangtools/runsettingswidget.h
+ 1 +
+
diff --git a/src/plugins/clangtools/clangtoolssettings.cpp b/src/plugins/clangtools/clangtoolssettings.cpp index 86f152f660..07b9592a8e 100644 --- a/src/plugins/clangtools/clangtoolssettings.cpp +++ b/src/plugins/clangtools/clangtoolssettings.cpp @@ -29,160 +29,112 @@ #include -#include -#include - -#include #include -static const char simultaneousProcessesKey[] = "simultaneousProcesses"; -static const char buildBeforeAnalysisKey[] = "buildBeforeAnalysis"; -static const char diagnosticConfigIdKey[] = "diagnosticConfigId"; -static const char clangTidyExecutableKey[] = "clangTidyExecutable"; -static const char clazyStandaloneExecutableKey[] = "clazyStandaloneExecutable"; +static const char clangTidyExecutableKey[] = "ClangTidyExecutable"; +static const char clazyStandaloneExecutableKey[] = "ClazyStandaloneExecutable"; -namespace ClangTools { -namespace Internal { +static const char parallelJobsKey[] = "ParallelJobs"; +static const char buildBeforeAnalysisKey[] = "BuildBeforeAnalysis"; -ClangToolsSettings::ClangToolsSettings() -{ - readSettings(); -} +static const char oldDiagnosticConfigIdKey[] = "diagnosticConfigId"; -ClangToolsSettings *ClangToolsSettings::instance() -{ - static ClangToolsSettings instance; - return &instance; -} +namespace ClangTools { +namespace Internal { -int ClangToolsSettings::savedSimultaneousProcesses() const +RunSettings::RunSettings() + : m_parallelJobs(qMax(0, QThread::idealThreadCount() / 2)) { - return m_savedSimultaneousProcesses; } -int ClangToolsSettings::simultaneousProcesses() const +void RunSettings::fromMap(const QVariantMap &map, const QString &prefix) { - return m_simultaneousProcesses; + m_diagnosticConfigId = Core::Id::fromSetting(map.value(prefix + diagnosticConfigIdKey)); + m_parallelJobs = map.value(prefix + parallelJobsKey).toInt(); + m_buildBeforeAnalysis = map.value(prefix + buildBeforeAnalysisKey).toBool(); } -void ClangToolsSettings::setSimultaneousProcesses(int processes) +void RunSettings::toMap(QVariantMap &map, const QString &prefix) const { - m_simultaneousProcesses = processes; + map.insert(prefix + diagnosticConfigIdKey, m_diagnosticConfigId.toSetting()); + map.insert(prefix + parallelJobsKey, m_parallelJobs); + map.insert(prefix + buildBeforeAnalysisKey, m_buildBeforeAnalysis); } -bool ClangToolsSettings::savedBuildBeforeAnalysis() const +ClangToolsSettings::ClangToolsSettings() { - return m_savedBuildBeforeAnalysis; + readSettings(); } -bool ClangToolsSettings::buildBeforeAnalysis() const +ClangToolsSettings *ClangToolsSettings::instance() { - return m_buildBeforeAnalysis; + static ClangToolsSettings instance; + return &instance; } -void ClangToolsSettings::setBuildBeforeAnalysis(bool build) +static QVariantMap convertToMapFromVersionBefore410(QSettings *s) { - m_buildBeforeAnalysis = build; -} + const char oldParallelJobsKey[] = "simultaneousProcesses"; + const char oldBuildBeforeAnalysisKey[] = "buildBeforeAnalysis"; -Core::Id ClangToolsSettings::savedDiagnosticConfigId() const -{ - return m_savedDiagnosticConfigId; -} + QVariantMap map; + map.insert(diagnosticConfigIdKey, s->value(oldDiagnosticConfigIdKey)); + map.insert(parallelJobsKey, s->value(oldParallelJobsKey)); + map.insert(buildBeforeAnalysisKey, s->value(oldBuildBeforeAnalysisKey)); -Core::Id ClangToolsSettings::diagnosticConfigId() const -{ - return m_diagnosticConfigId; -} + s->remove(oldDiagnosticConfigIdKey); + s->remove(oldParallelJobsKey); + s->remove(oldBuildBeforeAnalysisKey); -void ClangToolsSettings::setDiagnosticConfigId(Core::Id id) -{ - m_diagnosticConfigId = id; + return map; } -void ClangToolsSettings::updateSavedBuildBeforeAnalysiIfRequired() -{ - if (m_savedBuildBeforeAnalysis == m_buildBeforeAnalysis) - return; - m_savedBuildBeforeAnalysis = m_buildBeforeAnalysis; - emit buildBeforeAnalysisChanged(m_savedBuildBeforeAnalysis); -} - -QString ClangToolsSettings::savedClazyStandaloneExecutable() const +void ClangToolsSettings::readSettings() { - return m_savedClazyStandaloneExecutable; -} + QSettings *s = Core::ICore::settings(); + s->beginGroup(Constants::SETTINGS_ID); + m_clangTidyExecutable = s->value(clangTidyExecutableKey).toString(); + m_clazyStandaloneExecutable = s->value(clazyStandaloneExecutableKey).toString(); -QString ClangToolsSettings::savedClangTidyExecutable() const -{ - return m_savedClangTidyExecutable; -} + bool write = false; -QString ClangToolsSettings::clazyStandaloneExecutable() const -{ - return m_clazyStandaloneExecutable; -} + QVariantMap map; + if (!s->value(oldDiagnosticConfigIdKey).isNull()) { + map = convertToMapFromVersionBefore410(s); + write = true; + } else { + QVariantMap defaults; + defaults.insert(diagnosticConfigIdKey, m_runSettings.diagnosticConfigId().toSetting()); + defaults.insert(parallelJobsKey, m_runSettings.parallelJobs()); + defaults.insert(buildBeforeAnalysisKey, m_runSettings.buildBeforeAnalysis()); + map = defaults; + for (QVariantMap::ConstIterator it = defaults.constBegin(); it != defaults.constEnd(); ++it) + map.insert(it.key(), s->value(it.key(), it.value())); + } -void ClangToolsSettings::setClazyStandaloneExecutable(const QString &path) -{ - m_clazyStandaloneExecutable = path; -} + // Run settings + m_runSettings.fromMap(map); -QString ClangToolsSettings::clangTidyExecutable() const -{ - return m_clangTidyExecutable; -} + s->endGroup(); -void ClangToolsSettings::setClangTidyExecutable(const QString &path) -{ - m_clangTidyExecutable = path; + if (write) + writeSettings(); } -void ClangToolsSettings::readSettings() +void ClangToolsSettings::writeSettings() { - QSettings *settings = Core::ICore::settings(); - settings->beginGroup(QLatin1String(Constants::SETTINGS_ID)); - - const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2); - m_savedSimultaneousProcesses = m_simultaneousProcesses - = settings->value(QString(simultaneousProcessesKey), - defaultSimultaneousProcesses).toInt(); - - m_buildBeforeAnalysis = settings->value(QString(buildBeforeAnalysisKey), true).toBool(); + QSettings *s = Core::ICore::settings(); + s->beginGroup(Constants::SETTINGS_ID); - m_savedClangTidyExecutable = m_clangTidyExecutable - = settings->value(QLatin1String(clangTidyExecutableKey)).toString(); - m_savedClazyStandaloneExecutable = m_clazyStandaloneExecutable - = settings->value(QLatin1String(clazyStandaloneExecutableKey)).toString(); + s->setValue(clangTidyExecutableKey, m_clangTidyExecutable); + s->setValue(clazyStandaloneExecutableKey, m_clazyStandaloneExecutable); - m_diagnosticConfigId = Core::Id::fromSetting(settings->value(QString(diagnosticConfigIdKey))); - if (!m_diagnosticConfigId.isValid()) - m_diagnosticConfigId = "Builtin.TidyAndClazy"; + QVariantMap map; + m_runSettings.toMap(map); + for (QVariantMap::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) + s->setValue(it.key(), it.value()); - m_savedDiagnosticConfigId = m_diagnosticConfigId; - - updateSavedBuildBeforeAnalysiIfRequired(); - - settings->endGroup(); -} - -void ClangToolsSettings::writeSettings() -{ - QSettings *settings = Core::ICore::settings(); - settings->beginGroup(QString(Constants::SETTINGS_ID)); - settings->setValue(QString(simultaneousProcessesKey), m_simultaneousProcesses); - settings->setValue(QString(buildBeforeAnalysisKey), m_buildBeforeAnalysis); - settings->setValue(QString(clangTidyExecutableKey), m_clangTidyExecutable); - settings->setValue(QString(clazyStandaloneExecutableKey), m_clazyStandaloneExecutable); - settings->setValue(QString(diagnosticConfigIdKey), m_diagnosticConfigId.toSetting()); - - m_savedSimultaneousProcesses = m_simultaneousProcesses; - m_savedDiagnosticConfigId = m_diagnosticConfigId; - m_savedClangTidyExecutable = m_clangTidyExecutable; - m_savedClazyStandaloneExecutable = m_clazyStandaloneExecutable; - updateSavedBuildBeforeAnalysiIfRequired(); - - settings->endGroup(); + s->endGroup(); } } // namespace Internal diff --git a/src/plugins/clangtools/clangtoolssettings.h b/src/plugins/clangtools/clangtoolssettings.h index 402845d20f..893dbd23f9 100644 --- a/src/plugins/clangtools/clangtoolssettings.h +++ b/src/plugins/clangtools/clangtoolssettings.h @@ -27,61 +27,61 @@ #include -#include #include namespace ClangTools { namespace Internal { -// TODO: Remove need for "saved* members -class ClangToolsSettings : public QObject +const char diagnosticConfigIdKey[] = "DiagnosticConfigId"; + +class RunSettings { - Q_OBJECT public: - static ClangToolsSettings *instance(); + RunSettings(); - void writeSettings(); + void fromMap(const QVariantMap &map, const QString &prefix = QString()); + void toMap(QVariantMap &map, const QString &prefix = QString()) const; - int savedSimultaneousProcesses() const; - bool savedBuildBeforeAnalysis() const; - Core::Id savedDiagnosticConfigId() const; - QString savedClangTidyExecutable() const; - QString savedClazyStandaloneExecutable() const; + Core::Id diagnosticConfigId() const { return m_diagnosticConfigId; } + void setDiagnosticConfigId(const Core::Id &id) { m_diagnosticConfigId = id; } - int simultaneousProcesses() const; - void setSimultaneousProcesses(int processes); + bool buildBeforeAnalysis() const { return m_buildBeforeAnalysis; } + void setBuildBeforeAnalysis(bool yesno) { m_buildBeforeAnalysis = yesno; } - bool buildBeforeAnalysis() const; - void setBuildBeforeAnalysis(bool build); + int parallelJobs() const { return m_parallelJobs; } + void setParallelJobs(int jobs) { m_parallelJobs = jobs; } + +private: + Core::Id m_diagnosticConfigId = "Builtin.TidyAndClazy"; // TODO + int m_parallelJobs = -1; + bool m_buildBeforeAnalysis = true; +}; - Core::Id diagnosticConfigId() const; - void setDiagnosticConfigId(Core::Id id); +class ClangToolsSettings +{ +public: + static ClangToolsSettings *instance(); + void writeSettings(); - QString clangTidyExecutable() const; - void setClangTidyExecutable(const QString &path); + QString clangTidyExecutable() const { return m_clangTidyExecutable; } + void setClangTidyExecutable(const QString &path) { m_clangTidyExecutable = path; } - QString clazyStandaloneExecutable() const; - void setClazyStandaloneExecutable(const QString &path); + QString clazyStandaloneExecutable() const { return m_clazyStandaloneExecutable; } + void setClazyStandaloneExecutable(const QString &path) { m_clazyStandaloneExecutable = path; } -signals: - void buildBeforeAnalysisChanged(bool checked) const; + RunSettings runSettings() const { return m_runSettings; } + void setRunSettings(const RunSettings &settings) { m_runSettings = settings; } private: ClangToolsSettings(); void readSettings(); - void updateSavedBuildBeforeAnalysiIfRequired(); - - int m_simultaneousProcesses = -1; - int m_savedSimultaneousProcesses = -1; - bool m_buildBeforeAnalysis = false; - bool m_savedBuildBeforeAnalysis= false; + // Executables QString m_clangTidyExecutable; - QString m_savedClangTidyExecutable; QString m_clazyStandaloneExecutable; - QString m_savedClazyStandaloneExecutable; - Core::Id m_diagnosticConfigId; - Core::Id m_savedDiagnosticConfigId; + + // Run settings + RunSettings m_runSettings; }; } // namespace Internal diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp index b8546c58bd..5a034c61b6 100644 --- a/src/plugins/clangtools/clangtoolsunittests.cpp +++ b/src/plugins/clangtools/clangtoolsunittests.cpp @@ -87,7 +87,8 @@ static CppTools::ClangDiagnosticConfig configFor(const QString &tidyChecks, config.setIsReadOnly(true); config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")}); config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksPrefixList); - config.setClangTidyChecks("-*," + tidyChecks); + const QString theTidyChecks = tidyChecks.isEmpty() ? tidyChecks : "-*," + tidyChecks; + config.setClangTidyChecks(theTidyChecks); config.setClazyChecks(clazyChecks); return config; } @@ -115,7 +116,7 @@ void ClangToolsUnitTests::testProject() ClangToolsSettings *clangToolsSettings = ClangToolsSettings::instance(); const CppTools::ClangDiagnosticConfigs originalConfigs = cppToolsSettings ->clangCustomDiagnosticConfigs(); - const Core::Id originalId = clangToolsSettings->diagnosticConfigId(); + const Core::Id originalId = clangToolsSettings->runSettings().diagnosticConfigId(); CppTools::ClangDiagnosticConfigs modifiedConfigs = originalConfigs; modifiedConfigs.push_back(diagnosticConfig); @@ -123,12 +124,16 @@ void ClangToolsUnitTests::testProject() ExecuteOnDestruction executeOnDestruction([=]() { // Restore configs cppToolsSettings->setClangCustomDiagnosticConfigs(originalConfigs); - clangToolsSettings->setDiagnosticConfigId(originalId); + RunSettings runSettings = clangToolsSettings->runSettings(); + runSettings.setDiagnosticConfigId(originalId); + clangToolsSettings->setRunSettings(runSettings); clangToolsSettings->writeSettings(); }); cppToolsSettings->setClangCustomDiagnosticConfigs(modifiedConfigs); - clangToolsSettings->setDiagnosticConfigId(diagnosticConfig.id()); + RunSettings runSettings = clangToolsSettings->runSettings(); + runSettings.setDiagnosticConfigId(diagnosticConfig.id()); + clangToolsSettings->setRunSettings(runSettings); clangToolsSettings->writeSettings(); tool->startTool(ClangTidyClazyTool::FileSelection::AllFiles); diff --git a/src/plugins/clangtools/runsettingswidget.cpp b/src/plugins/clangtools/runsettingswidget.cpp new file mode 100644 index 0000000000..1a26d2e7d0 --- /dev/null +++ b/src/plugins/clangtools/runsettingswidget.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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. +** +****************************************************************************/ + +#include "runsettingswidget.h" + +#include "ui_runsettingswidget.h" + +#include "clangtoolssettings.h" +#include "clangtoolsutils.h" + +#include + +namespace ClangTools { +namespace Internal { + +RunSettingsWidget::RunSettingsWidget(QWidget *parent) + : QWidget(parent) + , m_ui(new Ui::RunSettingsWidget) +{ + m_ui->setupUi(this); + + connect(m_ui->diagnosticWidget, + &CppTools::ClangDiagnosticConfigsSelectionWidget::currentConfigChanged, + [this](const Core::Id &) { emit changed(); }); + // m_ui->buildBeforeAnalysis is handled in fromSettings() + connect(m_ui->parallelJobsSpinBox, + QOverload::of(&QSpinBox::valueChanged), + [this](int) { emit changed(); }); +} + +RunSettingsWidget::~RunSettingsWidget() +{ + delete m_ui; +} + +void RunSettingsWidget::fromSettings(const RunSettings &s) +{ + m_ui->diagnosticWidget->refresh(s.diagnosticConfigId()); + + disconnect(m_ui->buildBeforeAnalysis, 0, 0, 0); + m_ui->buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis()); + m_ui->buildBeforeAnalysis->setCheckState(s.buildBeforeAnalysis() ? Qt::Checked : Qt::Unchecked); + connect(m_ui->buildBeforeAnalysis, &QCheckBox::toggled, [this](bool checked) { + if (!checked) + showHintAboutBuildBeforeAnalysis(); + emit changed(); + }); + + m_ui->parallelJobsSpinBox->setValue(s.parallelJobs()); + m_ui->parallelJobsSpinBox->setMinimum(1); + m_ui->parallelJobsSpinBox->setMaximum(QThread::idealThreadCount()); +} + +RunSettings RunSettingsWidget::toSettings() const +{ + RunSettings s; + s.setDiagnosticConfigId(m_ui->diagnosticWidget->currentConfigId()); + s.setBuildBeforeAnalysis(m_ui->buildBeforeAnalysis->checkState() == Qt::CheckState::Checked); + s.setParallelJobs(m_ui->parallelJobsSpinBox->value()); + + return s; +} + +} // namespace Internal +} // namespace ClangTools diff --git a/src/plugins/clangtools/runsettingswidget.h b/src/plugins/clangtools/runsettingswidget.h new file mode 100644 index 0000000000..c49bc88f75 --- /dev/null +++ b/src/plugins/clangtools/runsettingswidget.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 + +namespace ClangTools { +namespace Internal { + +class RunSettings; + +namespace Ui { +class RunSettingsWidget; +} + +class RunSettingsWidget : public QWidget +{ + Q_OBJECT + +public: + explicit RunSettingsWidget(QWidget *parent = nullptr); + ~RunSettingsWidget(); + + void fromSettings(const RunSettings &s); + RunSettings toSettings() const; + +signals: + void changed(); + +private: + Ui::RunSettingsWidget *m_ui; +}; + +} // namespace Internal +} // namespace ClangTools diff --git a/src/plugins/clangtools/runsettingswidget.ui b/src/plugins/clangtools/runsettingswidget.ui new file mode 100644 index 0000000000..e7ad362c84 --- /dev/null +++ b/src/plugins/clangtools/runsettingswidget.ui @@ -0,0 +1,93 @@ + + + ClangTools::Internal::RunSettingsWidget + + + + 0 + 0 + 383 + 125 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Run Options + + + + + + + + + Build the project before analysis + + + + + + + + + Parallel jobs: + + + + + + + 1 + + + 32 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + CppTools::ClangDiagnosticConfigsSelectionWidget + QWidget +
cpptools/clangdiagnosticconfigsselectionwidget.h
+
+
+ + +
diff --git a/src/plugins/clangtools/settingswidget.cpp b/src/plugins/clangtools/settingswidget.cpp index de5976a04f..110135a779 100644 --- a/src/plugins/clangtools/settingswidget.cpp +++ b/src/plugins/clangtools/settingswidget.cpp @@ -30,17 +30,6 @@ #include "clangtoolsconstants.h" #include "clangtoolsutils.h" -#include - -#include -#include -#include - -#include -#include - -#include - namespace ClangTools { namespace Internal { @@ -48,15 +37,13 @@ static void setupPathChooser(Utils::PathChooser *const chooser, const QString &promptDiaglogTitle, const QString &placeHolderText, const QString &pathFromSettings, - const QString &historyCompleterId, - std::function savePath) + const QString &historyCompleterId) { chooser->setPromptDialogTitle(promptDiaglogTitle); chooser->lineEdit()->setPlaceholderText(placeHolderText); chooser->setPath(pathFromSettings); chooser->setExpectedKind(Utils::PathChooser::ExistingCommand); chooser->setHistoryCompleter(historyCompleterId); - QObject::connect(chooser, &Utils::PathChooser::rawPathChanged, savePath), chooser->setValidationFunction([chooser](Utils::FancyLineEdit *edit, QString *errorMessage) { const QString currentFilePath = chooser->fileName().toString(); Utils::PathChooser pc; @@ -92,8 +79,7 @@ SettingsWidget::SettingsWidget(ClangToolsSettings *settings, QWidget *parent) tr("Clang-Tidy Executable"), placeHolderText, path, - "ClangTools.ClangTidyExecutable.History", - [settings](const QString &path) { settings->setClangTidyExecutable(path); }); + "ClangTools.ClangTidyExecutable.History"); if (qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty()) { m_ui->clazyStandalonePathChooser->setVisible(false); @@ -107,47 +93,23 @@ SettingsWidget::SettingsWidget(ClangToolsSettings *settings, QWidget *parent) tr("Clazy Executable"), placeHolderText, path, - "ClangTools.ClazyStandaloneExecutable.History", - [settings](const QString &path) { - settings->setClazyStandaloneExecutable(path); - }); + "ClangTools.ClazyStandaloneExecutable.History"); } // // Group box "Run Options" // - m_ui->simultaneousProccessesSpinBox->setValue(settings->savedSimultaneousProcesses()); - m_ui->simultaneousProccessesSpinBox->setMinimum(1); - m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount()); - connect(m_ui->simultaneousProccessesSpinBox, - QOverload::of(&QSpinBox::valueChanged), - [settings](int count) { settings->setSimultaneousProcesses(count); }); - - QCheckBox *buildBeforeAnalysis = m_ui->buildBeforeAnalysis; - buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis()); - buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis() - ? Qt::Checked : Qt::Unchecked); - connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) { - if (!checked) - showHintAboutBuildBeforeAnalysis(); - settings->setBuildBeforeAnalysis(checked); - }); - CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticWidget = m_ui->diagnosticWidget; - diagnosticWidget->refresh(settings->savedDiagnosticConfigId()); + m_ui->runSettingsWidget->fromSettings(m_settings->runSettings()); +} - connect(diagnosticWidget, - &CppTools::ClangDiagnosticConfigsSelectionWidget::currentConfigChanged, - this, [this](const Core::Id ¤tConfigId) { - m_settings->setDiagnosticConfigId(currentConfigId); - }); +void SettingsWidget::apply() +{ + m_settings->setClangTidyExecutable(m_ui->clangTidyPathChooser->rawPath()); + m_settings->setClazyStandaloneExecutable(m_ui->clazyStandalonePathChooser->rawPath()); + m_settings->setRunSettings(m_ui->runSettingsWidget->toSettings()); - connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed, - this, [=]() { - // Settings were applied so apply also the current selection if possible. - diagnosticWidget->refresh(m_settings->diagnosticConfigId()); - m_settings->writeSettings(); - }); + m_settings->writeSettings(); } SettingsWidget::~SettingsWidget() = default; diff --git a/src/plugins/clangtools/settingswidget.h b/src/plugins/clangtools/settingswidget.h index 6eeaeb5d98..2002f32eec 100644 --- a/src/plugins/clangtools/settingswidget.h +++ b/src/plugins/clangtools/settingswidget.h @@ -43,6 +43,9 @@ class SettingsWidget : public QWidget public: SettingsWidget(ClangToolsSettings *settings, QWidget *parent = nullptr); ~SettingsWidget() override; + + void apply(); + private: std::unique_ptr m_ui; ClangToolsSettings *m_settings; diff --git a/src/plugins/clangtools/settingswidget.ui b/src/plugins/clangtools/settingswidget.ui index c73148d0da..6ef3d09297 100644 --- a/src/plugins/clangtools/settingswidget.ui +++ b/src/plugins/clangtools/settingswidget.ui @@ -44,57 +44,7 @@ - - - Run Options - - - - - - - - - Build the project before analysis - - - - - - - - - Simultaneous processes: - - - - - - - 1 - - - 32 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + @@ -113,14 +63,15 @@ - CppTools::ClangDiagnosticConfigsSelectionWidget + Utils::PathChooser QWidget -
cpptools/clangdiagnosticconfigsselectionwidget.h
+
utils/pathchooser.h
+ 1
- Utils::PathChooser + ClangTools::Internal::RunSettingsWidget QWidget -
utils/pathchooser.h
+
clangtools/runsettingswidget.h
1
-- cgit v1.2.1 From d5bae3c1eb9d262293da4e6a1d66119040efd1db Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 25 Sep 2019 15:07:59 +0200 Subject: ClangTools: Merge ClangTidyClazyTool into ClangTool Change-Id: Ieb6c4994ddcff9339a9cfb25c82e23dd2d2e8912 Reviewed-by: Cristian Adam Reviewed-by: Nikolai Kosjar --- src/plugins/clangtools/CMakeLists.txt | 1 - src/plugins/clangtools/clangtidyclazytool.cpp | 559 --------------------- src/plugins/clangtools/clangtidyclazytool.h | 87 ---- src/plugins/clangtools/clangtool.cpp | 491 +++++++++++++++++- src/plugins/clangtools/clangtool.h | 52 +- src/plugins/clangtools/clangtoolruncontrol.cpp | 3 +- src/plugins/clangtools/clangtools.pro | 2 - src/plugins/clangtools/clangtools.qbs | 2 - src/plugins/clangtools/clangtoolsplugin.cpp | 11 +- .../clangtoolspreconfiguredsessiontests.cpp | 8 +- .../clangtools/clangtoolsprojectsettingswidget.cpp | 4 +- src/plugins/clangtools/clangtoolsunittests.cpp | 6 +- 12 files changed, 546 insertions(+), 680 deletions(-) delete mode 100644 src/plugins/clangtools/clangtidyclazytool.cpp delete mode 100644 src/plugins/clangtools/clangtidyclazytool.h diff --git a/src/plugins/clangtools/CMakeLists.txt b/src/plugins/clangtools/CMakeLists.txt index fe34b67948..f5f2c2a84c 100644 --- a/src/plugins/clangtools/CMakeLists.txt +++ b/src/plugins/clangtools/CMakeLists.txt @@ -14,7 +14,6 @@ add_qtc_plugin(ClangTools clangfixitsrefactoringchanges.cpp clangfixitsrefactoringchanges.h clangselectablefilesdialog.cpp clangselectablefilesdialog.h clangselectablefilesdialog.ui clangtidyclazyrunner.cpp clangtidyclazyrunner.h - clangtidyclazytool.cpp clangtidyclazytool.h clangtool.cpp clangtool.h clangtoolruncontrol.cpp clangtoolruncontrol.h clangtoolrunner.cpp clangtoolrunner.h diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp deleted file mode 100644 index a5196765c6..0000000000 --- a/src/plugins/clangtools/clangtidyclazytool.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#include "clangtidyclazytool.h" - -#include "clangfixitsrefactoringchanges.h" -#include "clangselectablefilesdialog.h" -#include "clangtoolruncontrol.h" -#include "clangtoolsconstants.h" -#include "clangtoolsdiagnosticmodel.h" -#include "clangtoolslogfilereader.h" -#include "clangtoolsdiagnosticview.h" -#include "clangtoolsprojectsettings.h" -#include "clangtoolssettings.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -using namespace Core; -using namespace CppTools; -using namespace Debugger; -using namespace ProjectExplorer; -using namespace Utils; - -namespace ClangTools { -namespace Internal { - -static ClangTidyClazyTool *s_instance; - -class ApplyFixIts -{ -public: - class RefactoringFileInfo - { - public: - bool isValid() const { return file.isValid(); } - - FixitsRefactoringFile file; - QVector diagnosticItems; - bool hasScheduledFixits = false; - }; - - ApplyFixIts(const QVector &diagnosticItems) - { - for (DiagnosticItem *diagnosticItem : diagnosticItems) { - const QString &filePath = diagnosticItem->diagnostic().location.filePath; - QTC_ASSERT(!filePath.isEmpty(), continue); - - // Get or create refactoring file - RefactoringFileInfo &fileInfo = m_refactoringFileInfos[filePath]; - if (!fileInfo.isValid()) - fileInfo.file = FixitsRefactoringFile(filePath); - - // Append item - fileInfo.diagnosticItems += diagnosticItem; - if (diagnosticItem->fixItStatus() == FixitStatus::Scheduled) - fileInfo.hasScheduledFixits = true; - } - } - - static void addFixitOperations(DiagnosticItem *diagnosticItem, - const FixitsRefactoringFile &file, bool apply) - { - if (!diagnosticItem->hasNewFixIts()) - return; - - // Did we already created the fixit operations? - ReplacementOperations currentOps = diagnosticItem->fixitOperations(); - if (!currentOps.isEmpty()) { - for (ReplacementOperation *op : currentOps) - op->apply = apply; - return; - } - - // Collect/construct the fixit operations - ReplacementOperations replacements; - - for (const ExplainingStep &step : diagnosticItem->diagnostic().explainingSteps) { - if (!step.isFixIt) - continue; - - const Debugger::DiagnosticLocation start = step.ranges.first(); - const Debugger::DiagnosticLocation end = step.ranges.last(); - const int startPos = file.position(start.filePath, start.line, start.column); - const int endPos = file.position(start.filePath, end.line, end.column); - - auto op = new ReplacementOperation; - op->pos = startPos; - op->length = endPos - startPos; - op->text = step.message; - op->fileName = start.filePath; - op->apply = apply; - - replacements += op; - } - - diagnosticItem->setFixitOperations(replacements); - } - - void apply(ClangToolsDiagnosticModel *model) - { - for (auto it = m_refactoringFileInfos.begin(); it != m_refactoringFileInfos.end(); ++it) { - RefactoringFileInfo &fileInfo = it.value(); - - QVector itemsScheduledOrSchedulable; - QVector itemsScheduled; - QVector itemsSchedulable; - - // Construct refactoring operations - for (DiagnosticItem *diagnosticItem : fileInfo.diagnosticItems) { - const FixitStatus fixItStatus = diagnosticItem->fixItStatus(); - - const bool isScheduled = fixItStatus == FixitStatus::Scheduled; - const bool isSchedulable = fileInfo.hasScheduledFixits - && fixItStatus == FixitStatus::NotScheduled; - - if (isScheduled || isSchedulable) { - addFixitOperations(diagnosticItem, fileInfo.file, isScheduled); - itemsScheduledOrSchedulable += diagnosticItem; - if (isScheduled) - itemsScheduled += diagnosticItem; - else - itemsSchedulable += diagnosticItem; - } - } - - // Collect replacements - ReplacementOperations ops; - for (DiagnosticItem *item : itemsScheduledOrSchedulable) - ops += item->fixitOperations(); - - if (ops.empty()) - continue; - - // Apply file - QVector itemsApplied; - QVector itemsFailedToApply; - QVector itemsInvalidated; - - fileInfo.file.setReplacements(ops); - model->removeWatchedPath(ops.first()->fileName); - if (fileInfo.file.apply()) { - itemsApplied = itemsScheduled; - } else { - itemsFailedToApply = itemsScheduled; - itemsInvalidated = itemsSchedulable; - } - model->addWatchedPath(ops.first()->fileName); - - // Update DiagnosticItem state - for (DiagnosticItem *diagnosticItem : itemsScheduled) - diagnosticItem->setFixItStatus(FixitStatus::Applied); - for (DiagnosticItem *diagnosticItem : itemsFailedToApply) - diagnosticItem->setFixItStatus(FixitStatus::FailedToApply); - for (DiagnosticItem *diagnosticItem : itemsInvalidated) - diagnosticItem->setFixItStatus(FixitStatus::Invalidated); - } - } - -private: - QMap m_refactoringFileInfos; -}; - -ClangTidyClazyTool::ClangTidyClazyTool() - : ClangTool("Clang-Tidy and Clazy") -{ - setObjectName("ClangTidyClazyTool"); - s_instance = this; - - m_diagnosticFilterModel = new DiagnosticFilterModel(this); - m_diagnosticFilterModel->setSourceModel(m_diagnosticModel); - m_diagnosticFilterModel->setDynamicSortFilter(true); - - m_diagnosticView = new DiagnosticView; - initDiagnosticView(); - m_diagnosticView->setModel(m_diagnosticFilterModel); - m_diagnosticView->setSortingEnabled(true); - m_diagnosticView->sortByColumn(Debugger::DetailedErrorView::DiagnosticColumn, - Qt::AscendingOrder); - m_diagnosticView->setObjectName(QLatin1String("ClangTidyClazyIssuesView")); - m_diagnosticView->setWindowTitle(tr("Clang-Tidy and Clazy Diagnostics")); - - foreach (auto * const model, - QList({m_diagnosticModel, m_diagnosticFilterModel})) { - connect(model, &QAbstractItemModel::rowsInserted, - this, &ClangTidyClazyTool::handleStateUpdate); - connect(model, &QAbstractItemModel::rowsRemoved, - this, &ClangTidyClazyTool::handleStateUpdate); - connect(model, &QAbstractItemModel::modelReset, - this, &ClangTidyClazyTool::handleStateUpdate); - connect(model, &QAbstractItemModel::layoutChanged, // For QSortFilterProxyModel::invalidate() - this, &ClangTidyClazyTool::handleStateUpdate); - } - - // Go to previous diagnostic - auto action = new QAction(this); - action->setDisabled(true); - action->setIcon(Utils::Icons::PREV_TOOLBAR.icon()); - action->setToolTip(tr("Go to previous diagnostic.")); - connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goBack); - m_goBack = action; - - // Go to next diagnostic - action = new QAction(this); - action->setDisabled(true); - action->setIcon(Utils::Icons::NEXT_TOOLBAR.icon()); - action->setToolTip(tr("Go to next diagnostic.")); - connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goNext); - m_goNext = action; - - // Load diagnostics from file - action = new QAction(this); - action->setIcon(Utils::Icons::OPENFILE_TOOLBAR.icon()); - action->setToolTip(tr("Load Diagnostics from YAML Files exported with \"-export-fixes\".")); - connect(action, &QAction::triggered, this, &ClangTidyClazyTool::loadDiagnosticsFromFiles); - m_loadExported = action; - - // Clear data - action = new QAction(this); - action->setDisabled(true); - action->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon()); - action->setToolTip(tr("Clear")); - connect(action, &QAction::triggered, [this](){ - m_clear->setEnabled(false); - m_diagnosticModel->clear(); - Debugger::showPermanentStatusMessage(QString()); - }); - m_clear = action; - - // Expand/Collapse - action = new QAction(this); - action->setDisabled(true); - action->setCheckable(true); - action->setIcon(Utils::Icons::EXPAND_ALL_TOOLBAR.icon()); - action->setToolTip(tr("Expand All")); - connect(action, &QAction::toggled, [this](bool checked){ - if (checked) { - m_expandCollapse->setToolTip(tr("Collapse All")); - m_diagnosticView->expandAll(); - } else { - m_expandCollapse->setToolTip(tr("Expand All")); - m_diagnosticView->collapseAll(); - } - }); - m_expandCollapse = action; - - // Filter line edit - m_filterLineEdit = new Utils::FancyLineEdit(); - m_filterLineEdit->setFiltering(true); - m_filterLineEdit->setPlaceholderText(tr("Filter Diagnostics")); - m_filterLineEdit->setHistoryCompleter("CppTools.ClangTidyClazyIssueFilter", true); - connect(m_filterLineEdit, &Utils::FancyLineEdit::filterChanged, [this](const QString &filter) { - m_diagnosticFilterModel->setFilterRegExp( - QRegExp(filter, Qt::CaseSensitive, QRegExp::WildcardUnix)); - }); - - // Apply fixits button - m_applyFixitsButton = new QToolButton; - m_applyFixitsButton->setText(tr("Apply Fixits")); - m_applyFixitsButton->setEnabled(false); - connect(m_diagnosticModel, - &ClangToolsDiagnosticModel::fixItsToApplyCountChanged, - [this](int c) { - m_applyFixitsButton->setEnabled(c); - static_cast(m_diagnosticView.data())->setSelectedFixItsCount(c); - }); - connect(m_applyFixitsButton, &QToolButton::clicked, [this]() { - QVector diagnosticItems; - m_diagnosticModel->forItemsAtLevel<2>([&](DiagnosticItem *item){ - diagnosticItems += item; - }); - - ApplyFixIts(diagnosticItems).apply(m_diagnosticModel); - }); - - ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); - const QString toolTip = tr("Clang-Tidy and Clazy use a customized Clang executable from the " - "Clang project to search for diagnostics."); - - m_perspective.addWindow(m_diagnosticView, Perspective::SplitVertical, nullptr); - - action = new QAction(tr("Clang-Tidy and Clazy..."), this); - action->setToolTip(toolTip); - menu->addAction(ActionManager::registerAction(action, "ClangTidyClazy.Action"), - Debugger::Constants::G_ANALYZER_TOOLS); - QObject::connect(action, &QAction::triggered, this, [this]() { - startTool(ClangTidyClazyTool::FileSelection::AskUser); - }); - QObject::connect(m_startAction, &QAction::triggered, action, &QAction::triggered); - QObject::connect(m_startAction, &QAction::changed, action, [action, this] { - action->setEnabled(m_startAction->isEnabled()); - }); - - QObject::connect(m_startOnCurrentFileAction, &QAction::triggered, this, [this] { - startTool(ClangTidyClazyTool::FileSelection::CurrentFile); - }); - - m_perspective.addToolBarAction(m_startAction); - m_perspective.addToolBarAction(m_startOnCurrentFileAction); - m_perspective.addToolBarAction(m_stopAction); - m_perspective.addToolBarAction(m_loadExported); - m_perspective.addToolBarAction(m_clear); - m_perspective.addToolBarAction(m_goBack); - m_perspective.addToolBarAction(m_goNext); - m_perspective.addToolBarAction(m_expandCollapse); - m_perspective.addToolBarWidget(m_filterLineEdit); - m_perspective.addToolBarWidget(m_applyFixitsButton); - - updateRunActions(); - - connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions, - this, &ClangTidyClazyTool::updateRunActions); - -} - -ClangTidyClazyTool *ClangTidyClazyTool::instance() -{ - return s_instance; -} - -void ClangTidyClazyTool::selectPerspective() -{ - m_perspective.select(); -} - -static RunSettings runSettings(Project *project) -{ - auto *projectSettings = ClangToolsProjectSettingsManager::getSettings(project); - if (projectSettings->useGlobalSettings()) - return ClangToolsSettings::instance()->runSettings(); - return projectSettings->runSettings(); -} - -void ClangTidyClazyTool::startTool(FileSelection fileSelection) -{ - Project *project = SessionManager::startupProject(); - QTC_ASSERT(project, return); - QTC_ASSERT(project->activeTarget(), return); - - auto runControl = new RunControl(Constants::CLANGTIDYCLAZY_RUN_MODE); - runControl->setDisplayName(tr("Clang-Tidy and Clazy")); - runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); - runControl->setTarget(project->activeTarget()); - - const FileInfos fileInfos = collectFileInfos(project, fileSelection); - if (fileInfos.empty()) - return; - - const bool preventBuild = fileSelection == FileSelection::CurrentFile; - auto clangTool = new ClangToolRunWorker(runControl, - runSettings(project), - fileInfos, - preventBuild); - - m_stopAction->disconnect(); - connect(m_stopAction, &QAction::triggered, runControl, [runControl] { - runControl->appendMessage(tr("Clang-Tidy and Clazy tool stopped by user."), - NormalMessageFormat); - runControl->initiateStop(); - }); - - connect(runControl, &RunControl::stopped, this, [this, clangTool] { - bool success = clangTool->success(); - setToolBusy(false); - m_running = false; - handleStateUpdate(); - updateRunActions(); - emit finished(success); - }); - - m_perspective.select(); - - m_diagnosticModel->clear(); - - setToolBusy(true); - m_diagnosticFilterModel->setProject(project); - m_running = true; - handleStateUpdate(); - updateRunActions(); - - ProjectExplorerPlugin::startRunControl(runControl); -} - -void ClangTidyClazyTool::updateRunActions() -{ - if (m_toolBusy) { - QString tooltipText = tr("Clang-Tidy and Clazy are still running."); - - m_startAction->setEnabled(false); - m_startAction->setToolTip(tooltipText); - - m_startOnCurrentFileAction->setEnabled(false); - m_startOnCurrentFileAction->setToolTip(tooltipText); - - m_stopAction->setEnabled(true); - m_loadExported->setEnabled(false); - m_clear->setEnabled(false); - } else { - QString toolTipStart = m_startAction->text(); - QString toolTipStartOnCurrentFile = m_startOnCurrentFileAction->text(); - - Project *project = SessionManager::startupProject(); - Target *target = project ? project->activeTarget() : nullptr; - const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID; - bool canRun = target && project->projectLanguages().contains(cxx) - && ToolChainKitAspect::toolChain(target->kit(), cxx); - if (!canRun) - toolTipStart = toolTipStartOnCurrentFile = tr("This is not a C/C++ project."); - - m_startAction->setEnabled(canRun); - m_startAction->setToolTip(toolTipStart); - - m_startOnCurrentFileAction->setEnabled(canRun); - m_startOnCurrentFileAction->setToolTip(toolTipStartOnCurrentFile); - - m_stopAction->setEnabled(false); - m_loadExported->setEnabled(true); - m_clear->setEnabled(m_diagnosticModel->diagnostics().count()); - } -} - -void ClangTidyClazyTool::loadDiagnosticsFromFiles() -{ - // Ask user for files - const QStringList filePaths - = QFileDialog::getOpenFileNames(Core::ICore::mainWindow(), - tr("Select YAML Files with Diagnostics"), - QDir::homePath(), - tr("YAML Files (*.yml *.yaml);;All Files (*)")); - if (filePaths.isEmpty()) - return; - - // Load files - Diagnostics diagnostics; - QString errors; - for (const QString &filePath : filePaths) { - QString currentError; - diagnostics << readExportedDiagnostics(Utils::FilePath::fromString(filePath), - {}, - ¤tError); - - if (!currentError.isEmpty()) { - if (!errors.isEmpty()) - errors.append("\n"); - errors.append(currentError); - } - } - - // Show errors - if (!errors.isEmpty()) - AsynchronousMessageBox::critical(tr("Error Loading Diagnostics"), errors); - - // Show imported - m_diagnosticModel->clear(); - onNewDiagnosticsAvailable(diagnostics); -} - -void ClangTidyClazyTool::handleStateUpdate() -{ - QTC_ASSERT(m_goBack, return); - QTC_ASSERT(m_goNext, return); - QTC_ASSERT(m_diagnosticModel, return); - QTC_ASSERT(m_diagnosticFilterModel, return); - - const int issuesFound = m_diagnosticModel->diagnostics().count(); - const int issuesVisible = m_diagnosticFilterModel->rowCount(); - m_goBack->setEnabled(issuesVisible > 1); - m_goNext->setEnabled(issuesVisible > 1); - m_clear->setEnabled(issuesFound > 0); - m_expandCollapse->setEnabled(issuesVisible); - - m_loadExported->setEnabled(!m_running); - - QString message; - if (m_running) { - if (issuesFound) - message = tr("Running - %n diagnostics", nullptr, issuesFound); - else - message = tr("Running - No diagnostics"); - } else { - if (issuesFound) - message = tr("Finished - %n diagnostics", nullptr, issuesFound); - else - message = tr("Finished - No diagnostics"); - } - - Debugger::showPermanentStatusMessage(message); -} - -Diagnostics ClangTidyClazyTool::read(OutputFileFormat outputFileFormat, - const QString &logFilePath, - const QString &mainFilePath, - const QSet &projectFiles, - QString *errorMessage) const -{ - const auto acceptFromFilePath = [projectFiles](const Utils::FilePath &filePath) { - return projectFiles.contains(filePath); - }; - - if (outputFileFormat == OutputFileFormat::Yaml) { - return readExportedDiagnostics(Utils::FilePath::fromString(logFilePath), - acceptFromFilePath, - errorMessage); - } - return readSerializedDiagnostics(Utils::FilePath::fromString(logFilePath), - Utils::FilePath::fromString(mainFilePath), - acceptFromFilePath, - errorMessage); -} - -void ClangTidyClazyTool::onNewDiagnosticsAvailable(const Diagnostics &diagnostics) -{ - ClangTool::onNewDiagnosticsAvailable(diagnostics); - if (!m_diagnosticFilterModel->filterRegExp().pattern().isEmpty()) - m_diagnosticFilterModel->invalidateFilter(); -} - -} // namespace Internal -} // namespace ClangTools - diff --git a/src/plugins/clangtools/clangtidyclazytool.h b/src/plugins/clangtools/clangtidyclazytool.h deleted file mode 100644 index 5ae11ff440..0000000000 --- a/src/plugins/clangtools/clangtidyclazytool.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "clangtool.h" - -#include - -QT_BEGIN_NAMESPACE -class QToolButton; -QT_END_NAMESPACE - -namespace Utils { class FancyLineEdit; } - -namespace ClangTools { -namespace Internal { - -class DiagnosticFilterModel; - -const char ClangTidyClazyPerspectiveId[] = "ClangTidyClazy.Perspective"; - -class ClangTidyClazyTool final : public ClangTool -{ - Q_OBJECT - -public: - ClangTidyClazyTool(); - - static ClangTidyClazyTool *instance(); - - void selectPerspective(); - - void startTool(FileSelection fileSelection) final; - - Diagnostics read(OutputFileFormat outputFileFormat, - const QString &logFilePath, - const QString &mainFilePath, - const QSet &projectFiles, - QString *errorMessage) const final; - - void onNewDiagnosticsAvailable(const Diagnostics &diagnostics) override; - -private: - void handleStateUpdate() final; - - void updateRunActions(); - void loadDiagnosticsFromFiles(); - - DiagnosticFilterModel *m_diagnosticFilterModel = nullptr; - - Utils::FancyLineEdit *m_filterLineEdit = nullptr; - QToolButton *m_applyFixitsButton = nullptr; - - QAction *m_goBack = nullptr; - QAction *m_goNext = nullptr; - QAction *m_loadExported = nullptr; - QAction *m_clear = nullptr; - QAction *m_expandCollapse = nullptr; - - Utils::Perspective m_perspective{ClangTidyClazyPerspectiveId, tr("Clang-Tidy and Clazy")}; -}; - -} // namespace Internal -} // namespace ClangTools diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index a2ffb83c7b..da9e022b03 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -25,10 +25,16 @@ #include "clangtool.h" +#include "clangfixitsrefactoringchanges.h" #include "clangselectablefilesdialog.h" +#include "clangtoolruncontrol.h" #include "clangtoolsconstants.h" #include "clangtoolsdiagnostic.h" #include "clangtoolsdiagnosticmodel.h" +#include "clangtoolsdiagnosticview.h" +#include "clangtoolslogfilereader.h" +#include "clangtoolsprojectsettings.h" +#include "clangtoolssettings.h" #include "clangtoolsutils.h" #include @@ -36,6 +42,7 @@ #include #include #include +#include #include @@ -44,19 +51,22 @@ #include #include #include -#include #include +#include #include +#include #include #include #include +#include #include #include #include using namespace Core; +using namespace CppTools; using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; @@ -64,6 +74,142 @@ using namespace Utils; namespace ClangTools { namespace Internal { +static ClangTool *s_instance; + +class ApplyFixIts +{ +public: + class RefactoringFileInfo + { + public: + bool isValid() const { return file.isValid(); } + + FixitsRefactoringFile file; + QVector diagnosticItems; + bool hasScheduledFixits = false; + }; + + ApplyFixIts(const QVector &diagnosticItems) + { + for (DiagnosticItem *diagnosticItem : diagnosticItems) { + const QString &filePath = diagnosticItem->diagnostic().location.filePath; + QTC_ASSERT(!filePath.isEmpty(), continue); + + // Get or create refactoring file + RefactoringFileInfo &fileInfo = m_refactoringFileInfos[filePath]; + if (!fileInfo.isValid()) + fileInfo.file = FixitsRefactoringFile(filePath); + + // Append item + fileInfo.diagnosticItems += diagnosticItem; + if (diagnosticItem->fixItStatus() == FixitStatus::Scheduled) + fileInfo.hasScheduledFixits = true; + } + } + + static void addFixitOperations(DiagnosticItem *diagnosticItem, + const FixitsRefactoringFile &file, bool apply) + { + if (!diagnosticItem->hasNewFixIts()) + return; + + // Did we already created the fixit operations? + ReplacementOperations currentOps = diagnosticItem->fixitOperations(); + if (!currentOps.isEmpty()) { + for (ReplacementOperation *op : currentOps) + op->apply = apply; + return; + } + + // Collect/construct the fixit operations + ReplacementOperations replacements; + + for (const ExplainingStep &step : diagnosticItem->diagnostic().explainingSteps) { + if (!step.isFixIt) + continue; + + const Debugger::DiagnosticLocation start = step.ranges.first(); + const Debugger::DiagnosticLocation end = step.ranges.last(); + const int startPos = file.position(start.filePath, start.line, start.column); + const int endPos = file.position(start.filePath, end.line, end.column); + + auto op = new ReplacementOperation; + op->pos = startPos; + op->length = endPos - startPos; + op->text = step.message; + op->fileName = start.filePath; + op->apply = apply; + + replacements += op; + } + + diagnosticItem->setFixitOperations(replacements); + } + + void apply(ClangToolsDiagnosticModel *model) + { + for (auto it = m_refactoringFileInfos.begin(); it != m_refactoringFileInfos.end(); ++it) { + RefactoringFileInfo &fileInfo = it.value(); + + QVector itemsScheduledOrSchedulable; + QVector itemsScheduled; + QVector itemsSchedulable; + + // Construct refactoring operations + for (DiagnosticItem *diagnosticItem : fileInfo.diagnosticItems) { + const FixitStatus fixItStatus = diagnosticItem->fixItStatus(); + + const bool isScheduled = fixItStatus == FixitStatus::Scheduled; + const bool isSchedulable = fileInfo.hasScheduledFixits + && fixItStatus == FixitStatus::NotScheduled; + + if (isScheduled || isSchedulable) { + addFixitOperations(diagnosticItem, fileInfo.file, isScheduled); + itemsScheduledOrSchedulable += diagnosticItem; + if (isScheduled) + itemsScheduled += diagnosticItem; + else + itemsSchedulable += diagnosticItem; + } + } + + // Collect replacements + ReplacementOperations ops; + for (DiagnosticItem *item : itemsScheduledOrSchedulable) + ops += item->fixitOperations(); + + if (ops.empty()) + continue; + + // Apply file + QVector itemsApplied; + QVector itemsFailedToApply; + QVector itemsInvalidated; + + fileInfo.file.setReplacements(ops); + model->removeWatchedPath(ops.first()->fileName); + if (fileInfo.file.apply()) { + itemsApplied = itemsScheduled; + } else { + itemsFailedToApply = itemsScheduled; + itemsInvalidated = itemsSchedulable; + } + model->addWatchedPath(ops.first()->fileName); + + // Update DiagnosticItem state + for (DiagnosticItem *diagnosticItem : itemsScheduled) + diagnosticItem->setFixItStatus(FixitStatus::Applied); + for (DiagnosticItem *diagnosticItem : itemsFailedToApply) + diagnosticItem->setFixItStatus(FixitStatus::FailedToApply); + for (DiagnosticItem *diagnosticItem : itemsInvalidated) + diagnosticItem->setFixItStatus(FixitStatus::Invalidated); + } + } + +private: + QMap m_refactoringFileInfos; +}; + static FileInfos sortedFileInfos(const QVector &projectParts) { FileInfos fileInfos; @@ -93,9 +239,24 @@ static FileInfos sortedFileInfos(const QVector &proj return fileInfos; } -ClangTool::ClangTool(const QString &name) - : m_name(name) +static RunSettings runSettings(Project *project) +{ + auto *projectSettings = ClangToolsProjectSettingsManager::getSettings(project); + if (projectSettings->useGlobalSettings()) + return ClangToolsSettings::instance()->runSettings(); + return projectSettings->runSettings(); +} + +ClangTool *ClangTool::instance() +{ + return s_instance; +} + +ClangTool::ClangTool() + : m_name("Clang-Tidy and Clazy") { + setObjectName("ClangTidyClazyTool"); + s_instance = this; m_diagnosticModel = new ClangToolsDiagnosticModel(this); const Utils::Icon RUN_FILE_OVERLAY( @@ -120,6 +281,150 @@ ClangTool::ClangTool(const QString &name) m_startOnCurrentFileAction = action; m_stopAction = Debugger::createStopAction(); + + m_diagnosticFilterModel = new DiagnosticFilterModel(this); + m_diagnosticFilterModel->setSourceModel(m_diagnosticModel); + m_diagnosticFilterModel->setDynamicSortFilter(true); + + m_diagnosticView = new DiagnosticView; + initDiagnosticView(); + m_diagnosticView->setModel(m_diagnosticFilterModel); + m_diagnosticView->setSortingEnabled(true); + m_diagnosticView->sortByColumn(Debugger::DetailedErrorView::DiagnosticColumn, + Qt::AscendingOrder); + m_diagnosticView->setObjectName(QLatin1String("ClangTidyClazyIssuesView")); + m_diagnosticView->setWindowTitle(tr("Clang-Tidy and Clazy Diagnostics")); + + foreach (auto * const model, + QList({m_diagnosticModel, m_diagnosticFilterModel})) { + connect(model, &QAbstractItemModel::rowsInserted, + this, &ClangTool::handleStateUpdate); + connect(model, &QAbstractItemModel::rowsRemoved, + this, &ClangTool::handleStateUpdate); + connect(model, &QAbstractItemModel::modelReset, + this, &ClangTool::handleStateUpdate); + connect(model, &QAbstractItemModel::layoutChanged, // For QSortFilterProxyModel::invalidate() + this, &ClangTool::handleStateUpdate); + } + + // Go to previous diagnostic + action = new QAction(this); + action->setDisabled(true); + action->setIcon(Utils::Icons::PREV_TOOLBAR.icon()); + action->setToolTip(tr("Go to previous diagnostic.")); + connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goBack); + m_goBack = action; + + // Go to next diagnostic + action = new QAction(this); + action->setDisabled(true); + action->setIcon(Utils::Icons::NEXT_TOOLBAR.icon()); + action->setToolTip(tr("Go to next diagnostic.")); + connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goNext); + m_goNext = action; + + // Load diagnostics from file + action = new QAction(this); + action->setIcon(Utils::Icons::OPENFILE_TOOLBAR.icon()); + action->setToolTip(tr("Load Diagnostics from YAML Files exported with \"-export-fixes\".")); + connect(action, &QAction::triggered, this, &ClangTool::loadDiagnosticsFromFiles); + m_loadExported = action; + + // Clear data + action = new QAction(this); + action->setDisabled(true); + action->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon()); + action->setToolTip(tr("Clear")); + connect(action, &QAction::triggered, [this](){ + m_clear->setEnabled(false); + m_diagnosticModel->clear(); + Debugger::showPermanentStatusMessage(QString()); + }); + m_clear = action; + + // Expand/Collapse + action = new QAction(this); + action->setDisabled(true); + action->setCheckable(true); + action->setIcon(Utils::Icons::EXPAND_ALL_TOOLBAR.icon()); + action->setToolTip(tr("Expand All")); + connect(action, &QAction::toggled, [this](bool checked){ + if (checked) { + m_expandCollapse->setToolTip(tr("Collapse All")); + m_diagnosticView->expandAll(); + } else { + m_expandCollapse->setToolTip(tr("Expand All")); + m_diagnosticView->collapseAll(); + } + }); + m_expandCollapse = action; + + // Filter line edit + m_filterLineEdit = new Utils::FancyLineEdit(); + m_filterLineEdit->setFiltering(true); + m_filterLineEdit->setPlaceholderText(tr("Filter Diagnostics")); + m_filterLineEdit->setHistoryCompleter("CppTools.ClangTidyClazyIssueFilter", true); + connect(m_filterLineEdit, &Utils::FancyLineEdit::filterChanged, [this](const QString &filter) { + m_diagnosticFilterModel->setFilterRegExp( + QRegExp(filter, Qt::CaseSensitive, QRegExp::WildcardUnix)); + }); + + // Apply fixits button + m_applyFixitsButton = new QToolButton; + m_applyFixitsButton->setText(tr("Apply Fixits")); + m_applyFixitsButton->setEnabled(false); + connect(m_diagnosticModel, + &ClangToolsDiagnosticModel::fixItsToApplyCountChanged, + [this](int c) { + m_applyFixitsButton->setEnabled(c); + static_cast(m_diagnosticView.data())->setSelectedFixItsCount(c); + }); + connect(m_applyFixitsButton, &QToolButton::clicked, [this]() { + QVector diagnosticItems; + m_diagnosticModel->forItemsAtLevel<2>([&](DiagnosticItem *item){ + diagnosticItems += item; + }); + + ApplyFixIts(diagnosticItems).apply(m_diagnosticModel); + }); + + ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); + const QString toolTip = tr("Clang-Tidy and Clazy use a customized Clang executable from the " + "Clang project to search for diagnostics."); + + m_perspective.addWindow(m_diagnosticView, Perspective::SplitVertical, nullptr); + + action = new QAction(tr("Clang-Tidy and Clazy..."), this); + action->setToolTip(toolTip); + menu->addAction(ActionManager::registerAction(action, "ClangTidyClazy.Action"), + Debugger::Constants::G_ANALYZER_TOOLS); + QObject::connect(action, &QAction::triggered, this, [this]() { + startTool(ClangTool::FileSelection::AskUser); + }); + QObject::connect(m_startAction, &QAction::triggered, action, &QAction::triggered); + QObject::connect(m_startAction, &QAction::changed, action, [action, this] { + action->setEnabled(m_startAction->isEnabled()); + }); + + QObject::connect(m_startOnCurrentFileAction, &QAction::triggered, this, [this] { + startTool(ClangTool::FileSelection::CurrentFile); + }); + + m_perspective.addToolBarAction(m_startAction); + m_perspective.addToolBarAction(m_startOnCurrentFileAction); + m_perspective.addToolBarAction(m_stopAction); + m_perspective.addToolBarAction(m_loadExported); + m_perspective.addToolBarAction(m_clear); + m_perspective.addToolBarAction(m_goBack); + m_perspective.addToolBarAction(m_goNext); + m_perspective.addToolBarAction(m_expandCollapse); + m_perspective.addToolBarWidget(m_filterLineEdit); + m_perspective.addToolBarWidget(m_applyFixitsButton); + + updateRunActions(); + + connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions, + this, &ClangTool::updateRunActions); } ClangTool::~ClangTool() @@ -127,6 +432,78 @@ ClangTool::~ClangTool() delete m_diagnosticView; } +void ClangTool::selectPerspective() +{ + m_perspective.select(); +} + +void ClangTool::startTool(ClangTool::FileSelection fileSelection) +{ + Project *project = SessionManager::startupProject(); + QTC_ASSERT(project, return); + QTC_ASSERT(project->activeTarget(), return); + + auto runControl = new RunControl(Constants::CLANGTIDYCLAZY_RUN_MODE); + runControl->setDisplayName(tr("Clang-Tidy and Clazy")); + runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); + runControl->setTarget(project->activeTarget()); + + const FileInfos fileInfos = collectFileInfos(project, fileSelection); + if (fileInfos.empty()) + return; + + const bool preventBuild = fileSelection == FileSelection::CurrentFile; + auto clangTool = new ClangToolRunWorker(runControl, + runSettings(project), + fileInfos, + preventBuild); + + m_stopAction->disconnect(); + connect(m_stopAction, &QAction::triggered, runControl, [runControl] { + runControl->appendMessage(tr("Clang-Tidy and Clazy tool stopped by user."), + NormalMessageFormat); + runControl->initiateStop(); + }); + + connect(runControl, &RunControl::stopped, this, [this, clangTool] { + bool success = clangTool->success(); + setToolBusy(false); + m_running = false; + handleStateUpdate(); + updateRunActions(); + emit finished(success); + }); + + m_perspective.select(); + + m_diagnosticModel->clear(); + + setToolBusy(true); + m_diagnosticFilterModel->setProject(project); + m_running = true; + handleStateUpdate(); + updateRunActions(); + + ProjectExplorerPlugin::startRunControl(runControl); +} + +Diagnostics ClangTool::read(OutputFileFormat outputFileFormat, const QString &logFilePath, const QString &mainFilePath, const QSet &projectFiles, QString *errorMessage) const +{ + const auto acceptFromFilePath = [projectFiles](const Utils::FilePath &filePath) { + return projectFiles.contains(filePath); + }; + + if (outputFileFormat == OutputFileFormat::Yaml) { + return readExportedDiagnostics(Utils::FilePath::fromString(logFilePath), + acceptFromFilePath, + errorMessage); + } + return readSerializedDiagnostics(Utils::FilePath::fromString(logFilePath), + Utils::FilePath::fromString(mainFilePath), + acceptFromFilePath, + errorMessage); +} + FileInfos ClangTool::collectFileInfos(Project *project, FileSelection fileSelection) const { auto projectInfo = CppTools::CppModelManager::instance()->projectInfo(project); @@ -174,6 +551,42 @@ void ClangTool::initDiagnosticView() m_diagnosticView->setAutoScroll(false); } +void ClangTool::loadDiagnosticsFromFiles() +{ + // Ask user for files + const QStringList filePaths + = QFileDialog::getOpenFileNames(Core::ICore::mainWindow(), + tr("Select YAML Files with Diagnostics"), + QDir::homePath(), + tr("YAML Files (*.yml *.yaml);;All Files (*)")); + if (filePaths.isEmpty()) + return; + + // Load files + Diagnostics diagnostics; + QString errors; + for (const QString &filePath : filePaths) { + QString currentError; + diagnostics << readExportedDiagnostics(Utils::FilePath::fromString(filePath), + {}, + ¤tError); + + if (!currentError.isEmpty()) { + if (!errors.isEmpty()) + errors.append("\n"); + errors.append(currentError); + } + } + + // Show errors + if (!errors.isEmpty()) + AsynchronousMessageBox::critical(tr("Error Loading Diagnostics"), errors); + + // Show imported + m_diagnosticModel->clear(); + onNewDiagnosticsAvailable(diagnostics); +} + QSet ClangTool::diagnostics() const { return Utils::filtered(m_diagnosticModel->diagnostics(), [](const Diagnostic &diagnostic) { @@ -186,6 +599,78 @@ void ClangTool::onNewDiagnosticsAvailable(const Diagnostics &diagnostics) { QTC_ASSERT(m_diagnosticModel, return); m_diagnosticModel->addDiagnostics(diagnostics); + if (!m_diagnosticFilterModel->filterRegExp().pattern().isEmpty()) + m_diagnosticFilterModel->invalidateFilter(); +} + +void ClangTool::updateRunActions() +{ + if (m_toolBusy) { + QString tooltipText = tr("Clang-Tidy and Clazy are still running."); + + m_startAction->setEnabled(false); + m_startAction->setToolTip(tooltipText); + + m_startOnCurrentFileAction->setEnabled(false); + m_startOnCurrentFileAction->setToolTip(tooltipText); + + m_stopAction->setEnabled(true); + m_loadExported->setEnabled(false); + m_clear->setEnabled(false); + } else { + QString toolTipStart = m_startAction->text(); + QString toolTipStartOnCurrentFile = m_startOnCurrentFileAction->text(); + + Project *project = SessionManager::startupProject(); + Target *target = project ? project->activeTarget() : nullptr; + const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID; + bool canRun = target && project->projectLanguages().contains(cxx) + && ToolChainKitAspect::toolChain(target->kit(), cxx); + if (!canRun) + toolTipStart = toolTipStartOnCurrentFile = tr("This is not a C/C++ project."); + + m_startAction->setEnabled(canRun); + m_startAction->setToolTip(toolTipStart); + + m_startOnCurrentFileAction->setEnabled(canRun); + m_startOnCurrentFileAction->setToolTip(toolTipStartOnCurrentFile); + + m_stopAction->setEnabled(false); + m_loadExported->setEnabled(true); + m_clear->setEnabled(m_diagnosticModel->diagnostics().count()); + } +} + +void ClangTool::handleStateUpdate() +{ + QTC_ASSERT(m_goBack, return); + QTC_ASSERT(m_goNext, return); + QTC_ASSERT(m_diagnosticModel, return); + QTC_ASSERT(m_diagnosticFilterModel, return); + + const int issuesFound = m_diagnosticModel->diagnostics().count(); + const int issuesVisible = m_diagnosticFilterModel->rowCount(); + m_goBack->setEnabled(issuesVisible > 1); + m_goNext->setEnabled(issuesVisible > 1); + m_clear->setEnabled(issuesFound > 0); + m_expandCollapse->setEnabled(issuesVisible); + + m_loadExported->setEnabled(!m_running); + + QString message; + if (m_running) { + if (issuesFound) + message = tr("Running - %n diagnostics", nullptr, issuesFound); + else + message = tr("Running - No diagnostics"); + } else { + if (issuesFound) + message = tr("Finished - %n diagnostics", nullptr, issuesFound); + else + message = tr("Finished - No diagnostics"); + } + + Debugger::showPermanentStatusMessage(message); } void ClangTool::setToolBusy(bool busy) diff --git a/src/plugins/clangtools/clangtool.h b/src/plugins/clangtools/clangtool.h index c0b1565260..b61ed1ac44 100644 --- a/src/plugins/clangtools/clangtool.h +++ b/src/plugins/clangtools/clangtool.h @@ -29,38 +29,56 @@ #include "clangtoolsdiagnostic.h" #include "clangtoolslogfilereader.h" +#include + #include #include -namespace Debugger { class DetailedErrorView; } -namespace Utils { class FilePath; } +QT_BEGIN_NAMESPACE +class QToolButton; +QT_END_NAMESPACE + +namespace Debugger { +class DetailedErrorView; +} +namespace Utils { +class FilePath; +class FancyLineEdit; +} // namespace Utils namespace ClangTools { namespace Internal { class ClangToolsDiagnosticModel; class Diagnostic; +class DiagnosticFilterModel; + +const char ClangTidyClazyPerspectiveId[] = "ClangTidyClazy.Perspective"; class ClangTool : public QObject { Q_OBJECT public: - ClangTool(const QString &name); + static ClangTool *instance(); + + ClangTool(); ~ClangTool() override; + void selectPerspective(); + enum class FileSelection { AllFiles, CurrentFile, AskUser, }; - virtual void startTool(FileSelection fileSelection) = 0; + void startTool(FileSelection fileSelection); - virtual Diagnostics read(OutputFileFormat outputFileFormat, + Diagnostics read(OutputFileFormat outputFileFormat, const QString &logFilePath, const QString &mainFilePath, const QSet &projectFiles, - QString *errorMessage) const = 0; + QString *errorMessage) const; FileInfos collectFileInfos(ProjectExplorer::Project *project, FileSelection fileSelection) const; @@ -70,7 +88,7 @@ public: const QString &name() const; - virtual void onNewDiagnosticsAvailable(const Diagnostics &diagnostics); + void onNewDiagnosticsAvailable(const Diagnostics &diagnostics); QAction *startAction() const { return m_startAction; } QAction *startOnCurrentFileAction() const { return m_startOnCurrentFileAction; } @@ -78,11 +96,14 @@ public: signals: void finished(bool success); // For testing. -protected: - virtual void handleStateUpdate() = 0; +private: + void updateRunActions(); + void handleStateUpdate(); void setToolBusy(bool busy); + void initDiagnosticView(); + void loadDiagnosticsFromFiles(); ClangToolsDiagnosticModel *m_diagnosticModel = nullptr; QPointer m_diagnosticView; @@ -93,6 +114,19 @@ protected: bool m_running = false; bool m_toolBusy = false; + DiagnosticFilterModel *m_diagnosticFilterModel = nullptr; + + Utils::FancyLineEdit *m_filterLineEdit = nullptr; + QToolButton *m_applyFixitsButton = nullptr; + + QAction *m_goBack = nullptr; + QAction *m_goNext = nullptr; + QAction *m_loadExported = nullptr; + QAction *m_clear = nullptr; + QAction *m_expandCollapse = nullptr; + + Utils::Perspective m_perspective{ClangTidyClazyPerspectiveId, tr("Clang-Tidy and Clazy")}; + private: const QString m_name; }; diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index 9581fef4eb..2af11aa7ef 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -26,7 +26,6 @@ #include "clangtoolruncontrol.h" #include "clangtidyclazyrunner.h" -#include "clangtidyclazytool.h" #include "clangtool.h" #include "clangtoolslogfilereader.h" #include "clangtoolsprojectsettings.h" @@ -119,7 +118,7 @@ namespace Internal { static ClangTool *tool() { - return ClangTidyClazyTool::instance(); + return ClangTool::instance(); } class ProjectBuilder : public RunWorker diff --git a/src/plugins/clangtools/clangtools.pro b/src/plugins/clangtools/clangtools.pro index 49d4cf83a5..6173e2eec1 100644 --- a/src/plugins/clangtools/clangtools.pro +++ b/src/plugins/clangtools/clangtools.pro @@ -21,7 +21,6 @@ SOURCES += \ clangtoolsdiagnosticview.cpp \ clangtoolsprojectsettingswidget.cpp \ clangtidyclazyrunner.cpp \ - clangtidyclazytool.cpp \ clangtool.cpp \ clangtoolruncontrol.cpp \ clangtoolrunner.cpp \ @@ -42,7 +41,6 @@ HEADERS += \ clangtoolsdiagnosticview.h \ clangtoolsprojectsettingswidget.h \ clangtidyclazyrunner.h \ - clangtidyclazytool.h \ clangtool.h \ clangtoolruncontrol.h \ clangtoolrunner.h \ diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs index e0742256d5..daca2934c1 100644 --- a/src/plugins/clangtools/clangtools.qbs +++ b/src/plugins/clangtools/clangtools.qbs @@ -39,8 +39,6 @@ QtcPlugin { "clangselectablefilesdialog.ui", "clangtidyclazyrunner.cpp", "clangtidyclazyrunner.h", - "clangtidyclazytool.cpp", - "clangtidyclazytool.h", "clangtool.cpp", "clangtool.h", "clangtoolruncontrol.cpp", diff --git a/src/plugins/clangtools/clangtoolsplugin.cpp b/src/plugins/clangtools/clangtoolsplugin.cpp index b432891110..12031dc589 100644 --- a/src/plugins/clangtools/clangtoolsplugin.cpp +++ b/src/plugins/clangtools/clangtoolsplugin.cpp @@ -25,10 +25,10 @@ #include "clangtoolsplugin.h" +#include "clangtool.h" #include "clangtoolsconstants.h" -#include "clangtoolsprojectsettingswidget.h" -#include "clangtidyclazytool.h" #include "clangtoolsprojectsettings.h" +#include "clangtoolsprojectsettingswidget.h" #include "settingswidget.h" #ifdef WITH_TESTS @@ -98,7 +98,7 @@ private: class ClangToolsPluginPrivate { public: - ClangTidyClazyTool clangTidyClazyTool; + ClangTool clangTool; ClangToolsOptionsPage optionsPage; ClangToolsProjectSettingsManager settingsManager; }; @@ -115,9 +115,8 @@ bool ClangToolsPlugin::initialize(const QStringList &arguments, QString *errorSt d = new ClangToolsPluginPrivate; - ActionManager::registerAction(d->clangTidyClazyTool.startAction(), - Constants::RUN_ON_PROJECT); - ActionManager::registerAction(d->clangTidyClazyTool.startOnCurrentFileAction(), + ActionManager::registerAction(d->clangTool.startAction(), Constants::RUN_ON_PROJECT); + ActionManager::registerAction(d->clangTool.startOnCurrentFileAction(), Constants::RUN_ON_CURRENT_FILE); auto panelFactory = new ProjectPanelFactory(); diff --git a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp index 5d711a8aef..2ed19354f2 100644 --- a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp +++ b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp @@ -25,8 +25,8 @@ #include "clangtoolspreconfiguredsessiontests.h" +#include "clangtool.h" #include "clangtoolsdiagnostic.h" -#include "clangtidyclazytool.h" #include "clangtoolsutils.h" #include @@ -121,13 +121,13 @@ void PreconfiguredSessionTests::testPreconfiguredSession() QVERIFY(switchToProjectAndTarget(project, target)); - ClangTidyClazyTool::instance()->startTool(ClangTidyClazyTool::FileSelection::AllFiles); - QSignalSpy waitUntilAnalyzerFinished(ClangTidyClazyTool::instance(), SIGNAL(finished(bool))); + ClangTool::instance()->startTool(ClangTool::FileSelection::AllFiles); + QSignalSpy waitUntilAnalyzerFinished(ClangTool::instance(), SIGNAL(finished(bool))); QVERIFY(waitUntilAnalyzerFinished.wait(30000)); const QList arguments = waitUntilAnalyzerFinished.takeFirst(); const bool analyzerFinishedSuccessfully = arguments.first().toBool(); QVERIFY(analyzerFinishedSuccessfully); - QCOMPARE(ClangTidyClazyTool::instance()->diagnostics().count(), 0); + QCOMPARE(ClangTool::instance()->diagnostics().count(), 0); } static QList validProjects(const QList projectsOfSession) diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp index 765cd34012..c5b7c53a68 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp @@ -26,7 +26,7 @@ #include "clangtoolsprojectsettingswidget.h" #include "ui_clangtoolsprojectsettingswidget.h" -#include "clangtidyclazytool.h" +#include "clangtool.h" #include "clangtoolsconstants.h" #include "clangtoolsprojectsettings.h" @@ -90,7 +90,7 @@ ProjectSettingsWidget::ProjectSettingsWidget(ProjectExplorer::Project *project, }); connect(m_ui->gotoAnalyzerModeLabel, &QLabel::linkActivated, [](const QString &){ - ClangTidyClazyTool::instance()->selectPerspective(); + ClangTool::instance()->selectPerspective(); }); // Run options diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp index 5a034c61b6..79b7bfcc94 100644 --- a/src/plugins/clangtools/clangtoolsunittests.cpp +++ b/src/plugins/clangtools/clangtoolsunittests.cpp @@ -25,7 +25,7 @@ #include "clangtoolsunittests.h" -#include "clangtidyclazytool.h" +#include "clangtool.h" #include "clangtoolsdiagnostic.h" #include "clangtoolssettings.h" #include "clangtoolsutils.h" @@ -109,7 +109,7 @@ void ClangToolsUnitTests::testProject() CppTools::Tests::ProjectOpenerAndCloser projectManager; const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true); QVERIFY(projectInfo.isValid()); - ClangTool *tool = ClangTidyClazyTool::instance(); + ClangTool *tool = ClangTool::instance(); // Change configs QSharedPointer cppToolsSettings = CppTools::codeModelSettings(); @@ -136,7 +136,7 @@ void ClangToolsUnitTests::testProject() clangToolsSettings->setRunSettings(runSettings); clangToolsSettings->writeSettings(); - tool->startTool(ClangTidyClazyTool::FileSelection::AllFiles); + tool->startTool(ClangTool::FileSelection::AllFiles); QSignalSpy waiter(tool, SIGNAL(finished(bool))); QVERIFY(waiter.wait(30000)); -- cgit v1.2.1 From d29d747839b5104dc6831b10f26d292bec53e5b0 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 25 Sep 2019 10:50:44 +0200 Subject: ClangTools: Fix comment Change-Id: Ibf530af9d60cce45957c7a0b9c5b4e9f82407086 Reviewed-by: Cristian Adam Reviewed-by: Nikolai Kosjar --- src/plugins/clangtools/clangtoolslogfilereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/clangtools/clangtoolslogfilereader.cpp b/src/plugins/clangtools/clangtoolslogfilereader.cpp index 59ea741c25..1fe490a6bf 100644 --- a/src/plugins/clangtools/clangtoolslogfilereader.cpp +++ b/src/plugins/clangtools/clangtoolslogfilereader.cpp @@ -417,7 +417,7 @@ Diagnostics readExportedDiagnostics(const Utils::FilePath &logFilePath, try { YAML::Node document = YAML::LoadFile(logFilePath.toString().toStdString()); for (const auto &diagNode : document["Diagnostics"]) { - // clazy omits the "DiagnosticMessage" node. + // Since llvm/clang 9.0 the diagnostic items are wrapped in a "DiagnosticMessage" node. const auto msgNode = diagNode["DiagnosticMessage"]; const YAML::Node &node = msgNode ? msgNode : diagNode; -- cgit v1.2.1