diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d9e271498f..cbe90b1d3e 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguesubview previewsubview + scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap ) opencs_units (view/render diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index 697c5f4500..544d5cbc56 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -406,6 +406,17 @@ QVariant CSMWorld::RegionMap::data (const QModelIndex& index, int role) const return QString::fromUtf8 (stream.str().c_str()); } + if (role==Role_Region) + { + CellIndex cellIndex = getIndex (index); + + std::map::const_iterator cell = + mMap.find (cellIndex); + + if (cell!=mMap.end() && !cell->second.mRegion.empty()) + return QString::fromUtf8 (Misc::StringUtils::lowerCase (cell->second.mRegion).c_str()); + } + return QVariant(); } diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 7fb89f20ac..699166a725 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -25,6 +25,11 @@ namespace CSMWorld typedef std::pair CellIndex; + enum Role + { + Role_Region = Qt::UserRole + }; + private: struct CellDescription diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp new file mode 100644 index 0000000000..9502c423f8 --- /dev/null +++ b/apps/opencs/view/world/regionmap.cpp @@ -0,0 +1,142 @@ + +#include "regionmap.hpp" + +#include +#include + +#include +#include +#include + +#include "../../model/world/regionmap.hpp" + +void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event) +{ + QMenu menu (this); + + if (getUnselectedCells().size()>0) + menu.addAction (mSelectAllAction); + + if (selectionModel()->selectedIndexes().size()>0) + menu.addAction (mClearSelectionAction); + + if (getMissingRegionCells().size()>0) + menu.addAction (mSelectRegionsAction); + + menu.exec (event->globalPos()); +} + +QModelIndexList CSVWorld::RegionMap::getUnselectedCells() const +{ + const QAbstractItemModel *model = QTableView::model(); + + int rows = model->rowCount(); + int columns = model->columnCount(); + + QModelIndexList selected = selectionModel()->selectedIndexes(); + std::sort (selected.begin(), selected.end()); + + QModelIndexList all; + + for (int y=0; yindex (y, x); + if (model->data (index, Qt::BackgroundRole)!=QBrush (Qt::DiagCrossPattern)) + all.push_back (index); + } + + std::sort (all.begin(), all.end()); + + QModelIndexList list; + + std::set_difference (all.begin(), all.end(), selected.begin(), selected.end(), + std::back_inserter (list)); + + return list; +} + +QModelIndexList CSVWorld::RegionMap::getMissingRegionCells() const +{ + const QAbstractItemModel *model = QTableView::model(); + + QModelIndexList selected = selectionModel()->selectedIndexes(); + + std::set regions; + + for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + { + std::string region = + model->data (*iter, CSMWorld::RegionMap::Role_Region).toString().toUtf8().constData(); + + if (!region.empty()) + regions.insert (region); + } + + QModelIndexList list; + + QModelIndexList unselected = getUnselectedCells(); + + for (QModelIndexList::const_iterator iter (unselected.begin()); iter!=unselected.end(); ++iter) + { + std::string region = + model->data (*iter, CSMWorld::RegionMap::Role_Region).toString().toUtf8().constData(); + + if (!region.empty() && regions.find (region)!=regions.end()) + list.push_back (*iter); + } + + return list; +} + +CSVWorld::RegionMap::RegionMap (QAbstractItemModel *model, QWidget *parent) +: QTableView (parent) +{ + verticalHeader()->hide(); + horizontalHeader()->hide(); + + setSelectionMode (QAbstractItemView::ExtendedSelection); + + setModel (model); + + resizeColumnsToContents(); + resizeRowsToContents(); + + mSelectAllAction = new QAction (tr ("Select All"), this); + connect (mSelectAllAction, SIGNAL (triggered()), this, SLOT (selectAll())); + addAction (mSelectAllAction); + + mClearSelectionAction = new QAction (tr ("Clear Selection"), this); + connect (mClearSelectionAction, SIGNAL (triggered()), this, SLOT (clearSelection())); + addAction (mClearSelectionAction); + + mSelectRegionsAction = new QAction (tr ("Select Regions"), this); + connect (mSelectRegionsAction, SIGNAL (triggered()), this, SLOT (selectRegions())); + addAction (mSelectRegionsAction); +} + +void CSVWorld::RegionMap::setEditLock (bool locked) +{ + +} + +void CSVWorld::RegionMap::selectAll() +{ + QModelIndexList unselected = getUnselectedCells(); + + for (QModelIndexList::const_iterator iter (unselected.begin()); iter!=unselected.end(); ++iter) + selectionModel()->select (*iter, QItemSelectionModel::Select); +} + +void CSVWorld::RegionMap::clearSelection() +{ + selectionModel()->clearSelection(); +} + +void CSVWorld::RegionMap::selectRegions() +{ + QModelIndexList unselected = getMissingRegionCells(); + + for (QModelIndexList::const_iterator iter (unselected.begin()); iter!=unselected.end(); ++iter) + selectionModel()->select (*iter, QItemSelectionModel::Select); +} \ No newline at end of file diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp new file mode 100644 index 0000000000..e30267b03b --- /dev/null +++ b/apps/opencs/view/world/regionmap.hpp @@ -0,0 +1,45 @@ +#ifndef CSV_WORLD_REGIONMAP_H +#define CSV_WORLD_REGIONMAP_H + +#include + +class QAction; +class QAbstractItemModel; + +namespace CSVWorld +{ + class RegionMap : public QTableView + { + Q_OBJECT + + QAction *mSelectAllAction; + QAction *mClearSelectionAction; + QAction *mSelectRegionsAction; + + private: + + void contextMenuEvent (QContextMenuEvent *event); + + QModelIndexList getUnselectedCells() const; + ///< Note non-existent cells are not listed. + + QModelIndexList getMissingRegionCells() const; + ///< Unselected cells within all regions that have at least one selected cell. + + public: + + RegionMap (QAbstractItemModel *model, QWidget *parent = 0); + + void setEditLock (bool locked); + + private slots: + + void selectAll(); + + void clearSelection(); + + void selectRegions(); + }; +} + +#endif diff --git a/apps/opencs/view/world/regionmapsubview.cpp b/apps/opencs/view/world/regionmapsubview.cpp index b82c1afb54..e170ee309a 100644 --- a/apps/opencs/view/world/regionmapsubview.cpp +++ b/apps/opencs/view/world/regionmapsubview.cpp @@ -1,29 +1,18 @@ #include "regionmapsubview.hpp" -#include -#include +#include "regionmap.hpp" CSVWorld::RegionMapSubView::RegionMapSubView (CSMWorld::UniversalId universalId, CSMDoc::Document& document) : CSVDoc::SubView (universalId) { - mTable = new QTableView (this); + mRegionMap = new RegionMap (document.getData().getTableModel (universalId), this); - mTable->verticalHeader()->hide(); - mTable->horizontalHeader()->hide(); - - mTable->setSelectionMode (QAbstractItemView::ExtendedSelection); - - mTable->setModel (document.getData().getTableModel (universalId)); - - mTable->resizeColumnsToContents(); - mTable->resizeRowsToContents(); - - setWidget (mTable); + setWidget (mRegionMap); } void CSVWorld::RegionMapSubView::setEditLock (bool locked) { - + mRegionMap->setEditLock (locked); } \ No newline at end of file diff --git a/apps/opencs/view/world/regionmapsubview.hpp b/apps/opencs/view/world/regionmapsubview.hpp index 1655107af3..f329c7f3b9 100644 --- a/apps/opencs/view/world/regionmapsubview.hpp +++ b/apps/opencs/view/world/regionmapsubview.hpp @@ -3,7 +3,7 @@ #include "../doc/subview.hpp" -class QTableView; +class QAction; namespace CSMDoc { @@ -12,9 +12,13 @@ namespace CSMDoc namespace CSVWorld { + class RegionMap; + class RegionMapSubView : public CSVDoc::SubView { - QTableView *mTable; + Q_OBJECT + + RegionMap *mRegionMap; public: