summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Studio/Application
diff options
context:
space:
mode:
authorJanne Kangas <janne.kangas@qt.io>2018-08-22 10:31:47 +0300
committerJanne Kangas <janne.kangas@qt.io>2018-09-11 04:17:24 +0000
commit1880495b000c3bc4eac819120c2dccfb03e4ce52 (patch)
treee679e1d4b0b938bbb254b7646deeabd986aeb406 /src/Authoring/Studio/Application
parentda2a184d9f9497a41601519411c43f1881f41691 (diff)
Parse datainput use from subpresentation files and check allowable types
Search through controlledproperty tags in UIP files of subpresentations and store subpresentation id and datatypes controlled per datainput. Datainput that is in use in another presentation is indicated by highlight in datainput management dialog, similarly to ones in use in the current presentation. Task-id: QT3DS-2142 Change-Id: I7e40154e41863ff6123bb85348868f44ef0733cc Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Authoring/Studio/Application')
-rw-r--r--src/Authoring/Studio/Application/DataInputDlg.cpp20
-rw-r--r--src/Authoring/Studio/Application/DataInputListDlg.cpp32
-rw-r--r--src/Authoring/Studio/Application/PresentationFile.cpp70
-rw-r--r--src/Authoring/Studio/Application/PresentationFile.h6
-rw-r--r--src/Authoring/Studio/Application/ProjectFile.cpp11
-rw-r--r--src/Authoring/Studio/Application/ProjectFile.h1
-rw-r--r--src/Authoring/Studio/Application/StudioApp.cpp43
-rw-r--r--src/Authoring/Studio/Application/StudioApp.h2
8 files changed, 169 insertions, 16 deletions
diff --git a/src/Authoring/Studio/Application/DataInputDlg.cpp b/src/Authoring/Studio/Application/DataInputDlg.cpp
index 2f7cfa8f..3f63138c 100644
--- a/src/Authoring/Studio/Application/DataInputDlg.cpp
+++ b/src/Authoring/Studio/Application/DataInputDlg.cpp
@@ -68,13 +68,8 @@ CDataInputDlg::CDataInputDlg(CDataInputDialogItem **datainput, QStandardItemMode
for (int i = 0; i < m_ui->comboBoxTypeList->model()->rowCount(); ++i)
{
QStandardItem *item = model->item(i, 0);
- // We need special handling for Ranged Number as it is
- // not a studio property datatype, but relevant only for datainput.
- if (!acceptedTypes.contains((EDataType)i)
- && !(m_dataInput->type == DataTypeRangedNumber
- && item->data(Qt::UserRole) == DataTypeRangedNumber)) {
+ if (!acceptedTypes.contains((EDataType)i))
item->setEnabled(false);
- }
}
initDialog();
@@ -241,8 +236,7 @@ const bool CDataInputDlg::isEquivalentDataType(int dlgType,
if ((dlgType == EDataType::DataTypeString
&& dmType == qt3dsdm::DataModelDataType::String)
|| (dlgType == EDataType::DataTypeRangedNumber
- && (dmType == qt3dsdm::DataModelDataType::Float
- || dmType == qt3dsdm::DataModelDataType::String) && !strict)
+ && dmType == qt3dsdm::DataModelDataType::RangedNumber)
|| (dlgType == EDataType::DataTypeFloat
&& (dmType == qt3dsdm::DataModelDataType::Float
|| (dmType == qt3dsdm::DataModelDataType::String && !strict)))
@@ -252,10 +246,12 @@ const bool CDataInputDlg::isEquivalentDataType(int dlgType,
&& dmType == qt3dsdm::DataModelDataType::Float3)
|| (dlgType == EDataType::DataTypeVector2
&& dmType == qt3dsdm::DataModelDataType::Float2)
- // Variant can be bound to any property type.
- // Allow also Evaluator binding to any property as we only know the evaluation
- // result type at runtime.
- || dlgType == EDataType::DataTypeVariant
+ // Variant can be bound to any property type except
+ // as timeline controller because only datainput of type Ranged Number
+ // has additional min/max information. For slide control,
+ // we can allow variant type in addition to String type.
+ || (dlgType == EDataType::DataTypeVariant
+ && dmType != qt3dsdm::DataModelDataType::RangedNumber)
#ifdef DATAINPUT_EVALUATOR_ENABLED
|| dlgType == EDataType::DataTypeEvaluator
#endif
diff --git a/src/Authoring/Studio/Application/DataInputListDlg.cpp b/src/Authoring/Studio/Application/DataInputListDlg.cpp
index 238e3f3f..3b7cb0e2 100644
--- a/src/Authoring/Studio/Application/DataInputListDlg.cpp
+++ b/src/Authoring/Studio/Application/DataInputListDlg.cpp
@@ -187,7 +187,7 @@ void CDataInputListDlg::updateContents()
dataInput.append(new QStandardItem(tr("Variant")));
}
// highlight datainputs that are in use
- if (it->controlledElems.size() != 0)
+ if (it->controlledElems.size() || it->externalPresBoundTypes.size())
dataInput.first()->setForeground(QBrush(CStudioPreferences::dataInputColor()));
m_tableContents->appendRow(dataInput);
}
@@ -292,7 +292,10 @@ void CDataInputListDlg::onEditDataInput()
// Only show types that are ok for _all_ currently controlled properties.
// If datainput is not controlling any elements, all types are ok.
+
+ // Datainput binding types
QVector<EDataType> allowedTypes;
+ bool strictFound = false;
if (di->controlledElems.size()) {
for (auto type : qAsConst(di->boundTypes)) {
// If we hit strict type requirement for a certain bound datatype, set allowed types
@@ -309,13 +312,36 @@ void CDataInputListDlg::onEditDataInput()
allowedTypes.append(t);
}
// if we just hit a strict type requirement we are finished
+ if (type.second) {
+ strictFound = true;
+ break;
+ }
+ }
+ }
+
+ // Datainput bindings for all other presentations, unless we already have a
+ // strict type requirement
+ if (di->externalPresBoundTypes.size() && !strictFound) {
+ for (auto type : qAsConst(di->externalPresBoundTypes)) {
+ if (type.second)
+ allowedTypes.clear();
+
+ const auto acceptedTypes = CDataInputDlg::getAcceptedTypes(type.first, type.second);
+
+ for (auto t : acceptedTypes) {
+ if (!allowedTypes.contains(t))
+ allowedTypes.append(t);
+ }
+ // if we just hit a strict type requirement we are finished
if (type.second)
break;
}
- } else {
- allowedTypes = allDataTypes;
}
+ // no bindings in this or other presentations, all datatypes are ok
+ if (!allowedTypes.size())
+ allowedTypes = allDataTypes;
+
CDataInputDlg datainputdialog(&di, m_tableContents, this, allowedTypes);
datainputdialog.exec();
diff --git a/src/Authoring/Studio/Application/PresentationFile.cpp b/src/Authoring/Studio/Application/PresentationFile.cpp
index c1b2d467..8baf3e19 100644
--- a/src/Authoring/Studio/Application/PresentationFile.cpp
+++ b/src/Authoring/Studio/Application/PresentationFile.cpp
@@ -38,6 +38,7 @@
#include "QtCore/qfileinfo.h"
#include <QtCore/qdiriterator.h>
#include <qxmlstream.h>
+#include <QtCore/qlist.h>
// This class provides utility static methods for working with presentation files (.uip). Old uip
// functionality should be gradually moved here whenever feasible.
@@ -306,3 +307,72 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &
}
}
}
+
+/**
+ * Find datainput use in subpresentation
+ *
+ * @param subpresentation subpresentation
+ * @param outmap returned list of datainput - property name pairs
+ */
+// static
+bool PresentationFile::getDataInputBindings(const SubPresentationRecord &subpresentation,
+ QMultiMap<QString, QPair<QString, QString>> &outmap)
+{
+ QList<QString> ctrldPropList;
+
+ QString spPath(g_StudioApp.getRenderableAbsolutePath(subpresentation.m_id));
+ QFile file(spPath);
+
+ file.open(QFile::Text | QFile::ReadOnly);
+ if (!file.isOpen()) {
+ qWarning() << file.errorString();
+ return false;
+ }
+
+ QDomDocument domDoc;
+ domDoc.setContent(&file);
+
+ // search <Graph>
+ QDomElement graphElem = domDoc.documentElement().firstChild()
+ .firstChildElement(QStringLiteral("Graph"));
+ for (QDomElement p = graphElem.firstChild().toElement(); !p.isNull();
+ p = p.nextSibling().toElement()) {
+ QString ctrldPropStr = p.attribute(QStringLiteral("controlledproperty"));
+ if (!ctrldPropStr.isEmpty())
+ ctrldPropList.append(ctrldPropStr);
+ }
+ // Search Logic - State - Add
+ QDomNodeList addElems = domDoc.documentElement().firstChild()
+ .firstChildElement(QStringLiteral("Logic"))
+ .elementsByTagName(QStringLiteral("Add"));
+
+ for (int i = 0; i < addElems.count(); ++i) {
+ QDomElement elem = addElems.at(i).toElement();
+ QString ctrldPropStr = elem.attribute(QStringLiteral("controlledproperty"));
+ if (!ctrldPropStr.isEmpty())
+ ctrldPropList.append(ctrldPropStr);
+ }
+
+ for (auto di : qAsConst(ctrldPropList)) {
+ QStringList split = di.split(QLatin1String(" "));
+ for (int i = 0; i < split.size(); i += 2) {
+ QString diName = split[i];
+ // Datainput names indicated with prefix "$", remove
+ // if found.
+ if (diName.startsWith(QLatin1String("$")))
+ diName = diName.mid(1, diName.size() - 1);
+ QString propName = split[i + 1];
+ // We should find the datainput from the global datainput list
+ // parsed out from UIA file, but check just in case and do not insert
+ // if not found.
+ if (g_StudioApp.m_dataInputDialogItems.contains(diName)) {
+ outmap.insert(subpresentation.m_id, QPair<QString, QString>(diName, propName));
+ } else {
+ qWarning() << "Subpresentation" << subpresentation.m_id
+ << "is using datainput" << diName << "that is "
+ "not found from the current UIA file";
+ }
+ }
+ }
+ return true;
+}
diff --git a/src/Authoring/Studio/Application/PresentationFile.h b/src/Authoring/Studio/Application/PresentationFile.h
index 12ffa895..c18cfe7d 100644
--- a/src/Authoring/Studio/Application/PresentationFile.h
+++ b/src/Authoring/Studio/Application/PresentationFile.h
@@ -29,11 +29,15 @@
#ifndef PRESENTATIONFILE_H
#define PRESENTATIONFILE_H
+#include "ProjectFile.h"
+
#include <QtCore/qfile.h>
#include <QtXml/qdom.h>
+#include <QtCore/qmap.h>
QT_FORWARD_DECLARE_CLASS(QDir)
QT_FORWARD_DECLARE_CLASS(QFileInfo)
+class CDataInputDialogItem;
class PresentationFile
{
@@ -44,6 +48,8 @@ public:
const QString &newId);
static QSize readSize(const QString &uipPath);
static QString findProjectFile(const QString &uipPath);
+ static bool getDataInputBindings(const SubPresentationRecord &subpresentation,
+ QMultiMap<QString, QPair<QString, QString>> &outmap);
private:
PresentationFile();
diff --git a/src/Authoring/Studio/Application/ProjectFile.cpp b/src/Authoring/Studio/Application/ProjectFile.cpp
index 82a844b5..6dfeb5b8 100644
--- a/src/Authoring/Studio/Application/ProjectFile.cpp
+++ b/src/Authoring/Studio/Application/ProjectFile.cpp
@@ -530,3 +530,14 @@ QString ProjectFile::getResolvedPathTo(const QString &path) const
auto projectPath = QDir(getProjectPath()).absoluteFilePath(path);
return QDir::cleanPath(projectPath);
}
+
+// Return multimap of type subpresentationid - QPair<datainput, propertyname>
+QMultiMap<QString, QPair<QString, QString>>
+ProjectFile::getDiBindingtypesFromSubpresentations() const
+{
+ QMultiMap<QString, QPair<QString, QString>> map;
+ for (auto sp : qAsConst(g_StudioApp.m_subpresentations))
+ PresentationFile::getDataInputBindings(sp, map);
+
+ return map;
+}
diff --git a/src/Authoring/Studio/Application/ProjectFile.h b/src/Authoring/Studio/Application/ProjectFile.h
index 24f79100..2cf01572 100644
--- a/src/Authoring/Studio/Application/ProjectFile.h
+++ b/src/Authoring/Studio/Application/ProjectFile.h
@@ -60,6 +60,7 @@ public:
QString getPresentationId(const QString &src) const;
QString getResolvedPathTo(const QString &path) const;
QString createPreview();
+ QMultiMap<QString, QPair<QString, QString>> getDiBindingtypesFromSubpresentations() const;
static QString getInitialPresentationSrc(const QString &uiaPath);
static void getPresentations(const QString &inUiaPath,
diff --git a/src/Authoring/Studio/Application/StudioApp.cpp b/src/Authoring/Studio/Application/StudioApp.cpp
index 26a127e3..8a81db58 100644
--- a/src/Authoring/Studio/Application/StudioApp.cpp
+++ b/src/Authoring/Studio/Application/StudioApp.cpp
@@ -2101,10 +2101,51 @@ void CStudioApp::checkDeletedDatainputs()
QMultiMap<QString, QPair<qt3dsdm::Qt3DSDMInstanceHandle, qt3dsdm::Qt3DSDMPropertyHandle>> *map;
map = new QMultiMap<QString, QPair<qt3dsdm::Qt3DSDMInstanceHandle,
qt3dsdm::Qt3DSDMPropertyHandle>>;
- m_core->GetDoc()->UpdateDatainputMap(m_core->GetDoc()->GetActiveRootInstance(), map);
+
+ auto doc = m_core->GetDoc();
+ // Update datainputs for the currently open presentation
+ doc->UpdateDatainputMap(m_core->GetDoc()->GetActiveRootInstance(), map);
if (!map->empty())
m_core->GetDispatch()->FireOnUndefinedDatainputsFail(map);
+
+ // Update allowed property types for datainput-controlled properties
+ // in subpresentations. It is ok to do this once
+ // at the project opening, as the assumption is that subpresentation files
+ // do not change while we are editing currently open presentation.
+
+ // Clear the old subpresentation binding info only.
+ for (auto it : qAsConst(m_dataInputDialogItems))
+ it->externalPresBoundTypes.clear();
+
+ const QMultiMap<QString, QPair<QString, QString>> spDatainputs
+ = GetCore()->getProjectFile().getDiBindingtypesFromSubpresentations();
+
+ // For datainput bindings in subpresentations we do not have specific
+ // instance and/or property handles. Get the datatype for property using
+ // the generic name string and leave instance/property handle empty.
+ for (auto sp : spDatainputs) {
+ const QString propName = sp.second;
+ CDataInputDialogItem *item = m_dataInputDialogItems.find(sp.first).value();
+ QPair<qt3dsdm::DataModelDataType::Value, bool> spEntry;
+ if (propName == QLatin1String("@timeline")) {
+ spEntry.first = qt3dsdm::DataModelDataType::Value::RangedNumber;
+ spEntry.second = true;
+ } else if (propName == QLatin1String("@slide")) {
+ spEntry.first = qt3dsdm::DataModelDataType::Value::String;
+ spEntry.second = true;
+ } else {
+ qt3dsimp::SImportComposerTypes theTypes;
+ qt3dsimp::SImportAsset &theAsset(theTypes.GetImportAssetForType(
+ qt3dsdm::ComposerObjectTypes::Node));
+ qt3dsdm::DataModelDataType::Value theType(
+ theAsset.GetPropertyDataType(propName.toStdWString().c_str()));
+ spEntry.first = theType;
+ spEntry.second = false;
+ }
+
+ item->externalPresBoundTypes.insert(sp.first, spEntry);
+ }
}
void CStudioApp::verifyDatainputBindings()
diff --git a/src/Authoring/Studio/Application/StudioApp.h b/src/Authoring/Studio/Application/StudioApp.h
index aa512532..958daa9e 100644
--- a/src/Authoring/Studio/Application/StudioApp.h
+++ b/src/Authoring/Studio/Application/StudioApp.h
@@ -33,6 +33,8 @@
#pragma once
#include "StudioObjectTypes.h"
+#include "Qt3DSImportComposerTypes.h"
+#include "Qt3DSDMComposerTypeDefinitions.h"
#include "DispatchListeners.h"
#include "Qt3DSDMHandles.h"
#include "Qt3DSFileTools.h"