summaryrefslogtreecommitdiff
path: root/examples/demos/documentviewer/doc/src/documentviewer.qdoc
blob: ddcee81b8d1a9e5b8d5a7c82575f70451a091e08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \title Document Viewer
    \ingroup examples-widgets
    \example demos/documentviewer
    \meta {tag} {demo,widgets,mainwindow}
    \brief A Widgets application to display and print JSON, text, and PDF files.


    \e{Document Viewer} demonstrates how to use a QMainWindow with static
    and dynamic toolbars, menus, and actions. Additionally, it demonstrates
    the following features in widget-based applications:

    \list
        \li Using QSettings to query and save user preferences,
            and managing previously opened file history.
        \li Controlling cursor behavior when hovering over widgets.
        \li Creating dynamically loaded plugins.
    \endlist

    \image documentviewer_open.png


    \section1 Creating an application and the main window

    The application and its main window is constructed in \c main.cpp.
    The main() function uses QCommandLineParser to process command line
    arguments -- \e help, \e version, and an optional positional
    argument, \e file. If the user provided a path to a file when
    launching the application, the main window opens it:

    \quotefromfile demos/documentviewer/app/main.cpp
    \skipto int main
    \printuntil exec
    \printline }


    \section1 MainWindow class

    The \c MainWindow class provides an application screen with menus,
    actions, and a toolbar. It can open a file, automatically detecting its
    content type. It also maintains a list of previously opened files, using
    QSettings to store and reload settings when launched. The MainWindow
    creates a suitable \e viewer for the opened file, based on its content type,
    and provides support for printing a document.

    MainWindow's constructor initializes the user interface created in Qt
    Designer. The \c mainwindow.ui file provides a QTabWidget on the left,
    showing bookmarks and thumbnails. On the right, there is a QScrollArea for
    viewing file content.


    \section1 ViewerFactory class

    The \c ViewerFactory class manages viewers for known file types. These viewers
    are implemented as plugins. When an instance of a ViewerFactory is created,
    pointers to the view area and the main window are passed to the constructor:

    \code
    m_factory.reset(new ViewerFactory(ui->viewArea, this));
    \endcode

    ViewerFactory loads all available plugins on construction. It provides
    a public API to query the loaded plugins, their names, and supported MIME
    types:

    \quotefromfile demos/documentviewer/app/viewerfactory.h
    \skipto ViewerList
    \printuntil QStringList supportedMimeTypes() const;

    The \c viewer() function returns a pointer to the plugin suitable to open
    the QFile passed as an argument:

    \code
    m_viewer = m_factory->viewer(file);
    \endcode

    If the application settings contain a section for the viewer, it's passed
    to the viewer's virtual \c restoreState() function:

    \quotefromfile demos/documentviewer/app/mainwindow.cpp
    \skipto MainWindow::restoreViewerSettings
    \printuntil restoreState
    \printline }

    Then, the standard UI assets are passed to the viewer and the main scroll
    area is set to show the viewer's display widget:

    \quotefromfile demos/documentviewer/app/mainwindow.cpp
    \skipuntil void MainWindow::openFile
    \skipto m_viewer->initViewer
    \printuntil }


    \section1 AbstractViewer class

    \c AbstractViewer provides a generalized API to view, save, and print a
    document. Properties of both the document and the viewer can be queried:

    \list
        \li Does the document have content?
        \li Has it been modified?
        \li Is an overview (thumbnails or bookmarks) supported?
    \endlist

    AbstractViewer provides protected methods for derived classes to create
    actions and menus on the main window. In order to display these
    assets on the main window, they are parented to it. AbstractViewer is
    responsible for removing and destroying the UI assets it creates. It
    inherits from QObject to implement signals and slots.

    \section2 Signals

    \c {void uiInitialized();}

    This signal is emitted after a viewer receives all necessary information
    about UI assets on the main window.

    \c {void printingEnabledChanged(bool enabled);}

    This signal is emitted when document printing is either enabled or
    disabled. This happens after a new document was successfully loaded,
    or, for example, all content was removed.

    \c {void printStatusChanged(AbstractViewer::PrintStatus status);}

    After starting the printing process, this signal notifies about changes in
    its progress.

    \c {void documentLoaded(const QString &fileName);}

    This signal notifies the application that a document was successfully
    loaded.


    \section1 TxtViewer class

    \c TxtViewer is a simple text viewer, inheriting from AbstractViewer.
    It supports editing text files, copy/cut and paste, printing, and
    saving changes.


    \section1 JsonViewer class

    \c JsonViewer displays a JSON file in a QTreeView. Internally, it loads
    the contents of a file into a QJsonDocument and uses it to populate a
    custom tree model with \c JsonItemModel.

    The JSON viewer plugin demonstrates how to implement a custom item model
    inherited from QAbstractItemModel. The \c JsonTreeItem class provides a
    basic API for manipulating JSON data and propagating it back to the
    underlying QJsonDocument.

    JsonViewer uses the top-level objects of the document as bookmarks for
    navigation. Other nodes (keys and values) can be added as additional
    bookmarks, or removed from the bookmark list. A QLineEdit is used as a
    search field to navigate through the JSON tree.


    \section1 PdfViewer class

    The \c PdfViewer class (and plugin) is a fork of the \l {PDF Viewer
    Widget Example}. It demonstrates the use of QScroller to smoothly
    flick through a document.


    \section1 Other relevant classes

    \section2 HoverWatcher class

    The \c HoverWatcher class sets an override cursor when hovering the
    mouse over a widget, restoring it upon departure. To prevent multiple
    HoverWatcher instances being created for the same widget, it is
    implemented as a singleton per widget.

    HoverWatcher inherits from QObject and takes the QWidget it watches
    as the instance's parent. It installs an event filter to intercept hover
    events without consuming them:

    \quotefromfile demos/documentviewer/plugins/pdfviewer/hoverwatcher.cpp
    \skipto HoverWatcher::HoverWatcher
    \printuntil }

    The \c HoverAction enum lists the actions that HoverWatcher reacts to:

    \quotefromfile demos/documentviewer/plugins/pdfviewer/hoverwatcher.h
    \skipto enum HoverAction
    \printuntil };

    Static functions create watchers, check their existence for a specific
    QWidget, or dismiss a watcher:

    \quotefromfile demos/documentviewer/plugins/pdfviewer/hoverwatcher.h
    \skipto static HoverWatcher
    \printuntil static void dismiss

    A cursor shape can be set or unset for each HoverAction. If there is
    no associated cursor shape, the application's override cursor is
    restored when the action is triggered.

    \quotefromfile demos/documentviewer/plugins/pdfviewer/hoverwatcher.h
    \skipto public slots
    \printuntil void unSetCursorShape

    The \c mouseButtons property holds the mouse buttons to consider for a
    \c MousePress action:

    \quotefromfile demos/documentviewer/plugins/pdfviewer/hoverwatcher.h
    \skipuntil public slots
    \skipto setMouseButtons
    \printuntil setMouseButton(

    Action-specific signals are emitted after processing an action:

    \quotefromfile demos/documentviewer/plugins/pdfviewer/hoverwatcher.h
    \skipto signals
    \printuntil left();

    A general signal is emitted which passes the processed action as an
    argument:

    \code
    void hoverAction(HoverAction action);
    \endcode

    \section2 RecentFiles class

    \c RecentFiles is a QStringList that is specialized to manage a list of
    recently opened files.

    \quotefromfile demos/documentviewer/app/recentfiles.cpp
    \skipto RecentFiles::RecentFiles
    \printuntil }

    RecentFiles has slots to add either a single file or multiple files in one
    go. An entry is added to the list of recent files if the path points to a
    file that exists and can be opened. If a file is already in the list, it
    is removed from its original position and added to the top.

    \quotefromfile demos/documentviewer/app/recentfiles.h
    \skipto public slots
    \printuntil addFiles

    Files are removed from the list either by name or by index:

    \quotefromfile demos/documentviewer/app/recentfiles.h
    \skipuntil public slots
    \skipto removeFile
    \printuntil qsizetype index

    Slots that implement saving and restoring from QSettings:

    \quotefromfile demos/documentviewer/app/recentfiles.h
    \skipuntil public slots
    \skipto saveSettings
    \printuntil restoreFromSettings

    When restoring settings, nonexistent files are ignored. The \c maxFiles
    property holds the maximum amount of recent files to store (default is
    10).

    \code
    qsizetype maxFiles();
    void setMaxFiles(qsizetype maxFiles);
    \endcode

    \c {RecentFiles} verifies that a file can be opened in \c {openMode} before
    accepting it.

    \code
    void setOpenMode(QIODevice::OpenMode mode);
    QIODevice::OpenMode openMode() const;
    \endcode

    \section2 RecentFileMenu class

    \c {RecentFileMenu} is a QMenu, specialized to display a
    \l{RecentFiles class}{RecentFiles} object as a submenu.

    Its constructor takes a pointer to a parent QObject and a pointer to a
    RecentFiles object, the content of which it will visualize.
    Its \c fileOpened() signal, triggered when the user selects a recent file
    from the list, passes the absolute path to the file as an argument.

    \note \c {RecentFileMenu} is destroyed either by its parent widget, or by the
          \c {RecentFiles} object passed to its constructor.

    \quotefromfile demos/documentviewer/app/recentfilemenu.h
    \skipto class RecentFileMenu
    \printuntil void fileOpened
    \dots
    \skipuntil RecentFiles
    \printline }
*/