#include "pagedworldspacewidget.hpp" #include #include #include #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" #include "../widget/scenetooltoggle.hpp" #include "elements.hpp" bool CSVRender::PagedWorldspaceWidget::adjustCells() { bool modified = false; bool setCamera = false; const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); { // remove std::map::iterator iter (mCells.begin()); while (iter!=mCells.end()) { int index = cells.searchId (iter->first.getId (mWorldspace)); if (!mSelection.has (iter->first) || index==-1 || cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted) { delete iter->second; mCells.erase (iter++); modified = true; } else ++iter; } } if (mCells.begin()==mCells.end()) setCamera = true; // add for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); ++iter) { int index = cells.searchId (iter->getId (mWorldspace)); if (index!=0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted && mCells.find (*iter)==mCells.end()) { if (setCamera) { setCamera = false; getCamera()->setPosition (8192*iter->getX()+4096, 8192*iter->getY()+4096, 0); } mCells.insert (std::make_pair (*iter, new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)))); modified = true; } } return modified; } void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) if (iter->second->referenceableDataChanged (topLeft, bottomRight)) flagAsModified(); } void CSVRender::PagedWorldspaceWidget::referenceableAboutToBeRemoved ( const QModelIndex& parent, int start, int end) { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) if (iter->second->referenceableAboutToBeRemoved (parent, start, end)) flagAsModified(); } void CSVRender::PagedWorldspaceWidget::referenceableAdded (const QModelIndex& parent, int start, int end) { CSMWorld::IdTable& referenceables = dynamic_cast ( *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables)); for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) { QModelIndex topLeft = referenceables.index (start, 0); QModelIndex bottomRight = referenceables.index (end, referenceables.columnCount()); if (iter->second->referenceableDataChanged (topLeft, bottomRight)) flagAsModified(); } } void CSVRender::PagedWorldspaceWidget::referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) if (iter->second->referenceDataChanged (topLeft, bottomRight)) flagAsModified(); } void CSVRender::PagedWorldspaceWidget::referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) if (iter->second->referenceAboutToBeRemoved (parent, start, end)) flagAsModified(); } void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent, int start, int end) { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) if (iter->second->referenceAdded (parent, start, end)) flagAsModified(); } CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) : WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default") { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); connect (cells, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&))); connect (cells, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), this, SLOT (cellRemoved (const QModelIndex&, int, int))); connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (cellAdded (const QModelIndex&, int, int))); } CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) delete iter->second; } void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) { if (!hint.empty()) { CSMWorld::CellSelection selection; if (hint[0]=='c') { // syntax: c:#x1 y1; #x2 y2 (number of coordinate pairs can be 0 or larger) char ignore; std::istringstream stream (hint.c_str()); if (stream >> ignore) { char ignore1; // : or ; char ignore2; // # int x, y; while (stream >> ignore1 >> ignore2 >> x >> y) selection.add (CSMWorld::CellCoordinates (x, y)); /// \todo adjust camera position } } else if (hint[0]=='r') { /// \todo implement 'r' type hints } setCellSelection (selection); } } void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSelection& selection) { mSelection = selection; if (adjustCells()) flagAsModified(); emit cellSelectionChanged (mSelection); } std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const { std::istringstream stream (record.c_str()); char ignore; int x, y; stream >> ignore >> x >> y; return std::make_pair(x, y); } void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) { bool selectionChanged = false; for (unsigned i = 0; i < data.size(); ++i) { std::pair coordinates(getCoordinatesFromId(data[i].getId())); if (mSelection.add(CSMWorld::CellCoordinates(coordinates.first, coordinates.second))) { selectionChanged = true; } } if (selectionChanged) { if (adjustCells()) flagAsModified(); emit cellSelectionChanged(mSelection); } } CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const { switch (type) { case cellsExterior: return canHandle; case cellsInterior: return needUnpaged; default: return ignored; } } unsigned int CSVRender::PagedWorldspaceWidget::getElementMask() const { return WorldspaceWidget::getElementMask() | mControlElements->getSelection(); } CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector ( CSVWidget::SceneToolbar *parent) { mControlElements = new CSVWidget::SceneToolToggle (parent, "Controls & Guides Visibility", ":door.png"); mControlElements->addButton (":activator.png", Element_CellMarker, ":activator.png", "Cell marker"); mControlElements->addButton (":armor.png", Element_CellArrow, ":armor.png", "Cell arrows"); mControlElements->addButton (":armor.png", Element_CellBorder, ":armor.png", "Cell border"); mControlElements->setSelection (0xffffffff); connect (mControlElements, SIGNAL (selectionChanged()), this, SLOT (elementSelectionChanged())); return mControlElements; } void CSVRender::PagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { /// \todo check if no selected cell is affected and do not update, if that is the case if (adjustCells()) flagAsModified(); } void CSVRender::PagedWorldspaceWidget::cellRemoved (const QModelIndex& parent, int start, int end) { if (adjustCells()) flagAsModified(); } void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int start, int end) { /// \todo check if no selected cell is affected and do not update, if that is the case if (adjustCells()) flagAsModified(); }