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

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

Continued implementation:

  • removed bugs
  • improved features

Programming continues, but quite slow since I've got few time... unfortunately

File size: 5.5 KB
Line 
1#ifndef CARD_H
2#define CARD_H
3
4#include <QBitArray>
5#include <QHash>
6#include <QList>
7#include <QPointer>
8#include <QDebug>
9#include <QUndoStack>
10#include <QFile>
11
12#include <QModelIndex>
13
14namespace QPunchCard {
15        class Column; class Card; class Deck; class DeckIndex;
16};
17
18#include "format.h"
19
20namespace QPunchCard {
21
22/**
23 * A Column is a 12 bit storage...
24 **/
25class Column : public QBitArray {
26public:
27        Column() : QBitArray(13) {}
28
29        Column(int value) : QBitArray(13) {
30                // TODO: range check, throw exception if bad
31                for(int s=0; s<12; s++) {
32                        setBit(s, (1 << s) & value);
33                        //setBit(s, (value >> s) & 0x01);
34                }
35        }
36
37
38        operator int() const {
39                int ret=0;
40                for(int s=0; s<12; s++)
41                        ret |= testBit(s) << s;
42                return ret;
43        }
44};
45
46/**
47 * This is a punch card.
48 **/
49class Card : public QObject {
50        Q_OBJECT // must be qobject for signals/slots and QPointer usage
51
52public:
53        Card() {};
54        QHash<QString,QString> properties;
55
56        Column column[80];
57        Column& get(int x) {
58                if(x < 0 || x > 80)
59                        throw "Out of range exception";
60                return column[x];
61        }
62        const Column& get(int x) const {
63                if(x < 0 || x > 80)
64                        throw "Out of range exception";
65                return column[x];
66        }
67        Column& operator[](int x) { return get(x); }
68        const Column& operator[](int x) const { return column[x]; }
69        int length() const { return 80; } // aja...
70
71        /*Card& operator=(const Card& other) {
72                // copy assignment, etc.
73                for(int x=0; x<80; x++) column[x] = other[x];
74                return *this;
75        }*/
76
77        ~Card() {};
78
79signals:
80        // auf das level will echt keiner runter!
81        void dataChanged(int left_index, int right_index);
82        // wenn signal: klasse muss QObject sein =>
83        //              kein copy constructor möglich =>
84        //              File = QVector<Card*>
85};
86
87
88/**
89 * File uses the strategy pattern to switch between different
90 * I/O formats (using the FileFormat class).
91 **/
92class Deck : public QObject, public QList< QPointer<Card> > {
93        Q_OBJECT
94
95        QPointer<FileFormat> created_format;
96        void init();
97
98public:
99        typedef QList< QPointer<Card> >::iterator iterator;
100        QPointer<QUndoStack> undo;
101
102        // Creation and I/O handling ===================
103        /// Create empty
104        Deck() : QList< QPointer<Card> >() { init(); }
105        ~Deck() {};
106        /// Create from file/stream/etc., that is, calls format->read()
107        Deck(FileFormat* format) : QList< QPointer<Card> >(), created_format(format) { init(); }
108        /// Save with same device/format as created
109        bool save(QFile& file) { return save(created_format, file); }
110        /// Save
111        bool save(FileFormat* format, QFile& file);
112
113        bool canSave() const { return created_format; }
114        void setFormat(FileFormat* format) { created_format = format; } // TODO: was ist mit altem format?
115        //File* getFile() { if(created_format && created_format->file) return created_format->file; }
116
117        bool isModified() const { return !undo->isClean(); }
118
119        // index handling ======================
120        inline bool isValid(int i);
121        inline DeckIndex createIndex(int i);
122
123        // Bearbeitungsfunktionen
124        bool insert(DeckIndex after); // neue Karte hinzufuegen
125        bool move(DeckIndex from, DeckIndex to);
126
127signals:
128        void cardCountChanged(int newCardCount); // wer braucht das?
129
130        // das hier ist das FAVORISIERTE FORMAT:
131        void contentsChanged(DeckIndex lowerCard, DeckIndex upperCard);
132
133
134        void modified(bool modified);
135        //void redoAvailable(bool available);
136        //void undoAvailable(bool available);
137        //void undoCommandAdded();
138
139public slots:
140        //void redo() {}
141        //void undo() {}
142        //void setModified(bool modified) {}
143};
144
145// Java-style iterator
146typedef QListIterator< QPointer<Card> > DeckIterator;
147
148
149/**
150 * CardIndex feels like an int (normalized)
151 **/
152class DeckIndex {
153private:
154        QPointer<Deck> deck;
155        int i;
156public:
157        // behaves like int, copy constructor and operator= will be created automatically
158        DeckIndex(int i = 0) : i(i) {}
159        operator int() const { return normalized(); }
160        int asInt() const { return normalized(); }
161
162        DeckIndex(Deck* d, int i) : deck(d), i(i) { if(!deck) qDebug() << "NULL DECK!"; }
163        bool isValid() const { return deck ? (i >= 0 && i < deck->count()) : false; }
164
165        // "normalisierung" = in Deck Bounds
166        int normalized() const { if(!deck) return i; if(i < 0) return 0; else if(i >= deck->count()) return deck->count()-1; else return i; }
167        void normalize() { i = normalized(); }
168        bool canNormalize() const { return deck; }
169
170        // special positions
171        bool isTop() const { return i < 0; }
172        bool isEnd() const { return i >= deck->count(); }
173        bool isFirst() const { return i == 0; }
174        bool isLast() const { return i == deck->count(); }
175
176        const QPointer<Deck> getDeck() const { return deck; }
177        void setDeck(Deck* deck) { this->deck = deck; }
178        bool assertDeck(Deck* fallback) { if(!deck) deck=fallback; return deck == fallback; }
179        bool hasDeck() const { return deck; }
180
181        // ein paar abkuerzungen
182        /// @returns null wenn nicht normalisierbar (also letztlich kein Deck da ist)
183        QPointer<Card> getCard() const { return canNormalize() ? deck->at(normalized()) : NULL; }
184};
185
186/****************************************************************************
187  debug functions
188 ***************************************************************************/
189
190 QDebug operator<<(QDebug dbg, const Column &c);
191 QDebug operator<<(QDebug dbg, const Card &c);
192 QDebug operator<<(QDebug dbg, const Deck &c);
193 QDebug operator<<(QDebug dbg, const DeckIndex &c);
194
195
196/****************************************************************************
197  inline functions
198 ***************************************************************************/
199
200inline bool Deck::isValid(int i) { return createIndex(i).isValid(); }
201inline DeckIndex Deck::createIndex(int i) { return DeckIndex(this, i); }
202
203
204}; // Namespace
205#endif // CARD_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