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 "saveformastemplate.h"
30#include "qdesigner_settings.h"
31
32#include <QtCore/qfile.h>
33#include <QtWidgets/qfiledialog.h>
34#include <QtWidgets/qmessagebox.h>
35#include <QtWidgets/qpushbutton.h>
36
37#include <QtDesigner/abstractformeditor.h>
38#include <QtDesigner/abstractformwindow.h>
39
40QT_BEGIN_NAMESPACE
41
42SaveFormAsTemplate::SaveFormAsTemplate(QDesignerFormEditorInterface *core,
43 QDesignerFormWindowInterface *formWindow,
44 QWidget *parent)
45 : QDialog(parent, Qt::Sheet),
46 m_core(core),
47 m_formWindow(formWindow)
48{
49 ui.setupUi(this);
50 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
51
52 ui.templateNameEdit->setText(formWindow->mainContainer()->objectName());
53 ui.templateNameEdit->selectAll();
54
55 ui.templateNameEdit->setFocus();
56
57 QStringList paths = QDesignerSettings(m_core).formTemplatePaths();
58 ui.categoryCombo->addItems(texts: paths);
59 ui.categoryCombo->addItem(atext: tr(s: "Add path..."));
60 m_addPathIndex = ui.categoryCombo->count() - 1;
61 connect(sender: ui.templateNameEdit, signal: &QLineEdit::textChanged,
62 receiver: this, slot: &SaveFormAsTemplate::updateOKButton);
63 connect(sender: ui.categoryCombo, signal: QOverload<int>::of(ptr: &QComboBox::activated),
64 receiver: this, slot: &SaveFormAsTemplate::checkToAddPath);
65}
66
67SaveFormAsTemplate::~SaveFormAsTemplate() = default;
68
69void SaveFormAsTemplate::accept()
70{
71 QString templateFileName = ui.categoryCombo->currentText();
72 templateFileName += QLatin1Char('/');
73 const QString name = ui.templateNameEdit->text();
74 templateFileName += name;
75 const QString extension = QStringLiteral(".ui");
76 if (!templateFileName.endsWith(s: extension))
77 templateFileName.append(s: extension);
78 QFile file(templateFileName);
79
80 if (file.exists()) {
81 QMessageBox msgBox(QMessageBox::Information, tr(s: "Template Exists"),
82 tr(s: "A template with the name %1 already exists.\n"
83 "Do you want overwrite the template?").arg(a: name), QMessageBox::Cancel, m_formWindow);
84 msgBox.setDefaultButton(QMessageBox::Cancel);
85 QPushButton *overwriteButton = msgBox.addButton(text: tr(s: "Overwrite Template"), role: QMessageBox::AcceptRole);
86 msgBox.exec();
87 if (msgBox.clickedButton() != overwriteButton)
88 return;
89 }
90
91 while (!file.open(flags: QFile::WriteOnly)) {
92 if (QMessageBox::information(parent: m_formWindow, title: tr(s: "Open Error"),
93 text: tr(s: "There was an error opening template %1 for writing. Reason: %2")
94 .arg(args: name, args: file.errorString()),
95 buttons: QMessageBox::Retry|QMessageBox::Cancel, defaultButton: QMessageBox::Cancel) == QMessageBox::Cancel) {
96 return;
97 }
98 }
99
100 const QString origName = m_formWindow->fileName();
101 // ensure m_formWindow->contents() will convert properly resource paths to relative paths
102 // (relative to template location, not to the current form location)
103 m_formWindow->setFileName(templateFileName);
104 QByteArray ba = m_formWindow->contents().toUtf8();
105 m_formWindow->setFileName(origName);
106 while (file.write(data: ba) != ba.size()) {
107 if (QMessageBox::information(parent: m_formWindow, title: tr(s: "Write Error"),
108 text: tr(s: "There was an error writing the template %1 to disk. Reason: %2")
109 .arg(args: name, args: file.errorString()),
110 buttons: QMessageBox::Retry|QMessageBox::Cancel, defaultButton: QMessageBox::Cancel) == QMessageBox::Cancel) {
111 file.close();
112 file.remove();
113 return;
114 }
115 file.reset();
116 }
117 // update the list of places too...
118 QStringList sl;
119 for (int i = 0; i < m_addPathIndex; ++i)
120 sl << ui.categoryCombo->itemText(index: i);
121
122 QDesignerSettings(m_core).setFormTemplatePaths(sl);
123
124 QDialog::accept();
125}
126
127void SaveFormAsTemplate::updateOKButton(const QString &str)
128{
129 QPushButton *okButton = ui.buttonBox->button(which: QDialogButtonBox::Ok);
130 okButton->setEnabled(!str.isEmpty());
131}
132
133QString SaveFormAsTemplate::chooseTemplatePath(QWidget *parent)
134{
135 QString rc = QFileDialog::getExistingDirectory(parent,
136 caption: tr(s: "Pick a directory to save templates in"));
137 if (rc.isEmpty())
138 return rc;
139
140 if (rc.endsWith(c: QDir::separator()))
141 rc.remove(i: rc.size() - 1, len: 1);
142 return rc;
143}
144
145void SaveFormAsTemplate::checkToAddPath(int itemIndex)
146{
147 if (itemIndex != m_addPathIndex)
148 return;
149
150 const QString dir = chooseTemplatePath(parent: this);
151 if (dir.isEmpty()) {
152 ui.categoryCombo->setCurrentIndex(0);
153 return;
154 }
155
156 ui.categoryCombo->insertItem(aindex: m_addPathIndex, atext: dir);
157 ui.categoryCombo->setCurrentIndex(m_addPathIndex);
158 ++m_addPathIndex;
159}
160
161QT_END_NAMESPACE
162

source code of qttools/src/designer/src/designer/saveformastemplate.cpp