Merge remote-tracking branch 'smbas/feature-dialogue-edit-id'

c++11
Marc Zinnschlag 10 years ago
commit ea1ddb5c9f

@ -64,7 +64,7 @@ opencs_units (view/world
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
cellcreator referenceablecreator referencecreator scenesubview cellcreator referenceablecreator referencecreator scenesubview
infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable
dialoguespinbox recordbuttonbar dialoguespinbox recordbuttonbar tableeditidaction
) )
opencs_units_noqt (view/world opencs_units_noqt (view/world

@ -19,6 +19,7 @@
#include <QComboBox> #include <QComboBox>
#include <QHeaderView> #include <QHeaderView>
#include <QScrollBar> #include <QScrollBar>
#include <QMenu>
#include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/nestedtableproxymodel.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
@ -314,10 +315,141 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher()
} }
} }
CSVWorld::IdContextMenu::IdContextMenu(QWidget *widget, CSMWorld::ColumnBase::Display display)
: QObject(widget),
mWidget(widget),
mIdType(CSMWorld::TableMimeData::convertEnums(display))
{
Q_ASSERT(mWidget != NULL);
Q_ASSERT(CSMWorld::ColumnBase::isId(display));
Q_ASSERT(mIdType != CSMWorld::UniversalId::Type_None);
mWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(mWidget,
SIGNAL(customContextMenuRequested(const QPoint &)),
this,
SLOT(showContextMenu(const QPoint &)));
mEditIdAction = new QAction(this);
connect(mEditIdAction, SIGNAL(triggered()), this, SLOT(editIdRequest()));
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(mWidget);
if (lineEdit != NULL)
{
mContextMenu = lineEdit->createStandardContextMenu();
}
else
{
mContextMenu = new QMenu(mWidget);
}
}
void CSVWorld::IdContextMenu::excludeId(const std::string &id)
{
mExcludedIds.insert(id);
}
QString CSVWorld::IdContextMenu::getWidgetValue() const
{
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(mWidget);
QLabel *label = qobject_cast<QLabel *>(mWidget);
QString value = "";
if (lineEdit != NULL)
{
value = lineEdit->text();
}
else if (label != NULL)
{
value = label->text();
}
return value;
}
void CSVWorld::IdContextMenu::addEditIdActionToMenu(const QString &text)
{
mEditIdAction->setText(text);
if (mContextMenu->actions().isEmpty())
{
mContextMenu->addAction(mEditIdAction);
}
else if (mContextMenu->actions().first() != mEditIdAction)
{
QAction *action = mContextMenu->actions().first();
mContextMenu->insertAction(action, mEditIdAction);
mContextMenu->insertSeparator(action);
}
}
void CSVWorld::IdContextMenu::removeEditIdActionFromMenu()
{
if (mContextMenu->actions().isEmpty())
{
return;
}
if (mContextMenu->actions().first() == mEditIdAction)
{
mContextMenu->removeAction(mEditIdAction);
if (!mContextMenu->actions().isEmpty() && mContextMenu->actions().first()->isSeparator())
{
mContextMenu->removeAction(mContextMenu->actions().first());
}
}
}
void CSVWorld::IdContextMenu::showContextMenu(const QPoint &pos)
{
QString value = getWidgetValue();
bool isExcludedId = mExcludedIds.find(value.toUtf8().constData()) != mExcludedIds.end();
if (!value.isEmpty() && !isExcludedId)
{
addEditIdActionToMenu("Edit '" + value + "'");
}
else
{
removeEditIdActionFromMenu();
}
if (!mContextMenu->actions().isEmpty())
{
mContextMenu->exec(mWidget->mapToGlobal(pos));
}
}
void CSVWorld::IdContextMenu::editIdRequest()
{
CSMWorld::UniversalId editId(mIdType, getWidgetValue().toUtf8().constData());
emit editIdRequest(editId, "");
}
/* /*
=============================================================EditWidget===================================================== =============================================================EditWidget=====================================================
*/ */
void CSVWorld::EditWidget::createEditorContextMenu(QWidget *editor,
CSMWorld::ColumnBase::Display display,
int currentRow) const
{
Q_ASSERT(editor != NULL);
if (CSMWorld::ColumnBase::isId(display) &&
CSMWorld::TableMimeData::convertEnums(display) != CSMWorld::UniversalId::Type_None)
{
int idColumn = mTable->findColumnIndex(CSMWorld::Columns::ColumnId_Id);
QString id = mTable->data(mTable->index(currentRow, idColumn)).toString();
IdContextMenu *menu = new IdContextMenu(editor, display);
// Current ID is already opened, so no need to create Edit 'ID' action for it
menu->excludeId(id.toUtf8().constData());
connect(menu,
SIGNAL(editIdRequest(const CSMWorld::UniversalId &, const std::string &)),
this,
SIGNAL(editIdRequest(const CSMWorld::UniversalId &, const std::string &)));
}
}
CSVWorld::EditWidget::~EditWidget() CSVWorld::EditWidget::~EditWidget()
{ {
for (unsigned i = 0; i < mNestedModels.size(); ++i) for (unsigned i = 0; i < mNestedModels.size(); ++i)
@ -455,6 +587,11 @@ void CSVWorld::EditWidget::remake(int row)
tablesLayout->addWidget(label); tablesLayout->addWidget(label);
tablesLayout->addWidget(table); tablesLayout->addWidget(table);
connect(table,
SIGNAL(editRequest(const CSMWorld::UniversalId &, const std::string &)),
this,
SIGNAL(editIdRequest(const CSMWorld::UniversalId &, const std::string &)));
} }
else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List))
{ {
@ -488,6 +625,8 @@ void CSVWorld::EditWidget::remake(int row)
editor->setEnabled(false); editor->setEnabled(false);
label->setEnabled(false); label->setEnabled(false);
} }
createEditorContextMenu(editor, display, row);
} }
} }
else else
@ -539,6 +678,8 @@ void CSVWorld::EditWidget::remake(int row)
editor->setEnabled(false); editor->setEnabled(false);
label->setEnabled(false); label->setEnabled(false);
} }
createEditorContextMenu(editor, display, row);
} }
} }
mNestedTableMapper->setCurrentModelIndex(tree->index(0, 0, tree->index(row, i))); mNestedTableMapper->setCurrentModelIndex(tree->index(0, 0, tree->index(row, i)));
@ -607,6 +748,11 @@ CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::Universa
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
dataChanged(mTable->getModelIndex (getUniversalId().getId(), 0)); dataChanged(mTable->getModelIndex (getUniversalId().getId(), 0));
connect(mEditWidget,
SIGNAL(editIdRequest(const CSMWorld::UniversalId &, const std::string &)),
this,
SIGNAL(focusId(const CSMWorld::UniversalId &, const std::string &)));
} }
void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked) void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked)

@ -1,6 +1,7 @@
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H #ifndef CSV_WORLD_DIALOGUESUBVIEW_H
#define CSV_WORLD_DIALOGUESUBVIEW_H #define CSV_WORLD_DIALOGUESUBVIEW_H
#include <set>
#include <map> #include <map>
#include <memory> #include <memory>
@ -11,12 +12,14 @@
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commanddispatcher.hpp"
#include "../../model/world/universalid.hpp"
class QDataWidgetMapper; class QDataWidgetMapper;
class QSize; class QSize;
class QEvent; class QEvent;
class QLabel; class QLabel;
class QVBoxLayout; class QVBoxLayout;
class QMenu;
namespace CSMWorld namespace CSMWorld
{ {
@ -149,6 +152,36 @@ namespace CSVWorld
CSMWorld::ColumnBase::Display display); CSMWorld::ColumnBase::Display display);
}; };
/// A context menu with "Edit 'ID'" action for editors in the dialogue subview
class IdContextMenu : public QObject
{
Q_OBJECT
QWidget *mWidget;
CSMWorld::UniversalId::Type mIdType;
std::set<std::string> mExcludedIds;
///< A list of IDs that should not have the Edit 'ID' action.
QMenu *mContextMenu;
QAction *mEditIdAction;
QString getWidgetValue() const;
void addEditIdActionToMenu(const QString &text);
void removeEditIdActionFromMenu();
public:
IdContextMenu(QWidget *widget, CSMWorld::ColumnBase::Display display);
void excludeId(const std::string &id);
private slots:
void showContextMenu(const QPoint &pos);
void editIdRequest();
signals:
void editIdRequest(const CSMWorld::UniversalId &id, const std::string &hint);
};
class EditWidget : public QScrollArea class EditWidget : public QScrollArea
{ {
Q_OBJECT Q_OBJECT
@ -162,6 +195,9 @@ namespace CSVWorld
CSMDoc::Document& mDocument; CSMDoc::Document& mDocument;
std::vector<CSMWorld::NestedTableProxyModel*> mNestedModels; //Plain, raw C pointers, deleted in the dtor std::vector<CSMWorld::NestedTableProxyModel*> mNestedModels; //Plain, raw C pointers, deleted in the dtor
void createEditorContextMenu(QWidget *editor,
CSMWorld::ColumnBase::Display display,
int currentRow) const;
public: public:
EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table,
@ -171,6 +207,9 @@ namespace CSVWorld
virtual ~EditWidget(); virtual ~EditWidget();
void remake(int row); void remake(int row);
signals:
void editIdRequest(const CSMWorld::UniversalId &id, const std::string &hint);
}; };
class SimpleDialogueSubView : public CSVDoc::SubView class SimpleDialogueSubView : public CSVDoc::SubView

@ -1,15 +1,18 @@
#include "nestedtable.hpp" #include "nestedtable.hpp"
#include "../../model/world/nestedtableproxymodel.hpp"
#include "../../model/world/universalid.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/commanddispatcher.hpp"
#include "util.hpp"
#include <QHeaderView> #include <QHeaderView>
#include <QContextMenuEvent> #include <QContextMenuEvent>
#include <QMenu> #include <QMenu>
#include <QDebug> #include <QDebug>
#include "../../model/world/nestedtableproxymodel.hpp"
#include "../../model/world/universalid.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/commanddispatcher.hpp"
#include "tableeditidaction.hpp"
#include "util.hpp"
CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
CSMWorld::UniversalId id, CSMWorld::UniversalId id,
CSMWorld::NestedTableProxyModel* model, CSMWorld::NestedTableProxyModel* model,
@ -55,6 +58,9 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
connect(mRemoveRowAction, SIGNAL(triggered()), connect(mRemoveRowAction, SIGNAL(triggered()),
this, SLOT(removeRowActionTriggered())); this, SLOT(removeRowActionTriggered()));
mEditIdAction = new TableEditIdAction(*this, this);
connect(mEditIdAction, SIGNAL(triggered()), this, SLOT(editCell()));
} }
std::vector<CSMWorld::UniversalId> CSVWorld::NestedTable::getDraggedRecords() const std::vector<CSMWorld::UniversalId> CSVWorld::NestedTable::getDraggedRecords() const
@ -69,6 +75,15 @@ void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event)
QMenu menu(this); QMenu menu(this);
int currentRow = rowAt(event->y());
int currentColumn = columnAt(event->x());
if (mEditIdAction->isValidIdCell(currentRow, currentColumn))
{
mEditIdAction->setCell(currentRow, currentColumn);
menu.addAction(mEditIdAction);
menu.addSeparator();
}
if (selectionModel()->selectedRows().size() == 1) if (selectionModel()->selectedRows().size() == 1)
menu.addAction(mRemoveRowAction); menu.addAction(mRemoveRowAction);
@ -92,3 +107,8 @@ void CSVWorld::NestedTable::addNewRowActionTriggered()
selectionModel()->selectedRows().size(), selectionModel()->selectedRows().size(),
mModel->getParentColumn())); mModel->getParentColumn()));
} }
void CSVWorld::NestedTable::editCell()
{
emit editRequest(mEditIdAction->getCurrentId(), "");
}

@ -22,12 +22,15 @@ namespace CSMDoc
namespace CSVWorld namespace CSVWorld
{ {
class TableEditIdAction;
class NestedTable : public DragRecordTable class NestedTable : public DragRecordTable
{ {
Q_OBJECT Q_OBJECT
QAction *mAddNewRowAction; QAction *mAddNewRowAction;
QAction *mRemoveRowAction; QAction *mRemoveRowAction;
TableEditIdAction *mEditIdAction;
CSMWorld::NestedTableProxyModel* mModel; CSMWorld::NestedTableProxyModel* mModel;
CSMWorld::CommandDispatcher *mDispatcher; CSMWorld::CommandDispatcher *mDispatcher;
@ -46,6 +49,11 @@ namespace CSVWorld
void removeRowActionTriggered(); void removeRowActionTriggered();
void addNewRowActionTriggered(); void addNewRowActionTriggered();
void editCell();
signals:
void editRequest(const CSMWorld::UniversalId &id, const std::string &hint);
}; };
} }

@ -27,6 +27,7 @@
#include "../../model/settings/usersettings.hpp" #include "../../model/settings/usersettings.hpp"
#include "recordstatusdelegate.hpp" #include "recordstatusdelegate.hpp"
#include "tableeditidaction.hpp"
#include "util.hpp" #include "util.hpp"
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
@ -58,33 +59,13 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
/// \todo add menu items for select all and clear selection /// \todo add menu items for select all and clear selection
int currentRow = rowAt(event->y());
int currentColumn = columnAt(event->x());
if (mEditIdAction->isValidIdCell(currentRow, currentColumn))
{ {
// Request UniversalId editing from table columns. mEditIdAction->setCell(currentRow, currentColumn);
menu.addAction(mEditIdAction);
int currRow = rowAt( event->y() ), menu.addSeparator();
currCol = columnAt( event->x() );
currRow = mProxyModel->mapToSource(mProxyModel->index( currRow, 0 )).row();
CSMWorld::ColumnBase::Display colDisplay =
static_cast<CSMWorld::ColumnBase::Display>(
mModel->headerData(
currCol,
Qt::Horizontal,
CSMWorld::ColumnBase::Role_Display ).toInt());
QString cellData = mModel->data(mModel->index( currRow, currCol )).toString();
CSMWorld::UniversalId::Type colType = CSMWorld::TableMimeData::convertEnums( colDisplay );
if ( !cellData.isEmpty()
&& colType != CSMWorld::UniversalId::Type_None )
{
mEditCellAction->setText(tr("Edit '").append(cellData).append("'"));
menu.addAction( mEditCellAction );
mEditCellId = CSMWorld::UniversalId( colType, cellData.toUtf8().constData() );
}
} }
if (!mEditLock && !(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant)) if (!mEditLock && !(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
@ -363,10 +344,6 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord())); connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
addAction (mMoveDownAction); addAction (mMoveDownAction);
mEditCellAction = new QAction( tr("Edit Cell"), this );
connect( mEditCellAction, SIGNAL(triggered()), this, SLOT(editCell()) );
addAction( mEditCellAction );
mViewAction = new QAction (tr ("View"), this); mViewAction = new QAction (tr ("View"), this);
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord())); connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
addAction (mViewAction); addAction (mViewAction);
@ -387,6 +364,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
connect (mExtendedRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedRevert())); connect (mExtendedRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedRevert()));
addAction (mExtendedRevertAction); addAction (mExtendedRevertAction);
mEditIdAction = new TableEditIdAction (*this, this);
connect (mEditIdAction, SIGNAL (triggered()), this, SLOT (editCell()));
addAction (mEditIdAction);
connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (tableSizeUpdate())); this, SLOT (tableSizeUpdate()));
@ -522,7 +503,7 @@ void CSVWorld::Table::moveDownRecord()
void CSVWorld::Table::editCell() void CSVWorld::Table::editCell()
{ {
emit editRequest( mEditCellId, std::string() ); emit editRequest(mEditIdAction->getCurrentId(), "");
} }
void CSVWorld::Table::viewRecord() void CSVWorld::Table::viewRecord()

@ -30,6 +30,7 @@ namespace CSMWorld
namespace CSVWorld namespace CSVWorld
{ {
class CommandDelegate; class CommandDelegate;
class TableEditIdAction;
///< Table widget ///< Table widget
class Table : public DragRecordTable class Table : public DragRecordTable
@ -57,15 +58,14 @@ namespace CSVWorld
QAction *mMoveUpAction; QAction *mMoveUpAction;
QAction *mMoveDownAction; QAction *mMoveDownAction;
QAction *mViewAction; QAction *mViewAction;
QAction *mEditCellAction;
QAction *mPreviewAction; QAction *mPreviewAction;
QAction *mExtendedDeleteAction; QAction *mExtendedDeleteAction;
QAction *mExtendedRevertAction; QAction *mExtendedRevertAction;
TableEditIdAction *mEditIdAction;
CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTableBase *mModel; CSMWorld::IdTableBase *mModel;
int mRecordStatusDisplay; int mRecordStatusDisplay;
CSMWorld::CommandDispatcher *mDispatcher; CSMWorld::CommandDispatcher *mDispatcher;
CSMWorld::UniversalId mEditCellId;
std::map<Qt::KeyboardModifiers, DoubleClickAction> mDoubleClickActions; std::map<Qt::KeyboardModifiers, DoubleClickAction> mDoubleClickActions;
bool mJumpToAddedRecord; bool mJumpToAddedRecord;
bool mUnselectAfterJump; bool mUnselectAfterJump;

@ -0,0 +1,49 @@
#include "tableeditidaction.hpp"
#include <QTableView>
#include "../../model/world/tablemimedata.hpp"
CSVWorld::TableEditIdAction::CellData CSVWorld::TableEditIdAction::getCellData(int row, int column) const
{
QModelIndex index = mTable.model()->index(row, column);
if (index.isValid())
{
QVariant display = mTable.model()->data(index, CSMWorld::ColumnBase::Role_Display);
QString value = mTable.model()->data(index).toString();
return std::make_pair(static_cast<CSMWorld::ColumnBase::Display>(display.toInt()), value);
}
return std::make_pair(CSMWorld::ColumnBase::Display_None, "");
}
CSVWorld::TableEditIdAction::TableEditIdAction(const QTableView &table, QWidget *parent)
: QAction(parent),
mTable(table),
mCurrentId(CSMWorld::UniversalId::Type_None)
{}
void CSVWorld::TableEditIdAction::setCell(int row, int column)
{
CellData data = getCellData(row, column);
CSMWorld::UniversalId::Type idType = CSMWorld::TableMimeData::convertEnums(data.first);
if (idType != CSMWorld::UniversalId::Type_None)
{
mCurrentId = CSMWorld::UniversalId(idType, data.second.toUtf8().constData());
setText("Edit '" + data.second + "'");
}
}
CSMWorld::UniversalId CSVWorld::TableEditIdAction::getCurrentId() const
{
return mCurrentId;
}
bool CSVWorld::TableEditIdAction::isValidIdCell(int row, int column) const
{
CellData data = getCellData(row, column);
CSMWorld::UniversalId::Type idType = CSMWorld::TableMimeData::convertEnums(data.first);
return CSMWorld::ColumnBase::isId(data.first) &&
idType != CSMWorld::UniversalId::Type_None &&
!data.second.isEmpty();
}

@ -0,0 +1,31 @@
#ifndef CSVWORLD_TABLEEDITIDACTION_HPP
#define CSVWORLD_TABLEEDITIDACTION_HPP
#include <QAction>
#include "../../model/world/columnbase.hpp"
#include "../../model/world/universalid.hpp"
class QTableView;
namespace CSVWorld
{
class TableEditIdAction : public QAction
{
const QTableView &mTable;
CSMWorld::UniversalId mCurrentId;
typedef std::pair<CSMWorld::ColumnBase::Display, QString> CellData;
CellData getCellData(int row, int column) const;
public:
TableEditIdAction(const QTableView &table, QWidget *parent = 0);
void setCell(int row, int column);
CSMWorld::UniversalId getCurrentId() const;
bool isValidIdCell(int row, int column) const;
};
}
#endif
Loading…
Cancel
Save