diff --git a/HOWTO_MakeNewtemplate.txt b/HOWTO_MakeNewtemplate.txt index 7f1fdfd..29f2317 100644 --- a/HOWTO_MakeNewtemplate.txt +++ b/HOWTO_MakeNewtemplate.txt @@ -1,45 +1,44 @@ KAppTemplate and KDevelop placeholders -%{PROJECTDIRNAME} = %{APPNAMELC}-%{VERSION} for KAppTemplate +%{PROJECTDIRNAME} = %{APPNAMELC} for KAppTemplate %{APPNAME} used in .kdev4, project name as entered by user ex: MyKApp %{APPNAMELC} project name in lower case ex: mykapp %{APPNAMEUC} project name in upper case ex: MYKAPP %{CPP_TEMPLATE} license header for cpp file %{H_TEMPLATE} license header for h file %{AUTHOR} author name ex: George Ignacious %{EMAIL} author email ex: foo@bar.org %{VERSION} project version ex: 0.1 +%{CURRENT_YEAR} year at generation time ex: 2017 -%{VERSIONCONTROLPLUGIN} used in .kdev4 - -%{dest} used in .kdevtemplate -%{src} +Deprecated: +%{dest} used in .kdevtemplate with ShowFilesAfterGeneration entry, since KDevelop 5.1.1 supports relative paths (again) ***** In the view that lists the templates ***** kapptemplate -> ChoicePage or kdevelop -> plugins -> appwizard -> appwizard -> ProjectSelectionPage ** Template name The name of the template is the name you write in English in the .kdevtemplate file in Name= and which is translated in other languages. This appears in the Tree View. Example: Name=Qt4 GUI Application ** Template description The description of the template is the comment you write in English in the .kdevtemplate file in Comment= and which is translated in other languages. Example: Comment=Generate a QMake/Qt4 based application with graphical user interface (crossplatform compatible) ** Template Category The template category as it'll appear in the Tree View is extracted from the Category= line in the .kdevtemplate file. Example: Category=Qt/Graphical ** Template preview A screenshot will help the user preview the template. This screenshot name will be indicated as Icon= . This icon should be installed in ${DATA_INSTALL_DIR}/kapptemplate/pics to make it found by the program and should have a different name from any other one. Screenshot prefered size: 200 pixels width. Example: Icon=qt4gui.png KDevelop: templates are tarred using the CMake kdevelop_add_app_templates macro and installed in kdevappwizard/templates. Model untars it and extracts the .kdevtemplate files locally in $KDEHOME/share/apps/kdevappwizard/template_descriptions (void ProjectTemplatesModel::extractTemplateDescriptions()). Model then read the name and description from there (void ProjectTemplatesModel::refresh()). diff --git a/src/application/generatepage.cpp b/src/application/generatepage.cpp index a0cc9ae..3a090ed 100644 --- a/src/application/generatepage.cpp +++ b/src/application/generatepage.cpp @@ -1,210 +1,214 @@ /*************************************************************************** * Copyright 2001 Bernd Gehrmann * * Copyright 2004-2005 Sascha Cunz * * Copyright 2007 Alexander Dymo * * Copyright 2008 Anne-Marie Mahfouf * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "kapptemplate.h" #include "generatepage.h" #include "prefs.h" #include "logging.h" GeneratePage::GeneratePage(QWidget *parent) : QWizardPage(parent) { setTitle(i18n("Generating your project")); ui_generate.setupUi(this); } bool GeneratePage::unpackArchive(const KArchiveDirectory *dir, const QString &dest) { qCDebug(KAPPTEMPLATE) << "unpacking dir:" << dir->name() << "to" << dest; QStringList entries = dir->entries(); qCDebug(KAPPTEMPLATE) << "entries:" << entries.join(","); QTemporaryDir tdir; bool ret = true; //create path were we want copy files to if (!QDir::root().mkpath(dest)) { displayError(i18n("%1 cannot be created.", dest)); return false; } int progress = 0; bool failed = false; foreach (const QString &entry, entries) { progress++; ui_generate.progressBar->setValue((progress / entries.size()) * 100); if (entry.endsWith(".kdevtemplate")) continue; if (entry == templateName + ".png") continue; if (dir->entry(entry)->isDirectory()) { const KArchiveDirectory *file = dynamic_cast(dir->entry(entry)); QString newdest = dest + "/" + file->name(); if (!QFileInfo(newdest).exists()) { if (!QDir::root().mkdir(newdest)) { displayError(i18n("Path %1 could not be created.", newdest)); return false; } } ret |= unpackArchive(file, newdest); } else if (dir->entry(entry)->isFile()) { const KArchiveFile *file = dynamic_cast(dir->entry(entry)); file->copyTo(tdir.path()); QString destName = KMacroExpander::expandMacros(dest + '/' + file->name(), m_variables); if (QFile(QDir::cleanPath(tdir.path() + '/' + file->name())).copy(destName)) { if (!extractFileMacros(destName)) { displayError(i18n("Failed to integrate your project information into " "the file %1. The project has not been generated and " "all temporary files will be removed.", destName)); failed = true; break; } } else { displayError(i18n("Could not copy template file to %1.", destName)); failed = true; break; } } } if (failed && !QDir(dest).removeRecursively()) { qCDebug(KAPPTEMPLATE) << "Failed to remove incomplete destination directory" << dest; } return ret; } bool GeneratePage::extractFileMacros(const QString &entry) { QString text; QFile file(entry); if(file.exists() && file.open(QFile::ReadOnly)) { QTextStream input(&file); text = KMacroExpander::expandMacros(input.readAll(), m_variables); file.close(); if(file.open(QFile::WriteOnly | QIODevice::Truncate)) { QTextStream output(&file); output << text; file.close(); return true; } } return false; } void GeneratePage::initializePage() { feedback = i18n("Generation Progress\n"); ui_generate.label->setText(feedback); templateName = field("tempName").toString(); if (templateName.isEmpty()) { templateName = "kde4"; } QString archName; const QStringList templatePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "/kdevappwizard/templates/", QStandardPaths::LocateDirectory); foreach (const QString &templatePath, templatePaths) { foreach (const QString &templateArchive, QDir(templatePath).entryList(QDir::Files)) { const QString baseName = QFileInfo(templateArchive).baseName(); if (templateName.compare(baseName) == 0) { archName = templatePath + templateArchive; break; } } } if (archName.isEmpty()) return; //create dir where template project will be copied QString appName = field("appName").toString(); QString version = field("version").toString(); + + QString url = field("url").toString(); + if (url.endsWith(QLatin1Char('/'))) { + url.chop(1); + } + QString dest(url + '/' + appName.toLower()); + m_variables.clear(); m_variables["CURRENT_YEAR"] = QString().setNum(QDate::currentDate().year()); m_variables["APPNAME"] = appName; m_variables["APPNAMEUC"] = appName.toUpper(); m_variables["APPNAMELC"] = appName.toLower(); - m_variables["PROJECTDIRNAME"] = appName.toLower(); - m_variables["APPNAMEFU"] = appName.replace(0, 1, appName.toUpper().at(0)); m_variables["AUTHOR"] = field("author").toString(); m_variables["EMAIL"] = field("email").toString(); m_variables["VERSION"] = version; - m_variables["VERSIONCONTROLPLUGIN"] = version; - m_variables["PROJECTDIRNAME"] = appName.toLower() + "-" + version; // TODO what for? change "dest" to that? + m_variables["PROJECTDIRNAME"] = appName.toLower(); + // deprecated + m_variables["dest"] = dest; + // undocumented & deprecated + m_variables["APPNAMEFU"] = appName.replace(0, 1, appName.toUpper().at(0)); + m_variables["VERSIONCONTROLPLUGIN"] = QString(); // creation by kapptemplate is without VCS support/selection KArchive* arch = 0; if (archName.endsWith(".zip")) { arch = new KZip(archName); } else { arch = new KTar(archName, "application/x-bzip"); } - QString url = field("url").toString(); - if (url.endsWith(QLatin1Char('/'))) { - url.chop(1); - } - QString dest(url + '/' + appName.toLower()); if (arch->open(QIODevice::ReadOnly)) { if (!QFileInfo(dest).exists()) { QDir::root().mkdir(dest); qCDebug(KAPPTEMPLATE) << "Creating output directory:" << dest; } unpackArchive(arch->directory(), dest); } delete arch; feedback.append(i18n("Succeeded.\n")); ui_generate.label->setText(feedback); QString resume; resume = i18n("Your project name is: %1, based on the %2 template.
", appName, templateName); resume.append(i18n("Version: %1

", version)); resume.append(i18n("Installed in: %1

", url)); resume.append(i18n("You will find a README in your project folder %1
to help you get started with your project.", url + '/' + appName.toLower())); ui_generate.summaryLabel->setText(resume); } void GeneratePage::displayError(const QString &error) { KMessageBox::sorry(0, error, i18n("Error")); feedback.append("\n\n" + error); ui_generate.label->setText(feedback); }