source: projects/punch-card/punch-card-editor/src/app/editorwindow.cc @ 44

Last change on this file since 44 was 44, checked in by sven, 14 years ago

Import of the Punch Card Editor Project.
This is a C++/Qt project (using qmake) that I've started this weekend.
Of course it's supposed to be released as open source.

I've tried to start with a clean (but now still empty, of course)
directory structure. There will come the sourcecode for a complete
AVR ATmega microcontroller punch card device controller, soon.
I'm planing to finish this editing program and to implement the
communication protocol (over TTY, using some platform indepentent library).
Unfortunately that will take some time (and I don't have much time
any more...)

-- Sven @ workstation

File size: 11.8 KB
Line 
1#include "editorwindow.h"
2#include "qpunchcard/card.h"
3#include "qpunchcard/widget.h"
4#include "qpunchcard/deckmodel.h"
5
6#include <QApplication>
7#include <QLabel>
8#include <QtDebug>
9#include <QListView>
10#include <QDockWidget>
11#include <QHBoxLayout>
12#include <QPushButton>
13#include <QMessageBox>
14#include <QFileDialog>
15#include <QFileInfo>
16
17using namespace QPunchCard;
18
19EditorWindow::EditorWindow() {
20        // sehr praktisch:
21        setAttribute(Qt::WA_DeleteOnClose, true);
22
23        // etwas kartenmaterial besorgen
24        /*
25        Card* foo = new Card;
26        foo->column[0] = 12;
27        foo->column[9] = 78;
28        foo->column[12][0] = true;
29        foo->column[12][9] = true;
30
31        deck = new Deck;
32        deck->push_back(foo);
33
34        for(int x = 0; x < 10; x++) {
35                Card* c = new Card;
36                c->column[x] = x;
37                deck->push_back(c);
38        }
39        */
40
41        deck = new Deck();
42
43        graphical_editor = new CardEditor(this);
44        graphical_editor->createToolbar();
45        setCentralWidget(graphical_editor);
46        // signale und so:
47        connect(graphical_editor, SIGNAL(cardSelected(int)), this, SLOT(setCard(int)));
48        connect(this, SIGNAL(cardSelected(int)), graphical_editor, SLOT(setCard(int)));
49
50        createActions();
51        createMenus();
52        createToolBars();
53        createStatusBar();
54        createDockWindows();
55
56        // Titel einrichten und so
57        connect(this, SIGNAL(fileOpened(bool)), this, SLOT(window_update_on_file_state(bool)));
58        // und jetzt:
59
60        emit fileOpened(true);
61}
62
63void EditorWindow::window_update_on_file_state(bool opened) {
64        if(opened) {
65                // titel setzen
66                setWindowFilePath(QFileInfo(file).filePath());
67                setWindowTitle(tr("%1[*] - %2").arg(
68                        file.fileName().isEmpty() ? tr("New Card Deck") : file.fileName()
69                        ).arg(tr("Punch Card Editor")));
70                // Modified-Stern ([*]) verbinden
71                connect(deck, SIGNAL(modified(bool)), this, SLOT(setWindowModified(bool)));
72        } else {
73                setWindowTitle(tr("Punch Card Editor"));
74                // passiert folgendes nicht sowieso automatisch?
75                disconnect(this, SLOT(setWindowModified(bool)));
76        }
77}
78
79bool EditorWindow::maybeSave() {
80        if(!deck->isModified())
81                return true;
82        if(deck->empty()) // oder sowas in der Art -- eine leere Lochkarte oder so
83                return true;
84        switch(QMessageBox::warning(this, tr("Punch Card Editor"),
85                tr("The document has been modified.\nDo you want to save your changes?"),
86                QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)) {
87
88                case QMessageBox::Save:
89                        return saveFile();
90                case QMessageBox::Cancel:
91                        return false; // aborted the whole thing
92                default:
93                        return true; // discard the file
94        }
95}
96
97void EditorWindow::newWindow() {
98        // einfacher gehts nicht:
99        new EditorWindow();
100}
101
102void EditorWindow::closeDeck() {
103        qDebug() << "Emitting closing file...";
104        emit fileOpened(false);
105        qDebug() << "Deleting deck.";
106        delete deck; // jaha! :-)
107}
108
109void EditorWindow::loadDeck(const QString& filename) {
110        // load a new deck from a file. There can still be an old deck open,
111        // this method will close it when everything went good
112        QFile file(filename);
113        FileFormat* format = autoDetectFileFormat(file);
114        Deck* new_deck = new Deck(format);
115        // Leser anschmeissen
116        if( format->read(file) ) {
117                statusBar()->showMessage(QString(tr("Deck read in successfully")), 4000);
118        } else
119                qDebug() << "Errors while reading in the Deck.";
120        // Alte Datei rausschmeissen
121        closeDeck();
122        // Neue setzen
123        deck = new_deck;
124        this->file.setFileName( file.fileName() );
125        emit fileOpened(true);
126        emit setCard(0);
127}
128
129void EditorWindow::newFile() {
130        if(maybeSave()) {
131                // alte Datei schliessen.
132                // d.h. defakto: Deck loeschen, neues erstellen.
133                // und dann alle darueber informieren. Sehr kompliziert.
134                closeDeck();
135                deck = new Deck();
136                emit fileOpened(true);
137                emit setCard(0);
138        }
139}
140
141void EditorWindow::openFile() {
142        if(maybeSave()) {
143                // Oeffnen-Dialog anzeigen.
144                QString filename = QFileDialog::getOpenFileName(this,
145                        tr("Open Card Deck File..."),
146                        QFileInfo(file).absolutePath(),
147                        tr("Jones Emulated Card Decks (*);;Card Editor XML-Files (*.xml *.cml)"));
148                if(!filename.isEmpty()) {
149                        loadDeck(filename);
150                }
151        }
152}
153
154bool EditorWindow::saveFile() {
155        if(!file.exists() || !deck->canSave())
156                return saveFileAs();
157        else
158                return deck->save(file);
159}
160
161bool EditorWindow::saveFileAs() {
162        // GUI anzeigen zum Speichern
163        QString filename = QFileDialog::getSaveFileName(this,
164                tr("Save Card Deck File..."),
165                QFileInfo(file).absolutePath(),
166                tr("Jones Emulator Card Decks (*);;Card Editor XML-Files (*.xml *.cml)"));
167        if(filename.isEmpty())
168                return false;
169        // Eigentlich jetzt: Nachschauen, welches Dateiformat zum Benutzen und so.
170        // stattdessen jetzt mal billig:
171        file.setFileName(filename);
172        if(deck->canSave()) {
173                // Nutze das bekannte Dateiformat
174                return deck->save(file);
175        } else {
176                // Nutze einfach mal
177                deck->setFormat( new JonesFileFormat );
178                return deck->save(file);
179        }
180}
181
182void EditorWindow::exportText() {
183        // Strategie: In die text_editors-Liste schauen, wenn nur ein Editor
184        // drin ist, ist der zu nutzende Codec klar definiert. Sonst fragen,
185        // welchen Codec benutzen.
186        // Dann abspeichern oder so... hier waere natuerlich auch interessant,
187        // auf bestehende Dateinamen zurueckgreifen zu koennen...
188}
189
190void EditorWindow::exportPicture() {
191        // das haupteditorwidget bzw. nach Auswahl alle/bestimmte Karten als PNG/SVG/...
192        // rendern.
193}
194
195void EditorWindow::closeFile() {
196        if(maybeSave()) {
197                // Deck schliessen und fertig.
198                closeDeck();
199        }
200}
201
202void EditorWindow::quit() {
203        if(maybeSave()) {
204                // Deck schliesst automatisch ;-)
205                qApp->quit();
206        }
207}
208
209void EditorWindow::closeEvent(QCloseEvent* event) {
210        if(maybeSave()) {
211                event->accept();
212        } else
213                event->ignore();
214}
215
216void EditorWindow::help() {
217
218}
219
220void EditorWindow::about() {
221        QMessageBox::about(this, tr("About the Punch Card Editor"),
222                tr("<big><b>Punch Card Editor</b></big><br>Development version"
223                   "<br>This application is GPLv3 licensed"
224                   "<br>Copyright Sven Koeppel"));
225}
226
227void EditorWindow::newTextEditor() {
228        TextEditorDock* editor = new TextEditorDock(this);
229        addDockWidget(Qt::BottomDockWidgetArea, editor);
230        view_menu->addAction(editor->toggleViewAction());
231        text_editors.push_back(editor);
232
233        // Signale anschalten:
234        connect(editor->editor, SIGNAL(cursorRowChanged(int)), this, SLOT(setCard(int)));
235        connect(this, SIGNAL(cardSelected(int)), editor->editor, SLOT(highlightRow(int)));
236        connect(this, SIGNAL(fileOpened(bool)), editor, SLOT(setVisible(bool)));
237        // TODO: klaeren, wer den Texteditor irgendwann mal killt
238        // -- ist diese Liste wirklich noetig? (ggf. *ja* wegen Textexport)
239}
240
241void EditorWindow::nextCard() {
242        setCard( getCurrentCard() + 1);
243}
244
245void EditorWindow::prevCard() {
246        setCard( getCurrentCard() - 1);
247}
248
249void EditorWindow::setCard(int i) {
250        // wenn keine Datei offen und so
251        if(!deck) return;
252        if(i < 0) i = 0;
253        if(i >= deck->count()) i = deck->count() - 1;
254
255        // neue current Card setzen:
256        current_card = i;
257
258        // Signal weitergeben:
259        emit cardSelected(i);
260}
261
262void EditorWindow::createActions() {
263        new_file_action = new QAction(tr("&New File (Empty Card Deck)"), this);
264        new_file_action->setShortcuts(QKeySequence::New);
265        new_file_action->setStatusTip(tr("Create a new empty card deck"));
266        connect(new_file_action, SIGNAL(triggered()), this, SLOT(newFile()));
267
268        new_window_action = new QAction(tr("&New Window"), this);
269        new_window_action->setStatusTip(tr("Open a new Application window to edit two card decks concurrently"));
270        connect(new_window_action, SIGNAL(triggered()), this, SLOT(newWindow()));
271
272        open_file_action = new QAction(tr("&Open File..."), this);
273        open_file_action->setShortcuts(QKeySequence::Open);
274        open_file_action->setStatusTip(tr("Open existing card file (any card deck file or text file)"));
275        connect(open_file_action, SIGNAL(triggered()), this, SLOT(openFile()));
276
277        save_file_action = new QAction(tr("&Save File"), this);
278        save_file_action->setShortcuts(QKeySequence::Save);
279        save_file_action->setStatusTip(tr("Save the current file as card deck"));
280        connect(save_file_action, SIGNAL(triggered()), this, SLOT(saveFile()));
281
282        save_file_as_action = new QAction(tr("&Save File as..."), this);
283        save_file_as_action->setShortcuts(QKeySequence::SaveAs);
284        save_file_as_action->setStatusTip(tr("Save the current card deck as another file"));
285        connect(save_file_as_action, SIGNAL(triggered()), this, SLOT(saveFileAs()));
286
287        export_text_action = new QAction(tr("&Export Text..."), this);
288        export_text_action->setStatusTip(tr("Save the decoded plaintext of the current card deck"));
289        connect(export_text_action, SIGNAL(triggered()), this, SLOT(exportText()));
290
291        export_picture_action = new QAction(tr("&Export Picture of Card..."), this);
292        export_picture_action->setStatusTip(tr("Save the visualisation of one or more cards as a picture"));
293        connect(export_picture_action, SIGNAL(triggered()), this, SLOT(exportPicture()));
294
295        close_file_action = new QAction(tr("&Close File"), this);
296        close_file_action->setStatusTip(tr("Close current file while staying in the application"));
297        connect(close_file_action, SIGNAL(triggered()), this, SLOT(closeFile()));
298
299        quit_action = new QAction(tr("&Quit"), this);
300        quit_action->setStatusTip(tr("Quit Application"));
301        connect(quit_action, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
302
303        help_action = new QAction(tr("&Help"), this);
304        help_action->setStatusTip(tr("Get Help about the usage of this program"));
305        connect(help_action, SIGNAL(triggered()), this, SLOT(help()));
306
307        about_action = new QAction(tr("&About"), this);
308        about_action->setStatusTip(tr("Display some information about the author and program version"));
309        connect(about_action, SIGNAL(triggered()), this, SLOT(about()));
310
311        new_text_editor_action = new QAction(tr("Open new &Text editor"), this);
312        new_text_editor_action->setStatusTip(tr("Display another text editor for editing the dock using a card code"));
313
314        undo_action = new QAction(tr("&Undo"), this);
315        redo_action = new QAction(tr("&Redo"), this);
316        undo_action->setStatusTip(tr("Undo latest changes"));
317        redo_action->setStatusTip(tr("Redo latest changes"));
318        // mehr Signale erst beim oeffnen/schliessen einer Datei
319}
320
321void EditorWindow::createMenus() {
322        file_menu = menuBar()->addMenu(tr("&File"));
323        file_menu->addAction(new_file_action);
324        file_menu->addSeparator();
325        file_menu->addAction(open_file_action);
326        file_menu->addAction(save_file_action);
327        file_menu->addAction(save_file_as_action);
328        file_menu->addSeparator();
329        file_menu->addAction(export_text_action);
330        file_menu->addAction(export_picture_action);
331        file_menu->addSeparator();
332        file_menu->addAction(close_file_action);
333        file_menu->addAction(quit_action);
334
335        edit_menu = menuBar()->addMenu(tr("&Edit"));
336        edit_menu->addAction(undo_action);
337        edit_menu->addAction(redo_action);
338        edit_menu->addSeparator();
339        // ---
340        // Cut, Copy, Insert
341        // --
342        // Insert punch card
343        // usw.
344
345        view_menu = menuBar()->addMenu(tr("&View"));
346        view_menu->addAction(new_text_editor_action);
347        view_menu->addSeparator();
348        // Ansichten:
349        // - Neue Textansicht hinzufuegen
350        // - Eigenschaften der Lochkarten-Ansicht hinzufuegen
351        // - Visualisierungsansicht aendern und so (Qualitaet)
352        // Navigation
353        // - Vor/Zurueck bei Lochkarte oder Spalte (letzteres doof)
354
355        devices_menu = menuBar()->addMenu(tr("&Devices"));
356        // hier alle Geraete auflisten, fuer die es Treiber gibt (=> driver, DriverOverview oder so)
357
358        help_menu = menuBar()->addMenu(tr("&Help"));
359        help_menu->addAction(help_action);
360        help_menu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt()));
361        help_menu->addAction(about_action);
362}
363
364void EditorWindow::createToolBars() {
365        // ja ne... waere momentan noch das gleiche wie die Menus, also
366        // schon irgendwie iditisch.
367
368
369
370}
371
372void EditorWindow::createStatusBar() {
373        statusBar()->showMessage(tr("Ready"));
374}
375
376void EditorWindow::createDockWindows() {
377        // Kartenuebersicht:
378        navigator = new Navigator(this);
379        addDockWidget(Qt::LeftDockWidgetArea, navigator);
380        view_menu->addAction(navigator->toggleViewAction());
381        // Beim Klick auf Karte alle Views aktualisieren
382        connect(navigator, SIGNAL(cardSelected(int)), this, SLOT(setCard(int)));
383        connect(this, SIGNAL(cardSelected(int)), navigator, SLOT(setCard(int)));
384        connect(this, SIGNAL(fileOpened(bool)), navigator, SLOT(setVisible(bool)));
385}
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