OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / basefilewizard.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 (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "basefilewizard.h"
34
35 #include "coreconstants.h"
36 #include "icore.h"
37 #include "ifilewizardextension.h"
38 #include "mimedatabase.h"
39 #include "editormanager/editormanager.h"
40
41 #include <extensionsystem/pluginmanager.h>
42 #include <utils/filewizarddialog.h>
43 #include <utils/qtcassert.h>
44 #include <utils/stringutils.h>
45
46 #include <QtCore/QDir>
47 #include <QtCore/QFile>
48 #include <QtCore/QFileInfo>
49 #include <QtCore/QVector>
50 #include <QtCore/QDebug>
51 #include <QtCore/QSharedData>
52 #include <QtCore/QEventLoop>
53 #include <QtCore/QSharedPointer>
54 #include <QtCore/QScopedPointer>
55
56 #include <QtGui/QMessageBox>
57 #include <QtGui/QWizard>
58 #include <QtGui/QMainWindow>
59 #include <QtGui/QIcon>
60
61 enum { debugWizard = 0 };
62
63 namespace Core {
64
65 class GeneratedFilePrivate : public QSharedData
66 {
67 public:
68     GeneratedFilePrivate() : binary(false) {}
69     explicit GeneratedFilePrivate(const QString &p);
70     QString path;
71     QByteArray contents;
72     QString editorId;
73     bool binary;
74     GeneratedFile::Attributes attributes;
75 };
76
77 GeneratedFilePrivate::GeneratedFilePrivate(const QString &p) :
78     path(QDir::cleanPath(p)),
79     binary(false),
80     attributes(0)
81 {
82 }
83
84 GeneratedFile::GeneratedFile() :
85     m_d(new GeneratedFilePrivate)
86 {
87 }
88
89 GeneratedFile::GeneratedFile(const QString &p) :
90     m_d(new GeneratedFilePrivate(p))
91 {
92 }
93
94 GeneratedFile::GeneratedFile(const GeneratedFile &rhs) :
95     m_d(rhs.m_d)
96 {
97 }
98
99 GeneratedFile &GeneratedFile::operator=(const GeneratedFile &rhs)
100 {
101     if (this != &rhs)
102         m_d.operator=(rhs.m_d);
103     return *this;
104 }
105
106 GeneratedFile::~GeneratedFile()
107 {
108 }
109
110 QString GeneratedFile::path() const
111 {
112     return m_d->path;
113 }
114
115 void GeneratedFile::setPath(const QString &p)
116 {
117     m_d->path = QDir::cleanPath(p);
118 }
119
120 QString GeneratedFile::contents() const
121 {
122     return QString::fromUtf8(m_d->contents);
123 }
124
125 void GeneratedFile::setContents(const QString &c)
126 {
127     m_d->contents = c.toUtf8();
128 }
129
130 QByteArray GeneratedFile::binaryContents() const
131 {
132     return m_d->contents;
133 }
134
135 void GeneratedFile::setBinaryContents(const QByteArray &c)
136 {
137     m_d->contents = c;
138 }
139
140 bool GeneratedFile::isBinary() const
141 {
142     return m_d->binary;
143 }
144
145 void GeneratedFile::setBinary(bool b)
146 {
147     m_d->binary = b;
148 }
149
150 QString GeneratedFile::editorId() const
151 {
152     return m_d->editorId;
153 }
154
155 void GeneratedFile::setEditorId(const QString &k)
156 {
157     m_d->editorId = k;
158 }
159
160 bool GeneratedFile::write(QString *errorMessage) const
161 {
162     // Ensure the directory
163     const QFileInfo info(m_d->path);
164     const QDir dir = info.absoluteDir();
165     if (!dir.exists()) {
166         if (!dir.mkpath(dir.absolutePath())) {
167             *errorMessage = BaseFileWizard::tr("Unable to create the directory %1.").arg(dir.absolutePath());
168             return false;
169         }
170     }
171     // Write out
172     QFile file(m_d->path);
173
174     QIODevice::OpenMode flags = QIODevice::WriteOnly|QIODevice::Truncate;
175     if (!isBinary())
176         flags |= QIODevice::Text;
177
178     if (!file.open(flags)) {
179         *errorMessage = BaseFileWizard::tr("Unable to open %1 for writing: %2").arg(m_d->path, file.errorString());
180         return false;
181     }
182     if (file.write(m_d->contents) == -1) {
183         *errorMessage =  BaseFileWizard::tr("Error while writing to %1: %2").arg(m_d->path, file.errorString());
184         return false;
185     }
186     file.close();
187     return true;
188 }
189
190 GeneratedFile::Attributes GeneratedFile::attributes() const
191 {
192     return m_d->attributes;
193 }
194
195 void GeneratedFile::setAttributes(Attributes a)
196 {
197     m_d->attributes = a;
198 }
199
200 // ------------ BaseFileWizardParameterData
201 class BaseFileWizardParameterData : public QSharedData
202 {
203 public:
204     explicit BaseFileWizardParameterData(IWizard::WizardKind kind = IWizard::FileWizard);
205     void clear();
206
207     IWizard::WizardKind kind;
208     QIcon icon;
209     QString description;
210     QString displayName;
211     QString id;
212     QString category;
213     QString displayCategory;
214 };
215
216 BaseFileWizardParameterData::BaseFileWizardParameterData(IWizard::WizardKind k) :
217     kind(k)
218 {
219 }
220
221 void BaseFileWizardParameterData::clear()
222 {
223     kind = IWizard::FileWizard;
224     icon = QIcon();
225     description.clear();
226     displayName.clear();
227     id.clear();
228     category.clear();
229     displayCategory.clear();
230 }
231
232 BaseFileWizardParameters::BaseFileWizardParameters(IWizard::WizardKind kind) :
233    m_d(new BaseFileWizardParameterData(kind))
234 {
235 }
236
237 BaseFileWizardParameters::BaseFileWizardParameters(const BaseFileWizardParameters &rhs) :
238     m_d(rhs.m_d)
239 {
240 }
241
242 BaseFileWizardParameters &BaseFileWizardParameters::operator=(const BaseFileWizardParameters &rhs)
243 {
244     if (this != &rhs)
245         m_d.operator=(rhs.m_d);
246     return *this;
247 }
248
249 BaseFileWizardParameters::~BaseFileWizardParameters()
250 {
251 }
252
253 void BaseFileWizardParameters::clear()
254 {
255     m_d->clear();
256 }
257
258 CORE_EXPORT QDebug operator<<(QDebug d, const BaseFileWizardParameters &p)
259 {
260     d.nospace() << "Kind: " << p.kind() << " Id: " << p.id()
261                 << " Category: " << p.category()
262                 << " DisplayName: " << p.displayName()
263                 << " Description: " << p.description()
264                 << " DisplayCategory: " << p.displayCategory();
265     return d;
266 }
267
268 IWizard::WizardKind BaseFileWizardParameters::kind() const
269 {
270     return m_d->kind;
271 }
272
273 void BaseFileWizardParameters::setKind(IWizard::WizardKind k)
274 {
275     m_d->kind = k;
276 }
277
278 QIcon BaseFileWizardParameters::icon() const
279 {
280     return m_d->icon;
281 }
282
283 void BaseFileWizardParameters::setIcon(const QIcon &icon)
284 {
285     m_d->icon = icon;
286 }
287
288 QString BaseFileWizardParameters::description() const
289 {
290     return m_d->description;
291 }
292
293 void BaseFileWizardParameters::setDescription(const QString &v)
294 {
295     m_d->description = v;
296 }
297
298 QString BaseFileWizardParameters::displayName() const
299 {
300     return m_d->displayName;
301 }
302
303 void BaseFileWizardParameters::setDisplayName(const QString &v)
304 {
305     m_d->displayName = v;
306 }
307
308 QString BaseFileWizardParameters::id() const
309 {
310     return m_d->id;
311 }
312
313 void BaseFileWizardParameters::setId(const QString &v)
314 {
315     m_d->id = v;
316 }
317
318 QString BaseFileWizardParameters::category() const
319 {
320     return m_d->category;
321 }
322
323 void BaseFileWizardParameters::setCategory(const QString &v)
324 {
325     m_d->category = v;
326 }
327
328 QString BaseFileWizardParameters::displayCategory() const
329 {
330     return m_d->displayCategory;
331 }
332
333 void BaseFileWizardParameters::setDisplayCategory(const QString &v)
334 {
335     m_d->displayCategory = v;
336 }
337
338 /* WizardEventLoop: Special event loop that runs a QWizard and terminates if the page changes.
339  * Synopsis:
340  * \code
341     Wizard wizard(parent);
342     WizardEventLoop::WizardResult wr;
343     do {
344         wr = WizardEventLoop::execWizardPage(wizard);
345     } while (wr == WizardEventLoop::PageChanged);
346  * \endcode */
347
348 class WizardEventLoop : public QEventLoop
349 {
350     Q_OBJECT
351     Q_DISABLE_COPY(WizardEventLoop)
352     WizardEventLoop(QObject *parent);
353
354 public:
355     enum WizardResult { Accepted, Rejected , PageChanged };
356
357     static WizardResult execWizardPage(QWizard &w);
358
359 private slots:
360     void pageChanged(int);
361     void accepted();
362     void rejected();
363
364 private:
365     WizardResult execWizardPageI();
366
367     WizardResult m_result;
368 };
369
370 WizardEventLoop::WizardEventLoop(QObject *parent) :
371     QEventLoop(parent),
372     m_result(Rejected)
373 {
374 }
375
376 WizardEventLoop::WizardResult WizardEventLoop::execWizardPage(QWizard &wizard)
377 {
378     /* Install ourselves on the wizard. Main trick is here to connect
379      * to the page changed signal and quit() on it. */
380     WizardEventLoop *eventLoop = wizard.findChild<WizardEventLoop *>();
381     if (!eventLoop) {
382         eventLoop = new WizardEventLoop(&wizard);
383         connect(&wizard, SIGNAL(currentIdChanged(int)), eventLoop, SLOT(pageChanged(int)));
384         connect(&wizard, SIGNAL(accepted()), eventLoop, SLOT(accepted()));
385         connect(&wizard, SIGNAL(rejected()), eventLoop, SLOT(rejected()));
386         wizard.setAttribute(Qt::WA_ShowModal, true);
387         wizard.show();
388     }
389     const WizardResult result = eventLoop->execWizardPageI();
390     // Quitting?
391     if (result != PageChanged)
392         delete eventLoop;
393     if (debugWizard)
394         qDebug() << "WizardEventLoop::runWizard" << wizard.pageIds() << " returns " << result;
395
396     return result;
397 }
398
399 WizardEventLoop::WizardResult WizardEventLoop::execWizardPageI()
400 {
401     m_result = Rejected;
402     exec(QEventLoop::DialogExec);
403     return m_result;
404 }
405
406 void WizardEventLoop::pageChanged(int /*page*/)
407 {
408     m_result = PageChanged;
409     quit(); // !
410 }
411
412 void WizardEventLoop::accepted()
413 {
414     m_result = Accepted;
415     quit();
416 }
417
418 void WizardEventLoop::rejected()
419 {
420     m_result = Rejected;
421     quit();
422 }
423
424 // ---------------- BaseFileWizardPrivate
425 struct BaseFileWizardPrivate
426 {
427     explicit BaseFileWizardPrivate(const Core::BaseFileWizardParameters &parameters)
428       : m_parameters(parameters), m_wizardDialog(0)
429     {}
430
431     const Core::BaseFileWizardParameters m_parameters;
432     QWizard *m_wizardDialog;
433 };
434
435 // ---------------- Wizard
436 BaseFileWizard::BaseFileWizard(const BaseFileWizardParameters &parameters,
437                        QObject *parent) :
438     IWizard(parent),
439     m_d(new BaseFileWizardPrivate(parameters))
440 {
441 }
442
443 BaseFileWizard::~BaseFileWizard()
444 {
445     delete m_d;
446 }
447
448 IWizard::WizardKind  BaseFileWizard::kind() const
449 {
450     return m_d->m_parameters.kind();
451 }
452
453 QIcon BaseFileWizard::icon() const
454 {
455     return m_d->m_parameters.icon();
456 }
457
458 QString BaseFileWizard::description() const
459 {
460     return m_d->m_parameters.description();
461 }
462
463 QString BaseFileWizard::displayName() const
464 {
465     return m_d->m_parameters.displayName();
466 }
467
468 QString BaseFileWizard::id() const
469 {
470     return m_d->m_parameters.id();
471 }
472
473 QString BaseFileWizard::category() const
474 {
475     return m_d->m_parameters.category();
476 }
477
478 QString BaseFileWizard::displayCategory() const
479 {
480     return m_d->m_parameters.displayCategory();
481 }
482
483 void BaseFileWizard::runWizard(const QString &path, QWidget *parent)
484 {
485     QTC_ASSERT(!path.isEmpty(), return);
486
487     typedef  QList<IFileWizardExtension*> ExtensionList;
488
489     QString errorMessage;
490     // Compile extension pages, purge out unused ones
491     ExtensionList extensions = ExtensionSystem::PluginManager::instance()->getObjects<IFileWizardExtension>();
492     WizardPageList  allExtensionPages;
493     for (ExtensionList::iterator it = extensions.begin(); it !=  extensions.end(); ) {
494         const WizardPageList extensionPages = (*it)->extensionPages(this);
495         if (extensionPages.empty()) {
496             it = extensions.erase(it);
497         } else {
498             allExtensionPages += extensionPages;
499             ++it;
500         }
501     }
502
503     if (debugWizard)
504         qDebug() << Q_FUNC_INFO <<  path << parent << "exs" <<  extensions.size() << allExtensionPages.size();
505
506     QWizardPage *firstExtensionPage = 0;
507     if (!allExtensionPages.empty())
508         firstExtensionPage = allExtensionPages.front();
509
510     // Create dialog and run it. Ensure that the dialog is deleted when
511     // leaving the func, but not before the IFileWizardExtension::process
512     // has been called
513     const QScopedPointer<QWizard> wizard(createWizardDialog(parent, path, allExtensionPages));
514     QTC_ASSERT(!wizard.isNull(), return);
515
516     GeneratedFiles files;
517     // Run the wizard: Call generate files on switching to the first extension
518     // page is OR after 'Accepted' if there are no extension pages
519     while (true) {
520         const WizardEventLoop::WizardResult wr = WizardEventLoop::execWizardPage(*wizard);
521         if (wr == WizardEventLoop::Rejected) {
522             files.clear();
523             break;
524         }
525         const bool accepted = wr == WizardEventLoop::Accepted;
526         const bool firstExtensionPageHit = wr == WizardEventLoop::PageChanged
527                                            && wizard->page(wizard->currentId()) == firstExtensionPage;
528         const bool needGenerateFiles = firstExtensionPageHit || (accepted && allExtensionPages.empty());
529         if (needGenerateFiles) {
530             QString errorMessage;
531             files = generateFiles(wizard.data(), &errorMessage);
532             if (files.empty()) {
533                 QMessageBox::critical(0, tr("File Generation Failure"), errorMessage);
534                 break;
535             }
536         }
537         if (firstExtensionPageHit)
538             foreach (IFileWizardExtension *ex, extensions)
539                 ex->firstExtensionPageShown(files);
540         if (accepted)
541             break;
542     }
543     if (files.empty())
544         return;
545     // Compile result list and prompt for overwrite
546     QStringList result;
547     foreach (const GeneratedFile &generatedFile, files)
548         result.push_back(generatedFile.path());
549
550     switch (promptOverwrite(result, &errorMessage)) {
551     case OverwriteCanceled:
552         return;
553     case OverwriteError:
554         QMessageBox::critical(0, tr("Existing files"), errorMessage);
555         return;
556     case OverwriteOk:
557         break;
558     }
559
560     // Write
561     if (!writeFiles(files, &errorMessage)) {
562         QMessageBox::critical(parent, tr("File Generation Failure"), errorMessage);
563         return;
564     }
565
566     bool removeOpenProjectAttribute = false;
567     // Run the extensions
568     foreach (IFileWizardExtension *ex, extensions) {
569         bool remove;
570         if (!ex->process(files, &remove, &errorMessage)) {
571             QMessageBox::critical(parent, tr("File Generation Failure"), errorMessage);
572             return;
573         }
574         removeOpenProjectAttribute |= remove;
575     }
576
577     if (removeOpenProjectAttribute) {
578         for (int i = 0; i < files.count(); i++) {
579             if (files[i].attributes() & Core::GeneratedFile::OpenProjectAttribute)
580                 files[i].setAttributes(Core::GeneratedFile::OpenEditorAttribute);
581         }
582     }
583
584     // Post generation handler
585     if (!postGenerateFiles(wizard.data(), files, &errorMessage))
586         QMessageBox::critical(0, tr("File Generation Failure"), errorMessage);
587 }
588
589 // Write
590 bool BaseFileWizard::writeFiles(const GeneratedFiles &files, QString *errorMessage)
591 {
592     foreach (const GeneratedFile &generatedFile, files)
593         if (!(generatedFile.attributes() & GeneratedFile::CustomGeneratorAttribute))
594             if (!generatedFile.write(errorMessage))
595                 return false;
596     return true;
597 }
598
599
600 void BaseFileWizard::setupWizard(QWizard *w)
601 {
602     w->setOption(QWizard::NoCancelButton, false);
603     w->setOption(QWizard::NoDefaultButton, false);
604     w->setOption(QWizard::NoBackButtonOnStartPage, true);
605 }
606
607 void BaseFileWizard::applyExtensionPageShortTitle(Utils::Wizard *wizard, int pageId)
608 {
609     if (pageId < 0)
610         return;
611     QWizardPage *p = wizard->page(pageId);
612     if (!p)
613         return;
614     Utils::WizardProgressItem *item = wizard->wizardProgress()->item(pageId);
615     if (!item)
616         return;
617     const QString shortTitle = p->property("shortTitle").toString();
618     if (!shortTitle.isEmpty())
619       item->setTitle(shortTitle);
620 }
621
622 bool BaseFileWizard::postGenerateFiles(const QWizard *, const GeneratedFiles &l, QString *errorMessage)
623 {
624     return BaseFileWizard::postGenerateOpenEditors(l, errorMessage);
625 }
626
627 bool BaseFileWizard::postGenerateOpenEditors(const GeneratedFiles &l, QString *errorMessage)
628 {
629     Core::EditorManager *em = Core::EditorManager::instance();
630     foreach(const Core::GeneratedFile &file, l) {
631         if (file.attributes() & Core::GeneratedFile::OpenEditorAttribute) {
632             if (!em->openEditor(file.path(), file.editorId(), Core::EditorManager::ModeSwitch )) {
633                 if (errorMessage)
634                     *errorMessage = tr("Failed to open an editor for '%1'.").arg(QDir::toNativeSeparators(file.path()));
635                 return false;
636             }
637         }
638     }
639     return true;
640 }
641
642 BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QStringList &files,
643                                                                 QString *errorMessage) const
644 {
645     if (debugWizard)
646         qDebug() << Q_FUNC_INFO << files;
647
648     QStringList existingFiles;
649     bool oddStuffFound = false;
650
651     static const QString readOnlyMsg = tr(" [read only]");
652     static const QString directoryMsg = tr(" [directory]");
653     static const QString symLinkMsg = tr(" [symbolic link]");
654
655     foreach (const QString &fileName, files) {
656         const QFileInfo fi(fileName);
657         if (fi.exists())
658             existingFiles.append(fileName);
659     }
660     // Note: Generated files are using native separators, no need to convert.
661     const QString commonExistingPath = Utils::commonPath(existingFiles);
662     // Format a file list message as ( "<file1> [readonly], <file2> [directory]").
663     QString fileNamesMsgPart;
664     foreach (const QString &fileName, existingFiles) {
665         const QFileInfo fi(fileName);
666         if (fi.exists()) {
667             if (!fileNamesMsgPart.isEmpty())
668                 fileNamesMsgPart += QLatin1String(", ");
669             fileNamesMsgPart += QDir::toNativeSeparators(fileName.mid(commonExistingPath.size() + 1));
670             do {
671                 if (fi.isDir()) {
672                     oddStuffFound = true;
673                     fileNamesMsgPart += directoryMsg;
674                     break;
675                 }
676                 if (fi.isSymLink()) {
677                     oddStuffFound = true;
678                     fileNamesMsgPart += symLinkMsg;
679                     break;
680             }
681                 if (!fi.isWritable()) {
682                     oddStuffFound = true;
683                     fileNamesMsgPart += readOnlyMsg;
684                 }
685             } while (false);
686         }
687     }
688
689     if (existingFiles.isEmpty())
690         return OverwriteOk;
691
692     if (oddStuffFound) {
693         *errorMessage = tr("The project directory %1 contains files which cannot be overwritten:\n%2.")
694                 .arg(QDir::toNativeSeparators(commonExistingPath)).arg(fileNamesMsgPart);
695         return OverwriteError;
696     }
697
698     const QString messageFormat = tr("The following files already exist in the directory %1:\n"
699                                      "%2.\nWould you like to overwrite them?");
700     const QString message = messageFormat.arg(QDir::toNativeSeparators(commonExistingPath)).arg(fileNamesMsgPart);
701     const bool yes = (QMessageBox::question(Core::ICore::instance()->mainWindow(),
702                                             tr("Existing files"), message,
703                                             QMessageBox::Yes | QMessageBox::No,
704                                             QMessageBox::No)
705                       == QMessageBox::Yes);
706     return yes ? OverwriteOk :  OverwriteCanceled;
707 }
708
709 QString BaseFileWizard::buildFileName(const QString &path,
710                                       const QString &baseName,
711                                       const QString &extension)
712 {
713     QString rc = path;
714     if (!rc.isEmpty() && !rc.endsWith(QDir::separator()))
715         rc += QDir::separator();
716     rc += baseName;
717     // Add extension unless user specified something else
718     const QChar dot = QLatin1Char('.');
719     if (!extension.isEmpty() && !baseName.contains(dot)) {
720         if (!extension.startsWith(dot))
721             rc += dot;
722         rc += extension;
723     }
724     if (debugWizard)
725         qDebug() << Q_FUNC_INFO << rc;
726     return rc;
727 }
728
729 QString BaseFileWizard::preferredSuffix(const QString &mimeType)
730 {
731     const QString rc = Core::ICore::instance()->mimeDatabase()->preferredSuffixByType(mimeType);
732     if (rc.isEmpty())
733         qWarning("%s: WARNING: Unable to find a preferred suffix for %s.",
734                  Q_FUNC_INFO, mimeType.toUtf8().constData());
735     return rc;
736 }
737
738 // ------------- StandardFileWizard
739
740 StandardFileWizard::StandardFileWizard(const BaseFileWizardParameters &parameters,
741                                        QObject *parent) :
742     BaseFileWizard(parameters, parent)
743 {
744 }
745
746 QWizard *StandardFileWizard::createWizardDialog(QWidget *parent,
747                                                 const QString &defaultPath,
748                                                 const WizardPageList &extensionPages) const
749 {
750     Utils::FileWizardDialog *standardWizardDialog = new Utils::FileWizardDialog(parent);
751     standardWizardDialog->setWindowTitle(tr("New %1").arg(displayName()));
752     setupWizard(standardWizardDialog);
753     standardWizardDialog->setPath(defaultPath);
754     foreach (QWizardPage *p, extensionPages)
755         BaseFileWizard::applyExtensionPageShortTitle(standardWizardDialog, standardWizardDialog->addPage(p));
756     return standardWizardDialog;
757 }
758
759 GeneratedFiles StandardFileWizard::generateFiles(const QWizard *w,
760                                                  QString *errorMessage) const
761 {
762     const Utils::FileWizardDialog *standardWizardDialog = qobject_cast<const Utils::FileWizardDialog *>(w);
763     return generateFilesFromPath(standardWizardDialog->path(),
764                                  standardWizardDialog->fileName(),
765                                  errorMessage);
766 }
767
768 } // namespace Core
769
770 #include "basefilewizard.moc"