summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/Authoring/Client/Code/Core/Doc/Doc.cpp15
-rw-r--r--src/Authoring/Client/Code/Core/Doc/Doc.h5
-rw-r--r--src/Authoring/QT3DSDM/Systems/Qt3DSDMDataTypes.h1
-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
11 files changed, 183 insertions, 23 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/Doc.cpp b/src/Authoring/Client/Code/Core/Doc/Doc.cpp
index 6ad06e00..127e306d 100644
--- a/src/Authoring/Client/Code/Core/Doc/Doc.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/Doc.cpp
@@ -2883,8 +2883,6 @@ QString CDoc::GetDocumentUIAFile(bool master)
return file.isEmpty() ? masterFile : file;
}
-// TODO: use ProjectFile class framework to parse subpresentations and add datainput use
-// information from them to the map as well
void CDoc::UpdateDatainputMap(
const qt3dsdm::Qt3DSDMInstanceHandle inInstance,
QMultiMap<QString,
@@ -2911,11 +2909,9 @@ void CDoc::UpdateDatainputMap(
// Update the controlled elements and property types for
// verified, existing datainputs. Note that for @timeline and
// @slide controllers the property type is not found as these
- // are pseudo-properties, and return from GetDataType will be invalid.
- // For slide control, type is strictly set to String. For timeline,
- // the datainput is strictly Ranged Number which cannot be represented
- // with object property datatypes, so will be handled separately
- // when allowable datainput types are checked.
+ // are pseudo-properties, so we handle them here.
+ // For slide control, type is strictly set to String.
+ // For timeline the datainput is strictly Ranged Number only.
if (g_StudioApp.m_dataInputDialogItems.contains(diName)) {
g_StudioApp.m_dataInputDialogItems[diName]->
controlledElems.append(inInstance);
@@ -2927,6 +2923,11 @@ void CDoc::UpdateDatainputMap(
->boundTypes.append(QPair<qt3dsdm::DataModelDataType::Value, bool>
(qt3dsdm::DataModelDataType::Value::String, true));
+ } else if (propName == QLatin1String("@timeline")) {
+ g_StudioApp.m_dataInputDialogItems[diName]
+ ->boundTypes.append(
+ QPair<qt3dsdm::DataModelDataType::Value, bool>
+ (qt3dsdm::DataModelDataType::Value::RangedNumber, true));
}
} else if (outMap != nullptr) {
// Do multi insert as single datainput name can
diff --git a/src/Authoring/Client/Code/Core/Doc/Doc.h b/src/Authoring/Client/Code/Core/Doc/Doc.h
index 5b11acd7..7589096d 100644
--- a/src/Authoring/Client/Code/Core/Doc/Doc.h
+++ b/src/Authoring/Client/Code/Core/Doc/Doc.h
@@ -168,6 +168,11 @@ public:
// i.e. only the exact equivalent mapping from datainput type to
// property type is allowed (float to float, string to string etc.)
QVector<QPair<qt3dsdm::DataModelDataType::Value, bool>> boundTypes;
+ // Bindings in other subpresentations, of QMap format
+ // QMultiMap<subpresentation_id, QPair<datatype, strict>>.
+ // Stored separately so we can conveniently update/clear binding info
+ // for current presentation and keep subpresentation binding info intact or vice versa.
+ QMultiMap<QString, QPair<qt3dsdm::DataModelDataType::Value, bool>> externalPresBoundTypes;
};
//==============================================================================
diff --git a/src/Authoring/QT3DSDM/Systems/Qt3DSDMDataTypes.h b/src/Authoring/QT3DSDM/Systems/Qt3DSDMDataTypes.h
index 104a4558..d8c2673e 100644
--- a/src/Authoring/QT3DSDM/Systems/Qt3DSDMDataTypes.h
+++ b/src/Authoring/QT3DSDM/Systems/Qt3DSDMDataTypes.h
@@ -782,6 +782,7 @@ struct DataModelDataType {
ObjectRef,
StringOrInt,
FloatList,
+ RangedNumber // datainput-specific type for editor only
};
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"