source: projects/punch-card/punch-card-editor/src/qpunchcard/deck.h @ 52

Last change on this file since 52 was 52, checked in by sven, 10 years ago

Punch Card Editor: Code reordering and class renaming, rewriting.
Now using the namespace QPunchCard everywhere.

Parted the whole application into 5 parts/directories:

  • app: The application core with MainWindow and main() function
  • qpunchcard: Everything directly binary card related (no interpretation): modeling, input/output, view. Most important classes are Card, Deck, FileFormat, Widget
  • text: Everything related to text interpretation of Cards/Card Decks. Having the abstract Codec classes and the Text::Editor, Text::EditorDock
  • deckviewer: Application components like binary card editing central widget (CardEditor) and Navigator (Model View Controller classes)
  • driver: Basis for the driver framework, must be written soon.

Deck now hides the complete Storage to implement frontend methods that
implement versioning (Undo framework). All code was cleaned up, but doesn't
compile right now (still quite some non heavy errors).

-- Sven @ workstation

File size: 5.9 KB
Line 
1#ifndef DECK_H
2#define DECK_H
3
4#include <QList>
5#include <QSharedPointer>
6#include <QFile>
7#include <QUndoCommand>
8
9namespace QPunchCard {
10        class Deck;
11        class DeckIndex;
12
13        class DeckAppendCard;
14        class DeckModifyCard;
15        // usw.
16}
17
18#include "qpunchcard/card.h"
19#include "qpunchcard/format.h"
20
21namespace QPunchCard {
22
23/**
24 * File uses the strategy pattern to switch between different
25 * I/O formats (using the FileFormat class).
26 **/
27class Deck : public QObject {
28        Q_OBJECT
29
30        QSharedPointer<const FileFormat> format;
31        QList< Card > cards;
32        QSharedPointer< QFile > file;
33        //QPointer<QUndoStack> undo_stack;
34        QUndoStack undo_stack;
35        friend class FileFormat;
36        friend class DeckIndex;
37        friend class DeckAppendCard;
38        friend class DeckModifyCard;
39
40        void init();
41
42public:
43        //typedef QList< QPointer<Card> >::iterator iterator;
44
45        // =========== Constructors ==================
46        /// Create empty
47        Deck(QObject* parent = 0);
48        ~Deck() {};
49        /// Create from file/stream/etc., that is, calls format->read()
50        Deck(const FileFormat* format, QObject* parent = 0);
51
52        // =========== Loading and Saving, File Format Handling ==================
53        // (All Functions are just Shorthands for other direct public method calls)
54        bool save();
55        bool save(QFile& file);
56        bool save(const FileFormat* format, QFile& file);
57        bool read();
58        bool read(QFile& file);
59        bool read(const FileFormat* format, QFile& file);
60
61        bool canRead() const { return hasFile() && hasFormat(); }
62        bool canSave() const { return canRead(); }
63        bool hasFormat() const { return format; }
64        void setFormat(const FileFormat* format);
65        bool hasFile() const { return file; }
66        void setFile(QFile* file);
67
68        // =========== Undo Framework ==================
69        bool isModified() const { return !undo_stack.isClean(); }
70
71        // =========== Index Handling, reading access to cards ==================
72        bool isValid(int i);
73        DeckIndex createIndex(int i);
74        int count() const { return cards.count(); }
75        int length() const { return count(); }
76        int size() const { return count(); }
77        bool empty() const { return cards.empty(); }
78        const Card& at(int i) const { return cards.at(i); }
79
80public:
81        // =========== Editing (Undo captured) ==================
82        /// Insert one new card
83        bool insert(DeckIndex after);
84        /// Insert `times` empty cards after DeckIndex
85        bool insertTimes(DeckIndex after, int times = 1);
86        /// Move card from `from` to `to`
87        bool move(DeckIndex from, DeckIndex to);
88        /// Removes all items from `from` to `to`
89        bool erase(DeckIndex from, DeckIndex to);
90        /// Append a card
91        void append(Card card = Card());
92        void push_back(Card card) { append(card); }
93
94        // Quick & dirty, no official standard
95        inline void emitChanged(DeckIndex lower, DeckIndex upper);
96
97signals:
98        // =========== The fully official signals ==================
99
100        // wer brauchts?
101        void cardCountChanged(int newCardCount); // wer braucht das?
102
103        // das hier ist das FAVORISIERTE FORMAT:
104        void contentsChanged(DeckIndex lowerCard, DeckIndex upperCard);
105
106
107        void modified(bool modified);
108        //void redoAvailable(bool available);
109        //void undoAvailable(bool available);
110        //void undoCommandAdded();
111
112public slots:
113        void redo() { undo_stack.redo(); }
114        void undo() { undo_stack.undo(); }
115        //void setModified(bool modified) {}
116};
117
118// Java-style iterator
119//typedef QListIterator< QPointer<Card> > DeckIterator;
120
121
122/**
123 * CardIndex feels like an int (normalized)
124 **/
125class DeckIndex {
126private:
127        QPointer<Deck> deck;
128        int i;
129public:
130        // behaves like int, copy constructor and operator= will be created automatically
131        DeckIndex(int i = 0) : i(i) {}
132        operator int() const { return normalized(); }
133        int asInt() const { return normalized(); }
134
135        DeckIndex(Deck* d, int i) : deck(d), i(i) { if(!deck) qDebug() << "NULL DECK!"; }
136        bool isValid() const { return deck ? (i >= 0 && i < deck->count()) : false; }
137
138        // "normalisierung" = in Deck Bounds
139        int normalized() const { if(!deck) return i; if(i < 0) return 0; else if(i >= deck->count()) return deck->count()-1; else return i; }
140        void normalize() { i = normalized(); }
141        bool canNormalize() const { return deck; }
142
143        // special positions
144        bool isTop() const { return i < 0; }
145        bool isEnd() const { return i >= deck->count(); }
146        bool isFirst() const { return i == 0; }
147        bool isLast() const { return i == deck->count(); }
148
149        const QPointer<Deck> getDeck() const { return deck; }
150        void setDeck(Deck* deck) { this->deck = deck; }
151        bool assertDeck(Deck* fallback) { if(!deck) deck=fallback; return deck == fallback; }
152        bool hasDeck() const { return deck; }
153
154        // ein paar abkuerzungen
155        /// @returns null wenn nicht normalisierbar (also letztlich kein Deck da ist)
156        // QPointer geht nicht (mehr) weil Card jetzt kein QObject mehr ist
157        const Card* getCard() const { return canNormalize() ? &(deck->cards.at(normalized())) : NULL; }
158        // das wird crashen. *UNGUT*
159        //const Card& getCard() const { return canNormalize() ? deck->cards.at(normalized()) : Card(); }
160
161        DeckIndex& operator++() { i++; return *this; }
162        DeckIndex& operator+=(int x) { i+= x; return *this; }
163};
164
165/**
166 * Lauter schoene UndoCommands
167 **/
168class DeckAppendCard : public QUndoCommand {
169public:
170        DeckAppendCard(Deck* deck, Card* card, QUndoCommand* parent = 0) : QUndoCommand(parent) {
171                this->deck = deck;
172                this->card = card;
173                setText(deck->tr("Adding card to deck"));
174        }
175        void undo() { deck->cards.removeLast(); }
176        void redo() { deck->cards.push_back(*card); }
177private:
178        Deck* deck;
179        Card* card;
180};
181
182class DeckModifyCard : public QUndoCommand {
183public:
184        DeckModifyCard(DeckIndex& position, Card new_content, QUndoCommand* parent=0)
185                        : QUndoCommand(parent), position(position), new_content(new_content) {
186                // alten Inhalt irgendwie sichern
187                old_content = *position.getCard();
188                setText(position.getDeck()->tr("Changed contents of card").arg(position));
189        }
190        void undo() { position.getDeck()->cards[position] = old_content; }
191        void redo() { position.getDeck()->cards[position] = new_content; }
192private:
193        DeckIndex position;
194        Card new_content;
195        Card old_content;
196};
197
198// usw.
199
200QDebug operator<<(QDebug dbg, const Deck &c);
201QDebug operator<<(QDebug dbg, const DeckIndex &c);
202
203}; // namespace
204
205#endif /* DECK_H */
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License