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 | |
54 | QT_BEGIN_NAMESPACE |
55 | |
56 | NewForm::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 | |
93 | QDialogButtonBox *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 * = 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 | |
116 | NewForm::~NewForm() |
117 | { |
118 | QDesignerSettings settings (m_workbench->core()); |
119 | settings.setShowNewFormOnStartup(m_chkShowOnStartup->isChecked()); |
120 | } |
121 | |
122 | void 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 | |
132 | void 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 | |
142 | void NewForm::slotTemplateActivated() |
143 | { |
144 | m_createButton->animateClick(); |
145 | } |
146 | |
147 | void 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 | |
174 | bool 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 | |
203 | QImage 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 | |
211 | QT_END_NAMESPACE |
212 | |