diff options
Diffstat (limited to 'src/Authoring/Qt3DStudio/Application/StudioApp.cpp')
-rw-r--r-- | src/Authoring/Qt3DStudio/Application/StudioApp.cpp | 384 |
1 files changed, 187 insertions, 197 deletions
diff --git a/src/Authoring/Qt3DStudio/Application/StudioApp.cpp b/src/Authoring/Qt3DStudio/Application/StudioApp.cpp index f3594c94..ac9efb10 100644 --- a/src/Authoring/Qt3DStudio/Application/StudioApp.cpp +++ b/src/Authoring/Qt3DStudio/Application/StudioApp.cpp @@ -39,9 +39,9 @@ #include "qtlocalpeer.h" #include "TimelineWidget.h" #include "SlideView.h" -#include "IKeyframesManager.h" #include "PresentationFile.h" #include "EditPresentationIdDlg.h" +#include "Qt3DSDMWStrOps.h" #include <QtGui/qsurfaceformat.h> #include <QtCore/qfileinfo.h> @@ -160,9 +160,6 @@ int main(int argc, char *argv[]) return g_StudioApp.run(parser); } -//============================================================================== -// Includes -//============================================================================== #include "Exceptions.h" #include "IOLibraryException.h" #include "MainFrm.h" @@ -184,7 +181,6 @@ int main(int argc, char *argv[]) #include "StudioUtils.h" #include "ClientDataModelBridge.h" -#include "CommonConstants.h" #include "IOLibraryException.h" #include "Qt3DSDMErrors.h" @@ -196,7 +192,6 @@ int main(int argc, char *argv[]) #include <string.h> #include <QtWidgets/qapplication.h> -#include <QtCore/qsettings.h> #include "Core.h" #include "HotKeys.h" @@ -204,7 +199,6 @@ int main(int argc, char *argv[]) #include "Qt3DSDMStudioSystem.h" #include "Qt3DSDMInspectable.h" #include "Qt3DSDMSlides.h" -#include "Qt3DSDMMaterialInspectable.h" #include "Qt3DSDMAnimation.h" #include "Qt3DSDMDataCore.h" #include "IDirectoryWatchingSystem.h" @@ -215,21 +209,6 @@ CStudioApp g_StudioApp; using namespace Q3DStudio; -namespace qt3ds -{ -void Qt3DSAssert(const char *exp, const char *file, int line, bool *ignore) -{ - Q_UNUSED(ignore) - g_StudioApp.GetDialogs()->DestroyProgressScreen(); - g_StudioApp.GetDialogs()->DisplayKnownErrorDialog(exp); - qFatal("Assertion thrown %s(%d): %s", file, line, exp); -} -} - -//============================================================================= -/** - * Constructor - */ CStudioApp::CStudioApp() : m_core(nullptr) , m_isSilent(false) @@ -248,10 +227,6 @@ CStudioApp::CStudioApp() connect(m_autosaveTimer, &QTimer::timeout, this, [=](){ OnSave(true); }); } -//============================================================================= -/** - * Destructor - */ CStudioApp::~CStudioApp() { delete m_views; @@ -300,7 +275,6 @@ void CStudioApp::performShutdown() qApp->exit(); } -//============================================================================= /** * Entry location for the creation of this application. * This creates the all the views, then returns if everything @@ -311,10 +285,10 @@ bool CStudioApp::initInstance(const QCommandLineParser &parser, bool isOpenGLES) QApplication::setOrganizationName("The Qt Company"); QApplication::setOrganizationDomain("qt.io"); QApplication::setApplicationName("Qt 3D Studio"); - QApplication::setApplicationVersion(CStudioPreferences::GetVersionString()); + QApplication::setApplicationVersion(CStudioPreferences::versionString()); qCInfo(qt3ds::TRACE_INFO) << "Studio: " << QApplication::applicationFilePath(); - qCInfo(qt3ds::TRACE_INFO) << "Version: " << CStudioPreferences::GetVersionString(); + qCInfo(qt3ds::TRACE_INFO) << "Version: " << CStudioPreferences::versionString(); // Silent is ignored for everything but create m_isSilent = parser.isSet("silent") && parser.isSet("create"); @@ -325,9 +299,7 @@ bool CStudioApp::initInstance(const QCommandLineParser &parser, bool isOpenGLES) m_gettingStartedFilePath = Qt3DSFile::GetApplicationDirectory() + QStringLiteral("/../doc/qt3dstudio/getting-started.html"); - QString thePreferencesPath = CFilePath::GetUserApplicationDirectory() - + QStringLiteral("/Qt3DStudio/Preferences.setting"); - CStudioPreferences::loadPreferences(thePreferencesPath); + CStudioPreferences::loadPreferences(); m_dialogs = new CDialogs(!m_isSilent); @@ -352,14 +324,13 @@ bool CStudioApp::initInstance(const QCommandLineParser &parser, bool isOpenGLES) m_core->GetDispatch()->AddFailListener(this); // Initialize autosave - m_autosaveTimer->setInterval(CStudioPreferences::GetAutoSaveDelay() * 1000); - if (CStudioPreferences::GetAutoSavePreference()) + m_autosaveTimer->setInterval(CStudioPreferences::autoSaveDelay() * 1000); + if (CStudioPreferences::isAutoSavePreference()) m_autosaveTimer->start(); return true; } -//============================================================================= /** * Command handler to display the about dialog. */ @@ -369,7 +340,6 @@ void CStudioApp::onAppAbout() aboutDlg.exec(); } -//============================================================================= /** * Main application execution loop. * The application's main thread stays in this until the app exits. @@ -403,7 +373,7 @@ bool CStudioApp::run(const QCommandLineParser &parser) performShutdown(); } catch (qt3dsdm::Qt3DSDMError &uicdmError) { - Q_UNUSED(uicdmError); + Q_UNUSED(uicdmError) exit(1); } catch (...) { throw; @@ -521,7 +491,6 @@ QString CStudioApp::resolvePresentationFile(const QString &inFile) return {}; } -//============================================================================= /** * Show startup dialog and perform necessary action such as create new doc or load doc. * Return false if user requests to exit @@ -540,17 +509,15 @@ bool CStudioApp::showStartupDialog() m_welcomeShownThisSession = true; bool show = false; - QSettings settings; - if (!settings.contains("showWelcomeScreen")) { - settings.setValue("showWelcomeScreen", 1); + if (!CStudioPreferences::containsShowWelcomeScreen()) { + CStudioPreferences::setShowWelcomeScreen(true); show = true; } else { // if we are returning to welcome dialog page after canceling // file dialog, do not care about settings but always show // welcome - show = settings.value("showWelcomeScreen").toBool() - || m_goStraightToWelcomeFileDialog; + show = CStudioPreferences::isShowWelcomeScreen() || m_goStraightToWelcomeFileDialog; } if (show) { @@ -635,7 +602,6 @@ void CStudioApp::openApplication(const QString &inFilename) } #endif -//============================================================================= /** * Start the app. */ @@ -653,7 +619,6 @@ bool CStudioApp::blankRunApplication() return runApplication(); } -//============================================================================= /** * Open the specified file and run the application. * This will load the file then go into the standard app loop. @@ -711,7 +676,6 @@ bool CStudioApp::createAndRunApplication(const QString &filename, const QString return theSuccess; } -//============================================================================= /** * This is the app execution loop, the main thread loops here until the app exits. * @return true on success; false on failure @@ -721,7 +685,6 @@ bool CStudioApp::runApplication() return qApp->exec() == 0; } -//============================================================================= /** * Initialize the core and all the views. */ @@ -737,7 +700,13 @@ void CStudioApp::initCore() if (m_views) { m_views->createViews(m_isSilent); m_pMainWnd = m_views->getMainFrame(); - m_pMainWnd->initializeGeometryAndState(); + if (!CStudioPreferences::containsWindowState(STUDIO_VERSION_NUM)) { + // On first run, save and restore geometry and state. For some reason they are both + // needed to avoid a bug with palettes resizing to their original size when window is + // resized or something in a palette is edited. + m_pMainWnd->handleGeometryAndState(true); + } + m_pMainWnd->handleGeometryAndState(false); } RegisterGlobalKeyboardShortcuts(m_core->GetHotKeys(), m_pMainWnd); @@ -880,7 +849,6 @@ CCore *CStudioApp::GetCore() return m_core; } -//============================================================================= /** * Get the view manager for this core to communicate to the views. */ @@ -889,7 +857,6 @@ CViews *CStudioApp::GetViews() return m_views; } -//============================================================================= /** * Get the dialog manager for this core for displaying dialogs. */ @@ -936,20 +903,12 @@ void CStudioApp::SetManipulationMode(StudioManipulationModes::Enum inManipulatio } } -//============================================================================= -/** - * return true if undo is possible - */ bool CStudioApp::CanUndo() { return m_core->GetCmdStack()->CanUndo() && !m_views->getMainFrame()->getTimelineWidget()->dndActive(); } -//============================================================================= -/** - * return true if redo is possible - */ bool CStudioApp::CanRedo() { return m_core->GetCmdStack()->CanRedo(); @@ -965,7 +924,6 @@ bool CStudioApp::CanCopy() return m_core->GetDoc()->canCopy(); } -//============================================================================= /** * Get a string describing the type of the copy operation that can be done. * Precedence of copying is 1) Actions; 2) Keyframes; 3) Objects @@ -1025,7 +983,7 @@ QString CStudioApp::getDeleteType() const if (bridge->CanDelete(selected[idx])) deletableCount++; } - if (deletableCount && deletableCount == selected.size()) + if (deletableCount && deletableCount == int(selected.size())) return tr("Object"); } return {}; @@ -1103,7 +1061,6 @@ bool CStudioApp::ungroupSelectedObjects() const return false; } -//============================================================================= /** * Cuts the selected object or keys */ @@ -1117,7 +1074,6 @@ bool CStudioApp::CanCut() return m_core->GetDoc()->canCut(); } -//============================================================================= /** * Paste keys from the copied list yo */ @@ -1131,7 +1087,6 @@ bool CStudioApp::CanPaste() return m_core->GetDoc()->canPaste(); } -//============================================================================= /** * Get a string describing the type of the paste operation that can be done. * Precedence of paste is 1) Actions; 2) Object ; 3) Keyframes @@ -1153,18 +1108,14 @@ QString CStudioApp::GetPasteType() bool CStudioApp::CanChangeTimebarColor() { - bool theRetVal = true; - qt3dsdm::Qt3DSDMInstanceHandle theSelectedInstance = m_core->GetDoc()->GetSelectedInstance(); - if (!theSelectedInstance.Valid() - || m_core->GetDoc()->GetStudioSystem()->GetClientDataModelBridge()->IsSceneInstance( - theSelectedInstance)) { - theRetVal = false; + auto theSelectedInstance = m_core->GetDoc()->GetSelectedInstance(); + if (theSelectedInstance.Valid()) { + auto bridge = m_core->GetDoc()->GetStudioSystem()->GetClientDataModelBridge(); + return !bridge->IsActiveComponent(theSelectedInstance); } - - return theRetVal; + return false; } -//============================================================================= /** * Sets any changed keyframes on the selected object */ @@ -1173,7 +1124,6 @@ void CStudioApp::HandleSetChangedKeys() m_core->GetDoc()->SetChangedKeyframes(); } -//============================================================================= /** * Deletes all selected keys */ @@ -1182,7 +1132,6 @@ void CStudioApp::DeleteSelectedKeys() m_core->GetDoc()->deleteSelectedKeyframes(); } -//============================================================================= /** * Deletes selected object or keyframes */ @@ -1206,23 +1155,21 @@ void CStudioApp::HandleDuplicateCommand() */ void CStudioApp::OnToggleAutosetKeyframes() { - SetAutosetKeyframes(!CStudioPreferences::IsAutosetKeyframesOn()); + SetAutosetKeyframes(!CStudioPreferences::isAutosetKeyframesOn()); m_core->GetDispatch()->FireOnToolbarChange(); } -//============================================================================== /** * Updates the preferences, and AnimationSystem. */ void CStudioApp::SetAutosetKeyframes(bool inFlag) { - CStudioPreferences::SetAutosetKeyframesOn(inFlag); + CStudioPreferences::setAutosetKeyframesOn(inFlag); m_core->GetDoc()->GetStudioSystem()->GetAnimationSystem()->SetAutoKeyframe(inFlag); } -//============================================================================== /** * If the presentation is not currently playing, this function will make it * start playing from the current position. The starting point of the playhead @@ -1230,19 +1177,20 @@ void CStudioApp::SetAutosetKeyframes(bool inFlag) */ void CStudioApp::PlaybackPlay() { - // Do not start playback if user is currently interacting with scene - if (getRenderer().isMouseDown()) - return; + if (!m_core->GetDoc()->getPresentationId().isEmpty()) { + // Do not start playback if user is currently interacting with scene + if (getRenderer().isMouseDown()) + return; - CDoc *theDoc = m_core->GetDoc(); - if (!theDoc->IsPlaying()) { - m_playbackTime = theDoc->GetCurrentViewTime(); - m_playbackOriginalSlide = theDoc->GetActiveSlide(); - theDoc->SetPlayMode(PLAYMODE_PLAY); + CDoc *theDoc = m_core->GetDoc(); + if (!theDoc->IsPlaying()) { + m_playbackTime = theDoc->GetCurrentViewTime(); + m_playbackOriginalSlide = theDoc->GetActiveSlide(); + theDoc->SetPlayMode(PLAYMODE_PLAY); + } } } -//============================================================================== /** * If the presentation is currently playing, it is stopped. The playhead is * left wherever it was stopped at (hence it's not restored). @@ -1252,7 +1200,6 @@ void CStudioApp::PlaybackStopNoRestore() m_core->GetDoc()->SetPlayMode(PLAYMODE_STOP); } -//============================================================================== /** * Moves the playhead back to time zero. */ @@ -1272,7 +1219,6 @@ bool CStudioApp::IsPlaying() return m_core->GetDoc()->IsPlaying(); } -//============================================================================= /** * Performs a file revert. * This will revert the doc to the last saved version. @@ -1285,7 +1231,6 @@ void CStudioApp::OnRevert() } } -//============================================================================= /** * Check to see if it is possible to perform a revert. */ @@ -1294,7 +1239,6 @@ bool CStudioApp::CanRevert() const return m_core->GetDoc()->isModified() && m_core->GetDoc()->isValid(); } -//============================================================================== /** * Handles the recent list. */ @@ -1304,7 +1248,6 @@ void CStudioApp::OnFileOpenRecent(const QString &inDocument) OnLoadDocument(inDocument); } -//============================================================================== /** * Called when closing the current doc, this prompts the user to save the doc. * This will only prompt if the doc is modified, and if the user selects save @@ -1328,7 +1271,6 @@ bool CStudioApp::PerformSavePrompt() return true; } -//============================================================================== /** * If the presentation is currently playing, it is stopped. The playhead is * restored to the position found in m_PlaybackTime. @@ -1346,53 +1288,54 @@ void CStudioApp::PlaybackStop() m_playbackOriginalSlide = 0; } -//============================================================================= /** - * Used for track wheel to do smooth tracking on mac, just scrolls the playhead. + * advance time by a small amount */ -void CStudioApp::AdvanceTime() +void CStudioApp::advanceTime() { - long theDeltaTime = CStudioPreferences::GetTimeAdvanceAmount(); - long theTime = - (m_core->GetDoc()->GetCurrentViewTime() + theDeltaTime) / theDeltaTime * theDeltaTime; - m_core->GetDoc()->NotifyTimeChanged(theTime); + if (!m_core->GetDoc()->getPresentationId().isEmpty()) { + long dt = CStudioPreferences::timeAdvanceAmount(); + long time = (m_core->GetDoc()->GetCurrentViewTime() + dt) / dt * dt; + m_core->GetDoc()->NotifyTimeChanged(time); + } } -//============================================================================= /** - * Used for track wheel to do smooth tracking on mac, just scrolls the playhead. + * move back time by a small amount */ -void CStudioApp::ReduceTime() +void CStudioApp::reduceTime() { - long theDeltaTime = CStudioPreferences::GetTimeAdvanceAmount(); - long theTime = (m_core->GetDoc()->GetCurrentViewTime() - 1) / theDeltaTime * theDeltaTime; - m_core->GetDoc()->NotifyTimeChanged(theTime); + if (!m_core->GetDoc()->getPresentationId().isEmpty()) { + long dt = CStudioPreferences::timeAdvanceAmount(); + long time = (m_core->GetDoc()->GetCurrentViewTime() - 1) / dt * dt; + m_core->GetDoc()->NotifyTimeChanged(time); + } } -//============================================================================= /** - * Used for track wheel to do smooth tracking on mac, just scrolls the playhead. + * advance time by a big amount */ -void CStudioApp::AdvanceUltraBigTime() +void CStudioApp::advanceTimeBig() { - long theDeltaTime = CStudioPreferences::GetBigTimeAdvanceAmount(); - long theTime = - (m_core->GetDoc()->GetCurrentViewTime() + theDeltaTime) / theDeltaTime * theDeltaTime; - m_core->GetDoc()->NotifyTimeChanged(theTime); + if (!m_core->GetDoc()->getPresentationId().isEmpty()) { + long dt = CStudioPreferences::bigTimeAdvanceAmount(); + long time = (m_core->GetDoc()->GetCurrentViewTime() + dt) / dt * dt; + m_core->GetDoc()->NotifyTimeChanged(time); + } } -//============================================================================= /** - * Used for track wheel to do smooth tracking on mac, just scrolls the playhead. + * move back time by a big amount */ -void CStudioApp::ReduceUltraBigTime() +void CStudioApp::reduceTimeBig() { - long theDeltaTime = CStudioPreferences::GetBigTimeAdvanceAmount(); - long theTime = (m_core->GetDoc()->GetCurrentViewTime() - 1) / theDeltaTime * theDeltaTime; - m_core->GetDoc()->NotifyTimeChanged(theTime); + if (!m_core->GetDoc()->getPresentationId().isEmpty()) { + long dt = CStudioPreferences::bigTimeAdvanceAmount(); + long time = (m_core->GetDoc()->GetCurrentViewTime() - 1) / dt * dt; + m_core->GetDoc()->NotifyTimeChanged(time); + } } -//============================================================================== /** * If the presentation is currently playing, it is stopped. Otherwise, the * presetation starts playing from its current position. Called when the user @@ -1400,69 +1343,34 @@ void CStudioApp::ReduceUltraBigTime() */ void CStudioApp::PlaybackToggle() { - // If the presentation is playing, stop it and leave the playhead where it is - if (m_core->GetDoc()->IsPlaying()) - PlaybackStopNoRestore(); - // Otherwise, the presentation is stopped, so start it playing - else - PlaybackPlay(); -} - -// TODO: move to more appropriate place (InspectorControlModel.cpp) -CInspectableBase *CStudioApp::getInspectableFromInstance(qt3dsdm::Qt3DSDMInstanceHandle inInstance) -{ - CInspectableBase *inspectableBase = nullptr; - CDoc *doc = m_core->GetDoc(); - - if (doc->GetDocumentReader().IsInstance(inInstance)) { - CClientDataModelBridge *theBridge = doc->GetStudioSystem()->GetClientDataModelBridge(); - qt3dsdm::Qt3DSDMSlideHandle activeSlide = doc->GetActiveSlide(); - - // Slide, scene or component - if (inInstance == theBridge->GetOwningComponentInstance(activeSlide)) { - Qt3DSDMInstanceHandle activeSlideInstance = doc->GetStudioSystem()->GetSlideSystem() - ->GetSlideInstance(activeSlide); - - inspectableBase = new Qt3DSDMInspectable(inInstance, activeSlideInstance); - } - if (!inspectableBase) { - if (theBridge->IsMaterialBaseInstance(inInstance)) - inspectableBase = new Qt3DSDMMaterialInspectable(inInstance); - else - inspectableBase = new Qt3DSDMInspectable(inInstance); - } + if (!m_core->GetDoc()->getPresentationId().isEmpty()) { + // If the presentation is playing, stop it and leave the playhead where it is + if (m_core->GetDoc()->IsPlaying()) + PlaybackStopNoRestore(); + // Otherwise, the presentation is stopped, so start it playing + else + PlaybackPlay(); } - - return inspectableBase; } -void CStudioApp::RegisterGlobalKeyboardShortcuts(CHotKeys *inShortcutHandler, - QWidget *actionParent) +void CStudioApp::RegisterGlobalKeyboardShortcuts(CHotKeys *inShortcutHandler, QWidget *actionParent) { m_core->RegisterGlobalKeyboardShortcuts(inShortcutHandler, actionParent); - ADD_GLOBAL_SHORTCUT(actionParent, - QKeySequence(Qt::Key_Period), - CStudioApp::AdvanceTime); - ADD_GLOBAL_SHORTCUT(actionParent, - QKeySequence(Qt::Key_Comma), - CStudioApp::ReduceTime); - ADD_GLOBAL_SHORTCUT(actionParent, - QKeySequence(Qt::ShiftModifier | Qt::Key_Period), - CStudioApp::AdvanceUltraBigTime); - ADD_GLOBAL_SHORTCUT(actionParent, - QKeySequence(Qt::ShiftModifier | Qt::Key_Comma), - CStudioApp::ReduceUltraBigTime); - ADD_GLOBAL_SHORTCUT(actionParent, - QKeySequence(Qt::Key_Return), - CStudioApp::PlaybackToggle); + ADD_GLOBAL_SHORTCUT(actionParent, QKeySequence(Qt::Key_Period), CStudioApp::advanceTime) + ADD_GLOBAL_SHORTCUT(actionParent, QKeySequence(Qt::Key_Comma), CStudioApp::reduceTime) + ADD_GLOBAL_SHORTCUT(actionParent, QKeySequence(Qt::ShiftModifier | Qt::Key_Period), + CStudioApp::advanceTimeBig) + ADD_GLOBAL_SHORTCUT(actionParent, QKeySequence(Qt::ShiftModifier | Qt::Key_Comma), + CStudioApp::reduceTimeBig) + ADD_GLOBAL_SHORTCUT(actionParent, QKeySequence(Qt::Key_Return), CStudioApp::PlaybackToggle) inShortcutHandler->RegisterKeyUpEvent( - new CDynHotKeyConsumer<CStudioApp>(this, &CStudioApp::playbackPreviewEnd), 0, + new CDynHotKeyConsumer<CStudioApp>(this, &CStudioApp::playbackPreviewEnd), nullptr, Qt::Key_Space); inShortcutHandler->RegisterKeyDownEvent( - new CDynHotKeyConsumer<CStudioApp>(this, &CStudioApp::playbackPreviewStart), 0, - Qt::Key_Space); + new CDynHotKeyConsumer<CStudioApp>(this, &CStudioApp::playbackPreviewStart), + nullptr, Qt::Key_Space); if (m_views) m_views->registerGlobalKeyboardShortcuts(inShortcutHandler, actionParent); @@ -1576,7 +1484,6 @@ void CStudioApp::SetAutosaveInterval(int interval) m_autosaveTimer->setInterval(interval * 1000); } -//============================================================================= /** * Call to load a new document. * There should not be a currently active document when this is called. @@ -1661,6 +1568,13 @@ bool CStudioApp::OnLoadDocument(const QString &inDocument, bool inShowStartupDia } } else { m_dialogs->ResetSettings(loadFile); + if (m_core->GetDoc()->ensureActiveCamera()) + m_dialogs->DisplayMessageBox( + tr("More than one camera active"), + tr("Layer can only have one active camera. " + "Additional cameras were set to inactive."), + Qt3DSMessageBox::ICON_WARNING, false); + m_core->getProjectFile().updateDocPresentationId(); m_core->getProjectFile().loadSubpresentationsAndDatainputs(m_subpresentations, m_dataInputDialogItems); @@ -1672,7 +1586,7 @@ bool CStudioApp::OnLoadDocument(const QString &inDocument, bool inShowStartupDia m_core->GetDispatch()->FireAuthorZoomChanged(); verifyDatainputBindings(); - checkDeletedDatainputs(); + checkDeletedDatainputs(true); } return theLoadResult; @@ -1721,12 +1635,6 @@ void CStudioApp::saveDataInputsToProjectFile() } else if (item->type == EDataType::DataTypeVariant) { diNode.setAttribute(QStringLiteral("type"), QStringLiteral("Variant")); } -#ifdef DATAINPUT_EVALUATOR_ENABLED - else if (item->type == EDataType::DataTypeEvaluator) { - diNode.setAttribute(QStringLiteral("type"), QStringLiteral("Evaluator")); - diNode.setAttribute(QStringLiteral("evaluator"), item->valueString); - } -#endif QHashIterator<QString, QString> it(item->metadata); QString metadataStr; @@ -1850,6 +1758,23 @@ QString CStudioApp::OnProjectNew() } /** + * Closes current project + */ +void CStudioApp::OnProjectClose() +{ + if (PerformSavePrompt()) { + // CloseDocument() clears all the OpenGL buffers so it needs the correct context + getRenderer().MakeContextCurrent(); + m_core->GetDoc()->CloseDocument(); + getRenderer().ReleaseContext(); + m_pMainWnd->setActionsEnabledStatus(false); + m_pMainWnd->setWindowTitle(QObject::tr("Qt 3D Studio")); + showStartupDialog(); + } +} + + +/** * Create a new presentation * this creates a .uip file */ @@ -1890,6 +1815,7 @@ void CStudioApp::OnAsynchronousCommand(CCmd *inCmd) void CStudioApp::OnDisplayAppStatus(const QString &inStatusMsg) { + Q_UNUSED(inStatusMsg) // Do nothing, it was used to show this in the status bar } @@ -1951,7 +1877,7 @@ void CStudioApp::OnRefreshResourceFail(const QString &inResourceName, const QStr void CStudioApp::OnNewPresentation() { m_core->GetDoc()->GetStudioSystem()->GetAnimationSystem()->SetAutoKeyframe( - CStudioPreferences::IsAutosetKeyframesOn()); + CStudioPreferences::isAutosetKeyframesOn()); qCInfo(qt3ds::TRACE_INFO) << "New Presentation: " << m_core->GetDoc()->GetDocumentPath(); } @@ -2069,11 +1995,12 @@ QSize CStudioApp::getRenderableSize(const QString &renderableId) void CStudioApp::OnUndefinedDatainputsFail( const QMultiMap<QString, QPair<qt3dsdm::Qt3DSDMInstanceHandle, - qt3dsdm::Qt3DSDMPropertyHandle>> *map) + qt3dsdm::Qt3DSDMPropertyHandle>> *map, + bool askFromUser) { - bool res = m_dialogs->DisplayUndefinedDatainputDlg(map); + bool res = askFromUser ? m_dialogs->DisplayUndefinedDatainputDlg(map) : true; - // Delete invalid datainput bindings if user prompted so. + // Delete invalid datainput bindings if user prompted so, or silently if not asked. if (res) { m_core->GetDoc()->RemoveDatainputBindings(map); // clear commands as we do not want to create undo point @@ -2133,6 +2060,13 @@ void CStudioApp::showPresentationIdEmptyWarning() Qt3DSMessageBox::ICON_WARNING, false); } +void CStudioApp::showShaderCompileError(const QString &error) +{ + m_dialogs->DisplayMessageBox(tr("Warning"), + tr("Shader compile error.\n") + error, + Qt3DSMessageBox::ICON_WARNING, false); +} + void CStudioApp::showInvalidFilenameWarning() { m_dialogs->DisplayMessageBox(tr("Invalid filename"), @@ -2140,7 +2074,7 @@ void CStudioApp::showInvalidFilenameWarning() Qt3DSMessageBox::ICON_WARNING, false); } -void CStudioApp::checkDeletedDatainputs() +void CStudioApp::checkDeletedDatainputs(bool askFromUser) { QMultiMap<QString, QPair<qt3dsdm::Qt3DSDMInstanceHandle, qt3dsdm::Qt3DSDMPropertyHandle>> *map; map = new QMultiMap<QString, QPair<qt3dsdm::Qt3DSDMInstanceHandle, @@ -2150,7 +2084,7 @@ void CStudioApp::checkDeletedDatainputs() doc->UpdateDatainputMap(map); if (!map->empty()) - m_core->GetDispatch()->FireOnUndefinedDatainputsFail(map); + m_core->GetDispatch()->FireOnUndefinedDatainputsFail(map, askFromUser); // Update allowed property types for datainput-controlled properties // in subpresentations. It is ok to do this once @@ -2161,15 +2095,16 @@ void CStudioApp::checkDeletedDatainputs() for (auto it : qAsConst(m_dataInputDialogItems)) it->externalPresBoundTypes.clear(); - const QMultiMap<QString, QPair<QString, QString>> spDatainputs + const QMultiHash<QString, ProjectFile::DataInputOutputBinding> spDatainputs = GetCore()->getProjectFile().getDiBindingtypesFromSubpresentations(); - + QHash<QString, QHash<QString, qt3dsdm::DataModelDataType::Value>> + customPropertyTypes; // sourcepath, <propname, proptype> // 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.cbegin(); sp != spDatainputs.cend(); ++sp) { - const QString propName = sp->second; - CDataInputDialogItem *item = m_dataInputDialogItems.find(sp->first).value(); + const QString propName = sp->propertyName; + CDataInputDialogItem *item = m_dataInputDialogItems.find(sp->dioName).value(); QPair<qt3dsdm::DataModelDataType::Value, bool> spEntry; if (propName == QLatin1String("@timeline")) { spEntry.first = qt3dsdm::DataModelDataType::Value::RangedNumber; @@ -2178,15 +2113,70 @@ void CStudioApp::checkDeletedDatainputs() spEntry.first = qt3dsdm::DataModelDataType::Value::String; spEntry.second = true; } else { - qt3dsimp::SImportComposerTypes theTypes; - qt3dsimp::SImportAsset &theAsset(theTypes.GetImportAssetForType( - qt3dsdm::ComposerObjectTypes::ControllableObject)); - qt3dsdm::DataModelDataType::Value theType( - theAsset.GetPropertyDataType(propName.toStdWString().c_str())); + qt3dsdm::DataModelDataType::Value theType = qt3dsdm::DataModelDataType::Value::None; + if (!sp->propertyDefinitionFile.isEmpty()) { + // Check property type from custom property definition file + if (!customPropertyTypes.contains(sp->propertyDefinitionFile)) { + QHash<QString, qt3dsdm::DataModelDataType::Value> propTypes; + QFile file(sp->propertyDefinitionFile); + file.open(QFile::Text | QFile::ReadOnly); + if (!file.isOpen()) { + qWarning() << file.errorString(); + } else { + QString xmlContent = file.readAll(); + if (sp->propertyDefinitionFile.endsWith(QLatin1String("qml"), + Qt::CaseInsensitive)) { + // Property defs are in comments in behavior scripts, and not in well + // formed XML format, so skip until start of the property definitions + // and extract properties under a fake root tag to avoid parsing issues + int start = xmlContent.indexOf(QLatin1String("/*[[")); + if (start != -1) { + int end = xmlContent.indexOf(QLatin1String("]]*/"), start); + QString tagged = QStringLiteral("<Behavior>\n"); + tagged.append(xmlContent.mid(start, end - start).trimmed()); + tagged.append(QLatin1String("</Behavior>\n")); + tagged.replace(QLatin1String("\r\n"), QLatin1String("\n")); + xmlContent = tagged; + } + } + QDomDocument domDoc; + domDoc.setContent(xmlContent); + QDomNodeList propElems + = domDoc.elementsByTagName(QStringLiteral("Property")); + for (int i = 0; i < propElems.count(); ++i) { + QDomElement elem = propElems.at(i).toElement(); + const QString metaName = elem.attribute(QStringLiteral("name")); + const QString metaType = elem.attribute(QStringLiteral("type")); + qt3dsdm::DataModelDataType::Value dataType; + if (metaType.isEmpty()) { + dataType = qt3dsdm::DataModelDataType::Value::Float; + } else { + QByteArray buf((metaType.size() + 1) * int(sizeof(wchar_t)),'\0'); + metaType.toWCharArray(reinterpret_cast<wchar_t *>(buf.data())); + qt3dsdm::CompleteMetaDataType::Enum typeValue; + WStrOps<qt3dsdm::CompleteMetaDataType::Enum> converter; + converter.StrTo(reinterpret_cast<const wchar_t *>( + buf.constData()), typeValue); + dataType = qt3dsdm::CompleteMetaDataType::ToDataType(typeValue); + } + propTypes.insert(metaName, dataType); + } + customPropertyTypes.insert(sp->propertyDefinitionFile, propTypes); + } + } + theType = customPropertyTypes[sp->propertyDefinitionFile].value( + propName, qt3dsdm::DataModelDataType::Value::None); + } + if (theType == qt3dsdm::DataModelDataType::Value::None) { + qt3dsimp::SImportComposerTypes theTypes; + qt3dsimp::SImportAsset &theAsset( + theTypes.GetImportAssetForType( + qt3dsdm::ComposerObjectTypes::ControllableObject)); + theType = theAsset.GetPropertyDataType(propName.toStdWString().c_str()); + } spEntry.first = theType; spEntry.second = false; } - item->externalPresBoundTypes.insert(sp.key(), spEntry); } } |