Merge remote-tracking branch 'origin/4.14'

Change-Id: Iea84f23cf394de13e99a9ed777c8c113e4eff473
This commit is contained in:
Eike Ziller
2020-11-19 15:38:13 +01:00
271 changed files with 2816 additions and 1016 deletions

View File

@@ -54,6 +54,14 @@ AndroidCreateKeystoreCertificate::AndroidCreateKeystoreCertificate(QWidget *pare
this, &AndroidCreateKeystoreCertificate::checkCertificateAlias);
connect(ui->countryLineEdit, &QLineEdit::textChanged,
this, &AndroidCreateKeystoreCertificate::checkCountryCode);
connect(ui->keystoreShowPassCheckBox, &QCheckBox::stateChanged,
this, &AndroidCreateKeystoreCertificate::keystoreShowPassStateChanged);
connect(ui->certificateShowPassCheckBox, &QCheckBox::stateChanged,
this, &AndroidCreateKeystoreCertificate::certificateShowPassStateChanged);
connect(ui->samePasswordCheckBox, &QCheckBox::stateChanged,
this, &AndroidCreateKeystoreCertificate::samePasswordStateChanged);
connect(ui->buttonBox, &QDialogButtonBox::accepted,
this, &AndroidCreateKeystoreCertificate::buttonBoxAccepted);
connect(ui->buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject);
connect(ui->keystorePassLineEdit,
@@ -144,19 +152,19 @@ bool AndroidCreateKeystoreCertificate::checkCountryCode()
return true;
}
void AndroidCreateKeystoreCertificate::on_keystoreShowPassCheckBox_stateChanged(int state)
void AndroidCreateKeystoreCertificate::keystoreShowPassStateChanged(int state)
{
ui->keystorePassLineEdit->setEchoMode(state == Qt::Checked ? QLineEdit::Normal : QLineEdit::Password);
ui->keystoreRetypePassLineEdit->setEchoMode(ui->keystorePassLineEdit->echoMode());
}
void AndroidCreateKeystoreCertificate::on_certificateShowPassCheckBox_stateChanged(int state)
void AndroidCreateKeystoreCertificate::certificateShowPassStateChanged(int state)
{
ui->certificatePassLineEdit->setEchoMode(state == Qt::Checked ? QLineEdit::Normal : QLineEdit::Password);
ui->certificateRetypePassLineEdit->setEchoMode(ui->certificatePassLineEdit->echoMode());
}
void AndroidCreateKeystoreCertificate::on_buttonBox_accepted()
void AndroidCreateKeystoreCertificate::buttonBoxAccepted()
{
if (!validateUserInput())
return;
@@ -200,7 +208,7 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted()
accept();
}
void AndroidCreateKeystoreCertificate::on_samePasswordCheckBox_stateChanged(int state)
void AndroidCreateKeystoreCertificate::samePasswordStateChanged(int state)
{
if (state == Qt::Checked) {
ui->certificatePassLineEdit->setDisabled(true);

View File

@@ -61,10 +61,10 @@ private:
bool checkCountryCode();
private slots:
void on_keystoreShowPassCheckBox_stateChanged(int state);
void on_certificateShowPassCheckBox_stateChanged(int state);
void on_buttonBox_accepted();
void on_samePasswordCheckBox_stateChanged(int state);
void keystoreShowPassStateChanged(int state);
void certificateShowPassStateChanged(int state);
void buttonBoxAccepted();
void samePasswordStateChanged(int state);
private:
bool validateUserInput();

View File

@@ -53,9 +53,6 @@ public:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
signals:
void changed();
private:
QStringList m_value;
QString m_label;

View File

@@ -327,7 +327,8 @@ void AndroidSettingsWidget::updateNdkList()
void AndroidSettingsWidget::addCustomNdkItem()
{
const QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first();
const QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
.constFirst();
const QString ndkPath = QFileDialog::getExistingDirectory(this, tr("Select an NDK"), homePath);
if (m_androidConfig.isValidNdk(ndkPath)) {

View File

@@ -174,7 +174,7 @@ AutotestPluginPrivate::AutotestPluginPrivate()
AutotestPluginPrivate::~AutotestPluginPrivate()
{
if (!s_projectSettings.isEmpty()) {
qDeleteAll(s_projectSettings.values());
qDeleteAll(s_projectSettings);
s_projectSettings.clear();
}

View File

@@ -109,7 +109,7 @@ ProjectTestSettingsWidget::ProjectTestSettingsWidget(ProjectExplorer::Project *p
TestTreeModel::instance(), &TestTreeModel::synchronizeTestFrameworks);
}
void ProjectTestSettingsWidget::populateFrameworks(const QMap<ITestFramework *, bool> &frameworks)
void ProjectTestSettingsWidget::populateFrameworks(const QHash<ITestFramework *, bool> &frameworks)
{
TestFrameworks sortedFrameworks = frameworks.keys();
Utils::sort(sortedFrameworks, &ITestFramework::priority);

View File

@@ -51,7 +51,7 @@ public:
explicit ProjectTestSettingsWidget(ProjectExplorer::Project *project,
QWidget *parent = nullptr);
private:
void populateFrameworks(const QMap<Autotest::ITestFramework *, bool> &frameworks);
void populateFrameworks(const QHash<Autotest::ITestFramework *, bool> &frameworks);
void onActiveFrameworkChanged(QTreeWidgetItem *item, int column);
TestProjectSettings *m_projectSettings;
QComboBox *m_useGlobalSettings = nullptr;

View File

@@ -141,7 +141,7 @@ static QString quickTestName(const CPlusPlus::Document::Ptr &doc,
return astVisitor.testBaseName();
}
QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const
QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir)
{
QStringList dirs(srcDir);
ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance();
@@ -159,7 +159,8 @@ QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QS
QFileInfo fi(it.fileInfo().canonicalFilePath());
dirs.append(fi.filePath());
}
emit updateWatchPaths(dirs);
QMetaObject::invokeMethod(this, [this, dirs] { QuickTestParser::doUpdateWatchPaths(dirs); },
Qt::QueuedConnection);
QList<Document::Ptr> foundDocs;
@@ -313,8 +314,6 @@ QuickTestParser::QuickTestParser(ITestFramework *framework)
});
connect(&m_directoryWatcher, &QFileSystemWatcher::directoryChanged,
this, &QuickTestParser::handleDirectoryChanged);
connect(this, &QuickTestParser::updateWatchPaths,
this, &QuickTestParser::doUpdateWatchPaths, Qt::QueuedConnection);
}
void QuickTestParser::init(const QStringList &filesToParse, bool fullParse)

View File

@@ -51,14 +51,12 @@ public:
bool processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
const QString &fileName) override;
QString projectFileForMainCppFile(const QString &fileName) const;
signals:
void updateWatchPaths(const QStringList &directories) const;
private:
bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface,
CPlusPlus::Document::Ptr document, ITestFramework *framework);
void handleDirectoryChanged(const QString &directory);
void doUpdateWatchPaths(const QStringList &directories);
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const;
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir);
QmlJS::Snapshot m_qmlSnapshot;
QHash<QString, QString> m_proFilesForQmlFiles;
QFileSystemWatcher m_directoryWatcher;

View File

@@ -47,9 +47,9 @@ public:
bool useGlobalSettings() const { return m_useGlobalSettings; }
void setRunAfterBuild(RunAfterBuildMode mode) {m_runAfterBuild = mode; }
RunAfterBuildMode runAfterBuild() const { return m_runAfterBuild; }
void setActiveFrameworks(const QMap<ITestFramework *, bool> enabledFrameworks)
void setActiveFrameworks(const QHash<ITestFramework *, bool> enabledFrameworks)
{ m_activeTestFrameworks = enabledFrameworks; }
QMap<ITestFramework *, bool> activeFrameworks() const { return m_activeTestFrameworks; }
QHash<ITestFramework *, bool> activeFrameworks() const { return m_activeTestFrameworks; }
void activateFramework(const Utils::Id &id, bool activate);
Internal::ItemDataCache<Qt::CheckState> *checkStateCache() { return &m_checkStateCache; }
private:
@@ -59,7 +59,7 @@ private:
ProjectExplorer::Project *m_project;
bool m_useGlobalSettings = true;
RunAfterBuildMode m_runAfterBuild = RunAfterBuildMode::None;
QMap<ITestFramework *, bool> m_activeTestFrameworks;
QHash<ITestFramework *, bool> m_activeTestFrameworks;
Internal::ItemDataCache<Qt::CheckState> m_checkStateCache;
};

View File

@@ -153,7 +153,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
connect(m_treeView, &ResultsTreeView::copyShortcutTriggered, [this] () {
onCopyItemTriggered(getTestResult(m_treeView->currentIndex()));
});
connect(m_model, &TestResultModel::requestExpansion, [this] (QModelIndex idx) {
connect(m_model, &TestResultModel::requestExpansion, [this] (const QModelIndex &idx) {
m_treeView->expand(m_filterModel->mapFromSource(idx));
});
connect(TestRunner::instance(), &TestRunner::testRunStarted,

View File

@@ -245,7 +245,7 @@ void TestTreeModel::synchronizeTestFrameworks()
qCDebug(LOG) << "Active frameworks sorted by priority" << sorted;
} else { // we've got custom project settings
const TestProjectSettings *settings = AutotestPlugin::projectSettings(project);
const QMap<ITestFramework *, bool> active = settings->activeFrameworks();
const QHash<ITestFramework *, bool> active = settings->activeFrameworks();
sorted = Utils::filtered(active.keys(), [active](ITestFramework *framework) {
return active.value(framework);
});

View File

@@ -115,6 +115,8 @@ QdbRunConfiguration::QdbRunConfiguration(Target *target, Utils::Id id)
});
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
connect(target, &Target::deploymentDataChanged, this, &RunConfiguration::update);
connect(target, &Target::kitChanged, this, &RunConfiguration::update);
setDefaultDisplayName(tr("Run on Boot2Qt Device"));
}
@@ -123,8 +125,8 @@ Tasks QdbRunConfiguration::checkForIssues() const
{
Tasks tasks;
if (aspect<ExecutableAspect>()->executable().toString().isEmpty()) {
tasks << createConfigurationIssue(tr("The remote executable must be set "
"in order to run on a Boot2Qt device."));
tasks << BuildSystemTask(Task::Warning, tr("The remote executable must be set "
"in order to run on a Boot2Qt device."));
}
return tasks;
}

View File

@@ -313,6 +313,12 @@ DiagnosticItem::~DiagnosticItem()
delete m_mark;
}
void DiagnosticItem::setTextMarkVisible(bool visible)
{
if (m_mark)
m_mark->setVisible(visible);
}
Qt::ItemFlags DiagnosticItem::flags(int column) const
{
const Qt::ItemFlags itemFlags = TreeItem::flags(column);
@@ -630,7 +636,7 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
// Filtered out?
if (m_filterOptions && !m_filterOptions->checks.contains(diag.name)) {
diagnosticItem->textMark()->setVisible(false);
diagnosticItem->setTextMarkVisible(false);
return false;
}
@@ -643,11 +649,11 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
if (fi.isRelative())
filePath = m_lastProjectDirectory.toString() + QLatin1Char('/') + filePath;
if (filePath == diag.location.filePath) {
diagnosticItem->textMark()->setVisible(false);
diagnosticItem->setTextMarkVisible(false);
return false;
}
}
diagnosticItem->textMark()->setVisible(true);
diagnosticItem->setTextMarkVisible(true);
return true;
}

View File

@@ -74,7 +74,7 @@ public:
~DiagnosticItem() override;
const Diagnostic &diagnostic() const { return m_diagnostic; }
TextEditor::TextMark *textMark() { return m_mark; }
void setTextMarkVisible(bool visible);
FixitStatus fixItStatus() const { return m_fixitStatus; }
void setFixItStatus(const FixitStatus &status);

View File

@@ -53,7 +53,7 @@ void VirtualFileSystemOverlay::update()
return;
std::map<Utils::FilePath, QList<Core::IDocument *>> documentRoots;
const QList<Core::IDocument *> &modifiedDocuments = Core::DocumentManager::modifiedDocuments();
QMap<Core::IDocument *, AutoSavedPath> newSaved;
QHash<Core::IDocument *, AutoSavedPath> newSaved;
for (Core::IDocument *doc : modifiedDocuments) {
auto document = qobject_cast<TextEditor::TextDocument *>(doc);
if (!document)

View File

@@ -28,6 +28,7 @@
#include <utils/fileutils.h>
#include <utils/temporarydirectory.h>
#include <QHash>
#include <QMap>
namespace Core { class IDocument; }
@@ -55,7 +56,7 @@ private:
Utils::FilePath path;
};
QMap<Core::IDocument *, AutoSavedPath> m_saved;
QHash<Core::IDocument *, AutoSavedPath> m_saved;
QMap<Utils::FilePath, Utils::FilePath> m_mapping;
};

View File

@@ -1059,7 +1059,7 @@ void ClearCasePluginPrivate::setStatus(const QString &file, FileStatus::Status s
m_statusMap->insert(file, FileStatus(status, QFileInfo(file).permissions()));
if (update && currentState().currentFile() == file)
QMetaObject::invokeMethod(this, "updateStatusActions");
QMetaObject::invokeMethod(this, &ClearCasePluginPrivate::updateStatusActions);
}
void ClearCasePluginPrivate::undoCheckOutCurrent()

View File

@@ -394,6 +394,12 @@ void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters &pa
tr("The kit needs to define a CMake tool to parse this project.")));
return;
}
if (!parameters.cmakeTool()->hasFileApi()) {
TaskHub::addTask(BuildSystemTask(Task::Error,
CMakeKitAspect::msgUnsupportedVersion(
parameters.cmakeTool()->version().fullVersion)));
return;
}
QTC_ASSERT(parameters.isValid(), return );
m_parameters = parameters;

View File

@@ -255,10 +255,7 @@ Tasks CMakeKitAspect::validate(const Kit *k) const
if (tool) {
CMakeTool::Version version = tool->version();
if (version.major < 3 || (version.major == 3 && version.minor < 14)) {
result << BuildSystemTask(Task::Warning,
tr("CMake version %1 is unsupported. Please update to "
"version 3.14 (with file-api) or later.")
.arg(QString::fromUtf8(version.fullVersion)));
result << BuildSystemTask(Task::Warning, msgUnsupportedVersion(version.fullVersion));
}
}
return result;
@@ -305,6 +302,13 @@ QSet<Utils::Id> CMakeKitAspect::availableFeatures(const Kit *k) const
return {};
}
QString CMakeKitAspect::msgUnsupportedVersion(const QByteArray &versionString)
{
return tr("CMake version %1 is unsupported. Please update to "
"version 3.14 (with file-api) or later.")
.arg(QString::fromUtf8(versionString));
}
// --------------------------------------------------------------------
// CMakeGeneratorKitAspect:
// --------------------------------------------------------------------

View File

@@ -56,6 +56,8 @@ public:
void addToMacroExpander(ProjectExplorer::Kit *k, Utils::MacroExpander *expander) const final;
QSet<Utils::Id> availableFeatures(const ProjectExplorer::Kit *k) const final;
static QString msgUnsupportedVersion(const QByteArray &versionString);
};
class CMAKE_EXPORT CMakeGeneratorKitAspect : public ProjectExplorer::KitAspect

View File

@@ -204,7 +204,8 @@ public:
if (column != 0)
return QVariant();
const bool hasError = !m_pathExists || !m_pathIsFile || !m_pathIsExecutable;
const bool hasError = !m_isSupported || !m_pathExists || !m_pathIsFile
|| !m_pathIsExecutable;
if (hasError)
return Utils::Icons::CRITICAL.icon();
return QVariant();

View File

@@ -94,8 +94,6 @@ public:
bool m_didAttemptToRun = false;
bool m_didRun = true;
bool m_triedCapabilities = false;
QList<CMakeTool::Generator> m_generators;
QMap<QString, QStringList> m_functionArgs;
QVector<FileApi> m_fileApis;
@@ -320,7 +318,7 @@ QVector<std::pair<QString, int>> CMakeTool::supportedFileApiObjects() const
CMakeTool::Version CMakeTool::version() const
{
return isValid() ? m_introspection->m_version : CMakeTool::Version();
return m_introspection ? m_introspection->m_version : CMakeTool::Version();
}
bool CMakeTool::isAutoDetected() const
@@ -393,7 +391,6 @@ void CMakeTool::readInformation() const
m_introspection->m_didAttemptToRun = true;
fetchFromCapabilities();
m_introspection->m_triedCapabilities = true;
}
static QStringList parseDefinition(const QString &definition)

View File

@@ -34,6 +34,7 @@
#include <utils/consoleprocess.h>
#include <utils/environment.h>
#include <utils/hostosinfo.h>
#include <utils/qtcprocess.h>
#include <utils/textfileformat.h>
#include <utils/unixutils.h>
@@ -102,12 +103,23 @@ void FileUtils::showInGraphicalShell(QWidget *parent, const QString &pathIn)
// we cannot select a file here, because no file browser really supports it...
const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.filePath();
const QString app = UnixUtils::fileBrowser(ICore::settings());
QProcess browserProc;
const QString browserArgs = UnixUtils::substituteFileBrowserParameters(app, folder);
bool success = browserProc.startDetached(browserArgs);
const QString error = QString::fromLocal8Bit(browserProc.readAllStandardError());
success = success && error.isEmpty();
if (!success)
QStringList browserArgs = Utils::QtcProcess::splitArgs(
UnixUtils::substituteFileBrowserParameters(app, folder));
QString error;
if (browserArgs.isEmpty()) {
error = QApplication::translate("Core::Internal",
"The command for file browser is not set.");
} else {
QProcess browserProc;
browserProc.setProgram(browserArgs.takeFirst());
browserProc.setArguments(browserArgs);
const bool success = browserProc.startDetached();
error = QString::fromLocal8Bit(browserProc.readAllStandardError());
if (!success && error.isEmpty())
error = QApplication::translate("Core::Internal",
"Error while starting file browser.");
}
if (!error.isEmpty())
showGraphicalShellError(parent, app, error);
}
}

View File

@@ -451,6 +451,9 @@ QTextCursor BaseTextFind::findOne(const QRegularExpression &expr,
if (!inScope(candidate.selectionStart(), candidate.selectionEnd()))
return candidate;
bool inVerticalFindScope = false;
// This code relies on the fact, that we have to keep TextEditorWidget subclass
// inside d->m_plaineditor which is of QPlainTextEdit class. So we can't
// transform it into a typed version now, as it relies on a dynamic match.
QMetaObject::invokeMethod(d->m_plaineditor, "inFindScope", Qt::DirectConnection,
Q_RETURN_ARG(bool, inVerticalFindScope),
Q_ARG(QTextCursor, candidate));

View File

@@ -129,7 +129,7 @@
<item>
<widget class="QCheckBox" name="matchCase">
<property name="text">
<string>Case sensiti&amp;ve</string>
<string>Case &amp;sensitive</string>
</property>
</widget>
</item>

View File

@@ -92,9 +92,9 @@ signals:
void navigateStateUpdate();
void flashButton();
void setBadgeNumber(int number);
void zoomIn(int range);
void zoomOut(int range);
void resetZoom();
void zoomInRequested(int range);
void zoomOutRequested(int range);
void resetZoomRequested();
void wheelZoomEnabledChanged(bool enabled);
void fontChanged(const QFont &font);

View File

@@ -113,7 +113,8 @@ QList<OpenDocumentsFilter::Entry> OpenDocumentsFilter::editors() const
void OpenDocumentsFilter::refresh(QFutureInterface<void> &future)
{
Q_UNUSED(future)
QMetaObject::invokeMethod(this, "refreshInternally", Qt::BlockingQueuedConnection);
QMetaObject::invokeMethod(this, &OpenDocumentsFilter::refreshInternally,
Qt::BlockingQueuedConnection);
}
void OpenDocumentsFilter::accept(LocatorFilterEntry selection,

View File

@@ -54,9 +54,9 @@ MessageOutputWindow::MessageOutputWindow()
p.setColor(QPalette::HighlightedText, activeHighlightedText);
m_widget->setPalette(p);
connect(this, &IOutputPane::zoomIn, m_widget, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, m_widget, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoom, m_widget, &Core::OutputWindow::resetZoom);
connect(this, &IOutputPane::zoomInRequested, m_widget, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOutRequested, m_widget, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoomRequested, m_widget, &Core::OutputWindow::resetZoom);
connect(this, &IOutputPane::fontChanged, m_widget, &OutputWindow::setBaseFont);
connect(this, &IOutputPane::wheelZoomEnabledChanged, m_widget, &OutputWindow::setWheelZoomEnabled);

View File

@@ -100,11 +100,11 @@ IOutputPane::IOutputPane(QObject *parent)
m_zoomInButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon());
m_zoomInButton->setCommandId(Constants::ZOOM_IN);
connect(m_zoomInButton, &QToolButton::clicked, this, [this] { emit zoomIn(1); });
connect(m_zoomInButton, &QToolButton::clicked, this, [this] { emit zoomInRequested(1); });
m_zoomOutButton->setIcon(Utils::Icons::MINUS.icon());
m_zoomOutButton->setCommandId(Constants::ZOOM_OUT);
connect(m_zoomOutButton, &QToolButton::clicked, this, [this] { emit zoomOut(1); });
connect(m_zoomOutButton, &QToolButton::clicked, this, [this] { emit zoomOutRequested(1); });
}
IOutputPane::~IOutputPane()
@@ -199,14 +199,14 @@ void IOutputPane::setupContext(const char *context, QWidget *widget)
const auto zoomInAction = new QAction(this);
Core::ActionManager::registerAction(zoomInAction, Constants::ZOOM_IN, m_context->context());
connect(zoomInAction, &QAction::triggered, this, [this] { emit zoomIn(1); });
connect(zoomInAction, &QAction::triggered, this, [this] { emit zoomInRequested(1); });
const auto zoomOutAction = new QAction(this);
Core::ActionManager::registerAction(zoomOutAction, Constants::ZOOM_OUT, m_context->context());
connect(zoomOutAction, &QAction::triggered, this, [this] { emit zoomOut(1); });
connect(zoomOutAction, &QAction::triggered, this, [this] { emit zoomOutRequested(1); });
const auto resetZoomAction = new QAction(this);
Core::ActionManager::registerAction(resetZoomAction, Constants::ZOOM_RESET,
m_context->context());
connect(resetZoomAction, &QAction::triggered, this, &IOutputPane::resetZoom);
connect(resetZoomAction, &QAction::triggered, this, &IOutputPane::resetZoomRequested);
}
void IOutputPane::setZoomButtonsEnabled(bool enabled)

View File

@@ -270,7 +270,10 @@ public:
PluginSpec *coreplugin = CorePlugin::instance()->pluginSpec();
// look for plugin
QDirIterator it(m_tempDir->path(), libraryNameFilter(), QDir::Files | QDir::NoSymLinks);
QDirIterator it(m_tempDir->path(),
libraryNameFilter(),
QDir::Files | QDir::NoSymLinks,
QDirIterator::Subdirectories);
while (it.hasNext()) {
if (fi.isCanceled())
return;
@@ -298,9 +301,9 @@ public:
return; // successful / no error
}
}
fi.reportResult({PluginInstallWizard::tr("Did not find %1 plugin in toplevel directory.")
.arg(Constants::IDE_DISPLAY_NAME),
InfoLabel::Error});
fi.reportResult(
{PluginInstallWizard::tr("Did not find %1 plugin.").arg(Constants::IDE_DISPLAY_NAME),
InfoLabel::Error});
}
void cleanupPage() final

View File

@@ -351,7 +351,7 @@ FilePaths VcsManager::promptToDelete(const FilePaths &filePaths)
}
// Categorize by version control system.
QMap<IVersionControl *, FilePaths> filesByVersionControl;
QHash<IVersionControl *, FilePaths> filesByVersionControl;
for (auto it = filesByParentDir.cbegin(); it != filesByParentDir.cend(); ++it) {
IVersionControl * const vc = findVersionControlForDirectory(it.key().toString());
if (vc)

View File

@@ -7293,6 +7293,26 @@ void CppEditorPlugin::test_quickfix_removeUsingNamespace_data()
"}\n"
"foo foos;\n";
// like header1 but without "using namespace std;\n"
QByteArray expected1 = "namespace std{\n"
" template<typename T>\n"
" class vector{};\n"
" namespace chrono{\n"
" using seconds = int;\n"
" }\n"
"}\n"
"namespace test{\n"
" class vector{\n"
" std::vector<int> ints;\n"
" };\n"
"}\n";
// like header2 but without "using namespace std;\n" and with std::vector
QByteArray expected2 = "#include \"header1.h\"\n"
"using foo = test::vector;\n"
"using namespace test;\n"
"std::vector<int> others;\n";
QByteArray expected3 = "#include \"header2.h\"\n"
"using namespace std::chrono;\n"
"namespace test{\n"
@@ -7313,22 +7333,18 @@ void CppEditorPlugin::test_quickfix_removeUsingNamespace_data()
QTest::newRow("remove only in one file local")
<< header1 << header2 << h3 << header1 << header2 << expected3 << 0;
QTest::newRow("remove only in one file globally")
<< header1 << header2 << h3 << header1 << header2 << expected3 << 1;
<< header1 << header2 << h3 << expected1 << expected2 << expected3 << 1;
QByteArray h2 = "#include \"header1.h\"\n"
"using foo = test::vector;\n"
"using namespace s@td;\n"
"using namespace test;\n"
"vector<int> others;\n";
QByteArray expected2 = "#include \"header1.h\"\n"
"using foo = test::vector;\n"
"using namespace test;\n"
"std::vector<int> others;\n";
QTest::newRow("remove across two files only this")
<< header1 << h2 << header3 << header1 << expected2 << header3 << 0;
QTest::newRow("remove across two files globally1")
<< header1 << h2 << header3 << header1 << expected2 << expected3 << 1;
<< header1 << h2 << header3 << expected1 << expected2 << expected3 << 1;
QByteArray h1 = "namespace std{\n"
" template<typename T>\n"
@@ -7343,18 +7359,6 @@ void CppEditorPlugin::test_quickfix_removeUsingNamespace_data()
" std::vector<int> ints;\n"
" };\n"
"}\n";
QByteArray expected1 = "namespace std{\n"
" template<typename T>\n"
" class vector{};\n"
" namespace chrono{\n"
" using seconds = int;\n"
" }\n"
"}\n"
"namespace test{\n"
" class vector{\n"
" std::vector<int> ints;\n"
" };\n"
"}\n";
QTest::newRow("remove across tree files only this")
<< h1 << header2 << header3 << expected1 << header2 << header3 << 0;
@@ -7409,6 +7413,15 @@ void CppEditorPlugin::test_quickfix_removeUsingNamespace_data()
QTest::newRow("existing namespace")
<< header1 << h2 << header3 << header1 << expected2 << header3 << 1;
// test: remove using directive at global scope in every file
h1 = "using namespace tes@t;";
h2 = "using namespace test;";
h3 = "using namespace test;";
expected1 = expected2 = expected3 = "";
QTest::newRow("global scope remove in every file")
<< h1 << h2 << h3 << expected1 << expected2 << expected3 << 1;
}
void CppEditorPlugin::test_quickfix_removeUsingNamespace()

View File

@@ -58,6 +58,7 @@
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/session.h>
#include <utils/algorithm.h>
#include <utils/basetreeview.h>
@@ -7904,6 +7905,7 @@ void removeLine(const CppRefactoringFile *file, AST *ast, ChangeSet &changeSet)
class RemoveNamespaceVisitor : public ASTVisitor
{
public:
constexpr static int SearchGlobalUsingDirectivePos = std::numeric_limits<int>::max();
RemoveNamespaceVisitor(const CppRefactoringFile *file,
const Snapshot &snapshot,
const Name *namespace_,
@@ -7942,8 +7944,16 @@ private:
bool preVisit(AST *ast) override
{
if (!m_start) {
if (ast->asTranslationUnit())
return true;
if (UsingDirectiveAST *usingDirective = ast->asUsingDirective()) {
if (nameEqual(usingDirective->name->name, m_namespace)) {
if (m_symbolPos == SearchGlobalUsingDirectivePos) {
// we have found a global using directive, so lets start
m_start = true;
removeLine(m_file, ast, m_changeSet);
return false;
}
// ignore the using namespace that should be removed
if (m_file->endOf(ast) != m_symbolPos) {
if (m_removeAllAtGlobalScope)
@@ -8129,6 +8139,18 @@ private:
class RemoveUsingNamespaceOperation : public CppQuickFixOperation
{
struct Node
{
Document::Ptr document;
bool hasGlobalUsingDirective = false;
int unprocessedParents;
std::vector<std::reference_wrapper<Node>> includes;
std::vector<std::reference_wrapper<Node>> includedBy;
Node() = default;
Node(const Node &) = delete;
Node(Node &&) = delete;
};
public:
RemoveUsingNamespaceOperation(const CppQuickFixInterface &interface,
UsingDirectiveAST *usingDirective,
@@ -8153,12 +8175,94 @@ public:
}
private:
std::map<Utils::FilePath, Node> buildIncludeGraph(CppRefactoringChanges &refactoring)
{
using namespace ProjectExplorer;
using namespace Utils;
const Snapshot &s = refactoring.snapshot();
std::map<Utils::FilePath, Node> includeGraph;
auto handleFile = [&](const FilePath &filePath, Document::Ptr doc, auto shouldHandle) {
Node &node = includeGraph[filePath];
node.document = doc;
for (const Document::Include &include : doc->resolvedIncludes()) {
const auto filePath = FilePath::fromString(include.resolvedFileName());
if (shouldHandle(filePath)) {
Node &includedNode = includeGraph[filePath];
includedNode.includedBy.push_back(node);
node.includes.push_back(includedNode);
}
}
};
if (const Project *project = SessionManager::projectForFile(filePath())) {
const FilePaths files = project->files(ProjectExplorer::Project::SourceFiles);
QSet<FilePath> projectFiles(files.begin(), files.end());
for (const auto &file : files) {
const Document::Ptr doc = s.document(file);
if (!doc)
continue;
handleFile(file, doc, [&](const FilePath &file) {
return projectFiles.contains(file);
});
}
} else {
for (auto i = s.begin(); i != s.end(); ++i) {
if (ProjectFile::classify(i.key().toString()) != ProjectFile::Unsupported) {
handleFile(i.key(), i.value(), [](const FilePath &file) {
return ProjectFile::classify(file.toString()) != ProjectFile::Unsupported;
});
}
}
}
for (auto &[_, node] : includeGraph) {
Q_UNUSED(_)
node.unprocessedParents = static_cast<int>(node.includes.size());
}
return includeGraph;
}
void removeAllUsingsAtGlobalScope(CppRefactoringChanges &refactoring)
{
auto includeGraph = buildIncludeGraph(refactoring);
std::vector<std::reference_wrapper<Node>> nodesWithProcessedParents;
for (auto &[_, node] : includeGraph) {
Q_UNUSED(_)
if (!node.unprocessedParents)
nodesWithProcessedParents.push_back(node);
}
while (!nodesWithProcessedParents.empty()) {
Node &node = nodesWithProcessedParents.back();
nodesWithProcessedParents.pop_back();
CppRefactoringFilePtr file = refactoring.file(node.document->fileName());
const bool parentHasUsing = Utils::anyOf(node.includes, &Node::hasGlobalUsingDirective);
const int startPos = parentHasUsing
? 0
: RemoveNamespaceVisitor::SearchGlobalUsingDirectivePos;
const bool noGlobalUsing = refactorFile(file, refactoring.snapshot(), startPos);
node.hasGlobalUsingDirective = !noGlobalUsing || parentHasUsing;
for (Node &subNode : node.includedBy) {
--subNode.unprocessedParents;
if (subNode.unprocessedParents == 0)
nodesWithProcessedParents.push_back(subNode);
}
}
}
void perform() override
{
CppRefactoringChanges refactoring(snapshot());
CppRefactoringFilePtr currentFile = refactoring.file(filePath().toString());
if (refactorFile(currentFile, refactoring.snapshot(), currentFile->endOf(m_usingDirective), true))
if (m_removeAllAtGlobalScope) {
removeAllUsingsAtGlobalScope(refactoring);
} else if (refactorFile(currentFile,
refactoring.snapshot(),
currentFile->endOf(m_usingDirective),
true)) {
processIncludes(refactoring, filePath().toString());
}
for (auto &file : m_changes)
file->apply();
@@ -8186,10 +8290,12 @@ private:
Utils::ChangeSet changes = visitor.getChanges();
if (removeUsing)
removeLine(file.get(), m_usingDirective, changes);
file->setChangeSet(changes);
// apply changes at the end, otherwise the symbol finder will fail to resolve symbols if
// the using namespace is missing
m_changes.insert(file);
if (!changes.isEmpty()) {
file->setChangeSet(changes);
// apply changes at the end, otherwise the symbol finder will fail to resolve symbols if
// the using namespace is missing
m_changes.insert(file);
}
return visitor.isGlobalUsingNamespace() && !visitor.foundGlobalUsingNamespace();
}

View File

@@ -596,6 +596,7 @@ static QStringList languageFeatureMacros()
"__cpp_binary_literals",
"__cpp_capture_star_this",
"__cpp_constexpr",
"__cpp_constexpr_in_decltype",
"__cpp_decltype",
"__cpp_decltype_auto",
"__cpp_deduction_guides",

View File

@@ -100,7 +100,7 @@ const char SYMBOLS_FIND_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("CppTools", "C
// CLANG_VERSION here because it might denote a version that was not yet
// released (e.g. 6.0.1, but only 6.0.0 was released).
constexpr const char TIDY_DOCUMENTATION_URL_TEMPLATE[]
= "https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/%1.html";
= "https://releases.llvm.org/11.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/%1.html";
constexpr const char CLANG_STATIC_ANALYZER_DOCUMENTATION_URL[]
= "https://clang-analyzer.llvm.org/available_checks.html";

View File

@@ -127,7 +127,7 @@ QString CppToolsJsExtension::includeStatement(
{
if (fullyQualifiedClassName.isEmpty())
return {};
const QString className = parts(fullyQualifiedClassName).last();
const QString className = parts(fullyQualifiedClassName).constLast();
if (className.isEmpty() || specialClasses.contains(className))
return {};
if (className.startsWith('Q') && className.length() > 2 && className.at(1).isUpper())

View File

@@ -43,7 +43,6 @@
#include <QDebug>
#include <QRegularExpression>
#include <QSet>
#include <QStringRef>
#include <QTextCursor>
#include <QTextDocument>

View File

@@ -37,7 +37,6 @@
QT_BEGIN_NAMESPACE
class QChar;
class QFileInfo;
class QStringRef;
class QTextCursor;
QT_END_NAMESPACE

View File

@@ -108,7 +108,8 @@ QString StringTablePrivate::insert(const QString &string)
void StringTable::scheduleGC()
{
QMetaObject::invokeMethod(&m_instance->m_gcCountDown, "start", Qt::QueuedConnection);
QMetaObject::invokeMethod(&m_instance->m_gcCountDown, QOverload<>::of(&QTimer::start),
Qt::QueuedConnection);
}
StringTable::StringTable()

View File

@@ -184,7 +184,7 @@ void ConsoleView::onRowActivated(const QModelIndex &index)
return;
const QFileInfo fi = m_finder.findFile(model()->data(index, ConsoleItem::FileRole).toString())
.first().toFileInfo();
.constFirst().toFileInfo();
if (fi.exists() && fi.isFile() && fi.isReadable()) {
Core::EditorManager::openEditorAt(fi.canonicalFilePath(),
model()->data(index, ConsoleItem::LineRole).toInt());

View File

@@ -973,7 +973,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
m_runParameters.toolChainAbi = ToolChainKitAspect::targetAbi(kit);
bool ok = false;
int nativeMixedOverride = qgetenv("QTC_DEBUGGER_NATIVE_MIXED").toInt(&ok);
const int nativeMixedOverride = qEnvironmentVariableIntValue("QTC_DEBUGGER_NATIVE_MIXED", &ok);
if (ok)
m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride);

View File

@@ -765,8 +765,7 @@ void GdbEngine::runCommand(const DebuggerCommand &command)
m_scheduledTestResponses.remove(token);
showMessage(QString("FAKING TEST RESPONSE (TOKEN: %2, RESPONSE: %3)")
.arg(token).arg(buffer));
QMetaObject::invokeMethod(this, "handleResponse",
Q_ARG(QString, buffer));
QMetaObject::invokeMethod(this, [this, buffer] { handleResponse(buffer); });
} else {
m_gdbProc.write(cmd.function.toUtf8() + "\r\n");
if (command.flags & NeedsFlush)

View File

@@ -2447,7 +2447,7 @@ QString QmlEngine::toFileInProject(const QUrl &fileUrl)
d->fileFinder.setAdditionalSearchDirectories(rp.additionalSearchDirectories);
d->fileFinder.setSysroot(rp.sysRoot);
return d->fileFinder.findFile(fileUrl).first().toString();
return d->fileFinder.findFile(fileUrl).constFirst().toString();
}
DebuggerEngine *createQmlEngine()

View File

@@ -259,8 +259,10 @@ QString cppExpressionAt(TextEditorWidget *editorWidget, int pos,
const Snapshot snapshot = CppModelManager::instance()->snapshot();
const Document::Ptr document = snapshot.document(fileName);
QTextCursor tc = editorWidget->textCursor();
QString expr = tc.selectedText();
if (expr.isEmpty()) {
QString expr;
if (tc.hasSelection() && pos >= tc.selectionStart() && pos <= tc.selectionEnd()) {
expr = tc.selectedText();
} else {
tc.setPosition(pos);
const QChar ch = editorWidget->characterAt(pos);
if (ch.isLetterOrNumber() || ch == '_')

View File

@@ -531,8 +531,8 @@ void UvscEngine::doUpdateLocals(const UpdateParameters &params)
const bool partial = !params.partialVariable.isEmpty();
// This is a workaround to avoid a strange QVector index assertion
// inside of the watch model.
QMetaObject::invokeMethod(this, "handleUpdateLocals", Qt::QueuedConnection,
Q_ARG(bool, partial));
QMetaObject::invokeMethod(this, [this, partial] { handleUpdateLocals(partial); },
Qt::QueuedConnection);
}
void UvscEngine::updateAll()

View File

@@ -67,7 +67,8 @@ QDebug operator<<(QDebug d, const GerritApproval &a)
// Sort approvals by type and reviewer
bool gerritApprovalLessThan(const GerritApproval &a1, const GerritApproval &a2)
{
return a1.type.compare(a2.type) < 0 || a1.reviewer.fullName.compare(a2.reviewer.fullName) < 0;
const int compare = a1.type.compare(a2.type);
return compare == 0 ? a1.reviewer.fullName.compare(a2.reviewer.fullName) < 0 : compare < 0;
}
QDebug operator<<(QDebug d, const GerritPatchSet &p)

View File

@@ -102,7 +102,7 @@ GitSubmitEditor::GitSubmitEditor() :
VcsBaseSubmitEditor(new GitSubmitEditorWidget)
{
connect(this, &VcsBaseSubmitEditor::diffSelectedRows, this, &GitSubmitEditor::slotDiffSelected);
connect(submitEditorWidget(), &GitSubmitEditorWidget::show, this, &GitSubmitEditor::showCommit);
connect(submitEditorWidget(), &GitSubmitEditorWidget::showRequested, this, &GitSubmitEditor::showCommit);
connect(GitPlugin::versionControl(), &Core::IVersionControl::repositoryChanged,
this, &GitSubmitEditor::forceUpdateFileModel);
connect(&m_fetchWatcher, &QFutureWatcher<CommitDataFetchResult>::finished,

View File

@@ -101,7 +101,7 @@ void GitSubmitEditorWidget::initialize(CommitType commitType,
logChangeGroupBox->setLayout(logChangeLayout);
m_logChangeWidget = new LogChangeWidget;
m_logChangeWidget->init(repository);
connect(m_logChangeWidget, &LogChangeWidget::commitActivated, this, &GitSubmitEditorWidget::show);
connect(m_logChangeWidget, &LogChangeWidget::commitActivated, this, &GitSubmitEditorWidget::showRequested);
logChangeLayout->addWidget(m_logChangeWidget);
insertLeftWidget(logChangeGroupBox);
m_gitSubmitPanelUi.editGroup->hide();

View File

@@ -76,7 +76,7 @@ protected:
QString commitName() const override;
signals:
void show(const QString &commit);
void showRequested(const QString &commit);
private:
void authorInformationChanged();

View File

@@ -180,8 +180,8 @@ QList<LocatorFilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<LocatorFi
if (forceUpdate) {
QStringList indices;
QMetaObject::invokeMethod(this, "allIndices", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QStringList, indices));
QMetaObject::invokeMethod(this, [this] { return allIndices(); },
Qt::BlockingQueuedConnection, &indices);
m_mutex.lock(); // guard m_needsUpdate
m_needsUpdate = false;
m_mutex.unlock();

View File

@@ -155,7 +155,7 @@ void SearchWidget::showEvent(QShowEvent *event)
connect(searchEngine, &QHelpSearchEngine::indexingFinished, this,
&SearchWidget::indexingFinished);
QMetaObject::invokeMethod(&LocalHelpManager::helpEngine(), "setupFinished",
QMetaObject::invokeMethod(&LocalHelpManager::helpEngine(), &QHelpEngine::setupFinished,
Qt::QueuedConnection);
}
}

View File

@@ -153,8 +153,9 @@ IosBuildSettingsWidget::IosBuildSettingsWidget(IosBuildConfiguration *bc)
this, &IosBuildSettingsWidget::onSigningEntityComboIndexChanged);
connect(m_autoSignCheckbox, &QCheckBox::toggled,
this, &IosBuildSettingsWidget::configureSigningUi);
const QString signingIdentifier = bc->m_signingIdentifier->value();
configureSigningUi(m_autoSignCheckbox->isChecked());
setDefaultSigningIdentfier(bc->m_signingIdentifier->value());
setDefaultSigningIdentfier(signingIdentifier);
}
m_signEntityCombo->setEnabled(m_isDevice);

View File

@@ -369,11 +369,6 @@ void IosRunSupport::start()
IosRunner::start();
}
void IosRunSupport::stop()
{
IosRunner::stop();
}
//
// IosQmlProfilerSupport
//

View File

@@ -60,7 +60,7 @@ public:
QmlDebug::QmlDebugServicesPreset qmlDebugServices() const;
void start() override;
void stop() override;
void stop() override final;
virtual void appOutput(const QString &/*output*/) {}
virtual void errorMsg(const QString &/*msg*/) {}
@@ -106,7 +106,6 @@ public:
void didStartApp(IosToolHandler::OpStatus status);
private:
void start() override;
void stop() override;
};

View File

@@ -207,7 +207,7 @@ void updateEditorToolBar(Core::IEditor *editor)
TextDocument *document = textEditor->textDocument();
Client *client = LanguageClientManager::clientForDocument(textEditor->textDocument());
static QMap<QWidget *, QAction *> actions;
static QHash<QWidget *, QAction *> actions;
if (actions.contains(widget)) {
auto action = actions[widget];
@@ -253,7 +253,7 @@ void updateEditorToolBar(Core::IEditor *editor)
});
}
static QMap<QWidget *, QPair<Client *, QAction *>> outlines;
static QHash<QWidget *, QPair<Client *, QAction *>> outlines;
if (outlines.contains(widget)) {
auto outline = outlines[widget];

View File

@@ -193,7 +193,7 @@ SectionedProducts::SectionedProducts(QWidget *parent)
SectionedProducts::~SectionedProducts()
{
qDeleteAll(m_gridViews.values());
qDeleteAll(m_gridViews);
delete m_productDelegate;
delete m_gridModel;
}

View File

@@ -152,7 +152,7 @@ ApplicationLauncherPrivate::ApplicationLauncherPrivate(ApplicationLauncher *pare
this, &ApplicationLauncherPrivate::localConsoleProcessError);
connect(&m_consoleProcess, &ConsoleProcess::processStopped,
this, &ApplicationLauncherPrivate::localProcessDone);
connect(&m_consoleProcess, QOverload<QProcess::ProcessError>::of(&ConsoleProcess::error),
connect(&m_consoleProcess, &ConsoleProcess::errorOccurred,
q, &ApplicationLauncher::error);
#ifdef Q_OS_WIN

View File

@@ -204,9 +204,9 @@ AppOutputPane::AppOutputPane() :
connect(m_attachButton, &QToolButton::clicked,
this, &AppOutputPane::attachToRunControl);
connect(this, &Core::IOutputPane::zoomIn, this, &AppOutputPane::zoomIn);
connect(this, &Core::IOutputPane::zoomOut, this, &AppOutputPane::zoomOut);
connect(this, &IOutputPane::resetZoom, this, &AppOutputPane::resetZoom);
connect(this, &IOutputPane::zoomInRequested, this, &AppOutputPane::zoomIn);
connect(this, &IOutputPane::zoomOutRequested, this, &AppOutputPane::zoomOut);
connect(this, &IOutputPane::resetZoomRequested, this, &AppOutputPane::resetZoom);
m_settingsButton->setToolTip(tr("Open Settings Page"));
m_settingsButton->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon());

View File

@@ -212,12 +212,6 @@ BuildConfiguration *BuildStep::buildConfiguration() const
if (config)
return config;
// This situation should be avoided, as the step returned below is almost
// always not the right one, but the fallback is best we can do.
// A potential currently still valid path is accessing a build configuration
// from a BuildStep in a DeployConfiguration. Let's hunt those down and
// replace with explicit code there.
QTC_CHECK(false);
// step is not part of a build configuration, use active build configuration of step's target
return target()->activeBuildConfiguration();
}

View File

@@ -123,9 +123,9 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
setupFilterUi("CompileOutputPane.Filter");
setFilteringEnabled(true);
connect(this, &IOutputPane::zoomIn, m_outputWindow, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, m_outputWindow, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoom, m_outputWindow, &Core::OutputWindow::resetZoom);
connect(this, &IOutputPane::zoomInRequested, m_outputWindow, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOutRequested, m_outputWindow, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoomRequested, m_outputWindow, &Core::OutputWindow::resetZoom);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged,
this, updateFontSettings);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,

View File

@@ -195,7 +195,7 @@ void SshDeviceProcess::handleConnected()
d->process->requestX11Forwarding(display);
if (runInTerminal()) {
d->process->requestTerminal();
connect(&d->consoleProcess, QOverload<QProcess::ProcessError>::of(&ConsoleProcess::error),
connect(&d->consoleProcess, &ConsoleProcess::errorOccurred,
this, &DeviceProcess::error);
connect(&d->consoleProcess, &ConsoleProcess::processStarted,
this, &SshDeviceProcess::handleProcessStarted);

View File

@@ -28,6 +28,7 @@
#include <coreplugin/fileutils.h>
#include <coreplugin/find/itemviewfind.h>
#include <utils/algorithm.h>
#include <utils/detailswidget.h>
#include <utils/environment.h>
#include <utils/environmentdialog.h>
@@ -449,6 +450,12 @@ bool EnvironmentWidget::currentEntryIsPathList(const QModelIndex &current) const
return true;
if (Utils::HostOsInfo::isAnyUnixHost() && varName == "LD_LIBRARY_PATH")
return true;
if (varName == "PKG_CONFIG_DIR")
return true;
if (Utils::HostOsInfo::isWindowsHost()
&& QStringList{"INCLUDE", "LIB", "LIBPATH"}.contains(varName)) {
return true;
}
// Now check the value: If it's a list of strings separated by the platform's path separator
// and at least one of the strings is an existing directory, then that's enough proof for us.
@@ -459,11 +466,7 @@ bool EnvironmentWidget::currentEntryIsPathList(const QModelIndex &current) const
.split(Utils::HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts);
if (entries.length() < 2)
return false;
for (const QString &potentialDir : entries) {
if (QFileInfo(potentialDir).isDir())
return true;
}
return false;
return Utils::anyOf(entries, [](const QString &d) { return QFileInfo(d).isDir(); });
}
void EnvironmentWidget::updateButtons()

View File

@@ -388,10 +388,8 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
// QTimer::singleShot only posts directly onto the event loop if you use the SLOT("...")
// notation, so using a singleShot with a lambda would flicker
// QTimer::singleShot(0, this, [this, filePath]() { setCrumblePath(filePath); });
QMetaObject::invokeMethod(this,
"setCrumblePath",
Qt::QueuedConnection,
Q_ARG(Utils::FilePath, filePath));
QMetaObject::invokeMethod(this, [this, filePath] { setCrumblePath(filePath); },
Qt::QueuedConnection);
});
connect(m_crumbLabel, &Utils::FileCrumbLabel::pathClicked, [this](const Utils::FilePath &path) {
const QModelIndex rootIndex = m_sortProxyModel->mapToSource(m_listView->rootIndex());

View File

@@ -92,7 +92,6 @@ public:
signals:
void renamed(const Utils::FilePath &oldName, const Utils::FilePath &newName);
void requestExpansion(const QModelIndex &index);
private:
bool m_filterProjects = false;

View File

@@ -221,6 +221,11 @@ QWidget *RunConfiguration::createConfigurationWidget()
return detailsWidget;
}
bool RunConfiguration::isConfigured() const
{
return !Utils::anyOf(checkForIssues(), [](const Task &t) { return t.type == Task::Error; });
}
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
{
theAspectFactories.push_back(aspectFactory);

View File

@@ -134,7 +134,7 @@ public:
QWidget *createConfigurationWidget();
bool isConfigured() const { return checkForIssues().isEmpty(); }
bool isConfigured() const;
virtual Tasks checkForIssues() const { return {}; }
using CommandLineGetter = std::function<Utils::CommandLine()>;

View File

@@ -138,10 +138,10 @@ SessionDialog::SessionDialog(QWidget *parent) : QDialog(parent)
m_ui.sessionView, &SessionView::switchToCurrentSession);
connect(m_ui.btRename, &QAbstractButton::clicked,
m_ui.sessionView, &SessionView::renameCurrentSession);
connect(m_ui.sessionView, &SessionView::activated,
connect(m_ui.sessionView, &SessionView::sessionActivated,
m_ui.sessionView, &SessionView::switchToCurrentSession);
connect(m_ui.sessionView, &SessionView::selected,
connect(m_ui.sessionView, &SessionView::sessionsSelected,
this, &SessionDialog::updateActions);
connect(m_ui.sessionView, &SessionView::sessionSwitched,
this, &QDialog::reject);

View File

@@ -77,10 +77,10 @@ SessionView::SessionView(QWidget *parent)
SelectCurrent);
connect(this, &Utils::TreeView::activated, [this](const QModelIndex &index){
emit activated(m_sessionModel.sessionAt(index.row()));
emit sessionActivated(m_sessionModel.sessionAt(index.row()));
});
connect(selectionModel(), &QItemSelectionModel::selectionChanged, [this] {
emit selected(selectedSessions());
emit sessionsSelected(selectedSessions());
});
connect(&m_sessionModel, &SessionModel::sessionSwitched,

View File

@@ -52,8 +52,8 @@ public:
void selectSession(const QString &sessionName);
signals:
void activated(const QString &session);
void selected(const QStringList &sessions);
void sessionActivated(const QString &session);
void sessionsSelected(const QStringList &sessions);
void sessionSwitched();
private:

View File

@@ -197,7 +197,7 @@ static FilePath detectPython(const FilePath &documentPath)
python = PythonSettings::defaultInterpreter().command;
if (!python.exists() && !PythonSettings::interpreters().isEmpty())
python = PythonSettings::interpreters().first().command;
python = PythonSettings::interpreters().constFirst().command;
return python;
}

View File

@@ -39,14 +39,22 @@ ClassDefinition::ClassDefinition(QWidget *parent) :
m_ui.iconPathChooser->setHistoryCompleter(QLatin1String("Qmake.Icon.History"));
m_ui.iconPathChooser->setPromptDialogTitle(tr("Select Icon"));
m_ui.iconPathChooser->setPromptDialogFilter(tr("Icon files (*.png *.ico *.jpg *.xpm *.tif *.svg)"));
connect(m_ui.libraryRadio, &QRadioButton::toggled, this, &ClassDefinition::enableButtons);
connect(m_ui.skeletonCheck, &QCheckBox::toggled, this, &ClassDefinition::enableButtons);
connect(m_ui.widgetLibraryEdit, &QLineEdit::textChanged,
this, &ClassDefinition::widgetLibraryChanged);
connect(m_ui.widgetHeaderEdit, &QLineEdit::textChanged,
this, &ClassDefinition::widgetHeaderChanged);
connect(m_ui.pluginClassEdit, &QLineEdit::textChanged,
this, &ClassDefinition::pluginClassChanged);
connect(m_ui.pluginHeaderEdit, &QLineEdit::textChanged,
this, &ClassDefinition::pluginHeaderChanged);
connect(m_ui.domXmlEdit, &QTextEdit::textChanged,
this, [this] { m_domXmlChanged = true; });
}
void ClassDefinition::enableButtons()
{
on_libraryRadio_toggled();
}
void ClassDefinition::on_libraryRadio_toggled()
{
const bool enLib = m_ui.libraryRadio->isChecked();
m_ui.widgetLibraryLabel->setEnabled(enLib);
@@ -66,11 +74,6 @@ void ClassDefinition::on_libraryRadio_toggled()
(m_ui.libraryRadio->isChecked() ? QLatin1String(".pro") : QLatin1String(".pri")));
}
void ClassDefinition::on_skeletonCheck_toggled()
{
on_libraryRadio_toggled();
}
static inline QString xmlFromClassName(const QString &name)
{
QString rc = QLatin1String("<widget class=\"");
@@ -96,31 +99,25 @@ void ClassDefinition::setClassName(const QString &name)
}
}
void ClassDefinition::on_widgetLibraryEdit_textChanged()
void ClassDefinition::widgetLibraryChanged(const QString &text)
{
m_ui.widgetProjectEdit->setText(
m_ui.widgetLibraryEdit->text() +
m_ui.widgetProjectEdit->setText(text +
(m_ui.libraryRadio->isChecked() ? QLatin1String(".pro") : QLatin1String(".pri")));
}
void ClassDefinition::on_widgetHeaderEdit_textChanged()
void ClassDefinition::widgetHeaderChanged(const QString &text)
{
m_ui.widgetSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(m_ui.widgetHeaderEdit->text()));
m_ui.widgetSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text));
}
void ClassDefinition::on_pluginClassEdit_textChanged()
void ClassDefinition::pluginClassChanged(const QString &text)
{
m_ui.pluginHeaderEdit->setText(m_fileNamingParameters.headerFileName(m_ui.pluginClassEdit->text()));
m_ui.pluginHeaderEdit->setText(m_fileNamingParameters.headerFileName(text));
}
void ClassDefinition::on_pluginHeaderEdit_textChanged()
void ClassDefinition::pluginHeaderChanged(const QString &text)
{
m_ui.pluginSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(m_ui.pluginHeaderEdit->text()));
}
void ClassDefinition::on_domXmlEdit_textChanged()
{
m_domXmlChanged = true;
m_ui.pluginSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text));
}
PluginOptions::WidgetOptions ClassDefinition::widgetOptions(const QString &className) const

View File

@@ -50,13 +50,10 @@ public:
void enableButtons();
private Q_SLOTS:
void on_libraryRadio_toggled();
void on_skeletonCheck_toggled();
void on_widgetLibraryEdit_textChanged();
void on_widgetHeaderEdit_textChanged();
void on_pluginClassEdit_textChanged();
void on_pluginHeaderEdit_textChanged();
void on_domXmlEdit_textChanged();
void widgetLibraryChanged(const QString &text);
void widgetHeaderChanged(const QString &text);
void pluginClassChanged(const QString &text);
void pluginHeaderChanged(const QString &text);
private:
Ui::ClassDefinition m_ui;

View File

@@ -60,6 +60,12 @@ CustomWidgetWidgetsWizardPage::CustomWidgetWidgetsWizardPage(QWidget *parent) :
connect(m_ui->classList, &ClassList::currentRowChanged,
this, &CustomWidgetWidgetsWizardPage::slotCurrentRowChanged);
connect(m_ui->classList, &ClassList::classAdded,
this, &CustomWidgetWidgetsWizardPage::slotClassAdded);
connect(m_ui->classList, &ClassList::classDeleted,
this, &CustomWidgetWidgetsWizardPage::slotClassDeleted);
connect(m_ui->classList, &ClassList::classRenamed,
this, &CustomWidgetWidgetsWizardPage::slotClassRenamed);
setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Custom Widgets"));
}
@@ -87,7 +93,7 @@ void CustomWidgetWidgetsWizardPage::slotCurrentRowChanged(int row)
m_tabStackLayout->setCurrentIndex(row);
}
void CustomWidgetWidgetsWizardPage::on_classList_classAdded(const QString &name)
void CustomWidgetWidgetsWizardPage::slotClassAdded(const QString &name)
{
auto *cdef = new ClassDefinition;
cdef->setFileNamingParameters(m_fileNamingParameters);
@@ -96,12 +102,12 @@ void CustomWidgetWidgetsWizardPage::on_classList_classAdded(const QString &name)
m_tabStackLayout->setCurrentIndex(index);
m_uiClassDefs.append(cdef);
cdef->enableButtons();
on_classList_classRenamed(index, name);
slotClassRenamed(index, name);
// First class or collection class, re-check.
slotCheckCompleteness();
}
void CustomWidgetWidgetsWizardPage::on_classList_classDeleted(int index)
void CustomWidgetWidgetsWizardPage::slotClassDeleted(int index)
{
delete m_tabStackLayout->widget(index);
m_uiClassDefs.removeAt(index);
@@ -109,7 +115,7 @@ void CustomWidgetWidgetsWizardPage::on_classList_classDeleted(int index)
slotCheckCompleteness();
}
void CustomWidgetWidgetsWizardPage::on_classList_classRenamed(int index, const QString &name)
void CustomWidgetWidgetsWizardPage::slotClassRenamed(int index, const QString &name)
{
m_uiClassDefs[index]->setClassName(name);
}

View File

@@ -64,9 +64,9 @@ public:
void initializePage() override;
private Q_SLOTS:
void on_classList_classAdded(const QString &name);
void on_classList_classDeleted(int index);
void on_classList_classRenamed(int index, const QString &newName);
void slotClassAdded(const QString &name);
void slotClassDeleted(int index);
void slotClassRenamed(int index, const QString &newName);
void slotCheckCompleteness();
void slotCurrentRowChanged(int);

View File

@@ -344,7 +344,7 @@ void LibraryDetailsController::slotMacLibraryTypeChanged()
&& libraryDetailsWidget()->frameworkRadio->isChecked()) {
setIgnoreGuiSignals(true);
libraryDetailsWidget()->dynamicRadio->setChecked(true);
setIgnoreGuiSignals(true);
setIgnoreGuiSignals(false);
}
updateGui();
@@ -685,7 +685,7 @@ void NonInternalLibraryDetailsController::slotLinkageTypeChanged()
&& libraryDetailsWidget()->staticRadio->isChecked()) {
setIgnoreGuiSignals(true);
libraryDetailsWidget()->libraryRadio->setChecked(true);
setIgnoreGuiSignals(true);
setIgnoreGuiSignals(false);
}
updateGui();

View File

@@ -208,6 +208,7 @@ extend_qtc_plugin(QmlDesigner
modelnodecontextmenu_helper.cpp modelnodecontextmenu_helper.h
modelnodeoperations.cpp modelnodeoperations.h
navigation2d.cpp navigation2d.h
gestures.cpp gestures.h
qmldesignericonprovider.cpp qmldesignericonprovider.h
selectioncontext.cpp selectioncontext.h
theme.cpp theme.h
@@ -508,6 +509,7 @@ extend_qtc_plugin(QmlDesigner
include/variantproperty.h
include/viewmanager.h
include/imagecache.h
include/imagecacheinterface.h
)
extend_qtc_plugin(QmlDesigner

View File

@@ -49,9 +49,6 @@ public:
void setCustomId(const QString &customId);
QString customId() const;
signals:
void accepted();
private slots:
void acceptedClicked();
void tabChanged(int index);

View File

@@ -49,9 +49,6 @@ public:
void setStatus(GlobalAnnotationStatus status);
GlobalAnnotationStatus globalStatus() const;
signals:
void accepted();
private slots:
void acceptedClicked();
void tabChanged(int index);

View File

@@ -279,10 +279,9 @@ void ActionEditor::prepareConnections()
}
// States
for (const QmlModelState &state : QmlItemNode(m_modelNode).states().allStates())
for (const QmlModelState &state : QmlItemNode(m_modelNode.view()->rootModelNode()).states().allStates())
states.append(state.name());
if (!connections.isEmpty() && !m_dialog.isNull())
m_dialog->setAllConnections(connections, singletons, states);
}

View File

@@ -271,9 +271,7 @@ void BindingEditor::prepareBindings()
}
if (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
updateWindowName();
m_dialog->setAllBindings(bindings, m_backendValueTypeName);
}
void BindingEditor::updateWindowName()

View File

@@ -37,6 +37,7 @@
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPlainTextEdit>
namespace QmlDesigner {
@@ -50,6 +51,8 @@ BindingEditorDialog::BindingEditorDialog(QWidget *parent)
this, &BindingEditorDialog::itemIDChanged);
QObject::connect(m_comboBoxProperty, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &BindingEditorDialog::propertyIDChanged);
QObject::connect(m_checkBoxNot, QOverload<int>::of(&QCheckBox::stateChanged),
this, &BindingEditorDialog::checkBoxChanged);
}
BindingEditorDialog::~BindingEditorDialog()
@@ -58,7 +61,12 @@ BindingEditorDialog::~BindingEditorDialog()
void BindingEditorDialog::adjustProperties()
{
const QString expression = editorValue();
QString expression = editorValue().trimmed();
m_checkBoxNot->setChecked(expression.startsWith("!"));
if (m_checkBoxNot->isChecked())
expression.remove(0, 1);
QString item;
QString property;
QStringList expressionElements = expression.split(".");
@@ -94,12 +102,14 @@ void BindingEditorDialog::adjustProperties()
m_comboBoxProperty->setCurrentText(property);
}
void BindingEditorDialog::setAllBindings(QList<BindingOption> bindings)
void BindingEditorDialog::setAllBindings(const QList<BindingOption> &bindings, const TypeName &type)
{
m_lock = true;
m_bindings = bindings;
m_type = type;
setupComboBoxes();
setupCheckBox();
adjustProperties();
m_lock = false;
@@ -109,11 +119,15 @@ void BindingEditorDialog::setupUIComponents()
{
m_comboBoxItem = new QComboBox(this);
m_comboBoxProperty = new QComboBox(this);
m_checkBoxNot = new QCheckBox(this);
m_checkBoxNot->setText(tr("NOT"));
m_checkBoxNot->setVisible(false);
m_checkBoxNot->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
m_checkBoxNot->setToolTip(tr("Invert the boolean expression."));
m_comboBoxLayout->addWidget(m_comboBoxItem);
m_comboBoxLayout->addWidget(m_comboBoxProperty);
//this->resize(660, 240);
m_comboBoxLayout->addWidget(m_checkBoxNot);
}
void BindingEditorDialog::setupComboBoxes()
@@ -125,6 +139,12 @@ void BindingEditorDialog::setupComboBoxes()
m_comboBoxItem->addItem(bind.item);
}
void BindingEditorDialog::setupCheckBox()
{
const bool visible = (m_type == "bool");
m_checkBoxNot->setVisible(visible);
}
void BindingEditorDialog::itemIDChanged(int itemID)
{
const QString previousProperty = m_comboBoxProperty->currentText();
@@ -148,12 +168,31 @@ void BindingEditorDialog::propertyIDChanged(int propertyID)
const int itemID = m_comboBoxItem->currentIndex();
if (!m_lock)
if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString))
setEditorValue(m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID));
if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString)) {
QString expression = m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID);
if (m_checkBoxNot->isChecked())
expression.prepend("!");
setEditorValue(expression);
}
const int undefinedProperty = m_comboBoxProperty->findText(undefinedString);
if ((undefinedProperty != -1) && (m_comboBoxProperty->itemText(propertyID) != undefinedString))
m_comboBoxProperty->removeItem(undefinedProperty);
}
void BindingEditorDialog::checkBoxChanged(int state)
{
if (m_lock)
return;
QString expression = editorValue().trimmed();
if (state == Qt::Checked)
expression.prepend("!");
else
expression.remove(0, 1);
setEditorValue(expression);
}
} // QmlDesigner namespace

View File

@@ -30,6 +30,7 @@
QT_BEGIN_NAMESPACE
class QComboBox;
class QCheckBox;
QT_END_NAMESPACE
namespace QmlDesigner {
@@ -56,21 +57,25 @@ public:
void adjustProperties() override;
void setAllBindings(QList<BindingOption> bindings);
void setAllBindings(const QList<BindingOption> &bindings, const TypeName &type);
private:
void setupUIComponents();
void setupComboBoxes();
void setupCheckBox();
public slots:
void itemIDChanged(int);
void propertyIDChanged(int);
void checkBoxChanged(int);
private:
QComboBox *m_comboBoxItem = nullptr;
QComboBox *m_comboBoxProperty = nullptr;
QCheckBox *m_checkBoxNot = nullptr;
QList<BindingOption> m_bindings;
TypeName m_type;
};
}

View File

@@ -79,11 +79,6 @@ DefaultAction::DefaultAction(const QString &description)
connect(this, &QAction::triggered, this, &DefaultAction::actionTriggered);
}
void DefaultAction::actionTriggered(bool enable)
{
emit triggered(enable, m_selectionContext);
}
void DefaultAction::setSelectionContext(const SelectionContext &selectionContext)
{
m_selectionContext = selectionContext;

View File

@@ -40,12 +40,9 @@ public:
DefaultAction(const QString &description);
// virtual function instead of slot
virtual void actionTriggered(bool enable);
virtual void actionTriggered(bool enable) { Q_UNUSED(enable) }
void setSelectionContext(const SelectionContext &selectionContext);
signals:
void triggered(bool checked, const SelectionContext &selectionContext);
protected:
SelectionContext m_selectionContext;
};

View File

@@ -5,6 +5,7 @@ SOURCES += addimagesdialog.cpp
SOURCES += changestyleaction.cpp
SOURCES += theme.cpp
SOURCES += findimplementation.cpp
SOURCES += gestures.cpp
SOURCES += addsignalhandlerdialog.cpp
SOURCES += layoutingridlayout.cpp
SOURCES += abstractactiongroup.cpp
@@ -24,6 +25,7 @@ HEADERS += addimagesdialog.h
HEADERS += changestyleaction.h
HEADERS += theme.h
HEADERS += findimplementation.h
HEADERS += gestures.h
HEADERS += addsignalhandlerdialog.h
HEADERS += layoutingridlayout.h
HEADERS += abstractactiongroup.h

View File

@@ -0,0 +1,156 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Design Tooling
**
** 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 "gestures.h"
#include <QWidget>
namespace QmlDesigner {
Qt::GestureType TwoFingerSwipe::m_type = static_cast<Qt::GestureType>(0);
TwoFingerSwipe::TwoFingerSwipe() {}
Qt::GestureType TwoFingerSwipe::type()
{
return m_type;
}
void TwoFingerSwipe::registerRecognizer()
{
m_type = QGestureRecognizer::registerRecognizer(new TwoFingerSwipeRecognizer());
}
QPointF TwoFingerSwipe::direction() const
{
return m_current.center() - m_last.center();
}
void TwoFingerSwipe::reset()
{
m_start = QLineF();
m_current = QLineF();
m_last = QLineF();
}
QGestureRecognizer::Result TwoFingerSwipe::begin(QTouchEvent *event)
{
Q_UNUSED(event);
return QGestureRecognizer::MayBeGesture;
}
QGestureRecognizer::Result TwoFingerSwipe::update(QTouchEvent *event)
{
if (event->touchPoints().size() != 2) {
if (state() == Qt::NoGesture)
return QGestureRecognizer::Ignore;
else
return QGestureRecognizer::FinishGesture;
}
QTouchEvent::TouchPoint p0 = event->touchPoints().at(0);
QTouchEvent::TouchPoint p1 = event->touchPoints().at(1);
QLineF line(p0.scenePos(), p1.screenPos());
if (m_start.isNull()) {
m_start = line;
m_current = line;
m_last = line;
} else {
auto deltaLength = line.length() - m_current.length();
auto deltaCenter = QLineF(line.center(), m_current.center()).length();
if (deltaLength > deltaCenter)
return QGestureRecognizer::CancelGesture;
m_last = m_current;
m_current = line;
}
setHotSpot(m_current.center());
return QGestureRecognizer::TriggerGesture;
}
QGestureRecognizer::Result TwoFingerSwipe::end(QTouchEvent *event)
{
Q_UNUSED(event);
bool finish = state() != Qt::NoGesture;
reset();
if (finish)
return QGestureRecognizer::FinishGesture;
else
return QGestureRecognizer::CancelGesture;
}
TwoFingerSwipeRecognizer::TwoFingerSwipeRecognizer()
: QGestureRecognizer()
{}
QGesture *TwoFingerSwipeRecognizer::create(QObject *target)
{
if (target && target->isWidgetType())
qobject_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
return new TwoFingerSwipe;
}
QGestureRecognizer::Result TwoFingerSwipeRecognizer::recognize(QGesture *gesture,
QObject *,
QEvent *event)
{
if (gesture->gestureType() != TwoFingerSwipe::type())
return QGestureRecognizer::Ignore;
TwoFingerSwipe *swipe = static_cast<TwoFingerSwipe *>(gesture);
QTouchEvent *touch = static_cast<QTouchEvent *>(event);
switch (event->type()) {
case QEvent::TouchBegin:
return swipe->begin(touch);
case QEvent::TouchUpdate:
return swipe->update(touch);
case QEvent::TouchEnd:
return swipe->end(touch);
default:
return QGestureRecognizer::Ignore;
}
}
void TwoFingerSwipeRecognizer::reset(QGesture *gesture)
{
if (gesture->gestureType() == TwoFingerSwipe::type()) {
TwoFingerSwipe *swipe = static_cast<TwoFingerSwipe *>(gesture);
swipe->reset();
}
QGestureRecognizer::reset(gesture);
}
} // End namespace QmlDesigner.

View File

@@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Design Tooling
**
** 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 <QGesture>
#include <QGestureRecognizer>
#include <QLineF>
QT_FORWARD_DECLARE_CLASS(QTouchEvent)
namespace QmlDesigner {
class TwoFingerSwipe : public QGesture
{
Q_OBJECT
public:
TwoFingerSwipe();
static Qt::GestureType type();
static void registerRecognizer();
QPointF direction() const;
void reset();
QGestureRecognizer::Result begin(QTouchEvent *event);
QGestureRecognizer::Result update(QTouchEvent *event);
QGestureRecognizer::Result end(QTouchEvent *event);
private:
static Qt::GestureType m_type;
QLineF m_start;
QLineF m_current;
QLineF m_last;
};
class TwoFingerSwipeRecognizer : public QGestureRecognizer
{
public:
TwoFingerSwipeRecognizer();
QGesture *create(QObject *target) override;
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
void reset(QGesture *gesture) override;
};
} // namespace QmlDesigner

View File

@@ -1413,7 +1413,7 @@ QString getTemplateDialog(const Utils::FilePath &projectPath)
dialog->exec();
if (!result.isEmpty() && !QFileInfo(result).exists()) {
if (!result.isEmpty() && !QFileInfo::exists(result)) {
result = templateFiles.at(names.indexOf(result));
result = templatesPath.pathAppended(result).toString();
}
@@ -1489,7 +1489,7 @@ void mergeWithTemplate(const SelectionContext &selectionContext)
const QString templateFile = getTemplateDialog(projectPath);
if (QFileInfo(templateFile).exists())
if (QFileInfo::exists(templateFile))
styleMerge(selectionContext, templateFile);
}

View File

@@ -23,10 +23,13 @@
**
****************************************************************************/
#include "navigation2d.h"
#include "gestures.h"
#include <QGestureEvent>
#include <QWheelEvent>
#include <cmath>
namespace QmlDesigner {
Navigation2dScrollBar::Navigation2dScrollBar(QWidget *parent)
@@ -53,39 +56,60 @@ Navigation2dFilter::Navigation2dFilter(QWidget *parent, Navigation2dScrollBar *s
: QObject(parent)
, m_scrollbar(scrollbar)
{
if (parent)
if (parent) {
parent->grabGesture(Qt::PinchGesture);
if (!scrollbar)
parent->grabGesture(TwoFingerSwipe::type());
}
}
bool Navigation2dFilter::eventFilter(QObject *, QEvent *event)
bool Navigation2dFilter::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::Gesture)
return gestureEvent(static_cast<QGestureEvent *>(event));
else if (event->type() == QEvent::Wheel && m_scrollbar)
else if (event->type() == QEvent::Wheel)
return wheelEvent(static_cast<QWheelEvent *>(event));
return QObject::event(event);
return QObject::eventFilter(object, event);
}
bool Navigation2dFilter::gestureEvent(QGestureEvent *event)
{
if (QPinchGesture *pinch = static_cast<QPinchGesture *>(event->gesture(Qt::PinchGesture))) {
QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags();
if (changeFlags & QPinchGesture::ScaleFactorChanged) {
if (changeFlags.testFlag(QPinchGesture::ScaleFactorChanged)) {
emit zoomChanged(-(1.0 - pinch->scaleFactor()), pinch->startCenterPoint());
event->accept();
return true;
}
} else if (TwoFingerSwipe *swipe = static_cast<TwoFingerSwipe *>(
event->gesture(TwoFingerSwipe::type()))) {
emit panChanged(swipe->direction());
event->accept();
return true;
}
return false;
}
bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
{
if (m_scrollbar->postEvent(event))
event->ignore();
return false;
if (m_scrollbar) {
if (m_scrollbar->postEvent(event))
event->ignore();
} else if (event->source() == Qt::MouseEventNotSynthesized) {
if (event->modifiers().testFlag(Qt::ControlModifier)) {
if (QPointF angle = event->angleDelta(); !angle.isNull()) {
double delta = std::abs(angle.x()) > std::abs(angle.y()) ? angle.x() : angle.y();
if (delta > 0)
emit zoomIn();
else
emit zoomOut();
event->accept();
return true;
}
}
}
return true;
}
} // End namespace QmlDesigner.

View File

@@ -51,6 +51,10 @@ class Navigation2dFilter : public QObject
signals:
void zoomChanged(double scale, const QPointF &pos);
void panChanged(const QPointF &direction);
void zoomIn();
void zoomOut();
public:
Navigation2dFilter(QWidget *parent = nullptr, Navigation2dScrollBar *scrollbar = nullptr);

View File

@@ -24,130 +24,135 @@
****************************************************************************/
#include "zoomaction.h"
#include "formeditorwidget.h"
#include <algorithm>
#include <iterator>
#include <utility>
#include <QComboBox>
#include <QAbstractItemView>
#include <QComboBox>
#include <QToolBar>
#include <cmath>
namespace QmlDesigner {
const int defaultZoomIndex = 13;
// Order matters!
std::array<double, 27> ZoomAction::m_zooms = {
0.01, 0.02, 0.05, 0.0625, 0.1, 0.125, 0.2, 0.25, 0.33, 0.5, 0.66, 0.75, 0.9,
1.0, 1.1, 1.25, 1.33, 1.5, 1.66, 1.75, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 16.0
};
bool isValidIndex(int index)
{
if (index >= 0 && index < static_cast<int>(ZoomAction::zoomLevels().size()))
return true;
return false;
}
ZoomAction::ZoomAction(QObject *parent)
: QWidgetAction(parent),
m_zoomLevel(1.0),
m_currentComboBoxIndex(defaultZoomIndex)
{
: QWidgetAction(parent)
, m_combo(nullptr)
{}
std::array<double, 27> ZoomAction::zoomLevels()
{
return m_zooms;
}
float ZoomAction::zoomLevel() const
int ZoomAction::indexOf(double zoom)
{
return m_zoomLevel;
}
auto finder = [zoom](double val) { return qFuzzyCompare(val, zoom); };
if (auto iter = std::find_if(m_zooms.begin(), m_zooms.end(), finder); iter != m_zooms.end())
return static_cast<int>(std::distance(m_zooms.begin(), iter));
void ZoomAction::zoomIn()
{
if (m_currentComboBoxIndex < (m_comboBoxModel->rowCount() - 1))
emit indexChanged(m_currentComboBoxIndex + 1);
}
void ZoomAction::zoomOut()
{
if (m_currentComboBoxIndex > 0)
emit indexChanged(m_currentComboBoxIndex - 1);
}
void ZoomAction::resetZoomLevel()
{
m_zoomLevel = 1.0;
m_currentComboBoxIndex = defaultZoomIndex;
emit reseted();
}
void ZoomAction::setZoomLevel(float zoomLevel)
{
if (qFuzzyCompare(m_zoomLevel, zoomLevel))
return;
forceZoomLevel(zoomLevel);
}
void ZoomAction::forceZoomLevel(float zoomLevel)
{
m_zoomLevel = qBound(0.01f, zoomLevel, 16.0f);
emit zoomLevelChanged(m_zoomLevel);
}
//initial m_zoomLevel and m_currentComboBoxIndex
const QVector<float> s_zoomFactors = {0.01f, 0.02f, 0.05f, 0.0625f, 0.1f, 0.125f, 0.2f, 0.25f,
0.33f, 0.5f, 0.66f, 0.75f, 0.9f, 1.0f, 1.1f, 1.25f, 1.33f,
1.5f, 1.66f, 1.75f, 2.0f, 3.0f, 4.0f, 6.0f, 8.0f, 10.0f, 16.0f };
int getZoomIndex(float zoom)
{
for (int i = 0; i < s_zoomFactors.length(); i++) {
if (qFuzzyCompare(s_zoomFactors.at(i), zoom))
return i;
}
return -1;
}
float ZoomAction::getClosestZoomLevel(float zoomLevel)
void ZoomAction::setZoomFactor(double zoom)
{
int i = 0;
while (i < s_zoomFactors.size() && s_zoomFactors[i] < zoomLevel)
++i;
if (int index = indexOf(zoom); index >= 0) {
m_combo->setCurrentIndex(index);
m_combo->setToolTip(m_combo->currentText());
return;
}
int rounded = static_cast<int>(std::round(zoom * 100));
m_combo->setEditable(true);
m_combo->setEditText(QString::number(rounded) + " %");
m_combo->setToolTip(m_combo->currentText());
}
return s_zoomFactors[qBound(0, i - 1, s_zoomFactors.size() - 1)];
double ZoomAction::setNextZoomFactor(double zoom)
{
if (zoom >= m_zooms.back())
return zoom;
auto greater = [zoom](double val) { return val > zoom; };
if (auto iter = std::find_if(m_zooms.begin(), m_zooms.end(), greater); iter != m_zooms.end()) {
auto index = std::distance(m_zooms.begin(), iter);
m_combo->setCurrentIndex(static_cast<int>(index));
m_combo->setToolTip(m_combo->currentText());
return *iter;
}
return zoom;
}
double ZoomAction::setPreviousZoomFactor(double zoom)
{
if (zoom <= m_zooms.front())
return zoom;
auto smaller = [zoom](double val) { return val < zoom; };
if (auto iter = std::find_if(m_zooms.rbegin(), m_zooms.rend(), smaller); iter != m_zooms.rend()) {
auto index = std::distance(iter, m_zooms.rend() - 1);
m_combo->setCurrentIndex(static_cast<int>(index));
m_combo->setToolTip(m_combo->currentText());
return *iter;
}
return zoom;
}
bool parentIsFormEditor(QWidget *parent)
{
while (parent) {
if (qobject_cast<FormEditorWidget *>(parent))
return true;
parent = qobject_cast<QWidget *>(parent->parent());
}
return false;
}
QComboBox *createZoomComboBox(QWidget *parent)
{
auto *combo = new QComboBox(parent);
for (double z : ZoomAction::zoomLevels()) {
const QString name = QString::number(z * 100., 'g', 4) + " %";
combo->addItem(name, z);
}
return combo;
}
QWidget *ZoomAction::createWidget(QWidget *parent)
{
auto comboBox = new QComboBox(parent);
if (!m_combo && parentIsFormEditor(parent)) {
m_combo = createZoomComboBox(parent);
m_combo->setProperty("hideborder", true);
m_combo->setCurrentIndex(indexOf(1.0));
m_combo->setToolTip(m_combo->currentText());
/*
* When add zoom levels do not forget to update defaultZoomIndex
*/
if (m_comboBoxModel.isNull()) {
m_comboBoxModel = comboBox->model();
for (float z : s_zoomFactors) {
const QString name = QString::number(z * 100, 'g', 4) + " %";
comboBox->addItem(name, z);
}
} else {
comboBox->setModel(m_comboBoxModel.data());
auto currentChanged = QOverload<int>::of(&QComboBox::currentIndexChanged);
connect(m_combo, currentChanged, this, &ZoomAction::emitZoomLevelChanged);
return m_combo.data();
}
return nullptr;
}
comboBox->setCurrentIndex(m_currentComboBoxIndex);
comboBox->setToolTip(comboBox->currentText());
connect(this, &ZoomAction::reseted, comboBox, [this, comboBox]() {
blockSignals(true);
comboBox->setCurrentIndex(m_currentComboBoxIndex);
blockSignals(false);
});
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
[this, comboBox](int index) {
m_currentComboBoxIndex = index;
if (index == -1)
return;
const QModelIndex modelIndex(m_comboBoxModel.data()->index(index, 0));
setZoomLevel(m_comboBoxModel.data()->data(modelIndex, Qt::UserRole).toFloat());
comboBox->setToolTip(modelIndex.data().toString());
});
connect(this, &ZoomAction::indexChanged, comboBox, &QComboBox::setCurrentIndex);
connect(this, &ZoomAction::zoomLevelChanged, comboBox, [comboBox](double zoom){
const int index = getZoomIndex(zoom);
if (comboBox->currentIndex() != index)
comboBox->setCurrentIndex(index);
});
comboBox->setProperty("hideborder", true);
comboBox->setMaximumWidth(qMax(comboBox->view()->sizeHintForColumn(0) / 2, 16));
return comboBox;
void ZoomAction::emitZoomLevelChanged(int index)
{
if (index >= 0 && index < static_cast<int>(m_zooms.size()))
emit zoomLevelChanged(m_zooms[static_cast<size_t>(index)]);
}
} // namespace QmlDesigner

View File

@@ -26,11 +26,13 @@
#include <qmldesignercorelib_global.h>
#include <QWidgetAction>
#include <QPointer>
#include <QWidgetAction>
#include <array>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
class QComboBox;
QT_END_NAMESPACE
namespace QmlDesigner {
@@ -39,30 +41,27 @@ class QMLDESIGNERCORE_EXPORT ZoomAction : public QWidgetAction
{
Q_OBJECT
signals:
void zoomLevelChanged(double zoom);
public:
ZoomAction(QObject *parent);
float zoomLevel() const;
static std::array<double, 27> zoomLevels();
static int indexOf(double zoom);
void zoomIn();
void zoomOut();
void resetZoomLevel();
void setZoomLevel(float zoomLevel);
void forceZoomLevel(float zoomLevel);
static float getClosestZoomLevel(float zoomLevel);
void setZoomFactor(double zoom);
double setNextZoomFactor(double zoom);
double setPreviousZoomFactor(double zoom);
protected:
QWidget *createWidget(QWidget *parent) override;
signals:
void zoomLevelChanged(float zoom);
void indexChanged(int);
void reseted();
private:
QPointer<QAbstractItemModel> m_comboBoxModel;
float m_zoomLevel;
int m_currentComboBoxIndex;
void emitZoomLevelChanged(int index);
static std::array<double, 27> m_zooms;
QPointer<QComboBox> m_combo;
};
} // namespace QmlDesigner

View File

@@ -142,9 +142,9 @@ void ConnectionViewWidget::setConnectionModel(ConnectionModel *model)
void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
{
auto tablePos = [&](QTableView *targetView) {
//adjusting qpoint to the qtableview entrances:
// adjusting qpoint to the qtableview entrances:
QPoint posInTable(targetView->mapFromGlobal(mapToGlobal(event->pos())));
posInTable = QPoint(posInTable.x(), posInTable.y() - targetView->horizontalHeader()->height());
posInTable.ry() -= targetView->horizontalHeader()->height();
return posInTable;
};
@@ -152,24 +152,24 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
case ConnectionTab:
if (ui->connectionView != nullptr) {
QTableView *targetView = ui->connectionView;
//making sure that we have source column in our hands:
QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(ConnectionModel::SourceRow);
// making sure that we have source column in our hands:
const QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(ConnectionModel::SourceRow);
if (!index.isValid())
return;
QMenu menu(this);
menu.addAction(tr("Open Connection Editor"), [&]() {
if (index.isValid()) {
auto *connectionModel = qobject_cast<ConnectionModel *>(targetView->model());
ModelNode node = connectionModel->connectionView()->rootModelNode();
m_connectionEditor->showWidget();
m_connectionEditor->setConnectionValue(index.data().toString());
m_connectionEditor->setModelIndex(index);
m_connectionEditor->setModelNode(node);
m_connectionEditor->prepareConnections();
m_connectionEditor->updateWindowName();
}
auto *connectionModel = qobject_cast<ConnectionModel *>(targetView->model());
const SignalHandlerProperty property = connectionModel->signalHandlerPropertyForRow(index.row());
const ModelNode node = property.parentModelNode();
m_connectionEditor->showWidget();
m_connectionEditor->setConnectionValue(index.data().toString());
m_connectionEditor->setModelIndex(index);
m_connectionEditor->setModelNode(node);
m_connectionEditor->prepareConnections();
m_connectionEditor->updateWindowName();
});
menu.exec(event->globalPos());
@@ -179,37 +179,31 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
case BindingTab:
if (ui->bindingView != nullptr) {
QTableView *targetView = bindingTableView();
QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(BindingModel::SourcePropertyNameRow);
const QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(BindingModel::SourcePropertyNameRow);
if (!index.isValid())
return;
QMenu menu(this);
menu.addAction(tr("Open Binding Editor"), [&]() {
if (index.isValid()) {
BindingModel *binModel = qobject_cast<BindingModel*>(targetView->model());
ModelNode node = binModel->connectionView()->rootModelNode();
BindingModel *bindingModel = qobject_cast<BindingModel*>(targetView->model());
const BindingProperty property = bindingModel->bindingPropertyForRow(index.row());
BindingProperty property = binModel->bindingPropertyForRow(index.row());
if (!property.isValid() || !property.isBindingProperty())
return;
if (property.isValid()) {
if (property.isBindingProperty()) {
m_bindingEditor->showWidget();
m_bindingEditor->setBindingValue(property.expression());
m_bindingEditor->setModelNode(node);
if (property.isDynamic()) {
m_bindingEditor->setBackendValueTypeName(property.dynamicTypeName());
}
else {
m_bindingEditor->setBackendValueTypeName(node.metaInfo().propertyTypeName(property.name()));
}
m_bindingEditor->prepareBindings();
m_bindingEditor->updateWindowName();
const ModelNode node = property.parentModelNode();
const TypeName typeName = property.isDynamic() ? property.dynamicTypeName()
: node.metaInfo().propertyTypeName(property.name());
m_bindingIndex = index;
}
}
}
m_bindingEditor->showWidget();
m_bindingEditor->setBindingValue(property.expression());
m_bindingEditor->setModelNode(node);
m_bindingEditor->setBackendValueTypeName(typeName);
m_bindingEditor->prepareBindings();
m_bindingEditor->updateWindowName();
m_bindingIndex = index;
});
menu.exec(event->globalPos());
}
@@ -218,51 +212,40 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
case DynamicPropertiesTab:
if (ui->dynamicPropertiesView != nullptr) {
QTableView *targetView = dynamicPropertiesTableView();
QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(DynamicPropertiesModel::PropertyValueRow);
const QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(DynamicPropertiesModel::PropertyValueRow);
if (!index.isValid())
return;
DynamicPropertiesModel *propertiesModel = qobject_cast<DynamicPropertiesModel *>(targetView->model());
QMenu menu(this);
menu.addAction(tr("Open Binding Editor"), [&]() {
if (index.isValid()) {
DynamicPropertiesModel *dynPropModel = qobject_cast<DynamicPropertiesModel*>(targetView->model());
ModelNode node = dynPropModel->connectionView()->rootModelNode();
AbstractProperty abstractProperty = propertiesModel->abstractPropertyForRow(index.row());
if (!abstractProperty.isValid())
return;
AbstractProperty abProp = dynPropModel->abstractPropertyForRow(index.row());
const ModelNode node = abstractProperty.parentModelNode();
QString newExpression;
QString newExpression;
if (abstractProperty.isBindingProperty())
newExpression = abstractProperty.toBindingProperty().expression();
else if (abstractProperty.isVariantProperty())
newExpression = abstractProperty.toVariantProperty().value().toString();
else
return;
if (abProp.isValid()) {
if (abProp.isBindingProperty()) {
BindingProperty property = abProp.toBindingProperty();
newExpression = property.expression();
}
else if (abProp.isVariantProperty()) {
VariantProperty property = abProp.toVariantProperty();
newExpression = property.value().toString();
}
else
return;
m_dynamicEditor->showWidget();
m_dynamicEditor->setBindingValue(newExpression);
m_dynamicEditor->setModelNode(node);
m_dynamicEditor->setBackendValueTypeName(abstractProperty.dynamicTypeName());
m_dynamicEditor->prepareBindings();
m_dynamicEditor->updateWindowName();
m_dynamicEditor->showWidget();
m_dynamicEditor->setBindingValue(newExpression);
m_dynamicEditor->setModelNode(node);
m_dynamicEditor->setBackendValueTypeName(abProp.dynamicTypeName());
m_dynamicEditor->prepareBindings();
m_dynamicEditor->updateWindowName();
m_dynamicIndex = index;
}
}
m_dynamicIndex = index;
});
menu.addAction(tr("Reset Property"), [&]() {
if (index.isValid()) {
DynamicPropertiesModel *propertiesModel = qobject_cast<DynamicPropertiesModel *>(dynamicPropertiesTableView()->model());
propertiesModel->resetProperty(propertiesModel->abstractPropertyForRow(index.row()).name());
}
propertiesModel->resetProperty(propertiesModel->abstractPropertyForRow(index.row()).name());
});
menu.exec(event->globalPos());

View File

@@ -280,6 +280,7 @@ void DynamicPropertiesModel::bindingRemoved(const BindingProperty &bindingProper
void DynamicPropertiesModel::selectionChanged(const QList<ModelNode> &selectedNodes)
{
Q_UNUSED(selectedNodes)
m_handleDataChanged = false;
resetModel();
m_handleDataChanged = true;

View File

@@ -82,7 +82,7 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
// Register action as creator command to make it configurable
Core::Command *command = Core::ActionManager::registerAction(
action->action(), action->menuId().data(), context);
action->action(), action->menuId().constData(), context);
command->setDefaultKeySequence(action->action()->shortcut());
command->augmentActionWithShortcutToolTip(action->action());
// Clear action shortcut so it doesn't conflict with command's override action

View File

@@ -91,7 +91,7 @@ QList<QColor> BackgroundAction::colors()
static QColor alphaZero(Qt::transparent);
static QList<QColor> colorList = {alphaZero,
QColor(Qt::black),
QColor("#4c4e50"),
QColor(0x4c4e50),
QColor(Qt::darkGray),
QColor(Qt::lightGray),
QColor(Qt::white)};

View File

@@ -24,20 +24,24 @@
****************************************************************************/
#include "formeditorgraphicsview.h"
#include "formeditoritem.h"
#include "formeditorwidget.h"
#include "navigation2d.h"
#include <QWheelEvent>
#include <QScrollBar>
#include <QGraphicsItem>
#include <QGraphicsWidget>
#include <QGraphicsProxyWidget>
#include <QAction>
#include <QCoreApplication>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>
#include <QGraphicsWidget>
#include <QScrollBar>
#include <QWheelEvent>
#include <QTimer>
namespace QmlDesigner {
FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent) :
QGraphicsView(parent)
FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent)
: QGraphicsView(parent)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setResizeAnchor(QGraphicsView::AnchorViewCenter);
@@ -57,6 +61,39 @@ FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent) :
// as mousetracking only works for mouse key it is better to handle it in the
// eventFilter method so it works also for the space scrolling case as expected
QCoreApplication::instance()->installEventFilter(this);
QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this);
connect(filter, &Navigation2dFilter::zoomIn, this, &FormEditorGraphicsView::zoomIn);
connect(filter, &Navigation2dFilter::zoomOut, this, &FormEditorGraphicsView::zoomOut);
auto panChanged = &Navigation2dFilter::panChanged;
connect(filter, panChanged, [this](const QPointF &direction) {
QScrollBar *sbx = horizontalScrollBar();
QScrollBar *sby = verticalScrollBar();
// max - min + pageStep = sceneRect.size * scale
QPointF min(sbx->minimum(), sby->minimum());
QPointF max(sbx->maximum(), sby->maximum());
QPointF step(sbx->pageStep(), sby->pageStep());
QPointF d1 = max - min;
QPointF d2 = d1 + step;
QPoint val = QPointF((direction.x() / d2.x()) * d1.x(), (direction.y() / d2.y()) * d1.y())
.toPoint();
sbx->setValue(sbx->value() - val.x());
sby->setValue(sby->value() - val.y());
});
auto zoomChanged = &Navigation2dFilter::zoomChanged;
connect(filter, zoomChanged, [this](double s, const QPointF &/*pos*/) {
if (auto trans = transform() * QTransform::fromScale(1.0 + s, 1.0 + s); trans.m11() > 0) {
setTransform(trans);
emit this->zoomChanged(transform().m11());
}
});
installEventFilter(filter);
}
bool FormEditorGraphicsView::eventFilter(QObject *watched, QEvent *event)
@@ -67,7 +104,7 @@ bool FormEditorGraphicsView::eventFilter(QObject *watched, QEvent *event)
stopPanning(event);
}
if (event->type() == QEvent::MouseMove) {
auto mouseEvent = static_cast<QMouseEvent*>(event);
auto mouseEvent = static_cast<QMouseEvent *>(event);
if (!m_panningStartPosition.isNull()) {
horizontalScrollBar()->setValue(horizontalScrollBar()->value() -
(mouseEvent->x() - m_panningStartPosition.x()));
@@ -86,7 +123,7 @@ void FormEditorGraphicsView::wheelEvent(QWheelEvent *event)
{
if (event->modifiers().testFlag(Qt::ControlModifier))
event->ignore();
else
else if (event->source() == Qt::MouseEventNotSynthesized)
QGraphicsView::wheelEvent(event);
}
@@ -109,7 +146,7 @@ void FormEditorGraphicsView::mouseReleaseEvent(QMouseEvent *event)
QGraphicsView::mouseReleaseEvent(event);
}
bool isTextInputItem(QGraphicsItem* item)
bool isTextInputItem(QGraphicsItem *item)
{
if (item && item->isWidget()) {
auto graphicsWidget = static_cast<QGraphicsWidget *>(item);
@@ -128,7 +165,7 @@ void FormEditorGraphicsView::keyPressEvent(QKeyEvent *event)
{
// check for autorepeat to avoid a stoped space panning by leave event to be restarted
if (!event->isAutoRepeat() && m_isPanning == Panning::NotStarted && event->key() == Qt::Key_Space &&
!isTextInputItem(scene()->focusItem())) {
!isTextInputItem(scene()->focusItem())) {
startPanning(event);
return;
}
@@ -203,4 +240,15 @@ void FormEditorGraphicsView::drawBackground(QPainter *painter, const QRectF &rec
painter->restore();
}
void FormEditorGraphicsView::frame(const QRectF &boundingRect)
{
fitInView(boundingRect, Qt::KeepAspectRatio);
}
void FormEditorGraphicsView::setZoomFactor(double zoom)
{
resetTransform();
scale(zoom, zoom);
}
} // namespace QmlDesigner

View File

@@ -30,7 +30,13 @@ namespace QmlDesigner {
class FormEditorGraphicsView : public QGraphicsView
{
Q_OBJECT
Q_OBJECT
signals:
void zoomChanged(double zoom);
void zoomIn();
void zoomOut();
public:
explicit FormEditorGraphicsView(QWidget *parent = nullptr);
@@ -41,6 +47,9 @@ public:
void activateColoredBackground(const QColor &color);
void drawBackground(QPainter *painter, const QRectF &rect) override;
void setZoomFactor(double zoom);
void frame(const QRectF &bbox);
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
@@ -48,13 +57,13 @@ protected:
void mouseReleaseEvent(QMouseEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void keyReleaseEvent(QKeyEvent *event) override;
private:
enum Panning{
NotStarted, MouseWheelStarted, SpaceKeyStarted
};
enum Panning { NotStarted, MouseWheelStarted, SpaceKeyStarted };
void startPanning(QEvent *event);
void stopPanning(QEvent *event);
Panning m_isPanning = Panning::NotStarted;
QPoint m_panningStartPosition;
QRectF m_rootItemRect;

View File

@@ -679,7 +679,7 @@ void FormEditorFlowActionItem::paint(QPainter *painter, const QStyleOptionGraphi
pen.setJoinStyle(Qt::MiterJoin);
pen.setCosmetic(true);
QColor flowColor = "#e71919";
QColor flowColor(0xe71919);
if (qmlItemNode().rootModelNode().hasAuxiliaryData("areaColor"))
flowColor = qmlItemNode().rootModelNode().auxiliaryData("areaColor").value<QColor>();
@@ -857,7 +857,7 @@ public:
bool hitTest = false)
: width(2)
, adjustedWidth(width / scaleFactor)
, color(QColor("#e71919"))
, color(QColor(0xe71919))
, lineBrush(QBrush(color))
, penStyle(Qt::SolidLine)
, dashPattern()
@@ -1776,7 +1776,7 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
pen.setJoinStyle(Qt::MiterJoin);
pen.setCosmetic(true);
QColor flowColor = "#e71919";
QColor flowColor(0xe71919);
if (qmlItemNode().rootModelNode().hasAuxiliaryData("blockColor"))
flowColor = qmlItemNode().rootModelNode().auxiliaryData("blockColor").value<QColor>();

Some files were not shown because too many files have changed in this diff Show More