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 "deviceprofiledialog.h"
30#include "ui_deviceprofiledialog.h"
31
32#include <abstractdialoggui_p.h>
33#include <deviceprofile_p.h>
34
35#include <QtWidgets/qdialogbuttonbox.h>
36#include <QtWidgets/qboxlayout.h>
37#include <QtWidgets/qpushbutton.h>
38#include <QtWidgets/qstylefactory.h>
39#include <QtGui/qfontdatabase.h>
40#include <QtGui/qvalidator.h>
41
42#include <QtCore/qfileinfo.h>
43#include <QtCore/qfile.h>
44
45QT_BEGIN_NAMESPACE
46
47static const char *profileExtensionC = "qdp";
48
49static inline QString fileFilter()
50{
51 return qdesigner_internal::DeviceProfileDialog::tr(s: "Device Profiles (*.%1)").arg(a: QLatin1String(profileExtensionC));
52}
53
54// Populate a combo with a sequence of integers, also set them as data.
55template <class IntIterator>
56 static void populateNumericCombo(IntIterator i1, IntIterator i2, QComboBox *cb)
57{
58 QString s;
59 for ( ; i1 != i2 ; ++i1) {
60 const int n = *i1;
61 s.setNum(n);
62 cb->addItem(atext: s, auserData: QVariant(n));
63 }
64}
65
66namespace qdesigner_internal {
67
68DeviceProfileDialog::DeviceProfileDialog(QDesignerDialogGuiInterface *dlgGui, QWidget *parent) :
69 QDialog(parent),
70 m_ui(new Ui::DeviceProfileDialog),
71 m_dlgGui(dlgGui)
72{
73 setModal(true);
74 m_ui->setupUi(this);
75
76 const auto standardFontSizes = QFontDatabase::standardSizes();
77 populateNumericCombo(i1: standardFontSizes.constBegin(), i2: standardFontSizes.constEnd(), cb: m_ui->m_systemFontSizeCombo);
78
79 // 288pt observed on macOS.
80 const int maxPointSize = qMax(a: 288, b: standardFontSizes.constLast());
81 m_ui->m_systemFontSizeCombo->setValidator(new QIntValidator(1, maxPointSize,
82 m_ui->m_systemFontSizeCombo));
83
84 // Styles
85 const QStringList styles = QStyleFactory::keys();
86 m_ui->m_styleCombo->addItem(atext: tr(s: "Default"), auserData: QVariant(QString()));
87 const QStringList::const_iterator cend = styles.constEnd();
88 for (QStringList::const_iterator it = styles.constBegin(); it != cend; ++it)
89 m_ui->m_styleCombo->addItem(atext: *it, auserData: *it);
90
91 connect(sender: m_ui->m_nameLineEdit, signal: &QLineEdit::textChanged, receiver: this, slot: &DeviceProfileDialog::nameChanged);
92 connect(sender: m_ui->buttonBox, signal: &QDialogButtonBox::rejected, receiver: this, slot: &QDialog::reject);
93 connect(sender: m_ui->buttonBox->button(which: QDialogButtonBox::Ok), signal: &QAbstractButton::clicked,
94 receiver: this, slot: &QDialog::accept);
95 // Note that Load/Save emit accepted() of the button box..
96 connect(sender: m_ui->buttonBox->button(which: QDialogButtonBox::Save), signal: &QAbstractButton::clicked,
97 receiver: this, slot: &DeviceProfileDialog::save);
98 connect(sender: m_ui->buttonBox->button(which: QDialogButtonBox::Open), signal: &QAbstractButton::clicked,
99 receiver: this, slot: &DeviceProfileDialog::open);
100}
101
102DeviceProfileDialog::~DeviceProfileDialog()
103{
104 delete m_ui;
105}
106
107DeviceProfile DeviceProfileDialog::deviceProfile() const
108{
109 DeviceProfile rc;
110 rc.setName(m_ui->m_nameLineEdit->text());
111 rc.setFontFamily(m_ui->m_systemFontComboBox->currentFont().family());
112 rc.setFontPointSize(m_ui->m_systemFontSizeCombo->itemData(index: m_ui->m_systemFontSizeCombo->currentIndex()).toInt());
113
114 int dpiX, dpiY;
115 m_ui->m_dpiChooser->getDPI(dpiX: &dpiX, dpiY: &dpiY);
116 rc.setDpiX(dpiX);
117 rc.setDpiY(dpiY);
118
119 rc.setStyle(m_ui->m_styleCombo->itemData(index: m_ui->m_styleCombo->currentIndex()).toString());
120
121 return rc;
122}
123
124void DeviceProfileDialog::setDeviceProfile(const DeviceProfile &s)
125{
126 m_ui->m_nameLineEdit->setText(s.name());
127 m_ui->m_systemFontComboBox->setCurrentFont(QFont(s.fontFamily()));
128 const int fontSizeIndex = m_ui->m_systemFontSizeCombo->findData(data: QVariant(s.fontPointSize()));
129 m_ui->m_systemFontSizeCombo->setCurrentIndex(fontSizeIndex != -1 ? fontSizeIndex : 0);
130 m_ui->m_dpiChooser->setDPI(dpiX: s.dpiX(), dpiY: s.dpiY());
131 const int styleIndex = m_ui->m_styleCombo->findData(data: s.style());
132 m_ui->m_styleCombo->setCurrentIndex(styleIndex != -1 ? styleIndex : 0);
133}
134
135void DeviceProfileDialog::setOkButtonEnabled(bool v)
136{
137 m_ui->buttonBox->button(which: QDialogButtonBox::Ok)->setEnabled(v);
138}
139
140bool DeviceProfileDialog::showDialog(const QStringList &existingNames)
141{
142 m_existingNames = existingNames;
143 m_ui->m_nameLineEdit->setFocus(Qt::OtherFocusReason);
144 nameChanged(name: m_ui->m_nameLineEdit->text());
145 return exec() == Accepted;
146}
147
148void DeviceProfileDialog::nameChanged(const QString &name)
149{
150 const bool invalid = name.isEmpty() || m_existingNames.indexOf(t: name) != -1;
151 setOkButtonEnabled(!invalid);
152}
153
154void DeviceProfileDialog::save()
155{
156 QString fn = m_dlgGui->getSaveFileName(parent: this, caption: tr(s: "Save Profile"), dir: QString(), filter: fileFilter());
157 if (fn.isEmpty())
158 return;
159 if (QFileInfo(fn).completeSuffix().isEmpty()) {
160 fn += QLatin1Char('.');
161 fn += QLatin1String(profileExtensionC);
162 }
163
164 QFile file(fn);
165 if (!file.open(flags: QIODevice::WriteOnly|QIODevice::Text)) {
166 critical(title: tr(s: "Save Profile - Error"), msg: tr(s: "Unable to open the file '%1' for writing: %2").arg(args&: fn, args: file.errorString()));
167 return;
168 }
169 file.write(data: deviceProfile().toXml().toUtf8());
170}
171
172void DeviceProfileDialog::open()
173{
174 const QString fn = m_dlgGui->getOpenFileName(parent: this, caption: tr(s: "Open profile"), dir: QString(), filter: fileFilter());
175 if (fn.isEmpty())
176 return;
177
178 QFile file(fn);
179 if (!file.open(flags: QIODevice::ReadOnly|QIODevice::Text)) {
180 critical(title: tr(s: "Open Profile - Error"), msg: tr(s: "Unable to open the file '%1' for reading: %2").arg(args: fn, args: file.errorString()));
181 return;
182 }
183 QString errorMessage;
184 DeviceProfile newSettings;
185 if (!newSettings.fromXml(xml: QString::fromUtf8(str: file.readAll()), errorMessage: &errorMessage)) {
186 critical(title: tr(s: "Open Profile - Error"), msg: tr(s: "'%1' is not a valid profile: %2").arg(args: fn, args&: errorMessage));
187 return;
188 }
189 setDeviceProfile(newSettings);
190}
191
192void DeviceProfileDialog::critical(const QString &title, const QString &msg)
193{
194 m_dlgGui->message(parent: this, context: QDesignerDialogGuiInterface::OtherMessage, icon: QMessageBox::Critical, title, text: msg);
195}
196}
197
198QT_END_NAMESPACE
199

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