1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-21 10:53:51 +00:00

Merge remote-tracking branch 'sirherrbatka/DragDrop'

This commit is contained in:
Marc Zinnschlag 2014-02-17 09:55:50 +01:00
commit 02c6c65705
11 changed files with 193 additions and 27 deletions

View file

@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc
opencs_units (view/world opencs_units (view/world
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
scenetoolmode infocreator scenetoolmode infocreator scriptedit
) )
opencs_units (view/render opencs_units (view/render

View file

@ -71,7 +71,10 @@ namespace CSMDoc
public: public:
Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_); Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files,
const boost::filesystem::path& savePath,
const boost::filesystem::path& resDir, bool new_);
~Document(); ~Document();

View file

@ -29,7 +29,9 @@ namespace CSMDoc
~DocumentManager(); ~DocumentManager();
Document *addDocument (const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, bool new_); Document *addDocument (const std::vector< boost::filesystem::path >& files,
const boost::filesystem::path& savePath,
bool new_);
///< The ownership of the returned document is not transferred to the caller. ///< The ownership of the returned document is not transferred to the caller.
/// ///
/// \param new_ Do not load the last content file in \a files and instead create in an /// \param new_ Do not load the last content file in \a files and instead create in an

View file

@ -4,14 +4,15 @@
#include "universalid.hpp" #include "universalid.hpp"
#include "columnbase.hpp" #include "columnbase.hpp"
CSMWorld::TableMimeData::TableMimeData (UniversalId id) CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document& document) :
mDocument(document)
{ {
mUniversalId.push_back (id); mUniversalId.push_back (id);
mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName()); mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName());
} }
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id) : CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
mUniversalId (id) mUniversalId (id), mDocument(document)
{ {
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
{ {
@ -115,6 +116,11 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnB
throw ("TableMimeData object does not hold object of the seeked type"); throw ("TableMimeData object does not hold object of the seeked type");
} }
bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) const
{
return &document == &mDocument;
}
CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::ColumnBase::Display type) const CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::ColumnBase::Display type) const
{ {
switch (type) switch (type)

View file

@ -10,6 +10,10 @@
#include "universalid.hpp" #include "universalid.hpp"
#include "columnbase.hpp" #include "columnbase.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSMWorld namespace CSMWorld
{ {
@ -24,20 +28,32 @@ namespace CSMWorld
class TableMimeData : public QMimeData class TableMimeData : public QMimeData
{ {
public: public:
TableMimeData(UniversalId id); TableMimeData(UniversalId id, const CSMDoc::Document& document);
TableMimeData(std::vector<UniversalId>& id);
TableMimeData(std::vector<UniversalId>& id, const CSMDoc::Document& document);
~TableMimeData(); ~TableMimeData();
virtual QStringList formats() const; virtual QStringList formats() const;
std::string getIcon() const; std::string getIcon() const;
std::vector<UniversalId> getData() const; std::vector<UniversalId> getData() const;
bool holdsType(UniversalId::Type type) const; bool holdsType(UniversalId::Type type) const;
bool holdsType(CSMWorld::ColumnBase::Display type) const; bool holdsType(CSMWorld::ColumnBase::Display type) const;
bool fromDocument(const CSMDoc::Document& document) const;
UniversalId returnMatching(UniversalId::Type type) const; UniversalId returnMatching(UniversalId::Type type) const;
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
private: private:
std::vector<UniversalId> mUniversalId; std::vector<UniversalId> mUniversalId;
QStringList mObjectsFormats; QStringList mObjectsFormats;
const CSMDoc::Document& mDocument;
CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type) const; CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type) const;
}; };

View file

@ -0,0 +1,88 @@
#include "scriptedit.hpp"
#include <algorithm>
#include <QDragEnterEvent>
#include <QRegExp>
#include <QString>
#include "../../model/world/universalid.hpp"
#include "../../model/world/tablemimedata.hpp"
CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& document) :
QTextEdit (parent),
mDocument (document),
mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive)
{
mAllowedTypes <<CSMWorld::UniversalId::Type_Journal
<<CSMWorld::UniversalId::Type_Global
<<CSMWorld::UniversalId::Type_Topic
<<CSMWorld::UniversalId::Type_Sound
<<CSMWorld::UniversalId::Type_Spell
<<CSMWorld::UniversalId::Type_Cell
<<CSMWorld::UniversalId::Type_Referenceable
<<CSMWorld::UniversalId::Type_Activator
<<CSMWorld::UniversalId::Type_Potion
<<CSMWorld::UniversalId::Type_Apparatus
<<CSMWorld::UniversalId::Type_Armor
<<CSMWorld::UniversalId::Type_Book
<<CSMWorld::UniversalId::Type_Clothing
<<CSMWorld::UniversalId::Type_Container
<<CSMWorld::UniversalId::Type_Creature
<<CSMWorld::UniversalId::Type_Door
<<CSMWorld::UniversalId::Type_Ingredient
<<CSMWorld::UniversalId::Type_CreatureLevelledList
<<CSMWorld::UniversalId::Type_ItemLevelledList
<<CSMWorld::UniversalId::Type_Light
<<CSMWorld::UniversalId::Type_Lockpick
<<CSMWorld::UniversalId::Type_Miscellaneous
<<CSMWorld::UniversalId::Type_Npc
<<CSMWorld::UniversalId::Type_Probe
<<CSMWorld::UniversalId::Type_Repair
<<CSMWorld::UniversalId::Type_Static
<<CSMWorld::UniversalId::Type_Weapon;
}
void CSVWorld::ScriptEdit::dragEnterEvent (QDragEnterEvent* event)
{
setTextCursor (cursorForPosition (event->pos()));
event->acceptProposedAction();
}
void CSVWorld::ScriptEdit::dragMoveEvent (QDragMoveEvent* event)
{
setTextCursor (cursorForPosition (event->pos()));
event->accept();
}
void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
{
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
setTextCursor (cursorForPosition (event->pos()));
if (mime->fromDocument (mDocument))
{
std::vector<CSMWorld::UniversalId> records (mime->getData());
for (std::vector<CSMWorld::UniversalId>::iterator it = records.begin(); it != records.end(); ++it)
{
if (mAllowedTypes.contains (it->getType()))
{
if (stringNeedsQuote(it->getId()))
{
insertPlainText(QString::fromStdString ('"' + it->getId() + '"'));
} else {
insertPlainText(QString::fromStdString (it->getId()));
}
}
}
}
}
bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
{
const QString string(QString::fromStdString(id)); //<regex> is only for c++11, so let's use qregexp for now.
//I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than…
return !(string.contains(mWhiteListQoutes));
}

View file

@ -0,0 +1,39 @@
#ifndef SCRIPTEDIT_H
#define SCRIPTEDIT_H
#include <qtextedit.h>
#include <QVector>
#include "../../model/world/universalid.hpp"
class QWidget;
class QRegExp;
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class ScriptEdit : public QTextEdit
{
Q_OBJECT
public:
ScriptEdit (QWidget* parent, const CSMDoc::Document& document);
private:
QVector<CSMWorld::UniversalId::Type> mAllowedTypes;
const CSMDoc::Document& mDocument;
const QRegExp mWhiteListQoutes;
void dragEnterEvent (QDragEnterEvent* event);
void dropEvent (QDropEvent* event);
void dragMoveEvent (QDragMoveEvent* event);
bool stringNeedsQuote(const std::string& id) const;
};
}
#endif // SCRIPTEDIT_H

View file

@ -13,6 +13,7 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "scripthighlighter.hpp" #include "scripthighlighter.hpp"
#include "scriptedit.hpp"
CSVWorld::ScriptSubView::ChangeLock::ChangeLock (ScriptSubView& view) : mView (view) CSVWorld::ScriptSubView::ChangeLock::ChangeLock (ScriptSubView& view) : mView (view)
{ {
@ -27,7 +28,7 @@ CSVWorld::ScriptSubView::ChangeLock::~ChangeLock()
CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: SubView (id), mDocument (document), mColumn (-1), mChangeLocked (0) : SubView (id), mDocument (document), mColumn (-1), mChangeLocked (0)
{ {
setWidget (mEditor = new QTextEdit (this)); setWidget (mEditor = new ScriptEdit (this, mDocument));
mEditor->setAcceptRichText (false); mEditor->setAcceptRichText (false);
mEditor->setLineWrapMode (QTextEdit::NoWrap); mEditor->setLineWrapMode (QTextEdit::NoWrap);

View file

@ -162,8 +162,8 @@ std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
} }
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
bool createAndDelete, bool sorting) bool createAndDelete, bool sorting, const CSMDoc::Document& document)
: mUndoStack (undoStack), mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0) : mUndoStack (undoStack), mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0), mDocument(document)
{ {
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
@ -455,7 +455,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
if (selectedRows.size() == 1) if (selectedRows.size() == 1)
{ {
mime = new CSMWorld::TableMimeData (getUniversalId (selectedRows.begin()->row())); mime = new CSMWorld::TableMimeData (getUniversalId (selectedRows.begin()->row()), mDocument);
} }
else else
{ {
@ -466,7 +466,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
idToDrag.push_back (getUniversalId (it.row())); idToDrag.push_back (getUniversalId (it.row()));
} }
mime = new CSMWorld::TableMimeData (idToDrag); mime = new CSMWorld::TableMimeData (idToDrag, mDocument);
} }
drag->setMimeData (mime); drag->setMimeData (mime);
@ -485,21 +485,22 @@ void CSVWorld::Table::dropEvent(QDropEvent *event)
{ {
QModelIndex index = indexAt (event->pos()); QModelIndex index = indexAt (event->pos());
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display> const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
(mModel->headerData(index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); if (mime->fromDocument (mDocument))
if (dynamic_cast<const CSMWorld::TableMimeData*>(event->mimeData())->holdsType(display))
{ {
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
(event->mimeData()); (mModel->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
CSMWorld::UniversalId record (mime->returnMatching (display)); if (mime->holdsType (display))
{
CSMWorld::UniversalId record (mime->returnMatching (display));
std::auto_ptr<CSMWorld::ModifyCommand> command (new CSMWorld::ModifyCommand std::auto_ptr<CSMWorld::ModifyCommand> command (new CSMWorld::ModifyCommand
(*mProxyModel, index, QVariant (QString::fromStdString (record.getId())))); (*mProxyModel, index, QVariant (QString::fromStdString (record.getId()))));
mUndoStack.push (command.release()); mUndoStack.push (command.release());
} }
} //TODO handle drops from different document
} }
void CSVWorld::Table::dragMoveEvent(QDragMoveEvent *event) void CSVWorld::Table::dragMoveEvent(QDragMoveEvent *event)

View file

@ -9,6 +9,10 @@
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
namespace CSMDoc {
class Document;
}
class QUndoStack; class QUndoStack;
class QAction; class QAction;
@ -43,6 +47,10 @@ namespace CSVWorld
bool mEditLock; bool mEditLock;
int mRecordStatusDisplay; int mRecordStatusDisplay;
/// \brief This variable is used exclusivly for checking if dropEvents came from the same document. Most likely you
/// should NOT use it for anything else.
const CSMDoc::Document& mDocument;
private: private:
void contextMenuEvent (QContextMenuEvent *event); void contextMenuEvent (QContextMenuEvent *event);
@ -62,7 +70,9 @@ namespace CSVWorld
public: public:
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete, bool sorting); Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete,
bool sorting, const CSMDoc::Document& document);
///< \param createAndDelete Allow creation and deletion of records. ///< \param createAndDelete Allow creation and deletion of records.
/// \param sorting Allow changing order of rows in the view via column headers. /// \param sorting Allow changing order of rows in the view via column headers.

View file

@ -22,7 +22,7 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0); new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
layout->insertWidget (0, mTable = layout->insertWidget (0, mTable =
new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete(), sorting), 2); new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete(), sorting, document), 2);
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);