1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "guiappwizard.h"
36 #include "guiappwizarddialog.h"
37 #include "qt4projectmanagerconstants.h"
39 #include <cpptools/abstracteditorsupport.h>
40 #include <designer/cpp/formclasswizardparameters.h>
41 #include <coreplugin/icore.h>
42 #include <extensionsystem/pluginmanager.h>
43 #include <extensionsystem/invoker.h>
45 #include <QtCore/QDir>
46 #include <QtCore/QFile>
47 #include <QtCore/QTextStream>
48 #include <QtCore/QUuid>
49 #include <QtCore/QFileInfo>
50 #include <QtCore/QSharedPointer>
52 #include <QtGui/QIcon>
54 static const char *mainSourceFileC = "main";
55 static const char *mainSourceShowC = " w.show();\n";
56 static const char *mainSourceMobilityShowC = "#if defined(Q_WS_S60)\n"
57 " w.showMaximized();\n"
62 static const char *mainWindowUiContentsC =
63 "\n <widget class=\"QMenuBar\" name=\"menuBar\" />"
64 "\n <widget class=\"QToolBar\" name=\"mainToolBar\" />"
65 "\n <widget class=\"QWidget\" name=\"centralWidget\" />"
66 "\n <widget class=\"QStatusBar\" name=\"statusBar\" />";
67 static const char *mainWindowMobileUiContentsC =
68 "\n <widget class=\"QWidget\" name=\"centralWidget\" />";
70 static const char *baseClassesC[] = { "QMainWindow", "QWidget", "QDialog" };
72 static inline QStringList baseClasses()
75 const int baseClassCount = sizeof(baseClassesC)/sizeof(const char *);
76 for (int i = 0; i < baseClassCount; i++)
77 rc.push_back(QLatin1String(baseClassesC[i]));
81 namespace Qt4ProjectManager {
84 GuiAppWizard::GuiAppWizard()
85 : QtWizard(QLatin1String("C.Qt4Gui"),
86 QLatin1String(Constants::QT_APP_WIZARD_CATEGORY),
87 QLatin1String(Constants::QT_APP_WIZARD_TR_SCOPE),
88 QLatin1String(Constants::QT_APP_WIZARD_TR_CATEGORY),
89 tr("Qt Gui Application"),
90 tr("Creates a Qt application for the desktop. "
91 "Includes a Qt Designer-based main window.\n\n"
92 "Preselects a desktop Qt for building the application if available."),
93 QIcon(QLatin1String(":/wizards/images/gui.png"))),
94 m_createMobileProject(false)
98 GuiAppWizard::GuiAppWizard(const QString &id,
99 const QString &category,
100 const QString &categoryTranslationScope,
101 const QString &displayCategory,
103 const QString &description,
106 : QtWizard(id, category, categoryTranslationScope,
107 displayCategory, name, description, icon),
108 m_createMobileProject(createMobile)
112 QWizard *GuiAppWizard::createWizardDialog(QWidget *parent,
113 const QString &defaultPath,
114 const WizardPageList &extensionPages) const
116 GuiAppWizardDialog *dialog = new GuiAppWizardDialog(displayName(), icon(), extensionPages,
117 showModulesPageForApplications(),
118 m_createMobileProject,
120 dialog->setPath(defaultPath);
121 dialog->setProjectName(GuiAppWizardDialog::uniqueProjectName(defaultPath));
122 // Order! suffixes first to generate files correctly
123 dialog->setLowerCaseFiles(QtWizard::lowerCaseFiles());
124 dialog->setSuffixes(headerSuffix(), sourceSuffix(), formSuffix());
125 dialog->setBaseClasses(baseClasses());
129 // Use the class generation utils provided by the designer plugin
130 static inline bool generateFormClass(const GuiAppParameters ¶ms,
131 const Core::GeneratedFile &uiFile,
132 Core::GeneratedFile *formSource,
133 Core::GeneratedFile *formHeader,
134 QString *errorMessage)
136 // Retrieve parameters from settings
137 Designer::FormClassWizardParameters fp;
138 fp.uiTemplate = uiFile.contents();
139 fp.uiFile = uiFile.path();
140 fp.className = params.className;
141 fp.sourceFile = params.sourceFileName;
142 fp.headerFile = params.headerFileName;
143 QString headerContents;
144 QString sourceContents;
145 // Invoke code generation service of Qt Designer plugin.
146 if (QObject *codeGenerator = ExtensionSystem::PluginManager::instance()->getObjectByClassName("Designer::QtDesignerFormClassCodeGenerator")) {
147 const QVariant code = ExtensionSystem::invoke<QVariant>(codeGenerator, "generateFormClassCode", fp);
148 if (code.type() == QVariant::List) {
149 const QVariantList vl = code.toList();
150 if (vl.size() == 2) {
151 headerContents = vl.front().toString();
152 sourceContents = vl.back().toString();
156 if (headerContents.isEmpty() || sourceContents.isEmpty()) {
157 *errorMessage = QString::fromAscii("Failed to obtain Designer plugin code generation service.");
161 formHeader->setContents(headerContents);
162 formSource->setContents(sourceContents);
166 Core::GeneratedFiles GuiAppWizard::generateFiles(const QWizard *w,
167 QString *errorMessage) const
169 const GuiAppWizardDialog *dialog = qobject_cast<const GuiAppWizardDialog *>(w);
170 const QtProjectParameters projectParams = dialog->projectParameters();
171 const QString projectPath = projectParams.projectPath();
172 const GuiAppParameters params = dialog->parameters();
173 const QString license = CppTools::AbstractEditorSupport::licenseTemplate();
175 // Generate file names. Note that the path for the project files is the
176 // newly generated project directory.
177 const QString templatePath = templateDir();
178 // Create files: main source
180 const QString mainSourceFileName = buildFileName(projectPath, QLatin1String(mainSourceFileC), sourceSuffix());
181 Core::GeneratedFile mainSource(mainSourceFileName);
182 if (!parametrizeTemplate(templatePath, QLatin1String("main.cpp"), params, &contents, errorMessage))
183 return Core::GeneratedFiles();
184 mainSource.setContents(CppTools::AbstractEditorSupport::licenseTemplate(mainSourceFileName)
186 // Create files: form source with or without form
187 const QString formSourceFileName = buildFileName(projectPath, params.sourceFileName, sourceSuffix());
188 const QString formHeaderName = buildFileName(projectPath, params.headerFileName, headerSuffix());
189 Core::GeneratedFile formSource(formSourceFileName);
190 Core::GeneratedFile formHeader(formHeaderName);
191 formSource.setAttributes(Core::GeneratedFile::OpenEditorAttribute);
193 QSharedPointer<Core::GeneratedFile> form;
194 if (params.designerForm) {
195 // Create files: form
196 const QString formName = buildFileName(projectPath, params.formFileName, formSuffix());
197 form = QSharedPointer<Core::GeneratedFile>(new Core::GeneratedFile(formName));
198 if (!parametrizeTemplate(templatePath, QLatin1String("widget.ui"), params, &contents, errorMessage))
199 return Core::GeneratedFiles();
200 form->setContents(contents);
201 if (!generateFormClass(params, *form, &formSource, &formHeader, errorMessage))
202 return Core::GeneratedFiles();
204 const QString formSourceTemplate = QLatin1String("mywidget.cpp");
205 if (!parametrizeTemplate(templatePath, formSourceTemplate, params, &contents, errorMessage))
206 return Core::GeneratedFiles();
207 formSource.setContents(CppTools::AbstractEditorSupport::licenseTemplate(formSourceFileName)
209 // Create files: form header
210 const QString formHeaderTemplate = QLatin1String("mywidget.h");
211 if (!parametrizeTemplate(templatePath, formHeaderTemplate, params, &contents, errorMessage))
212 return Core::GeneratedFiles();
213 formHeader.setContents(CppTools::AbstractEditorSupport::licenseTemplate(formHeaderName)
216 // Create files: profile
217 const QString profileName = buildFileName(projectPath, projectParams.fileName, profileSuffix());
218 Core::GeneratedFile profile(profileName);
219 profile.setAttributes(Core::GeneratedFile::OpenProjectAttribute);
222 QTextStream proStr(&contents);
223 QtProjectParameters::writeProFileHeader(proStr);
224 projectParams.writeProFile(proStr);
225 proStr << "\n\nSOURCES += " << QFileInfo(mainSourceFileName).fileName()
226 << "\\\n " << QFileInfo(formSource.path()).fileName()
227 << "\n\nHEADERS += " << QFileInfo(formHeader.path()).fileName();
228 if (params.designerForm)
229 proStr << "\n\nFORMS += " << QFileInfo(form->path()).fileName();
230 if (params.isMobileApplication) {
231 // Generate a development Symbian UID for the application:
232 QString uid3String = QLatin1String("0xe") + QUuid::createUuid().toString().mid(1, 7);
234 proStr << "\n\nCONFIG += mobility"
237 << "\n TARGET.UID3 = " << uid3String
238 << "\n # TARGET.CAPABILITY += "
239 << "\n TARGET.EPOCSTACKSIZE = 0x14000"
240 << "\n TARGET.EPOCHEAPSIZE = 0x020000 0x800000"
245 profile.setContents(contents);
247 Core::GeneratedFiles rc;
248 rc << mainSource << formSource << formHeader;
249 if (params.designerForm)
255 bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QString &templateName,
256 const GuiAppParameters ¶ms,
257 QString *target, QString *errorMessage)
259 QString fileName = templatePath;
260 fileName += QDir::separator();
261 fileName += templateName;
262 QFile inFile(fileName);
263 if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
264 *errorMessage = tr("The template file '%1' could not be opened for reading: %2").arg(fileName, inFile.errorString());
267 QString contents = QString::fromUtf8(inFile.readAll());
269 contents.replace(QLatin1String("%QAPP_INCLUDE%"), QLatin1String("QtGui/QApplication"));
270 contents.replace(QLatin1String("%INCLUDE%"), params.headerFileName);
271 contents.replace(QLatin1String("%CLASS%"), params.className);
272 contents.replace(QLatin1String("%BASECLASS%"), params.baseClassName);
273 contents.replace(QLatin1String("%WIDGET_HEIGHT%"), QString::number(params.widgetHeight));
274 contents.replace(QLatin1String("%WIDGET_WIDTH%"), QString::number(params.widgetWidth));
275 if (params.isMobileApplication)
276 contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceMobilityShowC));
278 contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceShowC));
281 const QChar dot = QLatin1Char('.');
283 QString preDef = params.headerFileName.toUpper();
284 preDef.replace(dot, QLatin1Char('_'));
285 contents.replace("%PRE_DEF%", preDef.toUtf8());
287 const QString uiFileName = params.formFileName;
288 QString uiHdr = QLatin1String("ui_");
289 uiHdr += uiFileName.left(uiFileName.indexOf(dot));
290 uiHdr += QLatin1String(".h");
292 contents.replace(QLatin1String("%UI_HDR%"), uiHdr);
293 if (params.baseClassName == QLatin1String("QMainWindow")) {
294 if (params.isMobileApplication)
295 contents.replace(QLatin1String("%CENTRAL_WIDGET%"), QLatin1String(mainWindowMobileUiContentsC));
297 contents.replace(QLatin1String("%CENTRAL_WIDGET%"), QLatin1String(mainWindowUiContentsC));
299 contents.remove(QLatin1String("%CENTRAL_WIDGET%"));
305 } // namespace Internal
306 } // namespace Qt4ProjectManager