forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.14'
Change-Id: Iea84f23cf394de13e99a9ed777c8c113e4eff473
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -174,7 +174,7 @@ AutotestPluginPrivate::AutotestPluginPrivate()
|
||||
AutotestPluginPrivate::~AutotestPluginPrivate()
|
||||
{
|
||||
if (!s_projectSettings.isEmpty()) {
|
||||
qDeleteAll(s_projectSettings.values());
|
||||
qDeleteAll(s_projectSettings);
|
||||
s_projectSettings.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="matchCase">
|
||||
<property name="text">
|
||||
<string>Case sensiti&ve</string>
|
||||
<string>Case &sensitive</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QStringRef>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QChar;
|
||||
class QFileInfo;
|
||||
class QStringRef;
|
||||
class QTextCursor;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 == '_')
|
||||
|
||||
@@ -531,8 +531,8 @@ void UvscEngine::doUpdateLocals(const UpdateParameters ¶ms)
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -76,7 +76,7 @@ protected:
|
||||
QString commitName() const override;
|
||||
|
||||
signals:
|
||||
void show(const QString &commit);
|
||||
void showRequested(const QString &commit);
|
||||
|
||||
private:
|
||||
void authorInformationChanged();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -369,11 +369,6 @@ void IosRunSupport::start()
|
||||
IosRunner::start();
|
||||
}
|
||||
|
||||
void IosRunSupport::stop()
|
||||
{
|
||||
IosRunner::stop();
|
||||
}
|
||||
|
||||
//
|
||||
// IosQmlProfilerSupport
|
||||
//
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -193,7 +193,7 @@ SectionedProducts::SectionedProducts(QWidget *parent)
|
||||
|
||||
SectionedProducts::~SectionedProducts()
|
||||
{
|
||||
qDeleteAll(m_gridViews.values());
|
||||
qDeleteAll(m_gridViews);
|
||||
delete m_productDelegate;
|
||||
delete m_gridModel;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ¤t) 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 ¤t) 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()
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()>;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -49,9 +49,6 @@ public:
|
||||
void setCustomId(const QString &customId);
|
||||
QString customId() const;
|
||||
|
||||
signals:
|
||||
void accepted();
|
||||
|
||||
private slots:
|
||||
void acceptedClicked();
|
||||
void tabChanged(int index);
|
||||
|
||||
@@ -49,9 +49,6 @@ public:
|
||||
void setStatus(GlobalAnnotationStatus status);
|
||||
GlobalAnnotationStatus globalStatus() const;
|
||||
|
||||
signals:
|
||||
void accepted();
|
||||
|
||||
private slots:
|
||||
void acceptedClicked();
|
||||
void tabChanged(int index);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
156
src/plugins/qmldesigner/components/componentcore/gestures.cpp
Normal file
156
src/plugins/qmldesigner/components/componentcore/gestures.cpp
Normal 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.
|
||||
72
src/plugins/qmldesigner/components/componentcore/gestures.h
Normal file
72
src/plugins/qmldesigner/components/componentcore/gestures.h
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user