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 
45 QT_BEGIN_NAMESPACE
46 
47 static const char *profileExtensionC = "qdp";
48 
fileFilter()49 static inline QString fileFilter()
50 {
51     return qdesigner_internal::DeviceProfileDialog::tr("Device Profiles (*.%1)").arg(QLatin1String(profileExtensionC));
52 }
53 
54 // Populate a combo with a sequence of integers, also set them as data.
55 template <class IntIterator>
populateNumericCombo(IntIterator i1,IntIterator i2,QComboBox * cb)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(s, QVariant(n));
63     }
64 }
65 
66 namespace qdesigner_internal {
67 
DeviceProfileDialog(QDesignerDialogGuiInterface * dlgGui,QWidget * parent)68 DeviceProfileDialog::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(standardFontSizes.constBegin(), standardFontSizes.constEnd(), m_ui->m_systemFontSizeCombo);
78 
79     // 288pt observed on macOS.
80     const int maxPointSize = qMax(288, 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(tr("Default"), 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(*it, *it);
90 
91     connect(m_ui->m_nameLineEdit, &QLineEdit::textChanged, this, &DeviceProfileDialog::nameChanged);
92     connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
93     connect(m_ui->buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
94             this, &QDialog::accept);
95     // Note that Load/Save emit accepted() of the button box..
96     connect(m_ui->buttonBox->button(QDialogButtonBox::Save), &QAbstractButton::clicked,
97             this, &DeviceProfileDialog::save);
98     connect(m_ui->buttonBox->button(QDialogButtonBox::Open), &QAbstractButton::clicked,
99             this, &DeviceProfileDialog::open);
100 }
101 
~DeviceProfileDialog()102 DeviceProfileDialog::~DeviceProfileDialog()
103 {
104     delete m_ui;
105 }
106 
deviceProfile() const107 DeviceProfile 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(m_ui->m_systemFontSizeCombo->currentIndex()).toInt());
113 
114     int dpiX, dpiY;
115     m_ui->m_dpiChooser->getDPI(&dpiX, &dpiY);
116     rc.setDpiX(dpiX);
117     rc.setDpiY(dpiY);
118 
119     rc.setStyle(m_ui->m_styleCombo->itemData(m_ui->m_styleCombo->currentIndex()).toString());
120 
121     return rc;
122 }
123 
setDeviceProfile(const DeviceProfile & s)124 void 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(QVariant(s.fontPointSize()));
129     m_ui->m_systemFontSizeCombo->setCurrentIndex(fontSizeIndex != -1 ? fontSizeIndex : 0);
130     m_ui->m_dpiChooser->setDPI(s.dpiX(), s.dpiY());
131     const int styleIndex = m_ui->m_styleCombo->findData(s.style());
132     m_ui->m_styleCombo->setCurrentIndex(styleIndex != -1 ? styleIndex : 0);
133 }
134 
setOkButtonEnabled(bool v)135 void DeviceProfileDialog::setOkButtonEnabled(bool v)
136 {
137     m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(v);
138 }
139 
showDialog(const QStringList & existingNames)140 bool DeviceProfileDialog::showDialog(const QStringList &existingNames)
141 {
142     m_existingNames = existingNames;
143     m_ui->m_nameLineEdit->setFocus(Qt::OtherFocusReason);
144     nameChanged(m_ui->m_nameLineEdit->text());
145     return exec() == Accepted;
146 }
147 
nameChanged(const QString & name)148 void DeviceProfileDialog::nameChanged(const QString &name)
149 {
150     const bool invalid = name.isEmpty() || m_existingNames.indexOf(name) != -1;
151     setOkButtonEnabled(!invalid);
152 }
153 
save()154 void DeviceProfileDialog::save()
155 {
156     QString fn = m_dlgGui->getSaveFileName(this, tr("Save Profile"), QString(), 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(QIODevice::WriteOnly|QIODevice::Text)) {
166         critical(tr("Save Profile - Error"), tr("Unable to open the file '%1' for writing: %2").arg(fn, file.errorString()));
167         return;
168     }
169     file.write(deviceProfile().toXml().toUtf8());
170 }
171 
open()172 void DeviceProfileDialog::open()
173 {
174     const QString fn = m_dlgGui->getOpenFileName(this, tr("Open profile"), QString(), fileFilter());
175     if (fn.isEmpty())
176         return;
177 
178     QFile file(fn);
179     if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
180         critical(tr("Open Profile - Error"), tr("Unable to open the file '%1' for reading: %2").arg(fn, file.errorString()));
181         return;
182     }
183     QString errorMessage;
184     DeviceProfile newSettings;
185     if (!newSettings.fromXml(QString::fromUtf8(file.readAll()), &errorMessage)) {
186         critical(tr("Open Profile - Error"), tr("'%1' is not a valid profile: %2").arg(fn, errorMessage));
187         return;
188     }
189     setDeviceProfile(newSettings);
190 }
191 
critical(const QString & title,const QString & msg)192 void DeviceProfileDialog::critical(const QString &title, const QString &msg)
193 {
194     m_dlgGui->message(this, QDesignerDialogGuiInterface::OtherMessage, QMessageBox::Critical, title, msg);
195 }
196 }
197 
198 QT_END_NAMESPACE
199