File: history.h

package info (click to toggle)
akonadi-calendar 4:18.08.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 3,808 kB
  • sloc: cpp: 14,079; xml: 36; makefile: 8; sh: 4
file content (270 lines) | stat: -rw-r--r-- 9,597 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/*
  Copyright (C) 2010-2012 Sérgio Martins <iamsergio@gmail.com>

  This library is free software; you can redistribute it and/or modify it
  under the terms of the GNU Library General Public License as published by
  the Free Software Foundation; either version 2 of the License, or (at your
  option) any later version.

  This library is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
  License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to the
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  02110-1301, USA.
*/

#ifndef AKONADI_HISTORY_H
#define AKONADI_HISTORY_H

#include "akonadi-calendar_export.h"
#include "incidencechanger.h"

#include <kcalcore/incidence.h>
#include <item.h>
#include <QWidget>

class HistoryTest;

namespace Akonadi
{

class IncidenceChanger;

/**
   @short History class for implementing undo/redo of calendar operations

   Whenever you use IncidenceChanger to create, delete or modify incidences,
   this class is used to record those changes onto a stack, so they can be
   undone or redone.

   If needed, groupware invitations will be sent to attendees and organizers when
   undoing or redoing changes.

   This class can't be instantiated directly, use it through IncidenceChanger:

   @code
      Akonadi::IncidenceChanger *myIncidenceChanger = new Akonadi::IncidenceChanger();
      connect( undoAction, SIGNAL(triggered()), myIncidenceChanger->history(), SLOT(undo()) );
      connect( redoAction, SIGNAL(triggered()), myIncidenceChanger->history(), SLOT(redo()) );
   @endcode

   @author Sérgio Martins <iamsergio@gmail.com>
   @since 4.11
*/

class AKONADI_CALENDAR_EXPORT History : public QObject
{
    Q_OBJECT
public:
    /**
      * This enum describes the possible result codes (success/error values) for an
      * undo or redo operation.
      * @see undone()
      * @see redone()
      */
    enum ResultCode {
        ResultCodeSuccess = 0, ///< Success
        ResultCodeError ///< An error occurred. Call lastErrorString() for the error message. This isn't very verbose because IncidenceChanger hasn't been refactored yet.
    };

    /**
      * Destroys the History instance.
      */
    ~History();

    /**
      * Pushes an incidence creation onto the undo stack. The creation can be
      * undone calling undo().
      *
      * @param item the item that was created. Must be valid and have a Incidence::Ptr payload
      * @param description text that can be used in the undo/redo menu item to describe the operation
      *        If empty, a default one will be provided.
      * @param atomicOperationId if not 0, specifies which group of changes this change belongs to.
      *        When a change is undone/redone, all other changes which are in the same group are also
      *        undone/redone
      */
    void recordCreation(const Akonadi::Item &item,
                        const QString &description,
                        const uint atomicOperationId = 0);

    /**
      * Pushes an incidence modification onto the undo stack. The modification can be undone calling
      * undo().
      *
      * @param oldItem item containing the payload before the change. Must be valid
      *        and contain an Incidence::Ptr payload.
      * @param newItem item containing the new payload. Must be valid and contain
      *        an Incidence::Ptr payload.
      * @param description text that can be used in the undo/redo menu item to describe the operation
      *        If empty, a default one will be provided.
      * @param atomicOperationId if not 0, specifies which group of changes this change belongs to.
      *        When a change is undone/redone, all other changes which are in the same group are also
      *        undone/redone
      */
    void recordModification(const Akonadi::Item &oldItem,
                            const Akonadi::Item &newItem,
                            const QString &description,
                            const uint atomicOperationId = 0);

    /**
      * Pushes an incidence deletion onto the undo stack. The deletion can be
      * undone calling undo().
      *
      * @param item The item to delete. Must be valid, doesn't need to contain a
      *        payload.
      * @param description text that can be used in the undo/redo menu item to describe the operation
      *        If empty, a default one will be provided.
      * @param atomicOperationId if not 0, specifies which group of changes this change belongs to.
      *        When a change is undone/redone, all other changes which are in the same group are also
      *        undone/redone
      */
    void recordDeletion(const Akonadi::Item &item,
                        const QString &description,
                        const uint atomicOperationId = 0);

    /**
      * Pushes a list of incidence deletions onto the undo stack. The deletions can
      * be undone calling undo() once.
      *
      * @param items The list of items to delete. All items must be valid.
      * @param description text that can be used in the undo/redo menu item to describe the operation
      *        If empty, a default one will be provided.
      * @param atomicOperationId If != 0, specifies which group of changes thischange belongs to.
      *        Will be useful for atomic undoing/redoing, not implemented yet.
      */
    void recordDeletions(const Akonadi::Item::List &items,
                         const QString &description,
                         const uint atomicOperationId = 0);

    /**
      * Returns the last error message.
      *
      * Call this immediately after catching the undone()/redone() signal
      * with an ResultCode != ResultCodeSuccess.
      *
      * The message is translated.
      */
    Q_REQUIRED_RESULT QString lastErrorString() const;

    /**
      * Reverts every change in the undo stack.
      *
      * @param parent will be passed to dialogs created by IncidenceChanger,
      *        for example those asking if you want to send invitations.
      */
    void undoAll(QWidget *parent = nullptr);

    /**
      * Returns true if there are changes that can be undone.
      */
    Q_REQUIRED_RESULT bool undoAvailable() const;

    /**
      * Returns true if there are changes that can be redone.
      */
    Q_REQUIRED_RESULT bool redoAvailable() const;

    /**
      * Returns the description of the next undo.
      *
      * This is the description that was passed when calling recordCreation(),
      * recordDeletion() or recordModification().
      *
      * @see nextRedoDescription()
      */
    Q_REQUIRED_RESULT QString nextUndoDescription() const;

    /**
      * Returns the description of the next redo.
      *
      * This is the description that was passed when calling recordCreation(),
      * recordDeletion() or recordModification().
      *
      * @see nextUndoDescription()
      */
    Q_REQUIRED_RESULT QString nextRedoDescription() const;

public Q_SLOTS:
    /**
      * Clears the undo and redo stacks.
      * Won't do anything if there's a undo/redo job currently running.
      *
      * @return true if the stacks were cleared, false if there was a job running
      */
    bool clear();

    /**
      * Reverts the change that's on top of the undo stack.
      * Can't be called if there's an undo/redo operation running, asserts.
      * Can be called if the stack is empty, in this case, nothing happens.
      * This function is async, catch signal undone() to know when the operation
      * finishes.
      *
      * @param parent will be passed to dialogs created by IncidenceChanger,
      *        for example those asking if you want to send invitations.
      *
      * @see redo()
      * @see undone()
      */
    void undo(QWidget *parent = nullptr);

    /**
      * Reverts the change that's on top of the redo stack.
      * Can't be called if there's an undo/redo operation running, asserts.
      * Can be called if the stack is empty, in this case, nothing happens.
      * This function is async, catch signal redone() to know when the operation
      * finishes.
      *
      * @param parent will be passed to dialogs created by IncidenceChanger,
      *        for example those asking if you want to send invitations.
      *
      * @see undo()
      * @see redone()
      */
    void redo(QWidget *parent = nullptr);

Q_SIGNALS:
    /**
      * This signal is emitted when an undo operation finishes.
      * @param resultCode History::ResultCodeSuccess on success.
      * @see lastErrorString()
      */
    void undone(Akonadi::History::ResultCode resultCode);

    /**
      * This signal is emitted when an redo operation finishes.
      * @param resultCode History::ResultCodeSuccess on success.
      * @see lastErrorString()
      */
    void redone(Akonadi::History::ResultCode resultCode);

    /**
      * The redo/undo stacks have changed.
      */
    void changed();

private:

    friend class ::HistoryTest;
    friend class IncidenceChanger;
    friend class Entry;

    // Only IncidenceChanger can create History classes
    explicit History(QObject *parent = nullptr);

    // Used by unit-tests
    Akonadi::IncidenceChanger *incidenceChanger() const;

    //@cond PRIVATE
    class Private;
    Private *const d;
    //@endcond
};

}

#endif