Skip to content
Permalink
Browse files

Implmeneted redo/undo in cards

  • Loading branch information...
dimkanovikov committed Nov 3, 2016
1 parent 8ccbeae commit 42f49c9405ddffbbfa77b699f1ae72aa44f7a5d2
Showing with 371 additions and 121 deletions.
  1. BIN ...nal Draft templates/Classic TV Templates/fd8_Jam-and-Jerusalem-aka-Clatterford-(UK).fdxt.zip.part
  2. +49 −13 src/bin/scenarist-core/3rd_party/Widgets/ActivityEdit/gui/activityedit.cpp
  3. +15 −0 src/bin/scenarist-core/3rd_party/Widgets/ActivityEdit/gui/activityedit.h
  4. +1 −8 src/bin/scenarist-core/3rd_party/Widgets/ActivityEdit/scene/customgraphicsscene.cpp
  5. +3 −3 src/bin/scenarist-core/3rd_party/Widgets/ActivityEdit/scene/customgraphicsscene.h
  6. +57 −7 src/bin/scenarist-core/3rd_party/Widgets/ActivityEdit/scene/sceneundostack.cpp
  7. +24 −4 src/bin/scenarist-core/3rd_party/Widgets/ActivityEdit/scene/sceneundostack.h
  8. BIN src/bin/scenarist-core/Resources/Images/corkboard.jpg
  9. +4 −14 src/bin/scenarist-core/UserInterfaceLayer/ScenarioTextEdit/ScenarioTextEdit.cpp
  10. +8 −7 src/bin/scenarist-core/UserInterfaceLayer/ScenarioTextEdit/ScenarioTextEdit.h
  11. +18 −0 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioCardsManager.cpp
  12. +25 −0 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioCardsManager.h
  13. +34 −7 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioManager.cpp
  14. +10 −0 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioManager.h
  15. +2 −2 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioNavigatorManager.cpp
  16. +2 −2 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioNavigatorManager.h
  17. +2 −10 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioTextEditManager.cpp
  18. +2 −12 src/bin/scenarist-desktop/ManagementLayer/Scenario/ScenarioTextEditManager.h
  19. +60 −1 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioCards/ScenarioCardsView.cpp
  20. +30 −0 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioCards/ScenarioCardsView.h
  21. +2 −2 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioNavigator/ScenarioNavigator.cpp
  22. +2 −2 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioNavigator/ScenarioNavigator.h
  23. +2 −2 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioTextEdit/ScenarioReviewView.cpp
  24. +2 −2 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioTextEdit/ScenarioReviewView.h
  25. +8 −14 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioTextEdit/ScenarioTextEditWidget.cpp
  26. +9 −9 src/bin/scenarist-desktop/UserInterfaceLayer/Scenario/ScenarioTextEdit/ScenarioTextEditWidget.h
Binary file not shown.
@@ -61,7 +61,6 @@ ActivityEdit::ActivityEdit(QWidget *parent) :
connect(m_view, &CustomGraphicsView::contextMenuRequest, this, &ActivityEdit::showContextMenu);

connect(scene, &CustomGraphicsScene::stateChangedByUser, [=] {
m_undoStack->addState(scene->toXML());
emit schemeChanged();
});

@@ -101,29 +100,35 @@ void ActivityEdit::clear()
m_undoStack->clear();
}

bool ActivityEdit::needSyncUndo() const
{
return m_undoStack->needSyncUndo();
}

void ActivityEdit::undo()
{
if (m_undoStack->canUndo()) {
CustomGraphicsScene* scene = dynamic_cast<CustomGraphicsScene*>(m_view->scene());
if (!m_undoStack->canRedo()) {
m_undoStack->addState(scene->toXML());
m_undoStack->undo();
}
scene->fromXML(m_undoStack->undo(), scene);

if (m_undoStack->canUndo()) {
if (CustomGraphicsScene* scene = dynamic_cast<CustomGraphicsScene*>(m_view->scene())) {
scene->removeAllShapes();
load(m_undoStack->undo());
emit schemeChanged();
}
}
}

bool ActivityEdit::needSyncRedo() const
{
return m_undoStack->needSyncRedo();
}

void ActivityEdit::redo()
{
if (m_undoStack->canRedo()) {
CustomGraphicsScene* scene = dynamic_cast<CustomGraphicsScene*>(m_view->scene());
scene->fromXML(m_undoStack->redo(), scene);

emit schemeChanged();
if (CustomGraphicsScene* scene = dynamic_cast<CustomGraphicsScene*>(m_view->scene())) {
scene->removeAllShapes();
load(m_undoStack->redo());
emit schemeChanged();
}
}
}

@@ -132,6 +137,37 @@ QString ActivityEdit::save() const
return createSceneXml(m_view->scene(), m_view);
}

void ActivityEdit::saveChanges(bool _hasChangesInText)
{
if (CustomGraphicsScene* scene = dynamic_cast<CustomGraphicsScene*>(m_view->scene())) {
const QString xml = scene->toXML();

//
// Если есть изменения сцены
//
if (m_undoStack->hasChanges(xml)) {
//
// ... то добавляем состояние в стек
//
m_undoStack->addState(xml, _hasChangesInText);
}
//
// А если изменений сцены нет
//
else {
//
// ... но есть изменения текста
//
if (_hasChangesInText) {
//
// ... очищаем стэк отмены действий, т.к. мы не предоставляем отмены действий для случаев, когда был изменён текст сценария
//
m_undoStack->clear();
}
}
}
}

void ActivityEdit::load(const QString& _xml)
{
loadSceneXml(_xml, m_view->scene(), m_view);
@@ -34,11 +34,21 @@ class ActivityEdit : public QFrame
*/
void clear();

/**
* @brief Нужно ли синхрозировать отмену действия с текстом
*/
bool needSyncUndo() const;

/**
* @brief Отменить последнее действие
*/
void undo();

/**
* @brief Нужно ли синхрозировать повтор действия с текстом
*/
bool needSyncRedo() const;

/**
* @brief Повторить последнее действие
*/
@@ -49,6 +59,11 @@ class ActivityEdit : public QFrame
*/
QString save() const;

/**
* @brief Сохранить изменения схемы
*/
void saveChanges(bool _hasChangesInText);

/**
* @brief Загрузить схему из XMl-строки
*/
@@ -517,14 +517,7 @@ void CustomGraphicsScene::notifyStateChangeByUser()

QString CustomGraphicsScene::toXML()
{
return createSceneXml(this, (this->views().count()==0? NULL : this->views()[0]));
}

CustomGraphicsScene *CustomGraphicsScene::fromXML (const QString &xml, CustomGraphicsScene *scene)
{
scene->removeAllShapes();
loadSceneXml(xml, scene);
return scene;
return createSceneXml(this, (views().count() == 0 ? nullptr : views().first()));
}

QList<Shape *> CustomGraphicsScene::selectedShapes()
@@ -24,9 +24,9 @@ class CustomGraphicsScene : public QGraphicsScene
Q_OBJECT

public:
/// Загружает сцену из XML
static CustomGraphicsScene *fromXML (const QString &xml, CustomGraphicsScene *scene);
/// Возвращает сцену, преобразованную в XML-формат
/**
* @brief Возвращает сцену, преобразованную в XML-формат
*/
QString toXML();

public:
@@ -1,20 +1,36 @@
#include "sceneundostack.h"

namespace {
/**
* @brief Точка в истории, которой ещё нет
*/
const int START_HISTORY_INDEX = -1;
}


SceneUndoStack::SceneUndoStack() :
m_historyIndex(0)
m_historyIndex(START_HISTORY_INDEX)
{
}

bool SceneUndoStack::canUndo()
{
if (m_historyIndex > 0 && !m_history.isEmpty()) {
if (m_historyIndex > 0) {
return true;
}

return false;
}

bool SceneUndoStack::needSyncUndo()
{
if (canUndo()) {
return m_historyNeedSync[m_historyIndex];
}

return false;
}

bool SceneUndoStack::canRedo()
{
if (m_historyIndex < m_history.count() - 1) {
@@ -24,6 +40,15 @@ bool SceneUndoStack::canRedo()
return false;
}

bool SceneUndoStack::needSyncRedo()
{
if (canRedo()) {
return m_historyNeedSync[m_historyIndex + 1];
}

return false;
}


QString SceneUndoStack::undo()
{
@@ -48,19 +73,44 @@ QString SceneUndoStack::redo()
void SceneUndoStack::clear()
{
m_history.clear();
m_historyIndex = 0;
m_historyNeedSync.clear();
m_historyIndex = START_HISTORY_INDEX;
}

void SceneUndoStack::addState (const QString& _data)
void SceneUndoStack::addState(const QString& _data, bool _needSync)
{
while (m_history.count() > m_historyIndex) {
m_history.removeAt(m_historyIndex);
//
// +1 т.к. нужно сохранить текущее состояние
//
const int indexToRemove = m_historyIndex + 1;
while (m_history.count() > indexToRemove) {
m_history.removeAt(indexToRemove);
m_historyNeedSync.removeAt(indexToRemove);
}

m_history << qCompress(_data.toUtf8());
m_historyNeedSync << _needSync;

++m_historyIndex;
}

bool SceneUndoStack::hasChanges(const QString& _data)
{
//
// Сравниваем сжатые массивы, так быстрее
//
if (!m_history.isEmpty()) {
return m_history[m_historyIndex] != qCompress(_data.toUtf8());
}

return true;
}

QString SceneUndoStack::currentState()
{
return qUncompress(m_history[m_historyIndex]);
if (!m_history.isEmpty()) {
return qUncompress(m_history[m_historyIndex]);
}

return QString::null;
}
@@ -1,7 +1,8 @@
#ifndef SCENEUNDOSTACK_H
#define SCENEUNDOSTACK_H

#include <QString>
#include <QList>
#include <QVector>


/**
@@ -23,11 +24,21 @@ class SceneUndoStack
*/
bool canUndo();

/**
* @brief Нужно ли синхронизировать отмену с текстом сценария
*/
bool needSyncUndo();

/**
* @brief Можно повторить?
*/
bool canRedo();

/**
* @brief Нужно ли синхронизировать повтор с текстом сценария
*/
bool needSyncRedo();

/**
* @brief Отменить (перейти к предыдущему состоянию)
*/
@@ -46,9 +57,13 @@ class SceneUndoStack
/**
* @brief Добавить изменение в историю
* Состояние представляет собой XML-строку, полученную в CustomGraphicsScene::toXML().
* Все повторы, которые расположены за текущим состоянием, будут уничтожены.
*/
void addState(const QString& _data);
void addState(const QString& _data, bool _needSync);

/**
* @brief Изменилась ли схема по сравнению с текущим состоянием
*/
bool hasChanges(const QString& _data);

private:
/**
@@ -60,7 +75,12 @@ class SceneUndoStack
/**
* @brief История изменений
*/
QList<QByteArray> m_history;
QVector<QByteArray> m_history;

/**
* @brief Нужно ли синхронизировать изменения с текстом сценария
*/
QVector<bool> m_historyNeedSync;

/**
* @brief Текущее положение в истории изменений
Binary file not shown.
@@ -412,11 +412,11 @@ QMenu* ScenarioTextEdit::createContextMenu(const QPoint& _pos, QWidget* _parent)
foreach (QAction* menuAction, menu->findChildren<QAction*>()) {
if (menuAction->text().endsWith(QKeySequence(QKeySequence::Undo).toString(QKeySequence::NativeText))) {
menuAction->disconnect();
connect(menuAction, SIGNAL(triggered()), this, SLOT(undoReimpl()));
connect(menuAction, &QAction::triggered, this, &ScenarioTextEdit::undoRequest);
menuAction->setEnabled(m_document->isUndoAvailableReimpl());
} else if (menuAction->text().endsWith(QKeySequence(QKeySequence::Redo).toString(QKeySequence::NativeText))) {
menuAction->disconnect();
connect(menuAction, SIGNAL(triggered()), this, SLOT(redoReimpl()));
connect(menuAction, &QAction::triggered, this, &ScenarioTextEdit::redoRequest);
menuAction->setEnabled(m_document->isRedoAvailableReimpl());
}
}
@@ -469,16 +469,6 @@ void ScenarioTextEdit::setAdditionalCursors(const QMap<QString, int>& _cursors)
}
}

void ScenarioTextEdit::undoReimpl()
{
m_document->undoReimpl();
}

void ScenarioTextEdit::redoReimpl()
{
m_document->redoReimpl();
}

void ScenarioTextEdit::keyPressEvent(QKeyEvent* _event)
{
//
@@ -496,10 +486,10 @@ void ScenarioTextEdit::keyPressEvent(QKeyEvent* _event)
if (_event == QKeySequence::Undo
|| _event == QKeySequence::Redo) {
if (_event == QKeySequence::Undo) {
undoReimpl();
emit undoRequest();
}
else if (_event == QKeySequence::Redo) {
redoReimpl();
emit redoRequest();
}
_event->accept();
return;
@@ -139,16 +139,17 @@ namespace UserInterface
*/
void setAdditionalCursors(const QMap<QString, int>& _cursors);

public slots:
signals:
/**
* @brief Собственные реализации отмены/повтора последнего действия
* @brief Запрос на отмену последнего действия
*/
/** @{ */
void undoReimpl();
void redoReimpl();
/** @} */
void undoRequest();

/**
* @brief Запрос на повтор последнего действия
*/
void redoRequest();

signals:
/**
* @brief Сменился стиль под курсором
*/

0 comments on commit 42f49c9

Please sign in to comment.
You can’t perform that action at this time.