Mercurial > projects > qtd
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(©Act.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 }; |