Merge remote-tracking branch 'origin/12.0'
Change-Id: I6309a8ffb18e40a581301bd275390395e250543c
3
dist/changelog/changes-12.0.0.md
vendored
@@ -212,7 +212,9 @@ Projects
|
||||
|
||||
* Added auto-detection of PySide from the installer
|
||||
([PYSIDE-2153](https://bugreports.qt.io/browse/PYSIDE-2153))
|
||||
([Documentation](https://doc-snapshots.qt.io/qtcreator-12.0/creator-python-development.html#set-up-pyside6))
|
||||
* Added the option to forward the display for remote Linux
|
||||
([Documentation](https://doc-snapshots.qt.io/qtcreator-12.0/creator-run-settings.html#specifying-run-settings-for-linux-based-devices))
|
||||
* Fixed PySide wheels installation on macOS
|
||||
|
||||
### vcpkg
|
||||
@@ -224,6 +226,7 @@ Projects
|
||||
### Qt Safe Renderer
|
||||
|
||||
* Added a wizard for Qt Safe Renderer 2.1 and later
|
||||
([Documentation](https://doc.qt.io/QtSafeRenderer/qtsr-safety-project.html#using-qt-safe-renderer-project-template-in-qt-creator))
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
BIN
doc/qtcreator/images/qtcreator-build-settings-default.webp
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
doc/qtcreator/images/qtcreator-locator-filter-t.webp
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
doc/qtcreator/images/qtcreator-projectpane.webp
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
BIN
doc/qtcreator/images/qtcreator-run-settings-remote-linux.webp
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
@@ -94,7 +94,7 @@
|
||||
You can enable or disable QML debugging globally in \preferences >
|
||||
\uicontrol {Build & Run} > \uicontrol {Default Build Properties}.
|
||||
|
||||
\image qtcreator-build-settings-default.png "Default Build Properties tab in Build & Run Preferences"
|
||||
\image qtcreator-build-settings-default.webp "Default Build Properties tab in Build & Run Preferences"
|
||||
|
||||
The value of the \uicontrol {QML debugging} field determines what happens
|
||||
when creating new build configurations. The values \uicontrol Enable
|
||||
|
||||
@@ -712,6 +712,8 @@
|
||||
\uicontrol {Disable messages for non Qt Quick UI}. You cannot
|
||||
enable messages just for non-Qt Quick UI files.
|
||||
|
||||
\sa {QML Language Server}
|
||||
|
||||
\section1 Resetting the Code Model
|
||||
|
||||
If you change the build and run kit when you have QML files open in the code
|
||||
|
||||
@@ -143,15 +143,22 @@
|
||||
|
||||
\section2 QML Language Server
|
||||
|
||||
Since Qt 6.4, the \c qmlls language server offers code completion and
|
||||
issues warnings for QML. To enable QML language server support, select
|
||||
\preferences > \uicontrol {Qt Quick} >
|
||||
\uicontrol {QML/JS Editing} > \uicontrol {Use qmlls (EXPERIMENTAL!)}.
|
||||
Since Qt 6.4, the QML language server offers code completion and
|
||||
issues warnings for QML. To use it, select \preferences >
|
||||
\uicontrol {Qt Quick} > \uicontrol {QML/JS Editing} >
|
||||
\uicontrol {Enable QML Language Server}.
|
||||
|
||||
To use advanced features, such as renaming and finding usages, select the
|
||||
\uicontrol {Use QML Language Server advanced features} check box.
|
||||
|
||||
To use the latest version of the language server installed on your
|
||||
system, select the \uicontrol {Always use latest qmlls} check box.
|
||||
system, select the
|
||||
\uicontrol {Use QML Language Server from latest Qt version} check box.
|
||||
|
||||
\image qtcreator-qml-js-editing.webp {QML/JS Editing preferences}
|
||||
|
||||
\sa {Enabling and Disabling Messages}
|
||||
|
||||
\section1 Supported Locator Filters
|
||||
|
||||
The locator enables you to browse not only files, but any items defined by
|
||||
|
||||
@@ -26,8 +26,19 @@
|
||||
\li \uicontrol {\QC} > \uicontrol Preferences
|
||||
\endtable
|
||||
|
||||
\section1 Filter preferences
|
||||
|
||||
To find a particular preference, use the filter located at the top left of
|
||||
the \uicontrol Preferences dialog.
|
||||
|
||||
\image qtcreator-preferences.webp {Filtering preferences}
|
||||
|
||||
\section1 Go to tabs in Preferences
|
||||
|
||||
To go to a tab in the \uicontrol Preferences dialog from anywhere in \QC,
|
||||
use the \c t \l{Searching with the Locator}{locator} filter. For example,
|
||||
to open the \uicontrol Interface tab, enter \c {t preferences interface}
|
||||
in the locator.
|
||||
|
||||
\image qtcreator-locator-filter-t.webp {Using the locator to open a tab in Preferences}
|
||||
*/
|
||||
|
||||
@@ -21,10 +21,13 @@
|
||||
command in the \uicontrol {Alternate executable on device} field and select the
|
||||
\uicontrol {Use this command instead} check box.
|
||||
|
||||
\image qtcreator-run-settings-linux.png "Run settings for Linux-based devices"
|
||||
\image qtcreator-run-settings-remote-linux.webp {Run settings for Linux-based devices}
|
||||
|
||||
You can specify arguments to pass to your application in the
|
||||
\uicontrol {Command line arguments} field.
|
||||
|
||||
Select the \uicontrol {Forward to local display} check box to show a remotely
|
||||
running X11 client on a local display.
|
||||
|
||||
//! [run settings linux]
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
@@ -8,15 +8,22 @@
|
||||
|
||||
\title qmake Build Configuration
|
||||
|
||||
\image qtcreator-projectpane.png "qmake build settings"
|
||||
Specify build settings for the selected \l{glossary-buildandrun-kit}
|
||||
{build and run kit} in \uicontrol Projects > \uicontrol {Build & Run}
|
||||
> \uicontrol Build > \uicontrol {Build Settings}.
|
||||
|
||||
\image qtcreator-projectpane.webp {qmake build settings}
|
||||
|
||||
By default, \QC builds qmake projects in a separate directory from the
|
||||
source directory, as \l{glossary-shadow-build} {shadow builds}. This
|
||||
keeps the files generated for each \l{glossary-buildandrun-kit}
|
||||
{build and run kit} separate. If you only build and run with a single
|
||||
\l{glossary-buildandrun-kit}{kit}, you can deselect the
|
||||
\uicontrol {Shadow build} checkbox. Select the build directory in the
|
||||
\uicontrol {Build Directory} field.
|
||||
keeps the files generated for each kit separate. If you only build and
|
||||
run with a single kit, you can deselect the \uicontrol {Shadow build}
|
||||
checkbox.
|
||||
|
||||
Select the build directory in the \uicontrol {Build Directory} field. You
|
||||
can use the \l{Using Qt Creator Variables}{variables} that are listed when
|
||||
you select the \inlineimage icons/replace.png (\uicontrol {Variables})
|
||||
button.
|
||||
|
||||
To make in-source builds the default option for all projects, select
|
||||
\preferences > \uicontrol {Build & Run} >
|
||||
@@ -54,7 +61,14 @@
|
||||
To set the default build properties, select \preferences >
|
||||
\uicontrol {Build & Run} > \uicontrol {Default Build Properties}.
|
||||
|
||||
\image qtcreator-build-settings-default.png "Default Build Properties tab in Build & Run Preferences"
|
||||
\image qtcreator-build-settings-default.webp {Default Build Properties tab in Build & Run Preferences}
|
||||
|
||||
In the \uicontrol {Default build directory} field, you can use the variables
|
||||
that are listed when you select \inlineimage icons/replace.png, as well as
|
||||
variables that are available for a particular kit. Those you can see when
|
||||
you select the button in the \uicontrol Projects > \uicontrol {Build & Run} >
|
||||
\uicontrol Build > \uicontrol {Build Settings} > \uicontrol {Build Directory}
|
||||
field for a kit.
|
||||
|
||||
\section1 Compiling QML
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
|
||||
\section1 Managing Build Configurations
|
||||
|
||||
Specify build settings in \uicontrol Projects > \uicontrol {Build & Run}
|
||||
Specify build settings for the selected \l{glossary-buildandrun-kit}
|
||||
{build and run kit} in \uicontrol Projects > \uicontrol {Build & Run}
|
||||
> \uicontrol Build > \uicontrol {Build Settings}.
|
||||
|
||||
\image qtcreator-build-configurations.png "Build Settings"
|
||||
|
||||
@@ -428,12 +428,14 @@ void FancyLineEdit::setFiltering(bool on)
|
||||
d->m_isFiltering = on;
|
||||
if (on) {
|
||||
d->m_lastFilterText = text();
|
||||
// KDE has custom icons for this. Notice that icon namings are counter intuitive.
|
||||
// If these icons are not available we use the freedesktop standard name before
|
||||
// falling back to a bundled resource.
|
||||
static const QIcon rtl = Icon::fromTheme("edit-clear-locationbar-rtl");
|
||||
static const QIcon ltr = Icon::fromTheme("edit-clear-locationbar-ltr");
|
||||
setButtonIcon(Right, layoutDirection() == Qt::LeftToRight ? ltr : rtl);
|
||||
// KDE has custom icons for this. The "ltr" and "rtl" suffixes describe the direction
|
||||
// into which the arrows are pointing. They do not describe which writing direction they
|
||||
// are intended to be used for.
|
||||
const QLatin1String pointingWest("edit-clear-locationbar-rtl");
|
||||
const QLatin1String pointingEast("edit-clear-locationbar-ltr");
|
||||
const QIcon icon = Icon::fromTheme(layoutDirection() == Qt::LeftToRight ? pointingWest
|
||||
: pointingEast);
|
||||
setButtonIcon(Right, icon);
|
||||
setButtonVisible(Right, true);
|
||||
setPlaceholderText(Tr::tr("Filter"));
|
||||
setButtonToolTip(Right, Tr::tr("Clear text"));
|
||||
|
||||
@@ -628,11 +628,6 @@ expected_str<qint64> FilePath::writeFileContents(const QByteArray &data, qint64
|
||||
return fileAccess()->writeFileContents(*this, data, offset);
|
||||
}
|
||||
|
||||
FilePathInfo FilePath::filePathInfo() const
|
||||
{
|
||||
return fileAccess()->filePathInfo(*this);
|
||||
}
|
||||
|
||||
FileStreamHandle FilePath::asyncCopy(const FilePath &target, QObject *context,
|
||||
const CopyContinuation &cont) const
|
||||
{
|
||||
@@ -1188,6 +1183,14 @@ bool FilePath::hasFileAccess() const
|
||||
return access.has_value();
|
||||
}
|
||||
|
||||
FilePathInfo FilePath::filePathInfo() const
|
||||
{
|
||||
const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
|
||||
if (!access)
|
||||
return {};
|
||||
return (*access)->filePathInfo(*this);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a bool indicating whether a file or directory with this FilePath exists.
|
||||
*/
|
||||
|
||||
@@ -268,13 +268,14 @@ QIcon Icon::fromTheme(const QString &name)
|
||||
cache.insert(name, !icon.isNull() ? icon : Icons::ZOOMOUT_TOOLBAR.icon());
|
||||
} else if (name == "zoom-original") {
|
||||
cache.insert(name, !icon.isNull() ? icon : Icons::EYE_OPEN_TOOLBAR.icon());
|
||||
} else if (name == "edit-clear") {
|
||||
cache.insert(name, !icon.isNull() ? icon : Icons::EDIT_CLEAR.icon());
|
||||
} else if (name == "edit-clear-locationbar-rtl") {
|
||||
// KDE has custom icons for this. Notice that icon namings are counter intuitive.
|
||||
// If these icons are not available we use the freedesktop standard name before
|
||||
// falling back to a bundled resource.
|
||||
cache.insert(name, !icon.isNull() ? icon : Icons::EDIT_CLEAR.icon());
|
||||
// KDE has custom icons for this. If these icons are not available we use the freedesktop
|
||||
// standard name "edit-clear" before falling back to a bundled resource.
|
||||
cache.insert(name, !icon.isNull() ? icon : fromTheme("edit-clear"));
|
||||
} else if (name == "edit-clear-locationbar-ltr") {
|
||||
cache.insert(name, !icon.isNull() ? icon : Icons::EDIT_CLEAR.icon());
|
||||
cache.insert(name, !icon.isNull() ? icon : fromTheme("edit-clear"));
|
||||
} else {
|
||||
cache.insert(name, icon);
|
||||
}
|
||||
|
||||
@@ -158,12 +158,15 @@ bool AxivionPlugin::handleCertificateIssue()
|
||||
|
||||
AxivionPluginPrivate::AxivionPluginPrivate()
|
||||
{
|
||||
#if QT_CONFIG(ssl)
|
||||
connect(&m_networkAccessManager, &QNetworkAccessManager::sslErrors,
|
||||
this, &AxivionPluginPrivate::handleSslErrors);
|
||||
#endif // ssl
|
||||
}
|
||||
|
||||
void AxivionPluginPrivate::handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||
{
|
||||
#if QT_CONFIG(ssl)
|
||||
const QList<QSslError::SslError> accepted{
|
||||
QSslError::CertificateNotYetValid, QSslError::CertificateExpired,
|
||||
QSslError::InvalidCaCertificate, QSslError::CertificateUntrusted,
|
||||
@@ -174,6 +177,10 @@ void AxivionPluginPrivate::handleSslErrors(QNetworkReply *reply, const QList<QSs
|
||||
if (!settings().server.validateCert || AxivionPlugin::handleCertificateIssue())
|
||||
reply->ignoreSslErrors(errors);
|
||||
}
|
||||
#else // ssl
|
||||
Q_UNUSED(reply)
|
||||
Q_UNUSED(errors)
|
||||
#endif // ssl
|
||||
}
|
||||
|
||||
void AxivionPluginPrivate::onStartupProjectChanged()
|
||||
|
||||
@@ -456,9 +456,10 @@ void ClangdFindReferences::Private::addSearchResultsForFile(const FilePath &file
|
||||
item.setContainingFunctionName(getContainingFunction(astPath, range).detail());
|
||||
|
||||
if (search->supportsReplace()) {
|
||||
const bool fileInSession = ProjectManager::projectForFile(file);
|
||||
item.setSelectForReplacement(fileInSession);
|
||||
if (fileInSession && file.baseName().compare(replacementData->oldSymbolName,
|
||||
const Node * const node = ProjectTree::nodeForFile(file);
|
||||
item.setSelectForReplacement(!ProjectManager::hasProjects()
|
||||
|| (node && !node->isGenerated()));
|
||||
if (node && file.baseName().compare(replacementData->oldSymbolName,
|
||||
Qt::CaseInsensitive) == 0) {
|
||||
replacementData->fileRenameCandidates << file;
|
||||
}
|
||||
|
||||
@@ -874,8 +874,10 @@ QWidget *ICore::dialogParent()
|
||||
QWidget *active = QApplication::activeModalWidget();
|
||||
if (!active)
|
||||
active = QApplication::activeWindow();
|
||||
if (!active || (active && active->windowFlags().testAnyFlags(Qt::SplashScreen | Qt::Popup)))
|
||||
if (!active || active->windowFlags().testFlag(Qt::SplashScreen)
|
||||
|| active->windowFlags().testFlag(Qt::Popup)) {
|
||||
active = d->m_mainwindow;
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QPointer>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include "coreplugintr.h"
|
||||
#include "icore.h"
|
||||
|
||||
#include <utils/async.h>
|
||||
#include <utils/basetreeview.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/listmodel.h>
|
||||
@@ -31,7 +33,6 @@
|
||||
#include <QSplitter>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace Core::Internal {
|
||||
|
||||
static QColor colorForCategory(const QString &category);
|
||||
@@ -209,6 +210,13 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isEnabledOriginally(QtMsgType msgType) const
|
||||
{
|
||||
if (m_originalSettings)
|
||||
return (*m_originalSettings)[msgType];
|
||||
return isEnabled(msgType);
|
||||
}
|
||||
|
||||
void setEnabled(QtMsgType msgType, bool isEnabled)
|
||||
{
|
||||
QTC_ASSERT(!m_useOriginal, return);
|
||||
@@ -308,6 +316,8 @@ public:
|
||||
~LoggingCategoryModel() override;
|
||||
enum Column { Color, Name, Debug, Warning, Critical, Fatal, Info };
|
||||
|
||||
enum Role { OriginalStateRole = Qt::UserRole + 1 };
|
||||
|
||||
void append(const LoggingCategoryEntry &entry);
|
||||
int columnCount(const QModelIndex &) const final { return 7; }
|
||||
int rowCount(const QModelIndex & = QModelIndex()) const final { return m_categories.size(); }
|
||||
@@ -363,12 +373,18 @@ QVariant LoggingCategoryModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
static const QColor defaultColor = Utils::creatorTheme()->palette().text().color();
|
||||
return defaultColor;
|
||||
} else if (role == Qt::CheckStateRole && index.column() >= Column::Debug
|
||||
&& index.column() <= Column::Info) {
|
||||
const LoggingCategoryEntry &entry = m_categories.at(index.row());
|
||||
return entry.isEnabled(static_cast<QtMsgType>(index.column() - Column::Debug))
|
||||
? Qt::Checked
|
||||
: Qt::Unchecked;
|
||||
} else if (index.column() >= Column::Debug && index.column() <= Column::Info) {
|
||||
if (role == Qt::CheckStateRole) {
|
||||
const LoggingCategoryEntry &entry = m_categories.at(index.row());
|
||||
const bool isEnabled = entry.isEnabled(
|
||||
static_cast<QtMsgType>(index.column() - Column::Debug));
|
||||
return isEnabled ? Qt::Checked : Qt::Unchecked;
|
||||
} else if (role == OriginalStateRole) {
|
||||
const LoggingCategoryEntry &entry = m_categories.at(index.row());
|
||||
return entry.isEnabledOriginally(static_cast<QtMsgType>(index.column() - Column::Debug))
|
||||
? Qt::Checked
|
||||
: Qt::Unchecked;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -609,9 +625,8 @@ LoggingViewManagerWidget::LoggingViewManagerWidget(QWidget *parent)
|
||||
|
||||
auto qtInternal = new QToolButton;
|
||||
qtInternal->setIcon(Core::Icons::QTLOGO.icon());
|
||||
qtInternal->setToolTip(Tr::tr("Toggle Qt Internal Logging"));
|
||||
qtInternal->setCheckable(true);
|
||||
qtInternal->setChecked(false);
|
||||
qtInternal->setToolTip(Tr::tr("Filter Qt Internal Log Categories"));
|
||||
qtInternal->setCheckable(false);
|
||||
|
||||
auto autoScroll = new QToolButton;
|
||||
autoScroll->setIcon(Utils::Icons::ARROW_DOWN.icon());
|
||||
@@ -663,26 +678,52 @@ LoggingViewManagerWidget::LoggingViewManagerWidget(QWidget *parent)
|
||||
for (int i = LoggingCategoryModel::Column::Color; i < LoggingCategoryModel::Column::Info; i++)
|
||||
m_categoryView->resizeColumnToContents(i);
|
||||
|
||||
auto filterEdit = new Utils::FancyLineEdit;
|
||||
filterEdit->setHistoryCompleter("LogFilterCompletionHistory");
|
||||
filterEdit->setFiltering(true);
|
||||
filterEdit->setPlaceholderText(Tr::tr("Filter categories by regular expression"));
|
||||
filterEdit->setText("^(?!qt\\.).+");
|
||||
filterEdit->setValidationFunction(
|
||||
[](const QString &input) {
|
||||
return Utils::asyncRun([input]() -> Utils::expected_str<QString> {
|
||||
QRegularExpression re(input);
|
||||
if (re.isValid())
|
||||
return input;
|
||||
|
||||
return Utils::make_unexpected(
|
||||
Tr::tr("Invalid regular expression: %1").arg(re.errorString()));
|
||||
});
|
||||
});
|
||||
|
||||
QSplitter *splitter{nullptr};
|
||||
|
||||
using namespace Layouting;
|
||||
// clang-format off
|
||||
Column {
|
||||
Row {
|
||||
spacing(0),
|
||||
save,
|
||||
clean,
|
||||
m_stopLog,
|
||||
qtInternal,
|
||||
autoScroll,
|
||||
m_timestamps,
|
||||
m_messageTypes,
|
||||
st,
|
||||
},
|
||||
Splitter {
|
||||
bindTo(&splitter),
|
||||
m_logView,
|
||||
m_categoryView,
|
||||
Column {
|
||||
noMargin(),
|
||||
Row {
|
||||
spacing(0),
|
||||
save,
|
||||
clean,
|
||||
m_stopLog,
|
||||
autoScroll,
|
||||
m_timestamps,
|
||||
m_messageTypes,
|
||||
st,
|
||||
},
|
||||
m_logView
|
||||
},
|
||||
Column {
|
||||
noMargin(),
|
||||
Row {
|
||||
qtInternal,
|
||||
filterEdit,
|
||||
},
|
||||
m_categoryView,
|
||||
}
|
||||
}
|
||||
}.attachTo(this);
|
||||
// clang-format on
|
||||
@@ -746,14 +787,19 @@ LoggingViewManagerWidget::LoggingViewManagerWidget(QWidget *parent)
|
||||
|
||||
m_sortFilterModel->setFilterRegularExpression("^(?!qt\\.).+");
|
||||
|
||||
connect(qtInternal, &QToolButton::toggled, m_sortFilterModel, [this](bool checked) {
|
||||
if (checked) {
|
||||
m_sortFilterModel->setFilterRegularExpression("");
|
||||
} else {
|
||||
m_sortFilterModel->setFilterRegularExpression("^(?!qt\\.).+");
|
||||
}
|
||||
connect(qtInternal, &QToolButton::clicked, filterEdit, [filterEdit] {
|
||||
filterEdit->setText("^(?!qt\\.).+");
|
||||
});
|
||||
|
||||
connect(filterEdit,
|
||||
&Utils::FancyLineEdit::textChanged,
|
||||
m_sortFilterModel,
|
||||
[this](const QString &f) {
|
||||
QRegularExpression re(f);
|
||||
if (re.isValid())
|
||||
m_sortFilterModel->setFilterRegularExpression(f);
|
||||
});
|
||||
|
||||
connect(m_timestamps, &QToolButton::toggled, this, [this](bool checked) {
|
||||
m_logView->setColumnHidden(0, !checked);
|
||||
});
|
||||
@@ -802,40 +848,70 @@ void LoggingViewManagerWidget::showLogCategoryContextMenu(const QPoint &pos) con
|
||||
|
||||
QMenu m;
|
||||
auto uncheckAll = new QAction(Tr::tr("Uncheck All"), &m);
|
||||
auto resetAll = new QAction(Tr::tr("Reset All"), &m);
|
||||
|
||||
int column = 0;
|
||||
auto isTypeColumn = [](int column) {
|
||||
return column >= LoggingCategoryModel::Column::Debug
|
||||
&& column <= LoggingCategoryModel::Column::Info;
|
||||
};
|
||||
|
||||
if (idx.isValid()) {
|
||||
column = idx.column();
|
||||
if (column >= LoggingCategoryModel::Column::Debug
|
||||
&& column <= LoggingCategoryModel::Column::Info) {
|
||||
bool isChecked = idx.data(Qt::CheckStateRole).toBool();
|
||||
|
||||
QString text = isChecked ? Tr::tr("Uncheck All %1") : Tr::tr("Check All %1");
|
||||
|
||||
uncheckAll->setText(text.arg(messageTypeToString(
|
||||
static_cast<QtMsgType>(column - LoggingCategoryModel::Column::Debug))));
|
||||
|
||||
connect(uncheckAll, &QAction::triggered, m_sortFilterModel, [this, idx, isChecked] {
|
||||
for (int i = 0; i < m_sortFilterModel->rowCount(); ++i) {
|
||||
m_sortFilterModel->setData(m_sortFilterModel->index(i, idx.column()),
|
||||
!isChecked,
|
||||
Qt::CheckStateRole);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
connect(uncheckAll, &QAction::triggered, m_sortFilterModel, [this] {
|
||||
for (int i = 0; i < m_sortFilterModel->rowCount(); ++i) {
|
||||
for (int c = LoggingCategoryModel::Column::Debug;
|
||||
c <= LoggingCategoryModel::Column::Info;
|
||||
++c) {
|
||||
m_sortFilterModel->setData(m_sortFilterModel->index(i, c),
|
||||
false,
|
||||
Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
});
|
||||
auto setChecked = [this](std::initializer_list<LoggingCategoryModel::Column> columns,
|
||||
Qt::CheckState checked) {
|
||||
for (int row = 0, count = m_sortFilterModel->rowCount(); row < count; ++row) {
|
||||
for (int column : columns) {
|
||||
m_sortFilterModel->setData(m_sortFilterModel->index(row, column),
|
||||
checked,
|
||||
Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
};
|
||||
auto resetToOriginal = [this](std::initializer_list<LoggingCategoryModel::Column> columns) {
|
||||
for (int row = 0, count = m_sortFilterModel->rowCount(); row < count; ++row) {
|
||||
for (int column : columns) {
|
||||
const QModelIndex id = m_sortFilterModel->index(row, column);
|
||||
m_sortFilterModel->setData(id,
|
||||
id.data(LoggingCategoryModel::OriginalStateRole),
|
||||
Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (idx.isValid() && isTypeColumn(idx.column())) {
|
||||
const LoggingCategoryModel::Column column = static_cast<LoggingCategoryModel::Column>(
|
||||
idx.column());
|
||||
bool isChecked = idx.data(Qt::CheckStateRole).toInt() == Qt::Checked;
|
||||
const QString uncheckText = isChecked ? Tr::tr("Uncheck All %1") : Tr::tr("Check All %1");
|
||||
|
||||
uncheckAll->setText(uncheckText.arg(messageTypeToString(
|
||||
static_cast<QtMsgType>(column - LoggingCategoryModel::Column::Debug))));
|
||||
resetAll->setText(Tr::tr("Reset All %1")
|
||||
.arg(messageTypeToString(static_cast<QtMsgType>(
|
||||
column - LoggingCategoryModel::Column::Debug))));
|
||||
|
||||
Qt::CheckState newState = isChecked ? Qt::Unchecked : Qt::Checked;
|
||||
|
||||
connect(uncheckAll,
|
||||
&QAction::triggered,
|
||||
m_sortFilterModel,
|
||||
[setChecked, column, newState]() { setChecked({column}, newState); });
|
||||
|
||||
connect(resetAll, &QAction::triggered, m_sortFilterModel, [resetToOriginal, column]() {
|
||||
resetToOriginal({column});
|
||||
});
|
||||
|
||||
} else {
|
||||
// No need to add Fatal here, as it is read-only
|
||||
static auto allColumns = {LoggingCategoryModel::Column::Debug,
|
||||
LoggingCategoryModel::Column::Warning,
|
||||
LoggingCategoryModel::Column::Critical,
|
||||
LoggingCategoryModel::Column::Info};
|
||||
|
||||
connect(uncheckAll, &QAction::triggered, m_sortFilterModel, [setChecked]() {
|
||||
setChecked(allColumns, Qt::Unchecked);
|
||||
});
|
||||
connect(resetAll, &QAction::triggered, m_sortFilterModel, [resetToOriginal]() {
|
||||
resetToOriginal(allColumns);
|
||||
});
|
||||
}
|
||||
|
||||
// minimal load/save - plugins could later provide presets on their own?
|
||||
@@ -844,6 +920,7 @@ void LoggingViewManagerWidget::showLogCategoryContextMenu(const QPoint &pos) con
|
||||
auto loadPreset = new QAction(Tr::tr("Update from Preset..."), &m);
|
||||
m.addAction(loadPreset);
|
||||
m.addAction(uncheckAll);
|
||||
m.addAction(resetAll);
|
||||
connect(savePreset,
|
||||
&QAction::triggered,
|
||||
m_categoryModel,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "coreplugintr.h"
|
||||
#include "icontext.h"
|
||||
#include "icore.h"
|
||||
#include "imode.h"
|
||||
#include "inavigationwidgetfactory.h"
|
||||
#include "modemanager.h"
|
||||
#include "navigationsubwidget.h"
|
||||
@@ -297,7 +296,9 @@ static QIcon closeIconForSide(Side side, int itemCount)
|
||||
: Utils::Icons::CLOSE_SPLIT_RIGHT.icon();
|
||||
}
|
||||
|
||||
Internal::NavigationSubWidget *NavigationWidget::insertSubItem(int position, int factoryIndex)
|
||||
Internal::NavigationSubWidget *NavigationWidget::insertSubItem(int position,
|
||||
int factoryIndex,
|
||||
bool updateActivationsMap)
|
||||
{
|
||||
for (int pos = position + 1; pos < d->m_subWidgets.size(); ++pos) {
|
||||
Internal::NavigationSubWidget *nsw = d->m_subWidgets.at(pos);
|
||||
@@ -323,7 +324,8 @@ Internal::NavigationSubWidget *NavigationWidget::insertSubItem(int position, int
|
||||
|
||||
d->m_subWidgets.insert(position, nsw);
|
||||
d->m_subWidgets.at(0)->setCloseIcon(closeIconForSide(d->m_side, d->m_subWidgets.size()));
|
||||
NavigationWidgetPrivate::updateActivationsMap(nsw->factory()->id(), {d->m_side, position});
|
||||
if (updateActivationsMap)
|
||||
NavigationWidgetPrivate::updateActivationsMap(nsw->factory()->id(), {d->m_side, position});
|
||||
return nsw;
|
||||
}
|
||||
|
||||
@@ -400,8 +402,11 @@ void NavigationWidget::saveSettings(QtcSettings *settings)
|
||||
const auto keys = NavigationWidgetPrivate::s_activationsMap.keys();
|
||||
for (const auto &factoryId : keys) {
|
||||
const auto &info = NavigationWidgetPrivate::s_activationsMap[factoryId];
|
||||
const Utils::Key key = settingsKey(activationKey + factoryId.name());
|
||||
if (info.side == d->m_side)
|
||||
settings->setValue(settingsKey(activationKey + factoryId.name()), info.position);
|
||||
settings->setValue(key, info.position);
|
||||
else
|
||||
settings->remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +439,7 @@ void NavigationWidget::restoreSettings(QtcSettings *settings)
|
||||
int index = factoryIndex(Id::fromString(id));
|
||||
if (index >= 0) {
|
||||
// Only add if the id was actually found!
|
||||
insertSubItem(position, index);
|
||||
insertSubItem(position, index, /*updateActivationsMap=*/false);
|
||||
++position;
|
||||
} else {
|
||||
restoreSplitterState = false;
|
||||
@@ -443,7 +448,9 @@ void NavigationWidget::restoreSettings(QtcSettings *settings)
|
||||
|
||||
if (d->m_subWidgets.isEmpty())
|
||||
// Make sure we have at least the projects widget or outline widget
|
||||
insertSubItem(0, qMax(0, factoryIndex(Id::fromString(defaultFirstView(d->m_side)))));
|
||||
insertSubItem(0,
|
||||
qMax(0, factoryIndex(Id::fromString(defaultFirstView(d->m_side)))),
|
||||
/*updateActivationsMap=*/false);
|
||||
|
||||
setShown(settings->value(settingsKey("Visible"), defaultVisible(d->m_side)).toBool());
|
||||
|
||||
|
||||
@@ -97,7 +97,9 @@ protected:
|
||||
private:
|
||||
void closeSubWidget(Internal::NavigationSubWidget *subWidget);
|
||||
void updateToggleText();
|
||||
Internal::NavigationSubWidget *insertSubItem(int position, int factoryIndex);
|
||||
Internal::NavigationSubWidget *insertSubItem(int position,
|
||||
int factoryIndex,
|
||||
bool updateActivationsMap = true);
|
||||
int factoryIndex(Utils::Id id);
|
||||
Utils::Key settingsKey(const Utils::Key &key) const;
|
||||
|
||||
|
||||
@@ -577,8 +577,9 @@ static void displayResults(SearchResult *search,
|
||||
item.setStyle(colorStyleForUsageType(result.tags));
|
||||
item.setUseTextEditorFont(true);
|
||||
if (search->supportsReplace()) {
|
||||
const Node * const node = ProjectTree::nodeForFile(result.path);
|
||||
item.setSelectForReplacement(!ProjectManager::hasProjects()
|
||||
|| ProjectManager::projectForFile(result.path));
|
||||
|| (node && !node->isGenerated()));
|
||||
}
|
||||
search->addResult(item);
|
||||
|
||||
|
||||
@@ -132,7 +132,8 @@ QtCreatorIntegration::QtCreatorIntegration(QDesignerFormEditorInterface *core, Q
|
||||
connect(this, &QtCreatorIntegration::propertyChanged,
|
||||
this, [this](QDesignerFormWindowInterface *formWindow, const QString &name,
|
||||
const QVariant &) {
|
||||
if (name == "objectName") {
|
||||
qCDebug(log) << "got propertyChanged() signal" << name;
|
||||
if (name.endsWith("Name")) {
|
||||
if (const auto extraCompiler = d->extraCompilers.find(formWindow);
|
||||
extraCompiler != d->extraCompilers.end()) {
|
||||
(*extraCompiler)->unblock();
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/mimeutils.h>
|
||||
@@ -308,10 +310,10 @@ Utils::SearchResultItems generateSearchResultItems(
|
||||
item.setFilePath(filePath);
|
||||
item.setUseTextEditorFont(true);
|
||||
if (renaming && limitToProjects) {
|
||||
const bool fileBelongsToProject = ProjectExplorer::ProjectManager::projectForFile(
|
||||
filePath);
|
||||
item.setSelectForReplacement(fileBelongsToProject);
|
||||
if (fileBelongsToProject
|
||||
const ProjectExplorer::Node * const node
|
||||
= ProjectExplorer::ProjectTree::nodeForFile(filePath);
|
||||
item.setSelectForReplacement(node && !node->isGenerated());
|
||||
if (node
|
||||
&& filePath.baseName().compare(oldSymbolName, Qt::CaseInsensitive) == 0) {
|
||||
fileRenameCandidates << filePath;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "qmlprojectmanager_global.h"
|
||||
#include <projectexplorer/project.h>
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProject;
|
||||
|
||||
@@ -427,7 +427,7 @@ void SshProcessInterface::emitStarted(qint64 processId)
|
||||
|
||||
void SshProcessInterface::killIfRunning()
|
||||
{
|
||||
if (d->m_killed || d->m_process.state() != QProcess::Running)
|
||||
if (d->m_killed || d->m_process.state() != QProcess::Running || d->m_processId == 0)
|
||||
return;
|
||||
sendControlSignal(ControlSignal::Kill);
|
||||
d->m_killed = true;
|
||||
@@ -449,9 +449,12 @@ bool SshProcessInterface::runInShell(const CommandLine &command, const QByteArra
|
||||
process.setCommand(cmd);
|
||||
process.setWriteData(data);
|
||||
process.start();
|
||||
bool isFinished = process.waitForFinished(2000); // TODO: it may freeze on some devices
|
||||
// otherwise we may start producing killers for killers
|
||||
QTC_CHECK(isFinished);
|
||||
bool isFinished = process.waitForFinished(2000); // It may freeze on some devices
|
||||
if (!isFinished) {
|
||||
Core::MessageManager::writeFlashing(tr("Can't send control signal to the %1 device. "
|
||||
"The device might have been disconnected.")
|
||||
.arg(d->m_device->displayName()));
|
||||
}
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <QDir>
|
||||
#include <QFileOpenEvent>
|
||||
#include <QLockFile>
|
||||
#include <QPointer>
|
||||
#include <QSharedMemory>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||