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.

161 lines
5.0 KiB

  1. /**
  2. * @file pl_editor_undo_redo.cpp
  3. * @brief page layout editor: undo and redo functions
  4. */
  5. /*
  6. * This program source code file is part of KiCad, a free EDA CAD application.
  7. *
  8. * Copyright (C) 2013 CERN
  9. * @author Jean-Pierre Charras, jp.charras at wanadoo.fr
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License
  13. * as published by the Free Software Foundation; either version 2
  14. * of the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, you may find one here:
  23. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  24. * or you may search the http://www.gnu.org website for the version 2 license,
  25. * or you may write to the Free Software Foundation, Inc.,
  26. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  27. */
  28. #include <fctsys.h>
  29. #include <class_drawpanel.h>
  30. #include <macros.h>
  31. #include <worksheet_shape_builder.h>
  32. #include <pl_editor_frame.h>
  33. /* Note: the Undo/redo commands use a "brute" method:
  34. * the full page layout is converted to a S expression, and saved as string.
  35. * When a previous version is needed, the old string is parsed,
  36. * and the description replaces the current desc, just like reading a new file
  37. *
  38. * This is not optimal from the memory point of view, but:
  39. * - the descriptions are never very long (max few thousand of bytes)
  40. * - this is very easy to code
  41. */
  42. // A helper class used in undo/redo commad:
  43. class PL_ITEM_LAYOUT: public EDA_ITEM
  44. {
  45. public:
  46. wxString m_Layout;
  47. public:
  48. PL_ITEM_LAYOUT() : EDA_ITEM( TYPE_PL_EDITOR_LAYOUT ) {}
  49. // Required to keep compiler happy on debug builds.
  50. #if defined(DEBUG)
  51. virtual void Show( int nestLevel, std::ostream& os ) const override {}
  52. #endif
  53. /** Get class name
  54. * @return string "PL_ITEM_LAYOUT"
  55. */
  56. virtual wxString GetClass() const override
  57. {
  58. return wxT( "PL_ITEM_LAYOUT" );
  59. }
  60. };
  61. void PL_EDITOR_FRAME::SaveCopyInUndoList()
  62. {
  63. PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT;
  64. WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
  65. pglayout.SaveInString( copyItem->m_Layout );
  66. PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
  67. ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
  68. lastcmd->PushItem(wrapper);
  69. GetScreen()->PushCommandToUndoList( lastcmd );
  70. // Clear redo list, because after new save there is no redo to do.
  71. GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
  72. }
  73. /* Redo the last edit:
  74. * - Place the current edited layout in undo list
  75. * - Get previous version of the current edited layput
  76. */
  77. void PL_EDITOR_FRAME::GetLayoutFromRedoList( wxCommandEvent& event )
  78. {
  79. if ( GetScreen()->GetRedoCommandCount() <= 0 )
  80. return;
  81. PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
  82. PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT;
  83. WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
  84. pglayout.SaveInString( copyItem->m_Layout );
  85. ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
  86. lastcmd->PushItem( wrapper );
  87. GetScreen()->PushCommandToUndoList( lastcmd );
  88. lastcmd = GetScreen()->PopCommandFromRedoList();
  89. wrapper = lastcmd->PopItem();
  90. copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() );
  91. pglayout.SetPageLayout( TO_UTF8(copyItem->m_Layout) );
  92. delete copyItem;
  93. OnModify();
  94. RebuildDesignTree();
  95. m_canvas->Refresh();
  96. }
  97. /* Undo the last edit:
  98. * - Place the current layout in Redo list
  99. * - Get previous version of the current edited layout
  100. */
  101. void PL_EDITOR_FRAME::GetLayoutFromUndoList( wxCommandEvent& event )
  102. {
  103. if ( GetScreen()->GetUndoCommandCount() <= 0 )
  104. return;
  105. PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
  106. PL_ITEM_LAYOUT* copyItem = new PL_ITEM_LAYOUT;
  107. WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
  108. pglayout.SaveInString( copyItem->m_Layout );
  109. ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
  110. lastcmd->PushItem( wrapper );
  111. GetScreen()->PushCommandToRedoList( lastcmd );
  112. lastcmd = GetScreen()->PopCommandFromUndoList();
  113. wrapper = lastcmd->PopItem();
  114. copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() );
  115. pglayout.SetPageLayout( TO_UTF8(copyItem->m_Layout) );
  116. delete copyItem;
  117. OnModify();
  118. RebuildDesignTree();
  119. m_canvas->Refresh();
  120. }
  121. /* Remove the last command in Undo List.
  122. * Used to clean the uUndo stack after a cancel command
  123. */
  124. void PL_EDITOR_FRAME::RemoveLastCommandInUndoList()
  125. {
  126. if ( GetScreen()->GetUndoCommandCount() <= 0 )
  127. return;
  128. PICKED_ITEMS_LIST* lastcmd = GetScreen()->PopCommandFromUndoList();
  129. ITEM_PICKER wrapper = lastcmd->PopItem();
  130. PL_ITEM_LAYOUT* copyItem = static_cast<PL_ITEM_LAYOUT*>( wrapper.GetItem() );
  131. delete copyItem;
  132. }