making clangd happy and making script to compile/build with run.sh
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,288 @@
|
||||
// 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
|
||||
\examplecategory {Application Examples}
|
||||
\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 bool 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.
|
||||
|
||||
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 read before
|
||||
accepting it.
|
||||
|
||||
\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 }
|
||||
*/
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example demos/documentviewer/plugins/txtviewer
|
||||
\title Qt Widgets - Text Viewer Plugin Example
|
||||
\examplecategory {Graphics & Multimedia}
|
||||
\ingroup examples-mainwindow
|
||||
|
||||
\brief A widget example with menus, toolbars and a status bar.
|
||||
|
||||
The Text Viewer example is a text editor built around QPlainTextEdit,
|
||||
in the form of a plugin for a general-purpose \l {Document Viewer}.
|
||||
|
||||
\image txtviewer_screenshot.png
|
||||
|
||||
All of the code for the Text Viewer example is in the \c TxtViewer class,
|
||||
which inherits \c AbstractViewer. \c AbstractViewer provides the framework
|
||||
for interaction between a viewer and the main window. The application provides
|
||||
\uicontrol{File}, \uicontrol{Edit}, and \uicontrol{Help} entries in the menu
|
||||
bar.
|
||||
|
||||
The status bar at the bottom of the main window shows a message provided by
|
||||
the application to its user.
|
||||
|
||||
Recently opened files are shown in the \uicontrol{File} menu.
|
||||
The example can only load one file at a time.
|
||||
|
||||
\section1 Class Definition
|
||||
|
||||
\snippet demos/documentviewer/plugins/txtviewer/txtviewer.h interfacing
|
||||
|
||||
The class definition starts with the \c Q_OBJECT macro, which handles
|
||||
signals and slots. It is followed by the \c Q_PLUGIN_METADATA and
|
||||
\c Q_INTERFACES macros which are necessary to register the plugin.
|
||||
|
||||
The class inherits from \c ViewerInterface, which inherits from
|
||||
\c AbstractViewer. The \c ViewerInterface class is used to provide an interface
|
||||
between the main window application and the plugin.
|
||||
|
||||
\c QPluginLoader also requires the file txtviewer.json, which has to contain
|
||||
the plugin's key:
|
||||
\code
|
||||
{ "Keys": [ "txtviewer" ] }
|
||||
\endcode
|
||||
|
||||
\snippet demos/documentviewer/plugins/txtviewer/txtviewer.h classDefinition
|
||||
|
||||
The class defines no constructor, which means that only a standard constructor
|
||||
without arguments is available. All other functions, including the destructor,
|
||||
re-implement virtual functions of \c ViewerInterface. They are used to exchange
|
||||
data, information, and instructions with the main application.
|
||||
|
||||
No functionality is implemented to save and restore settings.
|
||||
The \c supportsOverview function always returns \c false, which tells the main
|
||||
application that no window for thumbnail navigation has to be displayed.
|
||||
|
||||
\section1 TxtViewer Class Implementation
|
||||
|
||||
\snippet demos/documentviewer/plugins/txtviewer/txtviewer.cpp init
|
||||
|
||||
We start by including the header files necessary to access all classes used by
|
||||
\c TxtViewer. We also include \c txtviewer.h.
|
||||
|
||||
\c QPrinter and \c QPrintDialog are only included if print support is enabled
|
||||
on the compilation system.
|
||||
|
||||
You might wonder why we don't include these headers in \c mainwindow.h and
|
||||
be done with it. The reason is that including multiple large headers from another
|
||||
header file can rapidly degrade performance. Here, it wouldn't do any harm,
|
||||
but it's still generally a good idea to include only the header files that are
|
||||
strictly necessary from another header file.
|
||||
|
||||
The implementation starts with an empty destructor. It could be completely omitted.
|
||||
It's good practice to implement it empty in order to point out to code readers that
|
||||
nothing needs to be done in the destructor.
|
||||
|
||||
The destructor is followed by an initialization function, taking three arguments:
|
||||
\list
|
||||
\li \c file, the pointer to the file to be opened and displayed.
|
||||
\li \c parent, pointing to the \c QWidget inside which the editor shall be placed.
|
||||
\li \c mainWindow, pointing to the application's main window, where menus and menu bars
|
||||
are handled.
|
||||
\endlist
|
||||
The function calls the base init function of \c AbstractViwer.
|
||||
A new QPlainTextEdit widget is created, which will display the file's contents.
|
||||
Then, \c TxtViewer's setup function is connected to the base class' uiInitialized signal.
|
||||
|
||||
The next function returns the list of mime types, which the text viewer supports.
|
||||
Only plain text is supported.
|
||||
|
||||
The last initialization function adds viewer specific UI components like menus,
|
||||
icons, buttons, and tooltips. It uses functionality provided by \c AbstractViewer
|
||||
to make sure that these components are removed from the application's main window,
|
||||
once another file is displayed with another viewer plugin.
|
||||
|
||||
\snippet demos/documentviewer/plugins/txtviewer/txtviewer.cpp open
|
||||
|
||||
\c openFile opens a file, transfers its contents into the QPlainTextEdit, and prints
|
||||
a status message for the user, depending on whether or not the opening was successful.
|
||||
|
||||
\snippet demos/documentviewer/plugins/txtviewer/txtviewer.cpp infoPrintAndSave
|
||||
|
||||
The next re-implemented function tells the main application whether or not the viewer
|
||||
plugin is actually displaying content.
|
||||
|
||||
If printing is supported on the compiling system, the next section implements it.
|
||||
|
||||
The last two re-implementations provide functionality to save the current file or
|
||||
to save it under a new name.
|
||||
*/
|
||||
Reference in New Issue
Block a user