1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Comment écrire une extension pour Scribus</title>
</head>
<body>
<h2>Comment écrire une extension pour Scribus</h2>
<h3>Préface</h3>
<p>La présente section vous montre comment écrire une extension pour Scribus. Les extensions sont des librairies qui sont chargées dans
l'application principale au moment de l'exécution. Les extensions peuvent étendre, voire modifier le comportement de l'application sans nécessiter de réécriture ni de recompilation. Elles
permettent d'ajouter des outils supplémentaires, de nouvelles fonctions d'importation et d'exportation, et plusieurs autres fonctionnalités évoluées. </p>
<p>Ce document présuppose une connaissance de base du langage C++. Vous devez savoir ce qu'est un fichier d'en-tête
et comment fonctionne l'inclusion de fichier;aussi, vous devez posséder des connaissance sur l'héritage des classes et une certaine maîtrise du langage C++. La connaissance de Qt - principalement QString et QObject - sera également utile. Des questions comme les fonctions virtuelles et purement virtuelles, les déclarations "extern C", les détails de la gestion de mémoire, etc. sont éludées dans ce document. Vous n'avez pas à les connaître, mais elles pourraient vous aider à mieux suivre ce qui ce passe. </p>
<p>Nous n'allons pas tenter d'expliquer ici les détails du fonctionnement du système d'extensions de Scribus. Le présent document explique seulement comment écrire une extension. La documentation des texte d'aide <code>scplugin.h</code> et <code>pluginmanager.h</code> explique le fonctionnement du système.</p>
<h3>Où puis-je trouver les extensions Scribus ?</h3>
<p>Scribus est livré avec un certain nombre d'extensions standard. Celles-ci seront installées en même temps que le programme Scribus et ses autres fichiers. Sous UNIX, les extensions seront installées sous le même préfixe que l'application principale. Sous Mac OS X elles sont incluses avec l'application. Si vous voulez savoir ce que font ces extensions, le meilleur moyen de le découvrir est de démarrer Scribus et d'aller dans <code>Fichier->Préférences</code>
puis de cliquer sur l'icône "extensions". À partir de là, vous obtiendrez une liste des extensions installées, des types d'extensions associés et des emplacements des fichiers.</p>
<p>En plus des extensions livrées en standard avec Scribus, il est possible de compiler et d'installer des extensions obtenues ailleurs, ou d'écrire et d'ajouter la vôtre.</p>
<h3>Avant de commencer à coder</h3>
<p>Supposons que vous avez eu une bonne idée pour améliorer Scribus et que vous êtes impatient d'écrire un code C++ de qualité. <b>Patientez quelques minutes</b> et lisez la présente section; vous pourriez gagner du temps et vous éviter des problèmes.</p>
<h4>Important</h4>
<p>Peut-être que vous êtes sur le point de "réinventer la roue", c'est-à-dire de ré-écrire ce que quelqu'un d'autre a déjà fait. Vous devriez vous joindre à la liste de diffusion et afficher votre idée, ou vous connecter au canal <code>#scribus</code> sur <code>irc.freenode.net</code>. Votre sujet sera soumis à l'étude, et vous obtiendrez probablement de l'aide et des idées des développeurs et des utilisateurs. Comme Scribus est distribué sous licence libre, vous pouvez travailler en solitaire, mais vous devriez au moins avoir une conversation d'introduction sur IRC ou envoyer un courriel à la liste de diffusion, ce qui pourrait vous éviter des heures de travail et des maux de tête. Nous voulons faciliter l'écriture d'extensions le plus possible pour les personnes intéressées.
<h4>Compatibilité</h4>
<p>Scribus n'a pas une API fixe en C++ pour accommoder les extensions. Les versions ne sont pas compatibles en binaire, et les versions instables enfreignent souvent la compatibilité avec le code source.
La compatibilité source n'est pas garantie actuellement, même entre des versions stables, lorsque des changements sont requis pour corriger un problème. Nous espérons redresser la situation dans l'avenir et fournir une API C++ stable pour le code externe. Pour l'instant, vous devez tenter d'intégrer l'essentiel de vos fonctionnalités dans un module séparé qui dépend le moins possible des rouages internes de Scribus.</p>
<p>Ce document traite de la mise en oeuvre d'une extension pour Scribus 1.3.1cvs. Les exigences sont radicalement différentes de celles des versions 1.2.x. Les changements futurs devraient être moins importants.</p>
<p>Il est peu pratique de prévoir l'écriture d'une extension pouvant fonctionner sous les versions 1.2.x et 1.3.x de Scribus.</p>
<h3>Démarrage rapide</h3>
<p>Il n'est pas trop difficile de se mettre à écrire une extension. La documentation ci-dessous décrit l'implantation d'une extension et vous renvoie à des compléments d'information au besoin. Un "modèle d'extension" vous est fourni, et vous pouvez en faire une copie au moment de débuter la programmation. Des instructions de base sont incluses dans le fichier et, en cas doute, vous pouvez consulter ce document.</p>
<p>Nous allons bâtir l'extension comme un composant de Scribus. C'est la manière la plus simple de commencer,
même si vous prévoyez de la distribuer séparément plus tard (voir plus loin). Pour commencer à travailler sur une extension (de type Action) :</p>
<ul>
<li>Copiez <code>scribus/plugins/myplugin</code>
dans <code>scribus/plugins/pluginname</code>
(où "pluginname" est le nom que vous voulez donner à votre extension).
pluginname doit être un identifiant C valide - je suggère d'utiliser seulement les caractères minuscules.</li>
<li>Éditez <code>scribus/plugins/Makefile.am</code> et ajoutez "pluginname" à Makefile.am. Cela indique au système d'intégration de Scribus de compiler votre extension.</li>
<li>Renommez tous les fichiers dans <code>scribus/plugins/pluginname/</code>
de <code>myplugin</code> en <code>pluginname</code>, par exemple
<code>myplugin.h</code> en <code>pluginname.h</code>.
<i>Ne renommez pas Makefile.am</i>.</li>
<li>Renommez <code>myplugin</code> là où il figure dans les fichiers en
<code>pluginname</code>, par exemple <code>myplugin_getPluginAPIVersion()</code>
en <code>pluginname_getPluginAPIVersion()</code>. Faites de même pour
<code>MyPlugin</code> et <code>MYPLUGIN</code>. Sous UNIX, vous pouvez utiliser cette commande :<br/>
<code>sed -i -e "s/myplugin/pluginname/g" -e "s/MyPlugin/PluginName/g" -e "s/MYPLUGIN/PLUGINNAME/g" myplugin*</code><br/>
(tout sur une ligne, exécuté à partir de <code>scribus/plugins/pluginname/</code>).
</li>
</ul>
<p>Vous êtes maintenant prêt à commencer à travailler sur votre extension. Premièrement, vous devez entrer des renseignements à propos de votre extension dans <code>pluginname.cpp</code> :</p>
<ul>
<li>Dans <code>PluginName::languageChange()</code> :
<ul>
<li>Changez <code>m_actionInfo.text</code> pour le texte de l'élément de menu qui doit lancer votre extension.</li>
<li>Changez <code>m_actionInfo.menu</code> pour le nom du menu qui doit afficher cet élément. Voir <b><i>FIXME where????
FIXME</i></b> pour une liste de noms de menu.</li>
<li>Pour activer un raccourci clavier, décommentez <code>m_actionInfo.keySequence</code> et inscrivez-y votre raccourci préféré. L'exemple ci-dessousdevrait vous montrer comment cela fonctionne.</li>
</ul>
</li>
<li>Changez le nom inscrit dans <code>PluginName::fullTrName()</code>
pour le nom de votre extension tel que vous voulez qu'il figure à l'écran Aide->À propos des extensions et dans le panneau de gestion des extensions (dans les préférences).</li>
<li>Si vous souhaitez afficher de l'information (p. ex. l'auteur et la description) à l'utilisateur qui clique sur Aide->À propos des extensions, remplissez les zones prévues à cet effet en assignant les membres de la section <code>À propos</code>. Pour connaître l'information possible, consultez la définition de <code>AboutData</code> dans <code>scplugin.h</code>.</li>
</ul>
<p>Vous avez terminé la mise en place de l'extension et vous pouvez maintenant commencer à programmer. Votre code
doit être placé dans <code>pluginnameimpl.cpp</code> et
<code>pluginnameimpl.h</code>. Le code existant devrait afficher une boîte de dialogue contenant un message.</p>
<p>Pour compiler l'extension, il suffit d'exécuter une nouvelle fois <code>make -f Makefile.cvs</code>, <code>./configure</code>, et <code>make</code> dans le répertoire supérieur de Scribus.
Une fois la compilation terminée, exécutez <code>make install</code> et démarrez Scribus.
Votre extension doit maintenant figurer dans le gestionnaire d'extensions (dans les préférences) et doit être associée à un élément de menu. Si vous appuyez sur l'élément de menu, vous devriez obtenir une boîte de dialogue.</p>
<h3>Bâtir les extension en dehors de la hiérarchie de Scribus</h3>
<h4>Utilisation rapide et directe de QMake</h4>
<b>Avertissement</b>
<p>Attention, il est facile d'utiliser un projet qmake, mais il ne s'agit pas nécessairement de la méthode standard pour distribuer un logiciel sur une plateforme Linux. Le processus sert à titre d'exemple seulement, pour le développement. Quand vous créerez votre progiciel opérationnel, sans bogues, prenez le temps de préparer la distribution complète automagic (autoconf, automake)
tel que décrit dans la prochaine section.</p>
<p>Compilons maintenant l'extension (ce n'est pas aussi simple que de taper <code>gcc
myplugin.cpp</code> ;). Voici un procédé simple : qmake de Qt (parce que certaines personnes hésitent à utiliser autoconf et automake en raison de leur complexité). Nota : vous devrez créer un fichier vide <code>config.h</code> avant d'exécuter ces étapes. </p>
<blockquote><table width="100%" border="1" bgcolor="#eeeeee"><tr><td border="0">
<pre>
#qmake -project
</pre>
</td></tr></table></blockquote>
<p>Maintenant que le fichier projet est créé, nous allons y apporter quelques petits changements.</p>
<blockquote><table width="100%" border="1" bgcolor="#eeeeee"><tr><td border="0">
<pre>
######################################################################
# Automatically generated by qmake (1.06c) Sun Dec 14 13:32:11 2003
######################################################################
#change TEMPLATE = app. Nous ne travaillons pas sur l'application, seulement sur l'extension
TEMPLATE = lib
INCLUDEPATH += .
#Comme nous travaillons avec Scribus, nous avons besoin des inclusions de Scribus aussi.
INCLUDEPATH += /home/subzero/devel/Scribus/include/Scribus/
#Et Scribus doit utiliser freetype2.
#Donc nous devons le lier aussi. Utilisez les chemins retournés par
##freetype-config --cflags and --libs
INCLUDEPATH += /usr/include/freetype2
LIBS += -lfreetype -lz
# Entrée
#crée un fichier config.h vide
HEADERS += myplugin.h config.h
SOURCES += myplugin.cpp
</pre>
</td></tr></table></blockquote>
<p>Après ces changements, vous êtes prêt à compiler</p>
<blockquote><table width="100%" border="1" bgcolor="#eeeeee"><tr><td border="0">
<pre>
#qmake
#make
</pre>
</td></tr></table></blockquote>
<p>Exécuter Qmake crée le Makefile et, en l'exécutant, vous compilez votre extension.</p>
<p>Ensuite : Copiez seulement les fichiers *so* dans le répertoire d'extensions de Scribus et lancez Scribus.
Vous lirez "Do Nothing Plugin" dans le menu Extra.</p>
<p>Il est clair que vous devez utiliser une autre méthode pour distribuer votre code aux autres utilisateurs - certains utilisent les fichiers autogénérés qmake pro, d'autres, la combinaison autoconf/automake.</p>
<h4>Distribuez-le! (autrement dit compilez-le! 2e édition)</h4>
<p>Qmake est facile à utiliser et convient bien à un développement rapide, mais il y a une manière standard de compiler ou de distribuer un logiciel pour Linux, *BSD, etc. : autoconf et automake. Nous désignerons ces deux programmes sous l'acronyme automagic dans le texte qui suit.</p>
<p>Pour utiliser automagic avec succès, vous aurez besoin d'un pentagramme dessiné à la craie sur le sol et orienté au nord (Carrefour, 2€), d'un costume de diablotin rouge et noir (Hugo Boss, 2000€) et d'un pingouin sacrifié sur l'autel domestique (une heure de frayeur au zoo le plus proche). Ce n'était
qu'une blague... ne faites pas de mal aux mignons pingouins, ce n'est pas nécessaire!!</p>
<p>Téléchargez l'exemple <code>donothingplugin-1.0.tar.gz</code> à partir de http://docs.scribus.net, décomprimez-le et parcourez son contenu.</p>
<p>Quand vous accédez au répertoire principal, vous apercevez beaucoup de fichiers et de répertoires. <b>Attention</b> : Ne changez rien dans le répertoire admin.
Ce contenu vous est INTERDIT!</p>
<p>Puisque vous avez lu la documentation d'automagic (sûrement), vous savez que chaque répertoire de votre projet contient un fichier important appelé <code>Makefile.am</code>. Voici un court exemple commenté :</p>
<blockquote><table width="100%" border="1" bgcolor="#eeeeee"><tr><td border="0">
<pre>
# indique où l'extension sera installée
pluginsdir = $(prefix)/lib/scribus/plugins
# spécifie les inclusions additionnelles pour la compilation
AM_CPPFLAGS = -I$(prefix)/include/scribus
# spécifie les répertoires à parcourir (avec les sous-niveaux)
SUBDIRS = translation doc
# nom de l'extension = librairie
plugins_LTLIBRARIES = libscribusvlna.la
# join toutes les inclusions
INCLUDES = $(LIBFREETYPE_CFLAGS) $(all_includes)
# divers relatifs à la librairie - symlinks, etc.
libscribusvlna_la_LDFLAGS = -version-info 0:0:0
libscribusvlna_la_METASOURCES = AUTO
#
# liste des fichiers source de votre projet
libscribusvlna_la_SOURCES = frame.cpp selection.cpp vlnadialog.cpp vlnapage.cpp svlna.cpp
EXTRA_DIST = frame.cpp selection.cpp svlna.cpp vlnadialog.cpp vlnapage.cpp frame.h /
selection.h svlna.h vlnadialog.h vlnapage$
# comment compiler
KDE_OPTIONS = qtonly
AM_LDFLAGS = -s $(LIBFREETYPE_LIBS)
</pre>
</td></tr></table></blockquote>
<p>Pour récapituler : Si vous prenez le fichier <code>donothingplugin-1.0.tar.gz</code> (si vous le renommez, bien sûr) et si vous analysez le contenu des fichiers <code>Makefile.am</code>, vous obtiendrez un progiciel opérationnel.</p>
<p>Il reste une dernière chose à faire. Vous devez aussi spécifier la structure de répertoire dans le fichier <code>configure.in</code> du répertoire racine du projet : </p>
<blockquote><table width="100%" border="1" bgcolor="#eeeeee"><tr><td border="0">
<pre>
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([svlna/Makefile])
AC_CONFIG_FILES([svlna/translation/Makefile])
AC_CONFIG_FILES([svlna/doc/Makefile])
</pre>
</td></tr></table></blockquote>
<p>Et maintenant, comment ça marche?</p>
<p>Premièrement lancez <code>make -f Makefile.dist</code> dans le répertoire racine. Les modèles
de <code>Makefile.in</code> sont créés (comme par magie).</p>
<p>Ensuite, <code>./configure ; make ; make install</code>
devrait fonctionnner pour vous. Profitez-en.</p>
<h3>Complément d'information</h3>
<p>À ce stade, vous devriez lire <code>scplugin.h</code> et comprendre le texte d'aide. Pour des précisions sur le fonctionnement du système d'extensions <a href="WHERE">ici</a>. Surtout, vous apprendrez la procédure en lisant les autres extensions et le code central de Scribus.</p>
<h4>Comment conserver les préférences de votre extension :</h4>
<p>Scribus fournit une API de préférences pour les développeurs d'extensions qui permet de conserver les données entre les démarrages de Scribus. Il y a deux types de formats disponibles : Paires "clé-valeur" et Tables.</p>
<p>Tout d'abord, vous devrez obtenir l'objet <code>PrefsContext</code> pour votre extension. Ensuite, vous pouvez extraire de <code>PrefsContext</code> une valeur de clé spécifique ou vous pouvez solliciter <code>PrefsTable</code> par son nom. Voici un court exemple qui utilise les paires clé-valeur.</p>
<pre>
#include <prefsfile.h>
#include <prefscontext.h>
extern PrefsFile* prefsFile;
PrefsContext *myPluginPrefs = prefsFile->getPluginContext("MyPlugin");
// la valeur par défaut 1 sera utilisée si "i" n'existe pas déjà
int i = myPluginPrefs->getInt("i");
// la valeur par défaut "chien" sera utilisée si "s" n'existe pas
QString s = myPluginPrefs->get("s", "chien");
myPluginPrefs->set("i", 221);
myPluginPrefs->set("s", "chat");
</pre>
<h4>Modèle objet de Scribus</h4>
<p>Le code source de Scribus n'est pas documenté en détail. Beaucoup d'efforts sont déployés pour corriger la situation, mais étant donné la taille du code, cela prend du temps. Essayez de suivre l'évolution en vous basant sur les fichiers d'en-tête et sur le code. En cas de doute, n'hésitez pas à consulter le canal IRC ou à poser des questions via la liste de diffusion, et vous obtiendrez probablement une réponse. Soyezpatient, car nous ne sommes pas toujours disponibles ou présents sur IRC.
</p>
<p>Si vous souhaitez améliorer la documentation ou corriger l'API de génération doxygen api, nous vous en saurons gré. </p>
<p>Il est important de noter que l'accès au coeur de l'application Scribus passe par l'aide du pointeur statique global <code>ScApp</code>, déclaré dans <code>scribus.h</code>. Attention à la confusion : c'est aussi une sous-classe de QMainWindow.
Vous pouvez également aller à la sous-classe QApplication utilisée comme <code>ScQApp</code> à partir de <code>scribusapp.h</code>.</p>
<p>Certains sous-systèmes majeurs sont des classes uniques qui sont accessibles via ClassName::instance() . Il y a par exemple <code>PluginManager</code>,
<code>ScPaths</code>, ainsi qu'un nombre croissant d'autres classes. L'avantage
de cette approche est de vous permettre d'interagir avec ces classes sans pénétrer dans les rouages de ScApp.</p>
<h3>Liens associés aux extensions</h3>
<a href="http://doc.trolltech.com/">Documentation de Qt par Trolltech</a><br />
<a href="http://doc.trolltech.com/3.3/qmake-manual.html">Documentation de QMake par Trolltech</a><br />
<a href="http://www.murrayc.com/learning/linux/automake/automake.shtml">Exemple automake/autoconf</a><br />
</body>
</html>
o
|