1 #ifndef CSV_WORLD_UTIL_H
2 #define CSV_WORLD_UTIL_H
3 
4 #include <map>
5 
6 #include <QAbstractTableModel>
7 #include <QStyledItemDelegate>
8 
9 
10 #ifndef Q_MOC_RUN
11 #include "../../model/world/columnbase.hpp"
12 #include "../../model/doc/document.hpp"
13 #endif
14 
15 class QUndoStack;
16 
17 namespace CSMWorld
18 {
19     class TableMimeData;
20     class UniversalId;
21     class CommandDispatcher;
22 }
23 
24 namespace CSMPrefs
25 {
26     class Setting;
27 }
28 
29 namespace CSVWorld
30 {
31     ///< \brief Getting the data out of an editor widget
32     ///
33     /// Really, Qt? Really?
34     class NastyTableModelHack : public QAbstractTableModel
35     {
36             QAbstractItemModel& mModel;
37             QVariant mData;
38 
39         public:
40 
41             NastyTableModelHack (QAbstractItemModel& model);
42 
43             int rowCount (const QModelIndex & parent = QModelIndex()) const override;
44 
45             int columnCount (const QModelIndex & parent = QModelIndex()) const override;
46 
47             QVariant data  (const QModelIndex & index, int role = Qt::DisplayRole) const override;
48 
49             bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
50 
51             QVariant getData() const;
52     };
53 
54     class CommandDelegate;
55 
56     class CommandDelegateFactory
57     {
58         public:
59 
60             virtual ~CommandDelegateFactory();
61 
62             virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher,
63                 CSMDoc::Document& document, QObject *parent)
64                 const = 0;
65             ///< The ownership of the returned CommandDelegate is transferred to the caller.
66     };
67 
68     class CommandDelegateFactoryCollection
69     {
70             static CommandDelegateFactoryCollection *sThis;
71             std::map<CSMWorld::ColumnBase::Display, CommandDelegateFactory *> mFactories;
72 
73         private:
74 
75             // not implemented
76             CommandDelegateFactoryCollection (const CommandDelegateFactoryCollection&);
77             CommandDelegateFactoryCollection& operator= (const CommandDelegateFactoryCollection&);
78 
79         public:
80 
81             CommandDelegateFactoryCollection();
82 
83             ~CommandDelegateFactoryCollection();
84 
85             void add (CSMWorld::ColumnBase::Display display, CommandDelegateFactory *factory);
86             ///< The ownership of \a factory is transferred to *this.
87             ///
88             /// This function must not be called more than once per value of \a display.
89 
90             CommandDelegate *makeDelegate (CSMWorld::ColumnBase::Display display,
91                 CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document,
92                 QObject *parent) const;
93             ///< The ownership of the returned CommandDelegate is transferred to the caller.
94             ///
95             /// If no factory is registered for \a display, a CommandDelegate will be returned.
96 
97             static const CommandDelegateFactoryCollection& get();
98 
99     };
100 
101     ///< \brief Use commands instead of manipulating the model directly
102     class CommandDelegate : public QStyledItemDelegate
103     {
104             Q_OBJECT
105 
106             bool mEditLock;
107             CSMWorld::CommandDispatcher *mCommandDispatcher;
108             CSMDoc::Document& mDocument;
109 
110         protected:
111 
112             QUndoStack& getUndoStack() const;
113 
114             CSMDoc::Document& getDocument() const;
115 
116             CSMWorld::ColumnBase::Display getDisplayTypeFromIndex(const QModelIndex &index) const;
117 
118             virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model,
119                 const QModelIndex& index) const;
120 
121         public:
122 
123             /// \param commandDispatcher If CommandDelegate will be only be used on read-only
124             /// cells, a 0-pointer can be passed here.
125             CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, CSMDoc::Document& document, QObject *parent);
126 
127             void setModelData (QWidget *editor, QAbstractItemModel *model,
128                 const QModelIndex& index) const override;
129 
130             QWidget *createEditor (QWidget *parent,
131                                            const QStyleOptionViewItem& option,
132                                            const QModelIndex& index) const override;
133 
134             virtual QWidget *createEditor (QWidget *parent,
135                                            const QStyleOptionViewItem& option,
136                                            const QModelIndex& index,
137                                            CSMWorld::ColumnBase::Display display) const;
138 
139             void setEditLock (bool locked);
140 
141             bool isEditLocked() const;
142 
143             ///< \return Does column require update?
144 
145             void setEditorData (QWidget *editor, const QModelIndex& index) const override;
146 
147             virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const;
148 
149             /// \attention This is not a slot. For ordering reasons this function needs to be
150             /// called manually from the parent object's settingChanged function.
151             virtual void settingChanged (const CSMPrefs::Setting *setting);
152     };
153 }
154 
155 #endif
156