1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51//! [0]
52#include <QtWidgets>
53#if defined(QT_PRINTSUPPORT_LIB)
54#include <QtPrintSupport/qtprintsupportglobal.h>
55#if QT_CONFIG(printdialog)
56#include <QtPrintSupport>
57#endif
58#endif
59
60#include "mainwindow.h"
61//! [0]
62
63//! [1]
64MainWindow::MainWindow()
65 : textEdit(new QTextEdit)
66{
67 setCentralWidget(textEdit);
68
69 createActions();
70 createStatusBar();
71 createDockWindows();
72
73 setWindowTitle(tr(s: "Dock Widgets"));
74
75 newLetter();
76 setUnifiedTitleAndToolBarOnMac(true);
77}
78//! [1]
79
80//! [2]
81void MainWindow::newLetter()
82{
83 textEdit->clear();
84
85 QTextCursor cursor(textEdit->textCursor());
86 cursor.movePosition(op: QTextCursor::Start);
87 QTextFrame *topFrame = cursor.currentFrame();
88 QTextFrameFormat topFrameFormat = topFrame->frameFormat();
89 topFrameFormat.setPadding(16);
90 topFrame->setFrameFormat(topFrameFormat);
91
92 QTextCharFormat textFormat;
93 QTextCharFormat boldFormat;
94 boldFormat.setFontWeight(QFont::Bold);
95 QTextCharFormat italicFormat;
96 italicFormat.setFontItalic(true);
97
98 QTextTableFormat tableFormat;
99 tableFormat.setBorder(1);
100 tableFormat.setCellPadding(16);
101 tableFormat.setAlignment(Qt::AlignRight);
102 cursor.insertTable(rows: 1, cols: 1, format: tableFormat);
103 cursor.insertText(text: "The Firm", format: boldFormat);
104 cursor.insertBlock();
105 cursor.insertText(text: "321 City Street", format: textFormat);
106 cursor.insertBlock();
107 cursor.insertText(text: "Industry Park");
108 cursor.insertBlock();
109 cursor.insertText(text: "Some Country");
110 cursor.setPosition(pos: topFrame->lastPosition());
111 cursor.insertText(text: QDate::currentDate().toString(format: "d MMMM yyyy"), format: textFormat);
112 cursor.insertBlock();
113 cursor.insertBlock();
114 cursor.insertText(text: "Dear ", format: textFormat);
115 cursor.insertText(text: "NAME", format: italicFormat);
116 cursor.insertText(text: ",", format: textFormat);
117 for (int i = 0; i < 3; ++i)
118 cursor.insertBlock();
119 cursor.insertText(text: tr(s: "Yours sincerely,"), format: textFormat);
120 for (int i = 0; i < 3; ++i)
121 cursor.insertBlock();
122 cursor.insertText(text: "The Boss", format: textFormat);
123 cursor.insertBlock();
124 cursor.insertText(text: "ADDRESS", format: italicFormat);
125}
126//! [2]
127
128//! [3]
129void MainWindow::print()
130{
131#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
132 QTextDocument *document = textEdit->document();
133 QPrinter printer;
134
135 QPrintDialog dlg(&printer, this);
136 if (dlg.exec() != QDialog::Accepted) {
137 return;
138 }
139
140 document->print(printer: &printer);
141 statusBar()->showMessage(text: tr(s: "Ready"), timeout: 2000);
142#endif
143}
144//! [3]
145
146//! [4]
147void MainWindow::save()
148{
149 QMimeDatabase mimeDatabase;
150 QString fileName = QFileDialog::getSaveFileName(parent: this,
151 caption: tr(s: "Choose a file name"), dir: ".",
152 filter: mimeDatabase.mimeTypeForName(nameOrAlias: "text/html").filterString());
153 if (fileName.isEmpty())
154 return;
155 QFile file(fileName);
156 if (!file.open(flags: QFile::WriteOnly | QFile::Text)) {
157 QMessageBox::warning(parent: this, title: tr(s: "Dock Widgets"),
158 text: tr(s: "Cannot write file %1:\n%2.")
159 .arg(args: QDir::toNativeSeparators(pathName: fileName), args: file.errorString()));
160 return;
161 }
162
163 QTextStream out(&file);
164 QGuiApplication::setOverrideCursor(Qt::WaitCursor);
165 out << textEdit->toHtml();
166 QGuiApplication::restoreOverrideCursor();
167
168 statusBar()->showMessage(text: tr(s: "Saved '%1'").arg(a: fileName), timeout: 2000);
169}
170//! [4]
171
172//! [5]
173void MainWindow::undo()
174{
175 QTextDocument *document = textEdit->document();
176 document->undo();
177}
178//! [5]
179
180//! [6]
181void MainWindow::insertCustomer(const QString &customer)
182{
183 if (customer.isEmpty())
184 return;
185 QStringList customerList = customer.split(sep: ", ");
186 QTextDocument *document = textEdit->document();
187 QTextCursor cursor = document->find(subString: "NAME");
188 if (!cursor.isNull()) {
189 cursor.beginEditBlock();
190 cursor.insertText(text: customerList.at(i: 0));
191 QTextCursor oldcursor = cursor;
192 cursor = document->find(subString: "ADDRESS");
193 if (!cursor.isNull()) {
194 for (int i = 1; i < customerList.size(); ++i) {
195 cursor.insertBlock();
196 cursor.insertText(text: customerList.at(i));
197 }
198 cursor.endEditBlock();
199 }
200 else
201 oldcursor.endEditBlock();
202 }
203}
204//! [6]
205
206//! [7]
207void MainWindow::addParagraph(const QString &paragraph)
208{
209 if (paragraph.isEmpty())
210 return;
211 QTextDocument *document = textEdit->document();
212 QTextCursor cursor = document->find(subString: tr(s: "Yours sincerely,"));
213 if (cursor.isNull())
214 return;
215 cursor.beginEditBlock();
216 cursor.movePosition(op: QTextCursor::PreviousBlock, QTextCursor::MoveAnchor, n: 2);
217 cursor.insertBlock();
218 cursor.insertText(text: paragraph);
219 cursor.insertBlock();
220 cursor.endEditBlock();
221
222}
223//! [7]
224
225void MainWindow::about()
226{
227 QMessageBox::about(parent: this, title: tr(s: "About Dock Widgets"),
228 text: tr(s: "The <b>Dock Widgets</b> example demonstrates how to "
229 "use Qt's dock widgets. You can enter your own text, "
230 "click a customer to add a customer name and "
231 "address, and click standard paragraphs to add them."));
232}
233
234void MainWindow::createActions()
235{
236 QMenu *fileMenu = menuBar()->addMenu(title: tr(s: "&File"));
237 QToolBar *fileToolBar = addToolBar(title: tr(s: "File"));
238
239 const QIcon newIcon = QIcon::fromTheme(name: "document-new", fallback: QIcon(":/images/new.png"));
240 QAction *newLetterAct = new QAction(newIcon, tr(s: "&New Letter"), this);
241 newLetterAct->setShortcuts(QKeySequence::New);
242 newLetterAct->setStatusTip(tr(s: "Create a new form letter"));
243 connect(sender: newLetterAct, signal: &QAction::triggered, receiver: this, slot: &MainWindow::newLetter);
244 fileMenu->addAction(action: newLetterAct);
245 fileToolBar->addAction(action: newLetterAct);
246
247 const QIcon saveIcon = QIcon::fromTheme(name: "document-save", fallback: QIcon(":/images/save.png"));
248 QAction *saveAct = new QAction(saveIcon, tr(s: "&Save..."), this);
249 saveAct->setShortcuts(QKeySequence::Save);
250 saveAct->setStatusTip(tr(s: "Save the current form letter"));
251 connect(sender: saveAct, signal: &QAction::triggered, receiver: this, slot: &MainWindow::save);
252 fileMenu->addAction(action: saveAct);
253 fileToolBar->addAction(action: saveAct);
254
255 const QIcon printIcon = QIcon::fromTheme(name: "document-print", fallback: QIcon(":/images/print.png"));
256 QAction *printAct = new QAction(printIcon, tr(s: "&Print..."), this);
257 printAct->setShortcuts(QKeySequence::Print);
258 printAct->setStatusTip(tr(s: "Print the current form letter"));
259 connect(sender: printAct, signal: &QAction::triggered, receiver: this, slot: &MainWindow::print);
260 fileMenu->addAction(action: printAct);
261 fileToolBar->addAction(action: printAct);
262
263 fileMenu->addSeparator();
264
265 QAction *quitAct = fileMenu->addAction(text: tr(s: "&Quit"), object: this, slot: &QWidget::close);
266 quitAct->setShortcuts(QKeySequence::Quit);
267 quitAct->setStatusTip(tr(s: "Quit the application"));
268
269 QMenu *editMenu = menuBar()->addMenu(title: tr(s: "&Edit"));
270 QToolBar *editToolBar = addToolBar(title: tr(s: "Edit"));
271 const QIcon undoIcon = QIcon::fromTheme(name: "edit-undo", fallback: QIcon(":/images/undo.png"));
272 QAction *undoAct = new QAction(undoIcon, tr(s: "&Undo"), this);
273 undoAct->setShortcuts(QKeySequence::Undo);
274 undoAct->setStatusTip(tr(s: "Undo the last editing action"));
275 connect(sender: undoAct, signal: &QAction::triggered, receiver: this, slot: &MainWindow::undo);
276 editMenu->addAction(action: undoAct);
277 editToolBar->addAction(action: undoAct);
278
279 viewMenu = menuBar()->addMenu(title: tr(s: "&View"));
280
281 menuBar()->addSeparator();
282
283 QMenu *helpMenu = menuBar()->addMenu(title: tr(s: "&Help"));
284
285 QAction *aboutAct = helpMenu->addAction(text: tr(s: "&About"), object: this, slot: &MainWindow::about);
286 aboutAct->setStatusTip(tr(s: "Show the application's About box"));
287
288 QAction *aboutQtAct = helpMenu->addAction(text: tr(s: "About &Qt"), qApp, slot: &QApplication::aboutQt);
289 aboutQtAct->setStatusTip(tr(s: "Show the Qt library's About box"));
290}
291
292//! [8]
293void MainWindow::createStatusBar()
294{
295 statusBar()->showMessage(text: tr(s: "Ready"));
296}
297//! [8]
298
299//! [9]
300void MainWindow::createDockWindows()
301{
302 QDockWidget *dock = new QDockWidget(tr(s: "Customers"), this);
303 dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
304 customerList = new QListWidget(dock);
305 customerList->addItems(labels: QStringList()
306 << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton"
307 << "Jane Doe, Memorabilia, 23 Watersedge, Beaton"
308 << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton"
309 << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal"
310 << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston"
311 << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula");
312 dock->setWidget(customerList);
313 addDockWidget(area: Qt::RightDockWidgetArea, dockwidget: dock);
314 viewMenu->addAction(action: dock->toggleViewAction());
315
316 dock = new QDockWidget(tr(s: "Paragraphs"), this);
317 paragraphsList = new QListWidget(dock);
318 paragraphsList->addItems(labels: QStringList()
319 << "Thank you for your payment which we have received today."
320 << "Your order has been dispatched and should be with you "
321 "within 28 days."
322 << "We have dispatched those items that were in stock. The "
323 "rest of your order will be dispatched once all the "
324 "remaining items have arrived at our warehouse. No "
325 "additional shipping charges will be made."
326 << "You made a small overpayment (less than $5) which we "
327 "will keep on account for you, or return at your request."
328 << "You made a small underpayment (less than $1), but we have "
329 "sent your order anyway. We'll add this underpayment to "
330 "your next bill."
331 << "Unfortunately you did not send enough money. Please remit "
332 "an additional $. Your order will be dispatched as soon as "
333 "the complete amount has been received."
334 << "You made an overpayment (more than $5). Do you wish to "
335 "buy more items, or should we return the excess to you?");
336 dock->setWidget(paragraphsList);
337 addDockWidget(area: Qt::RightDockWidgetArea, dockwidget: dock);
338 viewMenu->addAction(action: dock->toggleViewAction());
339
340 connect(sender: customerList, signal: &QListWidget::currentTextChanged,
341 receiver: this, slot: &MainWindow::insertCustomer);
342 connect(sender: paragraphsList, signal: &QListWidget::currentTextChanged,
343 receiver: this, slot: &MainWindow::addParagraph);
344}
345//! [9]
346

source code of qtbase/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp