Skip to content

Commit 76aa95e

Browse files
committed
Version 1.0.10
2 parents 3d7449e + a5ee350 commit 76aa95e

File tree

119 files changed

+2915
-1158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+2915
-1158
lines changed

AbstractFilter.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <vector>
2626

2727
class FilterUiInterface;
28-
class PageId;
28+
class PageInfo;
2929
class ProjectReader;
3030
class ProjectWriter;
3131
class AbstractRelinker;
@@ -60,17 +60,13 @@ class AbstractFilter : public ref_countable {
6060

6161
virtual void performRelinking(const AbstractRelinker& relinker) = 0;
6262

63-
virtual void preUpdateUI(FilterUiInterface* ui, const PageId& page_id) = 0;
64-
65-
virtual void updateStatistics() {
66-
}
63+
virtual void preUpdateUI(FilterUiInterface* ui, const PageInfo& page_info) = 0;
6764

6865
virtual QDomElement saveSettings(const ProjectWriter& writer, QDomDocument& doc) const = 0;
6966

7067
virtual void loadSettings(const ProjectReader& reader, const QDomElement& filters_el) = 0;
7168

72-
virtual void loadDefaultSettings(const PageId& page_id) {
73-
};
69+
virtual void loadDefaultSettings(const PageInfo& page_info) = 0;
7470
};
7571

7672

Application.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ void Application::initTranslations() {
9090

9191
const QStringList language_file_filter("scantailor_*.qm");
9292
for (const QString& path : translation_dirs) {
93-
QDir dir(path);
93+
QDir dir(QDir::cleanPath(applicationDirPath() + '/' + path));
9494
if (dir.exists()) {
95-
QStringList translationFileNames = QDir(path).entryList(language_file_filter);
95+
QStringList translationFileNames = QDir(dir.path()).entryList(language_file_filter);
9696
for (const QString& fileName : translationFileNames) {
9797
QString locale(fileName);
9898
locale.truncate(locale.lastIndexOf('.'));

CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,14 +548,16 @@ SET(
548548
filter_dc/ContentBoxCollector.h
549549
filter_dc/PageOrientationCollector.h
550550
ImageViewInfoProvider.cpp ImageViewInfoProvider.h
551-
ImageViewInfoObserver.cpp ImageViewInfoObserver.h
551+
ImageViewInfoObserver.h
552552
UnitsProvider.cpp UnitsProvider.h
553553
UnitsObserver.h UnitsObserver.cpp
554554
UnitsConverter.cpp UnitsConverter.h
555555
Units.cpp Units.h
556556
DefaultParams.cpp DefaultParams.h
557557
DefaultParamsProfileManager.cpp DefaultParamsProfileManager.h
558558
DefaultParamsProvider.cpp DefaultParamsProvider.h
559+
DeviationProvider.h
560+
OrderByDeviationProvider.cpp OrderByDeviationProvider.h
559561
version.h
560562
config.h.in
561563
${common_ui_files})
@@ -582,7 +584,8 @@ SET(
582584
MainWindow.cpp MainWindow.h
583585
main.cpp
584586
StatusBarPanel.cpp StatusBarPanel.h
585-
DefaultParamsDialog.cpp DefaultParamsDialog.h)
587+
DefaultParamsDialog.cpp DefaultParamsDialog.h
588+
CollapsibleGroupBox.cpp CollapsibleGroupBox.h)
586589

587590
SET(
588591
cli_only_sources

CollapsibleGroupBox.cpp

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
2+
#include "CollapsibleGroupBox.h"
3+
#include <QSettings>
4+
#include <QtCore/QEvent>
5+
#include <QtGui/QShowEvent>
6+
#include <foundation/ScopedIncDec.h>
7+
8+
CollapsibleGroupBox::CollapsibleGroupBox(QWidget* parent)
9+
: QGroupBox(parent) {
10+
initialize();
11+
}
12+
13+
CollapsibleGroupBox::CollapsibleGroupBox(const QString& title, QWidget* parent)
14+
: QGroupBox(title, parent) {
15+
initialize();
16+
}
17+
18+
void CollapsibleGroupBox::initialize() {
19+
collapseIcon.addPixmap(
20+
QPixmap(QString::fromLatin1(":/icons/minus-16.png"))
21+
);
22+
expandIcon.addPixmap(
23+
QPixmap(QString::fromLatin1(":/icons/plus-16.png"))
24+
);
25+
collapseButton = new QToolButton(this);
26+
collapseButton->setObjectName("collapseButton");
27+
collapseButton->setAutoRaise(true);
28+
collapseButton->setFixedSize(14, 14);
29+
collapseButton->setIconSize(QSize(12, 12));
30+
collapseButton->setIcon(collapseIcon);
31+
setFocusProxy(collapseButton);
32+
setFocusPolicy(Qt::StrongFocus);
33+
34+
connect(collapseButton, &QAbstractButton::clicked, this, &CollapsibleGroupBox::toggleCollapsed);
35+
connect(this, &QGroupBox::toggled, this, &CollapsibleGroupBox::checkToggled);
36+
connect(this, &QGroupBox::clicked, this, &CollapsibleGroupBox::checkClicked);
37+
}
38+
39+
void CollapsibleGroupBox::setCollapsed(const bool collapse) {
40+
const bool changed = (collapse != collapsed);
41+
42+
if (changed) {
43+
collapsed = collapse;
44+
collapseButton->setIcon(collapse ? expandIcon : collapseIcon);
45+
46+
updateWidgets();
47+
48+
emit collapsedStateChanged(isCollapsed());
49+
}
50+
}
51+
52+
bool CollapsibleGroupBox::isCollapsed() const {
53+
return collapsed;
54+
}
55+
56+
void CollapsibleGroupBox::checkToggled(bool) {
57+
collapseButton->setEnabled(true);
58+
}
59+
60+
void CollapsibleGroupBox::checkClicked(bool checked) {
61+
if (checked && isCollapsed()) {
62+
setCollapsed(false);
63+
} else if (!checked && !isCollapsed()) {
64+
setCollapsed(true);
65+
}
66+
}
67+
68+
void CollapsibleGroupBox::toggleCollapsed() {
69+
// verify if sender is this group box's collapse button
70+
auto* sender = dynamic_cast<QToolButton*>(QObject::sender());
71+
const bool isSenderCollapseButton = (sender && (sender == collapseButton));
72+
73+
if (isSenderCollapseButton) {
74+
setCollapsed(!isCollapsed());
75+
}
76+
}
77+
78+
void CollapsibleGroupBox::updateWidgets() {
79+
const ScopedIncDec<int> guard(ignoreVisibilityEvents);
80+
81+
if (collapsed) {
82+
for (QObject* child : children()) {
83+
auto* widget = dynamic_cast<QWidget*>(child);
84+
if (widget && (widget != collapseButton) && widget->isVisible()) {
85+
collapsedWidgets.insert(widget);
86+
widget->hide();
87+
}
88+
}
89+
} else {
90+
for (QObject* child : children()) {
91+
auto* widget = dynamic_cast<QWidget*>(child);
92+
if (widget && (widget != collapseButton) && (collapsedWidgets.find(widget) != collapsedWidgets.end())) {
93+
collapsedWidgets.erase(widget);
94+
widget->show();
95+
}
96+
}
97+
}
98+
}
99+
100+
void CollapsibleGroupBox::showEvent(QShowEvent* event) {
101+
// initialize widget on first show event only
102+
if (shown) {
103+
event->accept();
104+
return;
105+
}
106+
shown = true;
107+
108+
loadState();
109+
110+
QWidget::showEvent(event);
111+
}
112+
113+
void CollapsibleGroupBox::changeEvent(QEvent* event) {
114+
QGroupBox::changeEvent(event);
115+
116+
if ((event->type() == QEvent::EnabledChange) && isEnabled()) {
117+
collapseButton->setEnabled(true);
118+
}
119+
}
120+
121+
void CollapsibleGroupBox::childEvent(QChildEvent* event) {
122+
auto* childWidget = dynamic_cast<QWidget*>(event->child());
123+
if (childWidget && (event)->type() == QEvent::ChildAdded) {
124+
if (collapsed) {
125+
if (childWidget->isVisible()) {
126+
collapsedWidgets.insert(childWidget);
127+
childWidget->hide();
128+
}
129+
}
130+
131+
childWidget->installEventFilter(this);
132+
}
133+
134+
QGroupBox::childEvent(event);
135+
}
136+
137+
bool CollapsibleGroupBox::eventFilter(QObject* watched, QEvent* event) {
138+
if (collapsed && !ignoreVisibilityEvents) {
139+
auto* childWidget = dynamic_cast<QWidget*>(watched);
140+
if (childWidget) {
141+
if (event->type() == QEvent::ShowToParent) {
142+
const ScopedIncDec<int> guard(ignoreVisibilityEvents);
143+
144+
collapsedWidgets.insert(childWidget);
145+
childWidget->hide();
146+
} else if (event->type() == QEvent::HideToParent) {
147+
collapsedWidgets.erase(childWidget);
148+
}
149+
}
150+
}
151+
152+
return QObject::eventFilter(watched, event);
153+
}
154+
155+
CollapsibleGroupBox::~CollapsibleGroupBox() {
156+
saveState();
157+
}
158+
159+
void CollapsibleGroupBox::loadState() {
160+
if (!isEnabled()) {
161+
return;
162+
}
163+
164+
const QString key = getSettingsKey();
165+
if (key.isEmpty()) {
166+
return;
167+
}
168+
169+
setUpdatesEnabled(false);
170+
171+
QSettings settings;
172+
173+
if (isCheckable()) {
174+
QVariant val = settings.value(key + "/checked");
175+
if (!val.isNull()) {
176+
setChecked(val.toBool());
177+
}
178+
}
179+
180+
{
181+
QVariant val = settings.value(key + "/collapsed");
182+
if (!val.isNull()) {
183+
setCollapsed(val.toBool());
184+
}
185+
}
186+
187+
setUpdatesEnabled(true);
188+
}
189+
190+
void CollapsibleGroupBox::saveState() {
191+
if (!shown || !isEnabled()) {
192+
return;
193+
}
194+
195+
const QString key = getSettingsKey();
196+
if (key.isEmpty()) {
197+
return;
198+
}
199+
200+
QSettings settings;
201+
202+
if (isCheckable()) {
203+
settings.setValue(key + "/checked", isChecked());
204+
}
205+
settings.setValue(key + "/collapsed", isCollapsed());
206+
}
207+
208+
QString CollapsibleGroupBox::getSettingsKey() const {
209+
if (objectName().isEmpty()) {
210+
return QString();
211+
}
212+
213+
QString saveKey = '/' + objectName();
214+
saveKey = "CollapsibleGroupBox" + saveKey;
215+
return saveKey;
216+
}
217+

CollapsibleGroupBox.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
#ifndef SCANTAILOR_COLLAPSIBLEGROUPBOX_H
3+
#define SCANTAILOR_COLLAPSIBLEGROUPBOX_H
4+
5+
6+
#include <QtWidgets/QToolButton>
7+
#include <QtWidgets/QGroupBox>
8+
#include <unordered_set>
9+
10+
class CollapsibleGroupBox : public QGroupBox {
11+
Q_OBJECT
12+
13+
/**
14+
* The collapsed state of this group box. If it is set to true, all content is hidden
15+
* if it is set to false all content is shown.
16+
*/
17+
Q_PROPERTY(bool collapsed READ isCollapsed WRITE setCollapsed USER true)
18+
19+
public:
20+
explicit CollapsibleGroupBox(QWidget* parent = nullptr);
21+
22+
explicit CollapsibleGroupBox(const QString& title, QWidget* parent = nullptr);
23+
24+
~CollapsibleGroupBox() override;
25+
26+
/**
27+
* Returns the current collapsed state of this group box.
28+
*/
29+
bool isCollapsed() const;
30+
31+
/**
32+
* Collapse or expand this group box.
33+
*
34+
* \param collapse Will collapse on true and expand on false
35+
*/
36+
void setCollapsed(bool collapse);
37+
38+
signals:
39+
40+
/** Signal emitted when the group box collapsed/expanded state is changed, and when first shown */
41+
void collapsedStateChanged(bool collapsed);
42+
43+
public slots:
44+
45+
void checkToggled(bool);
46+
47+
void checkClicked(bool checked);
48+
49+
void toggleCollapsed();
50+
51+
protected:
52+
void updateWidgets();
53+
54+
void showEvent(QShowEvent* event) override;
55+
56+
void changeEvent(QEvent* event) override;
57+
58+
void childEvent(QChildEvent *event) override;
59+
60+
bool eventFilter(QObject* watched, QEvent* event) override;
61+
62+
void initialize();
63+
64+
void loadState();
65+
66+
void saveState();
67+
68+
QString getSettingsKey() const;
69+
70+
private:
71+
bool collapsed = false;
72+
bool shown = false;
73+
QToolButton* collapseButton = nullptr;
74+
75+
QIcon collapseIcon;
76+
QIcon expandIcon;
77+
78+
int ignoreVisibilityEvents = 0;
79+
std::unordered_set<QWidget*> collapsedWidgets;
80+
};
81+
82+
83+
#endif //SCANTAILOR_COLLAPSIBLEGROUPBOX_H

0 commit comments

Comments
 (0)