#include "dialoguesubview.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/idtree.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtree.hpp" #include "../../model/world/commands.hpp" #include "../../model/doc/document.hpp" #include "../widget/coloreditor.hpp" #include "../widget/droplineedit.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" #include "tablebottombox.hpp" #include "nestedtable.hpp" #include "recordbuttonbar.hpp" /* ==============================NotEditableSubDelegate========================================== */ CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent) : QAbstractItemDelegate(parent), mTable(table) {} void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QModelIndex& index) const { QLabel* label = qobject_cast(editor); if(!label) return; QVariant v = index.data(Qt::EditRole); if (!v.isValid()) { v = index.data(Qt::DisplayRole); if (!v.isValid()) { return; } } CSMWorld::Columns::ColumnId columnId = static_cast ( mTable->getColumnId (index.column())); if (QVariant::String == v.type()) { label->setText(v.toString()); } else if (CSMWorld::Columns::hasEnums (columnId)) { int data = v.toInt(); std::vector enumNames (CSMWorld::Columns::getEnums (columnId)); label->setText(QString::fromUtf8(enumNames.at(data).c_str())); } else { label->setText (v.toString()); } } void CSVWorld::NotEditableSubDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { //not editable widgets will not save model data } void CSVWorld::NotEditableSubDelegate::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { //does nothing } QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const { return QSize(); } QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return new QLabel(parent); } /* ==============================DialogueDelegateDispatcherProxy========================================== */ CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) : mIndex(index) {} CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) : mEditor(editor), mDisplay(display), mIndexWrapper(NULL) { } void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited() { if (mIndexWrapper.get()) { emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); } } void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index) { mIndexWrapper.reset(new refWrapper(index)); } QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const { return mEditor; } /* ==============================DialogueDelegateDispatcher========================================== */ CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, QAbstractItemModel *model) : mParent(parent), mTable(model ? model : table), mCommandDispatcher (commandDispatcher), mDocument (document), mNotEditableDelegate(table, parent) { } CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display) { CommandDelegate *delegate = NULL; std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt == mDelegates.end()) { delegate = CommandDelegateFactoryCollection::get().makeDelegate ( display, &mCommandDispatcher, mDocument, mParent); mDelegates.insert(std::make_pair(display, delegate)); } else { delegate = delegateIt->second; } return delegate; } void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display) { setModelData(editor, mTable, index, display); } void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const { CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None; if (index.parent().isValid()) { display = static_cast (static_cast(mTable)->nestedHeaderData (index.parent().column(), index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); } else { display = static_cast (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); } QLabel* label = qobject_cast(editor); if(label) { mNotEditableDelegate.setEditorData(label, index); return; } std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { delegateIt->second->setEditorData(editor, index, true); } for (unsigned i = 0; i < mProxys.size(); ++i) { if (mProxys[i]->getEditor() == editor) { mProxys[i]->setIndex(index); } } } void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { setModelData(editor, model, index, CSMWorld::ColumnBase::Display_None); } void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { delegateIt->second->setModelData(editor, model, index); } } void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { //Does nothing } QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const { return QSize(); //silencing warning, otherwise does nothing } QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index) { QVariant variant = index.data(); if (!variant.isValid()) { variant = index.data(Qt::DisplayRole); if (!variant.isValid()) { return NULL; } } QWidget* editor = NULL; if (! (mTable->flags (index) & Qt::ItemIsEditable)) { return mNotEditableDelegate.createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index); } std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { editor = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); // NOTE: For each entry in CSVWorld::CommandDelegate::createEditor() a corresponding entry // is required here if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); connect(editor, SIGNAL(tableMimeDataDropped(const CSMWorld::UniversalId&, const CSMDoc::Document*)), proxy, SLOT(editorDataCommited())); } else if (qobject_cast(editor)) { connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited())); } else if (qobject_cast(editor)) { connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited())); } else if (qobject_cast(editor)) { connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); } else if (qobject_cast(editor) || qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); } else if (qobject_cast(editor)) { connect(editor, SIGNAL(pickingFinished()), proxy, SLOT(editorDataCommited())); } else // throw an exception because this is a coding error throw std::logic_error ("Dialogue editor type missing"); connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor } return editor; } CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() { for (unsigned i = 0; i < mProxys.size(); ++i) { delete mProxys[i]; //unique_ptr could be handy } } /* =============================================================EditWidget===================================================== */ CSVWorld::EditWidget::~EditWidget() { for (unsigned i = 0; i < mNestedModels.size(); ++i) delete mNestedModels[i]; if (mDispatcher) delete mDispatcher; if (mNestedTableDispatcher) delete mNestedTableDispatcher; } CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete) : QScrollArea(parent), mWidgetMapper(NULL), mNestedTableMapper(NULL), mDispatcher(NULL), mNestedTableDispatcher(NULL), mMainWidget(NULL), mTable(table), mCommandDispatcher (commandDispatcher), mDocument (document) { remake (row); } void CSVWorld::EditWidget::remake(int row) { if (mMainWidget) { QWidget *del = this->takeWidget(); del->deleteLater(); } mMainWidget = new QWidget (this); for (unsigned i = 0; i < mNestedModels.size(); ++i) delete mNestedModels[i]; mNestedModels.clear(); if (mDispatcher) delete mDispatcher; mDispatcher = new DialogueDelegateDispatcher(0/*this*/, mTable, mCommandDispatcher, mDocument); if (mNestedTableDispatcher) delete mNestedTableDispatcher; //not sure if widget mapper can handle deleting the widgets that were mapped if (mWidgetMapper) delete mWidgetMapper; mWidgetMapper = new QDataWidgetMapper (this); mWidgetMapper->setModel(mTable); mWidgetMapper->setItemDelegate(mDispatcher); if (mNestedTableMapper) delete mNestedTableMapper; QFrame* line = new QFrame(mMainWidget); line->setObjectName(QString::fromUtf8("line")); line->setGeometry(QRect(320, 150, 118, 3)); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); QFrame* line2 = new QFrame(mMainWidget); line2->setObjectName(QString::fromUtf8("line")); line2->setGeometry(QRect(320, 150, 118, 3)); line2->setFrameShape(QFrame::HLine); line2->setFrameShadow(QFrame::Sunken); QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); QGridLayout *lockedLayout = new QGridLayout(); QGridLayout *unlockedLayout = new QGridLayout(); QVBoxLayout *tablesLayout = new QVBoxLayout(); mainLayout->addLayout(lockedLayout, QSizePolicy::Fixed); mainLayout->addWidget(line, 1); mainLayout->addLayout(unlockedLayout, QSizePolicy::Preferred); mainLayout->addWidget(line2, 1); mainLayout->addLayout(tablesLayout, QSizePolicy::Preferred); mainLayout->addStretch(1); int unlocked = 0; int locked = 0; const int columns = mTable->columnCount(); for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { CSMWorld::ColumnBase::Display display = static_cast (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); if (mTable->hasChildren(mTable->index(row, i)) && !(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { mNestedModels.push_back(new CSMWorld::NestedTableProxyModel ( mTable->index(row, i), display, dynamic_cast(mTable))); int idColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_Id); int typeColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); CSMWorld::UniversalId id = CSMWorld::UniversalId( static_cast (mTable->data (mTable->index (row, typeColumn)).toInt()), mTable->data (mTable->index (row, idColumn)).toString().toUtf8().constData()); NestedTable* table = new NestedTable(mDocument, id, mNestedModels.back(), this); table->resizeColumnsToContents(); if(mTable->index(row, i).data().type() == QVariant::UserType) { table->setEditTriggers(QAbstractItemView::NoEditTriggers); table->setEnabled(false); } else table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); int rows = mTable->rowCount(mTable->index(row, i)); int rowHeight = (rows == 0) ? table->horizontalHeader()->height() : table->rowHeight(0); int tableMaxHeight = (5 * rowHeight) + table->horizontalHeader()->height() + 2 * table->frameWidth(); table->setMinimumHeight(tableMaxHeight); QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); if(mTable->index(row, i).data().type() == QVariant::UserType) label->setEnabled(false); tablesLayout->addWidget(label); tablesLayout->addWidget(table); } else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { mDispatcher->makeDelegate (display); QWidget* editor = mDispatcher->makeEditor (display, (mTable->index (row, i))); if (editor) { mWidgetMapper->addMapping (editor, i); QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable)) { lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); ++locked; } else { unlockedLayout->addWidget (label, unlocked, 0); unlockedLayout->addWidget (editor, unlocked, 1); ++unlocked; } if(mTable->index(row, i).data().type() == QVariant::UserType) { editor->setEnabled(false); label->setEnabled(false); } } } else { CSMWorld::IdTree *tree = static_cast(mTable); mNestedTableMapper = new QDataWidgetMapper (this); mNestedTableMapper->setModel(tree); // FIXME: lack MIME support? mNestedTableDispatcher = new DialogueDelegateDispatcher (0/*this*/, mTable, mCommandDispatcher, mDocument, tree); mNestedTableMapper->setRootIndex (tree->index(row, i)); mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); int columnCount = tree->columnCount(tree->index(row, i)); for (int col = 0; col < columnCount; ++col) { int displayRole = tree->nestedHeaderData (i, col, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt(); CSMWorld::ColumnBase::Display display = static_cast (displayRole); mNestedTableDispatcher->makeDelegate (display); // FIXME: assumed all columns are editable QWidget* editor = mNestedTableDispatcher->makeEditor (display, tree->index (0, col, tree->index(row, i))); if (editor) { mNestedTableMapper->addMapping (editor, col); std::string disString = tree->nestedHeaderData (i, col, Qt::Horizontal, Qt::DisplayRole).toString().toStdString(); // Need to use Qt::DisplayRole in order to get the correct string // from CSMWorld::Columns QLabel* label = new QLabel (tree->nestedHeaderData (i, col, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); unlockedLayout->addWidget (label, unlocked, 0); unlockedLayout->addWidget (editor, unlocked, 1); ++unlocked; if(tree->index(0, col, tree->index(row, i)).data().type() == QVariant::UserType) { editor->setEnabled(false); label->setEnabled(false); } } } mNestedTableMapper->setCurrentModelIndex(tree->index(0, 0, tree->index(row, i))); } } } mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); if (unlocked == 0) mainLayout->removeWidget(line); this->setWidget(mMainWidget); this->setWidgetResizable(true); } QVBoxLayout& CSVWorld::SimpleDialogueSubView::getMainLayout() { return *mMainLayout; } CSMWorld::IdTable& CSVWorld::SimpleDialogueSubView::getTable() { return *mTable; } CSMWorld::CommandDispatcher& CSVWorld::SimpleDialogueSubView::getCommandDispatcher() { return mCommandDispatcher; } std::string CSVWorld::SimpleDialogueSubView::getCurrentId() const { return mCurrentId; } CSVWorld::EditWidget& CSVWorld::SimpleDialogueSubView::getEditWidget() { return *mEditWidget; } bool CSVWorld::SimpleDialogueSubView::isLocked() const { return mLocked; } CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mEditWidget(0), mMainLayout(NULL), mTable(dynamic_cast(document.getData().getTableModel(id))), mUndoStack(document.getUndoStack()), mLocked(false), mDocument(document), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) { connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); connect(mTable, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), this, SLOT(rowsAboutToBeRemoved(const QModelIndex&, int, int))); changeCurrentId(id.getId()); QWidget *mainWidget = new QWidget(this); mMainLayout = new QVBoxLayout(mainWidget); setWidget (mainWidget); mEditWidget = new EditWidget(mainWidget, mTable->getModelIndex(mCurrentId, 0).row(), mTable, mCommandDispatcher, document, false); mMainLayout->addWidget(mEditWidget); mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); dataChanged(mTable->getModelIndex (mCurrentId, 0)); } void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked) { if (!mEditWidget) // hack to indicate that mCurrentId is no longer valid return; mLocked = locked; QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); if (currentIndex.isValid()) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); mCommandDispatcher.setEditLock (locked); } } void CSVWorld::SimpleDialogueSubView::dataChanged (const QModelIndex & index) { QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); if (currentIndex.isValid() && (index.parent().isValid() ? index.parent().row() : index.row()) == currentIndex.row()) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); // Check if the changed data should force refresh (rebuild) the dialogue subview int flags = 0; if (index.parent().isValid()) // TODO: check that index is topLeft { flags = static_cast(mTable)->nestedHeaderData (index.parent().column(), index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); } else { flags = mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); } if (flags & CSMWorld::ColumnBase::Flag_Dialogue_Refresh) { int y = mEditWidget->verticalScrollBar()->value(); mEditWidget->remake (index.parent().isValid() ? index.parent().row() : index.row()); mEditWidget->verticalScrollBar()->setValue(y); } } } void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); if (currentIndex.isValid() && currentIndex.row() >= start && currentIndex.row() <= end) { if(mEditWidget) { delete mEditWidget; mEditWidget = 0; } emit closeRequest(this); } } void CSVWorld::SimpleDialogueSubView::requestFocus (const std::string& id) { changeCurrentId(id); mEditWidget->remake(mTable->getModelIndex (id, 0).row()); } void CSVWorld::SimpleDialogueSubView::changeCurrentId (const std::string& newId) { std::vector selection; mCurrentId = std::string(newId); selection.push_back(mCurrentId); mCommandDispatcher.setSelection(selection); } CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting) : SimpleDialogueSubView (id, document) { // bottom box mBottom = new TableBottomBox (creatorFactory, document, id, this); mBottom->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Fixed); connect (mBottom, SIGNAL (requestFocus (const std::string&)), this, SLOT (requestFocus (const std::string&))); // button bar RecordButtonBar *buttons = new RecordButtonBar (getTable(), mBottom, &getCommandDispatcher(), this); // layout getMainLayout().addWidget (buttons); getMainLayout().addWidget (mBottom); // connections connect (buttons, SIGNAL (nextId()), this, SLOT (nextId())); connect (buttons, SIGNAL (prevId()), this, SLOT (prevId())); connect (buttons, SIGNAL (cloneRequest()), this, SLOT (cloneRequest())); connect (buttons, SIGNAL (showPreview()), this, SLOT (showPreview())); connect (buttons, SIGNAL (viewRecord()), this, SLOT (viewRecord())); } void CSVWorld::DialogueSubView::cloneRequest() { mBottom->cloneRequest (getCurrentId(), static_cast (getTable(). data (getTable().getModelIndex(getCurrentId(), 2)).toInt())); } void CSVWorld::DialogueSubView::prevId() { int newRow = getTable().getModelIndex (getCurrentId(), 0).row() - 1; if (newRow < 0) { return; } while (newRow >= 0) { QModelIndex newIndex (getTable().index(newRow, 0)); if (!newIndex.isValid()) { return; } CSMWorld::RecordBase::State state = static_cast (getTable().data (getTable().index (newRow, 1)).toInt()); if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)) { getEditWidget().remake (newRow); setUniversalId(CSMWorld::UniversalId (static_cast (getTable().data (getTable().index (newRow, 2)).toInt()), getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); changeCurrentId(std::string (getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); getEditWidget().setDisabled (isLocked()); return; } --newRow; } } void CSVWorld::DialogueSubView::nextId () { int newRow = getTable().getModelIndex (getCurrentId(), 0).row() + 1; if (newRow >= getTable().rowCount()) { return; } while (newRow < getTable().rowCount()) { QModelIndex newIndex (getTable().index(newRow, 0)); if (!newIndex.isValid()) { return; } CSMWorld::RecordBase::State state = static_cast (getTable().data (getTable().index (newRow, 1)).toInt()); if (!(state == CSMWorld::RecordBase::State_Deleted)) { getEditWidget().remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (getTable().data (getTable().index (newRow, 2)).toInt()), getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); changeCurrentId(std::string (getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); getEditWidget().setDisabled (isLocked()); return; } ++newRow; } } void CSVWorld::DialogueSubView::showPreview () { QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0)); if (currentIndex.isValid() && getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview && currentIndex.row() < getTable().rowCount()) { emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, getCurrentId()), ""); } } void CSVWorld::DialogueSubView::viewRecord () { QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0)); if (currentIndex.isValid() && currentIndex.row() < getTable().rowCount()) { std::pair params = getTable().view (currentIndex.row()); if (params.first.getType()!=CSMWorld::UniversalId::Type_None) emit focusId (params.first, params.second); } }