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

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