123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <QATLControlsTreeModel.h>
- #include <ACEEnums.h>
- #include <AudioControl.h>
- #include <AudioControlsEditorUndo.h>
- #include <IEditor.h>
- #include <QAudioControlTreeWidget.h>
- #include <QStandardItem>
- #include <QMessageBox>
- namespace AudioControls
- {
- //-------------------------------------------------------------------------------------------//
- QATLTreeModel::QATLTreeModel()
- : m_pControlsModel(nullptr)
- {
- }
- //-------------------------------------------------------------------------------------------//
- QATLTreeModel::~QATLTreeModel()
- {
- if (m_pControlsModel)
- {
- m_pControlsModel->RemoveListener(this);
- }
- }
- //-------------------------------------------------------------------------------------------//
- void QATLTreeModel::Initialize(CATLControlsModel* pControlsModel)
- {
- m_pControlsModel = pControlsModel;
- m_pControlsModel->AddListener(this);
- }
- //-------------------------------------------------------------------------------------------//
- QStandardItem* QATLTreeModel::GetItemFromControlID(CID nID)
- {
- QModelIndexList indexes = match(index(0, 0, QModelIndex()), eDR_ID, nID, 1, Qt::MatchRecursive);
- if (!indexes.empty())
- {
- return itemFromIndex(indexes.at(0));
- }
- return nullptr;
- }
- //-------------------------------------------------------------------------------------------//
- QStandardItem* QATLTreeModel::AddControl(CATLControl* pControl, QStandardItem* pParent, int nRow)
- {
- if (pControl && pParent)
- {
- QStandardItem* pItem = new QAudioControlItem(QString(pControl->GetName().c_str()), pControl);
- if (pItem)
- {
- pParent->insertRow(nRow, pItem);
- SetItemAsDirty(pItem);
- }
- return pItem;
- }
- return nullptr;
- }
- //-------------------------------------------------------------------------------------------//
- QStandardItem* QATLTreeModel::CreateFolder(QStandardItem* pParent, const AZStd::string_view sName, int nRow)
- {
- if (pParent)
- {
- // Make a valid name for the folder (avoid having folders with the same name under same root)
- QString sRootName(sName.data());
- QString sFolderName(sRootName);
- int number = 1;
- bool bFoundName = false;
- while (!bFoundName)
- {
- bFoundName = true;
- const int size = pParent->rowCount();
- for (int i = 0; i < size; ++i)
- {
- QStandardItem* pItem = pParent->child(i);
- if (pItem && (pItem->data(eDR_TYPE) == eIT_FOLDER) && (QString::compare(sFolderName, pItem->text(), Qt::CaseInsensitive) == 0))
- {
- bFoundName = false;
- sFolderName = sRootName + "_" + QString::number(number);
- ++number;
- break;
- }
- }
- }
- if (!sFolderName.isEmpty())
- {
- if (QStandardItem* pFolderItem = new QFolderItem(sFolderName))
- {
- SetItemAsDirty(pFolderItem);
- pParent->insertRow(nRow, pFolderItem);
- if (!CUndo::IsSuspended())
- {
- CUndo undo("Audio Folder Created");
- CUndo::Record(new CUndoFolderAdd(pFolderItem));
- }
- return pFolderItem;
- }
- }
- }
- return nullptr;
- }
- //-------------------------------------------------------------------------------------------//
- void QATLTreeModel::RemoveItem(QModelIndex index)
- {
- QModelIndexList indexList;
- indexList.push_back(index);
- RemoveItems(indexList);
- }
- //-------------------------------------------------------------------------------------------//
- void QATLTreeModel::RemoveItems(QModelIndexList indexList)
- {
- // Sort the controls by the level they are inside the tree
- // (the deepest in the tree first) and then by their row number.
- // This way we guarantee we don't delete the parent of a
- // control before its children
- struct STreeIndex
- {
- QPersistentModelIndex m_index;
- int m_level;
- STreeIndex(QPersistentModelIndex index, int level)
- : m_index(index)
- , m_level(level) {}
- bool operator< (const STreeIndex& index) const
- {
- if (m_level == index.m_level)
- {
- return m_index.row() > index.m_index.row();
- }
- return m_level > index.m_level;
- }
- };
- AZStd::vector<STreeIndex> sortedIndexList;
- const int size = indexList.length();
- for (int i = 0; i < size; ++i)
- {
- int level = 0;
- QModelIndex index = indexList[i];
- while (index.isValid())
- {
- ++level;
- index = index.parent();
- }
- sortedIndexList.push_back(STreeIndex(indexList[i], level));
- }
- std::sort(sortedIndexList.begin(), sortedIndexList.end());
- for (int i = 0; i < size; ++i)
- {
- QModelIndex index = sortedIndexList[i].m_index;
- if (index.isValid())
- {
- DeleteInternalData(index);
- // Mark parent as modified
- QModelIndex parent = index.parent();
- if (parent.isValid())
- {
- SetItemAsDirty(itemFromIndex(parent));
- }
- removeRow(index.row(), index.parent());
- }
- }
- }
- //-------------------------------------------------------------------------------------------//
- void QATLTreeModel::DeleteInternalData(QModelIndex root)
- {
- // Delete children first and in reverse order
- // of their row (so that we can undo them in the same order)
- AZStd::vector<QModelIndex> childs;
- QModelIndex child = index(0, 0, root);
- for (int i = 1; child.isValid(); ++i)
- {
- childs.push_back(child);
- child = index(i, 0, root);
- }
- const size_t size = childs.size();
- for (size_t i = 0; i < size; ++i)
- {
- DeleteInternalData(childs[(size - 1) - i]);
- }
- if (root.data(eDR_TYPE) == eIT_AUDIO_CONTROL)
- {
- m_pControlsModel->RemoveControl(root.data(eDR_ID).toUInt());
- }
- else
- {
- if (!CUndo::IsSuspended())
- {
- CUndo::Record(new CUndoFolderRemove(itemFromIndex(root)));
- }
- }
- }
- //-------------------------------------------------------------------------------------------//
- CATLControl* QATLTreeModel::GetControlFromIndex(QModelIndex index)
- {
- if (m_pControlsModel && index.isValid() && (index.data(eDR_TYPE) == eIT_AUDIO_CONTROL))
- {
- return m_pControlsModel->GetControlByID(index.data(eDR_ID).toUInt());
- }
- return nullptr;
- }
- //-------------------------------------------------------------------------------------------//
- void QATLTreeModel::OnControlModified(CATLControl* pControl)
- {
- if (pControl)
- {
- if (QStandardItem* pItem = GetItemFromControlID(pControl->GetId()))
- {
- QString sNewName(pControl->GetName().c_str());
- if (pItem->text() != sNewName)
- {
- pItem->setText(sNewName);
- }
- SetItemAsDirty(pItem);
- }
- }
- }
- //-------------------------------------------------------------------------------------------//
- void QATLTreeModel::SetItemAsDirty(QStandardItem* pItem)
- {
- if (pItem)
- {
- blockSignals(true);
- pItem->setData(true, eDR_MODIFIED);
- blockSignals(false);
- SetItemAsDirty(pItem->parent());
- }
- }
- //-------------------------------------------------------------------------------------------//
- CATLControl* QATLTreeModel::CreateControl(EACEControlType eControlType, const AZStd::string_view sName, CATLControl* pParent)
- {
- AZStd::string sFinalName = m_pControlsModel->GenerateUniqueName(sName, eControlType, pParent ? pParent->GetScope() : "", pParent);
- return m_pControlsModel->CreateControl(sFinalName, eControlType, pParent);
- }
- //-------------------------------------------------------------------------------------------//
- bool QATLTreeModel::dropMimeData(const QMimeData* mimeData, Qt::DropAction action, int row, int column, const QModelIndex& parent)
- {
- // LY-17684
- QStandardItem* rootItem = invisibleRootItem();
- QStandardItem* targetItem = rootItem;
- if (parent.isValid())
- {
- targetItem = itemFromIndex(parent);
- }
- if (targetItem)
- {
- if (targetItem && (targetItem->data(eDR_TYPE) == eIT_FOLDER || targetItem == rootItem))
- {
- const QString format = "application/x-qabstractitemmodeldatalist";
- if (mimeData->hasFormat(format))
- {
- QByteArray encoded = mimeData->data(format);
- QDataStream stream(&encoded, QIODevice::ReadOnly);
- while (!stream.atEnd())
- {
- int streamRow, streamCol;
- QMap<int, QVariant> roleDataMap;
- stream >> streamRow >> streamCol >> roleDataMap;
- if (!roleDataMap.isEmpty())
- {
- // If dropping a folder, make sure that folder name doesn't already exist where it is being dropped
- if (roleDataMap[eDR_TYPE] == eIT_FOLDER)
- {
- // Make sure the target folder doesn't have a folder with the same name
- QString droppedFolderName = roleDataMap[Qt::DisplayRole].toString();
- const int size = targetItem->rowCount();
- for (int i = 0; i < size; ++i)
- {
- QStandardItem* pItem = targetItem->child(i);
- if (pItem && (pItem->data(eDR_TYPE) == eIT_FOLDER) && (QString::compare(droppedFolderName, pItem->text(), Qt::CaseInsensitive) == 0))
- {
- QMessageBox messageBox;
- messageBox.setStandardButtons(QMessageBox::Ok);
- messageBox.setWindowTitle("Audio Controls Editor");
- messageBox.setText("This destination already contains a folder named '" + droppedFolderName + "'.");
- messageBox.exec();
- return false;
- }
- }
- }
- }
- }
- }
- }
- }
- if (mimeData && action == Qt::MoveAction)
- {
- if (!CUndo::IsSuspended())
- {
- CUndo undo("Audio Control Moved");
- CUndo::Record(new CUndoItemMove());
- }
- }
- return QStandardItemModel::dropMimeData(mimeData, action, row, column, parent);
- }
- //-------------------------------------------------------------------------------------------//
- bool QATLTreeModel::canDropMimeData(const QMimeData* mimeData, Qt::DropAction action, int row, int column, const QModelIndex& parent) const
- {
- if (!parent.isValid())
- {
- // Prevent moving controls to the root (outside a folder)
- const QString format = "application/x-qabstractitemmodeldatalist";
- if (mimeData->hasFormat(format))
- {
- QByteArray data = mimeData->data(format);
- QDataStream stream(&data, QIODevice::ReadOnly);
- int streamRow, streamCol;
- QMap<int, QVariant> roleDataMap;
- stream >> streamRow >> streamCol >> roleDataMap;
- if (!roleDataMap.isEmpty() && roleDataMap[eDR_TYPE] != eIT_FOLDER)
- {
- return false;
- }
- }
- }
- else if (parent.data(eDR_TYPE) == eIT_AUDIO_CONTROL)
- {
- // Prevent dropping on switches
- CID nID = parent.data(eDR_ID).toUInt();
- if (CATLControl* pControl = m_pControlsModel->GetControlByID(nID))
- {
- EACEControlType eType = pControl->GetType();
- if (eType == eACET_SWITCH || eType == eACET_SWITCH_STATE)
- {
- return false;
- }
- }
- }
- return QStandardItemModel::canDropMimeData(mimeData, action, row, column, parent);
- }
- } // namespace AudioControls
|