comparison examples/mainwindows/sdi/mainwindow.d @ 269:cc9080066035

sdi example added. Thanks to jaddison.
author eldar
date Sun, 20 Sep 2009 10:23:48 +0000
parents
children 5df570e79cfc
comparison
equal deleted inserted replaced
268:cf6a4cd0e3f2 269:cc9080066035
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial Usage
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Nokia.
14 **
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at http://www.qtsoftware.com/contact.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /****************************************************************************
43 **
44 ** Translated from Qt/C++ to QtD/D by Jason Addison
45 ** Date: 2009 09 13
46 ** Contact: jraddison@gmail.com
47 **
48 ****************************************************************************/
49
50
51 import qt.gui.QMainWindow;
52 import qt.gui.QAction;
53 import qt.gui.QMenu;
54 import qt.gui.QTextEdit;
55 import qt.gui.QFileDialog;
56 import qt.gui.QMessageBox;
57 import qt.core.QSettings;
58 import qt.core.QTextStream;
59
60 version(Tango)
61 {
62 import tango.text.Util;
63 import Int = tango.text.convert.Integer;
64 }
65 else
66 {
67 import std.string;
68 import std.conv;
69 }
70 class MainWindow : public QMainWindow
71 {
72 // Q_OBJECT
73
74 public:
75 this()
76 {
77 init();
78 setCurrentFile("");
79 }
80
81 this(string fileName)
82 {
83 init();
84 loadFile(fileName);
85 }
86
87 protected:
88
89 void closeEvent(QCloseEvent event)
90 {
91 if (maybeSave()) {
92 writeSettings();
93 event.accept();
94 } else {
95 event.ignore();
96 }
97 }
98
99 private: // slots
100
101 void newFile()
102 {
103 MainWindow other = new MainWindow;
104 other.move(x() + 40, y() + 40);
105 other.show();
106 }
107
108 void open()
109 {
110 scope fileName = QFileDialog.getOpenFileName(this);
111 if (fileName) {
112 MainWindow existing = findMainWindow(fileName);
113 if (existing) {
114 existing.show();
115 existing.raise();
116 existing.activateWindow();
117 return;
118 }
119 if (isUntitled && textEdit.document().isEmpty()
120 && !isWindowModified()) {
121 loadFile(fileName);
122 } else {
123 MainWindow other = new MainWindow(fileName);
124 if (other.isUntitled) {
125 delete other;
126 return;
127 }
128 other.move(x() + 40, y() + 40);
129 other.show();
130 }
131 }
132 }
133
134 bool save()
135 {
136 if (isUntitled) {
137 return saveAs();
138 } else {
139 return saveFile(curFile);
140 }
141 }
142
143 bool saveAs()
144 {
145 string fileName = QFileDialog.getSaveFileName(this, tr("Save As"),
146 curFile);
147 if (!fileName)
148 return false;
149
150 return saveFile(fileName);
151 }
152
153 void about()
154 {
155 QMessageBox.about(this, tr("About SDI"),
156 tr("The <b>SDI</b> example demonstrates how to write single " ~
157 "document interface applications using Qt."));
158 }
159
160 void documentWasModified()
161 {
162 setWindowModified(true);
163 }
164
165 private:
166
167 void init()
168 {
169 setAttribute(Qt.WA_DeleteOnClose);
170
171 isUntitled = true;
172
173 textEdit = new QTextEdit;
174 setCentralWidget(textEdit);
175
176 createActions();
177 createMenus();
178 createToolBars();
179 createStatusBar();
180
181 readSettings();
182
183 textEdit.document().contentsChanged.connect(&this.documentWasModified);
184
185 setUnifiedTitleAndToolBarOnMac(true);
186 }
187
188 void createActions()
189 {
190 newAct = new QAction(new QIcon(":/images/new.png"), tr("&New"), this);
191 newAct.setShortcuts(QKeySequence.New);
192 newAct.setStatusTip(tr("Create a new file"));
193 newAct.triggered.connect(&this.newFile);
194
195 openAct = new QAction(new QIcon(":/images/open.png"), tr("&Open..."), this);
196 openAct.setShortcuts(QKeySequence.Open);
197 openAct.setStatusTip(tr("Open an existing file"));
198 openAct.triggered.connect(&this.open);
199
200 saveAct = new QAction(new QIcon(":/images/save.png"), tr("&Save"), this);
201 saveAct.setShortcuts(QKeySequence.Save);
202 saveAct.setStatusTip(tr("Save the document to disk"));
203 saveAct.triggered.connect(&this.save);
204
205 saveAsAct = new QAction(tr("Save &As..."), this);
206 saveAsAct.setShortcuts(QKeySequence.SaveAs);
207 saveAsAct.setStatusTip(tr("Save the document under a new name"));
208 saveAsAct.triggered.connect(&this.saveAs);
209
210 closeAct = new QAction(tr("&Close"), this);
211 closeAct.setShortcut(tr("Ctrl+W"));
212 closeAct.setStatusTip(tr("Close this window"));
213 closeAct.triggered.connect(&this.close);
214
215 exitAct = new QAction(tr("E&xit"), this);
216 exitAct.setShortcut(tr("Ctrl+Q"));
217 exitAct.setStatusTip(tr("Exit the application"));
218 exitAct.triggered.connect(&QApplication.closeAllWindows);
219
220 cutAct = new QAction(new QIcon(":/images/cut.png"), tr("Cu&t"), this);
221 cutAct.setShortcuts(QKeySequence.Cut);
222 cutAct.setStatusTip(tr("Cut the current selection's contents to the " ~
223 "clipboard"));
224 cutAct.triggered.connect(&textEdit.cut);
225
226 copyAct = new QAction(new QIcon(":/images/copy.png"), tr("&Copy"), this);
227 copyAct.setShortcuts(QKeySequence.Copy);
228 copyAct.setStatusTip(tr("Copy the current selection's contents to the " ~
229 "clipboard"));
230 copyAct.triggered.connect(&textEdit.copy);
231
232 pasteAct = new QAction(new QIcon(":/images/paste.png"), tr("&Paste"), this);
233 pasteAct.setShortcuts(QKeySequence.Paste);
234 pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current " ~
235 "selection"));
236 pasteAct.triggered.connect(&textEdit.paste);
237
238 aboutAct = new QAction(tr("&About"), this);
239 aboutAct.setStatusTip(tr("Show the application's About box"));
240 aboutAct.triggered.connect(&this.about);
241
242 aboutQtAct = new QAction(tr("About &Qt"), this);
243 aboutQtAct.setStatusTip(tr("Show the Qt library's About box"));
244 aboutQtAct.triggered.connect(&QApplication.aboutQt);
245
246 cutAct.setEnabled(false);
247 copyAct.setEnabled(false);
248
249 // QtD bug????
250 // only one of the following statements can be included
251 // otherwise the app crashes when a MainWindow is closeda
252 // textEdit.copyAvailable.connect(&cutAct.setEnabled);
253 textEdit.copyAvailable.connect(&copyAct.setEnabled);
254 }
255
256 void createMenus()
257 {
258 fileMenu = menuBar.addMenu(tr("&File"));
259 fileMenu.addAction(newAct);
260 fileMenu.addAction(openAct);
261 fileMenu.addAction(saveAct);
262 fileMenu.addAction(saveAsAct);
263 fileMenu.addSeparator();
264 fileMenu.addAction(closeAct);
265 fileMenu.addAction(exitAct);
266
267 editMenu = menuBar.addMenu(tr("&Edit"));
268 editMenu.addAction(cutAct);
269 editMenu.addAction(copyAct);
270 editMenu.addAction(pasteAct);
271
272 menuBar().addSeparator();
273
274 helpMenu = menuBar.addMenu(tr("&Help"));
275 helpMenu.addAction(aboutAct);
276 helpMenu.addAction(aboutQtAct);
277 }
278
279 void createToolBars()
280 {
281 fileToolBar = addToolBar(tr("File"));
282 fileToolBar.addAction(newAct);
283 fileToolBar.addAction(openAct);
284 fileToolBar.addAction(saveAct);
285
286 editToolBar = addToolBar(tr("Edit"));
287 editToolBar.addAction(cutAct);
288 editToolBar.addAction(copyAct);
289 editToolBar.addAction(pasteAct);
290 }
291
292 void createStatusBar()
293 {
294 statusBar.showMessage(tr("Ready"));
295 }
296
297 void readSettings()
298 {
299 scope QSettings settings = new QSettings("Trolltech", "SDI Example");
300 scope QPoint pos = settings.value("pos", new QVariant(QPoint(200, 200))).toPoint();
301 scope QSize size = settings.value("size", new QVariant(QSize(400, 400))).toSize();
302 move(pos);
303 resize(size);
304 }
305
306 void writeSettings()
307 {
308 QSettings settings = new QSettings("Trolltech", "SDI Example");
309 settings.setValue("pos", new QVariant(pos()));
310 settings.setValue("size", new QVariant(size()));
311 }
312
313 bool maybeSave()
314 {
315 if (textEdit.document().isModified()) {
316 QMessageBox.StandardButton ret;
317 ret = QMessageBox.warning(this, tr("SDI"),
318 tr("The document has been modified.\n" ~
319 "Do you want to save your changes?"),
320 QMessageBox.Save | QMessageBox.Discard
321 | QMessageBox.Cancel);
322 if (ret == QMessageBox.Save)
323 return save();
324 else if (ret == QMessageBox.Cancel)
325 return false;
326 }
327 return true;
328 }
329
330 void loadFile(string fileName)
331 {
332 scope file = new QFile(fileName);
333 if (!file.open(QFile.ReadOnly | QFile.Text)) {
334 QMessageBox.warning(this, tr("SDI"),
335 tr("Cannot read file " ~
336 fileName ~ ":\n" ~
337 file.errorString ~ "."));
338 return;
339 }
340
341 scope inStream = new QTextStream(file);
342 QApplication.setOverrideCursor(new QCursor(Qt.WaitCursor));
343 textEdit.setPlainText(inStream.readAll());
344 QApplication.restoreOverrideCursor();
345
346 setCurrentFile(fileName);
347 statusBar.showMessage(tr("File loaded"), 2000);
348 }
349
350 bool saveFile(string fileName)
351 {
352 scope file = new QFile(fileName);
353 if (!file.open(QFile.WriteOnly | QFile.Text)) {
354 QMessageBox.warning(this, tr("SDI"),
355 tr("Cannot write file " ~
356 fileName ~ ":\n" ~
357 file.errorString ~ "."));
358 return false;
359 }
360
361 scope outStream = new QTextStream(file);
362 QApplication.setOverrideCursor(new QCursor(Qt.WaitCursor));
363 outStream.writeString(textEdit.toPlainText());
364 QApplication.restoreOverrideCursor();
365
366 setCurrentFile(fileName);
367 statusBar.showMessage("Saved '" ~ fileName ~ "'", 2000);
368 return true;
369 }
370
371 void setCurrentFile(string fileName)
372 {
373 static int sequenceNumber = 1;
374
375 isUntitled = fileName == null;
376 if (isUntitled) {
377 version(Tango)
378 curFile = tr("document" ~ Int.toString(sequenceNumber++) ~ ".txt");
379 else
380 curFile = tr("document" ~ to!(string)(sequenceNumber++) ~ ".txt");
381 } else {
382 scope qfi = new QFileInfo(fileName);
383 curFile = qfi.canonicalFilePath;
384 }
385
386 textEdit.document().setModified(false);
387 setWindowModified(false);
388
389 setWindowTitle(strippedName(curFile) ~ "[*] - " ~ tr("SDI"));
390 }
391
392 string strippedName(string fullFileName)
393 {
394 scope qfi = new QFileInfo(fullFileName);
395 return qfi.fileName();
396 }
397
398 MainWindow findMainWindow(string fileName)
399 {
400 scope qfi = new QFileInfo(fileName);
401 string canonicalFilePath = qfi.canonicalFilePath();
402
403 foreach (QWidget widget; QApplication.topLevelWidgets) {
404 MainWindow mainWin = cast(MainWindow)(widget);
405 if (mainWin && mainWin.curFile == canonicalFilePath)
406 return mainWin;
407 }
408 return null;
409 }
410
411 QTextEdit textEdit;
412 string curFile;
413 bool isUntitled;
414
415 QMenu fileMenu;
416 QMenu editMenu;
417 QMenu helpMenu;
418 QToolBar fileToolBar;
419 QToolBar editToolBar;
420
421 QAction newAct;
422 QAction openAct;
423 QAction saveAct;
424 QAction saveAsAct;
425 QAction closeAct;
426 QAction exitAct;
427 QAction cutAct;
428 QAction copyAct;
429 QAction pasteAct;
430 QAction aboutAct;
431 QAction aboutQtAct;
432 };