diff --git a/src/plugins/pythoneditor/pythoneditor.pro b/src/plugins/pythoneditor/pythoneditor.pro index b064e945810..ec79b248f93 100644 --- a/src/plugins/pythoneditor/pythoneditor.pro +++ b/src/plugins/pythoneditor/pythoneditor.pro @@ -18,6 +18,10 @@ HEADERS += \ pythoneditorwidget.h \ pythoneditorconstants.h \ wizard/pythonfilewizard.h \ + wizard/pythonclasswizard.h \ + wizard/pythonclassnamepage.h \ + wizard/pythonclasswizarddialog.h \ + wizard/pythonsourcegenerator.h \ tools/pythonhighlighter.h \ tools/pythonindenter.h \ tools/lexical/pythonformattoken.h \ @@ -30,6 +34,10 @@ SOURCES += \ pythoneditor.cpp \ pythoneditorwidget.cpp \ wizard/pythonfilewizard.cpp \ + wizard/pythonclasswizarddialog.cpp \ + wizard/pythonclasswizard.cpp \ + wizard/pythonclassnamepage.cpp \ + wizard/pythonsourcegenerator.cpp \ tools/pythonhighlighter.cpp \ tools/pythonindenter.cpp \ tools/lexical/pythonscanner.cpp diff --git a/src/plugins/pythoneditor/pythoneditor.qbs b/src/plugins/pythoneditor/pythoneditor.qbs index e77e4f8eb14..9a2025df736 100644 --- a/src/plugins/pythoneditor/pythoneditor.qbs +++ b/src/plugins/pythoneditor/pythoneditor.qbs @@ -37,6 +37,14 @@ QtcPlugin { "tools/pythonindenter.h", "wizard/pythonfilewizard.h", "wizard/pythonfilewizard.cpp", + "wizard/pythonclasswizard.h", + "wizard/pythonclassnamepage.h", + "wizard/pythonclasswizarddialog.h", + "wizard/pythonsourcegenerator.h", + "wizard/pythonclasswizarddialog.cpp", + "wizard/pythonclasswizard.cpp", + "wizard/pythonclassnamepage.cpp", + "wizard/pythonsourcegenerator.cpp" ] } diff --git a/src/plugins/pythoneditor/pythoneditor_dependencies.pri b/src/plugins/pythoneditor/pythoneditor_dependencies.pri index 2988622acc1..8c2256879e7 100644 --- a/src/plugins/pythoneditor/pythoneditor_dependencies.pri +++ b/src/plugins/pythoneditor/pythoneditor_dependencies.pri @@ -2,4 +2,6 @@ QTC_PLUGIN_NAME = PythonEditor QTC_PLUGIN_DEPENDS += \ coreplugin \ texteditor \ - cpptools + cpptools \ + qtsupport \ + projectexplorer diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index a800aa39256..d027bf986da 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -30,6 +30,7 @@ #include "pythoneditorplugin.h" #include "pythoneditorconstants.h" #include "wizard/pythonfilewizard.h" +#include "wizard/pythonclasswizard.h" #include "pythoneditorwidget.h" #include "pythoneditorfactory.h" @@ -249,6 +250,7 @@ bool PythonEditorPlugin::initialize( // Add Python files and classes creation dialogs //////////////////////////////////////////////////////////////////////////// addAutoReleasedObject(new FileWizard(Core::ICore::instance())); + addAutoReleasedObject(new ClassWizard(Core::ICore::instance())); return true; } diff --git a/src/plugins/pythoneditor/wizard/pythonclassnamepage.cpp b/src/plugins/pythoneditor/wizard/pythonclassnamepage.cpp new file mode 100644 index 00000000000..96548386e3c --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonclassnamepage.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "pythonclassnamepage.h" +#include "../pythoneditorconstants.h" + +#include +#include +#include + +#include + +namespace PythonEditor { + +ClassNamePage::ClassNamePage(QWidget *parent) + : QWizardPage(parent) + , m_isValid(false) +{ + setTitle(tr("Enter Class Name")); + setSubTitle(tr("The source file name will be derived from the class name")); + + m_newClassWidget.reset(new Utils::NewClassWidget); + // Order, set extensions first before suggested name is derived + m_newClassWidget->setClassTypeComboVisible(true); + m_newClassWidget->setBaseClassChoices(QStringList() + << QString() + << QLatin1String("QObject") + << QLatin1String("QWidget") + << QLatin1String("QMainWindow") + << QLatin1String("QDeclarativeItem")); + + m_newClassWidget->setBaseClassEditable(true); + m_newClassWidget->setFormInputVisible(false); + m_newClassWidget->setHeaderInputVisible(false); + m_newClassWidget->setNamespacesEnabled(true); + m_newClassWidget->setBaseClassInputVisible(true); + m_newClassWidget->setNamesDelimiter(QLatin1String(".")); + m_newClassWidget->setAllowDirectories(true); + + connect(m_newClassWidget.data(), SIGNAL(validChanged()), this, SLOT(slotValidChanged())); + + QVBoxLayout *pageLayout = new QVBoxLayout(this); + pageLayout->addWidget(m_newClassWidget.data()); + QSpacerItem *vSpacer = new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::Expanding); + pageLayout->addItem(vSpacer); + + initParameters(); +} + +ClassNamePage::~ClassNamePage() +{ +} + +void ClassNamePage::initParameters() +{ + m_newClassWidget->setSourceExtension(QLatin1String(Constants::C_PY_EXTENSION)); +} + +void ClassNamePage::slotValidChanged() +{ + const bool validNow = m_newClassWidget->isValid(); + if (m_isValid != validNow) { + m_isValid = validNow; + emit completeChanged(); + } +} + +} // namespace PythonEditor diff --git a/src/plugins/pythoneditor/wizard/pythonclassnamepage.h b/src/plugins/pythoneditor/wizard/pythonclassnamepage.h new file mode 100644 index 00000000000..ca8c98a35a8 --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonclassnamepage.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef PYTHONEDITOR_CLASSNAMEPAGE_H +#define PYTHONEDITOR_CLASSNAMEPAGE_H + +#include +#include + +namespace Utils { class NewClassWidget; } + +namespace PythonEditor { + +class ClassNamePage : public QWizardPage +{ + Q_OBJECT + +public: + explicit ClassNamePage(QWidget *parent = 0); + virtual ~ClassNamePage(); + + bool isComplete() const { return m_isValid; } + Utils::NewClassWidget *newClassWidget() const { return m_newClassWidget.data(); } + +private slots: + void slotValidChanged(); + +private: + void initParameters(); + + QScopedPointer m_newClassWidget; + bool m_isValid; +}; + +} // namespace PythonEditor + +#endif // PYTHONEDITOR_CLASSNAMEPAGE_H diff --git a/src/plugins/pythoneditor/wizard/pythonclasswizard.cpp b/src/plugins/pythoneditor/wizard/pythonclasswizard.cpp new file mode 100644 index 00000000000..f172d1ce1d1 --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonclasswizard.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "pythonclasswizard.h" +#include "pythonclasswizarddialog.h" +#include "pythonclassnamepage.h" +#include "pythonsourcegenerator.h" +#include "../pythoneditorconstants.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace ProjectExplorer; + +namespace PythonEditor { + +static Core::BaseFileWizardParameters getDefaultParams() +{ + Core::BaseFileWizardParameters p(Core::IWizard::FileWizard); + + p.setId(QLatin1String(Constants::C_PY_CLASS_WIZARD_ID)); + p.setCategory(QLatin1String(Constants::C_PY_WIZARD_CATEGORY)); + p.setDisplayCategory(QLatin1String(Constants::C_PY_DISPLAY_CATEGORY)); + p.setDisplayName(ClassWizard::tr(Constants::EN_PY_CLASS_DISPLAY_NAME)); + p.setDescription(ClassWizard::tr(Constants::EN_PY_CLASS_DESCRIPTION)); + + return p; +} + +ClassWizard::ClassWizard(QObject *parent) : + Core::BaseFileWizard(getDefaultParams(), parent) +{ +} + +QWizard *ClassWizard::createWizardDialog( + QWidget *parent, + const Core::WizardDialogParameters ¶ms) const +{ + ClassWizardDialog *wizard = new ClassWizardDialog(parent); + foreach (QWizardPage *p, params.extensionPages()) + BaseFileWizard::applyExtensionPageShortTitle(wizard, wizard->addPage(p)); + wizard->setPath(params.defaultPath()); + wizard->setExtraValues(params.extraValues()); + return wizard; +} + +Core::GeneratedFiles ClassWizard::generateFiles(const QWizard *w, + QString *errorMessage) const +{ + Q_UNUSED(errorMessage); + + const ClassWizardDialog *wizard = qobject_cast(w); + const ClassWizardParameters params = wizard->parameters(); + + const QString fileName = Core::BaseFileWizard::buildFileName( + params.path, params.fileName, QLatin1String(Constants::C_PY_EXTENSION)); + Core::GeneratedFile sourceFile(fileName); + + SourceGenerator generator; + generator.setPythonQtBinding(SourceGenerator::PySide); + Kit *kit = kitForWizard(wizard); + if (kit) { + QtSupport::BaseQtVersion *baseVersion = QtSupport::QtKitInformation::qtVersion(kit); + if (baseVersion && baseVersion->qtVersion().majorVersion == 5) + generator.setPythonQtVersion(SourceGenerator::Qt5); + else + generator.setPythonQtVersion(SourceGenerator::Qt4); + } + + QString sourceContent = generator.generateClass( + params.className, params.baseClass, params.classType + ); + + sourceFile.setContents(sourceContent); + sourceFile.setAttributes(Core::GeneratedFile::OpenEditorAttribute); + return Core::GeneratedFiles() << sourceFile; +} + +Kit *ClassWizard::kitForWizard(const ClassWizardDialog *wizard) const +{ + const QString key = QLatin1String(ProjectExplorer::Constants::PREFERED_PROJECT_NODE); + const QString nodePath = wizard->extraValues().value(key).toString(); + + // projectForFile doesn't find project if project file path passed + Node *node = ProjectExplorerPlugin::instance()->session()->nodeForFile(nodePath); + Project *proj = ProjectExplorerPlugin::instance()->session()->projectForNode(node); + if (proj && proj->activeTarget()) + return proj->activeTarget()->kit(); + + return KitManager::instance()->defaultKit(); +} + +} // namespace PythonEditor diff --git a/src/plugins/pythoneditor/wizard/pythonclasswizard.h b/src/plugins/pythoneditor/wizard/pythonclasswizard.h new file mode 100644 index 00000000000..763be1b9f67 --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonclasswizard.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef PYTHONEDITOR_CLASSWIZARD_H +#define PYTHONEDITOR_CLASSWIZARD_H + +#include +#include + +namespace Utils { class NewClassWidget; } +namespace ProjectExplorer { class Kit; } + +namespace PythonEditor { +class ClassWizardDialog; + +class ClassWizard : public Core::BaseFileWizard +{ + Q_OBJECT + +public: + explicit ClassWizard(QObject *parent = 0); + +protected: + QWizard *createWizardDialog(QWidget *parent, + const Core::WizardDialogParameters ¶ms) const; + + Core::GeneratedFiles generateFiles(const QWizard *w, + QString *errorMessage) const; + + ProjectExplorer::Kit *kitForWizard(const ClassWizardDialog *wizard) const; +}; + +} // namespace PythonEditor + +#endif // PYTHONEDITOR_CLASSWIZARD_H diff --git a/src/plugins/pythoneditor/wizard/pythonclasswizarddialog.cpp b/src/plugins/pythoneditor/wizard/pythonclasswizarddialog.cpp new file mode 100644 index 00000000000..80d5f0e4b5d --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonclasswizarddialog.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "pythonclasswizarddialog.h" +#include "pythonclassnamepage.h" + +#include +#include + +namespace PythonEditor { + +ClassWizardDialog::ClassWizardDialog(QWidget *parent) + : Utils::Wizard(parent) + , m_classNamePage(new ClassNamePage(this)) +{ + setWindowTitle(tr("Python Class Wizard")); + Core::BaseFileWizard::setupWizard(this); + const int classNameId = addPage(m_classNamePage.data()); + wizardProgress()->item(classNameId)->setTitle(tr("Details")); +} + +ClassWizardDialog::~ClassWizardDialog() +{ +} + +ClassWizardParameters ClassWizardDialog::parameters() const +{ + ClassWizardParameters p; + const Utils::NewClassWidget *ncw = m_classNamePage->newClassWidget(); + p.className = ncw->className(); + p.fileName = ncw->sourceFileName(); + p.baseClass = ncw->baseClassName(); + p.path = ncw->path(); + p.classType = ncw->classType(); + + return p; +} + +void ClassWizardDialog::setExtraValues(const QVariantMap &extraValues) +{ + m_extraValues = extraValues; +} + +const QVariantMap &ClassWizardDialog::extraValues() const +{ + return m_extraValues; +} + +void ClassWizardDialog::setPath(const QString &path) +{ + m_classNamePage->newClassWidget()->setPath(path); +} + +} // namespace PythonEditor diff --git a/src/plugins/pythoneditor/wizard/pythonclasswizarddialog.h b/src/plugins/pythoneditor/wizard/pythonclasswizarddialog.h new file mode 100644 index 00000000000..5e9d011f5fa --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonclasswizarddialog.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef PYTHONEDITOR_CLASSWIZARDDIALOG_H +#define PYTHONEDITOR_CLASSWIZARDDIALOG_H + +#include +#include +#include +#include + +namespace PythonEditor { + +class ClassNamePage; + +class ClassWizardParameters +{ +public: + QString className; + QString fileName; + QString path; + QString baseClass; + Utils::NewClassWidget::ClassType classType; +}; + +class ClassWizardDialog : public Utils::Wizard +{ + Q_OBJECT +public: + explicit ClassWizardDialog(QWidget *parent = 0); + virtual ~ClassWizardDialog(); + + void setPath(const QString &path); + ClassWizardParameters parameters() const; + + void setExtraValues(const QVariantMap &extraValues); + const QVariantMap &extraValues() const; + +private: + QScopedPointer m_classNamePage; + QVariantMap m_extraValues; +}; + +} // namespace PythonEditor + +#endif // PYTHONEDITOR_CLASSWIZARDDIALOG_H diff --git a/src/plugins/pythoneditor/wizard/pythonsourcegenerator.cpp b/src/plugins/pythoneditor/wizard/pythonsourcegenerator.cpp new file mode 100644 index 00000000000..d1407a06ec3 --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonsourcegenerator.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "pythonsourcegenerator.h" +#include + +namespace PythonEditor { + +static const char BASH_RUN_HEADER[] = "#!/usr/bin/env python\n"; +static const char ENCODING_HEADER[] = "# -*- coding: utf-8 -*-\n"; + +SourceGenerator::SourceGenerator() + : m_pythonQtBinding(PySide) + , m_pythonQtVersion(Qt4) +{ +} + +SourceGenerator::~SourceGenerator() +{ +} + +void SourceGenerator::setPythonQtBinding(QtBinding binding) +{ + m_pythonQtBinding = binding; +} + +void SourceGenerator::setPythonQtVersion(SourceGenerator::QtVersion version) +{ + m_pythonQtVersion = version; +} + +QString SourceGenerator::generateClass(const QString &className, + const QString &baseClass, + Utils::NewClassWidget::ClassType classType) const +{ + QSet modules; + bool hasUserBaseClass = !baseClass.isEmpty(); + // heuristic + bool wasInheritedFromQt = hasUserBaseClass && (baseClass.at(0) == QLatin1Char('Q')); + + QString actualBase = baseClass; + + switch (classType) { + case Utils::NewClassWidget::NoClassType: + break; + case Utils::NewClassWidget::SharedDataClass: + case Utils::NewClassWidget::ClassInheritsQQuickItem: + break; + case Utils::NewClassWidget::ClassInheritsQObject: + wasInheritedFromQt = true; + modules.insert(QLatin1String("QtCore")); + if (!hasUserBaseClass) + actualBase = QLatin1String("QtCore.QObject"); + break; + + case Utils::NewClassWidget::ClassInheritsQWidget: + wasInheritedFromQt = true; + modules.insert(QLatin1String("QtCore")); + modules.insert(moduleForQWidget()); + if (!hasUserBaseClass) + actualBase = moduleForQWidget() + QLatin1String(".QWidget"); + break; + + case Utils::NewClassWidget::ClassInheritsQDeclarativeItem: + wasInheritedFromQt = true; + modules.insert(QLatin1String("QtCore")); + modules.insert(QLatin1String("QtDeclarative")); + if (!hasUserBaseClass) + actualBase = QLatin1String("QtDeclarative.QDeclarativeItem"); + break; + } + + QString nonQtModule; // empty + if (hasUserBaseClass) { + int dotIndex = baseClass.lastIndexOf(QLatin1Char('.')); + if (dotIndex != -1) { + if (wasInheritedFromQt) + modules.insert(baseClass.left(dotIndex)); + else + nonQtModule = baseClass.left(dotIndex); + } + } + + QString ret; + ret.reserve(1024); + ret += QLatin1String(ENCODING_HEADER); + ret += QLatin1Char('\n'); + + if (!modules.isEmpty()) { + ret += qtModulesImport(modules); + ret += QLatin1Char('\n'); + } + + if (!nonQtModule.isEmpty()) + ret += QString::fromLatin1("import %1\n\n").arg(nonQtModule); + + if (actualBase.isEmpty()) + ret += QString::fromLatin1("class %1:\n").arg(className); + else + ret += QString::fromLatin1("class %1(%2):\n").arg(className).arg(actualBase); + + ret += QLatin1String(" def __init__(self):\n"); + if (wasInheritedFromQt) + ret += QString::fromLatin1(" %1.__init__(self)\n").arg(actualBase); + ret += QLatin1String(" pass\n"); + + return ret; +} + +/** +* @brief Generates main file of PyQt/PySide application +* +* Class MainWindow should be defined in 'mainwindow' module. +* @param windowTitle Title for created window instance +*/ +QString SourceGenerator::generateQtMain(const QString &windowTitle) const +{ + QSet qtModules; + qtModules.insert(QLatin1String("QtCore")); + qtModules.insert(moduleForQWidget()); + + QString ret; + ret.reserve(1024); + ret += QLatin1String(BASH_RUN_HEADER); + ret += QLatin1String(ENCODING_HEADER); + ret += QLatin1Char('\n'); + ret += QLatin1String("import sys\n"); + ret += qtModulesImport(qtModules); + ret += QLatin1String("from mainwindow import MainWindow\n"); + ret += QLatin1Char('\n'); + + ret += QString::fromLatin1( + "if __name__ == \'__main__\':\n" + " app = %1.QApplication(sys.argv)\n" + " win = MainWindow()\n" + " win.setWindowTitle(u\'%2\')\n" + " win.show()\n" + " app.exec_()\n" + ).arg(moduleForQWidget()).arg(windowTitle); + + return ret; +} + +QString SourceGenerator::qtModulesImport(const QSet &modules) const +{ + QString slotsImport; + if (modules.contains(QLatin1String("QtCore"))) + slotsImport = QLatin1String(" from PyQt4.QtCore import pyqtSlot as Slot\n"); + + QLatin1String defaultBinding("PySide"); + QLatin1String fallbackBinding("PyQt4"); + if (m_pythonQtBinding == PyQt) + qSwap(defaultBinding, fallbackBinding); + + QString ret; + ret.reserve(256); + ret += QLatin1String("try:\n"); + if (m_pythonQtBinding == PyQt) + ret += slotsImport; + foreach (const QString &name, modules) + ret += QString::fromLatin1(" from %1 import %2\n") + .arg(defaultBinding) + .arg(name); + + ret += QLatin1String("except:\n"); + if (m_pythonQtBinding != PyQt) + ret += slotsImport; + foreach (const QString &name, modules) + ret += QString::fromLatin1(" from %1 import %2\n") + .arg(fallbackBinding) + .arg(name); + + return ret; +} + +QString SourceGenerator::moduleForQWidget() const +{ + if (m_pythonQtVersion == Qt4) + return QLatin1String("QtGui"); + else + return QLatin1String("QtWidgets"); +} + +} // namespace PythonEditor diff --git a/src/plugins/pythoneditor/wizard/pythonsourcegenerator.h b/src/plugins/pythoneditor/wizard/pythonsourcegenerator.h new file mode 100644 index 00000000000..ef82955351f --- /dev/null +++ b/src/plugins/pythoneditor/wizard/pythonsourcegenerator.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef PYTHON_SOURCEGENERATOR_H +#define PYTHON_SOURCEGENERATOR_H + +#include "../pythoneditor_global.h" +#include +#include +#include + +namespace PythonEditor { + +class PYEDITOR_EXPORT SourceGenerator +{ +public: + enum QtBinding { + PySide, + PyQt + }; + + enum QtVersion { + Qt4, + Qt5 + }; + + SourceGenerator(); + ~SourceGenerator(); + + void setPythonQtBinding(QtBinding binding); + void setPythonQtVersion(QtVersion version); + + QString generateClass(const QString &className, + const QString &baseClass, + Utils::NewClassWidget::ClassType classType) const; + + QString generateQtMain(const QString &windowTitle) const; + +private: + QString qtModulesImport(const QSet &modules) const; + QString moduleForQWidget() const; + + QtBinding m_pythonQtBinding; + QtVersion m_pythonQtVersion; +}; + +} // namespace PythonEditor + +#endif // PYTHON_SOURCEGENERATOR_H