diff options
-rw-r--r-- | src/Authoring/Client/Code/Core/Doc/Doc.cpp | 15 | ||||
-rw-r--r-- | src/Authoring/Client/Code/Core/Doc/Doc.h | 5 | ||||
-rw-r--r-- | src/Authoring/QT3DSDM/Systems/Qt3DSDMDataTypes.h | 1 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/DataInputDlg.cpp | 20 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/DataInputListDlg.cpp | 32 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/PresentationFile.cpp | 70 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/PresentationFile.h | 6 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/ProjectFile.cpp | 11 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/ProjectFile.h | 1 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/StudioApp.cpp | 43 | ||||
-rw-r--r-- | src/Authoring/Studio/Application/StudioApp.h | 2 |
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" |