Merge branch 'preview'

This commit is contained in:
Marc Zinnschlag 2014-03-21 12:35:40 +01:00
commit 1a9df4bc56
16 changed files with 168 additions and 60 deletions

View file

@ -61,7 +61,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
{ {
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
{ {
QString path = QString::fromStdString(iter->string()); QString path = QString::fromUtf8 (iter->string().c_str());
mFileDialog.addFiles(path); mFileDialog.addFiles(path);
} }
} }
@ -148,7 +148,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath)
std::vector<boost::filesystem::path> files; std::vector<boost::filesystem::path> files;
foreach (const QString &path, mFileDialog.selectedFilePaths()) foreach (const QString &path, mFileDialog.selectedFilePaths())
files.push_back(path.toStdString()); files.push_back(path.toUtf8().constData());
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false);
@ -161,10 +161,10 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
std::vector<boost::filesystem::path> files; std::vector<boost::filesystem::path> files;
foreach (const QString &path, mFileDialog.selectedFilePaths()) { foreach (const QString &path, mFileDialog.selectedFilePaths()) {
files.push_back(path.toStdString()); files.push_back(path.toUtf8().constData());
} }
files.push_back(mFileDialog.filename().toStdString()); files.push_back(mFileDialog.filename().toUtf8().constData());
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true);

View file

@ -143,6 +143,6 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type)
std::map<int, int>::iterator iter = mActiveReports.find (type); std::map<int, int>::iterator iter = mActiveReports.find (type);
if (iter!=mActiveReports.end()) if (iter!=mActiveReports.end())
mReports[iter->second]->add (message.toStdString()); mReports[iter->second]->add (message.toUtf8().constData());
} }

View file

@ -37,7 +37,6 @@ namespace CSMWorld
} }
}; };
/// \note Shares ID with IdColumn. A table can not have both.
template<typename ESXRecordT> template<typename ESXRecordT>
struct StringIdColumn : public Column<ESXRecordT> struct StringIdColumn : public Column<ESXRecordT>
{ {
@ -838,11 +837,11 @@ namespace CSMWorld
} }
}; };
/// \note Shares ID with StringIdColumn. A table can not have both.
template<typename ESXRecordT> template<typename ESXRecordT>
struct IdColumn : public Column<ESXRecordT> struct IdColumn : public Column<ESXRecordT>
{ {
IdColumn() : Column<ESXRecordT> (Columns::ColumnId_Id, ColumnBase::Display_String) {} IdColumn() : Column<ESXRecordT> (Columns::ColumnId_ReferenceableId,
ColumnBase::Display_Referenceable) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {

View file

@ -172,7 +172,8 @@ namespace CSMWorld
{ ColumnId_Rank, "Rank" }, { ColumnId_Rank, "Rank" },
{ ColumnId_Gender, "Gender" }, { ColumnId_Gender, "Gender" },
{ ColumnId_PcRank, "PC Rank" }, { ColumnId_PcRank, "PC Rank" },
{ ColumnId_Scope, "Scope", }, { ColumnId_Scope, "Scope" },
{ ColumnId_ReferenceableId, "Referenceable ID" },
{ ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue1, "Use value 1" },
{ ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue2, "Use value 2" },

View file

@ -166,6 +166,7 @@ namespace CSMWorld
ColumnId_Gender = 153, ColumnId_Gender = 153,
ColumnId_PcRank = 154, ColumnId_PcRank = 154,
ColumnId_Scope = 155, ColumnId_Scope = 155,
ColumnId_ReferenceableId = 156,
// Allocated to a separate value range, so we don't get a collision should we ever need // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.

View file

@ -8,7 +8,7 @@ CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document&
mDocument(document) mDocument(document)
{ {
mUniversalId.push_back (id); mUniversalId.push_back (id);
mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName()); mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str());
} }
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
@ -16,7 +16,7 @@ CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id
{ {
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
{ {
mObjectsFormats << QString::fromStdString ("tabledata/" + it->getTypeName()); mObjectsFormats << QString::fromUtf8 (("tabledata/" + it->getTypeName()).c_str());
} }
} }

View file

@ -40,7 +40,7 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent)
mCfgMgr.processPaths(mDataLocal); mCfgMgr.processPaths(mDataLocal);
// Set the charset for reading the esm/esp files // Set the charset for reading the esm/esp files
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>()); QString encoding = QString::fromUtf8 (variables["encoding"].as<std::string>().c_str());
Files::PathContainer dataDirs; Files::PathContainer dataDirs;
dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end()); dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end());

View file

@ -4,7 +4,7 @@ CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
{ {
/// \todo add a button to the title bar that clones this sub view /// \todo add a button to the title bar that clones this sub view
setWindowTitle (mUniversalId.toString().c_str()); setWindowTitle (QString::fromUtf8 (mUniversalId.toString().c_str()));
} }
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const

View file

@ -120,7 +120,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st
{ {
ss<<"!or("; ss<<"!or(";
} else { } else {
ss << orAnd << oldContent.toStdString() << ','; ss << orAnd << oldContent.toUtf8().constData() << ',';
} }
for (unsigned i = 0; i < count; ++i) for (unsigned i = 0; i < count; ++i)
@ -137,7 +137,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st
} else { } else {
if (!replaceMode) if (!replaceMode)
{ {
ss << orAnd << oldContent.toStdString() <<','; ss << orAnd << oldContent.toUtf8().constData() <<',';
} else { } else {
ss<<'!'; ss<<'!';
} }

View file

@ -4,36 +4,55 @@
#include <OgreSceneManager.h> #include <OgreSceneManager.h>
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp"
void CSVRender::PreviewWidget::setup (const std::string& id) void CSVRender::PreviewWidget::setup()
{ {
setNavigation (&mOrbit); setNavigation (&mOrbit);
int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
int row = mData.getReferenceables().getIndex (id);
QVariant value = mData.getReferenceables().getData (row, column);
if (!value.isValid())
return;
std::string model = value.toString().toUtf8().constData();
if (model.empty())
return;
mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode(); mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
mNode->setPosition (Ogre::Vector3 (0, 0, 0)); mNode->setPosition (Ogre::Vector3 (0, 0, 0));
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); setModel();
QAbstractItemModel *referenceables =
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&)));
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int)));
} }
void CSVRender::PreviewWidget::adjust (const std::string& id) void CSVRender::PreviewWidget::setModel()
{ {
if (mNode) if (mNode)
{ {
int row = mData.getReferences().getIndex (id); mObject.setNull();
int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
int row = mData.getReferenceables().getIndex (mReferenceableId);
QVariant value = mData.getReferenceables().getData (row, column);
if (!value.isValid())
return;
std::string model = value.toString().toUtf8().constData();
if (model.empty())
return;
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model);
}
}
void CSVRender::PreviewWidget::adjust()
{
if (mNode)
{
int row = mData.getReferences().getIndex (mReferenceId);
float scale = mData.getReferences().getData (row, mData.getReferences(). float scale = mData.getReferences().getData (row, mData.getReferences().
findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat(); findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat();
@ -56,17 +75,82 @@ void CSVRender::PreviewWidget::adjust (const std::string& id)
} }
} }
CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
const std::string& referenceableId, QWidget *parent) const std::string& referenceableId, QWidget *parent)
: SceneWidget (parent), mData (data), mNode (0) : SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId)
{ {
setup (referenceableId); setup();
} }
CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
const std::string& referenceableId, const std::string& referenceId, QWidget *parent) const std::string& referenceableId, const std::string& referenceId, QWidget *parent)
: SceneWidget (parent), mData (data) : SceneWidget (parent), mData (data), mReferenceableId (referenceableId),
mReferenceId (referenceId)
{ {
setup (referenceableId); setup();
adjust (referenceId);
adjust();
QAbstractItemModel *references =
mData.getTableModel (CSMWorld::UniversalId::Type_References);
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&)));
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int)));
}
void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight)
{
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
{
/// \todo possible optimisation; check columns and only update if relevant columns have
/// changed
setModel();
flagAsModified();
}
}
void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start,
int end)
{
}
void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight)
{
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
QModelIndex index = references.getModelIndex (mReferenceId, columnIndex);
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
{
/// \todo possible optimisation; check columns and only update if relevant columns have
/// changed
adjust();
if (index.column()>=topLeft.column() && index.column()<=bottomRight.row())
{
mReferenceableId = references.data (index).toString().toUtf8().constData();
setModel();
}
flagAsModified();
}
}
void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start,
int end)
{
} }

View file

@ -7,6 +7,8 @@
#include "navigationorbit.hpp" #include "navigationorbit.hpp"
class QModelIndex;
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
@ -18,28 +20,42 @@ namespace CSVRender
{ {
Q_OBJECT Q_OBJECT
const CSMWorld::Data& mData; CSMWorld::Data& mData;
CSVRender::NavigationOrbit mOrbit; CSVRender::NavigationOrbit mOrbit;
NifOgre::ObjectScenePtr mObject; NifOgre::ObjectScenePtr mObject;
Ogre::SceneNode *mNode; Ogre::SceneNode *mNode;
std::string mReferenceId;
std::string mReferenceableId;
void setup (const std::string& id); void setup();
///< \param id ID of the referenceable to be viewed
void adjust (const std::string& id); void setModel();
///< \param id ID of the reference to be viewed
void adjust();
///< Adjust referenceable preview according to the reference
public: public:
PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
QWidget *parent = 0); QWidget *parent = 0);
PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
const std::string& referenceId, QWidget *parent = 0); const std::string& referenceId, QWidget *parent = 0);
signals: signals:
void closeRequest(); void closeRequest();
private slots:
void ReferenceableDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight);
void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
}; };
} }

View file

@ -118,6 +118,11 @@ namespace CSVRender
return mSceneMgr; return mSceneMgr;
} }
void SceneWidget::flagAsModified()
{
mUpdate = true;
}
void SceneWidget::paintEvent(QPaintEvent* e) void SceneWidget::paintEvent(QPaintEvent* e)
{ {
if (!mWindow) if (!mWindow)

View file

@ -36,6 +36,8 @@ namespace CSVRender
Ogre::SceneManager *getSceneManager(); Ogre::SceneManager *getSceneManager();
void flagAsModified();
private: private:
void paintEvent(QPaintEvent* e); void paintEvent(QPaintEvent* e);
void resizeEvent(QResizeEvent* e); void resizeEvent(QResizeEvent* e);

View file

@ -471,7 +471,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
mMainLayout = new QVBoxLayout(mainWidget); mMainLayout = new QVBoxLayout(mainWidget);
mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false);
connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
mMainLayout->addWidget(mEditWidget); mMainLayout->addWidget(mEditWidget);
@ -517,7 +517,7 @@ void CSVWorld::DialogueSubView::prevId()
{ {
mEditWidget->remake(newRow); mEditWidget->remake(newRow);
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()), setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
mTable->data (mTable->index (newRow, 0)).toString().toStdString())); mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
mRow = newRow; mRow = newRow;
mEditWidget->setDisabled(mLocked); mEditWidget->setDisabled(mLocked);
return; return;
@ -549,7 +549,7 @@ void CSVWorld::DialogueSubView::nextId()
{ {
mEditWidget->remake(newRow); mEditWidget->remake(newRow);
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()), setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
mTable->data (mTable->index (newRow, 0)).toString().toStdString())); mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
mRow = newRow; mRow = newRow;
mEditWidget->setDisabled(mLocked); mEditWidget->setDisabled(mLocked);
return; return;
@ -607,7 +607,7 @@ void CSVWorld::DialogueSubView::revertRecord()
if (state!=CSMWorld::RecordBase::State_BaseOnly) if (state!=CSMWorld::RecordBase::State_BaseOnly)
{ {
mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
} }
if (rows != mTable->rowCount()) if (rows != mTable->rowCount())
{ {
@ -640,7 +640,7 @@ void CSVWorld::DialogueSubView::deleteRecord()
mRow < rows && mRow < rows &&
mBottom->canCreateAndDelete()) mBottom->canCreateAndDelete())
{ {
mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
if (rows != mTable->rowCount()) if (rows != mTable->rowCount())
{ {
if (mTable->rowCount() == 0) if (mTable->rowCount() == 0)
@ -666,7 +666,7 @@ void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
void CSVWorld::DialogueSubView::cloneRequest () void CSVWorld::DialogueSubView::cloneRequest ()
{ {
mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toStdString(), mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData(),
static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->index(mRow, 2)).toInt())); static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->index(mRow, 2)).toInt()));
} }
@ -674,7 +674,7 @@ void CSVWorld::DialogueSubView::showPreview ()
{ {
if (mTable->hasPreview() && mRow < mTable->rowCount()) if (mTable->hasPreview() && mRow < mTable->rowCount())
{ {
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toStdString()), ""); emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), "");
} }
} }

View file

@ -71,9 +71,9 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
{ {
if (stringNeedsQuote(it->getId())) if (stringNeedsQuote(it->getId()))
{ {
insertPlainText(QString::fromStdString ('"' + it->getId() + '"')); insertPlainText(QString::fromUtf8 (('"' + it->getId() + '"').c_str()));
} else { } else {
insertPlainText(QString::fromStdString (it->getId())); insertPlainText(QString::fromUtf8 (it->getId().c_str()));
} }
} }
} }
@ -82,7 +82,7 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const 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. const QString string(QString::fromUtf8(id.c_str())); //<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… //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)); return !(string.contains(mWhiteListQoutes));
} }

View file

@ -289,7 +289,7 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
{ {
return CSMWorld::UniversalId ( return CSMWorld::UniversalId (
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()), static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString()); mProxyModel->data (mProxyModel->index (row, 0)).toString().toUtf8().constData());
} }
void CSVWorld::Table::revertRecord() void CSVWorld::Table::revertRecord()
@ -533,7 +533,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
} }
drag->setMimeData (mime); drag->setMimeData (mime);
drag->setPixmap (QString::fromStdString (mime->getIcon())); drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str()));
drag->exec(Qt::CopyAction); drag->exec(Qt::CopyAction);
} }
@ -588,7 +588,7 @@ std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column
if (display == columndisplay) if (display == columndisplay)
{ {
titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toStdString()); titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData());
} }
} }
return titles; return titles;