mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-25 16:43:33 +00:00
Implement basic move algorithm, connect it to drag&drop
This commit is contained in:
parent
70087e16fe
commit
16e03c151a
@ -15,7 +15,15 @@ bool CSVWorld::DragDropUtils::canAcceptData(const QDropEvent &event, CSMWorld::C
|
||||
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)
|
||||
{
|
||||
if (canAcceptData(event, type))
|
||||
|
@ -20,6 +20,9 @@ namespace CSVWorld
|
||||
bool canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display 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);
|
||||
///< 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
|
||||
|
@ -46,7 +46,8 @@ void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent *event)
|
||||
void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
|
@ -23,6 +23,8 @@ namespace CSVWorld
|
||||
{
|
||||
class DragRecordTable : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
CSMDoc::Document& mDocument;
|
||||
bool mEditLock;
|
||||
@ -45,6 +47,9 @@ namespace CSVWorld
|
||||
|
||||
private:
|
||||
CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex &index) const;
|
||||
|
||||
signals:
|
||||
void moveRecordsFromSameTable(QDropEvent *event);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QString>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/misc/helpviewer.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
@ -248,6 +249,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||
if (isInfoTable)
|
||||
{
|
||||
mProxyModel = new CSMWorld::InfoTableProxyModel(id.getType(), this);
|
||||
connect (this, &CSVWorld::DragRecordTable::moveRecordsFromSameTable, this, &CSVWorld::Table::moveRecords);
|
||||
}
|
||||
else if (isLtexTable)
|
||||
{
|
||||
@ -563,6 +565,74 @@ 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 targetRow = targedIndex.row();
|
||||
int baseRow = targedIndex.row() - 1;
|
||||
int highestDifference = 0;
|
||||
|
||||
for (const auto& thisRowData : selectedRows)
|
||||
{
|
||||
if (std::abs(targetRow - thisRowData.row()) > highestDifference) highestDifference = std::abs(targetRow - thisRowData.row());
|
||||
if (thisRowData.row() - 1 < baseRow) baseRow = thisRowData.row() - 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 originRow = thisRowData.row();
|
||||
//int sourceMappedOriginRow = mProxyModel->mapToSource (mProxyModel->index (originRow, 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()
|
||||
{
|
||||
emit editRequest(mEditIdAction->getCurrentId(), "");
|
||||
|
@ -141,6 +141,8 @@ namespace CSVWorld
|
||||
|
||||
void moveDownRecord();
|
||||
|
||||
void moveRecords(QDropEvent *event);
|
||||
|
||||
void viewRecord();
|
||||
|
||||
void previewRecord();
|
||||
|
Loading…
x
Reference in New Issue
Block a user