#ifndef CSV_WORLD_DIALOGUESUBVIEW_H #define CSV_WORLD_DIALOGUESUBVIEW_H #include #include #include #include #include #include #include #include #include #ifndef Q_MOC_RUN #include "../doc/subview.hpp" #include "../../model/world/columnbase.hpp" #include "../../model/world/commanddispatcher.hpp" #include "../../model/world/universalid.hpp" #endif class QAbstractItemModel; class QAction; class QDataWidgetMapper; class QMenu; class QModelIndex; class QPainter; class QPoint; class QSize; class QVBoxLayout; class QWidget; namespace CSMWorld { class IdTable; class NestedTableProxyModel; } namespace CSMPrefs { class Setting; } namespace CSMDoc { class Document; } namespace CSVWorld { class CommandDelegate; class CreatorFactoryBase; class TableBottomBox; class NotEditableSubDelegate : public QAbstractItemDelegate { const CSMWorld::IdTable* mTable; public: NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject* parent = nullptr); void setEditorData(QWidget* editor, const QModelIndex& index) const override; void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; class DialogueDelegateDispatcherProxy : public QObject { Q_OBJECT QWidget* mEditor; CSMWorld::ColumnBase::Display mDisplay; std::optional mIndex; public: DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display); QWidget* getEditor() const; public slots: void editorDataCommited(); void setIndex(const QModelIndex& index); signals: void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); }; class DialogueDelegateDispatcher : public QAbstractItemDelegate { Q_OBJECT std::map mDelegates; QObject* mParent; QAbstractItemModel* mTable; CSMWorld::CommandDispatcher& mCommandDispatcher; CSMDoc::Document& mDocument; NotEditableSubDelegate mNotEditableDelegate; std::vector mProxys; // once we move to the C++11 we should use unique_ptr public: DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, QAbstractItemModel* model = nullptr); ~DialogueDelegateDispatcher(); CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display); QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index); ///< will return null if delegate is not present, parent of the widget is // same as for dispatcher itself void setEditorData(QWidget* editor, const QModelIndex& index) const override; void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing private slots: void editorDataCommited(QWidget* editor, const QModelIndex& index, 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 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 QDataWidgetMapper* mWidgetMapper; QDataWidgetMapper* mNestedTableMapper; DialogueDelegateDispatcher* mDispatcher; DialogueDelegateDispatcher* mNestedTableDispatcher; QWidget* mMainWidget; CSMWorld::IdTable* mTable; CSMWorld::CommandDispatcher& mCommandDispatcher; CSMDoc::Document& mDocument; std::vector 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, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete = false); virtual ~EditWidget(); void remake(int row); signals: void editIdRequest(const CSMWorld::UniversalId& id, const std::string& hint); }; class SimpleDialogueSubView : public CSVDoc::SubView { Q_OBJECT EditWidget* mEditWidget; QVBoxLayout* mMainLayout; CSMWorld::IdTable* mTable; bool mLocked; const CSMDoc::Document& mDocument; CSMWorld::CommandDispatcher mCommandDispatcher; protected: QVBoxLayout& getMainLayout(); CSMWorld::IdTable& getTable(); CSMWorld::CommandDispatcher& getCommandDispatcher(); EditWidget& getEditWidget(); void updateCurrentId(); bool isLocked() const; public: SimpleDialogueSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); void setEditLock(bool locked) override; private slots: void dataChanged(const QModelIndex& index); ///\brief we need to care for deleting currently edited record void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); }; class RecordButtonBar; class DialogueSubView : public SimpleDialogueSubView { Q_OBJECT TableBottomBox* mBottom; RecordButtonBar* mButtons; private: void addButtonBar(); public: DialogueSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting = false); void setEditLock(bool locked) override; private slots: void settingChanged(const CSMPrefs::Setting* setting); void showPreview(); void viewRecord(); void switchToRow(int row); void requestFocus(const std::string& id); }; } #endif