/* Copyright (C) 2010-2012 Sérgio Martins 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_P_H #define AKONADI_HISTORY_P_H #include "history.h" #include "incidencechanger.h" #include #include #include #include #include using namespace Akonadi; using namespace KCalCore; namespace Akonadi { class History; enum OperationType { TypeNone, TypeUndo, TypeRedo }; class Entry : public QObject { Q_OBJECT public: typedef QSharedPointer Ptr; typedef QVector List; Entry(const Akonadi::Item &item, const QString &description, History *qq); Entry(const Akonadi::Item::List &items, const QString &description, History *qq); virtual void updateIds(Item::Id oldId, Item::Id newId); void doIt(OperationType); Akonadi::Item::List mItems; QString mDescription; Q_SIGNALS: void finished(Akonadi::IncidenceChanger::ResultCode, const QString &errorString); protected: virtual bool undo() = 0; virtual bool redo() = 0; void updateIdsGlobaly(Item::Id oldId, Item::Id newId); QWidget* currentParent() const; IncidenceChanger *mChanger; QHash mLatestRevisionByItemId; History *q; QVector mChangeIds; private: void init(const QString &description, History *qq); Q_DISABLE_COPY(Entry) }; class History::Private : public QObject { Q_OBJECT public: Private(History *qq); ~Private() {} void doIt(OperationType); void stackEntry(const Entry::Ptr &entry, uint atomicOperationId); void updateIds(Item::Id oldId, Item::Id newId); void finishOperation(int changeId, History::ResultCode, const QString &errorString); QStack& destinationStack(); QStack& stack(OperationType); QStack& stack(); void undoOrRedo(OperationType, QWidget *parent); void emitDone(OperationType, History::ResultCode); void setEnabled(bool enabled); bool isUndoAvailable() const; bool isRedoAvailable() const; int redoCount() const; int undoCount() const; IncidenceChanger *mChanger; QStack mUndoStack; QStack mRedoStack; OperationType mOperationTypeInProgress; Entry::Ptr mEntryInProgress; QString mLastErrorString; bool mUndoAllInProgress; /** * When recordCreation/Deletion/Modification is called and an undo operation is already in progress * the entry is added here. */ QVector mQueuedEntries; bool mEnabled; QPointer mCurrentParent; public Q_SLOTS: void handleFinished(Akonadi::IncidenceChanger::ResultCode, const QString &errorString); private: History *q; }; class CreationEntry : public Entry { Q_OBJECT public: typedef QSharedPointer Ptr; CreationEntry(const Akonadi::Item &item, const QString &description, History *q); /**reimp*/ bool undo(); /** reimp */ bool redo(); private Q_SLOTS: void onDeleteFinished(int changeId, const QVector &deletedIds, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); void onCreateFinished(int changeId, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); private: Q_DISABLE_COPY(CreationEntry) }; class DeletionEntry : public Entry { Q_OBJECT public: DeletionEntry(const Akonadi::Item::List &items, const QString &description, History *q); /**reimp*/ bool undo(); /**reimp*/ bool redo(); private Q_SLOTS: void onDeleteFinished(int changeId, const QVector &deletedIds, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); void onCreateFinished(int changeId, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); private: IncidenceChanger::ResultCode mResultCode; QString mErrorString; QHash mOldIdByChangeId; int mNumPendingCreations; Q_DISABLE_COPY(DeletionEntry) }; class ModificationEntry : public Entry { Q_OBJECT public: ModificationEntry(const Akonadi::Item &item, const Incidence::Ptr &originalPayload, const QString &description, History *q); /**reimp*/ bool undo(); /**reimp*/ bool redo(); private Q_SLOTS: void onModifyFinished(int changeId, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); private: Q_DISABLE_COPY(ModificationEntry) Incidence::Ptr mOriginalPayload; }; class MultiEntry : public Entry { Q_OBJECT public: typedef QSharedPointer Ptr; MultiEntry(int id, const QString &description, History *q); void addEntry(const Entry::Ptr &entry); /** reimp */ void updateIds(Item::Id oldId, Item::Id newId); protected: /**reimp*/ bool undo(); /**reimp*/ bool redo(); private Q_SLOTS: void onEntryFinished(Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); public: const uint mAtomicOperationId; private: Entry::List mEntries; int mFinishedEntries; OperationType mOperationInProgress; Q_DISABLE_COPY(MultiEntry) }; } #endif