1 /*
2  * Copyright (C) 2002 Brett Viren
3  * Copyright (C) 2006-2015 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2006 Hans Fugal <hans@fugal.net>
5  * Copyright (C) 2007-2009 David Robillard <d@drobilla.net>
6  * Copyright (C) 2013 John Emmas <john@creativepost.co.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (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 along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #ifndef __lib_pbd_undo_h__
24 #define __lib_pbd_undo_h__
25 
26 #include <list>
27 #include <map>
28 #include <string>
29 
30 #include <sigc++/bind.h>
31 #include <sigc++/slot.h>
32 
33 #ifndef COMPILER_MSVC
34 #include <sys/time.h>
35 #else
36 #include <ardourext/misc.h>
37 #endif
38 
39 #include "pbd/command.h"
40 #include "pbd/libpbd_visibility.h"
41 
42 typedef sigc::slot<void> UndoAction;
43 
44 class LIBPBD_API UndoTransaction : public Command
45 {
46 public:
47 	UndoTransaction ();
48 	UndoTransaction (const UndoTransaction&);
49 	UndoTransaction& operator= (const UndoTransaction&);
50 	~UndoTransaction ();
51 
52 	void clear ();
53 	bool empty () const;
clearing()54 	bool clearing () const {
55 		return _clearing;
56 	}
57 
58 	void add_command (Command* const);
59 	void remove_command (Command* const);
60 
61 	void operator() ();
62 	void undo ();
63 	void redo ();
64 
65 	XMLNode& get_state ();
66 
set_timestamp(struct timeval & t)67 	void set_timestamp (struct timeval& t)
68 	{
69 		_timestamp = t;
70 	}
71 
timestamp()72 	const struct timeval& timestamp () const
73 	{
74 		return _timestamp;
75 	}
76 
77 private:
78 	std::list<Command*> actions;
79 	struct timeval      _timestamp;
80 	bool                _clearing;
81 
82 	void about_to_explicitly_delete ();
83 };
84 
85 class LIBPBD_API UndoHistory : public PBD::ScopedConnectionList
86 {
87 public:
88 	UndoHistory ();
~UndoHistory()89 	~UndoHistory () {}
90 
91 	void add (UndoTransaction* ut);
92 	void undo (unsigned int n);
93 	void redo (unsigned int n);
94 
undo_depth()95 	unsigned long undo_depth () const
96 	{
97 		return UndoList.size ();
98 	}
redo_depth()99 	unsigned long redo_depth () const
100 	{
101 		return RedoList.size ();
102 	}
103 
next_undo()104 	std::string next_undo () const
105 	{
106 		return (UndoList.empty () ? std::string () : UndoList.back ()->name ());
107 	}
next_redo()108 	std::string next_redo () const
109 	{
110 		return (RedoList.empty () ? std::string () : RedoList.back ()->name ());
111 	}
112 
113 	void clear ();
114 	void clear_undo ();
115 	void clear_redo ();
116 
117 	/* returns all or part of the history.
118 	 * If depth==0 it returns just the top
119 	 * node. If depth<0, it returns everything.
120 	 * If depth>0, it returns state for that
121 	 * many elements of the history, or
122 	 * the full history, whichever is smaller.
123 	 */
124 
125 	XMLNode& get_state (int32_t depth = 0);
126 	void     save_state ();
127 
128 	void set_depth (uint32_t);
129 
130 	PBD::Signal0<void> Changed;
131 	PBD::Signal0<void> BeginUndoRedo;
132 	PBD::Signal0<void> EndUndoRedo;
133 
134 private:
135 	bool                        _clearing;
136 	uint32_t                    _depth;
137 	std::list<UndoTransaction*> UndoList;
138 	std::list<UndoTransaction*> RedoList;
139 
140 	void remove (UndoTransaction*);
141 };
142 
143 #endif /* __lib_pbd_undo_h__ */
144