tagtransactionmanager.h 5.65 KB
Newer Older
1
/**
2
 * Copyright (C) 2004, 2017 Michael Pyne <mpyne@kde.org>
3 4 5 6 7 8 9 10 11 12 13 14 15
 *
 * 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.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
16

17 18
#ifndef TAGTRANSACTIONMANAGER_H
#define TAGTRANSACTIONMANAGER_H
19

20
#include <QObject>
21 22 23 24 25

#include <memory>
#include <vector>

#include "tag.h"
26 27 28

class PlaylistItem;
class QWidget;
29
class QFileInfo;
30

31 32
using std::unique_ptr;

33 34 35 36
/**
 * Class to encapsulate a change to the tag, and optionally the file name, of
 * a PlaylistItem.
 *
37
 * @author Michael Pyne <mpyne@kde.org>
38 39
 * @see TagTransactionManager
 */
40
struct TagTransactionAtom
41 42 43 44 45 46
{
    public:
    /**
     * Creates an atom detailing a change made by \p tag to \p item.
     *
     * @param item The PlaylistItem to change.
47
     * @param tag Contains the new tag to apply to item.
48 49 50 51
     */
    TagTransactionAtom(PlaylistItem *item, Tag *tag);

    PlaylistItem *item() const { return m_item; }
52
    const Tag *tag() const { return m_tag.get(); }
53 54

    PlaylistItem *m_item;
55
    unique_ptr<Tag> m_tag;
56 57
};

58 59 60
// Qt's containers don't play well with std::unique_ptr, but being able to use
// unique_ptr avoids a bunch of custom code on my part.
using TagAlterationList = std::vector<TagTransactionAtom>;
61 62 63 64 65 66 67 68 69 70 71

/**
 * 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.
 *
72
 * @author Michael Pyne <mpyne@kde.org>
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
 */
class TagTransactionManager : public QObject
{
    Q_OBJECT

    public:
    /**
     * 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);

    /**
97
     * Convenience function to duplicate a Tag object, since the Tag
98 99 100
     * object doesn't have a decent copy constructor.
     *
     * @param tag The Tag to duplicate.
101
     * @param fileName The filename to assign to the tag.  If an empty QString
102 103 104 105 106
     *        (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.
     */
107
    static Tag *duplicateTag(const Tag *tag, const QString &fileName = QString());
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

    /**
     * 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 QFileInfo with the filename of the original file.
     * @param to QFileInfo with the new filename.
     * @return true if no errors occurred, false otherwise.
     */
    bool renameFile(const QFileInfo &from, const QFileInfo &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
};

171
#endif /* TAGTRANSACTIONMANAGER_H */
172

173
// vim: set et sw=4 tw=0 sta: