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 "newform.h"
30#include "qdesigner_workbench.h"
31#include "qdesigner_actions.h"
32#include "qdesigner_formwindow.h"
33#include "qdesigner_settings.h"
34
35#include <newformwidget_p.h>
36
37#include <QtDesigner/abstractformeditor.h>
38
39#include <QtCore/qdir.h>
40#include <QtCore/qfileinfo.h>
41#include <QtCore/qdebug.h>
42#include <QtCore/qdir.h>
43#include <QtCore/qtemporaryfile.h>
44
45#include <QtWidgets/qapplication.h>
46#include <QtWidgets/qboxlayout.h>
47#include <QtWidgets/qpushbutton.h>
48#include <QtWidgets/qdialogbuttonbox.h>
49#include <QtWidgets/qmenu.h>
50#include <QtWidgets/qcheckbox.h>
51#include <QtWidgets/qframe.h>
52#include <QtWidgets/qmessagebox.h>
53
54QT_BEGIN_NAMESPACE
55
56NewForm::NewForm(QDesignerWorkbench *workbench, QWidget *parentWidget, const QString &fileName)
57 : QDialog(parentWidget, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint),
58 m_fileName(fileName),
59 m_newFormWidget(QDesignerNewFormWidgetInterface::createNewFormWidget(core: workbench->core())),
60 m_workbench(workbench),
61 m_chkShowOnStartup(new QCheckBox(tr(s: "Show this Dialog on Startup"))),
62 m_createButton(new QPushButton(QApplication::translate(context: "NewForm", key: "C&reate", disambiguation: nullptr))),
63 m_recentButton(new QPushButton(QApplication::translate(context: "NewForm", key: "Recent", disambiguation: nullptr))),
64 m_buttonBox(nullptr)
65{
66 setWindowTitle(tr(s: "New Form"));
67 QDesignerSettings settings(m_workbench->core());
68
69 QVBoxLayout *vBoxLayout = new QVBoxLayout;
70
71 connect(sender: m_newFormWidget, signal: &QDesignerNewFormWidgetInterface::templateActivated,
72 receiver: this, slot: &NewForm::slotTemplateActivated);
73 connect(sender: m_newFormWidget, signal: &QDesignerNewFormWidgetInterface::currentTemplateChanged,
74 receiver: this, slot: &NewForm::slotCurrentTemplateChanged);
75 vBoxLayout->addWidget(m_newFormWidget);
76
77 QFrame *horizontalLine = new QFrame;
78 horizontalLine->setFrameShape(QFrame::HLine);
79 horizontalLine->setFrameShadow(QFrame::Sunken);
80 vBoxLayout->addWidget(horizontalLine);
81
82 m_chkShowOnStartup->setChecked(settings.showNewFormOnStartup());
83 vBoxLayout->addWidget(m_chkShowOnStartup);
84
85 m_buttonBox = createButtonBox();
86 vBoxLayout->addWidget(m_buttonBox);
87 setLayout(vBoxLayout);
88
89 resize(w: 500, h: 400);
90 slotCurrentTemplateChanged(templateSelected: m_newFormWidget->hasCurrentTemplate());
91}
92
93QDialogButtonBox *NewForm::createButtonBox()
94{
95 // Dialog buttons with 'recent files'
96 QDialogButtonBox *buttonBox = new QDialogButtonBox;
97 buttonBox->addButton(text: QApplication::translate(context: "NewForm", key: "&Close", disambiguation: nullptr),
98 role: QDialogButtonBox::RejectRole);
99 buttonBox->addButton(button: m_createButton, role: QDialogButtonBox::AcceptRole);
100 buttonBox->addButton(text: QApplication::translate(context: "NewForm", key: "&Open...", disambiguation: nullptr),
101 role: QDialogButtonBox::ActionRole);
102 buttonBox->addButton(button: m_recentButton, role: QDialogButtonBox::ActionRole);
103 QDesignerActions *da = m_workbench->actionManager();
104 QMenu *recentFilesMenu = new QMenu(tr(s: "&Recent Forms"), m_recentButton);
105 // Pop the "Recent Files" stuff in here.
106 const auto recentActions = da->recentFilesActions()->actions();
107 for (auto action : recentActions) {
108 recentFilesMenu->addAction(action);
109 connect(sender: action, signal: &QAction::triggered, receiver: this, slot: &NewForm::recentFileChosen);
110 }
111 m_recentButton->setMenu(recentFilesMenu);
112 connect(sender: buttonBox, signal: &QDialogButtonBox::clicked, receiver: this, slot: &NewForm::slotButtonBoxClicked);
113 return buttonBox;
114}
115
116NewForm::~NewForm()
117{
118 QDesignerSettings settings (m_workbench->core());
119 settings.setShowNewFormOnStartup(m_chkShowOnStartup->isChecked());
120}
121
122void NewForm::recentFileChosen()
123{
124 QAction *action = qobject_cast<QAction *>(object: sender());
125 if (!action)
126 return;
127 if (action->objectName() == QStringLiteral("__qt_action_clear_menu_"))
128 return;
129 close();
130}
131
132void NewForm::slotCurrentTemplateChanged(bool templateSelected)
133{
134 if (templateSelected) {
135 m_createButton->setEnabled(true);
136 m_createButton->setDefault(true);
137 } else {
138 m_createButton->setEnabled(false);
139 }
140}
141
142void NewForm::slotTemplateActivated()
143{
144 m_createButton->animateClick();
145}
146
147void NewForm::slotButtonBoxClicked(QAbstractButton *btn)
148{
149 switch (m_buttonBox->buttonRole(button: btn)) {
150 case QDialogButtonBox::RejectRole:
151 reject();
152 break;
153 case QDialogButtonBox::ActionRole:
154 if (btn != m_recentButton) {
155 m_fileName.clear();
156 if (m_workbench->actionManager()->openForm(parent: this))
157 accept();
158 }
159 break;
160 case QDialogButtonBox::AcceptRole: {
161 QString errorMessage;
162 if (openTemplate(ptrToErrorMessage: &errorMessage)) {
163 accept();
164 } else {
165 QMessageBox::warning(parent: this, title: tr(s: "Read error"), text: errorMessage);
166 }
167 }
168 break;
169 default:
170 break;
171 }
172}
173
174bool NewForm::openTemplate(QString *ptrToErrorMessage)
175{
176 const QString contents = m_newFormWidget->currentTemplate(errorMessage: ptrToErrorMessage);
177 if (contents.isEmpty())
178 return false;
179 // Write to temporary file and open
180 QString tempPattern = QDir::tempPath();
181 if (!tempPattern.endsWith(c: QDir::separator())) // platform-dependant
182 tempPattern += QDir::separator();
183 tempPattern += QStringLiteral("XXXXXX.ui");
184 QTemporaryFile tempFormFile(tempPattern);
185
186 tempFormFile.setAutoRemove(true);
187 if (!tempFormFile.open()) {
188 *ptrToErrorMessage = tr(s: "A temporary form file could not be created in %1: %2")
189 .arg(args: QDir::toNativeSeparators(pathName: QDir::tempPath()), args: tempFormFile.errorString());
190 return false;
191 }
192 const QString tempFormFileName = tempFormFile.fileName();
193 tempFormFile.write(data: contents.toUtf8());
194 if (!tempFormFile.flush()) {
195 *ptrToErrorMessage = tr(s: "The temporary form file %1 could not be written: %2")
196 .arg(args: QDir::toNativeSeparators(pathName: tempFormFileName), args: tempFormFile.errorString());
197 return false;
198 }
199 tempFormFile.close();
200 return m_workbench->openTemplate(templateFileName: tempFormFileName, editorFileName: m_fileName, errorMessage: ptrToErrorMessage);
201}
202
203QImage NewForm::grabForm(QDesignerFormEditorInterface *core,
204 QIODevice &file,
205 const QString &workingDir,
206 const qdesigner_internal::DeviceProfile &dp)
207{
208 return qdesigner_internal::NewFormWidget::grabForm(core, file, workingDir, dp);
209}
210
211QT_END_NAMESPACE
212

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