Merge branch 'disableinfotablesorting' into 'master'

[OpenMW-CS] Info table dragging to move record order, disable sorting

See merge request OpenMW/openmw!538
pull/3044/head
psi29a 3 years ago
commit a8c5607aa6

@ -23,6 +23,7 @@
Bug #4083: Door animation freezes when colliding with actors Bug #4083: Door animation freezes when colliding with actors
Bug #4201: Projectile-projectile collision Bug #4201: Projectile-projectile collision
Bug #4247: Cannot walk up stairs in Ebonheart docks Bug #4247: Cannot walk up stairs in Ebonheart docks
Bug #4357: OpenMW-CS: TopicInfos index sorting and rearranging isn't fully functional
Bug #4363: Editor: Defect in Clone Function for Dialogue Info records Bug #4363: Editor: Defect in Clone Function for Dialogue Info records
Bug #4447: Actor collision capsule shape allows looking through some walls Bug #4447: Actor collision capsule shape allows looking through some walls
Bug #4465: Collision shape overlapping causes twitching Bug #4465: Collision shape overlapping causes twitching

@ -35,6 +35,7 @@ Bug Fixes:
Editor Bug Fixes: Editor Bug Fixes:
- Deleted and moved objects within a cell are now saved properly (#832) - Deleted and moved objects within a cell are now saved properly (#832)
- Disabled record sorting in Topic and Journal Info tables, implemented drag-move for records (#4357)
- Topic and Journal Info records can now be cloned with a different parent Topic/Journal Id (#4363) - Topic and Journal Info records can now be cloned with a different parent Topic/Journal Id (#4363)
- Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400) - Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400)
- Loading mods now keeps the master index (#5675) - Loading mods now keeps the master index (#5675)

@ -15,7 +15,15 @@ bool CSVWorld::DragDropUtils::canAcceptData(const QDropEvent &event, CSMWorld::C
return data != nullptr && data->holdsType(type); return data != nullptr && data->holdsType(type);
} }
CSMWorld::UniversalId CSVWorld::DragDropUtils::getAcceptedData(const QDropEvent &event, bool CSVWorld::DragDropUtils::isInfo(const QDropEvent &event, CSMWorld::ColumnBase::Display type)
{
const CSMWorld::TableMimeData *data = getTableMimeData(event);
return data != nullptr && (
data->holdsType(CSMWorld::UniversalId::Type_TopicInfo) ||
data->holdsType(CSMWorld::UniversalId::Type_JournalInfo) );
}
CSMWorld::UniversalId CSVWorld::DragDropUtils::getAcceptedData(const QDropEvent &event,
CSMWorld::ColumnBase::Display type) CSMWorld::ColumnBase::Display type)
{ {
if (canAcceptData(event, type)) if (canAcceptData(event, type))

@ -20,6 +20,9 @@ namespace CSVWorld
bool canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display type); bool canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display type);
///< Checks whether the \a event contains a valid CSMWorld::TableMimeData that holds the \a type ///< Checks whether the \a event contains a valid CSMWorld::TableMimeData that holds the \a type
bool isInfo(const QDropEvent &event, CSMWorld::ColumnBase::Display type);
///< Info types can be dragged to sort the info table
CSMWorld::UniversalId getAcceptedData(const QDropEvent &event, CSMWorld::ColumnBase::Display type); CSMWorld::UniversalId getAcceptedData(const QDropEvent &event, CSMWorld::ColumnBase::Display type);
///< Gets the accepted data from the \a event using the \a type ///< Gets the accepted data from the \a event using the \a type
///< \return Type_None if the \a event data doesn't holds the \a type ///< \return Type_None if the \a event data doesn't holds the \a type

@ -46,7 +46,8 @@ void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent *event)
void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event) void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event)
{ {
QModelIndex index = indexAt(event->pos()); QModelIndex index = indexAt(event->pos());
if (CSVWorld::DragDropUtils::canAcceptData(*event, getIndexDisplayType(index))) if (CSVWorld::DragDropUtils::canAcceptData(*event, getIndexDisplayType(index)) ||
CSVWorld::DragDropUtils::isInfo(*event, getIndexDisplayType(index)) )
{ {
if (index.flags() & Qt::ItemIsEditable) if (index.flags() & Qt::ItemIsEditable)
{ {
@ -75,6 +76,10 @@ void CSVWorld::DragRecordTable::dropEvent(QDropEvent *event)
} }
} }
} }
else if (CSVWorld::DragDropUtils::isInfo(*event, display) && event->source() == this)
{
emit moveRecordsFromSameTable(event);
}
} }
CSMWorld::ColumnBase::Display CSVWorld::DragRecordTable::getIndexDisplayType(const QModelIndex &index) const CSMWorld::ColumnBase::Display CSVWorld::DragRecordTable::getIndexDisplayType(const QModelIndex &index) const

@ -23,6 +23,8 @@ namespace CSVWorld
{ {
class DragRecordTable : public QTableView class DragRecordTable : public QTableView
{ {
Q_OBJECT
protected: protected:
CSMDoc::Document& mDocument; CSMDoc::Document& mDocument;
bool mEditLock; bool mEditLock;
@ -45,6 +47,9 @@ namespace CSVWorld
private: private:
CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex &index) const; CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex &index) const;
signals:
void moveRecordsFromSameTable(QDropEvent *event);
}; };
} }

@ -75,10 +75,10 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
new CSVDoc::SubViewFactoryWithCreator<TableSubView, JournalCreatorFactory>); new CSVDoc::SubViewFactoryWithCreator<TableSubView, JournalCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_TopicInfos, manager.add (CSMWorld::UniversalId::Type_TopicInfos,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>); new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>(false));
manager.add (CSMWorld::UniversalId::Type_JournalInfos, manager.add (CSMWorld::UniversalId::Type_JournalInfos,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>); new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>(false));
manager.add (CSMWorld::UniversalId::Type_Pathgrids, manager.add (CSMWorld::UniversalId::Type_Pathgrids,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, PathgridCreatorFactory>); new CSVDoc::SubViewFactoryWithCreator<TableSubView, PathgridCreatorFactory>);

@ -7,6 +7,7 @@
#include <QString> #include <QString>
#include <QtCore/qnamespace.h> #include <QtCore/qnamespace.h>
#include <components/debug/debuglog.hpp>
#include <components/misc/helpviewer.hpp> #include <components/misc/helpviewer.hpp>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
@ -248,6 +249,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
if (isInfoTable) if (isInfoTable)
{ {
mProxyModel = new CSMWorld::InfoTableProxyModel(id.getType(), this); mProxyModel = new CSMWorld::InfoTableProxyModel(id.getType(), this);
connect (this, &CSVWorld::DragRecordTable::moveRecordsFromSameTable, this, &CSVWorld::Table::moveRecords);
} }
else if (isLtexTable) else if (isLtexTable)
{ {
@ -563,6 +565,77 @@ void CSVWorld::Table::moveDownRecord()
} }
} }
void CSVWorld::Table::moveRecords(QDropEvent *event)
{
if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
return;
QModelIndex targedIndex = indexAt(event->pos());
QModelIndexList selectedRows = selectionModel()->selectedRows();
int targetRowRaw = targedIndex.row();
int targetRow = mProxyModel->mapToSource (mProxyModel->index (targetRowRaw, 0)).row();
int baseRowRaw = targedIndex.row() - 1;
int baseRow = mProxyModel->mapToSource (mProxyModel->index (baseRowRaw, 0)).row();
int highestDifference = 0;
for (const auto& thisRowData : selectedRows)
{
int thisRow = mProxyModel->mapToSource (mProxyModel->index (thisRowData.row(), 0)).row();
if (std::abs(targetRow - thisRow) > highestDifference) highestDifference = std::abs(targetRow - thisRow);
if (thisRow - 1 < baseRow) baseRow = thisRow - 1;
}
std::vector<int> newOrder (highestDifference + 1);
for (long unsigned int i = 0; i < newOrder.size(); ++i)
{
newOrder[i] = i;
}
if (selectedRows.size() > 1)
{
Log(Debug::Warning) << "Move operation failed: Moving multiple selections isn't implemented.";
return;
}
for (const auto& thisRowData : selectedRows)
{
/*
Moving algorithm description
a) Remove the (ORIGIN + 1)th list member.
b) Add (ORIGIN+1)th list member with value TARGET
c) If ORIGIN > TARGET,d_INC; ELSE d_DEC
d_INC) increase all members after (and including) the TARGET by one, stop before hitting ORIGINth address
d_DEC) decrease all members after the ORIGIN by one, stop after hitting address TARGET
*/
int originRowRaw = thisRowData.row();
int originRow = mProxyModel->mapToSource (mProxyModel->index (originRowRaw, 0)).row();
newOrder.erase(newOrder.begin() + originRow - baseRow - 1);
newOrder.emplace(newOrder.begin() + originRow - baseRow - 1, targetRow - baseRow - 1);
if (originRow > targetRow)
{
for (int i = targetRow - baseRow - 1; i < originRow - baseRow - 1; ++i)
{
++newOrder[i];
}
}
else
{
for (int i = originRow - baseRow; i <= targetRow - baseRow - 1; ++i)
{
--newOrder[i];
}
}
}
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (
dynamic_cast<CSMWorld::IdTable&> (*mModel), baseRow + 1, newOrder));
}
void CSVWorld::Table::editCell() void CSVWorld::Table::editCell()
{ {
emit editRequest(mEditIdAction->getCurrentId(), ""); emit editRequest(mEditIdAction->getCurrentId(), "");

@ -141,6 +141,8 @@ namespace CSVWorld
void moveDownRecord(); void moveDownRecord();
void moveRecords(QDropEvent *event);
void viewRecord(); void viewRecord();
void previewRecord(); void previewRecord();

Loading…
Cancel
Save