mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +00:00
Merge branch 'replace'
This commit is contained in:
commit
38ce074a62
37 changed files with 1444 additions and 44 deletions
|
@ -40,7 +40,7 @@ opencs_units (model/tools
|
||||||
opencs_units_noqt (model/tools
|
opencs_units_noqt (model/tools
|
||||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||||
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
|
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
|
||||||
startscriptcheck
|
startscriptcheck search searchoperation searchstage
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ opencs_hdrs_noqt (view/render
|
||||||
|
|
||||||
|
|
||||||
opencs_units (view/tools
|
opencs_units (view/tools
|
||||||
reportsubview reporttable
|
reportsubview reporttable searchsubview searchbox
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/tools
|
opencs_units_noqt (view/tools
|
||||||
|
|
|
@ -2374,6 +2374,17 @@ CSMWorld::UniversalId CSMDoc::Document::verify()
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMWorld::UniversalId CSMDoc::Document::newSearch()
|
||||||
|
{
|
||||||
|
return mTools.newSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Document::runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search)
|
||||||
|
{
|
||||||
|
return mTools.runSearch (searchId, search);
|
||||||
|
}
|
||||||
|
|
||||||
void CSMDoc::Document::abortOperation (int type)
|
void CSMDoc::Document::abortOperation (int type)
|
||||||
{
|
{
|
||||||
if (type==State_Saving)
|
if (type==State_Saving)
|
||||||
|
|
|
@ -120,6 +120,10 @@ namespace CSMDoc
|
||||||
|
|
||||||
CSMWorld::UniversalId verify();
|
CSMWorld::UniversalId verify();
|
||||||
|
|
||||||
|
CSMWorld::UniversalId newSearch();
|
||||||
|
|
||||||
|
void runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search);
|
||||||
|
|
||||||
void abortOperation (int type);
|
void abortOperation (int type);
|
||||||
|
|
||||||
const CSMWorld::Data& getData() const;
|
const CSMWorld::Data& getData() const;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace CSMDoc
|
||||||
State_Saving = 16,
|
State_Saving = 16,
|
||||||
State_Verifying = 32,
|
State_Verifying = 32,
|
||||||
State_Compiling = 64, // not implemented yet
|
State_Compiling = 64, // not implemented yet
|
||||||
State_Searching = 128, // not implemented yet
|
State_Searching = 128,
|
||||||
State_Loading = 256 // pseudo-state; can not be encountered in a loaded document
|
State_Loading = 256 // pseudo-state; can not be encountered in a loaded document
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,21 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
||||||
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
|
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declareSection ("search", "Search & Replace");
|
||||||
|
{
|
||||||
|
Setting *before = createSetting (Type_SpinBox, "char-before",
|
||||||
|
"Characters before search string");
|
||||||
|
before->setDefaultValue (10);
|
||||||
|
before->setRange (0, 1000);
|
||||||
|
before->setToolTip ("Maximum number of character to display in search result before the searched text");
|
||||||
|
|
||||||
|
Setting *after = createSetting (Type_SpinBox, "char-after",
|
||||||
|
"Characters after search string");
|
||||||
|
after->setDefaultValue (10);
|
||||||
|
after->setRange (0, 1000);
|
||||||
|
after->setToolTip ("Maximum number of character to display in search result after the searched text");
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* There are three types of values:
|
* There are three types of values:
|
||||||
|
|
|
@ -2,6 +2,29 @@
|
||||||
#include "reportmodel.hpp"
|
#include "reportmodel.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../world/columns.hpp"
|
||||||
|
|
||||||
|
CSMTools::ReportModel::Line::Line (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint)
|
||||||
|
: mId (id), mMessage (message), mHint (hint)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMTools::ReportModel::ReportModel (bool fieldColumn)
|
||||||
|
{
|
||||||
|
if (fieldColumn)
|
||||||
|
{
|
||||||
|
mColumnField = 3;
|
||||||
|
mColumnDescription = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mColumnDescription = 3;
|
||||||
|
|
||||||
|
mColumnField = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
|
int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
|
||||||
{
|
{
|
||||||
|
@ -16,7 +39,7 @@ int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 3;
|
return mColumnDescription+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
||||||
|
@ -24,13 +47,49 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
||||||
if (role!=Qt::DisplayRole)
|
if (role!=Qt::DisplayRole)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (index.column()==0)
|
switch (index.column())
|
||||||
return static_cast<int> (mRows.at (index.row()).first.getType());
|
{
|
||||||
|
case Column_Type:
|
||||||
|
|
||||||
if (index.column()==1)
|
return static_cast<int> (mRows.at (index.row()).mId.getType());
|
||||||
return QString::fromUtf8 (mRows.at (index.row()).second.first.c_str());
|
|
||||||
|
|
||||||
return QString::fromUtf8 (mRows.at (index.row()).second.second.c_str());
|
case Column_Id:
|
||||||
|
{
|
||||||
|
CSMWorld::UniversalId id = mRows.at (index.row()).mId;
|
||||||
|
|
||||||
|
if (id.getArgumentType()==CSMWorld::UniversalId::ArgumentType_Id)
|
||||||
|
return QString::fromUtf8 (id.getId().c_str());
|
||||||
|
|
||||||
|
return QString ("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
case Column_Hint:
|
||||||
|
|
||||||
|
return QString::fromUtf8 (mRows.at (index.row()).mHint.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index.column()==mColumnDescription)
|
||||||
|
return QString::fromUtf8 (mRows.at (index.row()).mMessage.c_str());
|
||||||
|
|
||||||
|
if (index.column()==mColumnField)
|
||||||
|
{
|
||||||
|
std::string field;
|
||||||
|
|
||||||
|
std::istringstream stream (mRows.at (index.row()).mHint);
|
||||||
|
|
||||||
|
char type, ignore;
|
||||||
|
int fieldIndex;
|
||||||
|
|
||||||
|
if ((stream >> type >> ignore >> fieldIndex) && (type=='r' || type=='R'))
|
||||||
|
{
|
||||||
|
field = CSMWorld::Columns::getName (
|
||||||
|
static_cast<CSMWorld::Columns::ColumnId> (fieldIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString::fromUtf8 (field.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
|
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
|
||||||
|
@ -41,13 +100,19 @@ QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orienta
|
||||||
if (orientation==Qt::Vertical)
|
if (orientation==Qt::Vertical)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (section==0)
|
switch (section)
|
||||||
return "Type";
|
{
|
||||||
|
case Column_Type: return "Type";
|
||||||
|
case Column_Id: return "ID";
|
||||||
|
}
|
||||||
|
|
||||||
if (section==1)
|
if (section==mColumnDescription)
|
||||||
return "Description";
|
return "Description";
|
||||||
|
|
||||||
return "Hint";
|
if (section==mColumnField)
|
||||||
|
return "Field";
|
||||||
|
|
||||||
|
return "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
|
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
|
||||||
|
@ -65,17 +130,42 @@ void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::str
|
||||||
{
|
{
|
||||||
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
||||||
|
|
||||||
mRows.push_back (std::make_pair (id, std::make_pair (message, hint)));
|
mRows.push_back (Line (id, message, hint));
|
||||||
|
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMTools::ReportModel::flagAsReplaced (int index)
|
||||||
|
{
|
||||||
|
Line& line = mRows.at (index);
|
||||||
|
std::string hint = line.mHint;
|
||||||
|
|
||||||
|
if (hint.empty() || hint[0]!='R')
|
||||||
|
throw std::logic_error ("trying to flag message as replaced that is not replaceable");
|
||||||
|
|
||||||
|
hint[0] = 'r';
|
||||||
|
|
||||||
|
line.mHint = hint;
|
||||||
|
|
||||||
|
emit dataChanged (this->index (index, 0), this->index (index, columnCount()));
|
||||||
|
}
|
||||||
|
|
||||||
const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const
|
const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const
|
||||||
{
|
{
|
||||||
return mRows.at (row).first;
|
return mRows.at (row).mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CSMTools::ReportModel::getHint (int row) const
|
std::string CSMTools::ReportModel::getHint (int row) const
|
||||||
{
|
{
|
||||||
return mRows.at (row).second.second;
|
return mRows.at (row).mHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::ReportModel::clear()
|
||||||
|
{
|
||||||
|
if (!mRows.empty())
|
||||||
|
{
|
||||||
|
beginRemoveRows (QModelIndex(), 0, mRows.size()-1);
|
||||||
|
mRows.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,32 @@ namespace CSMTools
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
std::vector<std::pair<CSMWorld::UniversalId, std::pair<std::string, std::string> > > mRows;
|
struct Line
|
||||||
|
{
|
||||||
|
Line (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint);
|
||||||
|
|
||||||
|
CSMWorld::UniversalId mId;
|
||||||
|
std::string mMessage;
|
||||||
|
std::string mHint;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Line> mRows;
|
||||||
|
|
||||||
|
// Fixed columns
|
||||||
|
enum Columns
|
||||||
|
{
|
||||||
|
Column_Type = 0, Column_Id = 1, Column_Hint = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
// Configurable columns
|
||||||
|
int mColumnDescription;
|
||||||
|
int mColumnField;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
ReportModel (bool fieldColumn = false);
|
||||||
|
|
||||||
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
||||||
|
|
||||||
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
|
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
|
||||||
|
@ -31,9 +53,13 @@ namespace CSMTools
|
||||||
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
const std::string& hint = "");
|
const std::string& hint = "");
|
||||||
|
|
||||||
|
void flagAsReplaced (int index);
|
||||||
|
|
||||||
const CSMWorld::UniversalId& getUniversalId (int row) const;
|
const CSMWorld::UniversalId& getUniversalId (int row) const;
|
||||||
|
|
||||||
std::string getHint (int row) const;
|
std::string getHint (int row) const;
|
||||||
|
|
||||||
|
void clear();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
279
apps/opencs/model/tools/search.cpp
Normal file
279
apps/opencs/model/tools/search.cpp
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
|
||||||
|
#include "search.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../doc/messages.hpp"
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
|
#include "../world/idtablebase.hpp"
|
||||||
|
#include "../world/columnbase.hpp"
|
||||||
|
#include "../world/universalid.hpp"
|
||||||
|
#include "../world/commands.hpp"
|
||||||
|
|
||||||
|
void CSMTools::Search::searchTextCell (const CSMWorld::IdTableBase *model,
|
||||||
|
const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable,
|
||||||
|
CSMDoc::Messages& messages) const
|
||||||
|
{
|
||||||
|
// using QString here for easier handling of case folding.
|
||||||
|
|
||||||
|
QString search = QString::fromUtf8 (mText.c_str());
|
||||||
|
QString text = model->data (index).toString();
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while ((pos = text.indexOf (search, pos, Qt::CaseInsensitive))!=-1)
|
||||||
|
{
|
||||||
|
std::ostringstream hint;
|
||||||
|
hint
|
||||||
|
<< (writable ? 'R' : 'r')
|
||||||
|
<<": "
|
||||||
|
<< model->getColumnId (index.column())
|
||||||
|
<< " " << pos
|
||||||
|
<< " " << search.length();
|
||||||
|
|
||||||
|
messages.add (id, formatDescription (text, pos, search.length()).toUtf8().data(), hint.str());
|
||||||
|
|
||||||
|
pos += search.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Search::searchRegExCell (const CSMWorld::IdTableBase *model,
|
||||||
|
const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable,
|
||||||
|
CSMDoc::Messages& messages) const
|
||||||
|
{
|
||||||
|
QString text = model->data (index).toString();
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while ((pos = mRegExp.indexIn (text, pos))!=-1)
|
||||||
|
{
|
||||||
|
int length = mRegExp.matchedLength();
|
||||||
|
|
||||||
|
std::ostringstream hint;
|
||||||
|
hint
|
||||||
|
<< (writable ? 'R' : 'r')
|
||||||
|
<<": "
|
||||||
|
<< model->getColumnId (index.column())
|
||||||
|
<< " " << pos
|
||||||
|
<< " " << length;
|
||||||
|
|
||||||
|
messages.add (id, formatDescription (text, pos, length).toUtf8().data(), hint.str());
|
||||||
|
|
||||||
|
pos += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Search::searchRecordStateCell (const CSMWorld::IdTableBase *model,
|
||||||
|
const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const
|
||||||
|
{
|
||||||
|
if (writable)
|
||||||
|
throw std::logic_error ("Record state can not be modified by search and replace");
|
||||||
|
|
||||||
|
int data = model->data (index).toInt();
|
||||||
|
|
||||||
|
if (data==mValue)
|
||||||
|
{
|
||||||
|
std::vector<std::string> states =
|
||||||
|
CSMWorld::Columns::getEnums (CSMWorld::Columns::ColumnId_Modification);
|
||||||
|
|
||||||
|
std::ostringstream message;
|
||||||
|
message << states.at (data);
|
||||||
|
|
||||||
|
std::ostringstream hint;
|
||||||
|
hint << "r: " << model->getColumnId (index.column());
|
||||||
|
|
||||||
|
messages.add (id, message.str(), hint.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSMTools::Search::formatDescription (const QString& description, int pos, int length) const
|
||||||
|
{
|
||||||
|
QString text (description);
|
||||||
|
|
||||||
|
// split
|
||||||
|
QString highlight = flatten (text.mid (pos, length));
|
||||||
|
QString before = flatten (mPaddingBefore>=pos ?
|
||||||
|
text.mid (0, pos) : text.mid (pos-mPaddingBefore, mPaddingBefore));
|
||||||
|
QString after = flatten (text.mid (pos+length, mPaddingAfter));
|
||||||
|
|
||||||
|
// compensate for Windows nonsense
|
||||||
|
text.remove ('\r');
|
||||||
|
|
||||||
|
// join
|
||||||
|
text = before + "<b>" + highlight + "</b>" + after;
|
||||||
|
|
||||||
|
// improve layout for single line display
|
||||||
|
text.replace ("\n", "<CR>");
|
||||||
|
text.replace ('\t', ' ');
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSMTools::Search::flatten (const QString& text) const
|
||||||
|
{
|
||||||
|
QString flat (text);
|
||||||
|
|
||||||
|
flat.replace ("&", "&");
|
||||||
|
flat.replace ("<", "<");
|
||||||
|
|
||||||
|
return flat;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMTools::Search::Search() : mType (Type_None), mPaddingBefore (10), mPaddingAfter (10) {}
|
||||||
|
|
||||||
|
CSMTools::Search::Search (Type type, const std::string& value)
|
||||||
|
: mType (type), mText (value), mPaddingBefore (10), mPaddingAfter (10)
|
||||||
|
{
|
||||||
|
if (type!=Type_Text && type!=Type_Id)
|
||||||
|
throw std::logic_error ("Invalid search parameter (string)");
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMTools::Search::Search (Type type, const QRegExp& value)
|
||||||
|
: mType (type), mRegExp (value), mPaddingBefore (10), mPaddingAfter (10)
|
||||||
|
{
|
||||||
|
if (type!=Type_TextRegEx && type!=Type_IdRegEx)
|
||||||
|
throw std::logic_error ("Invalid search parameter (RegExp)");
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMTools::Search::Search (Type type, int value)
|
||||||
|
: mType (type), mValue (value), mPaddingBefore (10), mPaddingAfter (10)
|
||||||
|
{
|
||||||
|
if (type!=Type_RecordState)
|
||||||
|
throw std::logic_error ("invalid search parameter (int)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Search::configure (const CSMWorld::IdTableBase *model)
|
||||||
|
{
|
||||||
|
mColumns.clear();
|
||||||
|
|
||||||
|
int columns = model->columnCount();
|
||||||
|
|
||||||
|
for (int i=0; i<columns; ++i)
|
||||||
|
{
|
||||||
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display> (
|
||||||
|
model->headerData (
|
||||||
|
i, Qt::Horizontal, static_cast<int> (CSMWorld::ColumnBase::Role_Display)).toInt());
|
||||||
|
|
||||||
|
bool consider = false;
|
||||||
|
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case Type_Text:
|
||||||
|
case Type_TextRegEx:
|
||||||
|
|
||||||
|
if (CSMWorld::ColumnBase::isText (display) ||
|
||||||
|
CSMWorld::ColumnBase::isScript (display))
|
||||||
|
{
|
||||||
|
consider = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_Id:
|
||||||
|
case Type_IdRegEx:
|
||||||
|
|
||||||
|
if (CSMWorld::ColumnBase::isId (display) ||
|
||||||
|
CSMWorld::ColumnBase::isScript (display))
|
||||||
|
{
|
||||||
|
consider = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_RecordState:
|
||||||
|
|
||||||
|
if (display==CSMWorld::ColumnBase::Display_RecordState)
|
||||||
|
consider = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_None:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consider)
|
||||||
|
mColumns.insert (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mIdColumn = model->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||||
|
mTypeColumn = model->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Search::searchRow (const CSMWorld::IdTableBase *model, int row,
|
||||||
|
CSMDoc::Messages& messages) const
|
||||||
|
{
|
||||||
|
for (std::set<int>::const_iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter)
|
||||||
|
{
|
||||||
|
QModelIndex index = model->index (row, *iter);
|
||||||
|
|
||||||
|
CSMWorld::UniversalId::Type type = static_cast<CSMWorld::UniversalId::Type> (
|
||||||
|
model->data (model->index (row, mTypeColumn)).toInt());
|
||||||
|
|
||||||
|
CSMWorld::UniversalId id (
|
||||||
|
type, model->data (model->index (row, mIdColumn)).toString().toUtf8().data());
|
||||||
|
|
||||||
|
bool writable = model->flags (index) & Qt::ItemIsEditable;
|
||||||
|
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case Type_Text:
|
||||||
|
case Type_Id:
|
||||||
|
|
||||||
|
searchTextCell (model, index, id, writable, messages);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_TextRegEx:
|
||||||
|
case Type_IdRegEx:
|
||||||
|
|
||||||
|
searchRegExCell (model, index, id, writable, messages);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_RecordState:
|
||||||
|
|
||||||
|
searchRecordStateCell (model, index, id, writable, messages);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_None:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Search::setPadding (int before, int after)
|
||||||
|
{
|
||||||
|
mPaddingBefore = before;
|
||||||
|
mPaddingAfter = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Search::replace (CSMDoc::Document& document, CSMWorld::IdTableBase *model,
|
||||||
|
const CSMWorld::UniversalId& id, const std::string& messageHint,
|
||||||
|
const std::string& replaceText) const
|
||||||
|
{
|
||||||
|
std::istringstream stream (messageHint.c_str());
|
||||||
|
|
||||||
|
char hint, ignore;
|
||||||
|
int columnId, pos, length;
|
||||||
|
|
||||||
|
if (stream >> hint >> ignore >> columnId >> pos >> length)
|
||||||
|
{
|
||||||
|
int column =
|
||||||
|
model->findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (columnId));
|
||||||
|
|
||||||
|
QModelIndex index = model->getModelIndex (id.getId(), column);
|
||||||
|
|
||||||
|
std::string text = model->data (index).toString().toUtf8().constData();
|
||||||
|
|
||||||
|
std::string before = text.substr (0, pos);
|
||||||
|
std::string after = text.substr (pos+length);
|
||||||
|
|
||||||
|
std::string newText = before + replaceText + after;
|
||||||
|
|
||||||
|
document.getUndoStack().push (
|
||||||
|
new CSMWorld::ModifyCommand (*model, index, QString::fromUtf8 (newText.c_str())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
96
apps/opencs/model/tools/search.hpp
Normal file
96
apps/opencs/model/tools/search.hpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#ifndef CSM_TOOLS_SEARCH_H
|
||||||
|
#define CSM_TOOLS_SEARCH_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Messages;
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdTableBase;
|
||||||
|
class UniversalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class Search
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Type_Text = 0,
|
||||||
|
Type_TextRegEx = 1,
|
||||||
|
Type_Id = 2,
|
||||||
|
Type_IdRegEx = 3,
|
||||||
|
Type_RecordState = 4,
|
||||||
|
Type_None
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Type mType;
|
||||||
|
std::string mText;
|
||||||
|
QRegExp mRegExp;
|
||||||
|
int mValue;
|
||||||
|
std::set<int> mColumns;
|
||||||
|
int mIdColumn;
|
||||||
|
int mTypeColumn;
|
||||||
|
int mPaddingBefore;
|
||||||
|
int mPaddingAfter;
|
||||||
|
|
||||||
|
void searchTextCell (const CSMWorld::IdTableBase *model, const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const;
|
||||||
|
|
||||||
|
void searchRegExCell (const CSMWorld::IdTableBase *model, const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const;
|
||||||
|
|
||||||
|
void searchRecordStateCell (const CSMWorld::IdTableBase *model,
|
||||||
|
const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable,
|
||||||
|
CSMDoc::Messages& messages) const;
|
||||||
|
|
||||||
|
QString formatDescription (const QString& description, int pos, int length) const;
|
||||||
|
|
||||||
|
QString flatten (const QString& text) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Search();
|
||||||
|
|
||||||
|
Search (Type type, const std::string& value);
|
||||||
|
|
||||||
|
Search (Type type, const QRegExp& value);
|
||||||
|
|
||||||
|
Search (Type type, int value);
|
||||||
|
|
||||||
|
// Configure search for the specified model.
|
||||||
|
void configure (const CSMWorld::IdTableBase *model);
|
||||||
|
|
||||||
|
// Search row in \a model and store results in \a messages.
|
||||||
|
//
|
||||||
|
// \attention *this needs to be configured for \a model.
|
||||||
|
void searchRow (const CSMWorld::IdTableBase *model, int row,
|
||||||
|
CSMDoc::Messages& messages) const;
|
||||||
|
|
||||||
|
void setPadding (int before, int after);
|
||||||
|
|
||||||
|
// Configuring *this for the model is not necessary when calling this function.
|
||||||
|
void replace (CSMDoc::Document& document, CSMWorld::IdTableBase *model,
|
||||||
|
const CSMWorld::UniversalId& id, const std::string& messageHint,
|
||||||
|
const std::string& replaceText) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE (CSMTools::Search)
|
||||||
|
|
||||||
|
#endif
|
40
apps/opencs/model/tools/searchoperation.cpp
Normal file
40
apps/opencs/model/tools/searchoperation.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
#include "searchoperation.hpp"
|
||||||
|
|
||||||
|
#include "../doc/state.hpp"
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
|
#include "../world/data.hpp"
|
||||||
|
#include "../world/idtablebase.hpp"
|
||||||
|
|
||||||
|
#include "searchstage.hpp"
|
||||||
|
|
||||||
|
CSMTools::SearchOperation::SearchOperation (CSMDoc::Document& document)
|
||||||
|
: CSMDoc::Operation (CSMDoc::State_Searching, false)
|
||||||
|
{
|
||||||
|
std::vector<CSMWorld::UniversalId::Type> types = CSMWorld::UniversalId::listTypes (
|
||||||
|
CSMWorld::UniversalId::Class_RecordList |
|
||||||
|
CSMWorld::UniversalId::Class_ResourceList
|
||||||
|
);
|
||||||
|
|
||||||
|
for (std::vector<CSMWorld::UniversalId::Type>::const_iterator iter (types.begin());
|
||||||
|
iter!=types.end(); ++iter)
|
||||||
|
appendStage (new SearchStage (&dynamic_cast<CSMWorld::IdTableBase&> (
|
||||||
|
*document.getData().getTableModel (*iter))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::SearchOperation::configure (const Search& search)
|
||||||
|
{
|
||||||
|
mSearch = search;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::SearchOperation::appendStage (SearchStage *stage)
|
||||||
|
{
|
||||||
|
CSMDoc::Operation::appendStage (stage);
|
||||||
|
stage->setOperation (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSMTools::Search& CSMTools::SearchOperation::getSearch() const
|
||||||
|
{
|
||||||
|
return mSearch;
|
||||||
|
}
|
38
apps/opencs/model/tools/searchoperation.hpp
Normal file
38
apps/opencs/model/tools/searchoperation.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef CSM_TOOLS_SEARCHOPERATION_H
|
||||||
|
#define CSM_TOOLS_SEARCHOPERATION_H
|
||||||
|
|
||||||
|
#include "../doc/operation.hpp"
|
||||||
|
|
||||||
|
#include "search.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class SearchStage;
|
||||||
|
|
||||||
|
class SearchOperation : public CSMDoc::Operation
|
||||||
|
{
|
||||||
|
Search mSearch;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SearchOperation (CSMDoc::Document& document);
|
||||||
|
|
||||||
|
/// \attention Do not call this function while a search is running.
|
||||||
|
void configure (const Search& search);
|
||||||
|
|
||||||
|
void appendStage (SearchStage *stage);
|
||||||
|
///< The ownership of \a stage is transferred to *this.
|
||||||
|
///
|
||||||
|
/// \attention Do no call this function while this Operation is running.
|
||||||
|
|
||||||
|
const Search& getSearch() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
30
apps/opencs/model/tools/searchstage.cpp
Normal file
30
apps/opencs/model/tools/searchstage.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
#include "searchstage.hpp"
|
||||||
|
|
||||||
|
#include "../world/idtablebase.hpp"
|
||||||
|
|
||||||
|
#include "searchoperation.hpp"
|
||||||
|
|
||||||
|
CSMTools::SearchStage::SearchStage (const CSMWorld::IdTableBase *model)
|
||||||
|
: mModel (model), mOperation (0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::SearchStage::setup()
|
||||||
|
{
|
||||||
|
if (mOperation)
|
||||||
|
mSearch = mOperation->getSearch();
|
||||||
|
|
||||||
|
mSearch.configure (mModel);
|
||||||
|
|
||||||
|
return mModel->rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::SearchStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
mSearch.searchRow (mModel, stage, messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::SearchStage::setOperation (const SearchOperation *operation)
|
||||||
|
{
|
||||||
|
mOperation = operation;
|
||||||
|
}
|
37
apps/opencs/model/tools/searchstage.hpp
Normal file
37
apps/opencs/model/tools/searchstage.hpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef CSM_TOOLS_SEARCHSTAGE_H
|
||||||
|
#define CSM_TOOLS_SEARCHSTAGE_H
|
||||||
|
|
||||||
|
#include "../doc/stage.hpp"
|
||||||
|
|
||||||
|
#include "search.hpp"
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdTableBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class SearchOperation;
|
||||||
|
|
||||||
|
class SearchStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
const CSMWorld::IdTableBase *mModel;
|
||||||
|
Search mSearch;
|
||||||
|
const SearchOperation *mOperation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SearchStage (const CSMWorld::IdTableBase *model);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
|
||||||
|
void setOperation (const SearchOperation *operation);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -25,12 +25,14 @@
|
||||||
#include "bodypartcheck.hpp"
|
#include "bodypartcheck.hpp"
|
||||||
#include "referencecheck.hpp"
|
#include "referencecheck.hpp"
|
||||||
#include "startscriptcheck.hpp"
|
#include "startscriptcheck.hpp"
|
||||||
|
#include "searchoperation.hpp"
|
||||||
|
|
||||||
CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
|
CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case CSMDoc::State_Verifying: return &mVerifier;
|
case CSMDoc::State_Verifying: return &mVerifier;
|
||||||
|
case CSMDoc::State_Searching: return &mSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -101,11 +103,18 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Tools::Tools (CSMDoc::Document& document)
|
CSMTools::Tools::Tools (CSMDoc::Document& document)
|
||||||
: mDocument (document), mData (document.getData()), mVerifierOperation (0), mNextReportNumber (0)
|
: mDocument (document), mData (document.getData()), mVerifierOperation (0), mNextReportNumber (0),
|
||||||
|
mSearchOperation (0)
|
||||||
{
|
{
|
||||||
// index 0: load error log
|
// index 0: load error log
|
||||||
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
||||||
mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0));
|
mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0));
|
||||||
|
|
||||||
|
connect (&mSearch, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||||
|
connect (&mSearch, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||||
|
connect (&mSearch,
|
||||||
|
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||||
|
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Tools::~Tools()
|
CSMTools::Tools::~Tools()
|
||||||
|
@ -116,6 +125,12 @@ CSMTools::Tools::~Tools()
|
||||||
delete mVerifierOperation;
|
delete mVerifierOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mSearchOperation)
|
||||||
|
{
|
||||||
|
mSearch.abortAndWait();
|
||||||
|
delete mSearchOperation;
|
||||||
|
}
|
||||||
|
|
||||||
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
|
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +145,28 @@ CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
||||||
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1);
|
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSMWorld::UniversalId CSMTools::Tools::newSearch()
|
||||||
|
{
|
||||||
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel (true)));
|
||||||
|
|
||||||
|
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Search, mNextReportNumber-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::Tools::runSearch (const CSMWorld::UniversalId& searchId, const Search& search)
|
||||||
|
{
|
||||||
|
mActiveReports[CSMDoc::State_Searching] = searchId.getIndex();
|
||||||
|
|
||||||
|
if (!mSearchOperation)
|
||||||
|
{
|
||||||
|
mSearchOperation = new SearchOperation (mDocument);
|
||||||
|
mSearch.setOperation (mSearchOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSearchOperation->configure (search);
|
||||||
|
|
||||||
|
mSearch.start();
|
||||||
|
}
|
||||||
|
|
||||||
void CSMTools::Tools::abortOperation (int type)
|
void CSMTools::Tools::abortOperation (int type)
|
||||||
{
|
{
|
||||||
if (CSMDoc::OperationHolder *operation = get (type))
|
if (CSMDoc::OperationHolder *operation = get (type))
|
||||||
|
@ -141,6 +178,7 @@ int CSMTools::Tools::getRunningOperations() const
|
||||||
static const int sOperations[] =
|
static const int sOperations[] =
|
||||||
{
|
{
|
||||||
CSMDoc::State_Verifying,
|
CSMDoc::State_Verifying,
|
||||||
|
CSMDoc::State_Searching,
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -157,7 +195,8 @@ int CSMTools::Tools::getRunningOperations() const
|
||||||
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
|
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
|
||||||
{
|
{
|
||||||
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults &&
|
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults &&
|
||||||
id.getType()!=CSMWorld::UniversalId::Type_LoadErrorLog)
|
id.getType()!=CSMWorld::UniversalId::Type_LoadErrorLog &&
|
||||||
|
id.getType()!=CSMWorld::UniversalId::Type_Search)
|
||||||
throw std::logic_error ("invalid request for report model: " + id.toString());
|
throw std::logic_error ("invalid request for report model: " + id.toString());
|
||||||
|
|
||||||
return mReports.at (id.getIndex());
|
return mReports.at (id.getIndex());
|
||||||
|
|
|
@ -22,6 +22,8 @@ namespace CSMDoc
|
||||||
namespace CSMTools
|
namespace CSMTools
|
||||||
{
|
{
|
||||||
class ReportModel;
|
class ReportModel;
|
||||||
|
class Search;
|
||||||
|
class SearchOperation;
|
||||||
|
|
||||||
class Tools : public QObject
|
class Tools : public QObject
|
||||||
{
|
{
|
||||||
|
@ -31,6 +33,8 @@ namespace CSMTools
|
||||||
CSMWorld::Data& mData;
|
CSMWorld::Data& mData;
|
||||||
CSMDoc::Operation *mVerifierOperation;
|
CSMDoc::Operation *mVerifierOperation;
|
||||||
CSMDoc::OperationHolder mVerifier;
|
CSMDoc::OperationHolder mVerifier;
|
||||||
|
SearchOperation *mSearchOperation;
|
||||||
|
CSMDoc::OperationHolder mSearch;
|
||||||
std::map<int, ReportModel *> mReports;
|
std::map<int, ReportModel *> mReports;
|
||||||
int mNextReportNumber;
|
int mNextReportNumber;
|
||||||
std::map<int, int> mActiveReports; // type, report number
|
std::map<int, int> mActiveReports; // type, report number
|
||||||
|
@ -56,6 +60,11 @@ namespace CSMTools
|
||||||
CSMWorld::UniversalId runVerifier();
|
CSMWorld::UniversalId runVerifier();
|
||||||
///< \return ID of the report for this verification run
|
///< \return ID of the report for this verification run
|
||||||
|
|
||||||
|
/// Return ID of the report for this search.
|
||||||
|
CSMWorld::UniversalId newSearch();
|
||||||
|
|
||||||
|
void runSearch (const CSMWorld::UniversalId& searchId, const Search& search);
|
||||||
|
|
||||||
void abortOperation (int type);
|
void abortOperation (int type);
|
||||||
///< \attention The operation is not aborted immediately.
|
///< \attention The operation is not aborted immediately.
|
||||||
|
|
||||||
|
|
|
@ -23,3 +23,76 @@ int CSMWorld::ColumnBase::getId() const
|
||||||
{
|
{
|
||||||
return mColumnId;
|
return mColumnId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::ColumnBase::isId (Display display)
|
||||||
|
{
|
||||||
|
static const Display ids[] =
|
||||||
|
{
|
||||||
|
Display_Skill,
|
||||||
|
Display_Class,
|
||||||
|
Display_Faction,
|
||||||
|
Display_Race,
|
||||||
|
Display_Sound,
|
||||||
|
Display_Region,
|
||||||
|
Display_Birthsign,
|
||||||
|
Display_Spell,
|
||||||
|
Display_Cell,
|
||||||
|
Display_Referenceable,
|
||||||
|
Display_Activator,
|
||||||
|
Display_Potion,
|
||||||
|
Display_Apparatus,
|
||||||
|
Display_Armor,
|
||||||
|
Display_Book,
|
||||||
|
Display_Clothing,
|
||||||
|
Display_Container,
|
||||||
|
Display_Creature,
|
||||||
|
Display_Door,
|
||||||
|
Display_Ingredient,
|
||||||
|
Display_CreatureLevelledList,
|
||||||
|
Display_ItemLevelledList,
|
||||||
|
Display_Light,
|
||||||
|
Display_Lockpick,
|
||||||
|
Display_Miscellaneous,
|
||||||
|
Display_Npc,
|
||||||
|
Display_Probe,
|
||||||
|
Display_Repair,
|
||||||
|
Display_Static,
|
||||||
|
Display_Weapon,
|
||||||
|
Display_Reference,
|
||||||
|
Display_Filter,
|
||||||
|
Display_Topic,
|
||||||
|
Display_Journal,
|
||||||
|
Display_TopicInfo,
|
||||||
|
Display_JournalInfo,
|
||||||
|
Display_Scene,
|
||||||
|
Display_GlobalVariable,
|
||||||
|
Display_Script,
|
||||||
|
|
||||||
|
Display_Mesh,
|
||||||
|
Display_Icon,
|
||||||
|
Display_Music,
|
||||||
|
Display_SoundRes,
|
||||||
|
Display_Texture,
|
||||||
|
Display_Video,
|
||||||
|
|
||||||
|
Display_Id,
|
||||||
|
|
||||||
|
Display_None
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i=0; ids[i]!=Display_None; ++i)
|
||||||
|
if (ids[i]==display)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::ColumnBase::isText (Display display)
|
||||||
|
{
|
||||||
|
return display==Display_String || display==Display_LongString;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::ColumnBase::isScript (Display display)
|
||||||
|
{
|
||||||
|
return display==Display_ScriptFile || display==Display_ScriptLines;
|
||||||
|
}
|
||||||
|
|
|
@ -101,9 +101,11 @@ namespace CSMWorld
|
||||||
Display_Texture,
|
Display_Texture,
|
||||||
Display_Video,
|
Display_Video,
|
||||||
Display_Colour,
|
Display_Colour,
|
||||||
|
Display_ScriptFile,
|
||||||
Display_ScriptLines, // console context
|
Display_ScriptLines, // console context
|
||||||
Display_SoundGeneratorType,
|
Display_SoundGeneratorType,
|
||||||
Display_School
|
Display_School,
|
||||||
|
Display_Id
|
||||||
};
|
};
|
||||||
|
|
||||||
int mColumnId;
|
int mColumnId;
|
||||||
|
@ -122,6 +124,12 @@ namespace CSMWorld
|
||||||
virtual std::string getTitle() const;
|
virtual std::string getTitle() const;
|
||||||
|
|
||||||
virtual int getId() const;
|
virtual int getId() const;
|
||||||
|
|
||||||
|
static bool isId (Display display);
|
||||||
|
|
||||||
|
static bool isText (Display display);
|
||||||
|
|
||||||
|
static bool isScript (Display display);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace CSMWorld
|
||||||
struct StringIdColumn : public Column<ESXRecordT>
|
struct StringIdColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
StringIdColumn (bool hidden = false)
|
StringIdColumn (bool hidden = false)
|
||||||
: Column<ESXRecordT> (Columns::ColumnId_Id, ColumnBase::Display_String,
|
: Column<ESXRecordT> (Columns::ColumnId_Id, ColumnBase::Display_Id,
|
||||||
hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue)
|
hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -818,7 +818,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
ScriptColumn (Type type)
|
ScriptColumn (Type type)
|
||||||
: Column<ESXRecordT> (Columns::ColumnId_ScriptText,
|
: Column<ESXRecordT> (Columns::ColumnId_ScriptText,
|
||||||
type==Type_File ? ColumnBase::Display_Script : ColumnBase::Display_ScriptLines,
|
type==Type_File ? ColumnBase::Display_ScriptFile : ColumnBase::Display_ScriptLines,
|
||||||
type==Type_File ? 0 : ColumnBase::Flag_Dialogue)
|
type==Type_File ? 0 : ColumnBase::Flag_Dialogue)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace CSMWorld
|
||||||
/// Is \a id flagged as deleted?
|
/// Is \a id flagged as deleted?
|
||||||
virtual bool isDeleted (const std::string& id) const;
|
virtual bool isDeleted (const std::string& id) const;
|
||||||
|
|
||||||
int getColumnId(int column) const;
|
virtual int getColumnId(int column) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ namespace CSMWorld
|
||||||
/// Is \a id flagged as deleted?
|
/// Is \a id flagged as deleted?
|
||||||
virtual bool isDeleted (const std::string& id) const = 0;
|
virtual bool isDeleted (const std::string& id) const = 0;
|
||||||
|
|
||||||
|
virtual int getColumnId (int column) const = 0;
|
||||||
|
|
||||||
unsigned int getFeatures() const;
|
unsigned int getFeatures() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||||
{
|
{
|
||||||
BaseColumns baseColumns;
|
BaseColumns baseColumns;
|
||||||
|
|
||||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Id, ColumnBase::Display_String,
|
mColumns.push_back (RefIdColumn (Columns::ColumnId_Id, ColumnBase::Display_Id,
|
||||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||||
baseColumns.mId = &mColumns.back();
|
baseColumns.mId = &mColumns.back();
|
||||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Modification, ColumnBase::Display_RecordState,
|
mColumns.push_back (RefIdColumn (Columns::ColumnId_Modification, ColumnBase::Display_RecordState,
|
||||||
|
|
|
@ -60,7 +60,7 @@ QVariant CSMWorld::ResourceTable::headerData (int section, Qt::Orientation orien
|
||||||
return Columns::getName (Columns::ColumnId_Id).c_str();
|
return Columns::getName (Columns::ColumnId_Id).c_str();
|
||||||
|
|
||||||
if (role==ColumnBase::Role_Display)
|
if (role==ColumnBase::Role_Display)
|
||||||
return ColumnBase::Display_String;
|
return ColumnBase::Display_Id;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -144,3 +144,14 @@ bool CSMWorld::ResourceTable::isDeleted (const std::string& id) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CSMWorld::ResourceTable::getColumnId (int column) const
|
||||||
|
{
|
||||||
|
switch (column)
|
||||||
|
{
|
||||||
|
case 0: return Columns::ColumnId_Id;
|
||||||
|
case 1: return Columns::ColumnId_RecordType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
/// Is \a id flagged as deleted?
|
/// Is \a id flagged as deleted?
|
||||||
virtual bool isDeleted (const std::string& id) const;
|
virtual bool isDeleted (const std::string& id) const;
|
||||||
|
|
||||||
|
virtual int getColumnId (int column) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,7 @@ namespace
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", 0 },
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", 0 },
|
||||||
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_Search, "Global Search", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -347,6 +348,25 @@ std::vector<CSMWorld::UniversalId::Type> CSMWorld::UniversalId::listReferenceabl
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CSMWorld::UniversalId::Type> CSMWorld::UniversalId::listTypes (int classes)
|
||||||
|
{
|
||||||
|
std::vector<CSMWorld::UniversalId::Type> list;
|
||||||
|
|
||||||
|
for (int i=0; sNoArg[i].mName; ++i)
|
||||||
|
if (sNoArg[i].mClass & classes)
|
||||||
|
list.push_back (sNoArg[i].mType);
|
||||||
|
|
||||||
|
for (int i=0; sIdArg[i].mName; ++i)
|
||||||
|
if (sIdArg[i].mClass & classes)
|
||||||
|
list.push_back (sIdArg[i].mType);
|
||||||
|
|
||||||
|
for (int i=0; sIndexArg[i].mName; ++i)
|
||||||
|
if (sIndexArg[i].mClass & classes)
|
||||||
|
list.push_back (sIndexArg[i].mType);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type)
|
CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type)
|
||||||
{
|
{
|
||||||
for (int i=0; sIdArg[i].mType; ++i)
|
for (int i=0; sIdArg[i].mType; ++i)
|
||||||
|
|
|
@ -16,16 +16,16 @@ namespace CSMWorld
|
||||||
enum Class
|
enum Class
|
||||||
{
|
{
|
||||||
Class_None = 0,
|
Class_None = 0,
|
||||||
Class_Record,
|
Class_Record = 1,
|
||||||
Class_RefRecord, // referenceable record
|
Class_RefRecord = 2, // referenceable record
|
||||||
Class_SubRecord,
|
Class_SubRecord = 4,
|
||||||
Class_RecordList,
|
Class_RecordList = 8,
|
||||||
Class_Collection, // multiple types of records combined
|
Class_Collection = 16, // multiple types of records combined
|
||||||
Class_Transient, // not part of the world data or the project data
|
Class_Transient = 32, // not part of the world data or the project data
|
||||||
Class_NonRecord, // record like data that is not part of the world
|
Class_NonRecord = 64, // record like data that is not part of the world
|
||||||
Class_Resource, ///< \attention Resource IDs are unique only within the
|
Class_Resource = 128, ///< \attention Resource IDs are unique only within the
|
||||||
/// respective collection
|
/// respective collection
|
||||||
Class_ResourceList
|
Class_ResourceList = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ArgumentType
|
enum ArgumentType
|
||||||
|
@ -130,6 +130,7 @@ namespace CSMWorld
|
||||||
Type_Pathgrid,
|
Type_Pathgrid,
|
||||||
Type_StartScripts,
|
Type_StartScripts,
|
||||||
Type_StartScript,
|
Type_StartScript,
|
||||||
|
Type_Search,
|
||||||
Type_RunLog
|
Type_RunLog
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,6 +181,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
static std::vector<Type> listReferenceableTypes();
|
static std::vector<Type> listReferenceableTypes();
|
||||||
|
|
||||||
|
static std::vector<Type> listTypes (int classes);
|
||||||
|
|
||||||
/// If \a type is a SubRecord, RefRecord or Record type return the type of the table
|
/// If \a type is a SubRecord, RefRecord or Record type return the type of the table
|
||||||
/// that contains records of type \a type.
|
/// that contains records of type \a type.
|
||||||
/// Otherwise return Type_None.
|
/// Otherwise return Type_None.
|
||||||
|
|
|
@ -18,6 +18,7 @@ void CSVDoc::Operation::updateLabel (int threads)
|
||||||
{
|
{
|
||||||
case CSMDoc::State_Saving: name = "saving"; break;
|
case CSMDoc::State_Saving: name = "saving"; break;
|
||||||
case CSMDoc::State_Verifying: name = "verifying"; break;
|
case CSMDoc::State_Verifying: name = "verifying"; break;
|
||||||
|
case CSMDoc::State_Searching: name = "searching"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
|
@ -91,6 +91,10 @@ void CSVDoc::View::setupEditMenu()
|
||||||
QAction *userSettings = new QAction (tr ("&Preferences"), this);
|
QAction *userSettings = new QAction (tr ("&Preferences"), this);
|
||||||
connect (userSettings, SIGNAL (triggered()), this, SIGNAL (editSettingsRequest()));
|
connect (userSettings, SIGNAL (triggered()), this, SIGNAL (editSettingsRequest()));
|
||||||
edit->addAction (userSettings);
|
edit->addAction (userSettings);
|
||||||
|
|
||||||
|
QAction *search = new QAction (tr ("Search"), this);
|
||||||
|
connect (search, SIGNAL (triggered()), this, SLOT (addSearchSubView()));
|
||||||
|
edit->addAction (search);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupViewMenu()
|
void CSVDoc::View::setupViewMenu()
|
||||||
|
@ -443,7 +447,7 @@ void CSVDoc::View::updateDocumentState()
|
||||||
|
|
||||||
static const int operations[] =
|
static const int operations[] =
|
||||||
{
|
{
|
||||||
CSMDoc::State_Saving, CSMDoc::State_Verifying,
|
CSMDoc::State_Saving, CSMDoc::State_Verifying, CSMDoc::State_Searching,
|
||||||
-1 // end marker
|
-1 // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -728,6 +732,11 @@ void CSVDoc::View::addStartScriptsSubView()
|
||||||
addSubView (CSMWorld::UniversalId::Type_StartScripts);
|
addSubView (CSMWorld::UniversalId::Type_StartScripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::addSearchSubView()
|
||||||
|
{
|
||||||
|
addSubView (mDocument->newSearch());
|
||||||
|
}
|
||||||
|
|
||||||
void CSVDoc::View::abortOperation (int type)
|
void CSVDoc::View::abortOperation (int type)
|
||||||
{
|
{
|
||||||
mDocument->abortOperation (type);
|
mDocument->abortOperation (type);
|
||||||
|
|
|
@ -217,6 +217,8 @@ namespace CSVDoc
|
||||||
|
|
||||||
void addStartScriptsSubView();
|
void addStartScriptsSubView();
|
||||||
|
|
||||||
|
void addSearchSubView();
|
||||||
|
|
||||||
void toggleShowStatusBar (bool show);
|
void toggleShowStatusBar (bool show);
|
||||||
|
|
||||||
void loadErrorLog();
|
void loadErrorLog();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
: CSVDoc::SubView (id)
|
: CSVDoc::SubView (id)
|
||||||
{
|
{
|
||||||
setWidget (mTable = new ReportTable (document, id, this));
|
setWidget (mTable = new ReportTable (document, id, false, this));
|
||||||
|
|
||||||
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
||||||
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
|
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
|
||||||
|
|
|
@ -6,11 +6,45 @@
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
#include "../../model/tools/reportmodel.hpp"
|
#include "../../model/tools/reportmodel.hpp"
|
||||||
|
|
||||||
#include "../../view/world/idtypedelegate.hpp"
|
#include "../../view/world/idtypedelegate.hpp"
|
||||||
|
|
||||||
|
namespace CSVTools
|
||||||
|
{
|
||||||
|
class RichTextDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RichTextDelegate (QObject *parent = 0);
|
||||||
|
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVTools::RichTextDelegate::RichTextDelegate (QObject *parent) : QStyledItemDelegate (parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSVTools::RichTextDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QTextDocument document;
|
||||||
|
QVariant value = index.data (Qt::DisplayRole);
|
||||||
|
if (value.isValid() && !value.isNull())
|
||||||
|
{
|
||||||
|
document.setHtml (value.toString());
|
||||||
|
painter->translate (option.rect.topLeft());
|
||||||
|
document.drawContents (painter);
|
||||||
|
painter->translate (-option.rect.topLeft());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
|
void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
@ -22,6 +56,23 @@ void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
menu.addAction (mShowAction);
|
menu.addAction (mShowAction);
|
||||||
menu.addAction (mRemoveAction);
|
menu.addAction (mRemoveAction);
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (QModelIndexList::const_iterator iter (selectedRows.begin());
|
||||||
|
iter!=selectedRows.end(); ++iter)
|
||||||
|
{
|
||||||
|
QString hint = mModel->data (mModel->index (iter->row(), 2)).toString();
|
||||||
|
|
||||||
|
if (!hint.isEmpty() && hint[0]=='R')
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
menu.addAction (mReplaceAction);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.exec (event->globalPos());
|
menu.exec (event->globalPos());
|
||||||
|
@ -67,10 +118,11 @@ void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||||
const CSMWorld::UniversalId& id, QWidget *parent)
|
const CSMWorld::UniversalId& id, bool richTextDescription, QWidget *parent)
|
||||||
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id))
|
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id))
|
||||||
{
|
{
|
||||||
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
||||||
|
horizontalHeader()->setStretchLastSection (true);
|
||||||
verticalHeader()->hide();
|
verticalHeader()->hide();
|
||||||
setSortingEnabled (true);
|
setSortingEnabled (true);
|
||||||
setSelectionBehavior (QAbstractItemView::SelectRows);
|
setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||||
|
@ -84,6 +136,9 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||||
|
|
||||||
setItemDelegateForColumn (0, mIdTypeDelegate);
|
setItemDelegateForColumn (0, mIdTypeDelegate);
|
||||||
|
|
||||||
|
if (richTextDescription)
|
||||||
|
setItemDelegateForColumn (mModel->columnCount()-1, new RichTextDelegate (this));
|
||||||
|
|
||||||
mShowAction = new QAction (tr ("Show"), this);
|
mShowAction = new QAction (tr ("Show"), this);
|
||||||
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
|
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
|
||||||
addAction (mShowAction);
|
addAction (mShowAction);
|
||||||
|
@ -91,6 +146,10 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||||
mRemoveAction = new QAction (tr ("Remove from list"), this);
|
mRemoveAction = new QAction (tr ("Remove from list"), this);
|
||||||
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
|
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
|
||||||
addAction (mRemoveAction);
|
addAction (mRemoveAction);
|
||||||
|
|
||||||
|
mReplaceAction = new QAction (tr ("Replace"), this);
|
||||||
|
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
||||||
|
addAction (mReplaceAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
|
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
|
||||||
|
@ -113,6 +172,42 @@ void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStrin
|
||||||
mIdTypeDelegate->updateUserSetting (name, list);
|
mIdTypeDelegate->updateUserSetting (name, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<int> CSVTools::ReportTable::getReplaceIndices (bool selection) const
|
||||||
|
{
|
||||||
|
std::vector<int> indices;
|
||||||
|
|
||||||
|
if (selection)
|
||||||
|
{
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
QString hint = mModel->data (mModel->index (iter->row(), 2)).toString();
|
||||||
|
|
||||||
|
if (!hint.isEmpty() && hint[0]=='R')
|
||||||
|
indices.push_back (iter->row());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i=0; i<mModel->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
QString hint = mModel->data (mModel->index (i, 2)).toString();
|
||||||
|
|
||||||
|
if (!hint.isEmpty() && hint[0]=='R')
|
||||||
|
indices.push_back (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::flagAsReplaced (int index)
|
||||||
|
{
|
||||||
|
mModel->flagAsReplaced (index);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVTools::ReportTable::showSelection()
|
void CSVTools::ReportTable::showSelection()
|
||||||
{
|
{
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
@ -134,3 +229,8 @@ void CSVTools::ReportTable::removeSelection()
|
||||||
|
|
||||||
selectionModel()->clear();
|
selectionModel()->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::clear()
|
||||||
|
{
|
||||||
|
mModel->clear();
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace CSVTools
|
||||||
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
||||||
QAction *mShowAction;
|
QAction *mShowAction;
|
||||||
QAction *mRemoveAction;
|
QAction *mRemoveAction;
|
||||||
|
QAction *mReplaceAction;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -36,13 +37,23 @@ namespace CSVTools
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// \param richTextDescription Use rich text in the description column.
|
||||||
ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
||||||
QWidget *parent = 0);
|
bool richTextDescription, QWidget *parent = 0);
|
||||||
|
|
||||||
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
|
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
|
||||||
|
|
||||||
void updateUserSetting (const QString& name, const QStringList& list);
|
void updateUserSetting (const QString& name, const QStringList& list);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
// Return indices of rows that are suitable for replacement.
|
||||||
|
//
|
||||||
|
// \param selection Only list selected rows.
|
||||||
|
std::vector<int> getReplaceIndices (bool selection) const;
|
||||||
|
|
||||||
|
void flagAsReplaced (int index);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void showSelection();
|
void showSelection();
|
||||||
|
@ -52,6 +63,8 @@ namespace CSVTools
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||||
|
|
||||||
|
void replaceRequest();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
192
apps/opencs/view/tools/searchbox.cpp
Normal file
192
apps/opencs/view/tools/searchbox.cpp
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
|
||||||
|
#include "searchbox.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include "../../model/world/columns.hpp"
|
||||||
|
|
||||||
|
#include "../../model/tools/search.hpp"
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::updateSearchButton()
|
||||||
|
{
|
||||||
|
if (!mSearchEnabled)
|
||||||
|
mSearch.setEnabled (false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (mMode.currentIndex())
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
|
||||||
|
mSearch.setEnabled (!mText.text().isEmpty());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
|
||||||
|
mSearch.setEnabled (true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVTools::SearchBox::SearchBox (QWidget *parent)
|
||||||
|
: QWidget (parent), mSearch ("Search"), mSearchEnabled (false), mReplace ("Replace All")
|
||||||
|
{
|
||||||
|
mLayout = new QGridLayout (this);
|
||||||
|
|
||||||
|
// search panel
|
||||||
|
std::vector<std::string> states =
|
||||||
|
CSMWorld::Columns::getEnums (CSMWorld::Columns::ColumnId_Modification);
|
||||||
|
states.resize (states.size()-1); // ignore erased state
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator iter (states.begin()); iter!=states.end();
|
||||||
|
++iter)
|
||||||
|
mRecordState.addItem (QString::fromUtf8 (iter->c_str()));
|
||||||
|
|
||||||
|
mMode.addItem ("Text");
|
||||||
|
mMode.addItem ("Text (RegEx)");
|
||||||
|
mMode.addItem ("ID");
|
||||||
|
mMode.addItem ("ID (RegEx)");
|
||||||
|
mMode.addItem ("Record State");
|
||||||
|
|
||||||
|
mLayout->addWidget (&mMode, 0, 0);
|
||||||
|
|
||||||
|
mLayout->addWidget (&mSearch, 0, 3);
|
||||||
|
|
||||||
|
mInput.insertWidget (0, &mText);
|
||||||
|
mInput.insertWidget (1, &mRecordState);
|
||||||
|
|
||||||
|
mLayout->addWidget (&mInput, 0, 1);
|
||||||
|
|
||||||
|
connect (&mMode, SIGNAL (activated (int)), this, SLOT (modeSelected (int)));
|
||||||
|
|
||||||
|
connect (&mText, SIGNAL (textChanged (const QString&)),
|
||||||
|
this, SLOT (textChanged (const QString&)));
|
||||||
|
|
||||||
|
connect (&mSearch, SIGNAL (clicked (bool)), this, SLOT (startSearch (bool)));
|
||||||
|
|
||||||
|
connect (&mText, SIGNAL (returnPressed()), this, SLOT (startSearch()));
|
||||||
|
|
||||||
|
// replace panel
|
||||||
|
mReplaceInput.insertWidget (0, &mReplaceText);
|
||||||
|
mReplaceInput.insertWidget (1, &mReplacePlaceholder);
|
||||||
|
|
||||||
|
mLayout->addWidget (&mReplaceInput, 1, 1);
|
||||||
|
|
||||||
|
mLayout->addWidget (&mReplace, 1, 3);
|
||||||
|
|
||||||
|
// layout adjustments
|
||||||
|
mLayout->setColumnMinimumWidth (2, 50);
|
||||||
|
mLayout->setColumnStretch (1, 1);
|
||||||
|
|
||||||
|
mLayout->setContentsMargins (0, 0, 0, 0);
|
||||||
|
|
||||||
|
connect (&mReplace, (SIGNAL (clicked (bool))), this, SLOT (replaceAll (bool)));
|
||||||
|
|
||||||
|
// update
|
||||||
|
modeSelected (0);
|
||||||
|
|
||||||
|
updateSearchButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::setSearchMode (bool enabled)
|
||||||
|
{
|
||||||
|
mSearchEnabled = enabled;
|
||||||
|
updateSearchButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMTools::Search CSVTools::SearchBox::getSearch() const
|
||||||
|
{
|
||||||
|
CSMTools::Search::Type type = static_cast<CSMTools::Search::Type> (mMode.currentIndex());
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case CSMTools::Search::Type_Text:
|
||||||
|
case CSMTools::Search::Type_Id:
|
||||||
|
|
||||||
|
return CSMTools::Search (type, std::string (mText.text().toUtf8().data()));
|
||||||
|
|
||||||
|
case CSMTools::Search::Type_TextRegEx:
|
||||||
|
case CSMTools::Search::Type_IdRegEx:
|
||||||
|
|
||||||
|
return CSMTools::Search (type, QRegExp (mText.text().toUtf8().data(), Qt::CaseInsensitive));
|
||||||
|
|
||||||
|
case CSMTools::Search::Type_RecordState:
|
||||||
|
|
||||||
|
return CSMTools::Search (type, mRecordState.currentIndex());
|
||||||
|
|
||||||
|
case CSMTools::Search::Type_None:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::logic_error ("invalid search mode index");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSVTools::SearchBox::getReplaceText() const
|
||||||
|
{
|
||||||
|
CSMTools::Search::Type type = static_cast<CSMTools::Search::Type> (mMode.currentIndex());
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case CSMTools::Search::Type_Text:
|
||||||
|
case CSMTools::Search::Type_TextRegEx:
|
||||||
|
case CSMTools::Search::Type_Id:
|
||||||
|
case CSMTools::Search::Type_IdRegEx:
|
||||||
|
|
||||||
|
return mReplaceText.text().toUtf8().data();
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
throw std::logic_error ("Invalid search mode for replace");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mReplace.setEnabled (!locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::modeSelected (int index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case CSMTools::Search::Type_Text:
|
||||||
|
case CSMTools::Search::Type_TextRegEx:
|
||||||
|
case CSMTools::Search::Type_Id:
|
||||||
|
case CSMTools::Search::Type_IdRegEx:
|
||||||
|
|
||||||
|
mInput.setCurrentIndex (0);
|
||||||
|
mReplaceInput.setCurrentIndex (0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSMTools::Search::Type_RecordState:
|
||||||
|
mInput.setCurrentIndex (1);
|
||||||
|
mReplaceInput.setCurrentIndex (1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSearchButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::textChanged (const QString& text)
|
||||||
|
{
|
||||||
|
updateSearchButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::startSearch (bool checked)
|
||||||
|
{
|
||||||
|
if (mSearch.isEnabled())
|
||||||
|
emit startSearch (getSearch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchBox::replaceAll (bool checked)
|
||||||
|
{
|
||||||
|
emit replaceAll();
|
||||||
|
}
|
70
apps/opencs/view/tools/searchbox.hpp
Normal file
70
apps/opencs/view/tools/searchbox.hpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#ifndef CSV_TOOLS_SEARCHBOX_H
|
||||||
|
#define CSV_TOOLS_SEARCHBOX_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QStackedWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
class QGridLayout;
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class Search;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVTools
|
||||||
|
{
|
||||||
|
class SearchBox : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QStackedWidget mInput;
|
||||||
|
QLineEdit mText;
|
||||||
|
QComboBox mRecordState;
|
||||||
|
QPushButton mSearch;
|
||||||
|
QGridLayout *mLayout;
|
||||||
|
QComboBox mMode;
|
||||||
|
bool mSearchEnabled;
|
||||||
|
QStackedWidget mReplaceInput;
|
||||||
|
QLineEdit mReplaceText;
|
||||||
|
QLabel mReplacePlaceholder;
|
||||||
|
QPushButton mReplace;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateSearchButton();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SearchBox (QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setSearchMode (bool enabled);
|
||||||
|
|
||||||
|
CSMTools::Search getSearch() const;
|
||||||
|
|
||||||
|
std::string getReplaceText() const;
|
||||||
|
|
||||||
|
void setEditLock (bool locked);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void modeSelected (int index);
|
||||||
|
|
||||||
|
void textChanged (const QString& text);
|
||||||
|
|
||||||
|
void startSearch (bool checked = true);
|
||||||
|
|
||||||
|
void replaceAll (bool checked);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void startSearch (const CSMTools::Search& search);
|
||||||
|
|
||||||
|
void replaceAll();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
119
apps/opencs/view/tools/searchsubview.cpp
Normal file
119
apps/opencs/view/tools/searchsubview.cpp
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
|
||||||
|
#include "searchsubview.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
#include "../../model/tools/search.hpp"
|
||||||
|
#include "../../model/tools/reportmodel.hpp"
|
||||||
|
#include "../../model/world/idtablebase.hpp"
|
||||||
|
|
||||||
|
#include "reporttable.hpp"
|
||||||
|
#include "searchbox.hpp"
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::replace (bool selection)
|
||||||
|
{
|
||||||
|
if (mLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<int> indices = mTable->getReplaceIndices (selection);
|
||||||
|
|
||||||
|
std::string replace = mSearchBox.getReplaceText();
|
||||||
|
|
||||||
|
const CSMTools::ReportModel& model =
|
||||||
|
dynamic_cast<const CSMTools::ReportModel&> (*mTable->model());
|
||||||
|
|
||||||
|
// We are running through the indices in reverse order to avoid messing up multiple results
|
||||||
|
// in a single string.
|
||||||
|
for (std::vector<int>::const_reverse_iterator iter (indices.rbegin()); iter!=indices.rend(); ++iter)
|
||||||
|
{
|
||||||
|
CSMWorld::UniversalId id = model.getUniversalId (*iter);
|
||||||
|
|
||||||
|
CSMWorld::UniversalId::Type type = CSMWorld::UniversalId::getParentType (id.getType());
|
||||||
|
|
||||||
|
CSMWorld::IdTableBase *table = &dynamic_cast<CSMWorld::IdTableBase&> (
|
||||||
|
*mDocument.getData().getTableModel (type));
|
||||||
|
|
||||||
|
std::string hint = model.getHint (*iter);
|
||||||
|
|
||||||
|
mSearch.replace (mDocument, table, id, hint, replace);
|
||||||
|
mTable->flagAsReplaced (*iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
|
: CSVDoc::SubView (id), mDocument (document), mPaddingBefore (10), mPaddingAfter (10),
|
||||||
|
mLocked (false)
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
|
||||||
|
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
|
layout->addWidget (&mSearchBox);
|
||||||
|
|
||||||
|
layout->addWidget (mTable = new ReportTable (document, id, true), 2);
|
||||||
|
|
||||||
|
QWidget *widget = new QWidget;
|
||||||
|
|
||||||
|
widget->setLayout (layout);
|
||||||
|
|
||||||
|
setWidget (widget);
|
||||||
|
|
||||||
|
stateChanged (document.getState(), &document);
|
||||||
|
|
||||||
|
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
||||||
|
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
|
||||||
|
|
||||||
|
connect (mTable, SIGNAL (replaceRequest()), this, SLOT (replaceRequest()));
|
||||||
|
|
||||||
|
connect (&document, SIGNAL (stateChanged (int, CSMDoc::Document *)),
|
||||||
|
this, SLOT (stateChanged (int, CSMDoc::Document *)));
|
||||||
|
|
||||||
|
connect (&mSearchBox, SIGNAL (startSearch (const CSMTools::Search&)),
|
||||||
|
this, SLOT (startSearch (const CSMTools::Search&)));
|
||||||
|
|
||||||
|
connect (&mSearchBox, SIGNAL (replaceAll()), this, SLOT (replaceAllRequest()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mLocked = locked;
|
||||||
|
mSearchBox.setEditLock (locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::updateUserSetting (const QString &name, const QStringList &list)
|
||||||
|
{
|
||||||
|
mTable->updateUserSetting (name, list);
|
||||||
|
|
||||||
|
if (!list.empty())
|
||||||
|
{
|
||||||
|
if (name=="search/char-before")
|
||||||
|
mPaddingBefore = list.at (0).toInt();
|
||||||
|
else if (name=="search/char-after")
|
||||||
|
mPaddingAfter = list.at (0).toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
mSearchBox.setSearchMode (!(state & CSMDoc::State_Searching));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search)
|
||||||
|
{
|
||||||
|
mSearch = search;
|
||||||
|
mSearch.setPadding (mPaddingBefore, mPaddingAfter);
|
||||||
|
|
||||||
|
mTable->clear();
|
||||||
|
mDocument.runSearch (getUniversalId(), mSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::replaceRequest()
|
||||||
|
{
|
||||||
|
replace (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::SearchSubView::replaceAllRequest()
|
||||||
|
{
|
||||||
|
replace (false);
|
||||||
|
}
|
58
apps/opencs/view/tools/searchsubview.hpp
Normal file
58
apps/opencs/view/tools/searchsubview.hpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef CSV_TOOLS_SEARCHSUBVIEW_H
|
||||||
|
#define CSV_TOOLS_SEARCHSUBVIEW_H
|
||||||
|
|
||||||
|
#include "../../model/tools/search.hpp"
|
||||||
|
|
||||||
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
|
#include "searchbox.hpp"
|
||||||
|
|
||||||
|
class QTableView;
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVTools
|
||||||
|
{
|
||||||
|
class ReportTable;
|
||||||
|
|
||||||
|
class SearchSubView : public CSVDoc::SubView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
ReportTable *mTable;
|
||||||
|
SearchBox mSearchBox;
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
|
int mPaddingBefore;
|
||||||
|
int mPaddingAfter;
|
||||||
|
CSMTools::Search mSearch;
|
||||||
|
bool mLocked;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void replace (bool selection);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
|
virtual void updateUserSetting (const QString &, const QStringList &);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void stateChanged (int state, CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void startSearch (const CSMTools::Search& search);
|
||||||
|
|
||||||
|
void replaceRequest();
|
||||||
|
|
||||||
|
void replaceAllRequest();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../doc/subviewfactoryimp.hpp"
|
#include "../doc/subviewfactoryimp.hpp"
|
||||||
|
|
||||||
#include "reportsubview.hpp"
|
#include "reportsubview.hpp"
|
||||||
|
#include "searchsubview.hpp"
|
||||||
|
|
||||||
void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
{
|
{
|
||||||
|
@ -11,4 +12,6 @@ void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
new CSVDoc::SubViewFactory<ReportSubView>);
|
new CSVDoc::SubViewFactory<ReportSubView>);
|
||||||
manager.add (CSMWorld::UniversalId::Type_LoadErrorLog,
|
manager.add (CSMWorld::UniversalId::Type_LoadErrorLog,
|
||||||
new CSVDoc::SubViewFactory<ReportSubView>);
|
new CSVDoc::SubViewFactory<ReportSubView>);
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Search,
|
||||||
|
new CSVDoc::SubViewFactory<SearchSubView>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
||||||
|
|
||||||
for (int i=0; i<mModel->columnCount(); ++i)
|
for (int i=0; i<mModel->columnCount(); ++i)
|
||||||
if (mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display)==
|
if (mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display)==
|
||||||
CSMWorld::ColumnBase::Display_Script)
|
CSMWorld::ColumnBase::Display_ScriptFile)
|
||||||
{
|
{
|
||||||
mColumn = i;
|
mColumn = i;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue