1 #ifndef CSM_WOLRD_COMMANDS_H 2 #define CSM_WOLRD_COMMANDS_H 3 4 #include "record.hpp" 5 6 #include <string> 7 #include <map> 8 #include <memory> 9 #include <vector> 10 11 #include <QVariant> 12 #include <QUndoCommand> 13 #include <QModelIndex> 14 15 #include "columnimp.hpp" 16 #include "universalid.hpp" 17 #include "nestedtablewrapper.hpp" 18 19 class QModelIndex; 20 class QAbstractItemModel; 21 22 namespace CSMWorld 23 { 24 class IdTable; 25 class IdTree; 26 struct RecordBase; 27 struct NestedTableWrapperBase; 28 29 class TouchCommand : public QUndoCommand 30 { 31 public: 32 33 TouchCommand(IdTable& model, const std::string& id, QUndoCommand* parent=nullptr); 34 35 void redo() override; 36 void undo() override; 37 38 private: 39 40 IdTable& mTable; 41 std::string mId; 42 std::unique_ptr<RecordBase> mOld; 43 44 bool mChanged; 45 }; 46 47 /// \brief Adds LandTexture records and modifies texture indices as needed. 48 /// 49 /// LandTexture records are different from other types of records, because 50 /// they only effect the current plugin. Thus, when modifying or copying 51 /// a Land record, all of the LandTexture records referenced need to be 52 /// added to the current plugin. Since these newly added LandTextures could 53 /// have indices that conflict with pre-existing LandTextures in the current 54 /// plugin, the indices might have to be changed, both for the newly added 55 /// LandRecord and within the Land record. 56 class ImportLandTexturesCommand : public QUndoCommand 57 { 58 public: 59 60 ImportLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, 61 QUndoCommand* parent); 62 63 void redo() override; 64 void undo() override; 65 66 protected: 67 68 using DataType = LandTexturesColumn::DataType; 69 70 virtual const std::string& getOriginId() const = 0; 71 virtual const std::string& getDestinationId() const = 0; 72 73 virtual void onRedo() = 0; 74 virtual void onUndo() = 0; 75 76 IdTable& mLands; 77 IdTable& mLtexs; 78 DataType mOld; 79 int mOldState; 80 std::vector<std::string> mCreatedTextures; 81 }; 82 83 /// \brief This command is used to fix LandTexture records and texture 84 /// indices after cloning a Land. See ImportLandTexturesCommand for 85 /// details. 86 class CopyLandTexturesCommand : public ImportLandTexturesCommand 87 { 88 public: 89 90 CopyLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, const std::string& origin, 91 const std::string& dest, QUndoCommand* parent = nullptr); 92 93 private: 94 95 const std::string& getOriginId() const override; 96 const std::string& getDestinationId() const override; 97 onRedo()98 void onRedo() override {} onUndo()99 void onUndo() override {} 100 101 std::string mOriginId; 102 std::string mDestId; 103 }; 104 105 /// \brief This command brings a land record into the current plugin, adding 106 /// LandTexture records and modifying texture indices as needed. 107 /// \note See ImportLandTextures for more details. 108 class TouchLandCommand : public ImportLandTexturesCommand 109 { 110 public: 111 112 TouchLandCommand(IdTable& landTable, IdTable& ltexTable, 113 const std::string& id, QUndoCommand* parent = nullptr); 114 115 private: 116 117 const std::string& getOriginId() const override; 118 const std::string& getDestinationId() const override; 119 120 void onRedo() override; 121 void onUndo() override; 122 123 std::string mId; 124 std::unique_ptr<RecordBase> mOld; 125 126 bool mChanged; 127 }; 128 129 class ModifyCommand : public QUndoCommand 130 { 131 QAbstractItemModel *mModel; 132 QModelIndex mIndex; 133 QVariant mNew; 134 QVariant mOld; 135 136 bool mHasRecordState; 137 QModelIndex mRecordStateIndex; 138 CSMWorld::RecordBase::State mOldRecordState; 139 140 public: 141 142 ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, 143 QUndoCommand *parent = nullptr); 144 145 void redo() override; 146 147 void undo() override; 148 }; 149 150 class CreateCommand : public QUndoCommand 151 { 152 std::map<int, QVariant> mValues; 153 std::map<int, std::pair<int, QVariant> > mNestedValues; 154 ///< Parameter order: a parent column, a nested column, a data. 155 ///< A nested row has index of 0. 156 157 protected: 158 159 IdTable& mModel; 160 std::string mId; 161 UniversalId::Type mType; 162 163 protected: 164 165 /// Apply modifications set via addValue. 166 void applyModifications(); 167 168 public: 169 170 CreateCommand (IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); 171 172 void setType (UniversalId::Type type); 173 174 void addValue (int column, const QVariant& value); 175 176 void addNestedValue(int parentColumn, int nestedColumn, const QVariant &value); 177 178 void redo() override; 179 180 void undo() override; 181 }; 182 183 class CloneCommand : public CreateCommand 184 { 185 std::string mIdOrigin; 186 std::vector<std::pair<int, QVariant>> mOverrideValues; 187 188 public: 189 190 CloneCommand (IdTable& model, const std::string& idOrigin, 191 const std::string& IdDestination, 192 const UniversalId::Type type, 193 QUndoCommand* parent = nullptr); 194 195 void redo() override; 196 197 void undo() override; 198 199 void setOverrideValue(int column, QVariant value); 200 }; 201 202 class RevertCommand : public QUndoCommand 203 { 204 IdTable& mModel; 205 std::string mId; 206 RecordBase *mOld; 207 208 // not implemented 209 RevertCommand (const RevertCommand&); 210 RevertCommand& operator= (const RevertCommand&); 211 212 public: 213 214 RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); 215 216 virtual ~RevertCommand(); 217 218 void redo() override; 219 220 void undo() override; 221 }; 222 223 class DeleteCommand : public QUndoCommand 224 { 225 IdTable& mModel; 226 std::string mId; 227 RecordBase *mOld; 228 UniversalId::Type mType; 229 230 // not implemented 231 DeleteCommand (const DeleteCommand&); 232 DeleteCommand& operator= (const DeleteCommand&); 233 234 public: 235 236 DeleteCommand (IdTable& model, const std::string& id, 237 UniversalId::Type type = UniversalId::Type_None, QUndoCommand *parent = nullptr); 238 239 virtual ~DeleteCommand(); 240 241 void redo() override; 242 243 void undo() override; 244 }; 245 246 class ReorderRowsCommand : public QUndoCommand 247 { 248 IdTable& mModel; 249 int mBaseIndex; 250 std::vector<int> mNewOrder; 251 252 public: 253 254 ReorderRowsCommand (IdTable& model, int baseIndex, const std::vector<int>& newOrder); 255 256 void redo() override; 257 258 void undo() override; 259 }; 260 261 class CreatePathgridCommand : public CreateCommand 262 { 263 public: 264 265 CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); 266 267 void redo() override; 268 }; 269 270 /// \brief Update cell ID according to x/y-coordinates 271 /// 272 /// \note The new value will be calculated in the first call to redo instead of the 273 /// constructor to accommodate multiple coordinate-affecting commands being executed 274 /// in a macro. 275 class UpdateCellCommand : public QUndoCommand 276 { 277 IdTable& mModel; 278 int mRow; 279 QModelIndex mIndex; 280 QVariant mNew; // invalid, if new cell ID has not been calculated yet 281 QVariant mOld; 282 283 public: 284 285 UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent = nullptr); 286 287 void redo() override; 288 289 void undo() override; 290 }; 291 292 293 class NestedTableStoring 294 { 295 NestedTableWrapperBase* mOld; 296 297 public: 298 NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn); 299 300 ~NestedTableStoring(); 301 302 protected: 303 304 const NestedTableWrapperBase& getOld() const; 305 }; 306 307 class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring 308 { 309 IdTree& mModel; 310 311 std::string mId; 312 313 int mParentColumn; 314 315 int mNestedRow; 316 317 // The command to redo/undo the Modified status of a record 318 ModifyCommand *mModifyParentCommand; 319 320 public: 321 322 DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); 323 324 void redo() override; 325 326 void undo() override; 327 }; 328 329 class AddNestedCommand : public QUndoCommand, private NestedTableStoring 330 { 331 IdTree& mModel; 332 333 std::string mId; 334 335 int mNewRow; 336 337 int mParentColumn; 338 339 // The command to redo/undo the Modified status of a record 340 ModifyCommand *mModifyParentCommand; 341 342 public: 343 344 AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); 345 346 void redo() override; 347 348 void undo() override; 349 }; 350 } 351 352 #endif 353