пятница, 17 февраля 2012 г.

Qt. Функционал Undo/Redo для QTableWidget

Решил поделиться своей реализацией функционала Отмена/Повтор для приложения, использующего несколько QTableWidget-ов.
undoredotable.h
#ifndef UNDOREDOTABLE_H
#define UNDOREDOTABLE_H

#include <QVector>
#include <QString>
#include <QTableWidget>

class UndoRedoTable {

public:

    UndoRedoTable(QTableWidget *);
    virtual ~UndoRedoTable();

    void saveState();
    void undoTable();
    void redoTable();
    ptrdiff_t undoTableNumber() const;
    ptrdiff_t redoTableNumber() const;
    void freeMemory();

private:

    QTableWidget *table;
    QVector< QVector< QVector<QString> > > data;
    ptrdiff_t position;

};

#endif /* UNDOREDOTABLE_H */
undoredotable.cpp
#include "undoredotable.h"
#include "tablewidgetfunctions.h"

#include <QVector>
#include <QString>
#include <QTableWidget>

UndoRedoTable::UndoRedoTable(QTableWidget *tbl) :
    position(-1) {

    table = tbl;
}

UndoRedoTable::~UndoRedoTable() {
}

void UndoRedoTable::saveState() {

    if ( (data.count() - position) > 1 ) {

        for ( ptrdiff_t i=(data.count()-1); i>position; i-- ) {

            data.remove(i);
        }
    }

    QVector<QString> row;
    QVector< QVector<QString> > matrix;

    for ( ptrdiff_t i=0; i<table->rowCount(); i++ ) {

        for ( ptrdiff_t j=0; j<table->columnCount(); j++ ) {

            row.push_back(table->item(i, j)->text());
        }

        matrix.push_back(row);
        row.clear();
    }

    data.push_back(matrix);
    matrix.clear();

    position++;
}

void UndoRedoTable::undoTable() {

    position--;

    if ( table->rowCount() < data[position].count() ) {

        addRows(table, data[position].count());
    }
    else if ( table->rowCount() > data[position].count() ) {

        table->setRowCount(data[position].count());
    }

    for ( ptrdiff_t i=0; i<data[position].count(); i++ ) {

        for ( ptrdiff_t j=0; j<data[position][i].count(); j++ ) {

            table->item(i, j)->setText(data[position][i][j]);
        }
    }
}

void UndoRedoTable::redoTable() {

    position++;
    position++;

    undoTable();
}

ptrdiff_t UndoRedoTable::undoTableNumber() const {

    return position;
}

ptrdiff_t UndoRedoTable::redoTableNumber() const {

    return data.count() - position - 1;
}

void UndoRedoTable::freeMemory() {

    data.clear();
}

Комментариев нет:

Отправить комментарий