forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.14' into master
Conflicts: src/plugins/cppeditor/cppquickfix_test.cpp Change-Id: Ib2984a3b3d9d071d11304b6cf132c2f8cef77e1c
This commit is contained in:
@@ -324,7 +324,7 @@ QWidget *AndroidBuildApkWidget::createAdvancedGroup()
|
||||
auto vbox = new QVBoxLayout(group);
|
||||
QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(m_step->kit());
|
||||
if (version && version->supportsMultipleQtAbis()) {
|
||||
auto buildAAB = new QCheckBox(tr("Build .aab (Android App Bundle)"), group);
|
||||
auto buildAAB = new QCheckBox(tr("Build Android App Bundle (*.aab)"), group);
|
||||
buildAAB->setChecked(m_step->buildAAB());
|
||||
connect(buildAAB, &QAbstractButton::toggled, m_step, &AndroidBuildApkStep::setBuildAAB);
|
||||
vbox->addWidget(buildAAB);
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/synchronousprocess.h>
|
||||
@@ -86,8 +87,18 @@ AndroidDeployQtStep::AndroidDeployQtStep(BuildStepList *parent, Utils::Id id)
|
||||
: BuildStep(parent, id)
|
||||
{
|
||||
setImmutable(true);
|
||||
|
||||
m_uninstallPreviousPackage = addAspect<BoolAspect>();
|
||||
m_uninstallPreviousPackage->setSettingsKey(UninstallPreviousPackageKey);
|
||||
m_uninstallPreviousPackage->setLabel(tr("Uninstall the existing app first"));
|
||||
m_uninstallPreviousPackage->setValue(false);
|
||||
|
||||
const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(kit());
|
||||
m_uninstallPreviousPackage = qt && qt->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0);
|
||||
const bool forced = qt && qt->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0);
|
||||
if (forced) {
|
||||
m_uninstallPreviousPackage->setValue(true);
|
||||
m_uninstallPreviousPackage->setEnabled(false);
|
||||
}
|
||||
|
||||
connect(this, &AndroidDeployQtStep::askForUninstall,
|
||||
this, &AndroidDeployQtStep::slotAskForUninstall,
|
||||
@@ -167,7 +178,7 @@ bool AndroidDeployQtStep::init()
|
||||
|
||||
emit addOutput(tr("Deploying to %1").arg(m_serialNumber), OutputFormat::Stdout);
|
||||
|
||||
m_uninstallPreviousPackageRun = m_uninstallPreviousPackage;
|
||||
m_uninstallPreviousPackageRun = m_uninstallPreviousPackage->value();
|
||||
if (m_uninstallPreviousPackageRun)
|
||||
m_manifestName = AndroidManager::manifestPath(target());
|
||||
|
||||
@@ -480,14 +491,6 @@ QWidget *AndroidDeployQtStep::createConfigWidget()
|
||||
setDisplayName(QString("<b>%1</b>").arg(displayName()));
|
||||
setSummaryText(displayName());
|
||||
|
||||
auto uninstallPreviousCheckBox = new QCheckBox(widget);
|
||||
uninstallPreviousCheckBox->setText(tr("Uninstall the existing app first"));
|
||||
uninstallPreviousCheckBox->setChecked(uninstallPreviousPackage() > Keep);
|
||||
uninstallPreviousCheckBox->setEnabled(uninstallPreviousPackage() != ForceUninstall);
|
||||
|
||||
connect(uninstallPreviousCheckBox, &QAbstractButton::toggled,
|
||||
this, &AndroidDeployQtStep::setUninstallPreviousPackage);
|
||||
|
||||
auto resetDefaultDevices = new QPushButton(widget);
|
||||
resetDefaultDevices->setText(tr("Reset Default Deployment Devices"));
|
||||
|
||||
@@ -508,10 +511,10 @@ QWidget *AndroidDeployQtStep::createConfigWidget()
|
||||
AndroidManager::installQASIPackage(target(), packagePath);
|
||||
});
|
||||
|
||||
auto layout = new QVBoxLayout(widget);
|
||||
layout->addWidget(uninstallPreviousCheckBox);
|
||||
layout->addWidget(resetDefaultDevices);
|
||||
layout->addWidget(installCustomApkButton);
|
||||
LayoutBuilder builder(widget);
|
||||
builder.addRow(m_uninstallPreviousPackage);
|
||||
builder.addRow(resetDefaultDevices);
|
||||
builder.addRow(installCustomApkButton);
|
||||
|
||||
return widget;
|
||||
}
|
||||
@@ -569,32 +572,6 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::parseDeployErrors(QStr
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
bool AndroidDeployQtStep::fromMap(const QVariantMap &map)
|
||||
{
|
||||
m_uninstallPreviousPackage = map.value(UninstallPreviousPackageKey, m_uninstallPreviousPackage).toBool();
|
||||
return ProjectExplorer::BuildStep::fromMap(map);
|
||||
}
|
||||
|
||||
QVariantMap AndroidDeployQtStep::toMap() const
|
||||
{
|
||||
QVariantMap map = ProjectExplorer::BuildStep::toMap();
|
||||
map.insert(UninstallPreviousPackageKey, m_uninstallPreviousPackage);
|
||||
return map;
|
||||
}
|
||||
|
||||
void AndroidDeployQtStep::setUninstallPreviousPackage(bool uninstall)
|
||||
{
|
||||
m_uninstallPreviousPackage = uninstall;
|
||||
}
|
||||
|
||||
AndroidDeployQtStep::UninstallType AndroidDeployQtStep::uninstallPreviousPackage()
|
||||
{
|
||||
const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(kit());
|
||||
if (qt && qt->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0))
|
||||
return ForceUninstall;
|
||||
return m_uninstallPreviousPackage ? Uninstall : Keep;
|
||||
}
|
||||
|
||||
// AndroidDeployQtStepFactory
|
||||
|
||||
AndroidDeployQtStepFactory::AndroidDeployQtStepFactory()
|
||||
|
||||
@@ -59,20 +59,8 @@ class AndroidDeployQtStep : public ProjectExplorer::BuildStep
|
||||
};
|
||||
|
||||
public:
|
||||
enum UninstallType {
|
||||
Keep,
|
||||
Uninstall,
|
||||
ForceUninstall
|
||||
};
|
||||
|
||||
AndroidDeployQtStep(ProjectExplorer::BuildStepList *bc, Utils::Id id);
|
||||
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
UninstallType uninstallPreviousPackage();
|
||||
void setUninstallPreviousPackage(bool uninstall);
|
||||
|
||||
signals:
|
||||
void askForUninstall(DeployErrorCode errorCode);
|
||||
|
||||
@@ -105,7 +93,7 @@ private:
|
||||
QMap<QString, QString> m_filesToPull;
|
||||
|
||||
QStringList m_androidABIs;
|
||||
bool m_uninstallPreviousPackage = false;
|
||||
Utils::BoolAspect *m_uninstallPreviousPackage = nullptr;
|
||||
bool m_uninstallPreviousPackageRun = false;
|
||||
bool m_useAndroiddeployqt = false;
|
||||
bool m_askForUninstall = false;
|
||||
|
||||
@@ -86,7 +86,8 @@ QString AndroidQtVersion::invalidReason() const
|
||||
|
||||
bool AndroidQtVersion::supportsMultipleQtAbis() const
|
||||
{
|
||||
return qtVersion() >= QtSupport::QtVersionNumber{5, 14};
|
||||
return qtVersion() >= QtSupport::QtVersionNumber{5, 14}
|
||||
&& qtVersion() < QtSupport::QtVersionNumber{6, 0};
|
||||
}
|
||||
|
||||
Abis AndroidQtVersion::detectQtAbis() const
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>284</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
|
||||
@@ -185,8 +185,11 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
|
||||
|
||||
qCDebug(LOG) << " LocalExecutable" << localExecutable;
|
||||
qCDebug(LOG) << " DeployedExecutable" << deployedExecutable;
|
||||
qCDebug(LOG) << "Iterating run configurations";
|
||||
for (RunConfiguration *runConfig : target->runConfigurations()) {
|
||||
qCDebug(LOG) << "Iterating run configurations - prefer active over others";
|
||||
QList<RunConfiguration *> runConfigurations = target->runConfigurations();
|
||||
runConfigurations.removeOne(target->activeRunConfiguration());
|
||||
runConfigurations.prepend(target->activeRunConfiguration());
|
||||
for (RunConfiguration *runConfig : qAsConst(runConfigurations)) {
|
||||
qCDebug(LOG) << "RunConfiguration" << runConfig->id();
|
||||
if (!isLocal(target)) { // TODO add device support
|
||||
qCDebug(LOG) << " Skipped as not being local";
|
||||
|
||||
@@ -58,10 +58,11 @@
|
||||
#include <QThread>
|
||||
|
||||
using namespace ClangBackEnd;
|
||||
using namespace ClangCodeModel;
|
||||
using namespace ClangCodeModel::Internal;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static Q_LOGGING_CATEGORY(debug, "qtc.clangcodemodel.batch", QtWarningMsg);
|
||||
|
||||
static int timeOutFromEnvironmentVariable()
|
||||
@@ -78,7 +79,7 @@ static int timeOutFromEnvironmentVariable()
|
||||
return intervalAsInt;
|
||||
}
|
||||
|
||||
static int timeOutInMs()
|
||||
int timeOutInMs()
|
||||
{
|
||||
static int timeOut = timeOutFromEnvironmentVariable();
|
||||
return timeOut;
|
||||
@@ -747,9 +748,6 @@ bool BatchFileParser::parseLine(const QString &line)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static QString applySubstitutions(const QString &filePath, const QString &text)
|
||||
{
|
||||
const QString dirPath = QFileInfo(filePath).absolutePath();
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
int timeOutInMs();
|
||||
|
||||
bool runClangBatchFile(const QString &filePath);
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "clangcodecompletion_test.h"
|
||||
|
||||
#include "clangautomationutils.h"
|
||||
#include "clangbatchfileprocessor.h"
|
||||
#include "../clangcompletionassistinterface.h"
|
||||
#include "../clangmodelmanagersupport.h"
|
||||
|
||||
@@ -344,7 +345,7 @@ public:
|
||||
if (!textToInsert.isEmpty())
|
||||
openEditor.editor()->insert(textToInsert);
|
||||
|
||||
proposal = completionResults(openEditor.editor(), includePaths, 15000);
|
||||
proposal = completionResults(openEditor.editor(), includePaths, timeOutInMs());
|
||||
}
|
||||
|
||||
TextEditor::ProposalModelPtr proposal;
|
||||
@@ -657,7 +658,8 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCode()
|
||||
OpenEditorAtCursorPosition openEditor(testDocument);
|
||||
QVERIFY(openEditor.succeeded());
|
||||
|
||||
TextEditor::ProposalModelPtr proposal = completionResults(openEditor.editor());
|
||||
TextEditor::ProposalModelPtr proposal = completionResults(openEditor.editor(), {},
|
||||
timeOutInMs());
|
||||
QVERIFY(hasItem(proposal, "projectConfiguration1"));
|
||||
}
|
||||
|
||||
@@ -670,7 +672,8 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje
|
||||
QVERIFY(openEditor.succeeded());
|
||||
|
||||
// Check completion without project
|
||||
TextEditor::ProposalModelPtr proposal = completionResults(openEditor.editor());
|
||||
TextEditor::ProposalModelPtr proposal = completionResults(openEditor.editor(), {},
|
||||
timeOutInMs());
|
||||
QVERIFY(hasItem(proposal, "noProjectConfigurationDetected"));
|
||||
|
||||
{
|
||||
@@ -681,7 +684,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje
|
||||
QVERIFY(projectLoader.load());
|
||||
openEditor.waitUntilProjectPartChanged(QLatin1String("myproject.project"));
|
||||
|
||||
proposal = completionResults(openEditor.editor());
|
||||
proposal = completionResults(openEditor.editor(), {}, timeOutInMs());
|
||||
|
||||
QVERIFY(hasItem(proposal, "projectConfiguration1"));
|
||||
QVERIFY(!hasItem(proposal, "projectConfiguration2"));
|
||||
@@ -689,7 +692,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje
|
||||
// Check completion with project configuration 2
|
||||
QVERIFY(projectLoader.updateProject({{"PROJECT_CONFIGURATION_2"}}));
|
||||
openEditor.waitUntilBackendIsNotified();
|
||||
proposal = completionResults(openEditor.editor());
|
||||
proposal = completionResults(openEditor.editor(), {}, timeOutInMs());
|
||||
|
||||
QVERIFY(!hasItem(proposal, "projectConfiguration1"));
|
||||
QVERIFY(hasItem(proposal, "projectConfiguration2"));
|
||||
@@ -697,7 +700,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje
|
||||
|
||||
// Check again completion without project
|
||||
openEditor.waitUntilProjectPartChanged(QLatin1String(""));
|
||||
proposal = completionResults(openEditor.editor());
|
||||
proposal = completionResults(openEditor.editor(), {}, timeOutInMs());
|
||||
QVERIFY(hasItem(proposal, "noProjectConfigurationDetected"));
|
||||
}
|
||||
|
||||
@@ -723,7 +726,8 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeInGeneratedUiFile(
|
||||
QVERIFY(openSource.succeeded());
|
||||
|
||||
// ...and check comletions
|
||||
TextEditor::ProposalModelPtr proposal = completionResults(openSource.editor());
|
||||
TextEditor::ProposalModelPtr proposal = completionResults(openSource.editor(), {},
|
||||
timeOutInMs());
|
||||
QVERIFY(hasItem(proposal, "menuBar"));
|
||||
QVERIFY(hasItem(proposal, "statusBar"));
|
||||
QVERIFY(hasItem(proposal, "centralWidget"));
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
|
||||
@@ -125,7 +125,7 @@ void ClangToolsUnitTests::testProject()
|
||||
ClangToolsSettings::instance()->runSettings(),
|
||||
diagnosticConfig);
|
||||
QSignalSpy waitForFinishedTool(tool, &ClangTool::finished);
|
||||
QVERIFY(waitForFinishedTool.wait(90000));
|
||||
QVERIFY(waitForFinishedTool.wait(m_timeout));
|
||||
|
||||
// Check for errors
|
||||
const QString errorText = waitForFinishedTool.takeFirst().first().toString();
|
||||
@@ -186,5 +186,11 @@ void ClangToolsUnitTests::addTestRow(const QByteArray &relativeFilePath,
|
||||
<< absoluteFilePath << expectedDiagCount << diagnosticConfig;
|
||||
}
|
||||
|
||||
int ClangToolsUnitTests::getTimeout()
|
||||
{
|
||||
const int t = qEnvironmentVariableIntValue("QTC_CLANGTOOLS_TEST_TIMEOUT");
|
||||
return t > 0 ? t : 480000;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangTools
|
||||
|
||||
@@ -56,8 +56,11 @@ private:
|
||||
const CppTools::ClangDiagnosticConfig &diagnosticConfig);
|
||||
|
||||
private:
|
||||
static int getTimeout();
|
||||
|
||||
CppTools::Tests::TemporaryCopiedDir *m_tmpDir = nullptr;
|
||||
ProjectExplorer::Kit *m_kit = nullptr;
|
||||
int m_timeout = getTimeout();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>125</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/macroexpander.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
#include <QThread>
|
||||
|
||||
@@ -67,7 +68,7 @@ void CppcheckTool::updateOptions(const CppcheckOptions &options)
|
||||
if (trimmedPattern.isEmpty())
|
||||
continue;
|
||||
|
||||
const QRegularExpression re(QRegularExpression::wildcardToRegularExpression(trimmedPattern));
|
||||
const QRegularExpression re(Utils::wildcardToRegularExpression(trimmedPattern));
|
||||
if (re.isValid())
|
||||
m_filters.push_back(re);
|
||||
}
|
||||
|
||||
@@ -226,6 +226,8 @@ private slots:
|
||||
|
||||
void test_quickfix_removeUsingNamespace_data();
|
||||
void test_quickfix_removeUsingNamespace();
|
||||
void test_quickfix_removeUsingNamespace_simple_data();
|
||||
void test_quickfix_removeUsingNamespace_simple();
|
||||
void test_quickfix_removeUsingNamespace_differentSymbols();
|
||||
|
||||
void test_quickfix_InsertVirtualMethods_data();
|
||||
|
||||
@@ -606,6 +606,32 @@ void CppEditorPlugin::test_quickfix_data()
|
||||
""
|
||||
);
|
||||
|
||||
// Checks: complete switch statement where enum is goes via a template type parameter
|
||||
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752")
|
||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||
"enum E {EA, EB};\n"
|
||||
"template<typename T> struct S {\n"
|
||||
" static T theType() { return T(); }\n"
|
||||
"};\n"
|
||||
"int main() {\n"
|
||||
" @switch (S<E>::theType()) {\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
) << _(
|
||||
"enum E {EA, EB};\n"
|
||||
"template<typename T> struct S {\n"
|
||||
" static T theType() { return T(); }\n"
|
||||
"};\n"
|
||||
"int main() {\n"
|
||||
" switch (S<E>::theType()) {\n"
|
||||
" case EA:\n"
|
||||
" break;\n"
|
||||
" case EB:\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
// Checks: No special treatment for reference to non const.
|
||||
|
||||
// Check: Quick fix is not triggered on a member function.
|
||||
@@ -7083,6 +7109,49 @@ void CppEditorPlugin::test_quickfix_removeUsingNamespace()
|
||||
QuickFixOperationTest(testDocuments, &factory, ProjectExplorer::HeaderPaths(), operation);
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_quickfix_removeUsingNamespace_simple_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("header");
|
||||
QTest::addColumn<QByteArray>("expected");
|
||||
|
||||
const QByteArray common = R"--(
|
||||
namespace N{
|
||||
template<typename T>
|
||||
struct vector{
|
||||
using iterator = T*;
|
||||
};
|
||||
using int_vector = vector<int>;
|
||||
}
|
||||
)--";
|
||||
const QByteArray header = common + R"--(
|
||||
using namespace N@;
|
||||
int_vector ints;
|
||||
int_vector::iterator intIter;
|
||||
using vec = vector<int>;
|
||||
vec::iterator it;
|
||||
)--";
|
||||
const QByteArray expected = common + R"--(
|
||||
N::int_vector ints;
|
||||
N::int_vector::iterator intIter;
|
||||
using vec = N::vector<int>;
|
||||
vec::iterator it;
|
||||
)--";
|
||||
|
||||
QTest::newRow("nested typedefs with Namespace") << header << expected;
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_quickfix_removeUsingNamespace_simple()
|
||||
{
|
||||
QFETCH(QByteArray, header);
|
||||
QFETCH(QByteArray, expected);
|
||||
|
||||
QList<QuickFixTestDocument::Ptr> testDocuments;
|
||||
testDocuments << QuickFixTestDocument::create("header.h", header, expected);
|
||||
|
||||
RemoveUsingNamespace factory;
|
||||
QuickFixOperationTest(testDocuments, &factory, ProjectExplorer::HeaderPaths());
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_quickfix_removeUsingNamespace_differentSymbols()
|
||||
{
|
||||
QByteArray header = "namespace test{\n"
|
||||
|
||||
@@ -2752,6 +2752,7 @@ Enum *conditionEnum(const CppQuickFixInterface &interface, SwitchStatementAST *s
|
||||
Block *block = statement->symbol;
|
||||
Scope *scope = interface.semanticInfo().doc->scopeAt(block->line(), block->column());
|
||||
TypeOfExpression typeOfExpression;
|
||||
typeOfExpression.setExpandTemplates(true);
|
||||
typeOfExpression.init(interface.semanticInfo().doc, interface.snapshot());
|
||||
const QList<LookupItem> results = typeOfExpression(statement->condition,
|
||||
interface.semanticInfo().doc,
|
||||
@@ -7794,6 +7795,33 @@ private:
|
||||
int counter;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief getBaseName returns the base name of a qualified name or nullptr.
|
||||
* E.g.: foo::bar => foo; bar => bar
|
||||
* @param name The Name, maybe qualified
|
||||
* @return The base name of the qualified name or nullptr
|
||||
*/
|
||||
const Identifier *getBaseName(const Name *name)
|
||||
{
|
||||
class GetBaseName : public NameVisitor
|
||||
{
|
||||
void visit(const Identifier *name) override { baseName = name; }
|
||||
void visit(const QualifiedNameId *name) override
|
||||
{
|
||||
if (name->base())
|
||||
accept(name->base());
|
||||
else
|
||||
accept(name->name());
|
||||
}
|
||||
|
||||
public:
|
||||
const Identifier *baseName = nullptr;
|
||||
};
|
||||
GetBaseName getter;
|
||||
getter.accept(name);
|
||||
return getter.baseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief countNames counts the parts of the Name.
|
||||
* E.g. if the name is std::vector, the function returns 2, if the name is variant, returns 1
|
||||
@@ -7993,11 +8021,24 @@ private:
|
||||
{
|
||||
if (m_start) {
|
||||
Scope *scope = m_file->scopeAt(ast->firstToken());
|
||||
const QList<LookupItem> lookups = m_context.lookup(ast->name->name, scope);
|
||||
const Name *wantToLookup = ast->name->name;
|
||||
// first check if the base name is a typedef. Consider the following example:
|
||||
// using namespace std;
|
||||
// using vec = std::vector<int>;
|
||||
// vec::iterator it; // we have to lookup 'vec' and not iterator (would result in
|
||||
// std::vector<int>::iterator => std::vec::iterator, which is wrong)
|
||||
const Name *baseName = getBaseName(wantToLookup);
|
||||
QList<LookupItem> typedefCandidates = m_context.lookup(baseName, scope);
|
||||
if (!typedefCandidates.isEmpty()) {
|
||||
if (typedefCandidates.front().declaration()->isTypedef())
|
||||
wantToLookup = baseName;
|
||||
}
|
||||
|
||||
const QList<LookupItem> lookups = m_context.lookup(wantToLookup, scope);
|
||||
if (!lookups.empty()) {
|
||||
QList<const Name *> fullName = m_context.fullyQualifiedName(
|
||||
lookups.first().declaration());
|
||||
const int currentNameCount = countNames(ast->name->name);
|
||||
const int currentNameCount = countNames(wantToLookup);
|
||||
const bool needNamespace = needMissingNamespaces(std::move(fullName),
|
||||
currentNameCount);
|
||||
if (needNamespace)
|
||||
|
||||
@@ -1117,12 +1117,12 @@ void CppToolsPlugin::test_modelmanager_renameIncludesInEditor()
|
||||
|
||||
const MyTestDataDir testDir2(_("testdata_project2"));
|
||||
QFile foobar2000Header(testDir2.file("foobar2000.h"));
|
||||
QVERIFY(foobar2000Header.open(QFile::ReadOnly));
|
||||
QVERIFY(foobar2000Header.open(QFile::ReadOnly | QFile::Text));
|
||||
const auto foobar2000HeaderContents = foobar2000Header.readAll();
|
||||
foobar2000Header.close();
|
||||
|
||||
QFile renamedHeader(renamedHeaderWithNormalGuard);
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly));
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly | QFile::Text));
|
||||
auto renamedHeaderContents = renamedHeader.readAll();
|
||||
renamedHeader.close();
|
||||
QCOMPARE(renamedHeaderContents, foobar2000HeaderContents);
|
||||
@@ -1133,12 +1133,12 @@ void CppToolsPlugin::test_modelmanager_renameIncludesInEditor()
|
||||
Core::HandleIncludeGuards::Yes));
|
||||
|
||||
QFile foobar4000Header(testDir2.file("foobar4000.h"));
|
||||
QVERIFY(foobar4000Header.open(QFile::ReadOnly));
|
||||
QVERIFY(foobar4000Header.open(QFile::ReadOnly | QFile::Text));
|
||||
const auto foobar4000HeaderContents = foobar4000Header.readAll();
|
||||
foobar4000Header.close();
|
||||
|
||||
renamedHeader.setFileName(renamedHeaderWithUnderscoredGuard);
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly));
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly | QFile::Text));
|
||||
renamedHeaderContents = renamedHeader.readAll();
|
||||
renamedHeader.close();
|
||||
QCOMPARE(renamedHeaderContents, foobar4000HeaderContents);
|
||||
@@ -1146,7 +1146,7 @@ void CppToolsPlugin::test_modelmanager_renameIncludesInEditor()
|
||||
// test the renaming of a header with a malformed guard to verify we do not make
|
||||
// accidental refactors
|
||||
renamedHeader.setFileName(headerWithMalformedGuard);
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly));
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly | QFile::Text));
|
||||
auto originalMalformedGuardContents = renamedHeader.readAll();
|
||||
renamedHeader.close();
|
||||
|
||||
@@ -1154,7 +1154,7 @@ void CppToolsPlugin::test_modelmanager_renameIncludesInEditor()
|
||||
Core::HandleIncludeGuards::Yes));
|
||||
|
||||
renamedHeader.setFileName(renamedHeaderWithMalformedGuard);
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly));
|
||||
QVERIFY(renamedHeader.open(QFile::ReadOnly | QFile::Text));
|
||||
renamedHeaderContents = renamedHeader.readAll();
|
||||
renamedHeader.close();
|
||||
QCOMPARE(renamedHeaderContents, originalMalformedGuardContents);
|
||||
|
||||
@@ -4166,7 +4166,7 @@ void GdbEngine::setupInferior()
|
||||
}
|
||||
|
||||
if (!symbolFile.isEmpty()) {
|
||||
runCommand({"-file-exec-and-symbols \"" + symbolFile + '"',
|
||||
runCommand({"-file-symbol-file \"" + symbolFile + '"',
|
||||
CB(handleFileExecAndSymbols)});
|
||||
}
|
||||
|
||||
|
||||
@@ -2951,14 +2951,12 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
|
||||
|
||||
const SynchronousProcessResponse resp = vcsSynchronousExec(repositoryDirectory, arguments,
|
||||
VcsCommand::NoFullySync);
|
||||
const QString stdErr = resp.stdErr();
|
||||
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||
VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount));
|
||||
VcsOutputWindow::appendError(stdErr);
|
||||
GitPlugin::updateCurrentBranch();
|
||||
return true;
|
||||
} else {
|
||||
VcsOutputWindow::appendError(tr("Cannot commit %n files: %1\n", nullptr, commitCount).arg(stdErr));
|
||||
VcsOutputWindow::appendError(tr("Cannot commit %n files\n", nullptr, commitCount));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,10 +325,9 @@ void Client::sendContent(const IContent &content)
|
||||
QString error;
|
||||
if (!QTC_GUARD(content.isValid(&error)))
|
||||
Core::MessageManager::write(error);
|
||||
LanguageClientManager::logBaseMessage(LspLogMessage::ClientMessage,
|
||||
name(),
|
||||
content.toBaseMessage());
|
||||
m_clientInterface->sendMessage(content.toBaseMessage());
|
||||
const BaseMessage message = content.toBaseMessage();
|
||||
LanguageClientManager::logBaseMessage(LspLogMessage::ClientMessage, name(), message);
|
||||
m_clientInterface->sendMessage(message);
|
||||
}
|
||||
|
||||
void Client::sendContent(const DocumentUri &uri, const IContent &content)
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>349</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>70</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="_nameLbl">
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
<height>349</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
|
||||
@@ -124,9 +124,6 @@ QWidget *NimbleTaskStep::createConfigWidget()
|
||||
|
||||
connect(buildSystem, &NimbleBuildSystem::tasksChanged, this, &NimbleTaskStep::updateTaskList);
|
||||
|
||||
connect(m_taskName, &StringAspect::changed, this, &BuildStep::recreateSummary);
|
||||
connect(m_taskArgs, &StringAspect::changed, this, &BuildStep::recreateSummary);
|
||||
|
||||
setSummaryUpdater([this] {
|
||||
return QString("<b>%1:</b> nimble %2 %3")
|
||||
.arg(displayName(), m_taskName->value(), m_taskArgs->value());
|
||||
|
||||
@@ -477,6 +477,7 @@ void BuildManager::finish()
|
||||
{
|
||||
const QString elapsedTime = Utils::formatElapsedTime(d->m_elapsed.elapsed());
|
||||
m_instance->addToOutputWindow(elapsedTime, BuildStep::OutputFormat::NormalMessage);
|
||||
d->m_outputWindow->flush();
|
||||
|
||||
QApplication::alert(ICore::dialogParent(), 3000);
|
||||
}
|
||||
@@ -696,7 +697,7 @@ void BuildManager::nextStep()
|
||||
}
|
||||
|
||||
static const auto finishedHandler = [](bool success) {
|
||||
d->m_outputWindow->outputFormatter()->flush();
|
||||
d->m_outputWindow->flush();
|
||||
d->m_lastStepSucceeded = success;
|
||||
disconnect(d->m_currentBuildStep, nullptr, instance(), nullptr);
|
||||
BuildManager::nextBuildQueue();
|
||||
|
||||
@@ -35,6 +35,7 @@ class PROJECTEXPLORER_EXPORT BuildPropertiesSettings
|
||||
{
|
||||
public:
|
||||
QString buildDirectoryTemplate;
|
||||
QString buildDirectoryTemplateOld; // TODO: Remove in ~4.16
|
||||
Utils::TriState separateDebugInfo;
|
||||
Utils::TriState qmlDebugging;
|
||||
Utils::TriState qtQuickCompiler;
|
||||
|
||||
@@ -157,6 +157,26 @@ void BuildStep::cancel()
|
||||
doCancel();
|
||||
}
|
||||
|
||||
QWidget *BuildStep::doCreateConfigWidget()
|
||||
{
|
||||
QWidget *widget = createConfigWidget();
|
||||
|
||||
const auto recreateSummary = [this] {
|
||||
if (m_summaryUpdater)
|
||||
setSummaryText(m_summaryUpdater());
|
||||
};
|
||||
|
||||
for (BaseAspect *aspect : qAsConst(m_aspects))
|
||||
connect(aspect, &BaseAspect::changed, widget, recreateSummary);
|
||||
|
||||
connect(buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
|
||||
widget, recreateSummary);
|
||||
|
||||
recreateSummary();
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget *BuildStep::createConfigWidget()
|
||||
{
|
||||
auto widget = new QWidget;
|
||||
@@ -165,12 +185,8 @@ QWidget *BuildStep::createConfigWidget()
|
||||
for (BaseAspect *aspect : qAsConst(m_aspects)) {
|
||||
if (aspect->isVisible())
|
||||
aspect->addToLayout(builder.finishRow());
|
||||
connect(aspect, &BaseAspect::changed, this, &BuildStep::recreateSummary);
|
||||
}
|
||||
|
||||
connect(buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
|
||||
this, &BuildStep::recreateSummary);
|
||||
|
||||
if (m_addMacroExpander)
|
||||
VariableChooser::addSupportForChildWidgets(widget, macroExpander());
|
||||
|
||||
@@ -500,13 +516,6 @@ void BuildStep::setSummaryText(const QString &summaryText)
|
||||
void BuildStep::setSummaryUpdater(const std::function<QString()> &summaryUpdater)
|
||||
{
|
||||
m_summaryUpdater = summaryUpdater;
|
||||
recreateSummary();
|
||||
}
|
||||
|
||||
void BuildStep::recreateSummary()
|
||||
{
|
||||
if (m_summaryUpdater)
|
||||
setSummaryText(m_summaryUpdater());
|
||||
}
|
||||
|
||||
} // ProjectExplorer
|
||||
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
virtual bool init() = 0;
|
||||
void run();
|
||||
void cancel();
|
||||
virtual QWidget *createConfigWidget();
|
||||
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
@@ -120,7 +119,7 @@ public:
|
||||
QString summaryText() const;
|
||||
void setSummaryText(const QString &summaryText);
|
||||
|
||||
void recreateSummary();
|
||||
QWidget *doCreateConfigWidget();
|
||||
|
||||
signals:
|
||||
void updateSummary();
|
||||
@@ -141,6 +140,8 @@ signals:
|
||||
void finished(bool result);
|
||||
|
||||
protected:
|
||||
virtual QWidget *createConfigWidget();
|
||||
|
||||
void runInThread(const std::function<bool()> &syncImpl);
|
||||
|
||||
std::function<bool()> cancelChecker() const;
|
||||
|
||||
@@ -170,7 +170,7 @@ void ToolWidget::setDownVisible(bool b)
|
||||
BuildStepsWidgetData::BuildStepsWidgetData(BuildStep *s) :
|
||||
step(s), widget(nullptr), detailsWidget(nullptr)
|
||||
{
|
||||
widget = s->createConfigWidget();
|
||||
widget = s->doCreateConfigWidget();
|
||||
Q_ASSERT(widget);
|
||||
|
||||
detailsWidget = new DetailsWidget;
|
||||
|
||||
@@ -416,8 +416,6 @@ QWidget *MakeStep::createConfigWidget()
|
||||
m_nonOverrideWarning->setVisible(makeflagsJobCountMismatch()
|
||||
&& !jobCountOverridesMakeflags());
|
||||
disableInSubDirsCheckBox->setChecked(!m_enabledForSubDirs);
|
||||
|
||||
recreateSummary();
|
||||
};
|
||||
|
||||
updateDetails();
|
||||
|
||||
@@ -259,7 +259,8 @@ const char PROJECT_OPEN_LOCATIONS_CONTEXT_MENU[] = "Project.P.OpenLocation.CtxM
|
||||
|
||||
// Default directories:
|
||||
const char DEFAULT_BUILD_DIRECTORY_TEMPLATE[] = "../%{JS: Util.asciify(\"build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}\")}";
|
||||
const char DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY[] = "Directories/BuildDirectory.Template";
|
||||
const char DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY_OLD[] = "Directories/BuildDirectory.Template"; // TODO: Remove in ~4.16
|
||||
const char DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY[] = "Directories/BuildDirectory.TemplateV2";
|
||||
|
||||
const char BUILD_BEFORE_DEPLOY_SETTINGS_KEY[] = "ProjectExplorer/Settings/BuildBeforeDeploy";
|
||||
const char DEPLOY_BEFORE_RUN_SETTINGS_KEY[] = "ProjectExplorer/Settings/DeployBeforeRun";
|
||||
@@ -1532,8 +1533,14 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
||||
dd->m_projectExplorerSettings.lowBuildPriority
|
||||
= s->value(Constants::LOW_BUILD_PRIORITY_SETTINGS_KEY, false).toBool();
|
||||
|
||||
dd->m_buildPropertiesSettings.buildDirectoryTemplateOld
|
||||
= s->value(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY_OLD).toString();
|
||||
dd->m_buildPropertiesSettings.buildDirectoryTemplate
|
||||
= s->value(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY).toString();
|
||||
if (dd->m_buildPropertiesSettings.buildDirectoryTemplate.isEmpty()) {
|
||||
dd->m_buildPropertiesSettings.buildDirectoryTemplate
|
||||
= dd->m_buildPropertiesSettings.buildDirectoryTemplateOld;
|
||||
}
|
||||
if (dd->m_buildPropertiesSettings.buildDirectoryTemplate.isEmpty())
|
||||
dd->m_buildPropertiesSettings.buildDirectoryTemplate = Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE;
|
||||
// TODO: Remove in ~4.16
|
||||
@@ -2110,6 +2117,8 @@ void ProjectExplorerPluginPrivate::savePersistentSettings()
|
||||
s->setValue(Constants::STOP_BEFORE_BUILD_SETTINGS_KEY, int(dd->m_projectExplorerSettings.stopBeforeBuild));
|
||||
|
||||
// Store this in the Core directory scope for backward compatibility!
|
||||
s->setValue(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY_OLD,
|
||||
dd->m_buildPropertiesSettings.buildDirectoryTemplateOld);
|
||||
s->setValue(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY,
|
||||
dd->m_buildPropertiesSettings.buildDirectoryTemplate);
|
||||
|
||||
|
||||
@@ -53,9 +53,11 @@ class PROJECTEXPLORER_EXPORT Target : public QObject
|
||||
friend class SessionManager; // for setActiveBuild and setActiveDeployConfiguration
|
||||
Q_OBJECT
|
||||
|
||||
struct _constructor_tag { explicit _constructor_tag() = default; };
|
||||
|
||||
public:
|
||||
struct _constructor_tag
|
||||
{
|
||||
explicit _constructor_tag() = default;
|
||||
};
|
||||
Target(Project *parent, Kit *k, _constructor_tag);
|
||||
~Target() override;
|
||||
|
||||
|
||||
@@ -75,6 +75,17 @@ using namespace QmakeProjectManager::Internal;
|
||||
|
||||
namespace QmakeProjectManager {
|
||||
|
||||
class RunSystemAspect : public TriStateAspect
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RunSystemAspect() : TriStateAspect(tr("Run"), tr("Ignore"), tr("Use global setting"))
|
||||
{
|
||||
setSettingsKey("RunSystemFunction");
|
||||
setDisplayName(tr("qmake system() behavior when parsing:"));
|
||||
}
|
||||
};
|
||||
|
||||
QmakeExtraBuildInfo::QmakeExtraBuildInfo()
|
||||
{
|
||||
const BuildPropertiesSettings &settings = ProjectExplorerPlugin::buildPropertiesSettings();
|
||||
@@ -198,6 +209,8 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Utils::Id id)
|
||||
emit qmakeBuildConfigurationChanged();
|
||||
qmakeBuildSystem()->scheduleUpdateAllNowOrLater();
|
||||
});
|
||||
|
||||
addAspect<RunSystemAspect>();
|
||||
}
|
||||
|
||||
QmakeBuildConfiguration::~QmakeBuildConfiguration()
|
||||
@@ -439,6 +452,17 @@ void QmakeBuildConfiguration::forceQtQuickCompiler(bool enable)
|
||||
aspect<QtQuickCompilerAspect>()->setSetting(enable ? TriState::Enabled : TriState::Disabled);
|
||||
}
|
||||
|
||||
bool QmakeBuildConfiguration::runSystemFunction() const
|
||||
{
|
||||
switch (aspect<RunSystemAspect>()->value()) {
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
return false;
|
||||
}
|
||||
return QmakeSettings::runSystemFunction();
|
||||
}
|
||||
|
||||
QStringList QmakeBuildConfiguration::configCommandLineArguments() const
|
||||
{
|
||||
QStringList result;
|
||||
@@ -875,3 +899,5 @@ void QmakeBuildConfiguration::restrictNextBuild(const RunConfiguration *rc)
|
||||
}
|
||||
|
||||
} // namespace QmakeProjectManager
|
||||
|
||||
#include <qmakebuildconfiguration.moc>
|
||||
|
||||
@@ -106,6 +106,8 @@ public:
|
||||
Utils::TriState useQtQuickCompiler() const;
|
||||
void forceQtQuickCompiler(bool enable);
|
||||
|
||||
bool runSystemFunction() const;
|
||||
|
||||
signals:
|
||||
/// emitted for setQMakeBuildConfig, not emitted for Qt version changes, even
|
||||
/// if those change the qmakebuildconfig
|
||||
|
||||
@@ -1839,15 +1839,24 @@ QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const F
|
||||
}
|
||||
|
||||
bool tryUnfixified = false;
|
||||
|
||||
// These paths should not be checked for existence, to ensure consistent include path lists
|
||||
// before and after building.
|
||||
const QString mocDir = mocDirPath(reader, buildDir);
|
||||
const QString uiDir = uiDirPath(reader, buildDir);
|
||||
|
||||
foreach (const ProFileEvaluator::SourceFile &el,
|
||||
reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir.toString(),
|
||||
false)) {
|
||||
const QString sysrootifiedPath = sysrootify(el.fileName, sysroot.toString(), projectDir,
|
||||
buildDir.toString());
|
||||
if (IoUtils::isAbsolutePath(sysrootifiedPath) && IoUtils::exists(sysrootifiedPath))
|
||||
if (IoUtils::isAbsolutePath(sysrootifiedPath)
|
||||
&& (IoUtils::exists(sysrootifiedPath) || sysrootifiedPath == mocDir
|
||||
|| sysrootifiedPath == uiDir)) {
|
||||
paths << sysrootifiedPath;
|
||||
else
|
||||
} else {
|
||||
tryUnfixified = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If sysrootifying a fixified path does not yield a valid path, try again with the
|
||||
@@ -1862,10 +1871,6 @@ QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const F
|
||||
}
|
||||
}
|
||||
|
||||
// paths already contains moc dir and ui dir, due to corrrectly parsing uic.prf and moc.prf
|
||||
// except if those directories don't exist at the time of parsing
|
||||
// thus we add those directories manually (without checking for existence)
|
||||
paths << mocDirPath(reader, buildDir) << uiDirPath(reader, buildDir);
|
||||
paths.removeDuplicates();
|
||||
return paths;
|
||||
}
|
||||
|
||||
@@ -797,6 +797,7 @@ QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFi
|
||||
m_qmakeGlobals->environment.insert(env.key(eit), env.expandedValueForKey(env.key(eit)));
|
||||
|
||||
m_qmakeGlobals->setCommandLineArguments(buildDir(rootProFile()->filePath()).toString(), qmakeArgs);
|
||||
m_qmakeGlobals->runSystemFunction = bc->runSystemFunction();
|
||||
|
||||
QtSupport::ProFileCacheManager::instance()->incRefCount();
|
||||
|
||||
|
||||
@@ -38,11 +38,13 @@ namespace Internal {
|
||||
|
||||
const char BUILD_DIR_WARNING_KEY[] = "QmakeProjectManager/WarnAgainstUnalignedBuildDir";
|
||||
const char ALWAYS_RUN_QMAKE_KEY[] = "QmakeProjectManager/AlwaysRunQmake";
|
||||
const char RUN_SYSTEM_KEY[] = "QmakeProjectManager/RunSystemFunction";
|
||||
|
||||
static bool operator==(const QmakeSettingsData &s1, const QmakeSettingsData &s2)
|
||||
{
|
||||
return s1.warnAgainstUnalignedBuildDir == s2.warnAgainstUnalignedBuildDir
|
||||
&& s1.alwaysRunQmake == s2.alwaysRunQmake;
|
||||
&& s1.alwaysRunQmake == s2.alwaysRunQmake
|
||||
&& s1.runSystemFunction == s2.runSystemFunction;
|
||||
}
|
||||
static bool operator!=(const QmakeSettingsData &s1, const QmakeSettingsData &s2)
|
||||
{
|
||||
@@ -59,6 +61,11 @@ bool QmakeSettings::alwaysRunQmake()
|
||||
return instance().m_settings.alwaysRunQmake;
|
||||
}
|
||||
|
||||
bool QmakeSettings::runSystemFunction()
|
||||
{
|
||||
return instance().m_settings.runSystemFunction;
|
||||
}
|
||||
|
||||
QmakeSettings &QmakeSettings::instance()
|
||||
{
|
||||
static QmakeSettings theSettings;
|
||||
@@ -85,6 +92,7 @@ void QmakeSettings::loadSettings()
|
||||
m_settings.warnAgainstUnalignedBuildDir = s->value(
|
||||
BUILD_DIR_WARNING_KEY, Utils::HostOsInfo::isWindowsHost()).toBool();
|
||||
m_settings.alwaysRunQmake = s->value(ALWAYS_RUN_QMAKE_KEY, false).toBool();
|
||||
m_settings.runSystemFunction = s->value(RUN_SYSTEM_KEY, false).toBool();
|
||||
}
|
||||
|
||||
void QmakeSettings::storeSettings() const
|
||||
@@ -92,6 +100,7 @@ void QmakeSettings::storeSettings() const
|
||||
QSettings * const s = Core::ICore::settings();
|
||||
s->setValue(BUILD_DIR_WARNING_KEY, warnAgainstUnalignedBuildDir());
|
||||
s->setValue(ALWAYS_RUN_QMAKE_KEY, alwaysRunQmake());
|
||||
s->setValue(RUN_SYSTEM_KEY, runSystemFunction());
|
||||
}
|
||||
|
||||
class QmakeSettingsPage::SettingsWidget : public QWidget
|
||||
@@ -110,9 +119,15 @@ public:
|
||||
m_alwaysRunQmakeCheckbox.setToolTip(tr("This option can help to prevent failures on "
|
||||
"incremental builds, but might slow them down unnecessarily in the general case."));
|
||||
m_alwaysRunQmakeCheckbox.setChecked(QmakeSettings::alwaysRunQmake());
|
||||
m_ignoreSystemCheckbox.setText(tr("Ignore qmake's system() function "
|
||||
"when parsing a project"));
|
||||
m_ignoreSystemCheckbox.setToolTip(tr("Unchecking this option can help getting more exact "
|
||||
"parsing results, but can have unwanted side effects."));
|
||||
m_ignoreSystemCheckbox.setChecked(!QmakeSettings::runSystemFunction());
|
||||
const auto layout = new QVBoxLayout(this);
|
||||
layout->addWidget(&m_warnAgainstUnalignedBuildDirCheckbox);
|
||||
layout->addWidget(&m_alwaysRunQmakeCheckbox);
|
||||
layout->addWidget(&m_ignoreSystemCheckbox);
|
||||
layout->addStretch(1);
|
||||
}
|
||||
|
||||
@@ -121,12 +136,14 @@ public:
|
||||
QmakeSettingsData settings;
|
||||
settings.warnAgainstUnalignedBuildDir = m_warnAgainstUnalignedBuildDirCheckbox.isChecked();
|
||||
settings.alwaysRunQmake = m_alwaysRunQmakeCheckbox.isChecked();
|
||||
settings.runSystemFunction = !m_ignoreSystemCheckbox.isChecked();
|
||||
QmakeSettings::setSettingsData(settings);
|
||||
}
|
||||
|
||||
private:
|
||||
QCheckBox m_warnAgainstUnalignedBuildDirCheckbox;
|
||||
QCheckBox m_alwaysRunQmakeCheckbox;
|
||||
QCheckBox m_ignoreSystemCheckbox;
|
||||
};
|
||||
|
||||
QmakeSettingsPage::QmakeSettingsPage()
|
||||
|
||||
@@ -37,6 +37,7 @@ class QmakeSettingsData {
|
||||
public:
|
||||
bool warnAgainstUnalignedBuildDir = false;
|
||||
bool alwaysRunQmake = false;
|
||||
bool runSystemFunction = false;
|
||||
};
|
||||
|
||||
class QmakeSettings : public QObject
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
static QmakeSettings &instance();
|
||||
static bool warnAgainstUnalignedBuildDir();
|
||||
static bool alwaysRunQmake();
|
||||
static bool runSystemFunction();
|
||||
static void setSettingsData(const QmakeSettingsData &settings);
|
||||
|
||||
signals:
|
||||
|
||||
@@ -6,7 +6,7 @@ endif()
|
||||
add_qtc_plugin(QmlDesigner
|
||||
DEPENDS
|
||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
||||
Qt5::QuickWidgets Qt5::CorePrivate
|
||||
Qt5::QuickWidgets Qt5::CorePrivate Sqlite
|
||||
DEFINES
|
||||
DESIGNER_CORE_LIBRARY
|
||||
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
|
||||
@@ -208,6 +208,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
modelnodecontextmenu.cpp modelnodecontextmenu.h
|
||||
modelnodecontextmenu_helper.cpp modelnodecontextmenu_helper.h
|
||||
modelnodeoperations.cpp modelnodeoperations.h
|
||||
navigation2d.cpp navigation2d.h
|
||||
qmldesignericonprovider.cpp qmldesignericonprovider.h
|
||||
selectioncontext.cpp selectioncontext.h
|
||||
theme.cpp theme.h
|
||||
@@ -316,6 +317,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
itemlibraryassetimportdialog.cpp itemlibraryassetimportdialog.h
|
||||
itemlibraryassetimportdialog.ui
|
||||
itemlibraryassetimporter.cpp itemlibraryassetimporter.h
|
||||
itemlibraryiconimageprovider.cpp itemlibraryiconimageprovider.h
|
||||
)
|
||||
|
||||
find_package(Qt5 COMPONENTS Quick3DAssetImport QUIET)
|
||||
@@ -501,6 +503,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
include/textmodifier.h
|
||||
include/variantproperty.h
|
||||
include/viewmanager.h
|
||||
include/imagecache.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
@@ -585,6 +588,21 @@ extend_qtc_plugin(QmlDesigner
|
||||
pluginmanager/widgetpluginmanager.cpp pluginmanager/widgetpluginmanager.h
|
||||
pluginmanager/widgetpluginpath.cpp pluginmanager/widgetpluginpath.h
|
||||
rewritertransaction.cpp rewritertransaction.h
|
||||
|
||||
imagecache/imagecachecollector.h
|
||||
imagecache/imagecachecollector.cpp
|
||||
imagecache/imagecache.cpp
|
||||
imagecache/imagecachecollectorinterface.h
|
||||
imagecache/imagecacheconnectionmanager.cpp
|
||||
imagecache/imagecacheconnectionmanager.h
|
||||
imagecache/imagecachegenerator.cpp
|
||||
imagecache/imagecachegenerator.h
|
||||
imagecache/imagecachestorage.h
|
||||
imagecache/imagecachegeneratorinterface.h
|
||||
imagecache/imagecachestorageinterface.h
|
||||
imagecache/timestampproviderinterface.h
|
||||
imagecache/timestampprovider.h
|
||||
imagecache/timestampprovider.cpp
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
@@ -644,6 +662,16 @@ extend_qtc_plugin(QmlDesigner
|
||||
texttool/texttool.cpp texttool/texttool.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/previewtooltip
|
||||
SOURCES
|
||||
previewimagetooltip.cpp
|
||||
previewimagetooltip.h
|
||||
previewimagetooltip.ui
|
||||
previewtooltipbackend.cpp
|
||||
previewtooltipbackend.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/richtexteditor
|
||||
SOURCES
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#include "assetexportpluginconstants.h"
|
||||
#include "filepathmodel.h"
|
||||
|
||||
#include "coreplugin/fileutils.h"
|
||||
#include "coreplugin/icore.h"
|
||||
#include "projectexplorer/task.h"
|
||||
#include "projectexplorer/taskhub.h"
|
||||
#include "utils/fileutils.h"
|
||||
#include "utils/outputformatter.h"
|
||||
#include <coreplugin/fileutils.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/task.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/outputformatter.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
|
||||
@@ -28,18 +28,34 @@
|
||||
|
||||
#include "richtexteditor/richtexteditor.h"
|
||||
|
||||
#include "QStringListModel"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
AnnotationCommentTab::AnnotationCommentTab(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::AnnotationCommentTab)
|
||||
AnnotationCommentTab::AnnotationCommentTab(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::AnnotationCommentTab)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_editor = new RichTextEditor;
|
||||
ui->formLayout->setWidget(3, QFormLayout::FieldRole, m_editor);
|
||||
|
||||
connect(ui->titleEdit, &QLineEdit::textEdited,
|
||||
ui->titleEdit->setModel(new QStringListModel{QStringList{"Description",
|
||||
"Display Condition",
|
||||
"helper_lines"
|
||||
"highlight"
|
||||
"project author",
|
||||
"project confirmed",
|
||||
"project developer",
|
||||
"project distributor",
|
||||
"project modified",
|
||||
"project type"
|
||||
"project version",
|
||||
"Screen Description"
|
||||
"Section"}});
|
||||
|
||||
connect(ui->titleEdit, &QComboBox::currentTextChanged,
|
||||
this, &AnnotationCommentTab::commentTitleChanged);
|
||||
}
|
||||
|
||||
@@ -52,7 +68,7 @@ Comment AnnotationCommentTab::currentComment() const
|
||||
{
|
||||
Comment result;
|
||||
|
||||
result.setTitle(ui->titleEdit->text().trimmed());
|
||||
result.setTitle(ui->titleEdit->currentText().trimmed());
|
||||
result.setAuthor(ui->authorEdit->text().trimmed());
|
||||
result.setText(m_editor->richText().trimmed());
|
||||
|
||||
@@ -77,7 +93,7 @@ void AnnotationCommentTab::setComment(const Comment &comment)
|
||||
|
||||
void AnnotationCommentTab::resetUI()
|
||||
{
|
||||
ui->titleEdit->setText(m_comment.title());
|
||||
ui->titleEdit->setCurrentText(m_comment.title());
|
||||
ui->authorEdit->setText(m_comment.author());
|
||||
m_editor->setRichText(m_comment.deescapedText());
|
||||
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="titleEdit"/>
|
||||
<widget class="QComboBox" name="titleEdit">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="textLabel">
|
||||
|
||||
@@ -14,6 +14,7 @@ SOURCES += modelnodecontextmenu_helper.cpp
|
||||
SOURCES += selectioncontext.cpp
|
||||
SOURCES += designeractionmanager.cpp
|
||||
SOURCES += modelnodeoperations.cpp
|
||||
SOURCES += navigation2d.cpp
|
||||
SOURCES += crumblebar.cpp
|
||||
SOURCES += qmldesignericonprovider.cpp
|
||||
SOURCES += zoomaction.cpp
|
||||
@@ -33,6 +34,7 @@ HEADERS += selectioncontext.h
|
||||
HEADERS += componentcore_constants.h
|
||||
HEADERS += designeractionmanager.h
|
||||
HEADERS += modelnodeoperations.h
|
||||
HEADERS += navigation2d.h
|
||||
HEADERS += actioninterface.h
|
||||
HEADERS += crumblebar.h
|
||||
HEADERS += qmldesignericonprovider.h
|
||||
|
||||
@@ -347,25 +347,27 @@ public:
|
||||
&& !selectionContext().currentSingleSelectedNode().isRootNode()
|
||||
&& selectionContext().currentSingleSelectedNode().hasParentProperty()) {
|
||||
|
||||
ActionTemplate *selectionAction = new ActionTemplate(QString(), &ModelNodeOperations::select);
|
||||
selectionAction->setParent(menu());
|
||||
|
||||
parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode();
|
||||
|
||||
selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg(
|
||||
captionForModelNode(parentNode)));
|
||||
if (!ModelNode::isThisOrAncestorLocked(parentNode)) {
|
||||
ActionTemplate *selectionAction = new ActionTemplate(QString(), &ModelNodeOperations::select);
|
||||
selectionAction->setParent(menu());
|
||||
selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg(
|
||||
captionForModelNode(parentNode)));
|
||||
|
||||
SelectionContext nodeSelectionContext = selectionContext();
|
||||
nodeSelectionContext.setTargetNode(parentNode);
|
||||
selectionAction->setSelectionContext(nodeSelectionContext);
|
||||
SelectionContext nodeSelectionContext = selectionContext();
|
||||
nodeSelectionContext.setTargetNode(parentNode);
|
||||
selectionAction->setSelectionContext(nodeSelectionContext);
|
||||
|
||||
menu()->addAction(selectionAction);
|
||||
menu()->addAction(selectionAction);
|
||||
}
|
||||
}
|
||||
foreach (const ModelNode &node, selectionContext().view()->allModelNodes()) {
|
||||
for (const ModelNode &node : selectionContext().view()->allModelNodes()) {
|
||||
if (node != selectionContext().currentSingleSelectedNode()
|
||||
&& node != parentNode
|
||||
&& contains(node, selectionContext().scenePosition())
|
||||
&& !node.isRootNode()) {
|
||||
&& !node.isRootNode()
|
||||
&& !ModelNode::isThisOrAncestorLocked(node)) {
|
||||
selectionContext().setTargetNode(node);
|
||||
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node));
|
||||
ActionTemplate *selectionAction = new ActionTemplate(what, &ModelNodeOperations::select);
|
||||
@@ -377,6 +379,9 @@ public:
|
||||
menu()->addAction(selectionAction);
|
||||
}
|
||||
}
|
||||
|
||||
if (menu()->isEmpty())
|
||||
action()->setEnabled(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -574,11 +579,6 @@ bool multiSelection(const SelectionContext &context)
|
||||
return !singleSelection(context) && selectionNotEmpty(context);
|
||||
}
|
||||
|
||||
bool singleSelectionAndInBaseState(const SelectionContext &context)
|
||||
{
|
||||
return singleSelection(context) && inBaseState(context);
|
||||
}
|
||||
|
||||
bool multiSelectionAndInBaseState(const SelectionContext &context)
|
||||
{
|
||||
return multiSelection(context) && inBaseState(context);
|
||||
@@ -828,6 +828,11 @@ bool studioComponentsAvailable(const SelectionContext &context)
|
||||
return context.view()->model()->isImportPossible(import, true, true);
|
||||
}
|
||||
|
||||
bool studioComponentsAvailableAndSelectionCanBeLayouted(const SelectionContext &context)
|
||||
{
|
||||
return selectionCanBeLayouted(context) && studioComponentsAvailable(context);
|
||||
}
|
||||
|
||||
bool singleSelectedAndUiFile(const SelectionContext &context)
|
||||
{
|
||||
if (!singleSelection(context))
|
||||
@@ -882,6 +887,12 @@ bool raiseAvailable(const SelectionContext &selectionState)
|
||||
return parentProperty.indexOf(modelNode) < parentProperty.count() - 1;
|
||||
}
|
||||
|
||||
bool anchorsMenuEnabled(const SelectionContext &context)
|
||||
{
|
||||
return singleSelectionItemIsNotAnchoredAndSingleSelectionNotRoot(context)
|
||||
|| singleSelectionItemIsAnchored(context);
|
||||
}
|
||||
|
||||
void DesignerActionManager::createDefaultDesignerActions()
|
||||
{
|
||||
using namespace SelectionContextFunctors;
|
||||
@@ -996,11 +1007,10 @@ void DesignerActionManager::createDefaultDesignerActions()
|
||||
&setVisible,
|
||||
&singleSelectedItem));
|
||||
|
||||
addDesignerAction(new ActionGroup(
|
||||
anchorsCategoryDisplayName,
|
||||
anchorsCategory,
|
||||
priorityAnchorsCategory,
|
||||
&singleSelectionAndInBaseState));
|
||||
addDesignerAction(new ActionGroup(anchorsCategoryDisplayName,
|
||||
anchorsCategory,
|
||||
priorityAnchorsCategory,
|
||||
&anchorsMenuEnabled));
|
||||
|
||||
addDesignerAction(new ModelNodeAction(
|
||||
anchorsFillCommandId,
|
||||
@@ -1042,7 +1052,7 @@ void DesignerActionManager::createDefaultDesignerActions()
|
||||
addDesignerAction(new ActionGroup(groupCategoryDisplayName,
|
||||
groupCategory,
|
||||
priorityGroupCategory,
|
||||
&studioComponentsAvailable));
|
||||
&studioComponentsAvailableAndSelectionCanBeLayouted));
|
||||
|
||||
addDesignerAction(new ActionGroup(
|
||||
flowCategoryDisplayName,
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "navigation2d.h"
|
||||
|
||||
#include <QGestureEvent>
|
||||
#include <QWheelEvent>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
Navigation2dScrollBar::Navigation2dScrollBar(QWidget *parent)
|
||||
: QScrollBar(parent)
|
||||
{}
|
||||
|
||||
bool Navigation2dScrollBar::postEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Wheel) {
|
||||
wheelEvent(static_cast<QWheelEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Navigation2dScrollBar::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (!event->angleDelta().isNull())
|
||||
QScrollBar::wheelEvent(event);
|
||||
}
|
||||
|
||||
|
||||
Navigation2dFilter::Navigation2dFilter(QWidget *parent, Navigation2dScrollBar *scrollbar)
|
||||
: QObject(parent)
|
||||
, m_scrollbar(scrollbar)
|
||||
{
|
||||
if (parent)
|
||||
parent->grabGesture(Qt::PinchGesture);
|
||||
}
|
||||
|
||||
bool Navigation2dFilter::eventFilter(QObject *, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Gesture)
|
||||
return gestureEvent(static_cast<QGestureEvent *>(event));
|
||||
else if (event->type() == QEvent::Wheel && m_scrollbar)
|
||||
return wheelEvent(static_cast<QWheelEvent *>(event));
|
||||
|
||||
return QObject::event(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) {
|
||||
emit zoomChanged(-(1.0 - pinch->scaleFactor()), pinch->startCenterPoint());
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (m_scrollbar->postEvent(event))
|
||||
event->ignore();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QScrollBar>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QGestureEvent)
|
||||
QT_FORWARD_DECLARE_CLASS(QWheelEvent)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Navigation2dScrollBar : public QScrollBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Navigation2dScrollBar(QWidget *parent = nullptr);
|
||||
|
||||
bool postEvent(QEvent *event);
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
};
|
||||
|
||||
|
||||
class Navigation2dFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void zoomChanged(double scale, const QPointF &pos);
|
||||
|
||||
public:
|
||||
Navigation2dFilter(QWidget *parent = nullptr, Navigation2dScrollBar *scrollbar = nullptr);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
private:
|
||||
bool gestureEvent(QGestureEvent *event);
|
||||
bool wheelEvent(QWheelEvent *event);
|
||||
Navigation2dScrollBar *m_scrollbar = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -107,6 +107,8 @@ public:
|
||||
idAliasOff,
|
||||
idAliasOn,
|
||||
listView,
|
||||
lockOff,
|
||||
lockOn,
|
||||
mergeCells,
|
||||
minus,
|
||||
plus,
|
||||
@@ -129,6 +131,8 @@ public:
|
||||
undo,
|
||||
upDownIcon,
|
||||
upDownSquare2,
|
||||
visibilityOff,
|
||||
visibilityOn,
|
||||
wildcard,
|
||||
zoomAll,
|
||||
zoomIn,
|
||||
|
||||
@@ -75,6 +75,23 @@ ConnectionModel::ConnectionModel(ConnectionView *parent)
|
||||
connect(this, &QStandardItemModel::dataChanged, this, &ConnectionModel::handleDataChanged);
|
||||
}
|
||||
|
||||
Qt::ItemFlags ConnectionModel::flags(const QModelIndex &modelIndex) const
|
||||
{
|
||||
if (!modelIndex.isValid())
|
||||
return Qt::ItemIsEnabled;
|
||||
|
||||
if (!m_connectionView || !m_connectionView->model())
|
||||
return Qt::ItemIsEnabled;
|
||||
|
||||
const int internalId = data(index(modelIndex.row(), TargetModelNodeRow), UserRoles::InternalIdRole).toInt();
|
||||
ModelNode modelNode = m_connectionView->modelNodeForInternalId(internalId);
|
||||
|
||||
if (modelNode.isValid() && ModelNode::isThisOrAncestorLocked(modelNode))
|
||||
return Qt::ItemIsEnabled;
|
||||
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
||||
}
|
||||
|
||||
void ConnectionModel::resetModel()
|
||||
{
|
||||
beginResetModel();
|
||||
@@ -82,7 +99,7 @@ void ConnectionModel::resetModel()
|
||||
setHorizontalHeaderLabels(QStringList({ tr("Target"), tr("Signal Handler"), tr("Action") }));
|
||||
|
||||
if (connectionView()->isAttached()) {
|
||||
for (const ModelNode modelNode : connectionView()->allModelNodes())
|
||||
for (const ModelNode &modelNode : connectionView()->allModelNodes())
|
||||
addModelNode(modelNode);
|
||||
}
|
||||
|
||||
@@ -94,8 +111,8 @@ void ConnectionModel::resetModel()
|
||||
|
||||
SignalHandlerProperty ConnectionModel::signalHandlerPropertyForRow(int rowNumber) const
|
||||
{
|
||||
const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt();
|
||||
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2).toString();
|
||||
const int internalId = data(index(rowNumber, TargetModelNodeRow), UserRoles::InternalIdRole).toInt();
|
||||
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), UserRoles::TargetPropertyNameRole).toString();
|
||||
|
||||
ModelNode modelNode = connectionView()->modelNodeForInternalId(internalId);
|
||||
if (modelNode.isValid())
|
||||
@@ -256,8 +273,8 @@ void ConnectionModel::updateTargetNode(int rowNumber)
|
||||
|
||||
void ConnectionModel::updateCustomData(QStandardItem *item, const SignalHandlerProperty &signalHandlerProperty)
|
||||
{
|
||||
item->setData(signalHandlerProperty.parentModelNode().internalId(), Qt::UserRole + 1);
|
||||
item->setData(signalHandlerProperty.name(), Qt::UserRole + 2);
|
||||
item->setData(signalHandlerProperty.parentModelNode().internalId(), UserRoles::InternalIdRole);
|
||||
item->setData(signalHandlerProperty.name(), UserRoles::TargetPropertyNameRole);
|
||||
}
|
||||
|
||||
ModelNode ConnectionModel::getTargetNodeForConnection(const ModelNode &connection) const
|
||||
|
||||
@@ -48,7 +48,14 @@ public:
|
||||
TargetPropertyNameRow = 1,
|
||||
SourceRow = 2
|
||||
};
|
||||
enum UserRoles {
|
||||
InternalIdRole = Qt::UserRole + 1,
|
||||
TargetPropertyNameRole
|
||||
};
|
||||
ConnectionModel(ConnectionView *parent = nullptr);
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &modelIndex) const override;
|
||||
|
||||
void resetModel();
|
||||
SignalHandlerProperty signalHandlerPropertyForRow(int rowNumber) const;
|
||||
ConnectionView *connectionView() const;
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <variantproperty.h>
|
||||
#include <signalhandlerproperty.h>
|
||||
|
||||
#include <QTableView>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace Internal {
|
||||
@@ -162,6 +164,33 @@ void ConnectionView::selectedNodesChanged(const QList<ModelNode> & selectedNodeL
|
||||
emit connectionViewWidget()->setEnabledAddButton(selectedNodeList.count() == 1);
|
||||
}
|
||||
|
||||
void ConnectionView::auxiliaryDataChanged(const ModelNode &node,
|
||||
const PropertyName &name,
|
||||
const QVariant &data)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
|
||||
// Check if the auxiliary data is actually the locked property or if it is unlocked
|
||||
if (name != QmlDesigner::lockedProperty || !data.toBool())
|
||||
return;
|
||||
|
||||
QItemSelectionModel *selectionModel = connectionTableView()->selectionModel();
|
||||
if (!selectionModel->hasSelection())
|
||||
return;
|
||||
|
||||
QModelIndex modelIndex = selectionModel->currentIndex();
|
||||
if (!modelIndex.isValid() || !model())
|
||||
return;
|
||||
|
||||
const int internalId = connectionModel()->data(connectionModel()->index(modelIndex.row(),
|
||||
ConnectionModel::TargetModelNodeRow),
|
||||
ConnectionModel::UserRoles::InternalIdRole).toInt();
|
||||
ModelNode modelNode = modelNodeForInternalId(internalId);
|
||||
|
||||
if (modelNode.isValid() && ModelNode::isThisOrAncestorLocked(modelNode))
|
||||
selectionModel->clearSelection();
|
||||
}
|
||||
|
||||
void ConnectionView::importsChanged(const QList<Import> & /*addedImports*/, const QList<Import> & /*removedImports*/)
|
||||
{
|
||||
backendModel()->resetModel();
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
|
||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||
void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override;
|
||||
|
||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "axis.h"
|
||||
#include "curveeditormodel.h"
|
||||
#include "curveitem.h"
|
||||
#include "navigation2d.h"
|
||||
#include "treeitem.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -79,6 +80,13 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
update();
|
||||
|
||||
QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this);
|
||||
auto zoomChanged = &QmlDesigner::Navigation2dFilter::zoomChanged;
|
||||
connect(filter, zoomChanged, [this](double scale, const QPointF &pos) {
|
||||
applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint()));
|
||||
});
|
||||
installEventFilter(filter);
|
||||
}
|
||||
|
||||
GraphicsView::~GraphicsView()
|
||||
|
||||
@@ -41,8 +41,11 @@ struct HandleGeometry
|
||||
handle = QRectF(topLeft, -topLeft);
|
||||
toKeyframe = QLineF(QPointF(0.0, 0.0), -pos);
|
||||
angle = -toKeyframe.angle() + 45.0;
|
||||
bbox = handle.united(QRectF(-pos, QSizeF(1.0,1.0)));
|
||||
}
|
||||
|
||||
QRectF bbox;
|
||||
|
||||
QRectF handle;
|
||||
|
||||
QLineF toKeyframe;
|
||||
@@ -97,7 +100,7 @@ HandleItem::Slot HandleItem::slot() const
|
||||
QRectF HandleItem::boundingRect() const
|
||||
{
|
||||
HandleGeometry geom(pos(), m_style);
|
||||
return geom.handle;
|
||||
return geom.bbox;
|
||||
}
|
||||
|
||||
bool HandleItem::contains(const QPointF &point) const
|
||||
|
||||
@@ -189,7 +189,7 @@ FormEditorItem *AbstractFormEditorTool::topMovableFormEditorItem(const QList<QGr
|
||||
FormEditorItem* AbstractFormEditorTool::nearestFormEditorItem(const QPointF &point, const QList<QGraphicsItem*> &itemList)
|
||||
{
|
||||
FormEditorItem* nearestItem = nullptr;
|
||||
foreach (QGraphicsItem *item, itemList) {
|
||||
for (QGraphicsItem *item : itemList) {
|
||||
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
|
||||
|
||||
if (formEditorItem && formEditorItem->flowHitTest(point))
|
||||
@@ -201,6 +201,9 @@ FormEditorItem* AbstractFormEditorTool::nearestFormEditorItem(const QPointF &poi
|
||||
if (formEditorItem->parentItem() && !formEditorItem->parentItem()->isContentVisible())
|
||||
continue;
|
||||
|
||||
if (formEditorItem && ModelNode::isThisOrAncestorLocked(formEditorItem->qmlItemNode().modelNode()))
|
||||
continue;
|
||||
|
||||
if (!nearestItem)
|
||||
nearestItem = formEditorItem;
|
||||
else if (formEditorItem->selectionWeigth(point, 1) < nearestItem->selectionWeigth(point, 0))
|
||||
|
||||
@@ -250,7 +250,6 @@ void DragTool::dropEvent(const QList<QGraphicsItem *> &/*itemList*/, QGraphicsSc
|
||||
if (m_dragNode.isValid())
|
||||
view()->setSelectedModelNode(m_dragNode);
|
||||
|
||||
|
||||
m_dragNode = QmlItemNode();
|
||||
|
||||
view()->changeToSelectionTool();
|
||||
|
||||
@@ -286,6 +286,7 @@ bool FormEditorItem::flowHitTest(const QPointF & ) const
|
||||
void FormEditorItem::setFrameColor(const QColor &color)
|
||||
{
|
||||
m_frameColor = color;
|
||||
update();
|
||||
}
|
||||
|
||||
FormEditorItem::~FormEditorItem()
|
||||
|
||||
@@ -90,10 +90,10 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType)
|
||||
if (!m_beginFormEditorItem)
|
||||
return;
|
||||
|
||||
QList<QGraphicsItem*> itemList = m_editorView->scene()->items(m_selectionRectangleElement.rect(), Qt::IntersectsItemBoundingRect);
|
||||
QList<QGraphicsItem *> itemList = m_editorView->scene()->items(m_selectionRectangleElement.rect(), Qt::IntersectsItemBoundingRect);
|
||||
QList<QmlItemNode> newNodeList;
|
||||
|
||||
foreach (QGraphicsItem* item, itemList)
|
||||
for (QGraphicsItem *item : itemList)
|
||||
{
|
||||
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
|
||||
|
||||
@@ -137,7 +137,7 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType)
|
||||
}
|
||||
|
||||
|
||||
void RubberBandSelectionManipulator::setItems(const QList<FormEditorItem*> &itemList)
|
||||
void RubberBandSelectionManipulator::setItems(const QList<FormEditorItem *> &itemList)
|
||||
{
|
||||
m_itemList = itemList;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
@@ -57,6 +58,7 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
@@ -375,9 +377,41 @@ void DesignDocument::deleteSelected()
|
||||
if (!currentModel())
|
||||
return;
|
||||
|
||||
QStringList lockedNodes;
|
||||
for (const ModelNode &modelNode : view()->selectedModelNodes()) {
|
||||
for (const ModelNode &node : modelNode.allSubModelNodesAndThisNode()) {
|
||||
if (node.isValid() && !node.isRootNode() && node.locked())
|
||||
lockedNodes.push_back(node.id());
|
||||
}
|
||||
}
|
||||
|
||||
if (!lockedNodes.empty()) {
|
||||
Utils::sort(lockedNodes);
|
||||
QString detailedText = QString("<b>" + tr("Locked items:") + "</b><br>");
|
||||
|
||||
for (const auto &id : qAsConst(lockedNodes))
|
||||
detailedText.append("- " + id + "<br>");
|
||||
|
||||
detailedText.chop(QString("<br>").size());
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setTextFormat(Qt::RichText);
|
||||
msgBox.setIcon(QMessageBox::Question);
|
||||
msgBox.setWindowTitle(tr("Delete/Cut Item"));
|
||||
msgBox.setText(QString(tr("Deleting or cutting this item will modify locked items.") + "<br><br>%1")
|
||||
.arg(detailedText));
|
||||
msgBox.setInformativeText(tr("Do you want to continue by removing the item (Delete) or removing it and copying it to the clipboard (Cut)?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
|
||||
if (msgBox.exec() == QMessageBox::Cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
rewriterView()->executeInTransaction("DesignDocument::deleteSelected", [this](){
|
||||
QList<ModelNode> toDelete = view()->selectedModelNodes();
|
||||
foreach (ModelNode node, toDelete) {
|
||||
|
||||
for (ModelNode node : toDelete) {
|
||||
if (node.isValid() && !node.isRootNode() && QmlObjectNode::isValidQmlObjectNode(node))
|
||||
QmlObjectNode(node).destroy();
|
||||
}
|
||||
@@ -545,7 +579,7 @@ void DesignDocument::paste()
|
||||
}
|
||||
view.setSelectedModelNodes({pastedNode});
|
||||
});
|
||||
NodeMetaInfo::clearCache();
|
||||
view.model()->clearMetaInfoCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ qtHaveModule(quick3dassetimport) {
|
||||
|
||||
# Input
|
||||
HEADERS += itemlibraryview.h \
|
||||
$$PWD/itemlibraryiconimageprovider.h \
|
||||
itemlibrarywidget.h \
|
||||
itemlibrarymodel.h \
|
||||
itemlibraryresourceview.h \
|
||||
@@ -19,6 +20,7 @@ HEADERS += itemlibraryview.h \
|
||||
customfilesystemmodel.h
|
||||
|
||||
SOURCES += itemlibraryview.cpp \
|
||||
$$PWD/itemlibraryiconimageprovider.cpp \
|
||||
itemlibrarywidget.cpp \
|
||||
itemlibrarymodel.cpp \
|
||||
itemlibraryresourceview.cpp \
|
||||
|
||||
@@ -502,7 +502,6 @@ bool ItemLibraryAssetImporter::generateComponentIcon(int size, const QString &ic
|
||||
QProcessUniquePointer process = puppetCreator.createPuppetProcess(
|
||||
"custom",
|
||||
{},
|
||||
this,
|
||||
std::function<void()>(),
|
||||
[&](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
processFinished(exitCode, exitStatus);
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "itemlibraryiconimageprovider.h"
|
||||
|
||||
#include <projectexplorer/target.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QMetaObject>
|
||||
#include <QQuickImageResponse>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ImageRespose : public QQuickImageResponse
|
||||
{
|
||||
public:
|
||||
QQuickTextureFactory *textureFactory() const override
|
||||
{
|
||||
return QQuickTextureFactory::textureFactoryForImage(m_image);
|
||||
}
|
||||
|
||||
void setImage(const QImage &image)
|
||||
{
|
||||
m_image = image;
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void abort()
|
||||
{
|
||||
m_image = QImage{
|
||||
Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/item-default-icon.png")};
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
private:
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
|
||||
QQuickImageResponse *ItemLibraryIconImageProvider::requestImageResponse(const QString &id,
|
||||
const QSize &)
|
||||
{
|
||||
auto response = std::make_unique<ImageRespose>();
|
||||
|
||||
m_cache.requestIcon(
|
||||
id,
|
||||
[response = QPointer<ImageRespose>(response.get())](const QImage &image) {
|
||||
QMetaObject::invokeMethod(
|
||||
response,
|
||||
[response, image] {
|
||||
if (response)
|
||||
response->setImage(image);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
},
|
||||
[response = QPointer<ImageRespose>(response.get())] {
|
||||
QMetaObject::invokeMethod(
|
||||
response,
|
||||
[response] {
|
||||
if (response)
|
||||
response->abort();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
});
|
||||
|
||||
return response.release();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nodeinstanceview.h>
|
||||
#include <rewriterview.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <imagecache.h>
|
||||
#include <imagecache/imagecachecollector.h>
|
||||
#include <imagecache/imagecacheconnectionmanager.h>
|
||||
#include <imagecache/imagecachegenerator.h>
|
||||
#include <imagecache/imagecachestorage.h>
|
||||
#include <imagecache/timestampprovider.h>
|
||||
|
||||
#include <sqlitedatabase.h>
|
||||
|
||||
#include <QQuickAsyncImageProvider>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ItemLibraryIconImageProvider : public QQuickAsyncImageProvider
|
||||
{
|
||||
public:
|
||||
ItemLibraryIconImageProvider(ImageCache &imageCache)
|
||||
: m_cache{imageCache}
|
||||
{}
|
||||
|
||||
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
||||
|
||||
private:
|
||||
ImageCache &m_cache;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -47,8 +47,18 @@ QString ItemLibraryItem::typeName() const
|
||||
|
||||
QString ItemLibraryItem::itemLibraryIconPath() const
|
||||
{
|
||||
//Prepend image provider prefix
|
||||
return QStringLiteral("image://qmldesigner_itemlibrary/") + m_itemLibraryEntry.libraryEntryIconPath();
|
||||
if (m_itemLibraryEntry.customComponentSource().isEmpty()) {
|
||||
return QStringLiteral("image://qmldesigner_itemlibrary/")
|
||||
+ m_itemLibraryEntry.libraryEntryIconPath();
|
||||
} else {
|
||||
return QStringLiteral("image://itemlibrary_preview/")
|
||||
+ m_itemLibraryEntry.customComponentSource();
|
||||
}
|
||||
}
|
||||
|
||||
QString ItemLibraryItem::componentPath() const
|
||||
{
|
||||
return m_itemLibraryEntry.customComponentSource();
|
||||
}
|
||||
|
||||
bool ItemLibraryItem::setVisible(bool isVisible)
|
||||
|
||||
@@ -42,6 +42,7 @@ class ItemLibraryItem: public QObject {
|
||||
Q_PROPERTY(QString itemName READ itemName FINAL)
|
||||
Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL)
|
||||
Q_PROPERTY(bool itemVisible READ isVisible NOTIFY visibilityChanged FINAL)
|
||||
Q_PROPERTY(QString componentPath READ componentPath FINAL)
|
||||
|
||||
public:
|
||||
ItemLibraryItem(QObject *parent);
|
||||
@@ -50,6 +51,7 @@ public:
|
||||
QString itemName() const;
|
||||
QString typeName() const;
|
||||
QString itemLibraryIconPath() const;
|
||||
QString componentPath() const;
|
||||
|
||||
bool setVisible(bool isVisible);
|
||||
bool isVisible() const;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "itemlibraryitem.h"
|
||||
#include "itemlibrarysection.h"
|
||||
|
||||
#include <components/previewtooltip/previewtooltipbackend.h>
|
||||
|
||||
#include <model.h>
|
||||
#include <nodehints.h>
|
||||
#include <nodemetainfo.h>
|
||||
|
||||
@@ -25,24 +25,47 @@
|
||||
|
||||
#include "itemlibraryview.h"
|
||||
#include "itemlibrarywidget.h"
|
||||
#include "metainfo.h"
|
||||
#include <bindingproperty.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <imagecache.h>
|
||||
#include <imagecache/imagecachecollector.h>
|
||||
#include <imagecache/imagecacheconnectionmanager.h>
|
||||
#include <imagecache/imagecachegenerator.h>
|
||||
#include <imagecache/imagecachestorage.h>
|
||||
#include <imagecache/timestampprovider.h>
|
||||
#include <import.h>
|
||||
#include <importmanagerview.h>
|
||||
#include <qmlitemnode.h>
|
||||
#include <rewriterview.h>
|
||||
#include <bindingproperty.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <rewriterview.h>
|
||||
#include <sqlitedatabase.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include "metainfo.h"
|
||||
#include <qmlitemnode.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ImageCacheData
|
||||
{
|
||||
public:
|
||||
Sqlite::Database database{
|
||||
Utils::PathString{Core::ICore::cacheResourcePath() + "/imagecache-v1.db"}};
|
||||
ImageCacheStorage<Sqlite::Database> storage{database};
|
||||
ImageCacheConnectionManager connectionManager;
|
||||
ImageCacheCollector collector{connectionManager};
|
||||
ImageCacheGenerator generator{collector, storage};
|
||||
TimeStampProvider timeStampProvider;
|
||||
ImageCache cache{storage, generator, timeStampProvider};
|
||||
};
|
||||
|
||||
ItemLibraryView::ItemLibraryView(QObject* parent)
|
||||
: AbstractView(parent),
|
||||
m_importManagerView(new ImportManagerView(this))
|
||||
|
||||
{
|
||||
|
||||
m_imageCacheData = std::make_unique<ImageCacheData>();
|
||||
}
|
||||
|
||||
ItemLibraryView::~ItemLibraryView() = default;
|
||||
@@ -55,7 +78,7 @@ bool ItemLibraryView::hasWidget() const
|
||||
WidgetInfo ItemLibraryView::widgetInfo()
|
||||
{
|
||||
if (m_widget.isNull()) {
|
||||
m_widget = new ItemLibraryWidget;
|
||||
m_widget = new ItemLibraryWidget{m_imageCacheData->cache};
|
||||
m_widget->setImportsWidget(m_importManagerView->widgetInfo().widget);
|
||||
}
|
||||
|
||||
@@ -70,6 +93,16 @@ WidgetInfo ItemLibraryView::widgetInfo()
|
||||
void ItemLibraryView::modelAttached(Model *model)
|
||||
{
|
||||
AbstractView::modelAttached(model);
|
||||
auto target = QmlDesignerPlugin::instance()->currentDesignDocument()->currentTarget();
|
||||
m_imageCacheData->cache.clean();
|
||||
|
||||
if (target) {
|
||||
auto clonedTarget = std::make_unique<ProjectExplorer::Target>(
|
||||
target->project(), target->kit()->clone(), ProjectExplorer::Target::_constructor_tag{});
|
||||
|
||||
m_imageCacheData->collector.setTarget(std::move(clonedTarget));
|
||||
}
|
||||
|
||||
m_widget->clearSearchFilter();
|
||||
m_widget->setModel(model);
|
||||
updateImports();
|
||||
@@ -83,6 +116,8 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model)
|
||||
{
|
||||
model->detachView(m_importManagerView);
|
||||
|
||||
m_imageCacheData->collector.setTarget({});
|
||||
|
||||
AbstractView::modelAboutToBeDetached(model);
|
||||
|
||||
m_widget->setModel(nullptr);
|
||||
@@ -124,7 +159,7 @@ void ItemLibraryView::importsChanged(const QList<Import> &addedImports, const QL
|
||||
void ItemLibraryView::setResourcePath(const QString &resourcePath)
|
||||
{
|
||||
if (m_widget.isNull())
|
||||
m_widget = new ItemLibraryWidget;
|
||||
m_widget = new ItemLibraryWidget{m_imageCacheData->cache};
|
||||
|
||||
m_widget->setResourcePath(resourcePath);
|
||||
}
|
||||
@@ -142,4 +177,4 @@ void ItemLibraryView::updateImports()
|
||||
m_widget->delayedUpdateModel();
|
||||
}
|
||||
|
||||
} //QmlDesigner
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace QmlDesigner {
|
||||
|
||||
class ItemLibraryWidget;
|
||||
class ImportManagerView;
|
||||
class ImageCacheData;
|
||||
|
||||
class ItemLibraryView : public AbstractView
|
||||
{
|
||||
@@ -58,6 +59,7 @@ protected:
|
||||
void updateImports();
|
||||
|
||||
private:
|
||||
std::unique_ptr<ImageCacheData> m_imageCacheData;
|
||||
QPointer<ItemLibraryWidget> m_widget;
|
||||
ImportManagerView *m_importManagerView;
|
||||
bool m_hasErrors = false;
|
||||
|
||||
@@ -27,19 +27,21 @@
|
||||
|
||||
#include "customfilesystemmodel.h"
|
||||
#include "itemlibraryassetimportdialog.h"
|
||||
#include "itemlibraryiconimageprovider.h"
|
||||
|
||||
#include <theme.h>
|
||||
|
||||
#include <itemlibrarymodel.h>
|
||||
#include <itemlibraryimageprovider.h>
|
||||
#include <itemlibraryinfo.h>
|
||||
#include <metainfo.h>
|
||||
#include <model.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <designeractionmanager.h>
|
||||
#include <designermcumanager.h>
|
||||
#include <itemlibraryimageprovider.h>
|
||||
#include <itemlibraryinfo.h>
|
||||
#include <itemlibrarymodel.h>
|
||||
#include <metainfo.h>
|
||||
#include <model.h>
|
||||
#include <previewtooltip/previewtooltipbackend.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/flowlayout.h>
|
||||
@@ -81,14 +83,14 @@ static QString propertyEditorResourcesPath() {
|
||||
return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/propertyEditorQmlSources");
|
||||
}
|
||||
|
||||
ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
QFrame(parent),
|
||||
m_itemIconSize(24, 24),
|
||||
m_itemViewQuickWidget(new QQuickWidget(this)),
|
||||
m_resourcesView(new ItemLibraryResourceView(this)),
|
||||
m_importTagsWidget(new QWidget(this)),
|
||||
m_addResourcesWidget(new QWidget(this)),
|
||||
m_filterFlag(QtBasic)
|
||||
ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache)
|
||||
: m_itemIconSize(24, 24)
|
||||
, m_itemViewQuickWidget(new QQuickWidget(this))
|
||||
, m_resourcesView(new ItemLibraryResourceView(this))
|
||||
, m_importTagsWidget(new QWidget(this))
|
||||
, m_addResourcesWidget(new QWidget(this))
|
||||
, m_imageCache{imageCache}
|
||||
, m_filterFlag(QtBasic)
|
||||
{
|
||||
m_compressionTimer.setInterval(200);
|
||||
m_compressionTimer.setSingleShot(true);
|
||||
@@ -102,16 +104,20 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
m_itemViewQuickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
m_itemLibraryModel = new ItemLibraryModel(this);
|
||||
|
||||
m_itemViewQuickWidget->rootContext()->setContextProperties(
|
||||
QVector<QQmlContext::PropertyPair>{
|
||||
{{"itemLibraryModel"}, QVariant::fromValue(m_itemLibraryModel.data())},
|
||||
{{"itemLibraryIconWidth"}, m_itemIconSize.width()},
|
||||
{{"itemLibraryIconHeight"}, m_itemIconSize.height()},
|
||||
{{"rootView"}, QVariant::fromValue(this)},
|
||||
{{"highlightColor"}, Utils::StyleHelper::notTooBrightHighlightColor()}
|
||||
}
|
||||
);
|
||||
m_itemViewQuickWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||
m_itemViewQuickWidget->rootContext()->setContextProperties(QVector<QQmlContext::PropertyPair>{
|
||||
{{"itemLibraryModel"}, QVariant::fromValue(m_itemLibraryModel.data())},
|
||||
{{"itemLibraryIconWidth"}, m_itemIconSize.width()},
|
||||
{{"itemLibraryIconHeight"}, m_itemIconSize.height()},
|
||||
{{"rootView"}, QVariant::fromValue(this)},
|
||||
{{"highlightColor"}, Utils::StyleHelper::notTooBrightHighlightColor()},
|
||||
});
|
||||
|
||||
m_previewTooltipBackend = std::make_unique<PreviewTooltipBackend>(m_imageCache);
|
||||
m_itemViewQuickWidget->rootContext()->setContextProperty("tooltipBackend",
|
||||
m_previewTooltipBackend.get());
|
||||
|
||||
m_itemViewQuickWidget->setClearColor(
|
||||
Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||
|
||||
/* create Resources view and its model */
|
||||
m_resourcesFileSystemModel = new CustomFileSystemModel(this);
|
||||
@@ -119,6 +125,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
|
||||
/* create image provider for loading item icons */
|
||||
m_itemViewQuickWidget->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider);
|
||||
|
||||
Theme::setupTheme(m_itemViewQuickWidget->engine());
|
||||
|
||||
/* other widgets */
|
||||
@@ -243,6 +250,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
reloadQmlSource();
|
||||
}
|
||||
|
||||
ItemLibraryWidget::~ItemLibraryWidget() = default;
|
||||
|
||||
void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo)
|
||||
{
|
||||
if (m_itemLibraryInfo.data() == itemLibraryInfo)
|
||||
@@ -306,9 +315,14 @@ void ItemLibraryWidget::delayedUpdateModel()
|
||||
|
||||
void ItemLibraryWidget::setModel(Model *model)
|
||||
{
|
||||
m_itemViewQuickWidget->engine()->removeImageProvider("itemlibrary_preview");
|
||||
m_model = model;
|
||||
if (!model)
|
||||
return;
|
||||
|
||||
m_itemViewQuickWidget->engine()->addImageProvider("itemlibrary_preview",
|
||||
new ItemLibraryIconImageProvider{m_imageCache});
|
||||
|
||||
setItemLibraryInfo(model->metaInfo().itemLibraryInfo());
|
||||
}
|
||||
|
||||
@@ -318,7 +332,8 @@ void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index)
|
||||
m_filterLineEdit->setVisible(false);
|
||||
m_importTagsWidget->setVisible(true);
|
||||
m_addResourcesWidget->setVisible(false);
|
||||
} if (index == 1) {
|
||||
}
|
||||
if (index == 1) {
|
||||
m_filterLineEdit->setVisible(true);
|
||||
m_importTagsWidget->setVisible(false);
|
||||
m_addResourcesWidget->setVisible(true);
|
||||
@@ -564,5 +579,4 @@ void ItemLibraryWidget::addResources()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include <QQmlPropertyMap>
|
||||
#include <QTimer>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QStackedWidget;
|
||||
class QShortcut;
|
||||
@@ -52,6 +54,9 @@ class CustomFileSystemModel;
|
||||
|
||||
class ItemLibraryModel;
|
||||
class ItemLibraryResourceView;
|
||||
class PreviewTooltipBackend;
|
||||
class ImageCache;
|
||||
class ImageCacheCollector;
|
||||
|
||||
class ItemLibraryWidget : public QFrame
|
||||
{
|
||||
@@ -63,7 +68,8 @@ class ItemLibraryWidget : public QFrame
|
||||
};
|
||||
|
||||
public:
|
||||
ItemLibraryWidget(QWidget *parent = nullptr);
|
||||
ItemLibraryWidget(ImageCache &imageCache);
|
||||
~ItemLibraryWidget();
|
||||
|
||||
void setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo);
|
||||
QList<QToolButton *> createToolBarWidgets();
|
||||
@@ -115,9 +121,10 @@ private:
|
||||
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
||||
QScopedPointer<QWidget> m_importTagsWidget;
|
||||
QScopedPointer<QWidget> m_addResourcesWidget;
|
||||
std::unique_ptr<PreviewTooltipBackend> m_previewTooltipBackend;
|
||||
|
||||
QShortcut *m_qmlSourceUpdateShortcut;
|
||||
|
||||
ImageCache &m_imageCache;
|
||||
QPointer<Model> m_model;
|
||||
FilterChangeFlag m_filterFlag;
|
||||
ItemLibraryEntry m_currentitemLibraryEntry;
|
||||
|
||||
@@ -82,6 +82,12 @@ void IconCheckboxItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &styleOption,
|
||||
const QModelIndex &modelIndex) const
|
||||
{
|
||||
bool isVisibilityIcon = modelIndex.column() != NavigatorTreeModel::ColumnType::Visibility;
|
||||
// We need to invert the check status if visibility icon
|
||||
bool checked = isVisibilityIcon ? isChecked(modelIndex) : !isChecked(modelIndex);
|
||||
if (!(styleOption.state & QStyle::State_MouseOver) && !checked)
|
||||
return;
|
||||
|
||||
if (rowIsPropertyRole(modelIndex.model(), modelIndex))
|
||||
return; //Do not paint icons for property rows
|
||||
|
||||
|
||||
@@ -200,10 +200,10 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
||||
if (!modelNode.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == ItemIsVisibleRole) //independent of column
|
||||
if (role == ItemIsVisibleRole) // independent of column
|
||||
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
||||
|
||||
if (index.column() == 0) {
|
||||
if (index.column() == ColumnType::Name) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
return modelNode.displayName();
|
||||
} else if (role == Qt::DecorationRole) {
|
||||
@@ -240,18 +240,24 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
||||
} else if (role == ModelNodeRole) {
|
||||
return QVariant::fromValue<ModelNode>(modelNode);
|
||||
}
|
||||
} else if (index.column() == 1) { //export
|
||||
} else if (index.column() == ColumnType::Alias) { // export
|
||||
if (role == Qt::CheckStateRole)
|
||||
return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked;
|
||||
return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked;
|
||||
else if (role == Qt::ToolTipRole)
|
||||
return tr("Toggles whether this item is exported as an "
|
||||
"alias property of the root item.");
|
||||
} else if (index.column() == 2) { //visible
|
||||
} else if (index.column() == ColumnType::Visibility) { // visible
|
||||
if (role == Qt::CheckStateRole)
|
||||
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
||||
else if (role == Qt::ToolTipRole)
|
||||
return tr("Toggles the visibility of this item in the form editor.\n"
|
||||
"This is independent of the visibility property in QML.");
|
||||
} else if (index.column() == ColumnType::Lock) { // lock
|
||||
if (role == Qt::CheckStateRole)
|
||||
return modelNode.locked() ? Qt::Checked : Qt::Unchecked;
|
||||
else if (role == Qt::ToolTipRole)
|
||||
return tr("Toggles whether this item is locked.\n"
|
||||
"Locked items can't be modified or selected.");
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -259,7 +265,16 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == 0)
|
||||
if (index.column() == ColumnType::Alias
|
||||
|| index.column() == ColumnType::Visibility
|
||||
|| index.column() == ColumnType::Lock)
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren;
|
||||
|
||||
const ModelNode modelNode = modelNodeForIndex(index);
|
||||
if (ModelNode::isThisOrAncestorLocked(modelNode))
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
if (index.column() == ColumnType::Name)
|
||||
return Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
||||
@@ -378,7 +393,7 @@ int NavigatorTreeModel::columnCount(const QModelIndex &parent) const
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
return 3;
|
||||
return ColumnType::Count;
|
||||
}
|
||||
|
||||
ModelNode NavigatorTreeModel::modelNodeForIndex(const QModelIndex &index) const
|
||||
@@ -755,7 +770,8 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper
|
||||
|
||||
auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex](){
|
||||
const TypeName propertyQmlType = parentProperty.parentModelNode().metaInfo().propertyTypeName(parentProperty.name());
|
||||
foreach (const ModelNode &modelNode, modelNodes) {
|
||||
int idx = targetIndex;
|
||||
for (const ModelNode &modelNode : modelNodes) {
|
||||
if (modelNode.isValid()
|
||||
&& modelNode != parentProperty.parentModelNode()
|
||||
&& !modelNode.isAncestorOf(parentProperty.parentModelNode())
|
||||
@@ -764,10 +780,9 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper
|
||||
//once the MetaInfo is part of instances we can do this right
|
||||
|
||||
bool nodeCanBeMovedToParentProperty = removeModelNodeFromNodeProperty(parentProperty, modelNode);
|
||||
|
||||
if (nodeCanBeMovedToParentProperty) {
|
||||
reparentModelNodeToNodeProperty(parentProperty, modelNode);
|
||||
slideModelNodeInList(parentProperty, modelNode, targetIndex);
|
||||
slideModelNodeInList(parentProperty, modelNode, idx++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,11 +807,13 @@ Qt::DropActions NavigatorTreeModel::supportedDragActions() const
|
||||
bool NavigatorTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
ModelNode modelNode = modelNodeForIndex(index);
|
||||
if (index.column() == 1 && role == Qt::CheckStateRole) {
|
||||
if (index.column() == ColumnType::Alias && role == Qt::CheckStateRole) {
|
||||
QTC_ASSERT(m_view, return false);
|
||||
m_view->handleChangedExport(modelNode, value.toInt() != 0);
|
||||
} else if (index.column() == 2 && role == Qt::CheckStateRole) {
|
||||
} else if (index.column() == ColumnType::Visibility && role == Qt::CheckStateRole) {
|
||||
QmlVisualNode(modelNode).setVisibilityOverride(value.toInt() == 0);
|
||||
} else if (index.column() == ColumnType::Lock && role == Qt::CheckStateRole) {
|
||||
modelNode.setLocked(value.toInt() != 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -806,7 +823,7 @@ void NavigatorTreeModel::notifyDataChanged(const ModelNode &modelNode)
|
||||
{
|
||||
const QModelIndex index = indexForModelNode(modelNode);
|
||||
const QAbstractItemModel *model = index.model();
|
||||
const QModelIndex sibling = model ? model->sibling(index.row(), 2, index) : QModelIndex();
|
||||
const QModelIndex sibling = model ? model->sibling(index.row(), ColumnType::Count - 1, index) : QModelIndex();
|
||||
emit dataChanged(index, sibling);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,14 @@ class NavigatorTreeModel : public QAbstractItemModel, public NavigatorModelInter
|
||||
|
||||
public:
|
||||
|
||||
enum ColumnType {
|
||||
Name = 0,
|
||||
Alias,
|
||||
Visibility,
|
||||
Lock,
|
||||
Count
|
||||
};
|
||||
|
||||
explicit NavigatorTreeModel(QObject *parent = nullptr);
|
||||
~NavigatorTreeModel() override;
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ NavigatorTreeView::NavigatorTreeView(QWidget *parent)
|
||||
setMinimumWidth(240);
|
||||
setRootIsDecorated(false);
|
||||
setIndentation(indentation() * 0.5);
|
||||
viewport()->setAttribute(Qt::WA_Hover);
|
||||
|
||||
m_toolTipHideTimer.setSingleShot(true);
|
||||
connect(&m_toolTipHideTimer, &QTimer::timeout, [this]() {
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <qmlitemnode.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <nodeinstanceview.h>
|
||||
#include <theme.h>
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -48,6 +49,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/icon.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QTimer>
|
||||
@@ -138,13 +140,14 @@ void NavigatorView::modelAttached(Model *model)
|
||||
|
||||
QTreeView *treeView = treeWidget();
|
||||
|
||||
treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
treeView->header()->resizeSection(1,26);
|
||||
treeView->header()->setSectionResizeMode(NavigatorTreeModel::ColumnType::Name, QHeaderView::Stretch);
|
||||
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Alias, 26);
|
||||
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Visibility, 26);
|
||||
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Lock, 26);
|
||||
treeView->setIndentation(20);
|
||||
|
||||
m_currentModelInterface->setFilter(false);
|
||||
|
||||
|
||||
QTimer::singleShot(0, this, [this, treeView]() {
|
||||
m_currentModelInterface->setFilter(
|
||||
DesignerSettings::getValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS).toBool());
|
||||
@@ -166,10 +169,6 @@ void NavigatorView::modelAttached(Model *model)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#ifdef _LOCK_ITEMS_
|
||||
treeView->header()->resizeSection(2,20);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NavigatorView::modelAboutToBeDetached(Model *model)
|
||||
@@ -304,7 +303,7 @@ void NavigatorView::nodeIdChanged(const ModelNode& modelNode, const QString & /*
|
||||
m_currentModelInterface->notifyDataChanged(modelNode);
|
||||
}
|
||||
|
||||
void NavigatorView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& /*propertyList*/)
|
||||
void NavigatorView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &/*propertyList*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -321,7 +320,7 @@ void NavigatorView::propertiesRemoved(const QList<AbstractProperty> &propertyLis
|
||||
m_currentModelInterface->notifyModelNodesRemoved(modelNodes);
|
||||
}
|
||||
|
||||
void NavigatorView::rootNodeTypeChanged(const QString & /*type*/, int /*majorVersion*/, int /*minorVersion*/)
|
||||
void NavigatorView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
|
||||
{
|
||||
m_currentModelInterface->notifyDataChanged(rootModelNode());
|
||||
}
|
||||
@@ -332,9 +331,12 @@ void NavigatorView::nodeTypeChanged(const ModelNode &modelNode, const TypeName &
|
||||
}
|
||||
|
||||
void NavigatorView::auxiliaryDataChanged(const ModelNode &modelNode,
|
||||
const PropertyName & /*name*/,
|
||||
const QVariant & /*data*/)
|
||||
const PropertyName &name,
|
||||
const QVariant &data)
|
||||
{
|
||||
Q_UNUSED(name)
|
||||
Q_UNUSED(data)
|
||||
|
||||
m_currentModelInterface->notifyDataChanged(modelNode);
|
||||
}
|
||||
|
||||
@@ -344,8 +346,8 @@ void NavigatorView::instanceErrorChanged(const QVector<ModelNode> &errorNodeList
|
||||
m_currentModelInterface->notifyDataChanged(modelNode);
|
||||
}
|
||||
|
||||
void NavigatorView::nodeOrderChanged(const NodeListProperty & listProperty,
|
||||
const ModelNode & /*node*/,
|
||||
void NavigatorView::nodeOrderChanged(const NodeListProperty &listProperty,
|
||||
const ModelNode &/*node*/,
|
||||
int /*oldIndex*/)
|
||||
{
|
||||
m_currentModelInterface->notifyModelNodesMoved(listProperty.directSubNodes());
|
||||
@@ -613,33 +615,50 @@ void NavigatorView::setupWidget()
|
||||
connect(m_widget.data(), &NavigatorWidget::reverseOrderToggled, this, &NavigatorView::reverseOrderToggled);
|
||||
|
||||
#ifndef QMLDESIGNER_TEST
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
|
||||
const QIcon visibilityOnIcon =
|
||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
Theme::getIconUnicode(Theme::Icon::visibilityOn),
|
||||
28, 28, QColor(Qt::white));
|
||||
const QIcon visibilityOffIcon =
|
||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
Theme::getIconUnicode(Theme::Icon::visibilityOff),
|
||||
28, 28, QColor(Qt::white));
|
||||
|
||||
const QIcon aliasOnIcon =
|
||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
Theme::getIconUnicode(Theme::Icon::idAliasOn),
|
||||
28, 28, QColor(Qt::red));
|
||||
const QIcon aliasOffIcon =
|
||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
Theme::getIconUnicode(Theme::Icon::idAliasOff),
|
||||
28, 28, QColor(Qt::white));
|
||||
|
||||
const QIcon lockOnIcon =
|
||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
Theme::getIconUnicode(Theme::Icon::lockOn),
|
||||
28, 28, QColor(Qt::white));
|
||||
const QIcon lockOffIcon =
|
||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
Theme::getIconUnicode(Theme::Icon::lockOff),
|
||||
28, 28, QColor(Qt::white));
|
||||
|
||||
auto idDelegate = new NameItemDelegate(this);
|
||||
IconCheckboxItemDelegate *showDelegate =
|
||||
new IconCheckboxItemDelegate(this,
|
||||
Utils::Icons::EYE_OPEN_TOOLBAR.icon(),
|
||||
Utils::Icons::EYE_CLOSED_TOOLBAR.icon());
|
||||
|
||||
IconCheckboxItemDelegate *exportDelegate =
|
||||
new IconCheckboxItemDelegate(this,
|
||||
Icons::EXPORT_CHECKED.icon(),
|
||||
Icons::EXPORT_UNCHECKED.icon());
|
||||
IconCheckboxItemDelegate *visibilityDelegate =
|
||||
new IconCheckboxItemDelegate(this, visibilityOnIcon, visibilityOffIcon);
|
||||
|
||||
IconCheckboxItemDelegate *aliasDelegate =
|
||||
new IconCheckboxItemDelegate(this, aliasOnIcon, aliasOffIcon);
|
||||
|
||||
#ifdef _LOCK_ITEMS_
|
||||
IconCheckboxItemDelegate *lockDelegate =
|
||||
new IconCheckboxItemDelegate(this,
|
||||
Utils::Icons::LOCKED_TOOLBAR.icon(),
|
||||
Utils::Icons::UNLOCKED_TOOLBAR.icon());
|
||||
#endif
|
||||
new IconCheckboxItemDelegate(this, lockOnIcon, lockOffIcon);
|
||||
|
||||
|
||||
treeWidget()->setItemDelegateForColumn(0, idDelegate);
|
||||
#ifdef _LOCK_ITEMS_
|
||||
treeWidget()->setItemDelegateForColumn(1,lockDelegate);
|
||||
treeWidget()->setItemDelegateForColumn(2,showDelegate);
|
||||
#else
|
||||
treeWidget()->setItemDelegateForColumn(1, exportDelegate);
|
||||
treeWidget()->setItemDelegateForColumn(2, showDelegate);
|
||||
#endif
|
||||
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Name, idDelegate);
|
||||
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Alias, aliasDelegate);
|
||||
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Visibility, visibilityDelegate);
|
||||
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Lock, lockDelegate);
|
||||
|
||||
#endif //QMLDESIGNER_TEST
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
void propertiesRemoved(const QList<AbstractProperty>& propertyList) override;
|
||||
|
||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList ,
|
||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||
void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override;
|
||||
void instanceErrorChanged(const QVector<ModelNode> &errorNodeList) override;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ NavigatorWidget::NavigatorWidget(NavigatorView *view)
|
||||
#endif
|
||||
}
|
||||
|
||||
void NavigatorWidget::setTreeModel(QAbstractItemModel* model)
|
||||
void NavigatorWidget::setTreeModel(QAbstractItemModel *model)
|
||||
{
|
||||
m_treeView->setModel(model);
|
||||
}
|
||||
@@ -92,7 +92,6 @@ QList<QToolButton *> NavigatorWidget::createToolBarWidgets()
|
||||
{
|
||||
QList<QToolButton *> buttons;
|
||||
|
||||
|
||||
auto button = new QToolButton();
|
||||
button->setIcon(Icons::ARROW_LEFT.icon());
|
||||
button->setToolTip(tr("Become last sibling of parent (CTRL + Left)."));
|
||||
@@ -180,7 +179,6 @@ void NavigatorWidget::enableNavigator()
|
||||
m_treeView->setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
NavigatorView *NavigatorWidget::navigatorView() const
|
||||
{
|
||||
return m_navigatorView.data();
|
||||
|
||||
@@ -82,12 +82,6 @@
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="imageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
@@ -100,9 +94,6 @@
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><image></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "previewimagetooltip.h"
|
||||
#include "ui_previewimagetooltip.h"
|
||||
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
#include <QtGui/qpixmap.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
PreviewImageTooltip::PreviewImageTooltip(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(std::make_unique<Ui::PreviewImageTooltip>())
|
||||
{
|
||||
// setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setWindowFlags(Qt::ToolTip);
|
||||
m_ui->setupUi(this);
|
||||
setStyleSheet(QString("QWidget { background-color: %1 }").arg(Utils::creatorTheme()->color(Utils::Theme::BackgroundColorNormal).name()));
|
||||
}
|
||||
|
||||
PreviewImageTooltip::~PreviewImageTooltip() = default;
|
||||
|
||||
void PreviewImageTooltip::setComponentPath(const QString &path)
|
||||
{
|
||||
m_ui->componentPathLabel->setText(path);
|
||||
}
|
||||
|
||||
void PreviewImageTooltip::setComponentName(const QString &name)
|
||||
{
|
||||
m_ui->componentNameLabel->setText(name);
|
||||
}
|
||||
|
||||
void PreviewImageTooltip::setImage(const QImage &image)
|
||||
{
|
||||
resize(image.width() + 20 + m_ui->componentNameLabel->width(),
|
||||
std::max(image.height() + 20, height()));
|
||||
m_ui->imageLabel->setPixmap(QPixmap::fromImage({image}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/qwidget.h>
|
||||
#include <QtGui/qpixmap.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Ui {
|
||||
class PreviewImageTooltip;
|
||||
}
|
||||
|
||||
class PreviewImageTooltip : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PreviewImageTooltip(QWidget *parent = {});
|
||||
~PreviewImageTooltip();
|
||||
|
||||
void setComponentPath(const QString &path);
|
||||
void setComponentName(const QString &name);
|
||||
void setImage(const QImage &pixmap);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::PreviewImageTooltip> m_ui;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QmlDesigner::PreviewImageTooltip</class>
|
||||
<widget class="QWidget" name="QmlDesigner::PreviewImageTooltip">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1000</width>
|
||||
<height>1000</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizeGripEnabled" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="componentPathLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="imageLabel">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Utils::ElidingLabel" name="componentNameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Utils::ElidingLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header location="global">utils/elidinglabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,110 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "previewtooltipbackend.h"
|
||||
|
||||
#include "previewimagetooltip.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <imagecache.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QMetaObject>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
PreviewTooltipBackend::PreviewTooltipBackend(ImageCache &cache)
|
||||
: m_cache{cache}
|
||||
{}
|
||||
|
||||
PreviewTooltipBackend::~PreviewTooltipBackend()
|
||||
{
|
||||
hideTooltip();
|
||||
}
|
||||
|
||||
void PreviewTooltipBackend::showTooltip()
|
||||
{
|
||||
if (m_componentPath.isEmpty())
|
||||
return;
|
||||
|
||||
m_tooltip = std::make_unique<PreviewImageTooltip>();
|
||||
|
||||
m_tooltip->setComponentName(m_componentName);
|
||||
m_tooltip->setComponentPath(m_componentPath);
|
||||
|
||||
m_cache.requestImage(
|
||||
m_componentPath,
|
||||
[tooltip = QPointer<PreviewImageTooltip>(m_tooltip.get())](const QImage &image) {
|
||||
QMetaObject::invokeMethod(tooltip, [tooltip, image] {
|
||||
if (tooltip)
|
||||
tooltip->setImage(image);
|
||||
});
|
||||
},
|
||||
[] {});
|
||||
|
||||
auto desktopWidget = QApplication::desktop();
|
||||
auto mousePosition = desktopWidget->cursor().pos();
|
||||
|
||||
mousePosition += {20, 20};
|
||||
m_tooltip->move(mousePosition);
|
||||
m_tooltip->show();
|
||||
}
|
||||
|
||||
void PreviewTooltipBackend::hideTooltip()
|
||||
{
|
||||
if (m_tooltip)
|
||||
m_tooltip->hide();
|
||||
|
||||
m_tooltip.reset();
|
||||
}
|
||||
|
||||
QString QmlDesigner::PreviewTooltipBackend::componentPath() const
|
||||
{
|
||||
return m_componentPath;
|
||||
}
|
||||
|
||||
void QmlDesigner::PreviewTooltipBackend::setComponentPath(const QString &path)
|
||||
{
|
||||
m_componentPath = path;
|
||||
|
||||
if (m_componentPath != path)
|
||||
emit componentPathChanged();
|
||||
}
|
||||
|
||||
QString QmlDesigner::PreviewTooltipBackend::componentName() const
|
||||
{
|
||||
return m_componentName;
|
||||
}
|
||||
|
||||
void QmlDesigner::PreviewTooltipBackend::setComponentName(const QString &name)
|
||||
{
|
||||
m_componentName = name;
|
||||
|
||||
if (m_componentName != name)
|
||||
emit componentNameChanged();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class PreviewImageTooltip;
|
||||
class ImageCache;
|
||||
|
||||
class PreviewTooltipBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString componentPath READ componentPath WRITE setComponentPath NOTIFY componentPathChanged)
|
||||
Q_PROPERTY(QString componentName READ componentName WRITE setComponentName NOTIFY componentNameChanged)
|
||||
|
||||
public:
|
||||
PreviewTooltipBackend(ImageCache &cache);
|
||||
~PreviewTooltipBackend();
|
||||
|
||||
Q_INVOKABLE void showTooltip();
|
||||
Q_INVOKABLE void hideTooltip();
|
||||
|
||||
QString componentPath() const;
|
||||
void setComponentPath(const QString &path);
|
||||
|
||||
QString componentName() const;
|
||||
void setComponentName(const QString &path);
|
||||
|
||||
signals:
|
||||
void componentPathChanged();
|
||||
void componentNameChanged();
|
||||
|
||||
private:
|
||||
QString m_componentPath;
|
||||
QString m_componentName;
|
||||
std::unique_ptr<PreviewImageTooltip> m_tooltip;
|
||||
ImageCache &m_cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QML_DECLARE_TYPE(QmlDesigner::PreviewTooltipBackend)
|
||||
@@ -0,0 +1,11 @@
|
||||
HEADERS += \
|
||||
$$PWD/previewtooltipbackend.h \
|
||||
$$PWD/previewimagetooltip.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/previewtooltipbackend.cpp \
|
||||
$$PWD/previewimagetooltip.cpp
|
||||
|
||||
FORMS += $$PWD/previewimagetooltip.ui
|
||||
|
||||
|
||||
@@ -29,15 +29,21 @@
|
||||
|
||||
#include <model.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDirIterator>
|
||||
#include <qmlmodelnodeproxy.h>
|
||||
|
||||
static QString s_lastBrowserPath;
|
||||
|
||||
FileResourcesModel::FileResourcesModel(QObject *parent) :
|
||||
QObject(parent), m_filter(QLatin1String("(*.*)")), m_lock(false)
|
||||
FileResourcesModel::FileResourcesModel(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_filter(QLatin1String("(*.*)"))
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
{
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged,
|
||||
this, &FileResourcesModel::refreshModel);
|
||||
}
|
||||
|
||||
void FileResourcesModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
||||
@@ -163,7 +169,6 @@ QVariant FileResourcesModel::modelNodeBackend() const
|
||||
|
||||
bool filterMetaIcons(const QString &fileName)
|
||||
{
|
||||
|
||||
QFileInfo info(fileName);
|
||||
|
||||
if (info.dir().path().split('/').contains("designer")) {
|
||||
@@ -189,12 +194,20 @@ bool filterMetaIcons(const QString &fileName)
|
||||
|
||||
void FileResourcesModel::setupModel()
|
||||
{
|
||||
m_lock = true;
|
||||
m_dirPath = QFileInfo(m_path.toLocalFile()).dir();
|
||||
|
||||
refreshModel();
|
||||
|
||||
m_fileSystemWatcher->removeDirectories(m_fileSystemWatcher->directories());
|
||||
m_fileSystemWatcher->addDirectory(m_dirPath.absolutePath(),
|
||||
Utils::FileSystemWatcher::WatchAllChanges);
|
||||
}
|
||||
|
||||
void FileResourcesModel::refreshModel()
|
||||
{
|
||||
m_fullPathModel.clear();
|
||||
m_fileNameModel.clear();
|
||||
|
||||
m_dirPath = QFileInfo(m_path.toLocalFile()).dir();
|
||||
|
||||
QStringList filterList = m_filter.split(QLatin1Char(' '));
|
||||
|
||||
QDirIterator it(m_dirPath.absolutePath(), filterList, QDir::Files, QDirIterator::Subdirectories);
|
||||
@@ -203,11 +216,15 @@ void FileResourcesModel::setupModel()
|
||||
if (filterMetaIcons(absolutePath)) {
|
||||
QString filePath = m_dirPath.relativeFilePath(absolutePath);
|
||||
m_fullPathModel.append(filePath);
|
||||
m_fileNameModel.append(filePath.mid(filePath.lastIndexOf('/') + 1));
|
||||
}
|
||||
}
|
||||
|
||||
m_lock = false;
|
||||
Utils::sort(m_fullPathModel, [](const QString &s1, const QString &s2) {
|
||||
return s1.mid(s1.lastIndexOf('/') + 1).toLower() < s2.mid(s2.lastIndexOf('/') + 1).toLower();
|
||||
});
|
||||
|
||||
for (const QString &fullPath : qAsConst(m_fullPathModel))
|
||||
m_fileNameModel.append(fullPath.mid(fullPath.lastIndexOf('/') + 1));
|
||||
|
||||
emit fullPathModelChanged();
|
||||
emit fileNameModelChanged();
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <qmlitemnode.h>
|
||||
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
@@ -60,6 +62,7 @@ public:
|
||||
QStringList fullPathModel() const;
|
||||
QStringList fileNameModel() const;
|
||||
void setupModel();
|
||||
void refreshModel();
|
||||
|
||||
Q_INVOKABLE void openFileDialog();
|
||||
|
||||
@@ -79,12 +82,11 @@ private:
|
||||
QUrl m_path;
|
||||
QDir m_dirPath;
|
||||
QString m_filter;
|
||||
bool m_lock;
|
||||
QString m_currentPath;
|
||||
QString m_lastModelPath;
|
||||
QStringList m_fullPathModel;
|
||||
QStringList m_fileNameModel;
|
||||
|
||||
Utils::FileSystemWatcher *m_fileSystemWatcher;
|
||||
};
|
||||
|
||||
QML_DECLARE_TYPE(FileResourcesModel)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#include <QMessageBox>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
@@ -42,6 +43,7 @@
|
||||
#include <qmlitemnode.h>
|
||||
#include <qmlstate.h>
|
||||
#include <annotationeditor/annotationeditor.h>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -92,11 +94,46 @@ void StatesEditorView::removeState(int nodeId)
|
||||
if (nodeId > 0 && hasModelNodeForInternalId(nodeId)) {
|
||||
ModelNode stateNode(modelNodeForInternalId(nodeId));
|
||||
Q_ASSERT(stateNode.metaInfo().isSubclassOf("QtQuick.State"));
|
||||
|
||||
QmlModelState modelState(stateNode);
|
||||
if (modelState.isValid()) {
|
||||
QStringList lockedTargets;
|
||||
const auto propertyChanges = modelState.propertyChanges();
|
||||
for (const QmlPropertyChanges &change : propertyChanges) {
|
||||
const ModelNode target = change.target();
|
||||
if (target.locked())
|
||||
lockedTargets.push_back(target.id());
|
||||
}
|
||||
|
||||
if (!lockedTargets.empty()) {
|
||||
Utils::sort(lockedTargets);
|
||||
QString detailedText = QString("<b>" + tr("Locked items:") + "</b><br>");
|
||||
|
||||
for (const auto &id : qAsConst(lockedTargets))
|
||||
detailedText.append("- " + id + "<br>");
|
||||
|
||||
detailedText.chop(QString("<br>").size());
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setTextFormat(Qt::RichText);
|
||||
msgBox.setIcon(QMessageBox::Question);
|
||||
msgBox.setWindowTitle(tr("Remove State"));
|
||||
msgBox.setText(QString(tr("Removing this state will modify locked items.") + "<br><br>%1")
|
||||
.arg(detailedText));
|
||||
msgBox.setInformativeText(tr("Do you want to continue by removing the state?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
|
||||
if (msgBox.exec() == QMessageBox::Cancel)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NodeListProperty parentProperty = stateNode.parentProperty().toNodeListProperty();
|
||||
|
||||
if (parentProperty.count() <= 1) {
|
||||
setCurrentState(baseState());
|
||||
} else if (parentProperty.isValid()){
|
||||
} else if (parentProperty.isValid()) {
|
||||
int index = parentProperty.indexOf(stateNode);
|
||||
if (index == 0)
|
||||
setCurrentState(parentProperty.at(1));
|
||||
@@ -104,7 +141,6 @@ void StatesEditorView::removeState(int nodeId)
|
||||
setCurrentState(parentProperty.at(index - 1));
|
||||
}
|
||||
|
||||
|
||||
stateNode.destroy();
|
||||
}
|
||||
} catch (const RewritingException &e) {
|
||||
|
||||
@@ -63,6 +63,11 @@ TimelineGraphicsLayout::TimelineGraphicsLayout(TimelineGraphicsScene *scene, Tim
|
||||
|
||||
TimelineGraphicsLayout::~TimelineGraphicsLayout() = default;
|
||||
|
||||
int TimelineGraphicsLayout::zoom() const
|
||||
{
|
||||
return m_rulerItem->zoom();
|
||||
}
|
||||
|
||||
double TimelineGraphicsLayout::rulerWidth() const
|
||||
{
|
||||
return m_rulerItem->preferredWidth();
|
||||
@@ -133,12 +138,12 @@ void TimelineGraphicsLayout::setTimeline(const QmlTimeline &timeline)
|
||||
if (auto *scene = timelineScene())
|
||||
if (auto *view = scene->timelineView())
|
||||
if (!timeline.isValid() && view->isAttached())
|
||||
emit scaleFactorChanged(0);
|
||||
emit zoomChanged(0);
|
||||
}
|
||||
|
||||
void TimelineGraphicsLayout::setRulerScaleFactor(int factor)
|
||||
void TimelineGraphicsLayout::setZoom(int factor)
|
||||
{
|
||||
m_rulerItem->setRulerScaleFactor(factor);
|
||||
m_rulerItem->setZoom(factor);
|
||||
}
|
||||
|
||||
void TimelineGraphicsLayout::invalidate()
|
||||
|
||||
@@ -44,7 +44,7 @@ class TimelineGraphicsLayout : public TimelineItem
|
||||
signals:
|
||||
void rulerClicked(const QPointF &pos);
|
||||
|
||||
void scaleFactorChanged(int factor);
|
||||
void zoomChanged(int factor);
|
||||
|
||||
public:
|
||||
TimelineGraphicsLayout(TimelineGraphicsScene *scene, TimelineItem *parent = nullptr);
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
~TimelineGraphicsLayout() override;
|
||||
|
||||
public:
|
||||
int zoom() const;
|
||||
|
||||
double rulerWidth() const;
|
||||
|
||||
double rulerScaling() const;
|
||||
@@ -66,7 +68,7 @@ public:
|
||||
|
||||
void setTimeline(const QmlTimeline &timeline);
|
||||
|
||||
void setRulerScaleFactor(int factor);
|
||||
void setZoom(int factor);
|
||||
|
||||
void invalidate();
|
||||
|
||||
|
||||
@@ -123,9 +123,9 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *parent)
|
||||
|
||||
auto changeScale = [this](int factor) {
|
||||
timelineWidget()->changeScaleFactor(factor);
|
||||
setRulerScaling(qreal(factor));
|
||||
setZoom(factor);
|
||||
};
|
||||
connect(m_layout, &TimelineGraphicsLayout::scaleFactorChanged, changeScale);
|
||||
connect(m_layout, &TimelineGraphicsLayout::zoomChanged, changeScale);
|
||||
}
|
||||
|
||||
TimelineGraphicsScene::~TimelineGraphicsScene()
|
||||
@@ -144,7 +144,7 @@ void TimelineGraphicsScene::onShow()
|
||||
setCurrentFrame(cf);
|
||||
}
|
||||
|
||||
emit m_layout->scaleFactorChanged(0);
|
||||
emit m_layout->zoomChanged(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +271,11 @@ void TimelineGraphicsScene::setEndFrame(int frame)
|
||||
timeline.modelNode().variantProperty("endFrame").setValue(frame);
|
||||
}
|
||||
|
||||
int TimelineGraphicsScene::zoom() const
|
||||
{
|
||||
return m_layout->zoom();
|
||||
}
|
||||
|
||||
qreal TimelineGraphicsScene::rulerScaling() const
|
||||
{
|
||||
return m_layout->rulerScaling();
|
||||
@@ -332,15 +337,20 @@ QVector<qreal> TimelineGraphicsScene::keyframePositions(const QmlTimelineKeyfram
|
||||
return positions;
|
||||
}
|
||||
|
||||
void TimelineGraphicsScene::setRulerScaling(int scaleFactor)
|
||||
void TimelineGraphicsScene::setZoom(int scaleFactor)
|
||||
{
|
||||
setZoom(scaleFactor, currentFramePosition());
|
||||
}
|
||||
|
||||
void TimelineGraphicsScene::setZoom(int scaleFactor, double pivot)
|
||||
{
|
||||
const qreal oldOffset = scrollOffset();
|
||||
const qreal oldScaling = m_layout->rulerScaling();
|
||||
const qreal oldPosition = mapToScene(currentFramePosition());
|
||||
m_layout->setRulerScaleFactor(scaleFactor);
|
||||
const qreal oldPosition = mapToScene(pivot);
|
||||
m_layout->setZoom(scaleFactor);
|
||||
|
||||
const qreal newScaling = m_layout->rulerScaling();
|
||||
const qreal newPosition = mapToScene(currentFramePosition());
|
||||
const qreal newPosition = mapToScene(pivot);
|
||||
|
||||
const qreal newOffset = oldOffset + (newPosition - oldPosition);
|
||||
|
||||
@@ -428,6 +438,18 @@ void TimelineGraphicsScene::invalidateKeyframesForTarget(const ModelNode &target
|
||||
TimelineSectionItem::updateFramesForTarget(child, target);
|
||||
}
|
||||
|
||||
void TimelineGraphicsScene::invalidateHeightForTarget(const ModelNode &target)
|
||||
{
|
||||
if (!target.isValid())
|
||||
return;
|
||||
|
||||
const auto children = m_layout->childItems();
|
||||
for (auto child : children)
|
||||
TimelineSectionItem::updateHeightForTarget(child, target);
|
||||
|
||||
invalidateLayout();
|
||||
}
|
||||
|
||||
void TimelineGraphicsScene::invalidateScene()
|
||||
{
|
||||
ModelNode node = timelineView()->modelNodeForId(
|
||||
@@ -502,7 +524,7 @@ QRectF AbstractScrollGraphicsScene::selectionBounds() const
|
||||
}
|
||||
|
||||
void AbstractScrollGraphicsScene::selectKeyframes(const SelectionMode &mode,
|
||||
const QList<TimelineKeyframeItem *> &items)
|
||||
const QList<TimelineKeyframeItem *> &items)
|
||||
{
|
||||
if (mode == SelectionMode::Remove || mode == SelectionMode::Toggle) {
|
||||
for (auto *item : items) {
|
||||
@@ -731,7 +753,7 @@ void TimelineGraphicsScene::deleteKeyframeGroup(const ModelNode &group)
|
||||
if (!QmlTimelineKeyframeGroup::isValidQmlTimelineKeyframeGroup(group))
|
||||
return;
|
||||
|
||||
timelineView()->executeInTransaction("TimelineGraphicsScene::handleKeyframeGroupDeletion", [group](){
|
||||
timelineView()->executeInTransaction("TimelineGraphicsScene::handleKeyframeGroupDeletion", [group]() {
|
||||
ModelNode nonConst = group;
|
||||
nonConst.destroy();
|
||||
});
|
||||
@@ -739,7 +761,7 @@ void TimelineGraphicsScene::deleteKeyframeGroup(const ModelNode &group)
|
||||
|
||||
void TimelineGraphicsScene::deleteKeyframes(const QList<ModelNode> &frames)
|
||||
{
|
||||
timelineView()->executeInTransaction("TimelineGraphicsScene::handleKeyframeDeletion", [frames](){
|
||||
timelineView()->executeInTransaction("TimelineGraphicsScene::handleKeyframeDeletion", [frames]() {
|
||||
for (auto keyframe : frames) {
|
||||
if (keyframe.isValid()) {
|
||||
ModelNode frame = keyframe;
|
||||
@@ -764,7 +786,7 @@ AbstractView *TimelineGraphicsScene::abstractView() const
|
||||
|
||||
int AbstractScrollGraphicsScene::getScrollOffset(QGraphicsScene *scene)
|
||||
{
|
||||
auto scrollScene = qobject_cast<AbstractScrollGraphicsScene*>(scene);
|
||||
auto scrollScene = qobject_cast<AbstractScrollGraphicsScene *>(scene);
|
||||
if (scrollScene)
|
||||
return scrollScene->scrollOffset();
|
||||
return 0;
|
||||
|
||||
@@ -58,7 +58,6 @@ class AbstractScrollGraphicsScene : public QGraphicsScene
|
||||
|
||||
public:
|
||||
AbstractScrollGraphicsScene(QWidget *parent);
|
||||
;
|
||||
|
||||
int scrollOffset() const;
|
||||
void setScrollOffset(int offset);
|
||||
@@ -74,6 +73,7 @@ public:
|
||||
bool isKeyframeSelected(TimelineKeyframeItem *keyframe) const;
|
||||
bool multipleKeyframesSelected() const;
|
||||
|
||||
virtual int zoom() const = 0;
|
||||
virtual qreal rulerScaling() const = 0;
|
||||
virtual int rulerWidth() const = 0;
|
||||
virtual qreal rulerDuration() const = 0;
|
||||
@@ -134,6 +134,7 @@ public:
|
||||
TimelineWidget *timelineWidget() const;
|
||||
TimelineToolBar *toolBar() const;
|
||||
|
||||
int zoom() const override;
|
||||
qreal rulerScaling() const override;
|
||||
int rulerWidth() const override;
|
||||
qreal rulerDuration() const override;
|
||||
@@ -152,12 +153,14 @@ public:
|
||||
|
||||
qreal snap(qreal frame, bool snapToPlayhead = true) override;
|
||||
|
||||
void setRulerScaling(int scaling);
|
||||
void setZoom(int scaling);
|
||||
void setZoom(int scaling, double pivot);
|
||||
|
||||
void commitCurrentFrame(qreal frame);
|
||||
|
||||
void invalidateSectionForTarget(const ModelNode &modelNode);
|
||||
void invalidateKeyframesForTarget(const ModelNode &modelNode);
|
||||
void invalidateHeightForTarget(const ModelNode &modelNode);
|
||||
|
||||
void invalidateScene();
|
||||
void invalidateScrollbar() override;
|
||||
@@ -203,7 +206,6 @@ private:
|
||||
QList<QGraphicsItem *> itemsAt(const QPointF &pos);
|
||||
|
||||
private:
|
||||
|
||||
TimelineWidget *m_parent = nullptr;
|
||||
|
||||
TimelineGraphicsLayout *m_layout = nullptr;
|
||||
|
||||
@@ -156,4 +156,9 @@ TimelineFrameHandle *TimelineMovableAbstractItem::asTimelineFrameHandle()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TimelineMovableAbstractItem::isLocked() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -69,6 +69,8 @@ public:
|
||||
virtual TimelineKeyframeItem *asTimelineKeyframeItem();
|
||||
virtual TimelineFrameHandle *asTimelineFrameHandle();
|
||||
|
||||
virtual bool isLocked() const;
|
||||
|
||||
protected:
|
||||
int scrollOffset() const;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
@@ -70,6 +70,9 @@ void TimelineMoveTool::mousePressEvent(TimelineMovableAbstractItem *item,
|
||||
{
|
||||
Q_UNUSED(item)
|
||||
|
||||
if (currentItem() && currentItem()->isLocked())
|
||||
return;
|
||||
|
||||
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
||||
const qreal sourceFrame = qRound(current->mapFromSceneToFrame(current->rect().center().x()));
|
||||
const qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
|
||||
@@ -85,6 +88,9 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
|
||||
if (!currentItem())
|
||||
return;
|
||||
|
||||
if (currentItem()->isLocked())
|
||||
return;
|
||||
|
||||
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
||||
// prevent dragging if deselecting a keyframe (Ctrl+click and drag a selected keyframe)
|
||||
if (!current->highlighted())
|
||||
|
||||
@@ -171,6 +171,17 @@ void TimelineSectionItem::updateFramesForTarget(QGraphicsItem *item, const Model
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineSectionItem::updateHeightForTarget(QGraphicsItem *item, const ModelNode &target)
|
||||
{
|
||||
if (!target.isValid())
|
||||
return;
|
||||
|
||||
if (auto sectionItem = qgraphicsitem_cast<TimelineSectionItem *>(item)) {
|
||||
if (sectionItem->targetNode() == target)
|
||||
sectionItem->updateHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineSectionItem::moveAllFrames(qreal offset)
|
||||
{
|
||||
if (m_timeline.isValid())
|
||||
@@ -313,7 +324,8 @@ void TimelineSectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
event->accept();
|
||||
toggleCollapsed();
|
||||
if (!ModelNode::isThisOrAncestorLocked(m_targetNode))
|
||||
toggleCollapsed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +357,8 @@ void TimelineSectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
if (m_targetNode.isValid())
|
||||
m_targetNode.view()->setSelectedModelNode(m_targetNode);
|
||||
} else {
|
||||
toggleCollapsed();
|
||||
if (!ModelNode::isThisOrAncestorLocked(m_targetNode))
|
||||
toggleCollapsed();
|
||||
}
|
||||
update();
|
||||
}
|
||||
@@ -414,6 +427,12 @@ void TimelineSectionItem::updateFrames()
|
||||
update();
|
||||
}
|
||||
|
||||
void TimelineSectionItem::updateHeight()
|
||||
{
|
||||
invalidateHeight();
|
||||
update();
|
||||
}
|
||||
|
||||
void TimelineSectionItem::invalidateHeight()
|
||||
{
|
||||
int height = 0;
|
||||
@@ -464,7 +483,8 @@ void TimelineSectionItem::invalidateFrames()
|
||||
|
||||
bool TimelineSectionItem::collapsed() const
|
||||
{
|
||||
return m_targetNode.isValid() && !m_targetNode.hasAuxiliaryData("timeline_expanded");
|
||||
return m_targetNode.isValid()
|
||||
&& (!m_targetNode.hasAuxiliaryData("timeline_expanded") || m_targetNode.locked());
|
||||
}
|
||||
|
||||
void TimelineSectionItem::createPropertyItems()
|
||||
@@ -549,9 +569,9 @@ void TimelineRulerSectionItem::invalidateRulerSize(const qreal length)
|
||||
m_end = length;
|
||||
}
|
||||
|
||||
void TimelineRulerSectionItem::setRulerScaleFactor(int scaling)
|
||||
void TimelineRulerSectionItem::setZoom(int zoom)
|
||||
{
|
||||
qreal blend = qreal(scaling) / 100.0;
|
||||
qreal blend = qreal(zoom) / 100.0;
|
||||
|
||||
qreal width = size().width() - qreal(TimelineConstants::sectionWidth);
|
||||
qreal duration = rulerDuration();
|
||||
@@ -572,7 +592,7 @@ void TimelineRulerSectionItem::setRulerScaleFactor(int scaling)
|
||||
update();
|
||||
}
|
||||
|
||||
int TimelineRulerSectionItem::getRulerScaleFactor() const
|
||||
int TimelineRulerSectionItem::zoom() const
|
||||
{
|
||||
qreal width = size().width() - qreal(TimelineConstants::sectionWidth);
|
||||
qreal duration = rulerDuration();
|
||||
@@ -589,7 +609,7 @@ int TimelineRulerSectionItem::getRulerScaleFactor() const
|
||||
qreal rcount = width / m_scaling;
|
||||
qreal rblend = TimelineUtils::reverseLerp(rcount, minCount, maxCount);
|
||||
|
||||
int rfactor = std::round(rblend * 100);
|
||||
int rfactor = static_cast<int>(std::round(rblend * 100));
|
||||
return TimelineUtils::clamp(rfactor, 0, 100);
|
||||
}
|
||||
|
||||
@@ -766,7 +786,7 @@ void TimelineRulerSectionItem::resizeEvent(QGraphicsSceneResizeEvent *event)
|
||||
{
|
||||
QGraphicsWidget::resizeEvent(event);
|
||||
|
||||
auto factor = getRulerScaleFactor();
|
||||
auto factor = zoom();
|
||||
|
||||
if (factor < 0) {
|
||||
if (event->oldSize().width() < event->newSize().width())
|
||||
@@ -775,7 +795,7 @@ void TimelineRulerSectionItem::resizeEvent(QGraphicsSceneResizeEvent *event)
|
||||
factor = 100;
|
||||
}
|
||||
|
||||
emit scaleFactorChanged(factor);
|
||||
emit zoomChanged(factor);
|
||||
}
|
||||
|
||||
void TimelineRulerSectionItem::setSizeHints(int width)
|
||||
@@ -845,6 +865,11 @@ void TimelineBarItem::commitPosition(const QPointF & /*point*/)
|
||||
m_oldRect = QRectF();
|
||||
}
|
||||
|
||||
bool TimelineBarItem::isLocked() const
|
||||
{
|
||||
return sectionItem()->targetNode().isValid() && sectionItem()->targetNode().locked();
|
||||
}
|
||||
|
||||
void TimelineBarItem::scrollOffsetChanged()
|
||||
{
|
||||
sectionItem()->invalidateBar();
|
||||
@@ -904,7 +929,9 @@ void TimelineBarItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
const auto p = event->pos();
|
||||
|
||||
QRectF left, right;
|
||||
if (handleRects(rect(), left, right)) {
|
||||
if (isLocked() && rect().contains(p)) {
|
||||
setCursor(QCursor(Qt::ForbiddenCursor));
|
||||
} else if (handleRects(rect(), left, right)) {
|
||||
if (left.contains(p) || right.contains(p)) {
|
||||
if (cursor().shape() != Qt::SizeHorCursor)
|
||||
setCursor(QCursor(Qt::SizeHorCursor));
|
||||
@@ -920,6 +947,9 @@ void TimelineBarItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
|
||||
void TimelineBarItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
|
||||
{
|
||||
if (isLocked())
|
||||
return;
|
||||
|
||||
QMenu menu;
|
||||
QAction* overrideColor = menu.addAction(tr("Override Color"));
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ public:
|
||||
void itemMoved(const QPointF &start, const QPointF &end) override;
|
||||
void commitPosition(const QPointF &point) override;
|
||||
|
||||
bool isLocked() const override;
|
||||
|
||||
protected:
|
||||
void scrollOffsetChanged() override;
|
||||
void paint(QPainter *painter,
|
||||
@@ -100,6 +102,7 @@ public:
|
||||
static void updateData(QGraphicsItem *item);
|
||||
static void updateDataForTarget(QGraphicsItem *item, const ModelNode &target, bool *b);
|
||||
static void updateFramesForTarget(QGraphicsItem *item, const ModelNode &target);
|
||||
static void updateHeightForTarget(QGraphicsItem *item, const ModelNode &target);
|
||||
|
||||
void moveAllFrames(qreal offset);
|
||||
void scaleAllFrames(qreal scale);
|
||||
@@ -121,6 +124,7 @@ protected:
|
||||
private:
|
||||
void updateData();
|
||||
void updateFrames();
|
||||
void updateHeight();
|
||||
void invalidateHeight();
|
||||
void invalidateProperties();
|
||||
void invalidateFrames();
|
||||
@@ -145,7 +149,7 @@ class TimelineRulerSectionItem : public TimelineItem
|
||||
signals:
|
||||
void rulerClicked(const QPointF &pos);
|
||||
|
||||
void scaleFactorChanged(int scale);
|
||||
void zoomChanged(int zoom);
|
||||
|
||||
public:
|
||||
static TimelineRulerSectionItem *create(QGraphicsScene *parentScene, TimelineItem *parent);
|
||||
@@ -153,9 +157,9 @@ public:
|
||||
void invalidateRulerSize(const QmlTimeline &timeline);
|
||||
void invalidateRulerSize(const qreal length);
|
||||
|
||||
void setRulerScaleFactor(int scaling);
|
||||
void setZoom(int zoom);
|
||||
|
||||
int getRulerScaleFactor() const;
|
||||
int zoom() const;
|
||||
qreal getFrameTick() const;
|
||||
|
||||
qreal rulerScaling() const;
|
||||
|
||||
@@ -236,6 +236,18 @@ void TimelineView::selectedNodesChanged(const QList<ModelNode> & /*selectedNodeL
|
||||
m_timelineWidget->graphicsScene()->update();
|
||||
}
|
||||
|
||||
void TimelineView::auxiliaryDataChanged(const ModelNode &modelNode,
|
||||
const PropertyName &name,
|
||||
const QVariant &data)
|
||||
{
|
||||
if (name == QmlDesigner::lockedProperty && data.toBool() && modelNode.isValid()) {
|
||||
for (const auto &node : modelNode.allSubModelNodesAndThisNode()) {
|
||||
if (node.hasAuxiliaryData("timeline_expanded"))
|
||||
m_timelineWidget->graphicsScene()->invalidateHeightForTarget(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
|
||||
{
|
||||
for (const auto &property : propertyList) {
|
||||
|
||||
@@ -62,6 +62,9 @@ public:
|
||||
PropertyChangeFlags propertyChange) override;
|
||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||
void auxiliaryDataChanged(const ModelNode &node,
|
||||
const PropertyName &name,
|
||||
const QVariant &data) override;
|
||||
|
||||
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "timelinepropertyitem.h"
|
||||
#include "timelinetoolbar.h"
|
||||
#include "timelineview.h"
|
||||
#include "navigation2d.h"
|
||||
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmlstate.h>
|
||||
@@ -60,6 +61,8 @@
|
||||
#include <QtGlobal>
|
||||
#include <QSpacerItem>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Eventfilter : public QObject
|
||||
@@ -114,7 +117,7 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
||||
, m_toolbar(new TimelineToolBar(this))
|
||||
, m_rulerView(new QGraphicsView(this))
|
||||
, m_graphicsView(new QGraphicsView(this))
|
||||
, m_scrollbar(new QScrollBar(this))
|
||||
, m_scrollbar(new Navigation2dScrollBar(this))
|
||||
, m_statusBar(new QLabel(this))
|
||||
, m_timelineView(view)
|
||||
, m_graphicsScene(new TimelineGraphicsScene(this))
|
||||
@@ -153,6 +156,7 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
||||
m_graphicsView->setFrameShape(QFrame::NoFrame);
|
||||
m_graphicsView->setFrameShadow(QFrame::Plain);
|
||||
m_graphicsView->setLineWidth(0);
|
||||
m_graphicsView->setVerticalScrollBar(new Navigation2dScrollBar);
|
||||
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
@@ -247,6 +251,14 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
||||
connect(m_addButton, &QPushButton::clicked, this, [this]() {
|
||||
m_timelineView->addNewTimelineDialog();
|
||||
});
|
||||
|
||||
Navigation2dFilter *filter = new Navigation2dFilter(this, m_scrollbar);
|
||||
connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF& pos) {
|
||||
int s = static_cast<int>(std::round(scale*100.));
|
||||
double ps = m_graphicsScene->mapFromScene(pos.x());
|
||||
m_graphicsScene->setZoom(std::clamp(m_graphicsScene->zoom() + s, 0, 100), ps);
|
||||
});
|
||||
installEventFilter(filter);
|
||||
}
|
||||
|
||||
void TimelineWidget::connectToolbar()
|
||||
@@ -258,8 +270,8 @@ void TimelineWidget::connectToolbar()
|
||||
|
||||
connect(graphicsScene(), &TimelineGraphicsScene::scroll, this, &TimelineWidget::scroll);
|
||||
|
||||
auto setRulerScaling = [this](int val) { m_graphicsScene->setRulerScaling(val); };
|
||||
connect(m_toolbar, &TimelineToolBar::scaleFactorChanged, setRulerScaling);
|
||||
auto setZoomFactor = [this](int val) { m_graphicsScene->setZoom(val); };
|
||||
connect(m_toolbar, &TimelineToolBar::scaleFactorChanged, setZoomFactor);
|
||||
|
||||
auto setToFirstFrame = [this]() {
|
||||
graphicsScene()->setCurrentFrame(graphicsScene()->startFrame());
|
||||
@@ -428,7 +440,7 @@ void TimelineWidget::init()
|
||||
|
||||
// setScaleFactor uses QSignalBlocker.
|
||||
m_toolbar->setScaleFactor(0);
|
||||
m_graphicsScene->setRulerScaling(0);
|
||||
m_graphicsScene->setZoom(0);
|
||||
}
|
||||
|
||||
void TimelineWidget::reset()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user