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
cellcreator referenceablecreator referencecreator scenesubview
infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable
dialoguespinbox recordbuttonbar
dialoguespinbox recordbuttonbar tableeditidaction
)
opencs_units_noqt (view/world

@ -19,6 +19,7 @@
#include <QComboBox>
#include <QHeaderView>
#include <QScrollBar>
#include <QMenu>
#include "../../model/world/nestedtableproxymodel.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=====================================================
*/
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()
{
for (unsigned i = 0; i < mNestedModels.size(); ++i)
@ -455,6 +587,11 @@ void CSVWorld::EditWidget::remake(int row)
tablesLayout->addWidget(label);
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))
{
@ -488,6 +625,8 @@ void CSVWorld::EditWidget::remake(int row)
editor->setEnabled(false);
label->setEnabled(false);
}
createEditorContextMenu(editor, display, row);
}
}
else
@ -539,6 +678,8 @@ void CSVWorld::EditWidget::remake(int row)
editor->setEnabled(false);
label->setEnabled(false);
}
createEditorContextMenu(editor, display, row);
}
}
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);
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)

@ -1,6 +1,7 @@
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
#define CSV_WORLD_DIALOGUESUBVIEW_H
#include <set>
#include <map>
#include <memory>
@ -11,12 +12,14 @@
#include "../../model/world/columnbase.hpp"
#include "../../model/world/commanddispatcher.hpp"
#include "../../model/world/universalid.hpp"
class QDataWidgetMapper;
class QSize;
class QEvent;
class QLabel;
class QVBoxLayout;
class QMenu;
namespace CSMWorld
{
@ -149,6 +152,36 @@ namespace CSVWorld
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
{
Q_OBJECT
@ -162,6 +195,9 @@ namespace CSVWorld
CSMDoc::Document& mDocument;
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:
EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table,
@ -171,6 +207,9 @@ namespace CSVWorld
virtual ~EditWidget();
void remake(int row);
signals:
void editIdRequest(const CSMWorld::UniversalId &id, const std::string &hint);
};
class SimpleDialogueSubView : public CSVDoc::SubView

@ -1,15 +1,18 @@
#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 <QContextMenuEvent>
#include <QMenu>
#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,
CSMWorld::UniversalId id,
CSMWorld::NestedTableProxyModel* model,
@ -55,6 +58,9 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
connect(mRemoveRowAction, SIGNAL(triggered()),
this, SLOT(removeRowActionTriggered()));
mEditIdAction = new TableEditIdAction(*this, this);
connect(mEditIdAction, SIGNAL(triggered()), this, SLOT(editCell()));
}
std::vector<CSMWorld::UniversalId> CSVWorld::NestedTable::getDraggedRecords() const
@ -69,6 +75,15 @@ void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event)
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)
menu.addAction(mRemoveRowAction);
@ -92,3 +107,8 @@ void CSVWorld::NestedTable::addNewRowActionTriggered()
selectionModel()->selectedRows().size(),
mModel->getParentColumn()));
}
void CSVWorld::NestedTable::editCell()
{
emit editRequest(mEditIdAction->getCurrentId(), "");
}

@ -22,12 +22,15 @@ namespace CSMDoc
namespace CSVWorld
{
class TableEditIdAction;
class NestedTable : public DragRecordTable
{
Q_OBJECT
QAction *mAddNewRowAction;
QAction *mRemoveRowAction;
TableEditIdAction *mEditIdAction;
CSMWorld::NestedTableProxyModel* mModel;
CSMWorld::CommandDispatcher *mDispatcher;
@ -46,6 +49,11 @@ namespace CSVWorld
void removeRowActionTriggered();
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 "recordstatusdelegate.hpp"
#include "tableeditidaction.hpp"
#include "util.hpp"
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
int currentRow = rowAt(event->y());
int currentColumn = columnAt(event->x());
if (mEditIdAction->isValidIdCell(currentRow, currentColumn))
{
// Request UniversalId editing from table columns.
int currRow = rowAt( event->y() ),
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() );
}
mEditIdAction->setCell(currentRow, currentColumn);
menu.addAction(mEditIdAction);
menu.addSeparator();
}
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()));
addAction (mMoveDownAction);
mEditCellAction = new QAction( tr("Edit Cell"), this );
connect( mEditCellAction, SIGNAL(triggered()), this, SLOT(editCell()) );
addAction( mEditCellAction );
mViewAction = new QAction (tr ("View"), this);
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
addAction (mViewAction);
@ -387,6 +364,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
connect (mExtendedRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedRevert()));
addAction (mExtendedRevertAction);
mEditIdAction = new TableEditIdAction (*this, this);
connect (mEditIdAction, SIGNAL (triggered()), this, SLOT (editCell()));
addAction (mEditIdAction);
connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (tableSizeUpdate()));
@ -522,7 +503,7 @@ void CSVWorld::Table::moveDownRecord()
void CSVWorld::Table::editCell()
{
emit editRequest( mEditCellId, std::string() );
emit editRequest(mEditIdAction->getCurrentId(), "");
}
void CSVWorld::Table::viewRecord()

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