Commit cef8982a authored by Emmanuel Promayon's avatar Emmanuel Promayon

NEW update coreschema, cepgenerator and test

A new test for generating, configuring and compiling a viewer extension
This test guarantees a CEP can add a viewer extension
parent c10a0a00
......@@ -325,5 +325,6 @@ testcepfile actionsExamplesLicence.xml 2
testcepfile actionsExamplesNoLicence.xml 2
testcepfile actionAndComponent.xml 2
testcepfile empty.xml 0
testcepfile viewerExample.xml 2
exit $exitStatus
......@@ -529,3 +529,46 @@ $USERDEF_LICENCE_END$
</libraries>
</cep>
EOF
# ---------------------- viewerExample.xml ----------------------
# Example taken from distributed source ./sdk/libraries/cepcoreschema/testdata/viewerExample.xml
cat <<EOF > viewerExample.xml
<?xml version="1.0" encoding="UTF-8"?>
<cep xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://camitk.imag.fr/cepcoreschema"
xsi:schemaLocation="http://camitk.imag.fr/cepcoreschema ../cep.xsd">
<name>Test Viewer CEP</name>
<contact>
<email>Emmanuel.Promayon@univ-grenoble-alpes.fr</email>
</contact>
<description>Example of a CEP with two viewer extensions</description>
<viewerExtensions>
<viewerExtension>
<name>Test Viewer 1</name>
<description>This viewer extension manages a default viewer</description>
<registerDefaultViewer/>
<viewer>
<name>Test Viewer 1</name>
<description>Example of simple embedded viewer</description>
<type>EMBEDDED</type>
<component>MeshComponent</component>
<component>ImageComponent</component>
</viewer>
</viewerExtension>
<viewerExtension>
<name>Test Viewer 2</name>
<description>This viewer extension manages three named viewer</description>
<registerNewViewer>First Test Viewer</registerNewViewer>
<registerNewViewer>Second Test Viewer</registerNewViewer>
<viewer>
<name>Test Viewer 2</name>
<description>Example of simple docked viewer</description>
<type>DOCKED</type>
<component>Component</component>
</viewer>
</viewerExtension>
</viewerExtensions>
</cep>
EOF
......@@ -10,6 +10,7 @@
<xsd:enumeration value="cepLibrary"/>
<xsd:enumeration value="component"/>
<xsd:enumeration value="action"/>
<xsd:enumeration value="viewer"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
\ No newline at end of file
</xsd:schema>
......@@ -96,7 +96,7 @@ ActionExtensionGenerator::~ActionExtensionGenerator() {
}
void ActionExtensionGenerator::generateActionOrComponent(QString directory) {
void ActionExtensionGenerator::generateExtensionClass(QString directory) {
// C generate actions
for (auto& action : actions) {
action->generateFiles(directory);
......@@ -104,7 +104,7 @@ void ActionExtensionGenerator::generateActionOrComponent(QString directory) {
}
void ActionExtensionGenerator::writeHFile(QString directory) {
QString className = ClassNameHandler::getClassName(this->name);
QString className = ClassNameHandler::getClassName(name);
QFile initHFile(":/resources/ActionExtension.h.in");
initHFile.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream inh(&initHFile);
......@@ -125,7 +125,7 @@ void ActionExtensionGenerator::writeHFile(QString directory) {
text.replace(QRegExp("@LICENCE@"), licence);
text.replace(QRegExp("@HEADDEF@"), headdef);
text.replace(QRegExp("@EXTENSIONCLASSNAME@"), className);
text.replace(QRegExp("@EXTENSIONNAME@"), this->name);
text.replace(QRegExp("@EXTENSIONNAME@"), name);
text.replace(QRegExp("@EXTENSIONDESCRIPTION@"), this->description);
outh << text << endl;
}
......@@ -135,7 +135,7 @@ void ActionExtensionGenerator::writeHFile(QString directory) {
}
void ActionExtensionGenerator::writeCFile(QString directory) {
QString className = ClassNameHandler::getClassName(this->name);
QString className = ClassNameHandler::getClassName(name);
QFile initCFile(":/resources/ActionExtension.cpp.in");
initCFile.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream inc(&initCFile);
......
......@@ -57,7 +57,7 @@ public:
protected:
/// @{ Helpers methods
void generateActionOrComponent(QString directory) override;
void generateExtensionClass(QString directory) override;
void writeCFile(QString directory) override;
void writeHFile(QString directory) override;
......
......@@ -45,7 +45,7 @@
using namespace cepcoreschema;
ActionGenerator::ActionGenerator(QString xmlFileName, QString licence) {
this->licence = licence;
licence = licence;
QFileInfo xmlFile(xmlFileName);
if ((! xmlFile.exists()) || (! xmlFile.isFile())) {
throw std::invalid_argument("I/O exception during action file generation:\nFile " + xmlFileName.toStdString() + " does not exist or is not a file...\n");
......@@ -82,23 +82,23 @@ QString ActionGenerator::getComponentNamespace() {
// -------------------- createFromDom --------------------
void ActionGenerator::createFromDom(Action& dom) {
std::cout << "Creating action..." << std::endl;
this->name = QString(dom.name().c_str());
this->description = QString(dom.description().c_str()).simplified();
this->className = ClassNameHandler::getClassName(this->name);
this->componentName = QString(dom.component().c_str());
name = QString(dom.name().c_str());
description = QString(dom.description().c_str()).simplified();
className = ClassNameHandler::getClassName(name);
componentName = QString(dom.component().c_str());
// classification
// 1- Family
this->family = QString(dom.classification().family().c_str());
family = QString(dom.classification().family().c_str());
// 2- Checking tags
for (Classification::tag_const_iterator it = dom.classification().tag().begin(); it != dom.classification().tag().end(); it++) {
tags << QString((*it).c_str());
}
// 3- Checking itk flag
this->isItkFilter = false;
isItkFilter = false;
if (dom.classification().itkFilter().present()) {
this->isItkFilter = true;
this->itkFilterOutputType = QString(dom.classification().itkFilter().get().outputType().c_str());
isItkFilter = true;
itkFilterOutputType = QString(dom.classification().itkFilter().get().outputType().c_str());
}
// parameters
......@@ -113,7 +113,7 @@ void ActionGenerator::createFromDom(Action& dom) {
}
QString ActionGenerator::getClassName() const {
return this->className;
return className;
}
......
......@@ -22,11 +22,13 @@
*
* $CAMITK_LICENCE_END$
****************************************************************************/
#include "CepGenerator.h"
#include "ExtensionGenerator.h"
#include "ActionExtensionGenerator.h"
#include "ComponentExtensionGenerator.h"
#include "LibraryGenerator.h"
#include "ViewerExtensionGenerator.h"
#include "ClassNameHandler.h"
// includes from std
......@@ -40,13 +42,15 @@
#include <Cep.hxx>
#include <Contact.hxx>
static const QString cepActionsDirectoryName = "actions";
static const QString cepApplicationsDirectoryName = "applications";
static const QString cepComponentsDirectoryName = "components";
static const QString cepApplicationsDirectoryName = "applications";
static const QString cepComponentsDirectoryName = "components";
static const QString cepLibrariesDirectoryName = "libraries";
static const QString cepManifestName = "CEPContent";
static const QString cepManifestExtension = ".xml";
static const QString cepSchemaNamespace = "http://camitk.imag.fr/cepcoreschema";
static const QString cepViewersDirectoryName = "viewers";
static const QString cepManifestName = "CEPContent";
static const QString cepManifestExtension = ".xml";
static const QString cepSchemaNamespace = "http://camitk.imag.fr/cepcoreschema";
inline void initMyResource() {
Q_INIT_RESOURCE(cepgenerator);
......@@ -67,7 +71,7 @@ CepGenerator::CepGenerator(QString xmlFilename, QString devDirectoryName) {
CepGenerator::CepGenerator(std::unique_ptr< cepcoreschema::Cep > domCep, QString devDirectoryName) {
initMyResource();
this->domCep = std::move(domCep);
domCep = std::move(domCep);
setDevDirectoryName(devDirectoryName);
}
......@@ -104,7 +108,7 @@ void CepGenerator::createDomTree() {
std::string xmlFileStr = xmlFileName.canonicalFilePath().toStdString();
try {
this->domCep = cep(xmlFileStr, xml_schema::flags::dont_validate);
domCep = cep(xmlFileStr, xml_schema::flags::dont_validate);
}
catch (const xml_schema::exception& e) {
std::cout << "Parsing exception during CEP file generation in XML document " << xmlFileStr << ": " << std::endl;
......@@ -119,7 +123,7 @@ void CepGenerator::generateDirectoryTree() {
// -------------------- Create a sub-directory with the CEP name
QString cepName(domCep->name().c_str());
// A directory name should be low case with no space
this->cepDirectoryName = ClassNameHandler::getDirectoryName(cepName);
cepDirectoryName = ClassNameHandler::getDirectoryName(cepName);
QDir currentDirectory;
currentDirectory.cd(devDirectoryName.absolutePath());
......@@ -146,8 +150,10 @@ void CepGenerator::generateDirectoryTree() {
generateComponentsDirectory();
// Libraries
generateLibrariesDirectory();
// Create build and doc directories ???
// Viewers
generateViewersDirectory();
// Create doc directories ???
}
......@@ -252,19 +258,19 @@ void CepGenerator::setLicence() {
// Get the copyright in the CEP DOM...
if (domCep->copyright().present()) {
std::cout << "I found a licence ! " << std::endl;
this->licence = QString(domCep->copyright().get().c_str());
licence = QString(domCep->copyright().get().c_str());
}
else {
std::cout << "No licence found... Copying the default one..." << endl;
std::cout << "No licence found... Copying the default one..." << std::endl;
QFile defaultLicenceFile(":/resources/COPYRIGHT.in");
defaultLicenceFile.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&defaultLicenceFile);
QString text;
this->licence = "";
licence = "";
text = in.readLine();
while (! text.isNull()) {
this->licence += text + "\n";
licence += text + "\n";
text = in.readLine();
}
}
......@@ -285,7 +291,7 @@ void CepGenerator::generateCopyright() {
}
QTextStream out(&copyrightOutFile);
QTextStream in(&(this->licence));
QTextStream in(&(licence));
QString text;
do {
text = in.readLine();
......@@ -354,6 +360,7 @@ void CepGenerator::generateActionsDirectory() {
cmakelistFileName = currentDirectory.absolutePath() + "/CMakeLists.txt";
QFile::copy(":/resources/actions.CMakeLists.txt.in", cmakelistFileName);
}
void CepGenerator::generateApplicationsDirectory() {
QString cmakelistFileName;
QDir currentDirectory;
......@@ -391,6 +398,18 @@ void CepGenerator::generateLibrariesDirectory() {
QFile::copy(":/resources/libraries.CMakeLists.txt.in", cmakelistFileName);
}
void CepGenerator::generateViewersDirectory() {
QString cmakelistFileName;
QDir currentDirectory;
currentDirectory.cd(devDirectoryName.absolutePath());
currentDirectory.cd(cepDirectoryName);
// createing actions directory
currentDirectory.mkdir(cepViewersDirectoryName);
// copying CMakeLists.txt
currentDirectory.cd(cepViewersDirectoryName);
cmakelistFileName = currentDirectory.absolutePath() + "/CMakeLists.txt";
QFile::copy(":/resources/viewers.CMakeLists.txt.in", cmakelistFileName);
}
void CepGenerator::createActionExtensionDoms() {
std::cout << "creating action extension doms..." << std::endl;
......@@ -446,12 +465,32 @@ void CepGenerator::createLibrarieDoms() {
// Is it only possible ? http://stackoverflow.com/questions/12674735/function-wont-accept-iterator-to-auto-ptr
Library& lib = (*i);
LibraryGenerator* generator = new LibraryGenerator(lib, currentDirectory.absolutePath(), licence);
this->extensions.append(generator);
extensions.append(generator);
}
}
}
void CepGenerator::createViewersExtensionDoms() {
std::cout << "creating viewer extension doms..." << std::endl;
QString cmakelistFileName;
QDir currentDirectory;
currentDirectory.cd(devDirectoryName.absolutePath());
currentDirectory.cd(cepDirectoryName);
currentDirectory.cd(cepViewersDirectoryName);
if (domCep->viewerExtensions().present()) {
ViewerExtensions extensions = domCep->viewerExtensions().get();
for (auto i = extensions.viewerExtension().begin(); i != extensions.viewerExtension().end(); i++) {
// TODO: find a way to use std:auto_ptr here for the dom extension instead of creating a new instance
// Is it only possible ? http://stackoverflow.com/questions/12674735/function-wont-accept-iterator-to-auto-ptr
ViewerExtension& extension = (*i);
ViewerExtensionGenerator* generator = new ViewerExtensionGenerator(extension, currentDirectory.absolutePath(), licence);
this->extensions.append(generator);
}
}
}
void CepGenerator::generateExtensions() {
std::cout << "inside generateExtension" << std::endl;
......@@ -468,5 +507,6 @@ void CepGenerator::process() {
createComponentExtensionDoms();
createActionExtensionDoms();
createLibrarieDoms();
createViewersExtensionDoms();
generateExtensions();
}
......@@ -105,25 +105,32 @@ public :
protected:
/** Create the general directory tree (the same for every CEP)
Copies the default files in the right directories:
/** Create the general directory tree (the same for every CEP).
* Copies the default files in the right directories:
\code
cepdirectoryname
|
+--- actions
|
---- CMakeLists.txt
----- CMakeLists.txt
+--- applications
|
---- CMakeLists.txt
+--- components
|
---- CMakeLists.txt
---- COPYRIGHT
---- FindCamiTK.cmake
+--- libraries
|
--- CMakeLists.txt
+--- viewers
|
--- CMakeLists.txt
---- COPYRIGHT
---- CMakeLists.txt
---- FindCamiTK.cmake
---- Manifest.xml
---- README
\endcode
*/
virtual void generateDirectoryTree();
......@@ -153,17 +160,20 @@ protected:
/// Generate the Libraries directory
virtual void generateLibrariesDirectory();
/// Generate the Libraries directory
virtual void generateViewersDirectory();
/// Set the licence ine the \c licence variable to be included later in the generated files.
virtual void setLicence();
/** @} */
/**
Create the ActionExtensionDom if needed and call the appropriate methods to generate the actions Extensions.
Create the ActionExtensionDom if needed and call the appropriate methods to generate the action extensions.
*/
virtual void createActionExtensionDoms();
/**
Create the ComponentExtensionDom if needed and call the appropriate methods to generate the components Extensions.
Create the ComponentExtensionDom if needed and call the appropriate methods to generate the component extensions.
*/
virtual void createComponentExtensionDoms();
......@@ -171,6 +181,11 @@ protected:
Create the LibrariesDom if needed and call the appropriate methods to generate the libraries.
*/
virtual void createLibrarieDoms();
/**
Create the ViewersDom if needed and call the appropriate methods to generate the viewer extensions.
*/
virtual void createViewersExtensionDoms();
virtual void generateExtensions();
......
......@@ -97,7 +97,7 @@ ComponentExtensionGenerator::~ComponentExtensionGenerator() {
}
void ComponentExtensionGenerator::generateActionOrComponent(QString directory) {
void ComponentExtensionGenerator::generateExtensionClass(QString directory) {
// C generate actions
for (auto& component : components) {
component->generateFiles(directory);
......
......@@ -61,7 +61,7 @@ public:
protected:
/// @{ Helpers methods
void generateActionOrComponent(QString directory) override;
void generateExtensionClass(QString directory) override;
void writeCFile(QString directory) override;
void writeHFile(QString directory) override;
......
......@@ -34,6 +34,7 @@ using namespace cepcoreschema;
static const QString MACRO_CALL_CEP_LIBRARIES = "NEEDS_CEP_LIBRARIES";
static const QString MACRO_CALL_COMPONENTS = "NEEDS_COMPONENT_EXTENSION";
static const QString MACRO_CALL_ACTIONS = "NEEDS_ACTION_EXTENSION";
static const QString MACRO_CALL_VIEWERS = "NEEDS_VIEWER_EXTENSION";
DependencyGenerator::DependencyGenerator(Dependency domDependency) {
......@@ -53,6 +54,9 @@ DependencyGenerator::DependencyGenerator(Dependency domDependency) {
case (DependencyType::action):
this->type = NEEDED_ACTION;
break;
case (DependencyType::viewer):
this->type = NEEDED_VIEWER;
break;
}
}
......@@ -133,4 +137,22 @@ QString DependencyGenerator::getNeededActionsString(QVector<DependencyGenerator*
}
QString DependencyGenerator::getNeededViewersString(QVector<DependencyGenerator* > dependencies) {
QStringList actions;
for (QVector<DependencyGenerator*>::const_iterator it = dependencies.begin(); it != dependencies.end(); it++) {
if ((*it)->type == NEEDED_VIEWER) {
actions << (*it)->getName();
}
}
QString result = "";
if (! actions.isEmpty()) {
result = MACRO_CALL_VIEWERS + " ";
for (int i = 0; i < actions.size(); i++) {
result += actions.at(i) + " ";
}
}
return result;
}
......@@ -52,14 +52,15 @@ public:
EXTERNAL_LIB,
CEP_LIB,
NEEDED_COMPONENT,
NEEDED_ACTION
NEEDED_ACTION,
NEEDED_VIEWER
};
static QString getExternalLibsString(QVector<DependencyGenerator* > dependencies);
static QString getCepLibsString(QVector<DependencyGenerator* > dependencies);
static QString getNeededComponentsString(QVector<DependencyGenerator* > dependencies);
static QString getNeededActionsString(QVector<DependencyGenerator* > dependencies);
static QString getNeededViewersString(QVector<DependencyGenerator* > dependencies);
DependencyGenerator(cepcoreschema::Dependency domDependency);
......
......@@ -50,9 +50,6 @@ ExtensionGenerator::ExtensionGenerator(QString extensionsDirectory, QString lice
}
ExtensionGenerator::~ExtensionGenerator() {
// for (QVector<DependencyGenerator *>::iterator dep = dependencyGenerators.begin(); dep != dependencyGenerators.end(); dep++)
// delete dep;
}
void ExtensionGenerator::setExtensionsDirectory(QString extensionsDirectory) {
......@@ -80,7 +77,7 @@ void ExtensionGenerator::generateExtension() {
generateExtensionCMakeLists(directory);
// C generate actions
generateActionOrComponent(directory);
generateExtensionClass(directory);
// D generate cpp and h files
writeHFile(directory);
......@@ -96,7 +93,7 @@ void ExtensionGenerator::generateExtensionCMakeLists(QString directory) {
QString cepLibs = DependencyGenerator::getCepLibsString(this->dependencyGenerators);
QString neededComps = DependencyGenerator::getNeededComponentsString(this->dependencyGenerators);
QString neededActions = DependencyGenerator::getNeededActionsString(this->dependencyGenerators);
QString neededViewers = DependencyGenerator::getNeededViewersString(this->dependencyGenerators);
// Open the resources CMakeFile model
QFile initFile(":/resources/CamiTKExtensionCMakeLists.txt.in");
......@@ -122,6 +119,7 @@ void ExtensionGenerator::generateExtensionCMakeLists(QString directory) {
text.replace(QRegExp("@NEEDEDCEPLIBRARIES@"), cepLibs);
text.replace(QRegExp("@NEEDEDCOMPEXT@"), neededComps);
text.replace(QRegExp("@NEEDEDACTIONEXT@"), neededActions);
text.replace(QRegExp("@NEEDEDVIEWEREXT@"), neededViewers);
text.replace(QRegExp("@EXTENSIONDESCRIPTION@"), this->description);
out << text << endl;
}
......
......@@ -51,7 +51,7 @@ class ExtensionGenerator {
public:
ExtensionGenerator(QString actionExtensionsDirectory, QString licence = "", QString extensionType = "NONE");
~ExtensionGenerator();
virtual ~ExtensionGenerator();
virtual void generateExtension();
......@@ -61,7 +61,8 @@ protected:
/// @{ Helpers methods
virtual void generateExtensionCMakeLists(QString directory);
virtual void generateActionOrComponent(QString directory) = 0;
/// generate an action, a component of a viewer
virtual void generateExtensionClass(QString directory) = 0;
virtual void writeCFile(QString directory) = 0;
virtual void writeHFile(QString directory) = 0;
......
......@@ -60,7 +60,7 @@ protected:
/// @{ Helpers methods
void generateExtensionCMakeLists(QString directory) override;
void generateActionOrComponent(QString directory) {};
void generateExtensionClass(QString directory) {};
void writeCFile(QString directory) {};
void writeHFile(QString directory) {};
......
/*****************************************************************************
* $CAMITK_LICENCE_BEGIN$
*
* CamiTK - Computer Assisted Medical Intervention ToolKit
* (c) 2001-2018 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
*
* Visit http://camitk.imag.fr for more information
*
* This file is part of CamiTK.
*
* CamiTK is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* CamiTK 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 Lesser General Public License version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with CamiTK. If not, see <http://www.gnu.org/licenses/>.
*
* $CAMITK_LICENCE_END$
****************************************************************************/
#include "ViewerExtensionGenerator.h"
// includes from cepcoreschema
#include <ViewerExtension.hxx>
#include <Viewer.hxx>
#include <Dependency.hxx>
// includes from STL
#include <iostream>
#include <memory>
// includes from Qt
#include <QFileInfo>
#include <QFile>
#include <QDir>
#include <QTextStream>
// local includes
#include "ClassNameHandler.h"
#include "ViewerGenerator.h"
#include "DependencyGenerator.h"
using namespace cepcoreschema;
ViewerExtensionGenerator::ViewerExtensionGenerator(QString xmlFileName, QString viewerExtensionDirectory, QString licence)
: ExtensionGenerator(viewerExtensionDirectory, licence, "Viewer") {
QFileInfo xmlFile(xmlFileName);
if ((! xmlFile.exists()) || (! xmlFile.isFile())) {
throw std::invalid_argument("I/O exception during viewer extension file generation:\nFile " + xmlFileName.toStdString() + " does not exist or is not a file...\n");
}
try {
std::string xmlFileStr = xmlFileName.toStdString();
std::unique_ptr<ViewerExtension>domViewerExtension = viewerExtension(xmlFileStr, xml_schema::flags::dont_validate);
createFromDom(*domViewerExtension);
}
catch (...) {
throw std::invalid_argument("I/O exception during viewer extension file generation:\nFile " + xmlFileName.toStdString() + " is not valid...\n");
}
}
ViewerExtensionGenerator::ViewerExtensionGenerator(ViewerExtension& domViewerExtension, QString viewerExtensionDirectory, QString licence)
: ExtensionGenerator(viewerExtensionDirectory, licence, "Viewer") {
createFromDom(domViewerExtension);
}
void ViewerExtensionGenerator::createFromDom(ViewerExtension& dom) {
name = QString(dom.name().c_str());
description = QString(dom.description().c_str()).simplified();
registerDefaultViewer = dom.registerDefaultViewer().present();
// named viewers
for (auto it = dom.registerNewViewer().begin(); it != dom.registerNewViewer().end(); it++) {
namedViewers << QString((*it).c_str());
}
if (dom.dependencies().present()) {
Dependencies deps = dom.dependencies().get();
for (Dependencies::dependency_iterator it = deps.dependency().begin(); it != deps.dependency().end(); it++) {
Dependency& dep = (*it);
DependencyGenerator* depGen = new DependencyGenerator(dep);
dependencyGenerators.append(depGen);
}
}
// Create the viewer class...
viewerGenerator = new ViewerGenerator(dom.viewer(), licence);
}
ViewerExtensionGenerator::~ViewerExtensionGenerator() {
// for (QVector<DependencyGenerator *>::iterator dep = dependencyGenerators.begin(); dep != dependencyGenerators.end(); dep++)
// delete dep;
}
void ViewerExtensionGenerator::generateExtensionClass(QString directory) {
// C generate viewers
viewerGenerator->generateFiles(directory);
}
void ViewerExtensionGenerator::writeHFile(QString directory) {
QString className = ClassNameHandler::getClassName(name) + "Extension";
QFile initHFile(":/resources/ViewerExtension.h.in");
initHFile.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream inh(&initHFile);
QFileInfo extFileHPath;
extFileHPath.setFile(directory, className + ".h");
QFile extFileH(extFileHPath.absoluteFilePath());
if (! extFileH.open(QIODevice::WriteOnly | QIODevice::Text)) {
QString msg = "Exception from extension generation: \n Cannot write on file " + extFileHPath.fileName() + "\n";
throw (msg);
}
QTextStream outh(&extFileH);
QString headdef = className.toUpper();
QString text;