diff options
Diffstat (limited to 'src/Authoring/Studio/Palettes/Action/ActionView.cpp')
-rw-r--r-- | src/Authoring/Studio/Palettes/Action/ActionView.cpp | 1203 |
1 files changed, 0 insertions, 1203 deletions
diff --git a/src/Authoring/Studio/Palettes/Action/ActionView.cpp b/src/Authoring/Studio/Palettes/Action/ActionView.cpp deleted file mode 100644 index 41d67789..00000000 --- a/src/Authoring/Studio/Palettes/Action/ActionView.cpp +++ /dev/null @@ -1,1203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "ActionView.h" -#include "ActionContextMenu.h" -#include "ActionModel.h" -#include "CmdDataModelActionSetValue.h" -#include "ClientDataModelBridge.h" -#include "Core.h" -#include "Dialogs.h" -#include "Dispatch.h" -#include "Doc.h" -#include "IDocumentEditor.h" -#include "IDocumentReader.h" -#include "IObjectReferenceHelper.h" -#include "Literals.h" -#include "ObjectListModel.h" -#include "StudioUtils.h" -#include "StudioApp.h" -#include "StudioClipboard.h" -#include "StudioObjectTypes.h" -#include "StudioPreferences.h" -#include "Qt3DSFileTools.h" -#include "Qt3DSDMActionCore.h" -#include "Qt3DSDMDataTypes.h" -#include "Qt3DSDMSlides.h" - -#include <QtCore/qcoreapplication.h> -#include <QtQml/qqmlcontext.h> -#include <QtQml/qqmlengine.h> -#include <QtCore/qtimer.h> -#include <QtWidgets/qdesktopwidget.h> - -ActionView::ActionView(const QSize &preferredSize, QWidget *parent) - : QQuickWidget(parent) - , TabNavigable() - , m_actionsModel(new ActionModel(this)) - , m_preferredSize(preferredSize) -{ - setResizeMode(QQuickWidget::SizeRootObjectToView); - QTimer::singleShot(0, this, &ActionView::initialize); - - g_StudioApp.GetCore()->GetDispatch()->AddPresentationChangeListener(this); - - connect(this, &ActionView::actionChanged, this, [this] { - if (!m_itemHandle.Valid()) - return; - - if (!m_propertyModel) - m_propertyModel = new PropertyModel(this); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - if (actionInfo.m_Handler == L"Set Property") { - setPropertyValueInvalid(true); - m_currentPropertyNameHandle = actionInfo.m_HandlerArgs.at(0); - m_currentPropertyValueHandle = actionInfo.m_HandlerArgs.at(1); - m_propertyModel->setAction(m_actionsModel->actionAt(m_currentActionIndex)); - m_propertyModel->setNameHandle(m_currentPropertyNameHandle); - m_propertyModel->setValueHandle(m_currentPropertyValueHandle); - m_currentPropertyIndex = m_propertyModel->defaultPropertyIndex(); - Q_EMIT propertyChanged(); - Q_EMIT propertyModelChanged(); - setPropertyValueInvalid(false); - } - }); - - m_actionChangedCompressionTimer.setInterval(20); - m_actionChangedCompressionTimer.setSingleShot(true); - connect(&m_actionChangedCompressionTimer, &QTimer::timeout, this, [this] { - updateHandlerArguments(); - updateFiredEvent(); - Q_EMIT actionChanged(); - }); - - QString ctrlKey(QStringLiteral("Ctrl+")); - QString shiftKey(QStringLiteral("Shift+")); -#ifdef Q_OS_MACOS - ctrlKey = "⌘"; - shiftKey = "⇧"; -#endif - - // These actions will be passed to the context menu. Some of them need to me members, as we - // have to change their enabled state based on selection and previous actions. - QAction *action = new QAction(tr("New Action\t%1A").arg(shiftKey)); - action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_A)); - connect(action, &QAction::triggered, this, &ActionView::addAction); - QQuickWidget::addAction(action); - - m_actionCopy = new QAction(tr("Copy Action\t%1C").arg(ctrlKey)); - connect(m_actionCopy, &QAction::triggered, this, &ActionView::copyAction); - QQuickWidget::addAction(m_actionCopy); - - m_actionPaste = new QAction(tr("Paste Action\t%1V").arg(ctrlKey)); - connect(m_actionPaste, &QAction::triggered, this, &ActionView::pasteAction); - QQuickWidget::addAction(m_actionPaste); - - m_actionCut = new QAction(tr("Cut Action\t%1X").arg(ctrlKey)); - connect(m_actionCut, &QAction::triggered, this, &ActionView::cutAction); - QQuickWidget::addAction(m_actionCut); - - m_actionDel = new QAction(tr("Delete Action\tDel")); - connect(m_actionDel, &QAction::triggered, [=](){ deleteAction(m_currentActionIndex); }); - QQuickWidget::addAction(m_actionDel); -} - -ActionView::~ActionView() -{ -} - -QSize ActionView::sizeHint() const -{ - return m_preferredSize; -} - -void ActionView::focusInEvent(QFocusEvent *event) -{ - updateActionStates(); - QQuickWidget::focusInEvent(event); -} - -void ActionView::mousePressEvent(QMouseEvent *event) -{ - g_StudioApp.setLastActiveView(this); - QQuickWidget::mousePressEvent(event); -} - -bool ActionView::event(QEvent *event) -{ - if (event->type() == QEvent::ShortcutOverride) { - QKeyEvent *ke = static_cast<QKeyEvent *>(event); - if (m_currentActionIndex >= 0 && (ke->key() == Qt::Key_Delete - || (ke->modifiers() == Qt::ControlModifier - && (ke->key() == Qt::Key_C || ke->key() == Qt::Key_V - || ke->key() == Qt::Key_X)))) { - auto focusItem = quickWindow()->activeFocusItem(); - if (focusItem && (focusItem->objectName() == QStringLiteral("actionListDelegate") - || focusItem->objectName() == QStringLiteral("focusEater"))) { - if (ke->key() == Qt::Key_Delete) { - if (m_actionDel->isEnabled()) - deleteAction(m_currentActionIndex); - } else if (ke->modifiers() == Qt::ControlModifier) { - if (ke->key() == Qt::Key_C) { - if (m_actionCopy->isEnabled()) - copyAction(); - } else if (ke->key() == Qt::Key_V) { - if (m_actionPaste->isEnabled()) - pasteAction(); - } else if (ke->key() == Qt::Key_X) { - if (m_actionCut->isEnabled()) - cutAction(); - } - } - event->accept(); - return true; - } - } - } - return QQuickWidget::event(event); -} - -void ActionView::setItem(const qt3dsdm::Qt3DSDMInstanceHandle &handle) -{ - if (!m_activeBrowser.isNull() && m_activeBrowser->isVisible()) { - m_activeBrowser->close(); - m_activeBrowser.clear(); - } - - m_objRefHelper = GetDoc()->GetDataModelObjectReferenceHelper(); - m_itemHandle = handle; - m_actionsModel->setInstanceHandle(handle); - if (m_itemHandle.Valid() != m_hasItem) { - m_hasItem = m_itemHandle.Valid(); - Q_EMIT hasItemChanged(); - } - emitActionChanged(); - Q_EMIT itemChanged(); - Q_EMIT itemTextChanged(); -} - -QString ActionView::itemIcon() const -{ - if (!m_itemHandle.Valid()) - return QString(); - - auto info = m_objRefHelper->GetInfo(m_itemHandle); - return CStudioObjectTypes::GetNormalIconName(info.m_Type); -} - -QString ActionView::itemText() const -{ - if (!m_itemHandle.Valid()) - return tr("No Object Selected"); - - const auto data = m_objRefHelper->GetInfo(m_itemHandle); - return data.m_Name.toQString(); -} - -QColor ActionView::itemColor() const -{ - if (!m_itemHandle.Valid()) - return Qt::white; - - auto info = m_objRefHelper->GetInfo(m_itemHandle); - if (info.m_Master) - return CStudioPreferences::masterColor(); - else - return CStudioPreferences::textColor(); -} - -QAbstractItemModel *ActionView::actionsModel() const -{ - return m_actionsModel; -} - -QAbstractItemModel *ActionView::propertyModel() const -{ - return m_propertyModel; -} - -QString ActionView::targetObjectName() const -{ - if (!GetDoc()->isValid() || !m_itemHandle.Valid()) - return QString(); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - - const auto targetInstance = - GetBridge()->GetInstance(actionInfo.m_Owner, actionInfo.m_TargetObject); - - QString targetName = targetInstance.Valid() - ? GetBridge()->GetName(targetInstance).toQString() - : tr("[Unknown Target]"); - - return targetName; -} - -QString ActionView::triggerObjectName() const -{ - if (!GetDoc()->isValid() || !m_itemHandle.Valid()) - return QString(); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - - const auto sourceInstance = - GetBridge()->GetInstance(actionInfo.m_Owner, actionInfo.m_TriggerObject); - - QString sourceName = sourceInstance.Valid() - ? GetBridge()->GetName(sourceInstance).toQString() - : tr("[Unknown Source]"); - - return sourceName; -} - -QString ActionView::eventName() const -{ - if (!GetDoc()->isValid() || !m_itemHandle.Valid()) - return QString(); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto bridge = GetBridge(); - const auto eventHandle = bridge->ResolveEvent(actionInfo); - const auto eventInfo = bridge->GetEventInfo(eventHandle); - - const QString formalName = QString::fromWCharArray(eventInfo.m_FormalName.wide_str()); - return formalName.isEmpty() ? tr("[Unknown Event]") : formalName; -} - -QString ActionView::handlerName() const -{ - if (!GetDoc()->isValid() || !m_itemHandle.Valid()) - return QString(); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto bridge = GetBridge(); - const auto handlerHandle = bridge->ResolveHandler(actionInfo); - - if (handlerHandle.Valid()) { - const auto handlerInfo = bridge->GetHandlerInfo(handlerHandle); - return QString::fromWCharArray(handlerInfo.m_FormalName.wide_str()); - } - - return tr("[Unknown Handler]"); -} - -QVariantList ActionView::handlerArguments() const -{ - return m_handlerArguments; -} - -PropertyInfo ActionView::property() const -{ - if (!m_propertyModel) - return {}; - return m_propertyModel->property(m_currentPropertyIndex); -} - -bool ActionView::isPropertyValueInvalid() const -{ - return m_propertyValueInvalid; -} - -void ActionView::setCurrentActionIndex(int index) -{ - if (index == m_currentActionIndex) - return; - - m_currentActionIndex = index; - emitActionChanged(); - - updateActionStates(); -} - -void ActionView::setCurrentPropertyIndex(int handle, int index) -{ - setPropertyValueInvalid(true); - // Make sure propertymodel name & value handles are always up-to-date, - // even when index is same as before - m_currentPropertyValueHandle = 0; - m_currentPropertyNameHandle = handle; - for (int i = 0; i < m_handlerArguments.size(); ++i) { - auto handlerArg = m_handlerArguments[i].value<HandlerArgument>(); - if (handlerArg.m_handle.GetHandleValue() == handle && i < m_handlerArguments.size() - 1) { - m_currentPropertyValueHandle - = m_handlerArguments[i + 1].value<HandlerArgument>().m_handle; - if (m_propertyModel) { - m_propertyModel->setNameHandle(m_currentPropertyNameHandle); - m_propertyModel->setValueHandle(m_currentPropertyValueHandle); - } - } - } - - if (index == m_currentPropertyIndex) - return; - - m_currentPropertyIndex = index; - - // set the property for the handler - if (m_propertyModel && handle != 0) { - qt3dsdm::SValue sValue(QVariant(m_propertyModel->property(index).m_nameId)); - qt3dsdm::SValue oldValue; - GetDoc()->GetStudioSystem()->GetActionCore()->GetHandlerArgumentValue(handle, oldValue); - - if (!Equals(oldValue, sValue)) { - CCmd *theCmd = - new CCmdDataModelActionSetArgumentValue(GetDoc(), handle, sValue); - g_StudioApp.GetCore()->ExecuteCommand(theCmd); - } - } - - Q_EMIT propertyChanged(); - // Clear the value invalid flag asynchronously as the value doesn't actually change until - // backend tells us it does - QTimer::singleShot(0, this, &ActionView::clearPropertyValueInvalid); -} - -void ActionView::addAction() -{ - if (m_itemHandle.Valid()) { - // Query data model bridge to see the applicable events and actions for this instance. - CClientDataModelBridge *theBridge = GetBridge(); - - std::wstring theEventName = theBridge->GetDefaultEvent(m_itemHandle); - std::wstring theHandlerName = theBridge->GetDefaultHandler(m_itemHandle); - - Q3DStudio::SCOPED_DOCUMENT_EDITOR(*GetDoc(), QObject::tr("Add Action")) - ->AddAction(GetDoc()->GetActiveSlide(), m_itemHandle, theEventName, - theHandlerName); - } - updateActionStates(); -} - -void ActionView::deleteAction(int index) -{ - if (!m_itemHandle.Valid()) - return; - - const auto action = m_actionsModel->actionAt(index); - if (action.Valid()) { - Q3DStudio::SCOPED_DOCUMENT_EDITOR(*GetDoc(), - QObject::tr("Delete Action"))->DeleteAction(action); - emitActionChanged(); - } - updateActionStates(); -} - -QObject *ActionView::showTriggerObjectBrowser(const QPoint &point) -{ - if (!m_itemHandle.Valid()) - return nullptr; - - if (!m_objectsModel) { - m_objectsModel = new ObjectListModel(g_StudioApp.GetCore(), - GetDoc()->GetSceneInstance(), this); - } - - if (!m_triggerObjectBrowser) - m_triggerObjectBrowser = new ObjectBrowserView(this); - - m_triggerObjectBrowser->setModel(m_objectsModel); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto instanceHandle = GetBridge()->GetInstance(actionInfo.m_Owner, - actionInfo.m_TriggerObject); - m_triggerObjectBrowser->disconnect(); - m_triggerObjectBrowser->selectAndExpand(instanceHandle, actionInfo.m_Owner); - CDialogs::showWidgetBrowser(this, m_triggerObjectBrowser, point); - m_activeBrowser = m_triggerObjectBrowser; - - connect(m_triggerObjectBrowser, &ObjectBrowserView::selectionChanged, - this, &ActionView::OnTriggerSelectionChanged); - // update also pathtype in the trigger object when changed from UI - connect(m_triggerObjectBrowser, &ObjectBrowserView::pathTypeChanged, - this, &ActionView::OnTriggerSelectionChanged); - - return m_triggerObjectBrowser; -} - -QObject *ActionView::showTargetObjectBrowser(const QPoint &point) -{ - if (!m_itemHandle.Valid()) - return nullptr; - - if (!m_objectsModel) { - m_objectsModel = new ObjectListModel(g_StudioApp.GetCore(), - GetDoc()->GetSceneInstance(), this); - } - - if (!m_targetObjectBrowser) - m_targetObjectBrowser = new ObjectBrowserView(this); - - m_targetObjectBrowser->setModel(m_objectsModel); - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto instanceHandle = GetBridge()->GetInstance(actionInfo.m_Owner, - actionInfo.m_TargetObject); - m_targetObjectBrowser->disconnect(); - m_targetObjectBrowser->selectAndExpand(instanceHandle, actionInfo.m_Owner); - CDialogs::showWidgetBrowser(this, m_targetObjectBrowser, point); - m_activeBrowser = m_targetObjectBrowser; - - connect(m_targetObjectBrowser, &ObjectBrowserView::selectionChanged, - this, &ActionView::OnTargetSelectionChanged); - // update also pathtype in the target object when changed from UI - connect(m_targetObjectBrowser, &ObjectBrowserView::pathTypeChanged, - this, &ActionView::OnTargetSelectionChanged); - - return m_targetObjectBrowser; -} - -void ActionView::OnTargetSelectionChanged() -{ - auto selectedItem = m_targetObjectBrowser->selectedHandle(); - setTargetObject(m_objRefHelper->GetAssetRefValue( - selectedItem, m_itemHandle, - (CRelativePathTools::EPathType)(m_targetObjectBrowser->pathType()))); - resetFiredEvent(); -} - -void ActionView::OnTriggerSelectionChanged() -{ - auto selectedItem = m_triggerObjectBrowser->selectedHandle(); - setTriggerObject(m_objRefHelper->GetAssetRefValue( - selectedItem, m_itemHandle, - (CRelativePathTools::EPathType)(m_triggerObjectBrowser->pathType()))); - resetFiredEvent(); -} - -void ActionView::showContextMenu(int x, int y) -{ - updateActionStates(); - CActionContextMenu contextMenu(QQuickWidget::actions(), this); - contextMenu.exec(mapToGlobal({x, y})); -} - -QObject *ActionView::showEventBrowser(const QPoint &point) -{ - if (!m_itemHandle.Valid()) - return nullptr; - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto bridge = GetBridge(); - const auto instanceHandle = bridge->GetInstance(actionInfo.m_Owner, actionInfo.m_TriggerObject); - - if (!instanceHandle.Valid()) - return nullptr; - - if (!m_eventsModel) - m_eventsModel = new EventsModel(this); - - qt3dsdm::TEventHandleList eventList; - bridge->GetEvents(instanceHandle, eventList); - m_eventsModel->setEventList(eventList); - - if (!m_eventsBrowser) - m_eventsBrowser = new EventsBrowserView(this); - - m_eventsBrowser->setModel(m_eventsModel); - - m_eventsBrowser->disconnect(); - m_eventsBrowser->selectAndExpand(QString::fromStdWString(actionInfo.m_Event)); - CDialogs::showWidgetBrowser(this, m_eventsBrowser, point); - m_activeBrowser = m_eventsBrowser; - - connect(m_eventsBrowser, &EventsBrowserView::selectionChanged, - this, [this] { - if (m_eventsBrowser->canCommit()) - setEvent(qt3dsdm::Qt3DSDMEventHandle(m_eventsBrowser->selectedHandle())); - }); - - return m_eventsBrowser; -} - -QObject *ActionView::showHandlerBrowser(const QPoint &point) -{ - if (!m_itemHandle.Valid()) - return nullptr; - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto bridge = GetBridge(); - const auto instanceHandle = bridge->GetInstance(actionInfo.m_Owner, actionInfo.m_TargetObject); - - if (!instanceHandle.Valid()) - return nullptr; - - if (!m_handlersModel) - m_handlersModel = new EventsModel(this); - - qt3dsdm::THandlerHandleList handlerList; - bridge->GetHandlers(instanceHandle, handlerList); - m_handlersModel->setHandlerList(handlerList); - - if (!m_handlerBrowser) - m_handlerBrowser = new EventsBrowserView(this); - - m_handlerBrowser->setModel(m_handlersModel); - - m_handlerBrowser->disconnect(); - m_handlerBrowser->selectAndExpand(QString::fromStdWString(actionInfo.m_Handler)); - CDialogs::showWidgetBrowser(this, m_handlerBrowser, point); - m_activeBrowser = m_handlerBrowser; - - connect(m_handlerBrowser, &EventsBrowserView::selectionChanged, - this, [this] { - if (m_handlerBrowser->canCommit()) - setHandler(qt3dsdm::Qt3DSDMHandlerHandle(m_handlerBrowser->selectedHandle())); - }); - - return m_handlerBrowser; -} - -QObject *ActionView::showEventBrowserForArgument(int handle, const QPoint &point) -{ - if (!m_itemHandle.Valid()) - return nullptr; - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto bridge = GetBridge(); - const auto instanceHandle = bridge->GetInstance(actionInfo.m_Owner, actionInfo.m_TargetObject); - - if (!instanceHandle.Valid()) - return nullptr; - - if (!m_fireEventsModel) - m_fireEventsModel = new EventsModel(this); - - qt3dsdm::TEventHandleList eventList; - bridge->GetEvents(instanceHandle, eventList); - m_fireEventsModel->setEventList(eventList); - - if (!m_fireEventsBrowser) - m_fireEventsBrowser = new EventsBrowserView(this); - - m_fireEventsBrowser->setModel(m_fireEventsModel); - m_fireEventsBrowser->setHandle(handle); - - qt3dsdm::SValue oldValue; - GetDoc()->GetStudioSystem()->GetActionCore()->GetHandlerArgumentValue(handle, oldValue); - - QString eventName; - for (Qt3DSDMEventHandle eventHandle : eventList) { - if (oldValue == eventHandle.GetHandleValue()) { - qt3dsdm::SEventInfo eventInfo = bridge->GetEventInfo(eventHandle); - eventName = QString::fromWCharArray(eventInfo.m_FormalName.wide_str()); - if (eventName.isEmpty()) - eventName = QString::fromWCharArray(eventInfo.m_Name.wide_str()); - } - } - m_fireEventsBrowser->disconnect(); - m_fireEventsBrowser->selectAndExpand(eventName); - CDialogs::showWidgetBrowser(this, m_fireEventsBrowser, point); - m_activeBrowser = m_fireEventsBrowser; - - connect(m_fireEventsBrowser, &EventsBrowserView::selectionChanged, - this, [this, handle] { - setArgumentValue(handle, qt3dsdm::Qt3DSDMEventHandle( - m_fireEventsBrowser->selectedHandle()).GetHandleValue()); - }); - - return m_fireEventsBrowser; -} - -void ActionView::updateFiredEvent() -{ - if (!m_itemHandle.Valid()) - return; - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - if (actionInfo.m_Handler != L"Fire Event") { - m_firedEvent = tr("[Unknown event]"); - return; - } - - const auto doc = GetDoc(); - if (!doc->isValid()) - return; - - const auto bridge = GetBridge(); - const auto handlerHandle = bridge->ResolveHandler(actionInfo); - IActionCore *actionCore = doc->GetStudioSystem()->GetActionCore(); - - if (handlerHandle.Valid()) { - for (const auto &argHandle: actionInfo.m_HandlerArgs) { - const auto &argumentInfo = actionCore->GetHandlerArgumentInfo(argHandle); - DataModelDataType::Value theArgType(GetValueType(argumentInfo.m_Value)); - SValue theArgValue(argumentInfo.m_Value); - if (argumentInfo.m_ArgType == HandlerArgumentType::Event) { - theArgType = DataModelDataType::String; - auto theEventHandle = get<qt3ds::QT3DSI32>(argumentInfo.m_Value); - theArgValue = SValue(std::make_shared<CDataStr>( - bridge->GetEventInfo(theEventHandle).m_Name.wide_str())); - m_firedEvent = theArgValue.toQVariant().toString(); - Q_EMIT firedEventChanged(); - } - } - } -} - -void ActionView::updateFiredEventFromHandle(int handle) -{ - m_firedEvent = QString::fromWCharArray( - GetBridge()->GetEventInfo(handle).m_FormalName.wide_str()); - Q_EMIT firedEventChanged(); -} - -void ActionView::resetFiredEvent() -{ - m_firedEvent = tr("[Unknown Event]"); - Q_EMIT firedEventChanged(); -} - -void ActionView::OnNewPresentation() -{ - // Register callback - qt3dsdm::IStudioFullSystemSignalProvider *theSignalProvider = - g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetFullSystemSignalProvider(); - m_connections.push_back(theSignalProvider->ConnectActionCreated( - std::bind(&ActionView::OnActionAdded, this, - std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3))); - m_connections.push_back(theSignalProvider->ConnectActionDeleted( - std::bind(&ActionView::OnActionDeleted, this, - std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3))); - m_connections.push_back(theSignalProvider->ConnectTriggerObjectSet( - std::bind(&ActionView::OnActionModified, this, - std::placeholders::_1))); - m_connections.push_back(theSignalProvider->ConnectTargetObjectSet( - std::bind(&ActionView::OnActionModified, this, - std::placeholders::_1))); - m_connections.push_back(theSignalProvider->ConnectEventSet( - std::bind(&ActionView::OnActionModified, this, - std::placeholders::_1))); - m_connections.push_back(theSignalProvider->ConnectHandlerSet( - std::bind(&ActionView::OnActionModified, this, - std::placeholders::_1))); - m_connections.push_back(theSignalProvider->ConnectHandlerArgumentValueSet( - std::bind(&ActionView::OnHandlerArgumentModified, this, - std::placeholders::_1))); - m_connections.push_back(theSignalProvider->ConnectInstancePropertyValue( - std::bind(&ActionView::OnInstancePropertyValueChanged, this, - std::placeholders::_1, - std::placeholders::_2))); - m_connections.push_back(theSignalProvider->ConnectInstanceDeleted( - std::bind(&ActionView::OnInstanceDeleted, this, - std::placeholders::_1))); - CDispatch *theDispatch = g_StudioApp.GetCore()->GetDispatch(); - m_connections.push_back(theDispatch->ConnectSelectionChange( - std::bind(&ActionView::OnSelectionSet, this, - std::placeholders::_1))); - - auto assetGraph = g_StudioApp.GetCore()->GetDoc()->GetAssetGraph(); - m_connections.push_back(assetGraph->ConnectChildAdded( - std::bind(&ActionView::onAssetGraphChanged, this))); - m_connections.push_back(assetGraph->ConnectChildRemoved( - std::bind(&ActionView::onAssetGraphChanged, this))); -} - -void ActionView::OnClosingPresentation() -{ - m_connections.clear(); -} - -void ActionView::OnSelectionSet(Q3DStudio::SSelectedValue inSelectable) -{ - qt3dsdm::Qt3DSDMInstanceHandle theInstance; - std::vector<qt3dsdm::Qt3DSDMInstanceHandle> instances; - - switch (inSelectable.getType()) { - case Q3DStudio::SelectedValueTypes::Instance: - theInstance = inSelectable.getData<qt3dsdm::Qt3DSDMInstanceHandle>(); - break; - case Q3DStudio::SelectedValueTypes::MultipleInstances: - instances = inSelectable.getData<std::vector<qt3dsdm::Qt3DSDMInstanceHandle>>(); - // handling only if we have one selected element. - if (instances.size() == 1) - theInstance = instances[0]; - break; - case Q3DStudio::SelectedValueTypes::Slide: { - qt3dsdm::Qt3DSDMSlideHandle theSlideHandle = - inSelectable.getData<Q3DStudio::SSlideInstanceWrapper>().m_Slide; - // Get the owning component instance - CClientDataModelBridge *theBridge = GetBridge(); - qt3dsdm::SLong4 theComponentGuid = theBridge->GetComponentGuid(theSlideHandle); - Q_ASSERT(theComponentGuid.Valid()); - theInstance = theBridge->GetInstanceByGUID(theComponentGuid); - Q_ASSERT(theInstance.Valid()); - } - break; - default: - // Clear selection on selecting other types or nothing at all - break; - }; - - setItem(theInstance); -} - -void ActionView::OnActionAdded(qt3dsdm::Qt3DSDMActionHandle inAction, - qt3dsdm::Qt3DSDMSlideHandle inSlide, - qt3dsdm::Qt3DSDMInstanceHandle inOwner) -{ - CDoc *theDoc = GetDoc(); - qt3dsdm::CStudioSystem *theStudioSystem = theDoc->GetStudioSystem(); - - qt3dsdm::Qt3DSDMSlideHandle theCurrentSlide = theDoc->GetActiveSlide(); - qt3dsdm::Qt3DSDMSlideHandle theMasterSlideOfAction = - theStudioSystem->GetSlideSystem()->GetMasterSlide(inSlide); - qt3dsdm::Qt3DSDMSlideHandle theMasterOfCurrentSlide = - theStudioSystem->GetSlideSystem()->GetMasterSlide(theCurrentSlide); - - if (!m_activeBrowser.isNull() && m_activeBrowser->isVisible()) { - m_activeBrowser->close(); - m_activeBrowser.clear(); - } - - if (inOwner == m_itemHandle // the action is added to current viewed instance - && (theCurrentSlide == inSlide // and is added to the current viewed slide - || (theMasterSlideOfAction == inSlide - && theMasterOfCurrentSlide == theMasterSlideOfAction))) { - // or it is added to the master of the current viewed slide - m_actionsModel->addAction(inAction); - } -} - -void ActionView::OnActionDeleted(qt3dsdm::Qt3DSDMActionHandle inAction, - qt3dsdm::Qt3DSDMSlideHandle inSlide, - qt3dsdm::Qt3DSDMInstanceHandle inOwner) -{ - Q_UNUSED(inSlide); - Q_UNUSED(inOwner); - - if (!m_activeBrowser.isNull() && m_activeBrowser->isVisible()) { - m_activeBrowser->close(); - m_activeBrowser.clear(); - } - m_actionsModel->removeAction(inAction); -} - -void ActionView::OnActionModified(qt3dsdm::Qt3DSDMActionHandle inAction) -{ - if (!m_itemHandle.Valid()) - return; - - if (GetDoc()->GetStudioSystem()->GetActionCore()->HandleValid(inAction)) { - if (!m_activeBrowser.isNull() && m_activeBrowser->isVisible()) { - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - if (!actionInfo.m_Instance.Valid()) { - m_activeBrowser->close(); - m_activeBrowser.clear(); - } else { - // Update the selection in an active browser dialog - if (m_activeBrowser == m_triggerObjectBrowser) { - const auto instanceHandle = GetBridge()->GetInstance( - actionInfo.m_Owner, actionInfo.m_TriggerObject); - m_triggerObjectBrowser->selectAndExpand(instanceHandle, actionInfo.m_Owner); - } else if (m_activeBrowser == m_targetObjectBrowser) { - const auto instanceHandle = GetBridge()->GetInstance( - actionInfo.m_Owner, actionInfo.m_TargetObject); - m_targetObjectBrowser->selectAndExpand(instanceHandle, actionInfo.m_Owner); - } else if (m_activeBrowser == m_eventsBrowser) { - m_eventsBrowser->selectAndExpand(QString::fromStdWString(actionInfo.m_Event)); - } else if (m_activeBrowser == m_handlerBrowser) { - m_handlerBrowser->selectAndExpand( - QString::fromStdWString(actionInfo.m_Handler)); - } - } - } - m_actionsModel->updateAction(inAction); - emitActionChanged(); - } -} - -void ActionView::OnHandlerArgumentModified(qt3dsdm::Qt3DSDMHandlerArgHandle inHandlerArgument) -{ - if (!m_itemHandle.Valid()) - return; - - if (!m_fireEventsBrowser.isNull() && m_activeBrowser == m_fireEventsBrowser - && m_activeBrowser->isVisible()) { - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - - // m_fireEventsBrowser needs to be closed if another type of target handler is chosen. - // Other browsers will remain valid always as long as the action is selected. - if (actionInfo.m_Handler != L"Fire Event") { - m_activeBrowser->close(); - m_activeBrowser.clear(); - } else { - // Update the selection in an active browser dialog - const auto bridge = GetBridge(); - const auto instanceHandle = bridge->GetInstance(actionInfo.m_Owner, - actionInfo.m_TargetObject); - qt3dsdm::TEventHandleList eventList; - bridge->GetEvents(instanceHandle, eventList); - qt3dsdm::SValue value; - GetDoc()->GetStudioSystem()->GetActionCore()->GetHandlerArgumentValue( - m_fireEventsBrowser->handle(), value); - QString eventName; - for (Qt3DSDMEventHandle eventHandle : eventList) { - if (value == eventHandle.GetHandleValue()) { - qt3dsdm::SEventInfo eventInfo = bridge->GetEventInfo(eventHandle); - eventName = QString::fromWCharArray(eventInfo.m_FormalName.wide_str()); - if (eventName.isEmpty()) - eventName = QString::fromWCharArray(eventInfo.m_Name.wide_str()); - } - } - m_fireEventsBrowser->selectAndExpand(eventName); - } - } - emitActionChanged(); -} - -void ActionView::OnInstancePropertyValueChanged(qt3dsdm::Qt3DSDMInstanceHandle inInstance, - qt3dsdm::Qt3DSDMPropertyHandle inProperty) -{ - if (!m_itemHandle.Valid() || m_itemHandle != inInstance) - return; - - auto bridge = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetClientDataModelBridge(); - if (inProperty == bridge->GetNameProperty()) - Q_EMIT itemTextChanged(); - - emitActionChanged(); -} - -void ActionView::OnInstanceDeleted(qt3dsdm::Qt3DSDMInstanceHandle inInstance) -{ - // Clear the model on instance deletion - if (inInstance == m_itemHandle) { - qt3dsdm::Qt3DSDMInstanceHandle noInstance; - setItem(noInstance); - } -} - -void ActionView::copyAction() -{ - if (!m_itemHandle.Valid()) - return; - - auto theTempAPFile = - GetDoc()->GetDocumentReader().CopyAction(m_actionsModel->actionAt(m_currentActionIndex), - GetDoc()->GetActiveSlide()); - Qt3DSFile theFile(theTempAPFile); - CStudioClipboard::CopyActionToClipboard(theFile); - updateActionStates(); -} - -void ActionView::cutAction() -{ - if (!m_itemHandle.Valid()) - return; - - copyAction(); - auto action = m_actionsModel->actionAt(m_currentActionIndex); - Q3DStudio::SCOPED_DOCUMENT_EDITOR(*GetDoc(), QObject::tr("Cut Action"))->DeleteAction(action); - updateActionStates(); -} - -void ActionView::pasteAction() -{ - if (!m_itemHandle.Valid()) - return; - - Qt3DSFile theTempAPFile = CStudioClipboard::GetActionFromClipboard(); - Q3DStudio::SCOPED_DOCUMENT_EDITOR(*GetDoc(), QObject::tr("Paste Action")) - ->PasteAction(theTempAPFile.GetAbsolutePath(), m_itemHandle); - updateActionStates(); -} - -void ActionView::setTriggerObject(const qt3dsdm::SObjectRefType &object) -{ - auto action = m_actionsModel->actionAt(m_currentActionIndex); - if (!action.Valid()) - return; - - if (!m_triggerObjectBrowser.isNull() && m_triggerObjectBrowser->canCommit()) { - auto core = g_StudioApp.GetCore(); - auto theBridge = GetBridge(); - - auto theCmd = new CCmdDataModelActionSetTriggerObject(GetDoc(), action, object); - const SActionInfo &theActionInfo - = GetDoc()->GetStudioSystem()->GetActionCore()->GetActionInfo(action); - - Qt3DSDMInstanceHandle theBaseInstance = theActionInfo.m_Owner; - Qt3DSDMInstanceHandle theObjectInstance = theBridge->GetInstance(theBaseInstance, object); - Qt3DSDMInstanceHandle theOldInstance = theBridge->GetInstance(theBaseInstance, - theActionInfo.m_TargetObject); - // old instance and object instance could be the same, for example if user changes the type - // from Absolute to Path. In this case we don't need to reset handler or event. - if (theOldInstance != theObjectInstance) { - theCmd->ResetEvent( - theBridge->GetDefaultEvent(theObjectInstance, theActionInfo.m_Event)); - } - - core->ExecuteCommand(theCmd); - } - emitActionChanged(); -} - -void ActionView::setTargetObject(const qt3dsdm::SObjectRefType &object) -{ - auto action = m_actionsModel->actionAt(m_currentActionIndex); - if (!action.Valid()) - return; - - if (!m_targetObjectBrowser.isNull() && m_targetObjectBrowser->canCommit()) { - auto core = g_StudioApp.GetCore(); - auto doc = GetDoc(); - auto theBridge = GetBridge(); - - auto theCmd = new CCmdDataModelActionSetTargetObject(doc, action, object); - const SActionInfo &theActionInfo = doc->GetStudioSystem()->GetActionCore()->GetActionInfo( - action); - - Qt3DSDMInstanceHandle theBaseInstance = theActionInfo.m_Owner; - Qt3DSDMInstanceHandle theObjectInstance = theBridge->GetInstance(theBaseInstance, object); - Qt3DSDMInstanceHandle theOldInstance = theBridge->GetInstance(theBaseInstance, - theActionInfo.m_TargetObject); - // old instance and object instance could be the same, for example if user changes the type - // from Absolute to Path. In this case we don't need to reset handler or event. - if (theOldInstance != theObjectInstance) { - theCmd->ResetHandler( - theBridge->GetDefaultHandler(theObjectInstance, theActionInfo.m_Handler)); - } - - core->ExecuteCommand(theCmd); - } - emitActionChanged(); -} - -void ActionView::setEvent(const Qt3DSDMEventHandle &event) -{ - if (!event.Valid()) - return; - - auto doc = GetDoc(); - const auto action = m_actionsModel->actionAt(m_currentActionIndex); - CCmd *theCmd = new CCmdDataModelActionSetEvent(doc, action, - doc->GetStudioSystem() - ->GetActionMetaData() - ->GetEventInfo(event) - ->m_Name.wide_str()); - g_StudioApp.GetCore()->ExecuteCommand(theCmd); -} - -void ActionView::setHandler(const Qt3DSDMHandlerHandle &handler) -{ - if (!handler.Valid()) - return; - - auto doc = GetDoc(); - const auto action = m_actionsModel->actionAt(m_currentActionIndex); - wstring handlerName(doc->GetStudioSystem()->GetActionMetaData()->GetHandlerInfo(handler) - ->m_Name.wide_str()); - CCmdDataModelActionSetHandler *theCmd = - new CCmdDataModelActionSetHandler(doc, action, handlerName); - theCmd->ResetHandler(handlerName); // reset the handler args - - g_StudioApp.GetCore()->ExecuteCommand(theCmd); -} - -QVariant ActionView::handlerArgumentValue(int handle) const -{ - qt3dsdm::SValue value; - GetDoc()->GetStudioSystem()->GetActionCore()->GetHandlerArgumentValue(handle, value); - return value.toQVariant(); -} - -void ActionView::updateHandlerArguments() -{ - m_currentPropertyValueHandle = 0; - m_currentPropertyNameHandle = 0; - m_handlerArguments.clear(); - const auto doc = GetDoc(); - if (!doc->isValid() || !m_itemHandle.Valid()) - return; - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - const auto bridge = GetBridge(); - const auto handlerHandle = bridge->ResolveHandler(actionInfo); - IActionCore *actionCore = doc->GetStudioSystem()->GetActionCore(); - - if (handlerHandle.Valid()) { - auto newMetaData = doc->GetStudioSystem()->GetActionMetaData(); - - for (const auto &argHandle: actionInfo.m_HandlerArgs) { - const auto &argumentInfo = actionCore->GetHandlerArgumentInfo(argHandle); - Option<SMetaDataHandlerArgumentInfo> argMetaData( - newMetaData->FindHandlerArgumentByName(handlerHandle, argumentInfo.m_Name)); - - HandlerArgument argument; - argument.m_handle = argHandle; - argument.m_type = argMetaData->m_ArgType; - argument.m_name = QString::fromWCharArray(argumentInfo.m_Name.wide_str()); - argument.m_value = argumentInfo.m_Value.toQVariant(); - argument.m_completeType = argMetaData->m_CompleteType; - m_handlerArguments.append(QVariant::fromValue(argument)); - } - } -} - -void ActionView::emitActionChanged() -{ - m_actionChangedCompressionTimer.start(); -} - -void ActionView::setArgumentValue(int handle, const QVariant &value) -{ - if (!m_itemHandle.Valid()) - return; - - if (handle == 0) - return; - - qt3dsdm::SValue sValue(value); - qt3dsdm::SValue oldValue; - GetDoc()->GetStudioSystem()->GetActionCore()->GetHandlerArgumentValue(handle, oldValue); - - if (!Equals(oldValue, sValue)) { - CCmd *theCmd = - new CCmdDataModelActionSetArgumentValue(GetDoc(), handle, sValue); - g_StudioApp.GetCore()->ExecuteCommand(theCmd); - } - - const auto actionInfo = m_actionsModel->actionInfoAt(m_currentActionIndex); - if (actionInfo.m_Handler == L"Fire Event") { - if (value.toInt()) - updateFiredEventFromHandle(value.toInt()); - } -} - -CDoc *ActionView::GetDoc() -{ - return g_StudioApp.GetCore()->GetDoc(); -} - -CClientDataModelBridge *ActionView::GetBridge() -{ - return GetDoc()->GetStudioSystem()->GetClientDataModelBridge(); -} - -void ActionView::initialize() -{ - CStudioPreferences::setQmlContextProperties(rootContext()); - rootContext()->setContextProperty(QStringLiteral("_parentView"), this); - rootContext()->setContextProperty(QStringLiteral("_resDir"), StudioUtils::resourceImageUrl()); - rootContext()->setContextProperty(QStringLiteral("_tabOrderHandler"), tabOrderHandler()); - rootContext()->setContextProperty(QStringLiteral("_mouseHelper"), &m_mouseHelper); - m_mouseHelper.setWidget(this); - - QString shiftKey(QStringLiteral("Shift+")); -#ifdef Q_OS_MACOS - shiftKey = "⇧"; -#endif - rootContext()->setContextProperty(QStringLiteral("_shiftKey"), shiftKey); - qmlRegisterUncreatableType<qt3dsdm::HandlerArgumentType>( - "Qt3DStudio", 1, 0, "HandlerArgumentType", - QStringLiteral("HandlerArgumentType is an enum container")); - qmlRegisterUncreatableType<qt3dsdm::DataModelDataType>( - "Qt3DStudio", 1, 0, "DataModelDataType", - QStringLiteral("DataModelDataType is an enum container")); - qmlRegisterUncreatableType<qt3dsdm::AdditionalMetaDataType>( - "Qt3DStudio", 1, 0, "AdditionalMetaDataType", - QStringLiteral("AdditionalMetaDataType is an enum container")); - qmlRegisterUncreatableType<PropertyInfo>( - "Qt3DStudio", 1, 0, "PropertyInfo", - QStringLiteral("PropertyInfo is not creatable in QML")); - qmlRegisterUncreatableType<qt3dsdm::CompleteMetaDataType>( - "Qt3DStudio", 1, 0, "CompleteMetaDataType", - QStringLiteral("CompleteMetaDataType is an enum container")); - engine()->addImportPath(StudioUtils::qmlImportPath()); - setSource(QUrl(QStringLiteral("qrc:/Palettes/Action/ActionView.qml"))); -} - -QStringList ActionView::slideNames() -{ - if (!m_itemHandle.Valid()) - return {}; - - std::list<Q3DStudio::CString> outSlideNames; - QStringList slideNames; - CClientDataModelBridge *theBridge = GetBridge(); - const auto action = m_actionsModel->actionAt(m_currentActionIndex); - - theBridge->GetSlideNamesOfAction(action, outSlideNames); - - for (auto slideName : outSlideNames) - slideNames.append(slideName.toQString()); - - return slideNames; -} - -int ActionView::slideNameToIndex(const QString &name) -{ - const auto slides = slideNames(); // KDAB_TODO cache it - return slides.indexOf(name); -} - -bool ActionView::toolTipsEnabled() -{ - return CStudioPreferences::ShouldShowTooltips(); -} - -void ActionView::updateActionStates() -{ - bool hasValidAction = (m_currentActionIndex != -1) && m_itemHandle.Valid(); - m_actionCopy->setEnabled(hasValidAction); - m_actionCut->setEnabled(hasValidAction); - m_actionDel->setEnabled(hasValidAction); - // Allow paste action even if item is not valid (list of actions is empty) - m_actionPaste->setEnabled(CStudioClipboard::CanPasteAction()); -} - -// m_propertyValueInvalid flag indicates that property value is changing and -// may not be valid if queried at the moment. It is used to prevent QML errors -// about invalid value types when changing property handlers. -void ActionView::setPropertyValueInvalid(bool invalid) -{ - if (invalid != m_propertyValueInvalid) { - m_propertyValueInvalid = invalid; - Q_EMIT propertyValueInvalidChanged(); - } -} - -// This is used to set m_propertyValueInvalid to false asynchronously -void ActionView::clearPropertyValueInvalid() -{ - setPropertyValueInvalid(false); -} - -void ActionView::onAssetGraphChanged() -{ - // Changes to asset graph invalidate the object browser model, so close it if it is open - if (!m_activeBrowser.isNull() && m_activeBrowser->isVisible() - && (m_activeBrowser == m_targetObjectBrowser - || m_activeBrowser == m_triggerObjectBrowser)) { - m_activeBrowser->close(); - m_activeBrowser.clear(); - } -} |