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]
MainWindow()64 MainWindow::MainWindow()
65     : textEdit(new QTextEdit)
66 {
67     setCentralWidget(textEdit);
68 
69     createActions();
70     createStatusBar();
71     createDockWindows();
72 
73     setWindowTitle(tr("Dock Widgets"));
74 
75     newLetter();
76     setUnifiedTitleAndToolBarOnMac(true);
77 }
78 //! [1]
79 
80 //! [2]
newLetter()81 void MainWindow::newLetter()
82 {
83     textEdit->clear();
84 
85     QTextCursor cursor(textEdit->textCursor());
86     cursor.movePosition(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(1, 1, tableFormat);
103     cursor.insertText("The Firm", boldFormat);
104     cursor.insertBlock();
105     cursor.insertText("321 City Street", textFormat);
106     cursor.insertBlock();
107     cursor.insertText("Industry Park");
108     cursor.insertBlock();
109     cursor.insertText("Some Country");
110     cursor.setPosition(topFrame->lastPosition());
111     cursor.insertText(QDate::currentDate().toString("d MMMM yyyy"), textFormat);
112     cursor.insertBlock();
113     cursor.insertBlock();
114     cursor.insertText("Dear ", textFormat);
115     cursor.insertText("NAME", italicFormat);
116     cursor.insertText(",", textFormat);
117     for (int i = 0; i < 3; ++i)
118         cursor.insertBlock();
119     cursor.insertText(tr("Yours sincerely,"), textFormat);
120     for (int i = 0; i < 3; ++i)
121         cursor.insertBlock();
122     cursor.insertText("The Boss", textFormat);
123     cursor.insertBlock();
124     cursor.insertText("ADDRESS", italicFormat);
125 }
126 //! [2]
127 
128 //! [3]
print()129 void 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);
141     statusBar()->showMessage(tr("Ready"), 2000);
142 #endif
143 }
144 //! [3]
145 
146 //! [4]
save()147 void MainWindow::save()
148 {
149     QMimeDatabase mimeDatabase;
150     QString fileName = QFileDialog::getSaveFileName(this,
151                         tr("Choose a file name"), ".",
152                         mimeDatabase.mimeTypeForName("text/html").filterString());
153     if (fileName.isEmpty())
154         return;
155     QFile file(fileName);
156     if (!file.open(QFile::WriteOnly | QFile::Text)) {
157         QMessageBox::warning(this, tr("Dock Widgets"),
158                              tr("Cannot write file %1:\n%2.")
159                              .arg(QDir::toNativeSeparators(fileName), 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(tr("Saved '%1'").arg(fileName), 2000);
169 }
170 //! [4]
171 
172 //! [5]
undo()173 void MainWindow::undo()
174 {
175     QTextDocument *document = textEdit->document();
176     document->undo();
177 }
178 //! [5]
179 
180 //! [6]
insertCustomer(const QString & customer)181 void MainWindow::insertCustomer(const QString &customer)
182 {
183     if (customer.isEmpty())
184         return;
185     QStringList customerList = customer.split(", ");
186     QTextDocument *document = textEdit->document();
187     QTextCursor cursor = document->find("NAME");
188     if (!cursor.isNull()) {
189         cursor.beginEditBlock();
190         cursor.insertText(customerList.at(0));
191         QTextCursor oldcursor = cursor;
192         cursor = document->find("ADDRESS");
193         if (!cursor.isNull()) {
194             for (int i = 1; i < customerList.size(); ++i) {
195                 cursor.insertBlock();
196                 cursor.insertText(customerList.at(i));
197             }
198             cursor.endEditBlock();
199         }
200         else
201             oldcursor.endEditBlock();
202     }
203 }
204 //! [6]
205 
206 //! [7]
addParagraph(const QString & paragraph)207 void MainWindow::addParagraph(const QString &paragraph)
208 {
209     if (paragraph.isEmpty())
210         return;
211     QTextDocument *document = textEdit->document();
212     QTextCursor cursor = document->find(tr("Yours sincerely,"));
213     if (cursor.isNull())
214         return;
215     cursor.beginEditBlock();
216     cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::MoveAnchor, 2);
217     cursor.insertBlock();
218     cursor.insertText(paragraph);
219     cursor.insertBlock();
220     cursor.endEditBlock();
221 
222 }
223 //! [7]
224 
about()225 void MainWindow::about()
226 {
227    QMessageBox::about(this, tr("About Dock Widgets"),
228             tr("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 
createActions()234 void MainWindow::createActions()
235 {
236     QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
237     QToolBar *fileToolBar = addToolBar(tr("File"));
238 
239     const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png"));
240     QAction *newLetterAct = new QAction(newIcon, tr("&New Letter"), this);
241     newLetterAct->setShortcuts(QKeySequence::New);
242     newLetterAct->setStatusTip(tr("Create a new form letter"));
243     connect(newLetterAct, &QAction::triggered, this, &MainWindow::newLetter);
244     fileMenu->addAction(newLetterAct);
245     fileToolBar->addAction(newLetterAct);
246 
247     const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png"));
248     QAction *saveAct = new QAction(saveIcon, tr("&Save..."), this);
249     saveAct->setShortcuts(QKeySequence::Save);
250     saveAct->setStatusTip(tr("Save the current form letter"));
251     connect(saveAct, &QAction::triggered, this, &MainWindow::save);
252     fileMenu->addAction(saveAct);
253     fileToolBar->addAction(saveAct);
254 
255     const QIcon printIcon = QIcon::fromTheme("document-print", QIcon(":/images/print.png"));
256     QAction *printAct = new QAction(printIcon, tr("&Print..."), this);
257     printAct->setShortcuts(QKeySequence::Print);
258     printAct->setStatusTip(tr("Print the current form letter"));
259     connect(printAct, &QAction::triggered, this, &MainWindow::print);
260     fileMenu->addAction(printAct);
261     fileToolBar->addAction(printAct);
262 
263     fileMenu->addSeparator();
264 
265     QAction *quitAct = fileMenu->addAction(tr("&Quit"), this, &QWidget::close);
266     quitAct->setShortcuts(QKeySequence::Quit);
267     quitAct->setStatusTip(tr("Quit the application"));
268 
269     QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
270     QToolBar *editToolBar = addToolBar(tr("Edit"));
271     const QIcon undoIcon = QIcon::fromTheme("edit-undo", QIcon(":/images/undo.png"));
272     QAction *undoAct = new QAction(undoIcon, tr("&Undo"), this);
273     undoAct->setShortcuts(QKeySequence::Undo);
274     undoAct->setStatusTip(tr("Undo the last editing action"));
275     connect(undoAct, &QAction::triggered, this, &MainWindow::undo);
276     editMenu->addAction(undoAct);
277     editToolBar->addAction(undoAct);
278 
279     viewMenu = menuBar()->addMenu(tr("&View"));
280 
281     menuBar()->addSeparator();
282 
283     QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
284 
285     QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
286     aboutAct->setStatusTip(tr("Show the application's About box"));
287 
288     QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
289     aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
290 }
291 
292 //! [8]
createStatusBar()293 void MainWindow::createStatusBar()
294 {
295     statusBar()->showMessage(tr("Ready"));
296 }
297 //! [8]
298 
299 //! [9]
createDockWindows()300 void MainWindow::createDockWindows()
301 {
302     QDockWidget *dock = new QDockWidget(tr("Customers"), this);
303     dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
304     customerList = new QListWidget(dock);
305     customerList->addItems(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(Qt::RightDockWidgetArea, dock);
314     viewMenu->addAction(dock->toggleViewAction());
315 
316     dock = new QDockWidget(tr("Paragraphs"), this);
317     paragraphsList = new QListWidget(dock);
318     paragraphsList->addItems(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(Qt::RightDockWidgetArea, dock);
338     viewMenu->addAction(dock->toggleViewAction());
339 
340     connect(customerList, &QListWidget::currentTextChanged,
341             this, &MainWindow::insertCustomer);
342     connect(paragraphsList, &QListWidget::currentTextChanged,
343             this, &MainWindow::addParagraph);
344 }
345 //! [9]
346