1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "formwindowsettings.h"
30#include "ui_formwindowsettings.h"
31
32#include <formwindowbase_p.h>
33#include <grid_p.h>
34
35#include <QtWidgets/qstyle.h>
36
37#include <QtCore/qregularexpression.h>
38#include <QtCore/qdebug.h>
39
40#include <algorithm>
41
42QT_BEGIN_NAMESPACE
43
44namespace qdesigner_internal {
45
46// Data structure containing form dialog data providing comparison
47struct FormWindowData {
48 bool equals(const FormWindowData&) const;
49
50 void fromFormWindow(FormWindowBase* fw);
51 void applyToFormWindow(FormWindowBase* fw) const;
52
53 bool layoutDefaultEnabled{false};
54 int defaultMargin{0};
55 int defaultSpacing{0};
56
57 bool layoutFunctionsEnabled{false};
58 QString marginFunction;
59 QString spacingFunction;
60
61 QString pixFunction;
62
63 QString author;
64
65 QStringList includeHints;
66
67 bool hasFormGrid{false};
68 Grid grid;
69 bool idBasedTranslations{false};
70 bool connectSlotsByName{true};
71};
72
73inline bool operator==(const FormWindowData &fd1, const FormWindowData &fd2) { return fd1.equals(fd2); }
74inline bool operator!=(const FormWindowData &fd1, const FormWindowData &fd2) { return !fd1.equals(fd2); }
75
76QDebug operator<<(QDebug str, const FormWindowData &d)
77{
78 str.nospace() << "LayoutDefault=" << d.layoutDefaultEnabled << ',' << d.defaultMargin
79 << ',' << d.defaultSpacing << " LayoutFunctions=" << d.layoutFunctionsEnabled << ','
80 << d.marginFunction << ',' << d.spacingFunction << " PixFunction="
81 << d.pixFunction << " Author=" << d.author << " Hints=" << d.includeHints
82 << " Grid=" << d.hasFormGrid << d.grid.deltaX() << d.grid.deltaY()
83 << " ID-based translations" << d.idBasedTranslations
84 << " Connect slots by name" << d.connectSlotsByName
85 << '\n';
86 return str;
87}
88
89bool FormWindowData::equals(const FormWindowData &rhs) const
90{
91 return layoutDefaultEnabled == rhs.layoutDefaultEnabled &&
92 defaultMargin == rhs.defaultMargin &&
93 defaultSpacing == rhs.defaultSpacing &&
94 layoutFunctionsEnabled == rhs.layoutFunctionsEnabled &&
95 marginFunction == rhs.marginFunction &&
96 spacingFunction == rhs.spacingFunction &&
97 pixFunction == rhs.pixFunction &&
98 author == rhs.author &&
99 includeHints == rhs.includeHints &&
100 hasFormGrid == rhs.hasFormGrid &&
101 grid == rhs.grid &&
102 idBasedTranslations == rhs.idBasedTranslations &&
103 connectSlotsByName == rhs.connectSlotsByName;
104}
105
106void FormWindowData::fromFormWindow(FormWindowBase* fw)
107{
108 defaultMargin = defaultSpacing = INT_MIN;
109 fw->layoutDefault(margin: &defaultMargin, spacing: &defaultSpacing);
110
111 auto container = fw->formContainer();
112 QStyle *style = container->style();
113 layoutDefaultEnabled = defaultMargin != INT_MIN || defaultSpacing != INT_MIN;
114 if (defaultMargin == INT_MIN)
115 defaultMargin = style->pixelMetric(metric: QStyle::PM_LayoutLeftMargin, option: nullptr, widget: container);
116 if (defaultSpacing == INT_MIN)
117 defaultSpacing = style->pixelMetric(metric: QStyle::PM_LayoutHorizontalSpacing, option: nullptr);
118
119
120 marginFunction.clear();
121 spacingFunction.clear();
122 fw->layoutFunction(margin: &marginFunction, spacing: &spacingFunction);
123 layoutFunctionsEnabled = !marginFunction.isEmpty() || !spacingFunction.isEmpty();
124
125 pixFunction = fw->pixmapFunction();
126
127 author = fw->author();
128
129 includeHints = fw->includeHints();
130 includeHints.removeAll(t: QString());
131
132 hasFormGrid = fw->hasFormGrid();
133 grid = hasFormGrid ? fw->designerGrid() : FormWindowBase::defaultDesignerGrid();
134 idBasedTranslations = fw->useIdBasedTranslations();
135 connectSlotsByName = fw->connectSlotsByName();
136}
137
138void FormWindowData::applyToFormWindow(FormWindowBase* fw) const
139{
140 fw->setAuthor(author);
141 fw->setPixmapFunction(pixFunction);
142
143 if (layoutDefaultEnabled) {
144 fw->setLayoutDefault(margin: defaultMargin, spacing: defaultSpacing);
145 } else {
146 fw->setLayoutDefault(INT_MIN, INT_MIN);
147 }
148
149 if (layoutFunctionsEnabled) {
150 fw->setLayoutFunction(margin: marginFunction, spacing: spacingFunction);
151 } else {
152 fw->setLayoutFunction(margin: QString(), spacing: QString());
153 }
154
155 fw->setIncludeHints(includeHints);
156
157 const bool hadFormGrid = fw->hasFormGrid();
158 fw->setHasFormGrid(hasFormGrid);
159 if (hasFormGrid || hadFormGrid != hasFormGrid)
160 fw->setDesignerGrid(hasFormGrid ? grid : FormWindowBase::defaultDesignerGrid());
161 fw->setUseIdBasedTranslations(idBasedTranslations);
162 fw->setConnectSlotsByName(connectSlotsByName);
163}
164
165// -------------------------- FormWindowSettings
166
167FormWindowSettings::FormWindowSettings(QDesignerFormWindowInterface *parent) :
168 QDialog(parent),
169 m_ui(new ::Ui::FormWindowSettings),
170 m_formWindow(qobject_cast<FormWindowBase*>(object: parent)),
171 m_oldData(new FormWindowData)
172{
173 Q_ASSERT(m_formWindow);
174
175 m_ui->setupUi(this);
176 m_ui->gridPanel->setCheckable(true);
177 m_ui->gridPanel->setResetButtonVisible(false);
178
179 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
180
181 QString deviceProfileName = m_formWindow->deviceProfileName();
182 if (deviceProfileName.isEmpty())
183 deviceProfileName = tr(s: "None");
184 m_ui->deviceProfileLabel->setText(tr(s: "Device Profile: %1").arg(a: deviceProfileName));
185
186 m_oldData->fromFormWindow(fw: m_formWindow);
187 setData(*m_oldData);
188}
189
190FormWindowSettings::~FormWindowSettings()
191{
192 delete m_oldData;
193 delete m_ui;
194}
195
196FormWindowData FormWindowSettings::data() const
197{
198 FormWindowData rc;
199 rc.author = m_ui->authorLineEdit->text();
200
201 if (m_ui->pixmapFunctionGroupBox->isChecked()) {
202 rc.pixFunction = m_ui->pixmapFunctionLineEdit->text();
203 } else {
204 rc.pixFunction.clear();
205 }
206
207 rc.layoutDefaultEnabled = m_ui->layoutDefaultGroupBox->isChecked();
208 rc.defaultMargin = m_ui->defaultMarginSpinBox->value();
209 rc.defaultSpacing = m_ui->defaultSpacingSpinBox->value();
210
211 rc.layoutFunctionsEnabled = m_ui->layoutFunctionGroupBox->isChecked();
212 rc.marginFunction = m_ui->marginFunctionLineEdit->text();
213 rc.spacingFunction = m_ui->spacingFunctionLineEdit->text();
214
215 const QString hints = m_ui->includeHintsTextEdit->toPlainText();
216 if (!hints.isEmpty()) {
217 rc.includeHints = hints.split(sep: QLatin1Char('\n'));
218 // Purge out any lines consisting of blanks only
219 const QRegularExpression blankLine(QStringLiteral("^\\s*$"));
220 Q_ASSERT(blankLine.isValid());
221 rc.includeHints.erase(afirst: std::remove_if(first: rc.includeHints.begin(), last: rc.includeHints.end(),
222 pred: [blankLine](const QString &hint){ return blankLine.match(subject: hint).hasMatch(); }),
223 alast: rc.includeHints.end());
224 }
225
226 rc.hasFormGrid = m_ui->gridPanel->isChecked();
227 rc.grid = m_ui->gridPanel->grid();
228 rc.idBasedTranslations = m_ui->idBasedTranslationsCheckBox->isChecked();
229 rc.connectSlotsByName = m_ui->connectSlotsByNameCheckBox->isChecked();
230 return rc;
231}
232
233void FormWindowSettings::setData(const FormWindowData &data)
234{
235 m_ui->layoutDefaultGroupBox->setChecked(data.layoutDefaultEnabled);
236 m_ui->defaultMarginSpinBox->setValue(data.defaultMargin);
237 m_ui->defaultSpacingSpinBox->setValue(data.defaultSpacing);
238
239 m_ui->layoutFunctionGroupBox->setChecked(data.layoutFunctionsEnabled);
240 m_ui->marginFunctionLineEdit->setText(data.marginFunction);
241 m_ui->spacingFunctionLineEdit->setText(data.spacingFunction);
242
243 m_ui->pixmapFunctionLineEdit->setText(data.pixFunction);
244 m_ui->pixmapFunctionGroupBox->setChecked(!data.pixFunction.isEmpty());
245
246 m_ui->authorLineEdit->setText(data.author);
247
248 if (data.includeHints.isEmpty()) {
249 m_ui->includeHintsTextEdit->clear();
250 } else {
251 m_ui->includeHintsTextEdit->setText(data.includeHints.join(sep: QLatin1Char('\n')));
252 }
253
254 m_ui->gridPanel->setChecked(data.hasFormGrid);
255 m_ui->gridPanel->setGrid(data.grid);
256 m_ui->idBasedTranslationsCheckBox->setChecked(data.idBasedTranslations);
257 m_ui->connectSlotsByNameCheckBox->setChecked(data.connectSlotsByName);
258}
259
260void FormWindowSettings::accept()
261{
262 // Anything changed? -> Apply and set dirty
263 const FormWindowData newData = data();
264 if (newData != *m_oldData) {
265 newData.applyToFormWindow(fw: m_formWindow);
266 m_formWindow->setDirty(true);
267 }
268
269 QDialog::accept();
270}
271}
272QT_END_NAMESPACE
273

source code of qttools/src/designer/src/components/formeditor/formwindowsettings.cpp