OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / wizards / guiappwizard.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "guiappwizard.h"
35
36 #include "guiappwizarddialog.h"
37 #include "qt4projectmanagerconstants.h"
38
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>
44
45 #include <QtCore/QDir>
46 #include <QtCore/QFile>
47 #include <QtCore/QTextStream>
48 #include <QtCore/QUuid>
49 #include <QtCore/QFileInfo>
50 #include <QtCore/QSharedPointer>
51
52 #include <QtGui/QIcon>
53
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"
58 "#else\n"
59 "    w.show();\n"
60 "#endif\n";
61
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\" />";
69
70 static const char *baseClassesC[] = { "QMainWindow", "QWidget", "QDialog" };
71
72 static inline QStringList baseClasses()
73 {
74     QStringList rc;
75     const int baseClassCount = sizeof(baseClassesC)/sizeof(const char *);
76     for (int i = 0; i < baseClassCount; i++)
77         rc.push_back(QLatin1String(baseClassesC[i]));
78     return rc;
79 }
80
81 namespace Qt4ProjectManager {
82 namespace Internal {
83
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)
95 {
96 }
97
98 GuiAppWizard::GuiAppWizard(const QString &id,
99                            const QString &category,
100                            const QString &categoryTranslationScope,
101                            const QString &displayCategory,
102                            const QString &name,
103                            const QString &description,
104                            const QIcon &icon,
105                            bool createMobile)
106     : QtWizard(id, category, categoryTranslationScope,
107                displayCategory, name, description, icon),
108       m_createMobileProject(createMobile)
109 {
110 }
111
112 QWizard *GuiAppWizard::createWizardDialog(QWidget *parent,
113                                           const QString &defaultPath,
114                                           const WizardPageList &extensionPages) const
115 {
116     GuiAppWizardDialog *dialog = new GuiAppWizardDialog(displayName(), icon(), extensionPages,
117                                                         showModulesPageForApplications(),
118                                                         m_createMobileProject,
119                                                         parent);
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());
126     return dialog;
127 }
128
129 // Use the class generation utils provided by the designer plugin
130 static inline bool generateFormClass(const GuiAppParameters &params,
131                                      const Core::GeneratedFile &uiFile,
132                                      Core::GeneratedFile *formSource,
133                                      Core::GeneratedFile *formHeader,
134                                      QString *errorMessage)
135 {
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();
153             }
154         }
155     }
156     if (headerContents.isEmpty() || sourceContents.isEmpty()) {
157         *errorMessage = QString::fromAscii("Failed to obtain Designer plugin code generation service.");
158         return false;
159     }
160
161     formHeader->setContents(headerContents);
162     formSource->setContents(sourceContents);
163     return true;
164 }
165
166 Core::GeneratedFiles GuiAppWizard::generateFiles(const QWizard *w,
167                                                  QString *errorMessage) const
168 {
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();
174
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
179     QString contents;
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)
185                            + contents);
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);
192
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();
203     } else {
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)
208                                + contents);
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)
214                                + contents);
215     }
216     // Create files: profile
217     const QString profileName = buildFileName(projectPath, projectParams.fileName, profileSuffix());
218     Core::GeneratedFile profile(profileName);
219     profile.setAttributes(Core::GeneratedFile::OpenProjectAttribute);
220     contents.clear();
221     {
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);
233
234             proStr << "\n\nCONFIG += mobility"
235                    << "\nMOBILITY = "
236                    << "\n\nsymbian {"
237                    << "\n    TARGET.UID3 = " << uid3String
238                    << "\n    # TARGET.CAPABILITY += "
239                    << "\n    TARGET.EPOCSTACKSIZE = 0x14000"
240                    << "\n    TARGET.EPOCHEAPSIZE = 0x020000 0x800000"
241                    << "\n}";
242         }
243         proStr << '\n';
244     }
245     profile.setContents(contents);
246     // List
247     Core::GeneratedFiles rc;
248     rc << mainSource << formSource << formHeader;
249     if (params.designerForm)
250         rc << *form;
251     rc << profile;
252     return rc;
253 }
254
255 bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QString &templateName,
256                                        const GuiAppParameters &params,
257                                        QString *target, QString *errorMessage)
258 {
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());
265         return false;
266     }
267     QString contents = QString::fromUtf8(inFile.readAll());
268
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));
277     else
278         contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceShowC));
279
280
281     const QChar dot = QLatin1Char('.');
282
283     QString preDef = params.headerFileName.toUpper();
284     preDef.replace(dot, QLatin1Char('_'));
285     contents.replace("%PRE_DEF%", preDef.toUtf8());
286
287     const QString uiFileName = params.formFileName;
288     QString uiHdr = QLatin1String("ui_");
289     uiHdr += uiFileName.left(uiFileName.indexOf(dot));
290     uiHdr += QLatin1String(".h");
291
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));
296         else
297             contents.replace(QLatin1String("%CENTRAL_WIDGET%"), QLatin1String(mainWindowUiContentsC));
298     } else {
299         contents.remove(QLatin1String("%CENTRAL_WIDGET%"));
300     }
301     *target = contents;
302     return true;
303 }
304
305 } // namespace Internal
306 } // namespace Qt4ProjectManager