summaryrefslogtreecommitdiffstats
path: root/juk/tagtransactionmanager.h
blob: 7f8ef8d0dfdedfb3901c5fa6be04dd1fb4f1d27e (plain)
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
/***************************************************************************
    begin                : Wed Sep 22 2004
    copyright            : (C) 2004 by Michael Pyne
    email                : michael.pyne@kdemail.net
***************************************************************************/

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

#ifndef _TAGTRANSACTIONMANAGER_H
#define _TAGTRANSACTIONMANAGER_H



class PlaylistItem;
class TQWidget;
class Tag;

/**
 * Class to encapsulate a change to the tag, and optionally the file name, of
 * a PlaylistItem.
 *
 * @author Michael Pyne <michael.pyne@kdemail.net>
 * @see TagTransactionManager
 */
class TagTransactionAtom
{
    public:
    /**
     * Default constructor, for use by TQValueList.
     */
    TagTransactionAtom();

    /**
     * Copy constructor.  This takes ownership of the m_tag pointer, so the
     * object being copied no longer has access to the tag.  This function also
     * exists mainly for QValueList's benefit.
     *
     * @param other The TagTransactionAtom to copy.
     */
    TagTransactionAtom(const TagTransactionAtom &other);

    /**
     * Creates an atom detailing a change made by \p tag to \p item.
     *
     * @param tag Contains the new tag to apply to item.
     * @param item The PlaylistItem to change.
     */
    TagTransactionAtom(PlaylistItem *item, Tag *tag);

    /**
     * Destroys the atom.  This function deletes the tag, so make sure you've
     * already copied out any data you need.  The PlaylistItem is unaffected.
     */
    ~TagTransactionAtom();

    /**
     * Assignment operator.  This operator takes ownership of the m_tag pointer,
     * so the object being assigned from no longer has access to the tag.  This
     * function exists mainly for the benefit of TQValueList.
     *
     * @param other The TagTransactionAtom to copy from.
     * @return The TagTransactionAtom being assigned to.
     */
    TagTransactionAtom &operator=(const TagTransactionAtom &other);

    /**
     * Accessor function to retrieve the PlaylistItem.
     *
     * @return The PlaylistItem being changed.
     */
    PlaylistItem *item() const { return m_item; }

    /**
     * Accessor function to retrieve the changed Tag.
     *
     * @return The Tag containing the changes to apply to item().
     */
    Tag *tag() const { return m_tag; }

    private:
    PlaylistItem *m_item;
    mutable Tag *m_tag;
};

typedef TQValueList<TagTransactionAtom> TagAlterationList;

/**
 * This class manages alterations of a group of PlaylistItem's FileHandles.  What this
 * means in practice is that you will use this class to change the tags and/or
 * filename of a PlaylistItem.
 *
 * This class supports a limited transactional interface.  Once you commit a
 * group of changes, you can call the undo() method to revert back to the way
 * things were (except possibly for file renames).  You can call forget() to
 * forget a series of changes as well.
 *
 * @author Michael Pyne <michael.pyne@kdemail.net>
 */
class TagTransactionManager : public QObject
{
    Q_OBJECT

    public:
    /**
     * Constructs a TagTransactionManager, owned by @p parent.
     *
     * @param parent The parent TQWidget.
     */
    TagTransactionManager(TQWidget *parent = 0);

    /**
     * Returns the global TagTransactionManager instance.
     *
     * @return The global TagTransactionManager.
     */
    static TagTransactionManager *instance();

    /**
     * Adds a change to the list of changes to apply.  Internally this
     * function extracts the CollectionListItem of @p item, and uses that
     * instead, so there is no need to do so yourself.
     *
     * @param item The PlaylistItem to change.
     * @param newTag The Tag containing the changed data.
     */
    void changeTagOnItem(PlaylistItem *item, Tag *newTag);

    /**
     * Convienience function to duplicate a Tag object, since the Tag
     * object doesn't have a decent copy constructor.
     *
     * @param tag The Tag to duplicate.
     * @param fileName The filename to assign to the tag.  If TQString::null
     *        (the default) is passed, the filename of the existing tag is
     *        used.
     * @bug Tag should have a correct copy ctor and assignment operator.
     * @return The duplicate Tag.
     */
    static Tag *duplicateTag(const Tag *tag, const TQString &fileName = TQString::null);

    /**
     * Commits the changes to the PlaylistItems.  It is important that the
     * PlaylistItems still exist when you call this function, although this
     * shouldn't be a problem in practice.  After altering the tags, and
     * renaming the files if necessary, you can call undo() to back out the
     * changes.
     *
     * If any errors have occurred, the user will be notified with a dialog
     * box, and those files which were unabled to be altered will be excluded
     * from the undo set.
     *
     * @return true if no errors occurred, false otherwise.
     */
    bool commit();

    /**
     * Clears the current update list.  The current undo list is unaffected.
     */
    void forget();

    /**
     * Undoes the changes caused by commit().  Like commit(), if any errors
     * occur changing the state back (for example, it may be impossible to
     * rename a file back to its original name), the user will be shown notified
     * via a dialog box.
     *
     * After performing the undo operation, it is impossible to call undo()
     * again on the same set of files.  Namely, you can't repeatedly call
     * undo() to switch between two different file states.
     *
     * @return true if no errors occurred, false otherwise.
     */
    bool undo();

    signals:
    void signalAboutToModifyTags();
    void signalDoneModifyingTags();

    private:
    /**
     * Renames the file identified by @p from to have the name given by @p to,
     * prompting the user to confirm if necessary.
     *
     * @param from TQFileInfo with the filename of the original file.
     * @param to TQFileInfo with the new filename.
     * @return true if no errors occurred, false otherwise.
     */
    bool renameFile(const TQFileInfo &from, const TQFileInfo &to) const;

    /**
     * Used internally by commit() and undo().  Performs the work of updating
     * the PlaylistItems and then updating the various GUI elements that need
     * to be updated.
     *
     * @param undo true if operating in undo mode, false otherwise.
     */
    bool processChangeList(bool undo = false);

    TagAlterationList m_list; ///< holds a list of changes to commit
    TagAlterationList m_undoList; ///< holds a list of changes to undo
    static TagTransactionManager *m_manager; ///< used by instance()
};

#endif /* _TAGTRANSACTIONMANAGER_H */

// vim: set et ts=4 sw=4 tw=0: