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 | |
32 | QT_BEGIN_NAMESPACE |
33 | |
34 | using namespace Qt::StringLiterals; |
35 | |
36 | NewForm::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 | |
73 | QDialogButtonBox *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 * = 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 | |
96 | NewForm::~NewForm() |
97 | { |
98 | QDesignerSettings settings (m_workbench->core()); |
99 | settings.setShowNewFormOnStartup(m_chkShowOnStartup->isChecked()); |
100 | } |
101 | |
102 | void 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 | |
109 | void 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 | |
119 | void NewForm::slotTemplateActivated() |
120 | { |
121 | m_createButton->animateClick(); |
122 | } |
123 | |
124 | void 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 | |
151 | bool 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 | |
180 | QImage 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 | |
188 | QT_END_NAMESPACE |
189 | |