You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
5.0 KiB

9 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright 2016-2017 CERN
  5. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  6. * @author Maciej Suminski <maciej.suminski@cern.ch>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. #ifndef __COMMIT_H
  26. #define __COMMIT_H
  27. #include <set>
  28. #include <vector>
  29. #include <undo_redo_container.h>
  30. class EDA_ITEM;
  31. ///> Types of changes
  32. enum CHANGE_TYPE {
  33. CHT_ADD = 1,
  34. CHT_REMOVE = 2,
  35. CHT_MODIFY = 4,
  36. CHT_TYPE = CHT_ADD | CHT_REMOVE | CHT_MODIFY,
  37. ///> Flag to indicate the change is already applied,
  38. ///> just notify observers (not compatible with CHT_MODIFY)
  39. CHT_DONE = 8,
  40. CHT_FLAGS = CHT_DONE
  41. };
  42. template<typename T>
  43. CHANGE_TYPE operator|( CHANGE_TYPE aTypeA, T aTypeB )
  44. {
  45. return CHANGE_TYPE( (int) aTypeA | (int) aTypeB );
  46. }
  47. template<typename T>
  48. CHANGE_TYPE operator&( CHANGE_TYPE aTypeA, T aTypeB )
  49. {
  50. return CHANGE_TYPE( (int) aTypeA & (int) aTypeB );
  51. }
  52. /**
  53. * COMMIT
  54. *
  55. * Represents a set of changes (additions, deletions or modifications)
  56. * of a data model (e.g. the BOARD) class.
  57. *
  58. * The class can be used to propagate changes to subscribed objects (e.g. views, ratsnest),
  59. * and automatically create undo/redo points.
  60. */
  61. class COMMIT
  62. {
  63. public:
  64. COMMIT();
  65. virtual ~COMMIT();
  66. ///> Adds a new item to the model
  67. COMMIT& Add( EDA_ITEM* aItem )
  68. {
  69. return Stage( aItem, CHT_ADD );
  70. }
  71. ///> Notifies observers that aItem has been added
  72. COMMIT& Added( EDA_ITEM* aItem )
  73. {
  74. return Stage( aItem, CHT_ADD | CHT_DONE );
  75. }
  76. ///> Removes a new item from the model
  77. COMMIT& Remove( EDA_ITEM* aItem )
  78. {
  79. return Stage( aItem, CHT_REMOVE );
  80. }
  81. ///> Notifies observers that aItem has been removed
  82. COMMIT& Removed( EDA_ITEM* aItem )
  83. {
  84. return Stage( aItem, CHT_REMOVE | CHT_DONE );
  85. }
  86. ///> Modifies a given item in the model.
  87. ///> Must be called before modification is performed.
  88. COMMIT& Modify( EDA_ITEM* aItem )
  89. {
  90. return Stage( aItem, CHT_MODIFY );
  91. }
  92. ///> Creates an undo entry for an item that has been already modified. Requires a copy done
  93. ///> before the modification.
  94. COMMIT& Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy )
  95. {
  96. return createModified( aItem, aCopy );
  97. }
  98. template<class Range>
  99. COMMIT& StageItems( const Range& aRange, CHANGE_TYPE aChangeType )
  100. {
  101. for( const auto& item : aRange )
  102. Stage( item, aChangeType );
  103. return *this;
  104. }
  105. ///> Adds a change of the item aItem of type aChangeType to the change list.
  106. virtual COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType );
  107. virtual COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType );
  108. virtual COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED );
  109. ///> Executes the changes.
  110. virtual void Push( const wxString& aMessage = wxT( "A commit" ),
  111. bool aCreateUndoEntry = true, bool aSetDirtyBit = true ) = 0;
  112. ///> Revertes the commit by restoring the modifed items state.
  113. virtual void Revert() = 0;
  114. bool Empty() const
  115. {
  116. return m_changes.empty();
  117. }
  118. ///> Returns status of an item.
  119. int GetStatus( EDA_ITEM* aItem );
  120. protected:
  121. struct COMMIT_LINE
  122. {
  123. ///> Main item that is added/deleted/modified
  124. EDA_ITEM* m_item;
  125. ///> Optional copy of the item
  126. EDA_ITEM* m_copy;
  127. ///> Modification type
  128. CHANGE_TYPE m_type;
  129. };
  130. // Should be called in Push() & Revert() methods
  131. void clear()
  132. {
  133. m_changedItems.clear();
  134. m_changes.clear();
  135. }
  136. COMMIT& createModified( EDA_ITEM* aItem, EDA_ITEM* aCopy, int aExtraFlags = 0 );
  137. virtual void makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy = NULL );
  138. /**
  139. * Searches for an entry describing change for a particular item
  140. * @return null if there is no related entry.
  141. */
  142. COMMIT_LINE* findEntry( EDA_ITEM* aItem );
  143. virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const = 0;
  144. CHANGE_TYPE convert( UNDO_REDO_T aType ) const;
  145. std::set<EDA_ITEM*> m_changedItems;
  146. std::vector<COMMIT_LINE> m_changes;
  147. };
  148. #endif