mercredi 23 novembre 2011

Formulaires dans libreoffice base

Nous allons revenir sur le sujet traité dans ce billet, à savoir la création de formulaires dans libreoffice base (à l'époque c'était openoffice base).
L'approche sera cette fois différente: nous n'utiliserons pas l'assistant et donnerons un rôle encore plus important au navigateur de formulaires. La base de données utilisée (appelée bd01) est une base de données PostgreSQL concernant comme précédemment la gestion du personnel d'une entreprise.

Création de la structure du formulaire.
Après connexion à cette base de données cliquons sur "Créer un formulaire en mode Ébauche" et ensuite dans la fenêtre qui apparaît cliquons sur l'icône du navigateur de formulaire située dans la barre d'outils horizontale inférieure:
Dans le navigateur, cliquons droit sur "Formulaires" et dans le menu contextuel qui surgit, choisissons "Nouveau Formulaire":
Ce nouveau formulaire s'appelle par défaut "Formulaire". Donnons lui un nom plus parlant. Pour afficher les données qui nous intéressent, nous allons utiliser une table "selection" contenant l'identifiant (matricule) du dossier à sélectionner. nous appellerons donc ce premier formulaire "Sélection".
Recommençons l'opération en cliquant droit sur l'icône du formulaire qui vient d'être créé:


Le nouveau formulaire (qui dépendra de "Sélection") contiendra les données des employés de l'entreprise: nous l’appellerons "Employés".
Continuons de la sorte de manière à arriver à ceci:

"Département" affichera le département du lieu de résidence de l'employé, "Salaire" le salaire pour un mois donné et "Détails" les détails de ce salaire (prime, régularisation, heures sup etc).
Il s'agit d'un exemple.
Autre exemple:
Il s'agit cette fois d'une structure correspondant à l'affichage des données d'un client (d'un magasin) avec date et montant d'une facture et les détails de celle-ci.

Sources de données et liens entre sous-formulaires.
Ouvrons la fenêtre "Propriétés"du formulaire "Sélection". On peut procéder via le menu contextuel de "Sélection" ou en cliquant sur l'icône formulaire de la barre d'outils:

On déclare la source de données comme étant la table selection et on n'autorise ni les ajouts ni les suppressions:


Rappelons que la table selection dont voici la description (ouput de la meta commande psql \dS):
  Colonne  |  Type   | Modificateurs
-----------+---------+---------------
 id        | integer | non NULL
 matricule | integer |
Index :
    "selection_pkey" PRIMARY KEY, btree (id)
est une table outil dont le seul but est de nous permettre d'afficher aisément le dossier qui nous intéresse.
(NB: les tables PostgreSQL dont le contenu est amené à être modifié dans libreoffice base doivent être munies d'une clef primaire)
Passons aux propriétés du sous-formulaire "Employés". La source de données à indiquer est la table que nous avons précédemment appelé entrh.
Elle contient les colonnes:
   Colonne   |     Type      | Modificateurs                    
-------------+---------------+---------------
 matricule   | integer       | non NULL
 nom         | character(50) |
 adresse     | character(50) |
 code_postal | character(5)  |
 cp_seq      | smallint      |
 naissance   | date          |
 sexe        | character(1)  |
 service     | character(2)  |
Les colonnes code_postal et cp_seq constituent une clé étrangère (foreign key) établissant une relation d'intégrité référentielle avec une table des codes postaux (frcp dans notre base de données) contenant le nom des localités:
    Colonne    |     Type      | Modificateurs
---------------+---------------+---------------
 code_postal   | character(5)  | non NULL
 cp_seq        | smallint      | non NULL
 localite_nom  | character(50) |
 code_departem | character(2)  |
De même la colonne service est définie comme une clé étrangère pointant vers une table service contenant le nom du service:
   Colonne    |     Type      | Modificateurs
--------------+---------------+---------------
 service_id   | character(2)  | non NULL
 dénomination | character(25) |

Le lien entre les formulaires  "Employés" et "Sélection" sera basé sur la colonne matricule:


Le nom du département se trouve dans une table nommée frdepartem:
   Colonne    |     Type      | Modificateurs
--------------+---------------+---------------
 departem_id  | character(2)  | non NULL
 departem_nom | character(30) |
 code_region  | character(2)  |
Pour avoir la possibilité de déduire le nom du département sur base du code postal, nous pouvons au niveau de PostgreSQL définir une vue liant les tables frcp et frdepartem:
CREATE VIEW cpdep AS
SELECT     
    frcp.code_postal,
    frcp.cp_seq,
    frcp.localite_nom,
    frdepartem.departem_nom
FROM frcp frcp, frdepartem frdepartem
WHERE (frcp.code_departem = frdepartem.departem_id)
; 
GRANT SELECT ON cpdep TO PUBLIC
On peut aussi créer une requête dans libreoffice base.
Pour libreoffice, cette vue apparaît comme une table que nous allons désigner comme source de données du sous-formulaire "Département" qui sera lié à "Employé" via code_postal et cp_seq:


Pour le reste nous avons créé la table paie (et donné les droits adéquats):
CREATE TABLE paie
(matricule INTEGER,
 mois CHAR(6),
 seq SMALLINT,
 code CHAR(2),
 montant NUMERIC(13,2),
 PRIMARY KEY (matricule,mois,seq),
 FOREIGN KEY (matricule) REFERENCES entrh)
;
GRANT ALL ON paie TO gestionrh
;
Cette table est liée dans une relation d'intégrité référentielle avec entrh, de sorte qu'un employé ne peut pas être supprimé s'il existe un paiement le concernant.
Nous avons aussi créé la vue salaire:
CREATE VIEW salaire
AS
SELECT matricule, mois, sum(montant) AS montant
FROM paie
GROUP BY matricule, mois
;
GRANT SELECT ON salaire TO gestionrh
;
Cette vue sera notre source de données ordonnée suivant le mois pour le sous-formulaire "Salaire", la laison avec "Employés" étant basée sur la colonne matricule:


Enfin pour le sous-formulaire "Détails", on établit les propriétés comme suit:



Mise en place des éléments du formulaire.
Passons à l'étape de la mise en place des différents éléments du formulaire.
Choisissons en premier un arrière-plan en passant par le menu  Format -> Page:


soit une couleur, soit une image:


Reste à disposer les différents champs.
Avant de procéder, veillons à ce que "Sélection" soit sélectionné au niveau du navigateur de formulaires.
Dans la barre d'outils verticale de gauche, choisissons "Champ d'étiquette":


Après que nous ayons dimensionné cet élément, cliquons droit pour afficher son menu contextuel:


Via l'élément du menu appelé "Contrôle" nous accédons à la fenêtre des propriétés:


Modifions le nom en "lblmatricule" et la valeur de l'étiquette en "Matricule".
Sélectionnons maintenant "Champ formaté" (toujours dans la barre d'outils verticale):


Nous plaçons ce champ en dessous du champ d'étiquette précédent et dans la fenêtre des propriétés, après avoir renommer ce champ, nous appuyons sur les 3 petits points qui permettent de lui attribuer le champ d'étiquette (label) précédent:


Nous mettons également la Séquence d'activation à 1:


Comme champ de données, nous prenons évidemment "matricule":


Le menu contextuel obtenu lorsque les deux éléments sont sélectionnés nous offre la possibilité de les grouper:


Après avoir sélectionné "Employés" dans le navigateur de formulaires, déposons et déployons un bouton issu de la barre d'outils gauche:

à droite du champ formaté fmtmatricule. Dans la fenêtre propriétés, onglet général, étiquette nous remplaçons la valeur standard "Bouton"  par "OK": 


C'est ce mot qui apparaîtra sur le bouton.
D'autre part, nous attribuons à ce bouton l'action "Rafraîchir le formulaire":


Procédant comme pour le matricule, plaçons sur le formulaire un champ de type zone de texte, surmonté de son étiquette, qui affichera le nom de l'employé.

Rôle du focus.
Après avoir enregistré le formulaire, désactivons le mode ébauche:


Le nom correspondant au matricule qui est inscrit dans la rangée unique de notre table sélection apparaît alors à l'écran:


Dès l'instant où nous modifions le matricule, la petite disquette de la barre d'outils horizontale prend des couleurs: 


signe que le matricule à l'écran n'est plus celui de la base de données.
Frappons la touche "Tabulation": le focus se déplace sur le bouton (ce qui est matérialisé par le rectangle en points tillés autour du mot OK) et la petite disquette perd ses couleurs:


il y a eu écriture du matricule 1007 dans la table sélection. Cela ne fonctionne pas si le bouton appartient au formulaire "Sélection". Autrement dit, l'opération d'écriture se déclenche lorsque le focus quitte le formulaire "Sélection" .
Si nous appuyons maintenant sur le bouton (par exemple en frappant la touche "Enter"), le nom correspondant au matricule 1007 s'affiche:


Nous pouvons aussi directement appuyer sur le bouton à l'aide de la souris (sans y amener le focus à l'aide la touche "tabulation"). Dans ce cas, le fait de cliquer met le focus sur le bouton, ce qui provoque l'écriture, celle-ci étant immédiatement suivie du rafraîchissement (action liée au bouton).
(EDIT: voir dans ce billet comment rafraîchir sans utiliser le bouton OK) 
Cliquer sur le bouton y met le focus à condition que dans les propriétés du bouton l'option (par défaut) 'Focus sur clic' ait été conservée:


Dans le cas contraire, cliquer sur le bouton sans toucher au clavier après saisie du matricule, ne produit aucun effet. Mais comment alors parvenir à ses fins sans plus toucher au clavier? Simplement il suffit avant de cliquer de déposer le curseur dans le champ nom, déclenchant ainsi l'écriture du matricule. Mais cette manipulation n'est évidemment jamais nécessaire puisque par défaut 'Focus sur clic = Oui'. 

Afficher la localité à l'aide de macros.
Continuons maintenant à disposer les différents éléments constitutifs du sous-formulaire "Employés": 
champ de date pour la date de naissance, accessible en cliquant sur "Contrôles supplémentaires"


boutons radio pour le sexe
zone de liste pour le service
adresse, code postal ...
(Pour le détail des manipulations voir ce billet.)
Par la magie de la zone de liste "service", le nom du service apparaît en clair à l'écran et le code derrière (qui est la seule information présente dans entrh) est transparent pour l'utilisateur.
Nous aimerions procéder de même pour la localité de résidence de l'employé et rendre transparent le numéro de séquence (cp_seq) qui associé au code postal pointe vers une localité de frcp. Mais nous allons nous heurter à un gros problème: comment limiter la liste aux localités dont le code postal est celui affiché? Pour parvenir à nos fins, nous allons devoir faire appel à une macro.
Mais tout d'abord, afin d'éliminer un problème  qui se présentera lors de l'utilisation de la macro, définissons une vue:
CREATE VIEW frcpn AS
SELECT frcp.code_postal::numeric AS code_postal,
frcp.cp_seq,
frcp.localite_nom,
frcp.code_departem
FROM frcp
;
GRANT SELECT ON frcpn TO PUBLIC
;
La seule différence entre la vue frcpn et la table originale est que le code postal est maintenant une grandeur de type numérique.
Notre zone de liste sera basée sur cette vue:


Le champ affiché est le nom de la localité:


Et les deux champs qui doivent coïncider sont les deux champs cp_seq:


Nous appellerons cette zone de liste lboxlocalite:


Le contenu de la liste est basé sur une instruction sql:


à laquelle on voudrait ajouter une clause WHERE via l'appel à une macro.
Les macros que nous allons utiliser se trouvent dans un fichier dont voici le contenu:

option explicit
dim  LstLocalite AS Object
'*******************************
sub MajListe
'*******************************
DIM var_code_postal
LstLocalite = Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("lboxlocalite")
var_code_postal = Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("txtcode_postal").TEXT
LstLocalite.ListSource() = array("SELECT localite_nom, cp_seq FROM public.frcpn AS frcpn WHERE code_postal =" & var_code_postal)
LstLocalite.refresh 
end sub
'*******************************
sub Actualisation
'*******************************
dim ExoTrav
MajListe  
ExoTrav= ExoRechercheDansTableau(LstLocalite.ValueItemList, LstLocalite.boundField.Value)
if ExoTrav <> "#N/A" then
LstLocalite.SelectedItems = array(ExoTrav)
else
LstLocalite.SelectedItems = array(0)
end if
end sub
'**************************************************
Function ExoRechercheDansTableau(ExoTablo, ExoRech)
'**************************************************
dim i as integer
ExoRechercheDansTableau = "#N/A"
for i = lbound(ExoTablo) to ubound(ExoTablo)
if ExoTablo(i)= ExoRech then
ExoRechercheDansTableau = i
exit for
end if
next i
end function

lbxlocalite correspond au nom de la zone de liste "Localité" et txtcode_postal au nom du champ "Code postal":


Pour intégrer ces macros à notre fichier odb, il faut passer par Outils->Macros-> Gérer les macros:


Sélectionnant bd01.odb (notre fichier odb), on appuie sur "Nouveau":


Après avoir valider "Module 1" dans la fenêtre qui surgit, on atterrit dans un éditeur et on y remplace le texte qui y figure:


par celui des 3 macros ci-dessus.
Assignons la macro "MajListe" à l'événement "Modifié" du champ txtcode_postal. Pour ce faire, on procède via la fenêtre des propriétés du champ, onglet Événement:


Un appui sur les 3 petits points de droite, nous permet d'arriver facilement sur le sélecteur de macro:


De même on assigne la macro "Actualisation" à l'événement "Après le changement d'enregistrement" du formulaire "Employés".
Vérifions si tout est OK:


C'est parfait: le numéro de séquence cp_seq est maintenant transparent pour l'utilisateur du formulaire. Le formulaire est donc considérablement simplifié puisqu'on ne doit plus afficher à l'intention de l'utilisateur une liste des numéros de séquence possibles avec les localités correspondantes. De plus, l'utilisateur ne doit plus encoder un numéro de séquence, mais cliquer sur une localité dans une liste déroulante. Pour éviter les avertissements relatifs à l'utilisation de macros, allons dans Outils -> Options -> Sécurité -> Sécurité des macros, onglet "Sources de confiance" et ajoutons le chemin vers notre fichier odb:



Le formulaire final.
Reste à compléter les sous-formulaires Département, Salaire et Détails.
Voici un exemple de ce à quoi on peut arriver:


(Nous avons remplacé la zone de saisie du matricule par une "boite combinée".)

jeudi 20 octobre 2011

rpmerizor

rpmerizor est un outil qui permet de générer très facilement un rpm lorsqu'on dispose des fichiers que le paquet est censé installer.
On le trouve ici.
Pour montrer comment cet outil peut être utilisé, nous allons revenir sur le cas traité dans le billet précédent.
Nous avons téléchargé le paquet libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb, puis nous en avons extrait le contenu...
[toto@rigel work]$ ar xv libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
[toto@rigel work]$ tar x --lzma -f data.tar.lzma
[toto@rigel work]$ tar xzf control.tar.gz
et effectué quelques petites manipulations:
[toto@rigel work]$ mv usr/lib usr/lib64
[toto@rigel work]$ mkdir work-b
[toto@rigel work]$ mv usr work-b
Et voilà, nous sommes prêts à utiliser rpmerizor. Après le lancement de la commande, il nous restera à fournir quelques informations (en bleu dans ce qui suit) dont certaines proviennent du fichier control du paquet debian (vive le copier-coller):
[toto@rigel work]$ rpmerizor -name libreoffice-sdbc-postgresql -version 0.8 --rootdir work-b
name: libreoffice-sdbc-postgresql
version: 0.8
A brief one line description.
SUMMARY> LibreOffice extension for PostgreSQL SDBC driver
The integer number of times you have built this rpm.
RELEASE> 0
toplevel_group/subclass (no biggie either way).
GROUP> Converted/misc
A sales pitch for the package.  A blank line means you are done.
DESCRIPTION> LibreOffice is a full-featured office productivity suite that provides
DESCRIPTION> a near drop-in replacement for Microsoft(R) Office.
DESCRIPTION> .
DESCRIPTION> The PostgreSQL SDBC Driver allows one to use the PostgreSQL database from
DESCRIPTION> LibreOffice without any wrapper layer such as ODBC or JDBC.
DESCRIPTION>
mkdir /home/toto/rpmbuild
mkdir /home/toto/rpmbuild/SPECS
write spec file on /home/toto/rpmbuild/SPECS/libreoffice-sdbc-postgresql-0.8.spec
Exécution_de(%prep): /bin/sh -e /var/tmp/rpm-tmp.spL2j6
+ umask 022
+ cd /home/toto/rpmbuild/BUILD
+ ln -s /home/toto/work/work-b /tmp/rpmerizor_buildroot
+ exit 0
Processing files: libreoffice-sdbc-postgresql-0.8-0.x86_64
Provides: config(libreoffice-sdbc-postgresql) = 0.8-0
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: /bin/sh
attention: Ne peut canoniser le nom d'hôte: rigel
Ecrit: /home/toto/rpmbuild/RPMS/x86_64/libreoffice-sdbc-postgresql-0.8-0.x86_64.rpm
Exécution_de(%clean): /bin/sh -e /var/tmp/rpm-tmp.tMJEcA
+ umask 022
+ cd /home/toto/rpmbuild/BUILD
+ rm /tmp/rpmerizor_buildroot
+ exit 0
package can be found on /home/toto/rpmbuild/RPMS
[toto@rigel work]$
Le produit a créé une arborescence rpmbuild standard:
Nous constatons qu'il a aussi créé un fichier spec que nous pouvons éditer pour y ajouter par exemple quelques dépendances requises:
Summary: LibreOffice extension for PostgreSQL SDBC driver
Name: %{name}
Version: %{version}
Release: 2
License: GPL
Group: Converted/misc

Requires: libreoffice-ure >= 3.3.3 libreoffice-core

%description
LibreOffice is a full-featured office productivity suite that provides
a near drop-in replacement for Microsoft(R) Office.
.
The PostgreSQL SDBC Driver allows one to use the PostgreSQL database from
LibreOffice without any wrapper layer such as ODBC or JDBC.
On peut alors construire un nouvel rpm tenant compte du spec modifié:
[toto@rigel ~]$ rpmbuild -bb --buildroot=/tmp/rpmerizor_buildroot ~/rpmbuild/SPECS/libreoffice-sdbc-postgresql-0.8.spec
Exécution_de(%prep): /bin/sh -e /var/tmp/rpm-tmp.NxDuhU
+ umask 022
+ cd /home/toto/rpmbuild/BUILD
+ ln -s /home/toto/work/work-b /tmp/rpmerizor_buildroot
+ exit 0
Processing files: libreoffice-sdbc-postgresql-0.8-0.x86_64
Provides: config(libreoffice-sdbc-postgresql) = 0.8-0
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: /bin/sh attention: Ne peut canoniser le nom d'hôte: rigel Ecrit: /home/toto/rpmbuild/RPMS/x86_64/libreoffice-sdbc-postgresql-0.8-0.x86_64.rpm Exécution_de(%clean): /bin/sh -e /var/tmp/rpm-tmp.4M2L2S + umask 022 + cd /home/toto/rpmbuild/BUILD + rm /tmp/rpmerizor_buildroot + exit 0
Cela n'apparait pas dans l'output, mais les dépendances requises ont bien été ajoutées au rpm
[toto@rigel ~]$ rpm -qp --requires ~/rpmbuild/RPMS/x86_64/libreoffice-sdbc-postgresql-0.8-0.x86_64.rpm
/bin/sh
config(libreoffice-sdbc-postgresql) = 0.8-0
libreoffice-core
libreoffice-ure >= 3.3.3
rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1

lundi 17 octobre 2011

Pilote postgresql sdbc: version 0.8

Ubuntu 11.10 est sorti et bonne nouvelle: il vient avec une toute nouvelle version, la version 0.8, du pilote libreoffice postgresql sdbc. Cette version remplace la version 0.7.6b qui avait un gros problème: elle permettait uniquement un accès en lecture seule. La nouvelle version est elle entièrement fonctionnelle. Il n'est donc plus nécessaire de retourner à OpenOffice 3.2 et à la version 0.7.6a du pilote (voir OOo base: retour vers le futur).
A nous les joies de LibreOffice 3.4. Pour y accéder à PostgreSQL via le pilote sdbc, il suffit d'installer le paquet libreoffice-sdbc-postgresql.
Il n'existe pas actuellement de paquet rpm pour la version 0.8 de ce pilote.
Pour une utilisation dans une distribution à base de rpm, on peut procéder comme ceci.
D'abord trouver et télécharger le fichier qui convient à son architecture, par exemple:
libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb.
Ensuite placer ce fichier dans un dossier work.
Puis:
[toto@rigel work]$ ar xv libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
[toto@rigel work]$ tar x --lzma -f data.tar.lzma
L'extraction du tar.lzma nous donne un répertoire usr:


Pour plus de facilités plaçons une copie du répertoire postgresql-sbbc-0.8.0 dans le répertoire work, copie que nous allons utiliser pour la constitution d'une archive zip.
[toto@rigel work]$ cp -r usr/lib/libreoffice/share/extensions/postgresql-sdbc-0.8.0/ .
[toto@rigel work]$ zip -r postgresql-sdbc-0.8.0.zip postgresql-sdbc-0.8.0/
  adding: postgresql-sdbc-0.8.0/ (stored 0%)
  adding: postgresql-sdbc-0.8.0/postgresql-sdbc.unorc (stored 0%)
  adding: postgresql-sdbc-0.8.0/description.xml (deflated 56%)
  adding: postgresql-sdbc-0.8.0/META-INF/ (stored 0%)
  adding: postgresql-sdbc-0.8.0/META-INF/manifest.xml (deflated 62%)
  adding: postgresql-sdbc-0.8.0/postgresql-sdbc-impl.uno.so (deflated 69%)
  adding: postgresql-sdbc-0.8.0/postgresql.xcu (deflated 64%)
  adding: postgresql-sdbc-0.8.0/postgresql-sdbc.uno.so (deflated 68%)
  adding: postgresql-sdbc-0.8.0/description/ (stored 0%)
  adding: postgresql-sdbc-0.8.0/description/description_en-US.txt (deflated 28%)
Nous disposons maintenant d'un fichier zip que nous pouvons ajouter en tant qu'extension à LibreOffice via le gestionnaire des extensions.
Avant de procéder, il convient toutefois d'effacer toute trace du pilote précédent.
[toto@rigel work]$ unopkg remove postgresql-sdbc-0.7.6b.zip
Si cette commande échoue:
[toto@rigel work]$ rm -rf ~/.libreoffice/3/user/uno_packages/
Dans le cas où l'installation du pilote précédent a été effectuée en root pour l'ensemble des utilisateurs:
[root@rigel work]# unopkg remove --shared postgresql-sdbc-0.7.6b
Il reste éventuellement à désinstaller le paquet qui a fournit l'extension.
Au lieu d'utiliser le gestionnaire des extensions, nous pouvons installer la nouvelle extension comme suit:
[root@rigel work]# cp -r postgresql-sdbc-0.8.0 /usr/lib64/libreoffice/share/extensions/
[root@rigel work]# unopkg add -v --shared /usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.8.0/
Évidemment dans ce cas, il n'était nul besoin du fichier zip.
Pour ceux que la copie dans /usr/lib64/libreoffice/share/extensions/ font hurler, il reste une alternative: construire un paquet rpm, ce qui peut être fait relativement aisément à l'aide de rpmerizor.
Une autre solution consiste à utiliser alien pour obtenir un rpm à partir du deb.
Cependant si à partir d'un paquet deb 64 bits par exemple, nous souhaitons une installation dans /usr/lib64 et non dans /usr/lib, il y a quelques manipulations à effectuer.
Procédons depuis Ubuntu.
toto@rigel:~work$ apt-get download libreoffice-sdbc-postgresql
Réception de : 1 Téléchargement de libreoffice-sdbc-postgresql 1:0.8.0+LibO3.4.3-3ubuntu2 [211 kB]
toto@rigel:~work$ ar xv libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
toto@rigel:~work$ tar xv --lzma -f data.tar.lzma
toto@rigel:~work$ tar xzvf control.tar.gz
./
./postinst
./preinst
./md5sums
./control
En plus du tar.lzma, nous avons cette fois extrait le tar.gz.
Remplaçons /usr/lib par /usr/lib64:
toto@rigel:~work$ mv usr/lib usr/lib64
toto@rigel:~work$ sed -i.old 's/lib/lib64/' md5sums
Reconstruisons le paquet deb:
toto@rigel:~/Téléchargements/work$ mkdir -p work-b/DEBIAN
toto@rigel:~/Téléchargements/work$ mv usr work-b
toto@rigel:~/Téléchargements/work$ mv control md5sums work-b/DEBIAN
toto@rigel:~/Téléchargements/work$ sudo dpkg -b work-b libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
[sudo] password for toto:
dpkg-deb : avertissement : « usr/DEBIAN/control » contient le champ « Original-Maintainer » défini par l'utilisateur
dpkg-deb : avertissement : 1 avertissement ignoré sur le(s) fichier(s) « control »
dpkg-deb : construction du paquet « libreoffice-sdbc-postgresql » dans « libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb ».
Le paquet deb ainsi obtenu n'est pas destiné à être utilisé dans Ubuntu, mais bien à être transformé en rpm avec alien:
toto@rigel:~work$ sudo alien --to-rpm libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
[sudo] password for toto:
libreoffice-sdbc-postgresql-0.8.0+LibO3.4.3-4.x86_64.rpm generated
Ce paquet peut maintenant être installé dans une distribution à base de rpm.
Avec Fedora 15 en tout cas, tout se passe bien et le pilote fonctionne avec LibreOffice 3.3.3.

mardi 11 octobre 2011

Deuxième session

Utilisons le menu de notre distribution préférée pour changer d'utilisateur.
Ça fonctionne: c'est merveilleux! En fait nous avons ouvert une deuxième session graphique en parallèle avec la première qui est encore bien présente.
Comment faire pour y revenir?
Examinons la situation:


Nous constatons que la première session est associée au terminal virtuel tty7 et la deuxième à tty8.
Nous pouvons donc basculer entre les deux sessions  à l'aide de CTRL-ALT-F7 et CTRL-ALT-8.
Il arrive cependant que l'item du menu 'Changer d'utilisateur' soit inopérant et ceci principalement en cas d'utilisation d'un autre bureau que celui par défaut. Plutôt que de se casser la tête pour y remédier, il est préférable de procéder manuellement.
Basculons vers tty2 (CTRL-ALT-F2) pour nous y connecter en tant que l'utilisateur qui sera propriétaire de la future deuxième session graphique.
Ensuite nous lançons la commande startx et recevons en retour une flopée de message d'erreurs, parmi lesquels celui-ci (qui n'est pas dénué de sens):
Fatal server error:
Server is already active for display 0
If this server is no longer running, remove /tmp/.X0-lock
and start again.
Evidemment, le serveur X qui va gérer la nouvelle session doit être démarré pour l'affichage (display) 1 et non pas 0 (comme on peut le constater ci-dessus sur l'ouput de la commande ps).
Recommençons cette fois avec la commande:
startx -- :1
Bingo: ça fonctionne. Tout baigne, sauf que cette fois on ne passe pas par la case 'display manager' (normal: on est déjà connecté) qui permet de choisir le type de session. Donc on se retrouve avec le bureau par défaut, ce qui n'est pas nécessairement notre désir le plus profond.
Certaines distributions comme Fedora (mais pas Ubuntu)  regardent dans le dossier /etc/sysconfig pour voir si les utilisateurs ne préfèrent pas un autre bureau que celui par défaut. Dans ce cas /etc/sysconfig contient un fichier desktop avec une ligne du genre:
DESKTOP=Bureau préféré.
Et bien vérifions:
[root@rigel ~]# cd /etc/sysconfig
[root@rigel sysconfig]# grep '^DESKTOP' desktop
grep: desktop: Aucun fichier ou dossier de ce type
[root@rigel sysconfig]#
Le fichier n'existe pas.
On peut aussi avoir ceci:
[root@rigel sysconfig]# grep '^DESKTOP' desktop
[root@rigel sysconfig]#
Le fichier existe mais il ne contient pas la ligne qui convient.
[root@rigel sysconfig]# echo 'DESKTOP=KDE' >> desktop
crée le fichier ad hoc ou si desktop existe déjà, y ajoute la ligne qui convient (si le bureau préféré est KDE).
Une autre possibilité est:
[root@rigel sysconfig]# grep '^DESKTOP' desktop
DESKTOP=GNOME
[root@rigel sysconfig]#
La définition du bureau préféré est bien présente, mais elle ne correspond pas à ce que nous voulons (dans l'hypothèse où notre bureau préféré est KDE).
Correction:
[root@rigel sysconfig]# sed -r -i.old 's/^(DESKTOP).*/\1=KDE/' desktop
Nous disposons donc maintenant d'un fichier desktop par la grâce duquel le bureau lancé par startx sera le bureau préféré de l'ensemble des utilisateurs.
Cependant, il nous est encore loisible de définir le bureau préféré d'un utilisateur donné. Il existe différentes façons de procéder dépendant de la distribution. Dans le cas de Fedora (et d'autres distributions), il suffit de créer un fichier ~/.Xclients:
[toto@rigel ~]$ echo 'startkde' > ~/.Xclients
[toto@rigel ~]$ chmod +x ~/.Xclients
('startkde' c'est bien sûr si le bureau désiré est KDE. Pour gnome mettre 'gnome-session')
A l'exécution de startx par un utilisateur, le système démarre le client préféré de cet utilisateur, à défaut le client préféré de l'ensemble des utilisateurs et enfin en l’absence de client préféré, le client par défaut de la distribution, suivant ce schéma (Fedora), réalisé avec kivio:


Examinons la situation dans le cas où une deuxième session a été lancée avec startx:

Le pid a été ajouté à l'output, de manière à pouvoir entrer plus dans les détails:
[toto@rigel ~]$  pstree -a 5360
bash
  └─startx /usr/bin/startx -- :1
      └─xinit /etc/X11/xinit/xinitrc -- /usr/bin/X :1 -auth /home/toto/.serverauth.6327
          ├─X :1 -auth /home/toto/.serverauth.6327
          └─ck-xinit-sessio /usr/bin/ssh-agent /home/toto/.Xclients
              └─sh /home/toto/.Xclients
                  ├─ssh-agent /home/toto/.Xclients
                  └─startkde /usr/bin/startkde
                      └─kwrapper4 ksmserver

xinit est appelé par startx qui lui intime (en l'absence du fichier ~/.xinitrc) d'exécuter le script /etc/X11/xinit/xinitrc aux fins de démarrer le programme client.
Si aucun script ne lui est désigné (ce n'est pas le cas s'il est appelé par startx), xinit recherche l'existence du fichier ~/.xinitrc. En l'absence de ce dernier, le client par défaut sera un xterm. Le serveur par défaut est X.
Ainsi la commande
xinit -- :1
a un effet plutôt surprenant: on bascule vers un écran sans gestionnaire de fenêtres, sans bureau, mais contenant un xterm (avec un shell bash). Dans cet xterm, on peut taper la commande startkde (par exemple), et voilà notre deuxième session sur les rails.
Une variante de la commande précédente est:
xinit -e 'startkde' -- :1
avec laquelle la deuxième session se lance sans que l'on ait plus à taper quoi que ce soit.
Cette dernière commande peut avoir une application assez amusante. Considérons que nous sommes aux commandes d'un système dans lequel X n'est pas démarré (ce qui correspond au niveau d'exécution 3 pour un grand nombre de distributions). La commande:
xinit -e 'gnome-system-monitor'
nous conduira vers un écran affichant graphiquement les performances du système.
On peut même lancer un éditeur graphique:
xinit -e 'gedit'
Mais tout ceci nous éloigne du sujet.
Pour le fun, signalons qu'il est possible de lancer une session graphique sans utilisation de xinit. Voici comment.
Depuis tty2, éventuellement en root si problème de droit, lancer X:
X :1
Depuis tty3:
xterm -display :1
Il reste à basculer vers le terminal virtuel où se trouve le xterm et y taper la commande adéquate (par exemple startkde).

Avec Ubuntu 11.04, il semblerait qu'il soit impossible de démarrer une session Unity sans passer par le display manager gdm.
Pour démarrer une session avec startx il convient donc de définir un bureau préféré (différent du bureau par défaut, à savoir Unity) en créant un fichier ~/.xsession contenant
gnome-session --session=classic-gnome (pour une session gnome normale)
startkde (pour kde)
Avec Ubuntu 11.10, startx peut maintenant ouvrir une session Unity, c'est la session par défaut et il n'est nul besoin d'un fichier ~/.xsession. Indiquons quand même que la commande qui serait à utiliser est simplement
gnome-session.
Il est également possible d'installer gnome shell tout en conservant un Unity fonctionnel. Pour que startx ouvre une session gnome shell, la commande est cette fois
gnome-session --session=gnome