├── .gitignore
├── LICENSE
├── README.md
├── aboutdialog
├── aboutdialog.pri
├── caboutdialog.cpp
├── caboutdialog.h
└── caboutdialog.ui
├── dialogs
├── csimpleprogressdialog.cpp
├── csimpleprogressdialog.h
├── csimpleprogressdialog.ui
└── dialogs.pri
├── historylist
├── chistorylist.h
└── historylist.pri
├── imageprocessing
├── imageprocessing.pri
└── resize
│ ├── cimageresizer.cpp
│ └── cimageresizer.h
├── logger
├── cloggerinmemory.cpp
├── cloggerinmemory.h
├── cloggerinterface.h
└── logger.pri
├── mouseclickdetector
├── cmouseclickdetector.cpp
├── cmouseclickdetector.h
└── mouseclickdetector.pri
├── qtcore_helpers
├── qdatetime_helpers.hpp
├── qdebug_helpers.hpp
├── qstring_helpers.hpp
└── qtcore_helpers.pri
├── qtutils.pro
├── qtutils_project_suppressions.cfg
├── settings
├── csettings.cpp
├── csettings.h
└── settings.pri
├── settingsui
├── csettingsdialog.cpp
├── csettingsdialog.h
├── csettingsdialog.ui
├── csettingspage.h
└── settingsui.pri
├── std_helpers
├── qt_container_helpers.hpp
└── std_helpers.pri
├── string
├── string.pri
├── stringutils.cpp
└── stringutils.h
├── taskbarprogress
├── cprogressbartaskbar.cpp
├── cprogressbartaskbar.h
├── taskbarprogress.pri
└── taskbarprogress
│ ├── ctaskbarprogress.h
│ ├── ctaskbarprogress_freebsd.cpp
│ ├── ctaskbarprogress_linux.cpp
│ ├── ctaskbarprogress_mac.cpp
│ ├── ctaskbarprogress_win.cpp
│ ├── freebsd
│ ├── qxtglobal.h
│ ├── qxttooltip.cpp
│ ├── qxttooltip.h
│ └── qxttooltip_p.h
│ └── linux
│ ├── qxtglobal.h
│ ├── qxttooltip.cpp
│ ├── qxttooltip.h
│ └── qxttooltip_p.h
├── ui
├── ui-inspector
│ ├── cuiinspector.cpp
│ └── cuiinspector.h
└── ui.pri
├── utils
├── naturalsorting
│ ├── cnaturalsorterqcollator.cpp
│ ├── cnaturalsorterqcollator.h
│ ├── cnaturalsorting.cpp
│ ├── cnaturalsorting.h
│ ├── naturalsorting_qt.cpp
│ ├── naturalsorting_qt.h
│ └── sortingoptions.h
├── resources.cpp
├── resources.h
└── utils.pri
├── widgets
├── cclickablelabel.cpp
├── cclickablelabel.h
├── chistorycombobox.cpp
├── chistorycombobox.h
├── circularprogressindicator
│ ├── ccircularprogressindicator.cpp
│ └── ccircularprogressindicator.h
├── clineedit.cpp
├── clineedit.h
├── cpersistentwindow.cpp
├── cpersistentwindow.h
├── ctexteditwithlinenumbers.cpp
├── ctexteditwithlinenumbers.h
├── layouts
│ ├── coverlaylayout.cpp
│ └── coverlaylayout.h
├── widgets.pri
├── widgetutils.cpp
└── widgetutils.h
└── windows
├── windows.pri
├── windowsutils.cpp
└── windowsutils.h
/.gitignore:
--------------------------------------------------------------------------------
1 | .hgignore
2 | .hg/
3 |
4 | *.pdb
5 | *.Debug
6 | *.Release
7 | *.vc*proj
8 | *.filters
9 | *.user
10 | *.orig
11 | *.orig
12 | *.sln
13 | *.sdf
14 | *.suo
15 | *.opensdf
16 | Makefile
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | qtutils
2 | =======
3 |
4 | A collection of various Qt-based classes and code snippets that I decided to extract in a standalone library for use across my Qt applications.
5 |
6 | Taskbar progress is probably the only module that might be of interest to the community. It allows using Windows Vista / 7 / 8 taskbar button progress indicator feature in a Qt-compatible way. There's also a class for easy reflection of an existing QProgressBar state in the taskbar.
7 |
8 | Currently there's only implementation for Windows, Mac OS implementation is planned.
9 |
--------------------------------------------------------------------------------
/aboutdialog/aboutdialog.pri:
--------------------------------------------------------------------------------
1 | FORMS += \
2 | $$PWD/caboutdialog.ui
3 |
4 | HEADERS += \
5 | $$PWD/caboutdialog.h
6 |
7 | SOURCES += \
8 | $$PWD/caboutdialog.cpp
9 |
--------------------------------------------------------------------------------
/aboutdialog/caboutdialog.cpp:
--------------------------------------------------------------------------------
1 | #include "caboutdialog.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include "ui_caboutdialog.h"
5 |
6 | #include
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | CAboutDialog::CAboutDialog(QWidget *parent /*= 0*/) : CAboutDialog(QString(), parent)
11 | {
12 | }
13 |
14 | CAboutDialog::CAboutDialog(const QString& versionString, QWidget *parent, const QString& inceptionYear, const QString& copyrightOwner) :
15 | QDialog(parent),
16 | ui(new Ui::CAboutDialog)
17 | {
18 | ui->setupUi(this);
19 |
20 | ui->lblProgramName->setText(QApplication::applicationDisplayName());
21 | setWindowTitle("About " + QApplication::applicationDisplayName());
22 |
23 | if (!versionString.isEmpty())
24 | ui->lblVersion->setText(tr("Version %1 (%2 %3)\nUsing Qt version %4").arg(versionString, __DATE__, __TIME__, QT_VERSION_STR));
25 | else
26 | ui->lblVersion->setText(tr("Built on %1 at %2\nUsing Qt version %3").arg(__DATE__, __TIME__, QT_VERSION_STR));
27 |
28 | ui->lblCopyright->setText("©" % inceptionYear % ' ' % copyrightOwner);
29 | }
30 |
31 | CAboutDialog::~CAboutDialog()
32 | {
33 | delete ui;
34 | }
35 |
--------------------------------------------------------------------------------
/aboutdialog/caboutdialog.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | namespace Ui {
10 | class CAboutDialog;
11 | }
12 |
13 | class CAboutDialog final : public QDialog
14 | {
15 | public:
16 | explicit CAboutDialog(QWidget *parent);
17 | explicit CAboutDialog(const QString& versionString, QWidget *parent, const QString& inceptionYear = QLatin1String(__DATE__).right(4), const QString& copyrightOwner = "Violet Giraffe");
18 | ~CAboutDialog() override;
19 |
20 | private:
21 | Ui::CAboutDialog *ui;
22 | };
23 |
--------------------------------------------------------------------------------
/aboutdialog/caboutdialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | CAboutDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 328
10 | 179
11 |
12 |
13 |
14 | About
15 |
16 |
17 | -
18 |
19 |
20 |
21 | 16
22 | 50
23 | false
24 |
25 |
26 |
27 | Application Name
28 |
29 |
30 | Qt::AlignCenter
31 |
32 |
33 |
34 | -
35 |
36 |
37 | Qt::Vertical
38 |
39 |
40 | QSizePolicy::Fixed
41 |
42 |
43 |
44 | 20
45 | 20
46 |
47 |
48 |
49 |
50 | -
51 |
52 |
53 | Version 0.9.1 (22.01.2016 14:37), using Qt version 5.5
54 |
55 |
56 | Qt::AlignCenter
57 |
58 |
59 |
60 | -
61 |
62 |
63 | Qt::Vertical
64 |
65 |
66 |
67 | 20
68 | 33
69 |
70 |
71 |
72 |
73 | -
74 |
75 |
76 |
77 | 7
78 |
79 |
80 |
81 | © 2016 Violet Giraffe
82 |
83 |
84 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
85 |
86 |
87 |
88 | -
89 |
90 |
91 | Qt::Horizontal
92 |
93 |
94 | QDialogButtonBox::Close
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | buttonBox
104 | accepted()
105 | CAboutDialog
106 | accept()
107 |
108 |
109 | 248
110 | 254
111 |
112 |
113 | 157
114 | 274
115 |
116 |
117 |
118 |
119 | buttonBox
120 | rejected()
121 | CAboutDialog
122 | reject()
123 |
124 |
125 | 316
126 | 260
127 |
128 |
129 | 286
130 | 274
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/dialogs/csimpleprogressdialog.cpp:
--------------------------------------------------------------------------------
1 | #include "csimpleprogressdialog.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include "ui_csimpleprogressdialog.h"
5 | RESTORE_COMPILER_WARNINGS
6 |
7 | CSimpleProgressDialog::CSimpleProgressDialog(QWidget *parent) noexcept :
8 | QDialog(parent),
9 | ui(new Ui::CSimpleProgressDialog)
10 | {
11 | ui->setupUi(this);
12 |
13 | connect(ui->_cancelButton, &QPushButton::clicked, this, &CSimpleProgressDialog::reject);
14 | }
15 |
16 | CSimpleProgressDialog::~CSimpleProgressDialog() noexcept
17 | {
18 | delete ui;
19 | }
20 |
21 | void CSimpleProgressDialog::setLabelText(const QString &text)
22 | {
23 | ui->_label->setText(text);
24 | }
25 |
26 | void CSimpleProgressDialog::setValue(int value)
27 | {
28 | ui->_progressBar->setValue(value);
29 | showOrHideAsNecessary();
30 | }
31 |
32 | void CSimpleProgressDialog::setMinValue(int value)
33 | {
34 | ui->_progressBar->setMinimum(value);
35 | showOrHideAsNecessary();
36 | }
37 |
38 | void CSimpleProgressDialog::setMaxValue(int value)
39 | {
40 | ui->_progressBar->setMaximum(value);
41 | showOrHideAsNecessary();
42 | }
43 |
44 | void CSimpleProgressDialog::setCancellable(bool visible)
45 | {
46 | ui->_cancelButton->setVisible(visible);
47 | setWindowFlag(Qt::WindowCloseButtonHint, visible);
48 | }
49 |
50 | void CSimpleProgressDialog::setCancelButtonText(const QString& text)
51 | {
52 | ui->_cancelButton->setText(text);
53 | }
54 |
55 | void CSimpleProgressDialog::setAutoShow(bool autoShow)
56 | {
57 | _autoShow = autoShow;
58 | showOrHideAsNecessary();
59 | }
60 |
61 | void CSimpleProgressDialog::setAutoClose(bool autoClose)
62 | {
63 | _autoClose = autoClose;
64 | showOrHideAsNecessary();
65 | }
66 |
67 | void CSimpleProgressDialog::showOrHideAsNecessary()
68 | {
69 | if (_autoClose && ui->_progressBar->value() >= ui->_progressBar->maximum())
70 | close();
71 | else if (_autoShow && ui->_progressBar->value() > ui->_progressBar->minimum())
72 | show();
73 | }
74 |
--------------------------------------------------------------------------------
/dialogs/csimpleprogressdialog.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "compiler/compiler_warnings_control.h"
3 |
4 | DISABLE_COMPILER_WARNINGS
5 | #include
6 | RESTORE_COMPILER_WARNINGS
7 |
8 | namespace Ui {
9 | class CSimpleProgressDialog;
10 | }
11 |
12 | class CSimpleProgressDialog : public QDialog
13 | {
14 | public:
15 | explicit CSimpleProgressDialog(QWidget *parent = nullptr) noexcept;
16 | ~CSimpleProgressDialog() noexcept override;
17 |
18 | void setLabelText(const QString& text);
19 |
20 | void setValue(int value);
21 | void setMinValue(int value);
22 | void setMaxValue(int value);
23 |
24 | void setCancellable(bool visible);
25 | void setCancelButtonText(const QString& text);
26 |
27 | void setAutoShow(bool autoShow);
28 | void setAutoClose(bool autoClose);
29 |
30 | private:
31 | void showOrHideAsNecessary();
32 |
33 | private:
34 | Ui::CSimpleProgressDialog *ui;
35 | bool _autoShow = false;
36 | bool _autoClose = false;
37 | };
38 |
--------------------------------------------------------------------------------
/dialogs/csimpleprogressdialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | CSimpleProgressDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 307
10 | 92
11 |
12 |
13 |
14 | Dialog
15 |
16 |
17 | -
18 |
19 |
20 | Making everything better, please wait...
21 |
22 |
23 |
24 | -
25 |
26 |
27 | 0
28 |
29 |
30 |
31 | -
32 |
33 |
-
34 |
35 |
36 | Qt::Horizontal
37 |
38 |
39 |
40 | 40
41 | 20
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 | &Cancel
50 |
51 |
52 |
53 |
54 |
55 | -
56 |
57 |
58 | Qt::Vertical
59 |
60 |
61 |
62 | 20
63 | 0
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/dialogs/dialogs.pri:
--------------------------------------------------------------------------------
1 | FORMS += \
2 | $$PWD/csimpleprogressdialog.ui
3 |
4 | HEADERS += \
5 | $$PWD/csimpleprogressdialog.h
6 |
7 | SOURCES += \
8 | $$PWD/csimpleprogressdialog.cpp
9 |
--------------------------------------------------------------------------------
/historylist/chistorylist.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "assert/advanced_assert.h"
3 | #include "container/set_operations.hpp"
4 | #include "lang/type_traits_fast.hpp"
5 |
6 | #include
7 | #include
8 |
9 | template
10 | class CHistoryList
11 | {
12 | public:
13 | using container_type = std::deque;
14 | explicit CHistoryList(size_t maxSize = 2000) noexcept :
15 | _currentIndex{ size_t_max },
16 | _maxSize{ maxSize }
17 | {}
18 |
19 | // Access and status
20 | [[nodiscard]] inline bool empty() const { return _list.empty(); }
21 | [[nodiscard]] inline size_t size() const { return _list.size(); }
22 | inline void clear() { _list.clear(); }
23 |
24 | [[nodiscard]] inline typename container_type::const_iterator begin() const { return _list.begin(); }
25 | [[nodiscard]] inline typename container_type::const_iterator end() const { return _list.end(); }
26 | [[nodiscard]] inline typename container_type::const_reverse_iterator rbegin() const { return _list.rbegin(); }
27 | [[nodiscard]] inline typename container_type::const_reverse_iterator rend() const { return _list.rend(); }
28 |
29 | [[nodiscard]] inline const T& front() const { return _list.front(); }
30 | [[nodiscard]] inline const T& back() const { return _list.back(); }
31 |
32 | [[nodiscard]] inline const T& operator[](size_t index) const { return _list[index]; }
33 |
34 | [[nodiscard]] inline bool historyLocationSet() const { return _currentIndex <= _list.size(); }
35 |
36 | [[nodiscard]] inline const container_type& list() const { return _list; }
37 |
38 | [[nodiscard]] size_t currentIndex() const;
39 | [[nodiscard]] const T& currentItem() const;
40 |
41 | [[nodiscard]] bool isAtEnd() const;
42 | [[nodiscard]] bool isAtBeginning() const;
43 |
44 | // Actions
45 | void addLatest(const T& item);
46 | void addLatest(const std::vector& items);
47 | const T& navigateBack();
48 | const T& navigateForward();
49 |
50 | private:
51 | container_type _list;
52 | size_t _currentIndex;
53 | const size_t _maxSize;
54 | };
55 |
56 | template
57 | const T& CHistoryList::navigateForward()
58 | {
59 | if (_currentIndex < size() - 1)
60 | _currentIndex = currentIndex() + 1;
61 | return currentItem();
62 | }
63 |
64 | template
65 | const T& CHistoryList::navigateBack()
66 | {
67 | if (_currentIndex > 0)
68 | _currentIndex = currentIndex() - 1;
69 | return currentItem();
70 | }
71 |
72 | template
73 | const T& CHistoryList::currentItem() const
74 | {
75 | if (!empty())
76 | return _list[currentIndex()];
77 | else
78 | {
79 | static const T blank;
80 | return blank;
81 | }
82 | }
83 |
84 | template
85 | bool CHistoryList::isAtEnd() const
86 | {
87 | assert_r(empty() || _currentIndex < size());
88 | return !empty() && _currentIndex == size() - 1;
89 | }
90 |
91 | template
92 | bool CHistoryList::isAtBeginning() const
93 | {
94 | assert_r(empty() || _currentIndex < size());
95 | return !empty() && _currentIndex == 0;
96 | }
97 |
98 | template
99 | size_t CHistoryList::currentIndex() const
100 | {
101 | if (empty())
102 | return size_t_max;
103 | else if (_currentIndex < size())
104 | return _currentIndex;
105 | else
106 | return size() - 1;
107 | }
108 |
109 | template
110 | void CHistoryList::addLatest(const T& item)
111 | {
112 | if (currentItem() == item)
113 | return;
114 |
115 | const auto currentPosition = std::find(_list.begin(), _list.end(), item);
116 | if (currentPosition == _list.end())
117 | _list.push_back(item);
118 | else if (size() > 1 && currentPosition != _list.end() - 1)
119 | std::rotate(currentPosition, currentPosition + 1, _list.end());
120 |
121 | assert_r(!empty());
122 | if (size() > 1 && _currentIndex <= size() - 2) // If we already were at the end of the list, just move the index to the newest element
123 | {
124 | // If we were not in the end, move and insert [0; _currentIndex] just before end
125 | decltype(_list) newList;
126 | for (size_t i = _currentIndex + 1; i < size() - 1; ++i)
127 | newList.push_back(std::move(_list[i]));
128 | for (size_t i = 0; i <= _currentIndex; ++i)
129 | newList.push_back(std::move(_list[i]));
130 | _list = newList;
131 | _list.emplace_back(item);
132 | }
133 |
134 | if (_list.size() > _maxSize)
135 | _list.pop_front();
136 |
137 | _currentIndex = _list.size() - 1;
138 | }
139 |
140 | template
141 | void CHistoryList::addLatest(const std::vector& items)
142 | {
143 | _list = container_type(items.begin(), items.end());
144 | _list = SetOperations::uniqueElements(_list);
145 | // Trim to size - erase old (first) items
146 | if (const auto size = _list.size(); size > _maxSize)
147 | _list.erase(_list.begin(), _list.begin() + size - _maxSize);
148 |
149 | _currentIndex = _list.size() - 1;
150 | }
151 |
--------------------------------------------------------------------------------
/historylist/historylist.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | historylist/chistorylist.h
3 |
--------------------------------------------------------------------------------
/imageprocessing/imageprocessing.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | imageprocessing/resize/cimageresizer.h
3 |
4 | SOURCES += \
5 | imageprocessing/resize/cimageresizer.cpp
6 |
--------------------------------------------------------------------------------
/imageprocessing/resize/cimageresizer.cpp:
--------------------------------------------------------------------------------
1 | #if __has_include("resize/cimageinterpolationkernel.h")
2 |
3 | #include "cimageresizer.h"
4 | #include "resize/cimageinterpolationkernel.h"
5 |
6 | #include "assert/advanced_assert.h"
7 | #include "math/math.hpp"
8 | #include "compiler/compiler_warnings_control.h"
9 |
10 | DISABLE_COMPILER_WARNINGS
11 | #include
12 | #include
13 | #include
14 | RESTORE_COMPILER_WARNINGS
15 |
16 | #include
17 | #include
18 |
19 | QSize scaled(const QSize& source, const QSize& dest)
20 | {
21 | const float xScaleFactor = (float)source.width() / (float)dest.width();
22 | const float yScaleFactor = (float)source.height() / (float)dest.height();
23 |
24 | const float actualFactor = (xScaleFactor > 1.0f && yScaleFactor > 1.0f) ? std::max(xScaleFactor, yScaleFactor) : std::min(xScaleFactor, yScaleFactor);
25 |
26 | return source / actualFactor;
27 | }
28 |
29 | inline QRgb applyKernel(const CImageInterpolationKernelBase& kernel, const QImage& source, uint32_t x, uint32_t y)
30 | {
31 | assert_r(x >= 0 && y >= 0); // Tested - doesn't affect performance within 1 ms resolution
32 |
33 | float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
34 |
35 | const uint32_t srcHeight = (uint32_t)source.height(), srcWidth = (uint32_t)source.width();
36 | const uint32_t kernelSize = kernel.size();
37 |
38 | using FloatType = decltype(kernel.coeff(0, 0));
39 |
40 | if (source.depth() == 32)
41 | {
42 | for (uint32_t k = y, k_kernel = 0; k < y + kernelSize && k < srcHeight; ++k, ++ k_kernel)
43 | {
44 | // TODO: strict aliasong violation!
45 | const QRgb * line = reinterpret_cast(source.constScanLine((int)k));
46 | for (uint32_t i = x, i_kernel = 0; i < x + kernelSize && i < srcWidth; ++i, ++i_kernel)
47 | {
48 | const auto coeff = kernel.coeff(i_kernel, k_kernel);
49 | r += static_cast(qRed(line[i])) * coeff;
50 | g += static_cast(qGreen(line[i])) * coeff;
51 | b += static_cast(qBlue(line[i])) * coeff;
52 | a += static_cast(qAlpha(line[i])) * coeff;
53 | }
54 | }
55 | }
56 | else
57 | {
58 | for (uint32_t i = x, i_kernel = 0; i < x + kernelSize && i < srcWidth; ++i, ++i_kernel)
59 | for (uint32_t k = y, k_kernel = 0; k < y + kernelSize && k < srcHeight; ++k, ++ k_kernel)
60 | {
61 | const QColor pixel(source.pixel(i, k));
62 | const auto coeff = kernel.coeff(i_kernel, k_kernel);
63 |
64 | r += static_cast(pixel.red()) * coeff;
65 | g += static_cast(pixel.green()) * coeff;
66 | b += static_cast(pixel.blue()) * coeff;
67 | a += static_cast(pixel.alpha()) * coeff;
68 | }
69 | }
70 |
71 | r = Math::clamp(FloatType{0.0f}, r, FloatType{255.0f});
72 | g = Math::clamp(FloatType{0.0f}, g, FloatType{255.0f});
73 | b = Math::clamp(FloatType{0.0f}, b, FloatType{255.0f});
74 | a = Math::clamp(FloatType{0.0f}, a, FloatType{255.0f});
75 |
76 | return qRgba(Math::round(r),
77 | Math::round(g),
78 | Math::round(b),
79 | Math::round(a)
80 | );
81 | }
82 |
83 | inline float ratio(const QSize& size)
84 | {
85 | return (float)size.width() / (float)size.height();
86 | }
87 |
88 | inline QSize operator*(const QSize& origSize, int k)
89 | {
90 | return QSize(origSize.width() * k, origSize.height() * k);
91 | }
92 |
93 | QImage bicubicInterpolation(const QImage& source, const QSize& targetSize, ImageResizing::AspectRatio aspectRatio)
94 | {
95 | using namespace ImageResizing;
96 |
97 | if (targetSize.width() == source.width() && targetSize.height() == source.height())
98 | return source;
99 | else if (targetSize.width() >= source.width() || targetSize.height() >= source.height())
100 | return source.scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
101 |
102 | QSize actualTargetSize = targetSize;
103 | if (::fabs(ratio(targetSize) - ratio(source.size())) < 0.01f)
104 | actualTargetSize = source.size().scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio);
105 |
106 | if (actualTargetSize.isEmpty())
107 | return QImage();
108 |
109 | const float scaleFactor = source.width() > actualTargetSize.width() ? (float)source.width() / (float)actualTargetSize.width() : (float)actualTargetSize.width() / (float)source.width();
110 |
111 | const int intScaleFactor = (int)ceilf(scaleFactor);
112 | const QSize upscaledSourceSize = ::fabs(scaleFactor - 1.0f) < 0.001f ? scaled(source.size(), actualTargetSize * intScaleFactor) : source.size();
113 |
114 | QImage dest(actualTargetSize, source.format());
115 | QImage upscaledSource(upscaledSourceSize == source.size() ? source : source.scaled(upscaledSourceSize, Qt::IgnoreAspectRatio, source.depth() == 32 ? Qt::SmoothTransformation : Qt::FastTransformation));
116 |
117 | // TODO: refactor this. There's no need to create all the kernels, we're only going to need one.
118 | const CLanczosKernel lanczosKernel((uint32_t)upscaledSource.width() / (uint32_t)actualTargetSize.width(), 3);
119 | const CBicubicKernel bicubicKernel((uint32_t)upscaledSource.width() / (uint32_t)actualTargetSize.width(), 0.5f);
120 |
121 | const CImageInterpolationKernelBase& kernel = upscaledSourceSize.width() / actualTargetSize.width() >= 30 ?
122 | (CImageInterpolationKernelBase&)bicubicKernel :
123 | (CImageInterpolationKernelBase&)bicubicKernel;
124 |
125 | const uint32_t kernelSize = kernel.size();
126 | const uint32_t targetWidth = (uint32_t)actualTargetSize.width(), targetHeight = (uint32_t)actualTargetSize.height();
127 | if (upscaledSource.depth() == 32)
128 | {
129 | for (uint32_t y = 0; y < targetHeight; ++y)
130 | {
131 | auto* scanLine = dest.scanLine(y);
132 | for (uint32_t x = 0; x < targetWidth; ++x)
133 | {
134 | const auto rgb = applyKernel(kernel, upscaledSource, x*kernelSize, y*kernelSize);
135 | auto* pixelAddress = scanLine + sizeof(QRgb) * x;
136 | memcpy(pixelAddress, &rgb, sizeof(rgb));
137 | }
138 | }
139 | }
140 | else
141 | {
142 | for (uint32_t x = 0; x < targetWidth; ++x)
143 | {
144 | for (uint32_t y = 0; y < targetHeight; ++y)
145 | {
146 | dest.setPixel(x, y, applyKernel(kernel, upscaledSource, x*kernelSize, y*kernelSize));
147 | }
148 | }
149 | }
150 | return dest;
151 | }
152 |
153 | QImage ImageResizing::resize(const QImage& source, const QSize& targetSize, ResizeMethod method, AspectRatio aspectRatio)
154 | {
155 | // CTimeElapsed timer(true);
156 | // EXEC_ON_SCOPE_EXIT([&]{
157 | // qInfo() << "Image resized from" << source.size() << "to" << targetSize << "in" << timer.elapsed() << "ms";
158 | // });
159 |
160 | switch(method)
161 | {
162 | case DefaultQimageFast:
163 | return source.scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::FastTransformation);
164 | case DefaultQimageSmooth:
165 | return source.scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
166 | case Smart:
167 | {
168 | auto actualTargetSize = source.size().scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio);
169 | if (source.size().width() < actualTargetSize.width())
170 | return source.scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::FastTransformation);
171 | else
172 | return source.scaled(targetSize, aspectRatio == KeepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
173 | }
174 | default:
175 | return {};
176 | }
177 | }
178 |
179 | #endif
180 |
--------------------------------------------------------------------------------
/imageprocessing/resize/cimageresizer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class QImage;
4 | class QSize;
5 |
6 | namespace ImageResizing
7 | {
8 |
9 | enum ResizeMethod {
10 | DefaultQimageFast,
11 | DefaultQimageSmooth,
12 | Smart
13 | };
14 |
15 | enum AspectRatio {
16 | KeepAspectRatio,
17 | IgnoreAspectRatio
18 | };
19 |
20 | QImage resize(const QImage& source, const QSize& targetSize, ResizeMethod method, AspectRatio aspectRatio = KeepAspectRatio);
21 |
22 | } // namespace ImageResizing
23 |
--------------------------------------------------------------------------------
/logger/cloggerinmemory.cpp:
--------------------------------------------------------------------------------
1 | #include "cloggerinmemory.h"
2 |
3 | void CLoggerInMemory::log(const QString& msg)
4 | {
5 | _entries.push_back(msg);
6 | }
7 |
8 | QStringList CLoggerInMemory::contents() const
9 | {
10 | return _entries;
11 | }
12 |
--------------------------------------------------------------------------------
/logger/cloggerinmemory.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "cloggerinterface.h"
4 |
5 | class CLoggerInMemory : public CLoggerInterface
6 | {
7 | public:
8 | void log(const QString& msg) override;
9 | [[nodiscard]] QStringList contents() const override;
10 |
11 | private:
12 | QStringList _entries;
13 | };
14 |
--------------------------------------------------------------------------------
/logger/cloggerinterface.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | class CLoggerInterface
10 | {
11 | public:
12 | virtual ~CLoggerInterface() = default;
13 |
14 | virtual void log(const QString& message) = 0;
15 | [[nodiscard]] virtual QStringList contents() const = 0;
16 | };
17 |
18 | template
19 | CLoggerInterface& loggerInstance()
20 | {
21 | static LoggerType instance;
22 | return instance;
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/logger/logger.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | $$PWD/cloggerinterface.h \
3 | $$PWD/cloggerinmemory.h
4 |
5 | SOURCES += \
6 | $$PWD/cloggerinmemory.cpp
7 |
--------------------------------------------------------------------------------
/mouseclickdetector/cmouseclickdetector.cpp:
--------------------------------------------------------------------------------
1 | #include "cmouseclickdetector.h"
2 | #include "assert/advanced_assert.h"
3 |
4 | DISABLE_COMPILER_WARNINGS
5 | #include
6 | #include
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | CMouseClickDetector *CMouseClickDetector::globalInstance()
11 | {
12 | static CMouseClickDetector inst;
13 | return &inst;
14 | }
15 |
16 | void CMouseClickDetector::notify(QObject * object, QEvent * event)
17 | {
18 | eventFilter(object, event);
19 | }
20 |
21 | bool CMouseClickDetector::eventFilter(QObject * object, QEvent * event)
22 | {
23 | if (event->type() == QEvent::MouseButtonRelease)
24 | {
25 | QMouseEvent * mouseEvent = dynamic_cast(event);
26 | assert_and_return_r(mouseEvent, false);
27 | if (mouseEvent->buttons() == Qt::LeftButton)
28 | {
29 | const QPoint pos = mouseEvent->pos();
30 |
31 | if (!_lastClickTimestampForObject.contains(object))
32 | _lastClickTimestampForObject[object] = 0;
33 |
34 | if (mouseEvent->timestamp() - _lastClickTimestampForObject[object] <= (unsigned int)QApplication::doubleClickInterval())
35 | {
36 | _lastClickTimestampForObject[object] = 0;
37 | emit doubleLeftClickDetected(object, pos);
38 | }
39 | else
40 | {
41 | _lastClickTimestampForObject[object] = (qint64)mouseEvent->timestamp();
42 | QTimer::singleShot(QApplication::doubleClickInterval() + 1, this, [this, object, pos](){
43 | if (_lastClickTimestampForObject[object] != 0)
44 | {
45 | _lastClickTimestampForObject[object] = 0;
46 | emit singleLeftClickDetected(object, pos);
47 | }
48 | });
49 | }
50 | }
51 | }
52 |
53 | return QObject::eventFilter(object, event);
54 | }
55 |
--------------------------------------------------------------------------------
/mouseclickdetector/cmouseclickdetector.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | #include
11 |
12 | class CMouseClickDetector final : public QObject
13 | {
14 | Q_OBJECT
15 | public:
16 | using QObject::QObject;
17 |
18 | [[nodiscard]] static CMouseClickDetector * globalInstance();
19 |
20 | void notify(QObject* object, QEvent* event);
21 |
22 | signals:
23 | void singleLeftClickDetected(QObject* object, QPoint pos);
24 | void doubleLeftClickDetected(QObject* object, QPoint pos);
25 |
26 | protected:
27 | bool eventFilter(QObject* object, QEvent* event) override;
28 |
29 | private:
30 | std::unordered_map _lastClickTimestampForObject;
31 | };
32 |
33 |
--------------------------------------------------------------------------------
/mouseclickdetector/mouseclickdetector.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | mouseclickdetector/cmouseclickdetector.h
3 |
4 | SOURCES += \
5 | mouseclickdetector/cmouseclickdetector.cpp
6 |
--------------------------------------------------------------------------------
/qtcore_helpers/qdatetime_helpers.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "compiler/compiler_warnings_control.h"
3 |
4 | DISABLE_COMPILER_WARNINGS
5 | #include
6 | RESTORE_COMPILER_WARNINGS
7 |
8 | [[nodiscard]] inline time_t toTime_t(const QDateTime& date) noexcept
9 | {
10 | return static_cast(date.toMSecsSinceEpoch() / 1000LL);
11 | }
12 |
13 | [[nodiscard]]inline QDateTime fromTime_t(const time_t time) noexcept
14 | {
15 | QDateTime date;
16 | date.setMSecsSinceEpoch(static_cast(time) * 1000LL);
17 | return date;
18 | }
19 |
--------------------------------------------------------------------------------
/qtcore_helpers/qdebug_helpers.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "compiler/compiler_warnings_control.h"
3 |
4 | DISABLE_COMPILER_WARNINGS
5 | #include
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | inline QDebug& operator<<(QDebug& debug, const std::string& std_str)
10 | {
11 | return debug << QString::fromStdString(std_str);
12 | }
13 |
14 | inline QDebug operator<<(QDebug&& debug, const std::string& std_str)
15 | {
16 | return debug << QString::fromStdString(std_str);
17 | }
18 |
19 | template
20 | QDebug operator<<(QDebug&& debug, const std::array& ar)
21 | {
22 | return debug << QByteArray::fromRawData(ar.data(), ar.size()).toHex();
23 | }
24 |
25 | template
26 | QDebug& operator<<(QDebug& debug, const std::array& ar)
27 | {
28 | return debug << QByteArray::fromRawData((const char*)ar.data(), (int)ar.size() * sizeof(T)).toHex();
29 | }
--------------------------------------------------------------------------------
/qtcore_helpers/qstring_helpers.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define QSL QStringLiteral
6 | #define QL1 QLatin1String
7 |
--------------------------------------------------------------------------------
/qtcore_helpers/qtcore_helpers.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | $$PWD/qdatetime_helpers.hpp \
3 | $$PWD/qdebug_helpers.hpp \
4 | $$PWD/qstring_helpers.hpp
5 |
--------------------------------------------------------------------------------
/qtutils.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = lib
2 | TARGET = qtutils
3 | CONFIG += staticlib
4 |
5 | CONFIG += strict_c++ c++latest
6 |
7 | mac* | linux* | freebsd {
8 | CONFIG(release, debug|release):CONFIG *= Release optimize_full
9 | CONFIG(debug, debug|release):CONFIG *= Debug
10 | }
11 |
12 | Release:OUTPUT_DIR=release/$${ARCHITECTURE}
13 | Debug:OUTPUT_DIR=debug/$${ARCHITECTURE}
14 |
15 | DESTDIR = ../bin/$${OUTPUT_DIR}
16 | OBJECTS_DIR = ../build/$${OUTPUT_DIR}/$${TARGET}
17 | MOC_DIR = ../build/$${OUTPUT_DIR}/$${TARGET}
18 | UI_DIR = ../build/$${OUTPUT_DIR}/$${TARGET}
19 | RCC_DIR = ../build/$${OUTPUT_DIR}/$${TARGET}
20 |
21 | QT = core gui widgets
22 |
23 | # Required for qInfo() to log function name, file and line in release build
24 | DEFINES += QT_MESSAGELOGCONTEXT
25 |
26 | INCLUDEPATH += \
27 | ../image-processing \
28 | ../cpputils \
29 | ../cpp-template-utils \
30 |
31 | win*{
32 | QMAKE_CXXFLAGS += /MP /Zi /wd4251 /JMC
33 | QMAKE_CXXFLAGS += /std:c++latest /permissive- /Zc:__cplusplus
34 | DEFINES += WIN32_LEAN_AND_MEAN NOMINMAX
35 | QMAKE_CXXFLAGS_WARN_ON = /W4
36 |
37 | !*msvc2013*:QMAKE_LFLAGS += /DEBUG:FASTLINK
38 |
39 | Debug:QMAKE_LFLAGS += /INCREMENTAL
40 | Release:QMAKE_LFLAGS += /OPT:REF /OPT:ICF
41 | *msvc*{
42 | QMAKE_CXXFLAGS += /FS
43 | }
44 | }
45 |
46 | linux*|mac*|freebsd{
47 | QMAKE_CXXFLAGS += -pedantic-errors
48 | QMAKE_CFLAGS += -pedantic-errors
49 | QMAKE_CXXFLAGS_WARN_ON = -Wall
50 |
51 | Release:DEFINES += NDEBUG=1
52 | Debug:DEFINES += _DEBUG
53 |
54 | PRE_TARGETDEPS += $${DESTDIR}/libcpputils.a
55 | }
56 |
57 | include(imageprocessing/imageprocessing.pri)
58 | include(logger/logger.pri)
59 | include(aboutdialog/aboutdialog.pri)
60 | include(settings/settings.pri)
61 | include(taskbarprogress/taskbarprogress.pri)
62 | include(utils/utils.pri)
63 | include(settingsui/settingsui.pri)
64 | include(string/string.pri)
65 | include(mouseclickdetector/mouseclickdetector.pri)
66 | include(historylist/historylist.pri)
67 | include(widgets/widgets.pri)
68 | include(dialogs/dialogs.pri)
69 | include(ui/ui.pri)
70 | include(std_helpers/std_helpers.pri)
71 | include(qtcore_helpers/qtcore_helpers.pri)
72 | win*:include(windows/windows.pri)
73 |
--------------------------------------------------------------------------------
/qtutils_project_suppressions.cfg:
--------------------------------------------------------------------------------
1 | [cppcheck]
2 | unusedPrivateFunction:*ctaskbarprogress.h:30
3 | [cppcheck_files]
4 | [cppcheck_includes]
5 |
--------------------------------------------------------------------------------
/settings/csettings.cpp:
--------------------------------------------------------------------------------
1 | #include "csettings.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include
5 | RESTORE_COMPILER_WARNINGS
6 |
7 | QString CSettings::_applicationName;
8 | QString CSettings::_organizationName;
9 | QSettings::Format CSettings::_settingsFormat = QSettings::NativeFormat;
10 |
11 | CSettings::CSettings() noexcept :
12 | _impl{
13 | _settingsFormat, QSettings::UserScope,
14 | _organizationName.isEmpty() ? qApp->organizationName() : _organizationName,
15 | _applicationName.isEmpty() ? qApp->applicationName() : _applicationName
16 | }
17 | {
18 | }
19 |
20 | void CSettings::setApplicationName(const QString &name)
21 | {
22 | _applicationName = name;
23 | }
24 |
25 | void CSettings::setOrganizationName(const QString &name)
26 | {
27 | _organizationName = name;
28 | }
29 |
30 | void CSettings::setFormat(QSettings::Format format)
31 | {
32 | _settingsFormat = format;
33 | }
34 |
35 | void CSettings::setValue(const QString & key, const QVariant & value)
36 | {
37 | _impl.setValue(key, value);
38 | }
39 |
40 | QVariant CSettings::value(const QString & key, const QVariant & defaultValue) const
41 | {
42 | return _impl.value(key, defaultValue);
43 | }
44 |
45 | QStringList CSettings::allKeys() const
46 | {
47 | return _impl.allKeys();
48 | }
49 |
50 | void CSettings::clear()
51 | {
52 | _impl.clear();
53 | }
54 |
--------------------------------------------------------------------------------
/settings/csettings.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | class CSettings
10 | {
11 | public:
12 | CSettings() noexcept;
13 |
14 | static void setApplicationName(const QString& name);
15 | static void setOrganizationName(const QString& name);
16 | static void setFormat(QSettings::Format format);
17 |
18 | void setValue(const QString& key, const QVariant& value);
19 | [[nodiscard]] QVariant value(const QString& key, const QVariant& defaultValue = QVariant()) const;
20 |
21 | [[nodiscard]] QStringList allKeys() const;
22 |
23 | void clear();
24 |
25 | private:
26 | QSettings _impl;
27 |
28 | static QString _applicationName;
29 | static QString _organizationName;
30 | static QSettings::Format _settingsFormat;
31 | };
32 |
33 |
--------------------------------------------------------------------------------
/settings/settings.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | settings/csettings.h
3 |
4 | SOURCES += \
5 | settings/csettings.cpp
6 |
--------------------------------------------------------------------------------
/settingsui/csettingsdialog.cpp:
--------------------------------------------------------------------------------
1 | #include "csettingsdialog.h"
2 | #include "csettingspage.h"
3 | #include "ui_csettingsdialog.h"
4 | #include "../settings/csettings.h"
5 | #include "assert/advanced_assert.h"
6 |
7 | DISABLE_COMPILER_WARNINGS
8 | #include
9 | #include
10 | RESTORE_COMPILER_WARNINGS
11 |
12 | CSettingsDialog::CSettingsDialog(QWidget *parent) noexcept :
13 | QDialog(parent),
14 | ui(new Ui::CSettingsDialog)
15 | {
16 | ui->setupUi(this);
17 |
18 | // The list doesn't expand, the settings pane does
19 | ui->splitter->setStretchFactor(0, 0);
20 | ui->splitter->setStretchFactor(1, 1);
21 |
22 | connect(ui->pageList, &QListWidget::currentItemChanged, this, &CSettingsDialog::pageChanged);
23 | ui->pageList->setResizeMode(QListWidget::Adjust);
24 |
25 | new QShortcut(QKeySequence("Ctrl+Shift+W"), this, this, &CSettingsDialog::wipeSettings);
26 |
27 | ui->pageList->setFocus();
28 | setTabOrder(ui->pageList, nullptr);
29 | }
30 |
31 | CSettingsDialog::~CSettingsDialog()
32 | {
33 | delete ui;
34 | }
35 |
36 | CSettingsDialog& CSettingsDialog::addSettingsPage(CSettingsPage* page, const QString &pageName)
37 | {
38 | page->setParent(this);
39 | ui->pages->addWidget(page);
40 |
41 | QListWidgetItem * item = new QListWidgetItem(pageName.isEmpty() ? page->windowTitle() : pageName);
42 | item->setData(Qt::UserRole, ui->pages->count()-1);
43 | ui->pageList->addItem(item);
44 |
45 | if (ui->pages->count() == 1)
46 | {
47 | ui->pageList->setCurrentRow(0);
48 | setTabOrder(ui->pageList, page);
49 | }
50 | else
51 | setTabOrder(ui->pages->widget(ui->pages->count() - 1), page);
52 |
53 | ui->pageList->adjustSize();
54 |
55 | return *this;
56 | }
57 |
58 | void CSettingsDialog::pageChanged(QListWidgetItem * item)
59 | {
60 | const int pageIndex = item->data(Qt::UserRole).toInt();
61 | ui->pages->setCurrentIndex(pageIndex);
62 | }
63 |
64 | void CSettingsDialog::wipeSettings()
65 | {
66 | if (QMessageBox::question(this, tr("Wipe settings"), tr("Wipe all settings?")) == QMessageBox::Yes)
67 | {
68 | CSettings{}.clear();
69 | exit(0); // Exiting immediately so that the current application state cannot be re-saved upon next normal exit
70 | }
71 | }
72 |
73 | void CSettingsDialog::accept()
74 | {
75 | for (int i = 0; i < ui->pages->count(); ++i)
76 | {
77 | CSettingsPage * page = dynamic_cast(ui->pages->widget(i));
78 | assert_r(page);
79 | page->acceptSettings();
80 | }
81 |
82 | emit settingsChanged();
83 |
84 | QDialog::accept();
85 | }
86 |
--------------------------------------------------------------------------------
/settingsui/csettingsdialog.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | namespace Ui {
10 | class CSettingsDialog;
11 | }
12 |
13 | class CSettingsPage;
14 |
15 | class QListWidgetItem;
16 |
17 | class CSettingsDialog final : public QDialog
18 | {
19 | Q_OBJECT
20 | public:
21 | explicit CSettingsDialog(QWidget *parent = nullptr) noexcept;
22 | ~CSettingsDialog() override;
23 |
24 | CSettingsDialog& addSettingsPage(CSettingsPage * page, const QString& pageName = QString());
25 |
26 | signals:
27 | void settingsChanged();
28 |
29 | private:
30 | void pageChanged(QListWidgetItem *item);
31 | void wipeSettings();
32 |
33 | private slots:
34 | void accept() override;
35 |
36 | private:
37 | Ui::CSettingsDialog *ui;
38 | };
39 |
--------------------------------------------------------------------------------
/settingsui/csettingsdialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | CSettingsDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 622
10 | 437
11 |
12 |
13 |
14 | Settings
15 |
16 |
17 | -
18 |
19 |
20 | Qt::Horizontal
21 |
22 |
23 | false
24 |
25 |
26 | false
27 |
28 |
29 |
30 |
31 |
32 | 50
33 | 0
34 |
35 |
36 |
37 |
38 |
39 | -
40 |
41 |
42 | Qt::TabFocus
43 |
44 |
45 | Qt::Horizontal
46 |
47 |
48 | QDialogButtonBox::Cancel|QDialogButtonBox::Save
49 |
50 |
51 |
52 |
53 |
54 |
55 | pageList
56 |
57 |
58 |
59 |
60 | buttonBox
61 | accepted()
62 | CSettingsDialog
63 | accept()
64 |
65 |
66 | 248
67 | 254
68 |
69 |
70 | 157
71 | 274
72 |
73 |
74 |
75 |
76 | buttonBox
77 | rejected()
78 | CSettingsDialog
79 | reject()
80 |
81 |
82 | 316
83 | 260
84 |
85 |
86 | 286
87 | 274
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/settingsui/csettingspage.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | class CSettingsPage : public QWidget
10 | {
11 | public:
12 | using QWidget::QWidget;
13 |
14 | virtual void acceptSettings() = 0;
15 | };
16 |
--------------------------------------------------------------------------------
/settingsui/settingsui.pri:
--------------------------------------------------------------------------------
1 | FORMS += \
2 | settingsui/csettingsdialog.ui
3 |
4 | HEADERS += \
5 | settingsui/csettingsdialog.h \
6 | settingsui/csettingspage.h
7 |
8 | SOURCES += \
9 | settingsui/csettingsdialog.cpp
10 |
--------------------------------------------------------------------------------
/std_helpers/qt_container_helpers.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | template
10 | std::vector to_vector(const Container& qtContainer)
11 | {
12 | using T = typename Container::value_type;
13 | std::vector v;
14 | v.reserve((size_t)qtContainer.size());
15 |
16 | std::copy(std::cbegin(qtContainer), std::cend(qtContainer), std::back_inserter(v));
17 | return v;
18 | }
19 |
20 | template
21 | std::vector to_vector(Container&& qtContainer)
22 | {
23 | static_assert (std::is_rvalue_reference_v);
24 | using T = typename Container::value_type;
25 | std::vector v;
26 | const size_t size = static_cast(qtContainer.size());
27 | v.reserve(size);
28 | for (int i = 0; i < static_cast(size); ++i)
29 | v.emplace_back(std::move(qtContainer[i]));
30 |
31 | return v;
32 | }
33 |
34 | template
35 | std::vector to_vector(const Container& qtContainer)
36 | {
37 | std::vector v;
38 | v.reserve((size_t)qtContainer.size());
39 |
40 | std::copy(std::cbegin(qtContainer), std::cend(qtContainer), std::back_inserter(v));
41 | return v;
42 | }
43 |
44 | template class StdContainer, typename T, template class QtContainer>
45 | QtContainer from_std_container(const StdContainer& stdContainer)
46 | {
47 | QtContainer qtContainer;
48 | std::copy(std::cbegin(stdContainer), std::cend(stdContainer), std::back_inserter(qtContainer));
49 |
50 | return qtContainer;
51 | }
52 |
--------------------------------------------------------------------------------
/std_helpers/std_helpers.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | $$PWD/qt_container_helpers.hpp
3 |
--------------------------------------------------------------------------------
/string/string.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | $$PWD/stringutils.h
3 |
4 | SOURCES += \
5 | $$PWD/stringutils.cpp
6 |
--------------------------------------------------------------------------------
/string/stringutils.cpp:
--------------------------------------------------------------------------------
1 | #include "stringutils.h"
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | #include
10 |
11 | size_t lineNumberForPosition(const QString &text, int pos) noexcept
12 | {
13 | return static_cast(std::count(text.begin(), text.begin() + pos, '\n'));
14 | }
15 |
--------------------------------------------------------------------------------
/string/stringutils.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | class QString;
6 |
7 | [[nodiscard]] size_t lineNumberForPosition(const QString& text, int pos) noexcept;
8 |
--------------------------------------------------------------------------------
/taskbarprogress/cprogressbartaskbar.cpp:
--------------------------------------------------------------------------------
1 | #include "cprogressbartaskbar.h"
2 |
3 | CProgressBarTaskbar::CProgressBarTaskbar(QWidget *parent) noexcept :
4 | QProgressBar(parent)
5 | {
6 | connect (this, &CProgressBarTaskbar::valueChanged, this, &CProgressBarTaskbar::progressChanged);
7 | }
8 |
9 | void CProgressBarTaskbar::linkToWidgetstaskbarButton(QWidget *widget)
10 | {
11 | if (widget)
12 | _taskBarProgress = std::make_shared(widget);
13 | }
14 |
15 | void CProgressBarTaskbar::setState(ProgressState state)
16 | {
17 | _state = state;
18 | updateState();
19 | }
20 |
21 | void CProgressBarTaskbar::setVisible(bool visible)
22 | {
23 | QProgressBar::setVisible(visible);
24 | updateState();
25 | }
26 |
27 | void CProgressBarTaskbar::updateState()
28 | {
29 | if (_taskBarProgress)
30 | _taskBarProgress->setState(isVisible() ? (_state) : psNoProgress);
31 | }
32 |
33 | void CProgressBarTaskbar::progressChanged(int progress)
34 | {
35 | if (_taskBarProgress)
36 | _taskBarProgress->setProgress(progress, minimum(), maximum());
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/taskbarprogress/cprogressbartaskbar.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "taskbarprogress/ctaskbarprogress.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | #include
10 |
11 | class CProgressBarTaskbar final : public QProgressBar
12 | {
13 | public:
14 | explicit CProgressBarTaskbar(QWidget *parent = nullptr) noexcept;
15 | void linkToWidgetstaskbarButton(QWidget * widget);
16 |
17 | void setState(ProgressState state);
18 | void setVisible(bool visible) override;
19 |
20 | private:
21 | void updateState();
22 | void progressChanged(int progress);
23 |
24 | private:
25 | std::shared_ptr _taskBarProgress;
26 | ProgressState _state = psNormal;
27 | };
28 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | taskbarprogress/cprogressbartaskbar.h \
3 | taskbarprogress/taskbarprogress/ctaskbarprogress.h
4 |
5 | SOURCES += taskbarprogress/cprogressbartaskbar.cpp
6 |
7 |
8 | win*{
9 | SOURCES += taskbarprogress/taskbarprogress/ctaskbarprogress_win.cpp \
10 |
11 | }
12 |
13 | mac*{
14 | SOURCES += taskbarprogress/taskbarprogress/ctaskbarprogress_mac.cpp \
15 |
16 | }
17 |
18 | linux*{
19 | SOURCES += taskbarprogress/taskbarprogress/ctaskbarprogress_linux.cpp \
20 |
21 | }
22 | freebsd{
23 | SOURCES += taskbarprogress/taskbarprogress/ctaskbarprogress_freebsd.cpp \
24 |
25 | }
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/ctaskbarprogress.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | enum ProgressState { psNormal, psPaused, psStopped, psIndeterminate, psNoProgress };
6 |
7 | #if defined _WIN32
8 |
9 | DISABLE_COMPILER_WARNINGS
10 | #include
11 | #include
12 | RESTORE_COMPILER_WARNINGS
13 |
14 | #include
15 |
16 | struct ITaskbarList3;
17 |
18 | class CTaskBarProgress final : protected QAbstractNativeEventFilter
19 | {
20 | public:
21 | explicit CTaskBarProgress(QWidget * widget = nullptr) noexcept;
22 | ~CTaskBarProgress() noexcept override;
23 |
24 | void linkToWidgetsTaskbarButton (QWidget * widget);
25 | void setProgress (int progress, int minValue = 0, int maxValue = 100);
26 | void setState (ProgressState state);
27 |
28 | private:
29 | ITaskbarList3 * taskbarListInterface ();
30 |
31 | static bool eventFilter (void * msg);
32 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
33 | bool nativeEventFilter(const QByteArray & eventType, void * message, qintptr * result) override;
34 | #else
35 | bool nativeEventFilter(const QByteArray & eventType, void * message, long * result) override;
36 | #endif
37 | static bool widgetAlreadyLinked (const QWidget * widget);
38 |
39 | private:
40 | static std::unordered_map _taskbarButtonCreatedMessageIdMap;
41 | // List of the widgets with which linkWithWidgetstaskbarButton have already been called.
42 | // It's used to guard against linking different progress bar instances to the same taskbar button.
43 | static std::unordered_map _registeredWidgetsList;
44 | static std::unordered_map _taskbarListInterface;
45 | };
46 |
47 | #elif defined __APPLE__
48 |
49 | class QWidget;
50 |
51 | class CTaskBarProgress
52 | {
53 | public:
54 | explicit CTaskBarProgress(QWidget * widget = nullptr);
55 |
56 | void linkToWidgetsTaskbarButton (QWidget * widget);
57 | void setProgress (int progress, int minValue = 0, int maxValue = 100);
58 | void setState (ProgressState state);
59 | };
60 |
61 | #elif defined __linux__ || defined __FreeBSD__
62 |
63 | class QWidget;
64 |
65 | class CTaskBarProgress
66 | {
67 | public:
68 | explicit CTaskBarProgress(QWidget * widget = nullptr);
69 |
70 | void linkToWidgetsTaskbarButton(QWidget * widget);
71 | void setProgress(int progress, int minValue = 0, int maxValue = 100);
72 | void setState(ProgressState state);
73 |
74 | private:
75 | QWidget * _parent = nullptr;
76 | };
77 |
78 | #endif // _WIN32 / __APPLE__
79 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/ctaskbarprogress_freebsd.cpp:
--------------------------------------------------------------------------------
1 | #include "ctaskbarprogress.h"
2 | #include "linux/qxttooltip.h"
3 |
4 | CTaskBarProgress::CTaskBarProgress(QWidget * widget) : _parent(widget)
5 | {
6 | }
7 |
8 | void CTaskBarProgress::linkToWidgetsTaskbarButton(QWidget * /*widget*/)
9 | {
10 | }
11 |
12 | void CTaskBarProgress::setProgress(int /*progress*/, int /*minValue*/ /*= 0*/, int /*maxValue*/ /*= 100*/)
13 | {
14 | }
15 |
16 | void CTaskBarProgress::setState(ProgressState /*state*/)
17 | {
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/ctaskbarprogress_linux.cpp:
--------------------------------------------------------------------------------
1 | #include "ctaskbarprogress.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include "linux/qxttooltip.h"
5 | RESTORE_COMPILER_WARNINGS
6 |
7 | CTaskBarProgress::CTaskBarProgress(QWidget * widget /*= 0*/) : _parent(widget)
8 | {
9 | }
10 |
11 | void CTaskBarProgress::linkToWidgetsTaskbarButton(QWidget * widget)
12 | {
13 | }
14 |
15 | void CTaskBarProgress::setProgress(int progress, int minValue /*= 0*/, int maxValue /*= 100*/)
16 | {
17 | }
18 |
19 | void CTaskBarProgress::setState(ProgressState state)
20 | {
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/ctaskbarprogress_mac.cpp:
--------------------------------------------------------------------------------
1 | #include "ctaskbarprogress.h"
2 |
3 | CTaskBarProgress::CTaskBarProgress(QWidget * /*widget*/ /*= 0*/)
4 | {
5 |
6 | }
7 |
8 | void CTaskBarProgress::linkToWidgetsTaskbarButton (QWidget * /*widget*/)
9 | {
10 |
11 | }
12 |
13 | void CTaskBarProgress::setProgress (int /*progress*/, int /*minValue*/ /*= 0*/, int /*maxValue*/ /*= 100*/)
14 | {
15 |
16 | }
17 |
18 | void CTaskBarProgress::setState (ProgressState /*state*/)
19 | {
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/ctaskbarprogress_win.cpp:
--------------------------------------------------------------------------------
1 | #include "ctaskbarprogress.h"
2 | #include "compiler/compiler_warnings_control.h"
3 | #include "assert/advanced_assert.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | #include
11 |
12 | CTaskBarProgress::CTaskBarProgress(QWidget *widget) noexcept
13 | {
14 | if (widget)
15 | linkToWidgetsTaskbarButton(widget);
16 | }
17 |
18 | CTaskBarProgress::~CTaskBarProgress() noexcept
19 | {
20 | qApp->removeNativeEventFilter(this);
21 |
22 | ITaskbarList3 * iface = taskbarListInterface();
23 | if (iface)
24 | iface->Release();
25 | }
26 |
27 | void CTaskBarProgress::linkToWidgetsTaskbarButton(QWidget *widget)
28 | {
29 | if (!widget)
30 | {
31 | qInfo() << __FUNCTION__ << ": widget is null";
32 | return;
33 | }
34 |
35 | if (widgetAlreadyLinked(widget))
36 | {
37 | qInfo() << __FUNCTION__ << ": CProgressBarTaskbar instance" << Qt::hex << this << " is trying to link to QWidget " << Qt::hex << widget << ", whose taskbar button has already been linked to";
38 | return;
39 | }
40 |
41 | _registeredWidgetsList[this] = widget;
42 | _taskbarButtonCreatedMessageIdMap[widget->winId()] = RegisterWindowMessageW(L"TaskbarButtonCreated");
43 |
44 | // Care: creating winId leads to creating a window which leads to creating a Window which leads to window procedure starting up, so you should only register event filter afterwards
45 | qApp->installNativeEventFilter(this);
46 | }
47 |
48 | void CTaskBarProgress::setProgress(int progress, int minValue /* = 0*/, int maxValue /* = 100*/)
49 | {
50 | ITaskbarList3 * iface = taskbarListInterface();
51 | if (iface)
52 | iface->SetProgressValue(HWND(_registeredWidgetsList[this]->winId()), progress, maxValue - minValue);
53 | }
54 |
55 | void CTaskBarProgress::setState(ProgressState state)
56 | {
57 | ITaskbarList3 * iface = taskbarListInterface();
58 | TBPFLAG taskbarProgressState = TBPF_NOPROGRESS;
59 | switch (state)
60 | {
61 | case psNormal:
62 | taskbarProgressState = TBPF_NORMAL;
63 | break;
64 | case psPaused:
65 | taskbarProgressState = TBPF_PAUSED;
66 | break;
67 | case psStopped:
68 | taskbarProgressState = TBPF_ERROR;
69 | break;
70 | case psIndeterminate:
71 | taskbarProgressState = TBPF_INDETERMINATE;
72 | break;
73 | case psNoProgress: [[fallthrough]];
74 | default:
75 | taskbarProgressState = TBPF_NOPROGRESS;
76 | break;
77 | }
78 |
79 | if (iface)
80 | iface->SetProgressState(HWND(_registeredWidgetsList[this]->winId()), taskbarProgressState);
81 | }
82 |
83 | bool CTaskBarProgress::eventFilter(void *msg)
84 | {
85 | MSG * message = static_cast(msg);
86 | assert_and_return_r(message, false);
87 |
88 | if (!_taskbarButtonCreatedMessageIdMap.contains(WId(message->hwnd)))
89 | return false;
90 |
91 | if (message->message == _taskbarButtonCreatedMessageIdMap[WId(message->hwnd)] && !_taskbarListInterface.contains(WId(message->hwnd)))
92 | {
93 | ITaskbarList3 * iface = nullptr;
94 | HRESULT result = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, IID_ITaskbarList3, reinterpret_cast(&iface));
95 | if (result != S_OK || !iface)
96 | qInfo() << "ITaskbarList3 creation failed";
97 | else
98 | {
99 | _taskbarListInterface[WId(message->hwnd)] = iface;
100 | }
101 | }
102 |
103 | return false;
104 | }
105 |
106 | bool CTaskBarProgress::widgetAlreadyLinked(const QWidget * widget)
107 | {
108 | for (const auto& item: _registeredWidgetsList)
109 | {
110 | if (item.second == widget)
111 | return true;
112 | }
113 |
114 | return false;
115 | }
116 |
117 | ITaskbarList3 * CTaskBarProgress::taskbarListInterface()
118 | {
119 | if (!_registeredWidgetsList.contains(this) || _registeredWidgetsList[this] == nullptr || !_taskbarListInterface.contains(_registeredWidgetsList[this]->winId()))
120 | return nullptr;
121 | else
122 | return _taskbarListInterface[_registeredWidgetsList[this]->winId()];
123 | }
124 |
125 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
126 | bool CTaskBarProgress::nativeEventFilter(const QByteArray & /*eventType*/, void * message, qintptr * /*result*/)
127 | #else
128 | bool CTaskBarProgress::nativeEventFilter(const QByteArray & /*eventType*/, void * message, long * /*result*/)
129 | #endif
130 | {
131 | return eventFilter(message);
132 | }
133 |
134 | std::unordered_map CTaskBarProgress::_taskbarListInterface;
135 | std::unordered_map CTaskBarProgress::_registeredWidgetsList;
136 | std::unordered_map CTaskBarProgress::_taskbarButtonCreatedMessageIdMap;
137 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/freebsd/qxtglobal.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtCore module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 |
26 | #ifndef QXTGLOBAL_H
27 | #define QXTGLOBAL_H
28 |
29 | #include
30 |
31 | #define QXT_VERSION 0x000602
32 | #define QXT_VERSION_STR "0.6.2"
33 |
34 | //--------------------------global macros------------------------------
35 |
36 | #ifndef QXT_NO_MACROS
37 |
38 | #endif // QXT_NO_MACROS
39 |
40 | //--------------------------export macros------------------------------
41 |
42 | #define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
43 |
44 | #if !defined(QXT_STATIC)
45 | # if defined(BUILD_QXT_CORE)
46 | # define QXT_CORE_EXPORT Q_DECL_EXPORT
47 | # else
48 | # define QXT_CORE_EXPORT Q_DECL_IMPORT
49 | # endif
50 | #else
51 | # define QXT_CORE_EXPORT
52 | #endif // BUILD_QXT_CORE
53 |
54 | #if !defined(QXT_STATIC)
55 | # if defined(BUILD_QXT_GUI)
56 | # define QXT_GUI_EXPORT Q_DECL_EXPORT
57 | # else
58 | # define QXT_GUI_EXPORT Q_DECL_IMPORT
59 | # endif
60 | #else
61 | # define QXT_GUI_EXPORT
62 | #endif // BUILD_QXT_GUI
63 |
64 | #if !defined(QXT_STATIC)
65 | # if defined(BUILD_QXT_NETWORK)
66 | # define QXT_NETWORK_EXPORT Q_DECL_EXPORT
67 | # else
68 | # define QXT_NETWORK_EXPORT Q_DECL_IMPORT
69 | # endif
70 | #else
71 | # define QXT_NETWORK_EXPORT
72 | #endif // BUILD_QXT_NETWORK
73 |
74 | #if !defined(QXT_STATIC)
75 | # if defined(BUILD_QXT_SQL)
76 | # define QXT_SQL_EXPORT Q_DECL_EXPORT
77 | # else
78 | # define QXT_SQL_EXPORT Q_DECL_IMPORT
79 | # endif
80 | #else
81 | # define QXT_SQL_EXPORT
82 | #endif // BUILD_QXT_SQL
83 |
84 | #if !defined(QXT_STATIC)
85 | # if defined(BUILD_QXT_WEB)
86 | # define QXT_WEB_EXPORT Q_DECL_EXPORT
87 | # else
88 | # define QXT_WEB_EXPORT Q_DECL_IMPORT
89 | # endif
90 | #else
91 | # define QXT_WEB_EXPORT
92 | #endif // BUILD_QXT_WEB
93 |
94 | #if !defined(QXT_STATIC)
95 | # if defined(BUILD_QXT_BERKELEY)
96 | # define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
97 | # else
98 | # define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
99 | # endif
100 | #else
101 | # define QXT_BERKELEY_EXPORT
102 | #endif // BUILD_QXT_BERKELEY
103 |
104 | #if !defined(QXT_STATIC)
105 | # if defined(BUILD_QXT_ZEROCONF)
106 | # define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
107 | # else
108 | # define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
109 | # endif
110 | #else
111 | # define QXT_ZEROCONF_EXPORT
112 | #endif // QXT_ZEROCONF_EXPORT
113 |
114 | #if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
115 | # define BUILD_QXT
116 | #endif
117 |
118 | QXT_CORE_EXPORT const char* qxtVersion();
119 |
120 | #ifndef QT_BEGIN_NAMESPACE
121 | #define QT_BEGIN_NAMESPACE
122 | #endif
123 |
124 | #ifndef QT_END_NAMESPACE
125 | #define QT_END_NAMESPACE
126 | #endif
127 |
128 | #ifndef QT_FORWARD_DECLARE_CLASS
129 | #define QT_FORWARD_DECLARE_CLASS(Class) class Class;
130 | #endif
131 |
132 | /****************************************************************************
133 | ** This file is derived from code bearing the following notice:
134 | ** The sole author of this file, Adam Higerd, has explicitly disclaimed all
135 | ** copyright interest and protection for the content within. This file has
136 | ** been placed in the public domain according to United States copyright
137 | ** statute and case law. In jurisdictions where this public domain dedication
138 | ** is not legally recognized, anyone who receives a copy of this file is
139 | ** permitted to use, modify, duplicate, and redistribute this file, in whole
140 | ** or in part, with no restrictions or conditions. In these jurisdictions,
141 | ** this file shall be copyright (C) 2006-2008 by Adam Higerd.
142 | ****************************************************************************/
143 |
144 | #define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d;
145 | #define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
146 | #define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
147 | #define QXT_D(PUB) PUB##Private& d = qxt_d()
148 | #define QXT_P(PUB) PUB& p = qxt_p()
149 |
150 | template
151 | class QxtPrivate
152 | {
153 | public:
154 | virtual ~QxtPrivate()
155 | {}
156 | inline void QXT_setPublic(PUB* pub)
157 | {
158 | qxt_p_ptr = pub;
159 | }
160 |
161 | protected:
162 | inline PUB& qxt_p()
163 | {
164 | return *qxt_p_ptr;
165 | }
166 | inline const PUB& qxt_p() const
167 | {
168 | return *qxt_p_ptr;
169 | }
170 |
171 | private:
172 | PUB* qxt_p_ptr;
173 | };
174 |
175 | template
176 | class QxtPrivateInterface
177 | {
178 | friend class QxtPrivate;
179 | public:
180 | QxtPrivateInterface()
181 | {
182 | pvt = new PVT;
183 | }
184 | ~QxtPrivateInterface()
185 | {
186 | delete pvt;
187 | }
188 |
189 | inline void setPublic(PUB* pub)
190 | {
191 | pvt->QXT_setPublic(pub);
192 | }
193 | inline PVT& operator()()
194 | {
195 | return *static_cast(pvt);
196 | }
197 | inline const PVT& operator()() const
198 | {
199 | return *static_cast(pvt);
200 | }
201 | private:
202 | QxtPrivateInterface(const QxtPrivateInterface&) { }
203 | QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
204 | QxtPrivate* pvt;
205 | };
206 |
207 | #endif // QXT_GLOBAL
208 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/freebsd/qxttooltip.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtGui module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 | #include "qxttooltip.h"
26 | #include "qxttooltip_p.h"
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 |
41 | static const Qt::WindowFlags FLAGS = Qt::ToolTip;
42 |
43 | QxtToolTipPrivate* QxtToolTipPrivate::self = 0;
44 |
45 | QxtToolTipPrivate* QxtToolTipPrivate::instance()
46 | {
47 | if (!self)
48 | self = new QxtToolTipPrivate();
49 | return self;
50 | }
51 |
52 | QxtToolTipPrivate::QxtToolTipPrivate() : QWidget(qApp->desktop(), FLAGS)
53 | {
54 | setWindowFlags(FLAGS);
55 | vbox = new QVBoxLayout(this);
56 | setPalette(QToolTip::palette());
57 | setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
58 | layout()->setMargin(style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, this));
59 | qApp->installEventFilter(this);
60 | }
61 |
62 | QxtToolTipPrivate::~QxtToolTipPrivate()
63 | {
64 | qApp->removeEventFilter(this); // not really necessary but rather for completeness :)
65 | self = 0;
66 | }
67 |
68 | void QxtToolTipPrivate::show(const QPoint& pos, QWidget* tooltip, QWidget* parent, const QRect& rect)
69 | {
70 | Q_ASSERT(tooltip && parent);
71 | if (!isVisible())
72 | {
73 | int scr = 0;
74 | if (QApplication::desktop()->isVirtualDesktop())
75 | scr = QApplication::desktop()->screenNumber(pos);
76 | else
77 | scr = QApplication::desktop()->screenNumber(this);
78 | setParent(QApplication::desktop()->screen(scr));
79 | setWindowFlags(FLAGS);
80 | setToolTip(tooltip);
81 | currentParent = parent;
82 | currentRect = rect;
83 | move(calculatePos(scr, pos));
84 | QWidget::show();
85 | }
86 | }
87 |
88 | void QxtToolTipPrivate::setToolTip(QWidget* tooltip)
89 | {
90 | for (int i = 0; i < vbox->count(); ++i)
91 | {
92 | QLayoutItem* item = layout()->takeAt(i);
93 | if (item->widget())
94 | item->widget()->hide();
95 | }
96 | vbox->addWidget(tooltip);
97 | tooltip->show();
98 | }
99 |
100 | void QxtToolTipPrivate::enterEvent(QEvent* event)
101 | {
102 | Q_UNUSED(event);
103 | hideLater();
104 | }
105 |
106 | void QxtToolTipPrivate::paintEvent(QPaintEvent* event)
107 | {
108 | Q_UNUSED(event);
109 | QStylePainter painter(this);
110 | QStyleOptionFrame opt;
111 | opt.initFrom(this);
112 | painter.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
113 | }
114 |
115 | bool QxtToolTipPrivate::eventFilter(QObject* object, QEvent* event)
116 | {
117 | switch (event->type())
118 | {
119 | case QEvent::KeyPress:
120 | case QEvent::KeyRelease:
121 | {
122 | // accept only modifiers
123 | const QKeyEvent* keyEvent = static_cast(event);
124 | const int key = keyEvent->key();
125 | const Qt::KeyboardModifiers mods = keyEvent->modifiers();
126 | if ((mods & Qt::KeyboardModifierMask) ||
127 | (key == Qt::Key_Shift || key == Qt::Key_Control ||
128 | key == Qt::Key_Alt || key == Qt::Key_Meta))
129 | break;
130 | }
131 | case QEvent::Leave:
132 | case QEvent::WindowActivate:
133 | case QEvent::WindowDeactivate:
134 | case QEvent::MouseButtonPress:
135 | case QEvent::MouseButtonRelease:
136 | case QEvent::MouseButtonDblClick:
137 | case QEvent::FocusIn:
138 | case QEvent::FocusOut:
139 | case QEvent::Wheel:
140 | hideLater();
141 | break;
142 |
143 | case QEvent::MouseMove:
144 | {
145 | const QPoint pos = static_cast(event)->pos();
146 | if (!currentRect.isNull() && !currentRect.contains(pos))
147 | {
148 | hideLater();
149 | }
150 | break;
151 | }
152 |
153 | case QEvent::ToolTip:
154 | {
155 | // eat appropriate tooltip events
156 | QWidget* widget = static_cast(object);
157 | if (tooltips.contains(widget))
158 | {
159 | QHelpEvent* helpEvent = static_cast(event);
160 | const QRect area = tooltips.value(widget).second;
161 | if (area.isNull() || area.contains(helpEvent->pos()))
162 | {
163 | show(helpEvent->globalPos(), tooltips.value(widget).first, widget, area);
164 | return true;
165 | }
166 | }
167 | }
168 |
169 | default:
170 | break;
171 | }
172 | return false;
173 | }
174 |
175 | void QxtToolTipPrivate::hideLater()
176 | {
177 | currentRect = QRect();
178 | if (isVisible())
179 | QTimer::singleShot(0, this, SLOT(hide()));
180 | }
181 |
182 | QPoint QxtToolTipPrivate::calculatePos(int scr, const QPoint& eventPos) const
183 | {
184 | #ifdef Q_WS_MAC
185 | QRect screen = QApplication::desktop()->availableGeometry(scr);
186 | #else
187 | QRect screen = QApplication::desktop()->screenGeometry(scr);
188 | #endif
189 |
190 | QPoint p = eventPos;
191 | p += QPoint(2,
192 | #ifdef Q_WS_WIN
193 | 24
194 | #else
195 | 16
196 | #endif
197 | );
198 | QSize s = sizeHint();
199 | if (p.x() + s.width() > screen.x() + screen.width())
200 | p.rx() -= 4 + s.width();
201 | if (p.y() + s.height() > screen.y() + screen.height())
202 | p.ry() -= 24 + s.height();
203 | if (p.y() < screen.y())
204 | p.setY(screen.y());
205 | if (p.x() + s.width() > screen.x() + screen.width())
206 | p.setX(screen.x() + screen.width() - s.width());
207 | if (p.x() < screen.x())
208 | p.setX(screen.x());
209 | if (p.y() + s.height() > screen.y() + screen.height())
210 | p.setY(screen.y() + screen.height() - s.height());
211 | return p;
212 | }
213 |
214 | /*!
215 | \class QxtToolTip
216 | \inmodule QxtGui
217 | \brief The QxtToolTip class provides means for showing any arbitrary widget as a tooltip.
218 |
219 | QxtToolTip provides means for showing any arbitrary widget as a tooltip.
220 |
221 | \bold {Note:} The rich text support of QToolTip already makes it possible to
222 | show heavily customized tooltips with lists, tables, embedded images
223 | and such. However, for example dynamically created images like
224 | thumbnails cause problems. Basically the only way is to dump the
225 | thumbnail to a temporary file to be able to embed it into HTML. This
226 | is where QxtToolTip steps in. A generated thumbnail may simply be set
227 | on a QLabel which is then shown as a tooltip. Yet another use case
228 | is a tooltip with dynamically changing content.
229 |
230 | \image qxttooltip.png "QxtToolTip in action."
231 |
232 | \warning Added tooltip widgets remain in the memory for the lifetime
233 | of the application or until they are removed/deleted. Do NOT flood your
234 | application up with lots of complex tooltip widgets or it will end up
235 | being a resource hog. QToolTip is sufficient for most of the cases!
236 | */
237 |
238 | /*!
239 | \internal
240 | */
241 | QxtToolTip::QxtToolTip()
242 | {
243 | }
244 |
245 | /*!
246 | Shows the \a tooltip at \a pos for \a parent at \a rect.
247 |
248 | \sa hide()
249 | */
250 | void QxtToolTip::show(const QPoint& pos, QWidget* tooltip, QWidget* parent, const QRect& rect)
251 | {
252 | QxtToolTipPrivate::instance()->show(pos, tooltip, parent, rect);
253 | }
254 |
255 | /*!
256 | Hides the tooltip.
257 |
258 | \sa show()
259 | */
260 | void QxtToolTip::hide()
261 | {
262 | QxtToolTipPrivate::instance()->hide();
263 | }
264 |
265 | /*!
266 | Returns the tooltip for \a parent.
267 |
268 | \sa setToolTip()
269 | */
270 | QWidget* QxtToolTip::toolTip(QWidget* parent)
271 | {
272 | Q_ASSERT(parent);
273 | QWidget* tooltip = 0;
274 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
275 | qWarning("QxtToolTip::toolTip: Unknown parent");
276 | else
277 | tooltip = QxtToolTipPrivate::instance()->tooltips.value(parent).first;
278 | return tooltip;
279 | }
280 |
281 | /*!
282 | Sets the \a tooltip to be shown for \a parent.
283 | An optional \a rect may also be passed.
284 |
285 | \sa toolTip()
286 | */
287 | void QxtToolTip::setToolTip(QWidget* parent, QWidget* tooltip, const QRect& rect)
288 | {
289 | Q_ASSERT(parent);
290 | if (tooltip)
291 | {
292 | // set
293 | tooltip->hide();
294 | QxtToolTipPrivate::instance()->tooltips[parent] = qMakePair(QPointer(tooltip), rect);
295 | }
296 | else
297 | {
298 | // remove
299 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
300 | qWarning("QxtToolTip::setToolTip: Unknown parent");
301 | else
302 | QxtToolTipPrivate::instance()->tooltips.remove(parent);
303 | }
304 | }
305 |
306 | /*!
307 | Returns the rect on which tooltip is shown for \a parent.
308 |
309 | \sa setToolTipRect()
310 | */
311 | QRect QxtToolTip::toolTipRect(QWidget* parent)
312 | {
313 | Q_ASSERT(parent);
314 | QRect rect;
315 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
316 | qWarning("QxtToolTip::toolTipRect: Unknown parent");
317 | else
318 | rect = QxtToolTipPrivate::instance()->tooltips.value(parent).second;
319 | return rect;
320 | }
321 |
322 | /*!
323 | Sets the \a rect on which tooltip is shown for \a parent.
324 |
325 | \sa toolTipRect()
326 | */
327 | void QxtToolTip::setToolTipRect(QWidget* parent, const QRect& rect)
328 | {
329 | Q_ASSERT(parent);
330 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
331 | qWarning("QxtToolTip::setToolTipRect: Unknown parent");
332 | else
333 | QxtToolTipPrivate::instance()->tooltips[parent].second = rect;
334 | }
335 |
336 | /*!
337 | Returns the margin of the tooltip.
338 |
339 | \sa setMargin()
340 | */
341 | int QxtToolTip::margin()
342 | {
343 | return QxtToolTipPrivate::instance()->layout()->margin();
344 | }
345 |
346 | /*!
347 | Sets the \a margin of the tooltip.
348 |
349 | The default value is QStyle::PM_ToolTipLabelFrameWidth.
350 |
351 | \sa margin()
352 | */
353 | void QxtToolTip::setMargin(int margin)
354 | {
355 | QxtToolTipPrivate::instance()->layout()->setMargin(margin);
356 | }
357 |
358 | /*!
359 | Returns the opacity level of the tooltip.
360 |
361 | \sa QWidget::windowOpacity()
362 | */
363 | qreal QxtToolTip::opacity()
364 | {
365 | return QxtToolTipPrivate::instance()->windowOpacity();
366 | }
367 |
368 | /*!
369 | Sets the opacity \a level of the tooltip.
370 |
371 | The default value is QStyle::SH_ToolTipLabel_Opacity.
372 |
373 | \sa QWidget::setWindowOpacity()
374 | */
375 | void QxtToolTip::setOpacity(qreal level)
376 | {
377 | QxtToolTipPrivate::instance()->setWindowOpacity(level);
378 | }
379 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/freebsd/qxttooltip.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtGui module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 | #ifndef QXTTOOLTIP_H
26 | #define QXTTOOLTIP_H
27 |
28 | #include
29 | #include
30 | #include
31 | #include "qxtglobal.h"
32 |
33 | class QXT_GUI_EXPORT QxtToolTip
34 | {
35 | QxtToolTip();
36 |
37 | public:
38 | static void show(const QPoint& pos, QWidget* tooltip, QWidget* parent = 0, const QRect& rect = QRect());
39 | static void hide();
40 |
41 | static QWidget* toolTip(QWidget* parent);
42 | static void setToolTip(QWidget* parent, QWidget* tooltip, const QRect& rect = QRect());
43 |
44 | static QRect toolTipRect(QWidget* parent);
45 | static void setToolTipRect(QWidget* parent, const QRect& rect);
46 |
47 | static int margin();
48 | static void setMargin(int margin);
49 |
50 | static qreal opacity();
51 | static void setOpacity(qreal level);
52 | };
53 |
54 | QT_BEGIN_NAMESPACE
55 | inline uint qHash(const QPointer key)
56 | {
57 | return reinterpret_cast(key ? (&*key) : 0);
58 | }
59 | QT_END_NAMESPACE
60 |
61 | #endif // QXTTOOLTIP_H
62 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/freebsd/qxttooltip_p.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtGui module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 | #ifndef QXTTOOLTIP_P_H
26 | #define QXTTOOLTIP_P_H
27 |
28 | #include
29 | #include
30 | #include
31 | #include "qxttooltip.h"
32 |
33 | QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
34 |
35 | typedef QPointer WidgetPtr;
36 | typedef QPair WidgetArea;
37 |
38 | class QxtToolTipPrivate : public QWidget
39 | {
40 | Q_OBJECT
41 |
42 | public:
43 | QxtToolTipPrivate();
44 | ~QxtToolTipPrivate();
45 |
46 | static QxtToolTipPrivate* instance();
47 | void show(const QPoint& pos, QWidget* tooltip, QWidget* parent = 0, const QRect& rect = QRect());
48 | void setToolTip(QWidget* tooltip);
49 | bool eventFilter(QObject* parent, QEvent* event);
50 | void hideLater();
51 | QPoint calculatePos(int scr, const QPoint& eventPos) const;
52 | QHash tooltips;
53 | QVBoxLayout* vbox;
54 |
55 | protected:
56 | void enterEvent(QEvent* event);
57 | void paintEvent(QPaintEvent* event);
58 |
59 | private:
60 | static QxtToolTipPrivate* self;
61 | QWidget* currentParent;
62 | QRect currentRect;
63 | };
64 |
65 | #endif // QXTTOOLTIP_P_H
66 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/linux/qxtglobal.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtCore module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 |
26 | #ifndef QXTGLOBAL_H
27 | #define QXTGLOBAL_H
28 |
29 | #include
30 |
31 | #define QXT_VERSION 0x000602
32 | #define QXT_VERSION_STR "0.6.2"
33 |
34 | //--------------------------global macros------------------------------
35 |
36 | #ifndef QXT_NO_MACROS
37 |
38 | #endif // QXT_NO_MACROS
39 |
40 | //--------------------------export macros------------------------------
41 |
42 | #define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
43 |
44 | #if !defined(QXT_STATIC)
45 | # if defined(BUILD_QXT_CORE)
46 | # define QXT_CORE_EXPORT Q_DECL_EXPORT
47 | # else
48 | # define QXT_CORE_EXPORT Q_DECL_IMPORT
49 | # endif
50 | #else
51 | # define QXT_CORE_EXPORT
52 | #endif // BUILD_QXT_CORE
53 |
54 | #if !defined(QXT_STATIC)
55 | # if defined(BUILD_QXT_GUI)
56 | # define QXT_GUI_EXPORT Q_DECL_EXPORT
57 | # else
58 | # define QXT_GUI_EXPORT Q_DECL_IMPORT
59 | # endif
60 | #else
61 | # define QXT_GUI_EXPORT
62 | #endif // BUILD_QXT_GUI
63 |
64 | #if !defined(QXT_STATIC)
65 | # if defined(BUILD_QXT_NETWORK)
66 | # define QXT_NETWORK_EXPORT Q_DECL_EXPORT
67 | # else
68 | # define QXT_NETWORK_EXPORT Q_DECL_IMPORT
69 | # endif
70 | #else
71 | # define QXT_NETWORK_EXPORT
72 | #endif // BUILD_QXT_NETWORK
73 |
74 | #if !defined(QXT_STATIC)
75 | # if defined(BUILD_QXT_SQL)
76 | # define QXT_SQL_EXPORT Q_DECL_EXPORT
77 | # else
78 | # define QXT_SQL_EXPORT Q_DECL_IMPORT
79 | # endif
80 | #else
81 | # define QXT_SQL_EXPORT
82 | #endif // BUILD_QXT_SQL
83 |
84 | #if !defined(QXT_STATIC)
85 | # if defined(BUILD_QXT_WEB)
86 | # define QXT_WEB_EXPORT Q_DECL_EXPORT
87 | # else
88 | # define QXT_WEB_EXPORT Q_DECL_IMPORT
89 | # endif
90 | #else
91 | # define QXT_WEB_EXPORT
92 | #endif // BUILD_QXT_WEB
93 |
94 | #if !defined(QXT_STATIC)
95 | # if defined(BUILD_QXT_BERKELEY)
96 | # define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
97 | # else
98 | # define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
99 | # endif
100 | #else
101 | # define QXT_BERKELEY_EXPORT
102 | #endif // BUILD_QXT_BERKELEY
103 |
104 | #if !defined(QXT_STATIC)
105 | # if defined(BUILD_QXT_ZEROCONF)
106 | # define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
107 | # else
108 | # define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
109 | # endif
110 | #else
111 | # define QXT_ZEROCONF_EXPORT
112 | #endif // QXT_ZEROCONF_EXPORT
113 |
114 | #if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
115 | # define BUILD_QXT
116 | #endif
117 |
118 | QXT_CORE_EXPORT const char* qxtVersion();
119 |
120 | #ifndef QT_BEGIN_NAMESPACE
121 | #define QT_BEGIN_NAMESPACE
122 | #endif
123 |
124 | #ifndef QT_END_NAMESPACE
125 | #define QT_END_NAMESPACE
126 | #endif
127 |
128 | #ifndef QT_FORWARD_DECLARE_CLASS
129 | #define QT_FORWARD_DECLARE_CLASS(Class) class Class;
130 | #endif
131 |
132 | /****************************************************************************
133 | ** This file is derived from code bearing the following notice:
134 | ** The sole author of this file, Adam Higerd, has explicitly disclaimed all
135 | ** copyright interest and protection for the content within. This file has
136 | ** been placed in the public domain according to United States copyright
137 | ** statute and case law. In jurisdictions where this public domain dedication
138 | ** is not legally recognized, anyone who receives a copy of this file is
139 | ** permitted to use, modify, duplicate, and redistribute this file, in whole
140 | ** or in part, with no restrictions or conditions. In these jurisdictions,
141 | ** this file shall be copyright (C) 2006-2008 by Adam Higerd.
142 | ****************************************************************************/
143 |
144 | #define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d;
145 | #define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
146 | #define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
147 | #define QXT_D(PUB) PUB##Private& d = qxt_d()
148 | #define QXT_P(PUB) PUB& p = qxt_p()
149 |
150 | template
151 | class QxtPrivate
152 | {
153 | public:
154 | virtual ~QxtPrivate()
155 | {}
156 | inline void QXT_setPublic(PUB* pub)
157 | {
158 | qxt_p_ptr = pub;
159 | }
160 |
161 | protected:
162 | inline PUB& qxt_p()
163 | {
164 | return *qxt_p_ptr;
165 | }
166 | inline const PUB& qxt_p() const
167 | {
168 | return *qxt_p_ptr;
169 | }
170 |
171 | private:
172 | PUB* qxt_p_ptr;
173 | };
174 |
175 | template
176 | class QxtPrivateInterface
177 | {
178 | friend class QxtPrivate;
179 | public:
180 | QxtPrivateInterface()
181 | {
182 | pvt = new PVT;
183 | }
184 | ~QxtPrivateInterface()
185 | {
186 | delete pvt;
187 | }
188 |
189 | inline void setPublic(PUB* pub)
190 | {
191 | pvt->QXT_setPublic(pub);
192 | }
193 | inline PVT& operator()()
194 | {
195 | return *static_cast(pvt);
196 | }
197 | inline const PVT& operator()() const
198 | {
199 | return *static_cast(pvt);
200 | }
201 | private:
202 | QxtPrivateInterface(const QxtPrivateInterface&) { }
203 | QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
204 | QxtPrivate* pvt;
205 | };
206 |
207 | #endif // QXT_GLOBAL
208 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/linux/qxttooltip.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtGui module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 | #include "qxttooltip.h"
26 | #include "qxttooltip_p.h"
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 |
41 | static const Qt::WindowFlags FLAGS = Qt::ToolTip;
42 |
43 | QxtToolTipPrivate* QxtToolTipPrivate::self = 0;
44 |
45 | QxtToolTipPrivate* QxtToolTipPrivate::instance()
46 | {
47 | if (!self)
48 | self = new QxtToolTipPrivate();
49 | return self;
50 | }
51 |
52 | QxtToolTipPrivate::QxtToolTipPrivate() : QWidget(qApp->desktop(), FLAGS)
53 | {
54 | setWindowFlags(FLAGS);
55 | vbox = new QVBoxLayout(this);
56 | setPalette(QToolTip::palette());
57 | setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
58 | layout()->setMargin(style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, this));
59 | qApp->installEventFilter(this);
60 | }
61 |
62 | QxtToolTipPrivate::~QxtToolTipPrivate()
63 | {
64 | qApp->removeEventFilter(this); // not really necessary but rather for completeness :)
65 | self = 0;
66 | }
67 |
68 | void QxtToolTipPrivate::show(const QPoint& pos, QWidget* tooltip, QWidget* parent, const QRect& rect)
69 | {
70 | Q_ASSERT(tooltip && parent);
71 | if (!isVisible())
72 | {
73 | int scr = 0;
74 | if (QApplication::desktop()->isVirtualDesktop())
75 | scr = QApplication::desktop()->screenNumber(pos);
76 | else
77 | scr = QApplication::desktop()->screenNumber(this);
78 | setParent(QApplication::desktop()->screen(scr));
79 | setWindowFlags(FLAGS);
80 | setToolTip(tooltip);
81 | currentParent = parent;
82 | currentRect = rect;
83 | move(calculatePos(scr, pos));
84 | QWidget::show();
85 | }
86 | }
87 |
88 | void QxtToolTipPrivate::setToolTip(QWidget* tooltip)
89 | {
90 | for (int i = 0; i < vbox->count(); ++i)
91 | {
92 | QLayoutItem* item = layout()->takeAt(i);
93 | if (item->widget())
94 | item->widget()->hide();
95 | }
96 | vbox->addWidget(tooltip);
97 | tooltip->show();
98 | }
99 |
100 | void QxtToolTipPrivate::enterEvent(QEvent* event)
101 | {
102 | Q_UNUSED(event);
103 | hideLater();
104 | }
105 |
106 | void QxtToolTipPrivate::paintEvent(QPaintEvent* event)
107 | {
108 | Q_UNUSED(event);
109 | QStylePainter painter(this);
110 | QStyleOptionFrame opt;
111 | opt.initFrom(this);
112 | painter.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
113 | }
114 |
115 | bool QxtToolTipPrivate::eventFilter(QObject* object, QEvent* event)
116 | {
117 | switch (event->type())
118 | {
119 | case QEvent::KeyPress:
120 | case QEvent::KeyRelease:
121 | {
122 | // accept only modifiers
123 | const QKeyEvent* keyEvent = static_cast(event);
124 | const int key = keyEvent->key();
125 | const Qt::KeyboardModifiers mods = keyEvent->modifiers();
126 | if ((mods & Qt::KeyboardModifierMask) ||
127 | (key == Qt::Key_Shift || key == Qt::Key_Control ||
128 | key == Qt::Key_Alt || key == Qt::Key_Meta))
129 | break;
130 | }
131 | case QEvent::Leave:
132 | case QEvent::WindowActivate:
133 | case QEvent::WindowDeactivate:
134 | case QEvent::MouseButtonPress:
135 | case QEvent::MouseButtonRelease:
136 | case QEvent::MouseButtonDblClick:
137 | case QEvent::FocusIn:
138 | case QEvent::FocusOut:
139 | case QEvent::Wheel:
140 | hideLater();
141 | break;
142 |
143 | case QEvent::MouseMove:
144 | {
145 | const QPoint pos = static_cast(event)->pos();
146 | if (!currentRect.isNull() && !currentRect.contains(pos))
147 | {
148 | hideLater();
149 | }
150 | break;
151 | }
152 |
153 | case QEvent::ToolTip:
154 | {
155 | // eat appropriate tooltip events
156 | QWidget* widget = static_cast(object);
157 | if (tooltips.contains(widget))
158 | {
159 | QHelpEvent* helpEvent = static_cast(event);
160 | const QRect area = tooltips.value(widget).second;
161 | if (area.isNull() || area.contains(helpEvent->pos()))
162 | {
163 | show(helpEvent->globalPos(), tooltips.value(widget).first, widget, area);
164 | return true;
165 | }
166 | }
167 | }
168 |
169 | default:
170 | break;
171 | }
172 | return false;
173 | }
174 |
175 | void QxtToolTipPrivate::hideLater()
176 | {
177 | currentRect = QRect();
178 | if (isVisible())
179 | QTimer::singleShot(0, this, SLOT(hide()));
180 | }
181 |
182 | QPoint QxtToolTipPrivate::calculatePos(int scr, const QPoint& eventPos) const
183 | {
184 | #ifdef Q_WS_MAC
185 | QRect screen = QApplication::desktop()->availableGeometry(scr);
186 | #else
187 | QRect screen = QApplication::desktop()->screenGeometry(scr);
188 | #endif
189 |
190 | QPoint p = eventPos;
191 | p += QPoint(2,
192 | #ifdef Q_WS_WIN
193 | 24
194 | #else
195 | 16
196 | #endif
197 | );
198 | QSize s = sizeHint();
199 | if (p.x() + s.width() > screen.x() + screen.width())
200 | p.rx() -= 4 + s.width();
201 | if (p.y() + s.height() > screen.y() + screen.height())
202 | p.ry() -= 24 + s.height();
203 | if (p.y() < screen.y())
204 | p.setY(screen.y());
205 | if (p.x() + s.width() > screen.x() + screen.width())
206 | p.setX(screen.x() + screen.width() - s.width());
207 | if (p.x() < screen.x())
208 | p.setX(screen.x());
209 | if (p.y() + s.height() > screen.y() + screen.height())
210 | p.setY(screen.y() + screen.height() - s.height());
211 | return p;
212 | }
213 |
214 | /*!
215 | \class QxtToolTip
216 | \inmodule QxtGui
217 | \brief The QxtToolTip class provides means for showing any arbitrary widget as a tooltip.
218 |
219 | QxtToolTip provides means for showing any arbitrary widget as a tooltip.
220 |
221 | \bold {Note:} The rich text support of QToolTip already makes it possible to
222 | show heavily customized tooltips with lists, tables, embedded images
223 | and such. However, for example dynamically created images like
224 | thumbnails cause problems. Basically the only way is to dump the
225 | thumbnail to a temporary file to be able to embed it into HTML. This
226 | is where QxtToolTip steps in. A generated thumbnail may simply be set
227 | on a QLabel which is then shown as a tooltip. Yet another use case
228 | is a tooltip with dynamically changing content.
229 |
230 | \image qxttooltip.png "QxtToolTip in action."
231 |
232 | \warning Added tooltip widgets remain in the memory for the lifetime
233 | of the application or until they are removed/deleted. Do NOT flood your
234 | application up with lots of complex tooltip widgets or it will end up
235 | being a resource hog. QToolTip is sufficient for most of the cases!
236 | */
237 |
238 | /*!
239 | \internal
240 | */
241 | QxtToolTip::QxtToolTip()
242 | {
243 | }
244 |
245 | /*!
246 | Shows the \a tooltip at \a pos for \a parent at \a rect.
247 |
248 | \sa hide()
249 | */
250 | void QxtToolTip::show(const QPoint& pos, QWidget* tooltip, QWidget* parent, const QRect& rect)
251 | {
252 | QxtToolTipPrivate::instance()->show(pos, tooltip, parent, rect);
253 | }
254 |
255 | /*!
256 | Hides the tooltip.
257 |
258 | \sa show()
259 | */
260 | void QxtToolTip::hide()
261 | {
262 | QxtToolTipPrivate::instance()->hide();
263 | }
264 |
265 | /*!
266 | Returns the tooltip for \a parent.
267 |
268 | \sa setToolTip()
269 | */
270 | QWidget* QxtToolTip::toolTip(QWidget* parent)
271 | {
272 | Q_ASSERT(parent);
273 | QWidget* tooltip = 0;
274 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
275 | qWarning("QxtToolTip::toolTip: Unknown parent");
276 | else
277 | tooltip = QxtToolTipPrivate::instance()->tooltips.value(parent).first;
278 | return tooltip;
279 | }
280 |
281 | /*!
282 | Sets the \a tooltip to be shown for \a parent.
283 | An optional \a rect may also be passed.
284 |
285 | \sa toolTip()
286 | */
287 | void QxtToolTip::setToolTip(QWidget* parent, QWidget* tooltip, const QRect& rect)
288 | {
289 | Q_ASSERT(parent);
290 | if (tooltip)
291 | {
292 | // set
293 | tooltip->hide();
294 | QxtToolTipPrivate::instance()->tooltips[parent] = qMakePair(QPointer(tooltip), rect);
295 | }
296 | else
297 | {
298 | // remove
299 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
300 | qWarning("QxtToolTip::setToolTip: Unknown parent");
301 | else
302 | QxtToolTipPrivate::instance()->tooltips.remove(parent);
303 | }
304 | }
305 |
306 | /*!
307 | Returns the rect on which tooltip is shown for \a parent.
308 |
309 | \sa setToolTipRect()
310 | */
311 | QRect QxtToolTip::toolTipRect(QWidget* parent)
312 | {
313 | Q_ASSERT(parent);
314 | QRect rect;
315 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
316 | qWarning("QxtToolTip::toolTipRect: Unknown parent");
317 | else
318 | rect = QxtToolTipPrivate::instance()->tooltips.value(parent).second;
319 | return rect;
320 | }
321 |
322 | /*!
323 | Sets the \a rect on which tooltip is shown for \a parent.
324 |
325 | \sa toolTipRect()
326 | */
327 | void QxtToolTip::setToolTipRect(QWidget* parent, const QRect& rect)
328 | {
329 | Q_ASSERT(parent);
330 | if (!QxtToolTipPrivate::instance()->tooltips.contains(parent))
331 | qWarning("QxtToolTip::setToolTipRect: Unknown parent");
332 | else
333 | QxtToolTipPrivate::instance()->tooltips[parent].second = rect;
334 | }
335 |
336 | /*!
337 | Returns the margin of the tooltip.
338 |
339 | \sa setMargin()
340 | */
341 | int QxtToolTip::margin()
342 | {
343 | return QxtToolTipPrivate::instance()->layout()->margin();
344 | }
345 |
346 | /*!
347 | Sets the \a margin of the tooltip.
348 |
349 | The default value is QStyle::PM_ToolTipLabelFrameWidth.
350 |
351 | \sa margin()
352 | */
353 | void QxtToolTip::setMargin(int margin)
354 | {
355 | QxtToolTipPrivate::instance()->layout()->setMargin(margin);
356 | }
357 |
358 | /*!
359 | Returns the opacity level of the tooltip.
360 |
361 | \sa QWidget::windowOpacity()
362 | */
363 | qreal QxtToolTip::opacity()
364 | {
365 | return QxtToolTipPrivate::instance()->windowOpacity();
366 | }
367 |
368 | /*!
369 | Sets the opacity \a level of the tooltip.
370 |
371 | The default value is QStyle::SH_ToolTipLabel_Opacity.
372 |
373 | \sa QWidget::setWindowOpacity()
374 | */
375 | void QxtToolTip::setOpacity(qreal level)
376 | {
377 | QxtToolTipPrivate::instance()->setWindowOpacity(level);
378 | }
379 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/linux/qxttooltip.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtGui module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 | #ifndef QXTTOOLTIP_H
26 | #define QXTTOOLTIP_H
27 |
28 | #include
29 | #include
30 | #include
31 | #include "qxtglobal.h"
32 |
33 | class QXT_GUI_EXPORT QxtToolTip
34 | {
35 | QxtToolTip();
36 |
37 | public:
38 | static void show(const QPoint& pos, QWidget* tooltip, QWidget* parent = 0, const QRect& rect = QRect());
39 | static void hide();
40 |
41 | static QWidget* toolTip(QWidget* parent);
42 | static void setToolTip(QWidget* parent, QWidget* tooltip, const QRect& rect = QRect());
43 |
44 | static QRect toolTipRect(QWidget* parent);
45 | static void setToolTipRect(QWidget* parent, const QRect& rect);
46 |
47 | static int margin();
48 | static void setMargin(int margin);
49 |
50 | static qreal opacity();
51 | static void setOpacity(qreal level);
52 | };
53 |
54 | QT_BEGIN_NAMESPACE
55 | inline uint qHash(const QPointer key)
56 | {
57 | return reinterpret_cast(key ? (&*key) : 0);
58 | }
59 | QT_END_NAMESPACE
60 |
61 | #endif // QXTTOOLTIP_H
62 |
--------------------------------------------------------------------------------
/taskbarprogress/taskbarprogress/linux/qxttooltip_p.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) Qxt Foundation. Some rights reserved.
4 | **
5 | ** This file is part of the QxtGui module of the Qxt library.
6 | **
7 | ** This library is free software; you can redistribute it and/or modify it
8 | ** under the terms of the Common Public License, version 1.0, as published
9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License,
10 | ** version 2.1, as published by the Free Software Foundation.
11 | **
12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
15 | ** FITNESS FOR A PARTICULAR PURPOSE.
16 | **
17 | ** You should have received a copy of the CPL and the LGPL along with this
18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
19 | ** included with the source distribution for more information.
20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
21 | **
22 | **
23 | **
24 | ****************************************************************************/
25 | #ifndef QXTTOOLTIP_P_H
26 | #define QXTTOOLTIP_P_H
27 |
28 | #include
29 | #include
30 | #include
31 | #include "qxttooltip.h"
32 |
33 | QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
34 |
35 | typedef QPointer WidgetPtr;
36 | typedef QPair WidgetArea;
37 |
38 | class QxtToolTipPrivate : public QWidget
39 | {
40 | Q_OBJECT
41 |
42 | public:
43 | QxtToolTipPrivate();
44 | ~QxtToolTipPrivate();
45 |
46 | static QxtToolTipPrivate* instance();
47 | void show(const QPoint& pos, QWidget* tooltip, QWidget* parent = 0, const QRect& rect = QRect());
48 | void setToolTip(QWidget* tooltip);
49 | bool eventFilter(QObject* parent, QEvent* event);
50 | void hideLater();
51 | QPoint calculatePos(int scr, const QPoint& eventPos) const;
52 | QHash tooltips;
53 | QVBoxLayout* vbox;
54 |
55 | protected:
56 | void enterEvent(QEvent* event);
57 | void paintEvent(QPaintEvent* event);
58 |
59 | private:
60 | static QxtToolTipPrivate* self;
61 | QWidget* currentParent;
62 | QRect currentRect;
63 | };
64 |
65 | #endif // QXTTOOLTIP_P_H
66 |
--------------------------------------------------------------------------------
/ui/ui-inspector/cuiinspector.cpp:
--------------------------------------------------------------------------------
1 | #include "cuiinspector.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | RESTORE_COMPILER_WARNINGS
14 |
15 |
16 | struct WidgetHierarchy {
17 | QWidget* widget = nullptr;
18 | QLayout* layout = nullptr;
19 |
20 | std::vector children;
21 | };
22 |
23 | CUiInspector::CUiInspector(QWidget* parent) noexcept :
24 | QMainWindow(parent)
25 | {
26 | QTimer::singleShot(500, this, &CUiInspector::inspect);
27 |
28 | setCentralWidget(_tree = new QTreeWidget);
29 | _tree->setSelectionMode(QAbstractItemView::NoSelection);
30 | _tree->setHeaderHidden(true);
31 | _tree->setContextMenuPolicy(Qt::CustomContextMenu);
32 | connect(_tree, &QWidget::customContextMenuRequested, this, &CUiInspector::showItemContextMenu);
33 |
34 | QMenuBar* mainMenu = menuBar();
35 | mainMenu->addAction(tr("&Refresh"), this, &CUiInspector::inspect);
36 | _actShowHiddenItems = mainMenu->addAction(tr("&Show hidden items"), this, &CUiInspector::inspect);
37 | _actShowHiddenItems->setCheckable(true);
38 | _actShowHiddenItems->setChecked(true);
39 |
40 | mainMenu->show();
41 | statusBar()->show();
42 |
43 | connect(qApp, &QApplication::focusChanged, this, [this](QWidget* old, QWidget* n) {
44 | QString text;
45 | {
46 | QDebug infoWriter(&text);
47 | infoWriter << "Focus changed from" << old << "to" << n;
48 | }
49 | statusBar()->showMessage(text);
50 | });
51 | }
52 |
53 | void CUiInspector::inspect()
54 | {
55 | std::vector hierarchy;
56 | for (QWidget* widget : QApplication::topLevelWidgets())
57 | {
58 | if (widget != this) // Do not show self
59 | inspectWidgetHierarchy(widget, hierarchy);
60 | }
61 |
62 | visualize(hierarchy);
63 | }
64 |
65 | QTreeWidgetItem* createTreeItem(const WidgetHierarchy& hierarchy, const bool showHidden, QTreeWidgetItem* parent = nullptr)
66 | {
67 | const bool isHiddenWidget = hierarchy.widget && !hierarchy.widget->isVisible();
68 | if (showHidden && isHiddenWidget) // Hidden widgets contain no visible children - do not iterate further
69 | return nullptr;
70 |
71 | auto* item = new QTreeWidgetItem(parent);
72 |
73 | QString description;
74 |
75 | // Scope to ensure destruction of the QDebug object
76 | {
77 | QDebug detailedInfoWriter(&description);
78 | if (hierarchy.widget)
79 | {
80 | item->setData(0, Qt::UserRole, (qulonglong)hierarchy.widget);
81 | detailedInfoWriter << hierarchy.widget;
82 | if (isHiddenWidget)
83 | detailedInfoWriter << "- HIDDEN";
84 |
85 | if (hierarchy.widget->testAttribute(Qt::WA_TransparentForMouseEvents))
86 | detailedInfoWriter << "(transparent for mouse events!)";
87 | }
88 | else if (hierarchy.layout)
89 | {
90 | item->setData(0, Qt::UserRole, (qulonglong)hierarchy.layout);
91 | detailedInfoWriter << hierarchy.layout;
92 | }
93 | else
94 | assert(!"Both widget and layout are nullptr");
95 | }
96 |
97 | item->setText(0, description);
98 | if (hierarchy.layout)
99 | item->setForeground(0, QColor(100, 255, 100));
100 |
101 | for (const auto& child : hierarchy.children)
102 | createTreeItem(child, showHidden, item);
103 |
104 | return item;
105 | }
106 |
107 | void CUiInspector::visualize(const std::vector& hierarchy)
108 | {
109 | QList items;
110 | items.reserve((int)hierarchy.size());
111 | const bool showHidden = _actShowHiddenItems->isChecked();
112 | for (const auto& h : hierarchy)
113 | {
114 | auto* item = createTreeItem(h, showHidden);
115 | if (item)
116 | items.push_back(item);
117 | }
118 |
119 | _tree->clear();
120 | _tree->addTopLevelItems(items);
121 | _tree->expandAll();
122 | }
123 |
124 | void CUiInspector::inspectWidgetHierarchy(QWidget* widget, std::vector& root) const
125 | {
126 | if (_ignoredClasses.contains(widget->objectName()) || _ignoredClasses.contains(widget->metaObject()->className()))
127 | return;
128 |
129 | root.emplace_back();
130 | WidgetHierarchy& thisItem = root.back();
131 | thisItem.widget = widget;
132 | if (widget->layout())
133 | inspectWidgetHierarchy(widget->layout(), thisItem.children);
134 | else
135 | {
136 | for (QObject* child : widget->children())
137 | {
138 | if (auto* childWidget = dynamic_cast(child))
139 | inspectWidgetHierarchy(childWidget, thisItem.children);
140 | }
141 | }
142 | }
143 |
144 | void CUiInspector::inspectWidgetHierarchy(QLayout* layout, std::vector& root) const
145 | {
146 | WidgetHierarchy& thisItem = root.emplace_back();
147 |
148 | thisItem.layout = layout;
149 | for (int i = 0; true; ++i)
150 | {
151 | QLayoutItem* item = layout->itemAt(i);
152 | if (!item)
153 | break;
154 |
155 | auto* l = item->layout();
156 | auto* w = item->widget();
157 | if (!l && !w)
158 | continue;
159 |
160 | assert(!(l && w));
161 |
162 | if (l)
163 | inspectWidgetHierarchy(l, thisItem.children);
164 | else if (w)
165 | inspectWidgetHierarchy(w, thisItem.children);
166 | }
167 | }
168 |
169 | inline void CUiInspector::showItemContextMenu(const QPoint& p)
170 | {
171 | auto* item = _tree->itemAt(p);
172 | if (!item)
173 | return;
174 |
175 | QMenu contextMenu(_tree);
176 | auto* goToParent = contextMenu.addAction(tr("Go to parent"));
177 | auto* highlight = contextMenu.addAction(tr("Highlight item"));
178 | if (const auto* selectedAction = contextMenu.exec(mapToGlobal(p)); selectedAction == goToParent)
179 | {
180 | auto* parent = item->parent();
181 | if (!parent)
182 | return;
183 |
184 | _tree->setCurrentItem(parent);
185 | _tree->scrollTo(_tree->currentIndex());
186 | }
187 | else if (selectedAction == highlight)
188 | {
189 | auto* ptr = (QObject*)item->data(0, Qt::UserRole).toULongLong();
190 | QWidget* widget = nullptr;
191 | QRect qRect;
192 | if (auto* l = dynamic_cast(ptr))
193 | {
194 | widget = l->widget();
195 | qRect = widget ? widget->rect() : QRect{};
196 | }
197 | else if (auto* w = dynamic_cast(ptr))
198 | {
199 | widget = w;
200 | qRect = w->rect();
201 | }
202 |
203 | if (qRect.isEmpty() || !widget)
204 | return;
205 |
206 | widget->setStyleSheet(QStringLiteral("* { border: 4px solid red; }"));
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/ui/ui-inspector/cuiinspector.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "compiler/compiler_warnings_control.h"
3 |
4 | DISABLE_COMPILER_WARNINGS
5 | #include
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | #include
10 |
11 | class QTreeWidget;
12 | class QAction;
13 | class QLayout;
14 |
15 | struct WidgetHierarchy;
16 |
17 | class CUiInspector final : public QMainWindow
18 | {
19 | public:
20 | explicit CUiInspector(QWidget *parent = nullptr) noexcept;
21 |
22 | private:
23 | void inspect();
24 | void visualize(const std::vector& hierarchy);
25 |
26 | void inspectWidgetHierarchy(QWidget* widget, std::vector& root) const;
27 | void inspectWidgetHierarchy(QLayout* layout, std::vector& root) const;
28 |
29 | void showItemContextMenu(const QPoint& p);
30 |
31 | private:
32 | QStringList _ignoredClasses;
33 |
34 | QTreeWidget* _tree;
35 | QAction* _actShowHiddenItems;
36 | };
37 |
--------------------------------------------------------------------------------
/ui/ui.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | $$PWD/ui-inspector/cuiinspector.h
3 |
4 | SOURCES += \
5 | $$PWD/ui-inspector/cuiinspector.cpp
6 |
--------------------------------------------------------------------------------
/utils/naturalsorting/cnaturalsorterqcollator.cpp:
--------------------------------------------------------------------------------
1 | #include "cnaturalsorterqcollator.h"
2 |
3 | CNaturalSorterQCollator::CNaturalSorterQCollator() noexcept
4 | {
5 | _collator.setCaseSensitivity(Qt::CaseSensitive);
6 | _collator.setNumericMode(true);
7 | }
8 |
9 | bool CNaturalSorterQCollator::compare(const QString & l, const QString & r, SortingOptions /*options*/) const
10 | {
11 | // Fix for the new breaking changes in QCollator in Qt 5.14 - null strings are no longer a valid input
12 | return _collator.compare(qToStringViewIgnoringNull(l), qToStringViewIgnoringNull(r)) < 0;
13 | }
14 |
--------------------------------------------------------------------------------
/utils/naturalsorting/cnaturalsorterqcollator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "sortingoptions.h"
4 | #include "compiler/compiler_warnings_control.h"
5 |
6 | DISABLE_COMPILER_WARNINGS
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | class CNaturalSorterQCollator
11 | {
12 | public:
13 | CNaturalSorterQCollator() noexcept;
14 | [[nodiscard]] bool compare(const QString& l,const QString& r, SortingOptions options) const;
15 |
16 | private:
17 | QCollator _collator;
18 | };
19 |
--------------------------------------------------------------------------------
/utils/naturalsorting/cnaturalsorting.cpp:
--------------------------------------------------------------------------------
1 | #include "cnaturalsorting.h"
2 | #include "naturalsorting_qt.h"
3 | #include "assert/advanced_assert.h"
4 |
5 | CNaturalSorting::CNaturalSorting(NaturalSortingAlgorithm algorithm, SortingOptions options) : _options(options), _algorithm(algorithm)
6 | {
7 | }
8 |
9 | void CNaturalSorting::setSortingOptions(SortingOptions options)
10 | {
11 | _options = options;
12 | }
13 |
14 | void CNaturalSorting::setSortingAlgorithm(NaturalSortingAlgorithm algorithm)
15 | {
16 | _algorithm = algorithm;
17 | }
18 |
19 | bool CNaturalSorting::lessThan(const QString &l, const QString &r) const
20 | {
21 | switch (_algorithm)
22 | {
23 | case nsaQtForum:
24 | return naturalSortComparisonQt(l, r, _options);
25 | case nsaQCollator:
26 | return _collatorSorter.compare(l, r, _options);
27 | default:
28 | assert_and_return_unconditional_r("Unknown algorithm", false);
29 | }
30 | }
31 |
32 | bool CNaturalSorting::equal(const QString & l, const QString & r) const
33 | {
34 | return compare(l, r) == 0;
35 | }
36 |
37 | int CNaturalSorting::compare(const QString & l, const QString & r) const
38 | {
39 | if (lessThan(l, r))
40 | return -1;
41 | else if (lessThan(r, l))
42 | return 1;
43 | else
44 | return 0;
45 | }
46 |
--------------------------------------------------------------------------------
/utils/naturalsorting/cnaturalsorting.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "sortingoptions.h"
4 | #include "cnaturalsorterqcollator.h"
5 |
6 | enum NaturalSortingAlgorithm
7 | {
8 | nsaQtForum,
9 | nsaQCollator
10 | };
11 |
12 | class QString;
13 | class CNaturalSorting
14 | {
15 | public:
16 | CNaturalSorting(NaturalSortingAlgorithm algorithm, SortingOptions options);
17 |
18 | void setSortingOptions(SortingOptions options);
19 | void setSortingAlgorithm(NaturalSortingAlgorithm algorithm);
20 |
21 | [[nodiscard]] bool lessThan(const QString& l, const QString& r) const;
22 | [[nodiscard]] bool equal(const QString& l, const QString& r) const;
23 | [[nodiscard]] int compare(const QString& l, const QString& r) const;
24 |
25 | private:
26 | SortingOptions _options;
27 | NaturalSortingAlgorithm _algorithm;
28 |
29 | CNaturalSorterQCollator _collatorSorter;
30 | };
31 |
--------------------------------------------------------------------------------
/utils/naturalsorting/naturalsorting_qt.cpp:
--------------------------------------------------------------------------------
1 | #include "naturalsorting_qt.h"
2 |
3 | bool naturalSortComparisonQt(const QString& s1, const QString& s2, SortingOptions options)
4 | {
5 | // ignore common prefix..
6 | int i = 0;
7 | while (i < s1.length() && i < s2.length() && s1[i].toLower() == s2[i].toLower())
8 | ++i;
9 | ++i;
10 |
11 | // something left to compare?
12 | if (i < s1.length() && i < s2.length())
13 | {
14 | // get number prefix from position i - doesn't matter from which string
15 | int k = i-1;
16 | //If not number return native comparator
17 | if(!s1[k].isNumber() || !s2[k].isNumber())
18 | {
19 | //Two next lines
20 | //E.g. 1_... < 12_...
21 | if (s1[k].isNumber())
22 | return !options.optionEnabled(SortingOptions::DigitsAfterLetters);
23 | if(s2[k].isNumber())
24 | return options.optionEnabled(SortingOptions::DigitsAfterLetters);
25 |
26 | return QString::compare(s1, s2, Qt::CaseInsensitive) < 0;
27 | }
28 |
29 | QString n;
30 | --k;
31 | while (k >= 0 && s1[k].isNumber())
32 | {
33 | n = s1[k]+n;
34 | --k;
35 | }
36 |
37 | // get relevant/significant number string for s1
38 | k = i-1;
39 | QString n1;
40 | while (k < s1.length() && s1[k].isNumber())
41 | {
42 | n1 += s1.at(k);
43 | ++k;
44 | }
45 |
46 | // get relevant/significant number string for s2
47 | //Decrease by
48 | k = i-1;
49 | QString n2;
50 | while (k < s2.length() && s2[k].isNumber())
51 | {
52 | n2 += s2.at(k);
53 | ++k;
54 | }
55 |
56 | // got two numbers to compare?
57 | if (!n1.isEmpty() && !n2.isEmpty())
58 | return (n+n1).toInt() < (n+n2).toInt();
59 | else
60 | {
61 | // not a number has to win over a number.. number could have ended earlier... same prefix..
62 | if (!n1.isEmpty())
63 | return options.optionEnabled(SortingOptions::DigitsAfterLetters);
64 | if (!n2.isEmpty())
65 | return !options.optionEnabled(SortingOptions::DigitsAfterLetters);
66 | return s1[i] < s2[i];
67 | }
68 | }
69 | else
70 | {
71 | // shortest string win
72 | return s1.length() < s2.length();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/utils/naturalsorting/naturalsorting_qt.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "cnaturalsorting.h"
4 |
5 | bool naturalSortComparisonQt(const QString& s1, const QString& s2, SortingOptions options);
6 |
--------------------------------------------------------------------------------
/utils/naturalsorting/sortingoptions.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | struct SortingOptions
6 | {
7 | enum Options {
8 | NoSpecialBehavior = 0,
9 | DigitsAfterLetters = 1
10 | };
11 |
12 | inline SortingOptions(std::initializer_list&& options)
13 | {
14 | for (auto option : options)
15 | _options = static_cast(_options | option);
16 | }
17 |
18 | [[nodiscard]] inline Options options() const
19 | {
20 | return _options;
21 | }
22 |
23 | [[nodiscard]] inline bool optionEnabled(const Options option) const
24 | {
25 | return (_options & option) != 0;
26 | }
27 |
28 | private:
29 | Options _options = NoSpecialBehavior;
30 | };
31 |
32 |
--------------------------------------------------------------------------------
/utils/resources.cpp:
--------------------------------------------------------------------------------
1 | #include "resources.h"
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 | #include "assert/advanced_assert.h"
5 |
6 | DISABLE_COMPILER_WARNINGS
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | QByteArray dataFromResource(const QString &resourcePath)
11 | {
12 | QFile resourceFile(resourcePath);
13 | assert(resourceFile.exists());
14 | assert_r(resourceFile.open(QFile::ReadOnly));
15 |
16 | return resourceFile.readAll();
17 | }
18 |
19 | QString textFromResource(const QString &resourcePath)
20 | {
21 | return dataFromResource(resourcePath);
22 | }
23 |
--------------------------------------------------------------------------------
/utils/resources.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class QString;
4 | class QByteArray;
5 |
6 | QByteArray dataFromResource(const QString& resourcePath);
7 | QString textFromResource(const QString& resourcePath);
8 |
--------------------------------------------------------------------------------
/utils/utils.pri:
--------------------------------------------------------------------------------
1 | HEADERS += \
2 | $$PWD/naturalsorting/cnaturalsorterqcollator.h \
3 | $$PWD/naturalsorting/cnaturalsorting.h \
4 | $$PWD/naturalsorting/naturalsorting_qt.h \
5 | $$PWD/naturalsorting/sortingoptions.h \
6 | $$PWD/resources.h
7 |
8 | SOURCES += \
9 | $$PWD/naturalsorting/cnaturalsorterqcollator.cpp \
10 | $$PWD/naturalsorting/cnaturalsorting.cpp \
11 | $$PWD/naturalsorting/naturalsorting_qt.cpp \
12 | $$PWD/resources.cpp
13 |
--------------------------------------------------------------------------------
/widgets/cclickablelabel.cpp:
--------------------------------------------------------------------------------
1 | #include "cclickablelabel.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include
5 | RESTORE_COMPILER_WARNINGS
6 |
7 | void CClickableLabel::mouseDoubleClickEvent(QMouseEvent* e)
8 | {
9 | QLabel::mouseDoubleClickEvent(e);
10 | emit doubleClicked(mapToGlobal(e->pos()));
11 | }
12 |
13 | void CClickableLabel::mouseReleaseEvent(QMouseEvent *ev)
14 | {
15 | QLabel::mouseReleaseEvent(ev);
16 | emit singleClicked(mapToGlobal(ev->pos()));
17 | }
18 |
--------------------------------------------------------------------------------
/widgets/cclickablelabel.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | class CClickableLabel : public QLabel
10 | {
11 | Q_OBJECT
12 |
13 | public:
14 | using QLabel::QLabel;
15 |
16 | signals:
17 | void doubleClicked(QPoint pos);
18 | void singleClicked(QPoint pos);
19 |
20 | protected:
21 | void mouseDoubleClickEvent(QMouseEvent* e) override;
22 | void mouseReleaseEvent(QMouseEvent *ev) override;
23 | };
24 |
--------------------------------------------------------------------------------
/widgets/chistorycombobox.cpp:
--------------------------------------------------------------------------------
1 | #include "chistorycombobox.h"
2 | #include "container/set_operations.hpp"
3 | #include "settings/csettings.h"
4 |
5 | #include "../qtcore_helpers/qstring_helpers.hpp"
6 |
7 | DISABLE_COMPILER_WARNINGS
8 | #include
9 | #include
10 | #include
11 | #include
12 | RESTORE_COMPILER_WARNINGS
13 |
14 | CHistoryComboBox::CHistoryComboBox(QWidget* parent) :
15 | QComboBox(parent)
16 | {
17 | // without this call lineEdit is not created so it would be impossible to access it
18 | setEditable(true);
19 |
20 | installEventFilter(this);
21 | }
22 |
23 | CHistoryComboBox::~CHistoryComboBox()
24 | {
25 | if (!_settingName.isEmpty())
26 | CSettings().setValue(_settingName, itemsToSave());
27 | }
28 |
29 | void CHistoryComboBox::enableAutoSave(const QString& settingName)
30 | {
31 | _settingName = settingName;
32 |
33 | if (!settingName.isEmpty())
34 | addItems(CSettings().value(settingName).toStringList());
35 | }
36 |
37 | void CHistoryComboBox::setClearEditorOnItemActivation(bool clear)
38 | {
39 | _bClearEditorOnItemActivation = clear;
40 | }
41 |
42 | void CHistoryComboBox::setSaveCurrentText(bool save)
43 | {
44 | _bSaveCurrentText = save;
45 | }
46 |
47 | void CHistoryComboBox::setSelectPreviousItemShortcut(const QKeySequence& selectPreviousItemShortcut)
48 | {
49 | _selectPreviousItemShortcut = selectPreviousItemShortcut;
50 | }
51 |
52 | // Enables or disables history mode (moving activated item to the top)
53 | void CHistoryComboBox::setHistoryMode(bool historyMode)
54 | {
55 | _bHistoryMode = historyMode;
56 | }
57 |
58 | bool CHistoryComboBox::historyMode() const
59 | {
60 | return _bHistoryMode;
61 | }
62 |
63 | // Switch to the next combobox item (which means going back through the history if history mode is set)
64 | void CHistoryComboBox::selectPreviousItem()
65 | {
66 | if (count() <= 0)
67 | return;
68 |
69 | if (currentText().isEmpty())
70 | setCurrentIndex(0);
71 | else if (currentIndex() < count() - 1)
72 | setCurrentIndex(currentIndex() + 1);
73 |
74 | lineEdit()->selectAll(); // Causes a bug
75 | }
76 |
77 | void CHistoryComboBox::resetToLastSelected(bool clearLineEdit)
78 | {
79 | lineEdit()->clear(); // To clear any user input
80 | setCurrentIndex(currentIndex());
81 | if (clearLineEdit)
82 | lineEdit()->clear(); // To clear the current item text set by setCurrentIndex()
83 |
84 | clearFocus();
85 | }
86 |
87 | // TODO: this does not belong inside this class
88 | bool CHistoryComboBox::eventFilter(QObject* receiver, QEvent* e)
89 | {
90 | if (e->type() == QEvent::KeyPress)
91 | {
92 | QKeyEvent * keyEvent = static_cast(e);
93 |
94 | if (keyEvent->text().isEmpty())
95 | return QComboBox::eventFilter(receiver, e);
96 |
97 | QString modifierString;
98 | if (keyEvent->modifiers() & Qt::ShiftModifier)
99 | modifierString = QSL("Shift+");
100 | if (keyEvent->modifiers() & Qt::ControlModifier)
101 | modifierString = QSL("Ctrl+");
102 | if (keyEvent->modifiers() & Qt::AltModifier)
103 | modifierString = QSL("Alt+");
104 | if (keyEvent->modifiers() & Qt::MetaModifier)
105 | modifierString = QSL("Meta+");
106 |
107 | QKeySequence fullSequence(modifierString + QKeySequence(keyEvent->key()).toString());
108 | if (!_selectPreviousItemShortcut.isEmpty() && fullSequence == _selectPreviousItemShortcut)
109 | {
110 | selectPreviousItem();
111 | return true;
112 | }
113 | }
114 |
115 | return QComboBox::eventFilter(receiver, e);
116 | }
117 |
118 | QStringList CHistoryComboBox::items() const
119 | {
120 | const QString currentItemText = currentText();
121 | const auto nItems = count();
122 |
123 | QStringList itemsList;
124 | itemsList.reserve(nItems + 1);
125 |
126 | if (!currentItemText.isEmpty() && currentIndex() >= 0 && currentItemText != itemText(currentIndex()))
127 | itemsList.push_back(currentItemText);
128 |
129 | for (int i = 0; i < nItems; ++i)
130 | itemsList.push_back(itemText(i));
131 |
132 | return itemsList;
133 | }
134 |
135 | void CHistoryComboBox::keyPressEvent(QKeyEvent* e)
136 | {
137 | if (lineEdit()->hasFocus() && (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter))
138 | {
139 | e->accept();
140 | currentItemActivated();
141 | }
142 | else
143 | QComboBox::keyPressEvent(e);
144 |
145 | if (!_settingName.isEmpty())
146 | CSettings().setValue(_settingName, itemsToSave());
147 | }
148 |
149 | // Moves the currently selected item to the top
150 | void CHistoryComboBox::currentItemActivated()
151 | {
152 | const QString newItem = currentText();
153 | emit itemActivated(newItem);
154 |
155 | if (_bHistoryMode)
156 | {
157 | // No longer necessary as of Qt 5.4?..
158 | // removeItem(currentIndex());
159 |
160 | auto list = items();
161 | list.push_front(newItem);
162 |
163 | list = SetOperations::uniqueElements(list);
164 | clear();
165 | for (auto it = list.rbegin(); it != list.rend(); ++it)
166 | insertItem(0, *it);
167 |
168 | setCurrentIndex(0);
169 |
170 | if (_bClearEditorOnItemActivation)
171 | lineEdit()->clear();
172 | }
173 | }
174 |
175 | QStringList CHistoryComboBox::itemsToSave() const
176 | {
177 | auto result = items();
178 | if (_bSaveCurrentText)
179 | result.push_front(currentText());
180 |
181 | return result;
182 | }
183 |
--------------------------------------------------------------------------------
/widgets/chistorycombobox.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | #include
8 | RESTORE_COMPILER_WARNINGS
9 |
10 | class CHistoryComboBox : public QComboBox
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit CHistoryComboBox(QWidget * parent);
16 | ~CHistoryComboBox() override;
17 |
18 | void enableAutoSave(const QString& settingName);
19 | void setClearEditorOnItemActivation(bool clear);
20 | void setSaveCurrentText(bool save);
21 |
22 | void setSelectPreviousItemShortcut(const QKeySequence& selectPreviousItemShortcut);
23 |
24 | [[nodiscard]] QStringList items() const;
25 | [[nodiscard]] bool historyMode() const;
26 |
27 | public slots:
28 | // Enables or disables history mode (moving activated item to the top)
29 | void setHistoryMode(bool historyMode);
30 | // Switch to the next combobox item (which means going back through the history if history mode is set)
31 | void selectPreviousItem();
32 | void resetToLastSelected(bool clearLineEdit);
33 |
34 | signals:
35 | void itemActivated(QString itemText);
36 |
37 | protected:
38 | bool eventFilter(QObject *, QEvent *) override;
39 | void keyPressEvent(QKeyEvent * e) override;
40 |
41 | private:
42 | // Moves the currently selected item to the top
43 | void currentItemActivated();
44 |
45 | [[nodiscard]] QStringList itemsToSave() const;
46 |
47 | private:
48 | // QShortcut doesn't work properly with this class for some reason, so here's a hack for creating a keyboard shortcut to selectPreviousItem
49 | QKeySequence _selectPreviousItemShortcut;
50 | QString _settingName;
51 | bool _bHistoryMode = true;
52 | bool _bClearEditorOnItemActivation = false;
53 | bool _bSaveCurrentText = false;
54 | };
55 |
--------------------------------------------------------------------------------
/widgets/circularprogressindicator/ccircularprogressindicator.cpp:
--------------------------------------------------------------------------------
1 | // Stolen from https://github.com/yageek/CCircularProgressIndicator.git
2 |
3 | #include "ccircularprogressindicator.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | CCircularProgressIndicator::CCircularProgressIndicator(QWidget* parent) noexcept
10 | : QWidget(parent),
11 | m_angle(0),
12 | m_timerId(-1),
13 | m_delay(40),
14 | m_displayedWhenStopped(false),
15 | m_color(Qt::black)
16 | {
17 | setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
18 | setFocusPolicy(Qt::NoFocus);
19 | }
20 |
21 | bool CCircularProgressIndicator::isAnimated () const
22 | {
23 | return (m_timerId != -1);
24 | }
25 |
26 | void CCircularProgressIndicator::setDisplayedWhenStopped(bool state)
27 | {
28 | m_displayedWhenStopped = state;
29 |
30 | update();
31 | }
32 |
33 | bool CCircularProgressIndicator::isDisplayedWhenStopped() const
34 | {
35 | return m_displayedWhenStopped;
36 | }
37 |
38 | void CCircularProgressIndicator::startAnimation()
39 | {
40 | m_angle = 0;
41 |
42 | if (m_timerId == -1)
43 | m_timerId = startTimer(m_delay);
44 | }
45 |
46 | void CCircularProgressIndicator::stopAnimation()
47 | {
48 | if (m_timerId != -1)
49 | killTimer(m_timerId);
50 |
51 | m_timerId = -1;
52 |
53 | update();
54 | }
55 |
56 | void CCircularProgressIndicator::setAnimationDelay(int delay)
57 | {
58 | if (m_timerId != -1)
59 | killTimer(m_timerId);
60 |
61 | m_delay = delay;
62 |
63 | if (m_timerId != -1)
64 | m_timerId = startTimer(m_delay);
65 | }
66 |
67 | void CCircularProgressIndicator::setColor(const QColor & color)
68 | {
69 | m_color = color;
70 |
71 | update();
72 | }
73 |
74 | QSize CCircularProgressIndicator::sizeHint() const
75 | {
76 | return QSize(20,20);
77 | }
78 |
79 | int CCircularProgressIndicator::heightForWidth(int w) const
80 | {
81 | return w;
82 | }
83 |
84 | void CCircularProgressIndicator::timerEvent(QTimerEvent * /*event*/)
85 | {
86 | m_angle = (m_angle+30)%360;
87 |
88 | update();
89 | }
90 |
91 | void CCircularProgressIndicator::paintEvent(QPaintEvent * /*event*/)
92 | {
93 | if (!m_displayedWhenStopped && !isAnimated())
94 | return;
95 |
96 | const int width = std::min(this->width(), this->height());
97 |
98 | QPainter p(this);
99 | p.setRenderHint(QPainter::Antialiasing);
100 |
101 | const int outerRadius = (width-1) / 2;
102 | const int innerRadius = (int)((float)(width - 1) * 0.5f * 0.38f);
103 |
104 | const int capsuleHeight = outerRadius - innerRadius;
105 | const int capsuleWidth = (int)((width > 32 ) ? (float)capsuleHeight * 0.23f : (float)capsuleHeight * 0.35f);
106 | const int capsuleRadius = capsuleWidth / 2;
107 |
108 | for (int i = 0; i < 12; i++)
109 | {
110 | QColor color = m_color;
111 | color.setAlphaF(1.0f - (float)i / 12.0f);
112 | p.setPen(Qt::NoPen);
113 | p.setBrush(color);
114 | p.save();
115 | p.translate(rect().center());
116 | p.rotate((qreal)m_angle - (qreal)i * qreal{30.0});
117 | p.drawRoundedRect(-capsuleWidth / 2, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
118 | p.restore();
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/widgets/circularprogressindicator/ccircularprogressindicator.h:
--------------------------------------------------------------------------------
1 | // Stolen from https://github.com/yageek/CCircularProgressIndicator.git
2 |
3 | #pragma once
4 |
5 | #include "compiler/compiler_warnings_control.h"
6 |
7 | DISABLE_COMPILER_WARNINGS
8 | #include
9 | RESTORE_COMPILER_WARNINGS
10 |
11 | /*!
12 | \class CCircularProgressIndicator
13 | \brief The CCircularProgressIndicator class lets an application display a progress indicator to show that a lengthy task is under way.
14 |
15 | Progress indicators are indeterminate and do nothing more than spin to show that the application is busy.
16 | \sa QProgressBar
17 | */
18 | class CCircularProgressIndicator : public QWidget
19 | {
20 | Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
21 | Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
22 | Q_PROPERTY(QColor color READ color WRITE setColor)
23 | public:
24 | CCircularProgressIndicator(QWidget* parent = 0) noexcept;
25 |
26 | /*! Returns the delay between animation steps.
27 | \return The number of milliseconds between animation steps. By default, the animation delay is set to 40 milliseconds.
28 | \sa setAnimationDelay
29 | */
30 | int animationDelay() const { return m_delay; }
31 |
32 | /*! Returns a Boolean value indicating whether the component is currently animated.
33 | \return Animation state.
34 | \sa startAnimation stopAnimation
35 | */
36 | bool isAnimated () const;
37 |
38 | /*! Returns a Boolean value indicating whether the receiver shows itself even when it is not animating.
39 | \return Return true if the progress indicator shows itself even when it is not animating. By default, it returns false.
40 | \sa setDisplayedWhenStopped
41 | */
42 | bool isDisplayedWhenStopped() const;
43 |
44 | /*! Returns the color of the component.
45 | \sa setColor
46 | */
47 | const QColor & color() const { return m_color; }
48 |
49 | virtual QSize sizeHint() const override;
50 | int heightForWidth(int w) const;
51 | public slots:
52 | /*! Starts the spin animation.
53 | \sa stopAnimation isAnimated
54 | */
55 | void startAnimation();
56 |
57 | /*! Stops the spin animation.
58 | \sa startAnimation isAnimated
59 | */
60 | void stopAnimation();
61 |
62 | /*! Sets the delay between animation steps.
63 | Setting the \a delay to a value larger than 40 slows the animation, while setting the \a delay to a smaller value speeds it up.
64 | \param delay The delay, in milliseconds.
65 | \sa animationDelay
66 | */
67 | void setAnimationDelay(int delay);
68 |
69 | /*! Sets whether the component hides itself when it is not animating.
70 | \param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true.
71 | \sa isDisplayedWhenStopped
72 | */
73 | void setDisplayedWhenStopped(bool state);
74 |
75 | /*! Sets the color of the components to the given color.
76 | \sa color
77 | */
78 | void setColor(const QColor & color);
79 | protected:
80 | virtual void timerEvent(QTimerEvent * event) override;
81 | virtual void paintEvent(QPaintEvent * event) override;
82 | private:
83 | int m_angle;
84 | int m_timerId;
85 | int m_delay;
86 | bool m_displayedWhenStopped;
87 | QColor m_color;
88 | };
89 |
90 |
--------------------------------------------------------------------------------
/widgets/clineedit.cpp:
--------------------------------------------------------------------------------
1 | #include "clineedit.h"
2 |
3 | DISABLE_COMPILER_WARNINGS
4 | #include
5 | RESTORE_COMPILER_WARNINGS
6 |
7 | void CLineEdit::setSelectAllOnFocus(bool select)
8 | {
9 | _bSelectAllOnFocus = select;
10 | }
11 |
12 | bool CLineEdit::selectAllOnFocus() const
13 | {
14 | return _bSelectAllOnFocus;
15 | }
16 |
17 | void CLineEdit::focusInEvent(QFocusEvent * event)
18 | {
19 | QLineEdit::focusInEvent(event);
20 |
21 | if (_bSelectAllOnFocus)
22 | QTimer::singleShot(0, this, &CLineEdit::selectAll);
23 | }
24 |
--------------------------------------------------------------------------------
/widgets/clineedit.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "compiler/compiler_warnings_control.h"
4 |
5 | DISABLE_COMPILER_WARNINGS
6 | #include
7 | RESTORE_COMPILER_WARNINGS
8 |
9 | class CLineEdit : public QLineEdit
10 | {
11 | public:
12 | using QLineEdit::QLineEdit;
13 |
14 | void setSelectAllOnFocus(bool select);
15 | [[nodiscard]] bool selectAllOnFocus() const;
16 |
17 | protected:
18 | void focusInEvent (QFocusEvent * event) override;
19 |
20 | private:
21 | bool _bSelectAllOnFocus = true;
22 | };
23 |
--------------------------------------------------------------------------------
/widgets/cpersistentwindow.cpp:
--------------------------------------------------------------------------------
1 | #include "cpersistentwindow.h"
2 |
3 | #include "../settings/csettings.h"
4 | #include "assert/advanced_assert.h"
5 |
6 | DISABLE_COMPILER_WARNINGS
7 | #include
8 | #include
9 | #include
10 | #include
11 | RESTORE_COMPILER_WARNINGS
12 |
13 | #define GEOMETRY_KEY (_settingsPath + "_geometry")
14 | #define STATE_KEY (_settingsPath + "_state")
15 |
16 | CPersistenceEnabler::CPersistenceEnabler(QString widgetSettingsPath, QObject* parent) :
17 | QObject(parent),
18 | _settingsPath{std::move(widgetSettingsPath)}
19 | {
20 | }
21 |
22 | bool CPersistenceEnabler::eventFilter(QObject* watched, QEvent* e)
23 | {
24 | if (!_windowStateRestored && e->type() == QEvent::Show)
25 | {
26 | _windowStateRestored = true;
27 |
28 | auto* widget = static_cast