fontypython-0.5/0000775000175000017500000000000013212250216013671 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/0000775000175000017500000000000013212250216017663 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/0000775000175000017500000000000013212250216021122 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/it/0000775000175000017500000000000013212250216021536 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/it/LC_MESSAGES/0000775000175000017500000000000013212250216023323 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/it/LC_MESSAGES/all.mo0000664000175000017500000002341213212036006024431 0ustar donndonn00000000000000^ $:Ma2y . :? "z ?   ! *1 \ n ~ +  #  * A  '   #8 \ e e3   ; *@Rc0kn   2/ I$W|  -   5-c!sw &0 3 H@I+4QAh8(:0k'$Lfv<  AL5_C#3 1"= `; %(,U1nvE@L #. n"6 5:J ]Ag%8 ^ k 9  +  !! 4!"B!%e! !+!!;!""&5" \"i" #)#6# $*$8;$Ut$$[$?%#U%y%%M%(%#&8&RL& &@&&31V5TDS6N(#U%],/8-F+)I>7\ ? @<B!OJ 0$&QH"=K AZ[^;PMWR 9XGYCL4'. *2E: (Also check your file permissions.) * indicates installed pogs%s already exists.%s has been purged.%s has not been purged.%s takes two arguments: SOURCE(folder) TARGET(pog)&About&Clear ENTIRE selection&Exit&Help&Select ALL the source fonts&Selection&Settings Ctrl+S(%s) cannot be found. Try -l to see the names.(%s) skipped. I can't display this name under your locale.(%s) skipped. It's an invalid pog.A Pog with no name won't be created, however it was a good try!Are you sure?Bad voodoo error. I give up.Cannot delete the Pog.%sChange settingsChecking fonts, this could take some time.Choose some fontsClear selectionClear the selection completely.Close the appCopying fonts from %(source)s to %(target)sCould not open (%s).Could not write to the config file.Creates a new, empty PogCreating a new pog: %sDo you want to purge %s? Purging means all the fonts in the pog that are not pointing to actual files will be removed from this pog.ErrorFont may be bad and it cannot be drawn.Fonty PythonFonty Python version %sFonty Python, um ... crashed.Fonty Python: bring out your fonts!H&elp F1I am sorry, but Unicode is not supported by this installation of wxPython. Fonty Python relies on Unicode and will simply not work without it. Please fetch and install the Unicode version of python-wxgtk.I can't decode your argument(s). Please check your LANG variable. Also, don't paste text, type it in.I can't find %sI could not find any bad fonts.I have placed %(count)s fonts from %(folder)s into %(pog)s.Include sub-folders.Installing (%s)Jump the lazy dog foxListing %d pog(s)Looking in %s...New PogNo config file found, creating it with defaults.Not a single font in this pog could be installed. The original font folder has probably moved or been renamed.Not a single font in this pog could be uninstalled. None of the fonts were in your fonts folder, please check your home .fonts (with a dot in front) folder for broken links. The pog has been marked as "not installed".Oh boy...Page length:Pog cannot be written to. Check your filesystem.%sPog is already installed.Pog is empty.Pog is invalid, please hand-edit it.Pog is not installed.Point size:Purge font?Remove %s, are you sure?Remove all ghost fonts from the selected Pog.Removing (%s)SORRY: UNICODE MUST BE SUPPORTEDSample text:Select ABSOLUTELY ALL the fonts in the chosen source.Selected fonts are now in %s.Selected fonts have been removed.SettingsSome fonts could not be uninstalled. Please check your home .fonts (with a dot in front) folder for broken links.%sSome fonts did not install. Perhaps the original fonts folder has moved or been renamed. You should purge or hand-edit.Sorry, (%s) does not exist. Try --listSorry, can't find (%s). Try -l to see the names.Starting in %s:Target PogsThe fonts from %(folder)s are *already* in %(pog)s.The fontypython config file is damaged. Please remove it and start againThe process is complete.The target pog (%s) is currently installed, you can't use it as a target.There are no fonts in here.There are no fonts to see here, move along.There are no pogs available.There is no such item.There was an error writing the pog to disk. Nothing has been doneThis folder has no fonts in it.This font is in %sThis pog is emptyUnicode problem. Font may be bad and it cannot be drawn.WarningYou cannot use a folder as the target argument. Try --helpYour pogs are the same! Try -eProject-Id-Version: Fontypython 0.3.0 Report-Msgid-Bugs-To: POT-Creation-Date: 2017-12-06 20:46+0200 PO-Revision-Date: 2009-07-07 12:35+0100 Last-Translator: Pietro Battiston Language-Team: Italian Translation Project Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Poedit-Language: Italian X-Poedit-Country: ITALY (Controlla anche i permessi dei file.)* indica i pog installati%s esiste già.%s è stato epurato.%s non è stato epurato.%s richiede due argomenti: SORGENTE(cartella) OBIETTIVO(pog)I&nformazioni su...&Ripulisci TUTTA la selezione&EsciA&iuto&Seleziona TUTTI i font sorgente&SelezionePreferen&ze Ctrl+SImpossibile trovare (%s). Prova -l per vedere i nomi.(%s) skipped. Non riesco a mostrarne il nome con la locale attuale.(%s) saltato. È un pog non valido.Buon tentativo... ma non creerò un pog senza nome!Sei sicuro?Errore voodoo maligno. Mi arrendo.Impossibile cancellare il pog.%sCambia le preferenzeSto controllando i font: potrebbe prendere un po' di tempo.Scegli i fontDeseleziona tuttoRipulisci completamente la selezione.Chiudi il programmaCopia di font da %(source)s a %(target)sImpossibile aprire (%s).Impossibile modificare il file di configurazione.Crea un nuovo pog vuotoCreo un nuovo pog: %sVuoi epurare %s? Epurare significa che tutti i font del pog che non puntano a file effettivi saranno rimossi dal pog.ErroreIl font potrebbe essere corrotto, non è possibile raffigurarlo.Fonty PythonFonty Python, versione %sFonty Python... ehm... ha crashato.Fonty Python: porta i tuoi font allo scoperto!A&iuto F1Spiacente, questa installazione di wxpython non supporta l'Unicode. Fonty Python necessità di Unicode e semplicemente non può funzionare senza. Per favore procurati ed installa la versione Unicode di python-wxgtk.Impossibile decifrare il/gli argomento/i. Verificare la variabile LANG. Attenzione: non incollare testo, ma digitarlo direttamente.Impossibile trovare %sNon ho trovato alcun font dannoso.Ho sistemato %(count)s fonts da %(folder)s in %(pog)s.Includi sottocartelle.Installo (%s)Ma la volpe col suo balzo ha raggiunto il quieto fidoLista di %d pogControllo in %s...Nuovo pogNon ho trovato il file di configurazione, ne ricreo uno standard.Non è stato possibile installare neanche un font di questo pog. La cartella di origine dei font è stata probabilmente spostata o rinominata.Non è stato possibile disinstallare neanche un font di questo pog. Nessuno di questi font era nella tua cartella dei font, per favore controlla eventuali link interrotti nella cartella .fonts (con un punto all'inizio) all'interno della tua home. Il pog è stato segnato come "non installato".O cribbio...Lunghezza della pagina:Impossibile modificare il pog. Controlla il filesystem.%sPog già installato.Pog vuoto.Il pog è invalido, modificalo manualmente.Pog non installato.Dimensione (in punti):Epurare font?Sei sicuro di voler cancellare %s?Rimuovi fantasmi dal pog selezionato.Rimuovo (%s)SPIACENTE: L'UNICODE DEVE ESSERE SUPPORTATOTesto di esempio:Seleziona ASSOLUTAMENTE TUTTI i font nella sorgente scelta.I font selezionati sono ora in %s.I font selezionati sono stati rimossi.ImpostazioniImpossibile disinstallare alcuni font. Per favore controlla eventuali link interrotti nella cartella .fonts (con un punto all'inizio) all'interno della tua home.%sNon è stato possibile installare alcuni font. Probabilmente la cartella di origine dei font è stata rimossa o rinominata. Doversti epurarli o modificare manualmente il pog.Spiacente, (%s) non esiste. Prova --list.Spiacente, non trovo (%s). Prova -l per vedere i nomi.Parto in %s:Pog destinazioneI font della cartella %(folder)s sono *già* in %(pog)s.Il file di configurazione fontypython è danneggiato. Per favore rimuovilo e riprova.Il processo è completo.Il pog destinazione (%s) è attualmente installato, non puoi utilizzarlo come destinazione.Non ci sono font qui.Qui non c'è nessun font da vedere.Nessun pog disponibile.Non c'è un tale elemento.C'è stato un errore nella memorizzazione del file. Non è stato fatto nulla.Questa cartella non contiene alcun font.Questo font è in %sQuesto pog è vuotoProblema unicode. Il font potrebbe essere corrotto, non è possibile raffigurarlo.AttenzioneNon puoi utilizzare una cartella come destinazione. Prova --helpI pog sono lo stesso! Prova -efontypython-0.5/fontypythonmodules/locale/de/0000775000175000017500000000000013212250216021512 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/de/LC_MESSAGES/0000775000175000017500000000000013212250216023277 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/de/LC_MESSAGES/all.mo0000664000175000017500000002470513212036006024413 0ustar donndonn00000000000000b,<H$In2  4 : @ ] h .y : " ? F T q  *     + A #V z  0 +6 'b   #  e .>Z;z0nM  2 $- C O[-t   5!2Ts]w&I0p 3H:IS+AB[8:$_B~)"$8R1n (H^_-I6G%f0 "5X/qqDxD #'.K za 9"8\ 7 " G, t  " &"N4"" "8""##"$#7G# #5# #8#/ $$:$_$h$2%-%M&N&]&8m&_&'V'#s'0'''H'HA(2(!((U(G)IO)+)>L7TM91 `-/Jb\0  GK<ROQ4BH:C%)+P[aDU]"?(N2YZ=_E. #FAV8!,S36$*IX;'^W5& @ (Also check your file permissions.) * indicates installed pogs%s already exists.%s has been purged.%s has not been purged.%s is already installed.%s takes two arguments: SOURCE(folder) TARGET(pog)&About&Clear ENTIRE selection&Exit&Help&Select ALL the source fonts&Selection&Settings Ctrl+S(%s) cannot be found. Try -l to see the names.(%s) skipped. I can't display this name under your locale.(%s) skipped. It's an invalid pog.A Pog with no name won't be created, however it was a good try!Are you sure?Bad voodoo error. I give up.Cannot delete the Pog.%sChange settingsChecking fonts, this could take some time.Choose some fontsClear selectionClear the selection completely.Close the appCopying fonts from %(source)s to %(target)sCould not open (%s).Could not write to the config file.Creates a new, empty PogCreating a new pog: %sDo you want to purge %s? Purging means all the fonts in the pog that are not pointing to actual files will be removed from this pog.ErrorFont causes a segfault. It cannot be drawn.Font may be bad and it cannot be drawn.Fonty PythonFonty Python version %sFonty Python, um ... crashed.Fonty Python: bring out your fonts!H&elp F1I am sorry, but Unicode is not supported by this installation of wxPython. Fonty Python relies on Unicode and will simply not work without it. Please fetch and install the Unicode version of python-wxgtk.I can't decode your argument(s). Please check your LANG variable. Also, don't paste text, type it in.I can't find %sI can't find a pog named %sI could not find any bad fonts.I have placed %(count)s fonts from %(folder)s into %(pog)s.Include sub-folders.Installing (%s)Jump the lazy dog foxListing %d pog(s)Looking in %s...New PogNo config file found, creating it with defaults.Not a single font in this pog could be installed. The original font folder has probably moved or been renamed.Not a single font in this pog could be uninstalled. None of the fonts were in your fonts folder, please check your home .fonts (with a dot in front) folder for broken links. The pog has been marked as "not installed".Oh boy...Page length:Pog cannot be written to. Check your filesystem.%sPog is already installed.Pog is empty.Pog is invalid, please hand-edit it.Pog is not installed.Point size:Purge font?Remove %s, are you sure?Remove all ghost fonts from the selected Pog.Removing (%s)SORRY: UNICODE MUST BE SUPPORTEDSample text:Select ABSOLUTELY ALL the fonts in the chosen source.Selected fonts are now in %s.Selected fonts have been removed.SettingsSome fonts could not be uninstalled. Please check your home .fonts (with a dot in front) folder for broken links.%sSome fonts did not install. Perhaps the original fonts folder has moved or been renamed. You should purge or hand-edit.Sorry, (%s) does not exist. Try --listSorry, can't find (%s). Try -l to see the names.Starting in %s:Target PogsThe fonts from %(folder)s are *already* in %(pog)s.The fontypython config file is damaged. Please remove it and start againThe process is complete.The target pog (%s) is currently installed, you can't use it as a target.There are no fonts in here.There are no fonts to see here, move along.There are no pogs available.There is no such item.There was an error writing the pog to disk. Nothing has been doneThere was an error writing the pog to disk. Nothing has been done.This folder has no fonts in it.This font is in %sThis pog is emptyUnicode problem. Font may be bad and it cannot be drawn.WarningYou cannot use a folder as the target argument. Try --helpYour pogs are the same! Try -eProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2017-12-06 20:46+0200 PO-Revision-Date: 2009-09-28 10:11+0200 Last-Translator: Donn Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (Auch die Nutzerberechtigungen prüfen.) (* kennzeichnet installiert Pogs)%s existiert bereits.%s wurde gelöscht.%s wurde nicht gelöscht.%s ist bereits installiert.%s nimmt zwei Argumente: QUELLE(Ordner) ZIEL(Pog)Ü&ber&GESAMTE Auswahl aufheben&Verlassen&Hilfe&ALLE Schriften im Ordner/Pog auswählen&Auswahl&Optionen Ctrl+O"%s" nicht gefunden. Versuchen Sie -l zum Anzeigen aller Namen der Pogs."%s" wurde übersprungen, Name kann mit der eingestellten Lokalisation nicht angezeigt werden."%s" wurde übersprungen, kein gültiges Pog.Ein Pog ohne Namen wird nicht angelegt, aber immerhin ein netter Versuch!Sind Sie sicher?Schwerer Fehler, ich gebe auf.Pog konnte nicht gelöscht werden. %sEinstellungen verändernPrüfe die Schriften, einen Moment Geduld bitte.Wähle einige SchriftenNichts &auswählenHebt die Auswahl komplett auf.Fonty Python beendenKopiere %(source)s nach %(target)sKann "%s" nicht öffnen.Konnte die Konfigurationsdatei nicht schreiben.Erstellt ein neues, leeres Pog.Erstellt ein neues Pog: %s%s soll bereinigt werden? Bereinigen bedeutet, dass alle Schriften in diesem Pog, die nicht auf eine vorhandene Schrift verweisen, entfernt werden.FehlerSchrift könnte beschädigt sein und nicht richtig angezeigt werden.Schrift könnte beschädigt sein und nicht richtig angezeigt werden.Fonty PythonFonty Python Version %sFonty Python, .... ist abgestürzt.Fonty Python : hole mehr aus Deinen Schriften!&Hilfe F1Entschuldigung, aber installierte Version von wxPython unterstützt Unicode nicht. Fonty Python ist aber auf Unicode angewiesen und wird ohne nicht arbeiten. Bitte besorgen Sie sich die Unicode-Version von python-wxgtk.Ich kann die Argumente nicht dekodieren. Bitte überprüfen Sie die Umgebungsvariable LANG. Kopieren Sie nicht den Text, sondern geben ihn direkt ein.Kann %s nicht findenKann %s nicht findenEs konnten keine beschädigten Schriften gefunden werden.%(count)s Schriften aus %(folder)s nach %(pog)s kopiert.Unterverzeichnisse einschliessenInstalliere "%s"Der rötliche Vogel springt über das bläuliche Faß. Liste %d Pog(s) aufSuche in %s...Neues PogKeine Konfigurationsdatei gefunden, wird mit Standardvorgaben erstellt.Keine einzige Schrift aus diesem Pog konnte installiert werden. Möglicherweise wurden die Original-Schriften verschoben oder umbenannt.Keine einzige Schrift aus diesem Pog konnte deinstalliert werden. Keine davon befand sich in ihrem Heimatverzeichnis. Schauen Sie unter ~/.fonts/ (WICHTIG: versteckter Ordner mit Punkt als erstes Zeichen) nach verwaisten Verknüpfungen. Das Pog wurde als "nicht installiert" markiert.Oh Junge...Seitenlänge:Es konnte nicht in das Pog geschrieben werden. Prüfen Sie das Dateisystem. %sPog ist bereits installiert.Pog ist leer.Pog ist nicht gültig, bearbeiten Sie es bitte von Hand.Pog ist nicht installiert.Schriftgröße:Schrift löschen?Soll %s wirklich gelöscht werden?Alle verwaisten Schriften vom gewählten Pog entfernen.Entferne "%s"ENTSCHULDIGUNG, ABER UNICODE MUSS UNTERSTÜTZT WERDENBeispieltext:Wählt RESTLOS ALLE Schriften im Ursprungsordner/Pog ausAusgewählte Schriften befindne sich nun in %s.Gewählte Schriften wurden entfernt.OptionenEinige Schriften konnten nicht deinstalliert werden. Schauen Sie in Ihrem Heimatverzeichnis unter ~/.fonts/ (WICHTIG: versteckter Ordner mit Punkt als erstes Zeichen) nach verwaisten Verknüpfungen. %sEinige Schriften wurden nicht installiert. Vielleicht wurden die Original-Schriften verschoben oder umbenannt. Entweder löschen (-p) oder von Hand bearbeiten."%s" existiert nicht. Versuche -l oder --listEntschuldigung,"%s" nicht gefunden. Versuche -l für die Anzeige aller Namen.Beginne in %s:Vorhandene PogsDie Schriften aus %(folder)s sind *bereits* in %(pog)s.Die Datei ~/.fontypython/fp.conf enthält Fehler. Bitte entfernen und Fonty Python neu starten.Vorgang abgeschlossenDas Pog "%s" ist im Moment installiert und kann daher nicht als Ziel verwendet werden.Hier befinden sich keine Schriften.Hier befinden sich keine Schriften, gehe weiter.Keine Pogs verfügbar.Element nicht vorhanden.Ein Fehler trat beim Schreiben des Pogs auf. Es wurde nichts verändert.Ein Fehler trat beim Schreiben des Pogs auf. Es wurde nichts verändert.Es befinden sich keine Schriften in diesem Ordner.Diese Schrift befindet sich in %sDas Pog ist leer.Unicode Problem. Schrift könnte beschädigt sein und nicht richtig angezeigt werden.AchtungEin Ordner kann nicht als Ziel-Argument verwendet werden. Versuche --helpQuell- und Zielpog sind gleich! Versuche -efontypython-0.5/fontypythonmodules/locale/fr/0000775000175000017500000000000013212250216021531 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/fr/LC_MESSAGES/0000775000175000017500000000000013212250216023316 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/locale/fr/LC_MESSAGES/all.mo0000664000175000017500000001463013212036006024426 0ustar donndonn00000000000000<S($)Nj}. !: J+X %#2V_o0n?  2& Y s $    !& H sQ w &= 0d H I 4 +P |  A   $ :, g | (,Ka| F&!;]s/d k8x- U"nxE+>3O, 42R} FF @lLV (!I!kX&  I(%r%&$23/;( .5' <9)-8:41!0 *, 7"#+6   (Also check your file permissions.) * indicates installed pogs%s already exists.%s has been purged.%s has not been purged.&About&Help&Settings Ctrl+S(%s) cannot be found. Try -l to see the names.Are you sure?Bad voodoo error. I give up.Cannot delete the Pog.%sClear selectionClose the appCopying fonts from %(source)s to %(target)sCould not open (%s).Do you want to purge %s? Purging means all the fonts in the pog that are not pointing to actual files will be removed from this pog.ErrorFonty PythonFonty Python: bring out your fonts!H&elp F1Installing (%s)Jump the lazy dog foxListing %d pog(s)New PogNo config file found, creating it with defaults.Not a single font in this pog could be installed. The original font folder has probably moved or been renamed.Not a single font in this pog could be uninstalled. None of the fonts were in your fonts folder, please check your home .fonts (with a dot in front) folder for broken links. The pog has been marked as "not installed".Page length:Pog cannot be written to. Check your filesystem.%sPog is already installed.Pog is empty.Pog is invalid, please hand-edit it.Pog is not installed.Point size:Purge font?Remove %s, are you sure?Removing (%s)Sample text:Selected fonts are now in %s.Selected fonts have been removed.SettingsSome fonts could not be uninstalled. Please check your home .fonts (with a dot in front) folder for broken links.%sSome fonts did not install. Perhaps the original fonts folder has moved or been renamed. You should purge or hand-edit.Sorry, (%s) does not exist. Try --listSorry, can't find (%s). Try -l to see the names.Target PogsThe fontypython config file is damaged. Please remove it and start againThe target pog (%s) is currently installed, you can't use it as a target.There are no fonts in here.There are no fonts to see here, move along.There are no pogs available.There is no such item.There was an error writing the pog to disk. Nothing has been doneThis folder has no fonts in it.This pog is emptyWarningYou cannot use a folder as the target argument. Try --helpYour pogs are the same! Try -eProject-Id-Version: fontypython 0.2.0 Report-Msgid-Bugs-To: POT-Creation-Date: 2017-12-06 20:46+0200 PO-Revision-Date: 2008-01-22 19:46+0200 Last-Translator: Donn Ingle Language-Team: French Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); (Vérifiez également les permissions.) * indique les pogs installésPog %s est installé.%s n'a pas été nettoyé.%s n'a pas été nettoyé.À &Propos&Aide&Options Ctrl+O(%s) ne peut être trouvé. essayez -l pour voir les noms disponibles.Êtes-vous certain ?Erreur maléfique vaudou, j'abandonne.Impossible de supprimer le Pog.%sNe rien sélectionnerQuitter Fonty PythonCopie des polices de %(source)s vers %(target)sImpossible d'ouvrir (%s).Voulez-vous nettoyer %s ? Nettoyer signifie que toutes les polices du Pog qui ne pointent pas vers des fichiers existants en seront supprimées.ErreurFonty PythonFonty Python : redécouvrez vos polices de caractères !&Aide F1Installer le Pog (%s)Portez ce vieux whisky au juge blond qui boitAffichage de %d pog(s) Nouveau PogAucun fichier de configuration détecté, création avec les paramètres par défaut.Pas la moindre police de ce pog n'a pu être installée. Le dossier originel a du être supprimé ou renommé.Pas la moindre police de ce pog n'a pu être désinstallée. Aucune d'entre elles n'étaient dans votre dossier de polices, veuillez vérifiez le dossier ~/.fonts/ (sans oublier le point). Le pog a été marqué comme désinstallé.Longueur de la page:Le pog ne peut être enregistré. Vérifiez le système de fichier.%sPog est installé.Le pog est vide.Le pog est invalide, veuillez l'éditer à la main.Le Pog n'est pas installé.Longueur de la page:Supprimer la police ?Êtes-vous certain de vouloir supprimer %s ?Visualisation de (%s)Texte affiché:Les polices sélectionnées sont maintenant dans %s.Les polices sélectionnées ont été supprimées.OptionsCertaines polices ne peuvent pas être désinstallées. Veuillez vérifier votre dossier ~/.fonts/ (sans oublier le point).%sCertaines polices n'ont pas été installées. Peut-être que le dossier d'origine a été déplacé ou renommé. Vous devriez le purger (-p) ou l'éditer à la main.(%s) ne peut être trouvé. essayez -l pour voir les noms disponibles.(%s) ne peut être trouvé. essayez -l pour voir les noms disponibles.Pogs CiblesLe fichier ~/.fontypython/fp.conf semble être endommagé. Veuillez le supprimer puis relancer Fonty Python.Le pog (%s) est actuellement installé, vous ne pouvez pas l'utiliser comme une cible.Aucun fonts disponible.Choisissez un dossier ou un Pog,Il n'y a pas autant d'éléments.Il n'y a pas autant d'éléments.Il y a eu une erreur pendant l'écriture du pog sur le disque. Rien n'a été effectué.Ce dossier ne contient pas de fichier.Le pog est vide.AttentionVous ne pouvez pas utiliser un dossier comme un pog cible. Essayez --helpVos pogs sont les mêmes ! Essayez -efontypython-0.5/fontypythonmodules/fontybugs.py0000664000175000017500000001671313212036007022265 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import locale import os import strings import linux_safe_path_library LSP = linux_safe_path_library.linuxSafePath() """ testing i18n with fontybugs try: raise fontybugs.BadVoodoo("bad voodoo") except fontybugs.BadVoodoo, e: print "error:", unicode(e) try: raise fontybugs.PogWriteError("/some/path/po.pog") except fontybugs.PogWriteError, e: print unicode(e) """ ## The %s must be OUTSIDE the _() construct. class Errors ( Exception ): checkperms = _("\n(Also check your file permissions.)") messages = { 001 : _("Bad voodoo error. I give up."), 100 : _("There is no such item."), 200 : _("Pog is empty."), 300 : _("Pog is already installed."), 500 : _("Pog cannot be written to.\nCheck your filesystem.%s") % checkperms, 600 : _("Pog is invalid, please hand-edit it."), 700 : _("Some fonts did not install.\nPerhaps the original fonts folder has moved or been renamed.\nYou should purge or hand-edit."), 800 : _("Pog is not installed."), 900 : _("Some fonts could not be uninstalled.\nPlease check your home .fonts (with a dot in front) folder for broken links.%s") % checkperms, 1000 : _("Cannot delete the Pog.%s") % checkperms, 1010 : _("Not a single font in this pog could be installed.\nThe original font folder has probably moved or been renamed."), 1020 : _("Not a single font in this pog could be uninstalled.\nNone of the fonts were in your fonts folder, please check your home .fonts (with a dot in front) folder for broken links.\nThe pog has been marked as \"not installed\"."), 1030 : _("This folder has no fonts in it."), } def __unicode__( self ): return u"%s : %s" % ( self.__class__.messages[self._id], self._item ) def _format_error(self): ## As of Python 2.6 e.message has been deprecated. ## Turn 'self' into a 'string like object' by calling __unicode__ above. msg = unicode(self) msg = LSP.to_bytes( msg ) return msg def unicode_of_error(self): """For use in wx gui when I am going to print the error in a messagebox.""" return self._format_error() def print_error(self): print self._format_error() def print_error_and_quit(self): print self._format_error() raise SystemExit def get_error_string(self): return self._format_error() class BadVoodoo ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 001 class ErrNoSuchItem ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 100 class PogEmpty ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 200 class PogInstalled ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 300 class PogWriteError ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 500 class PogInvalid ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 600 class PogSomeFontsDidNotInstall ( Errors ): #Some fonts did get installed, but not all def __init__ ( self, item = None): self._item = item self._id = 700 class PogNotInstalled ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 800 class PogLinksRemain ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 900 class PogCannotDelete ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 1000 class PogAllFontsFailedToInstall ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 1010 class PogAllFontsFailedToUninstall ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 1020 class FolderHasNoFonts ( Errors ): def __init__ ( self, item = None): self._item = item self._id = 1030 ## Sept 2017 ## Some new errors. ## These errors take a path argument so their unicode ## can display that path in the error message. ## They also take an "associated_err" which is an error object ## (Probably an OSError of some kind.) class NoFontypythonDir(Errors): def __init__(self,path, associated_err): self.path = path self.associated_err = associated_err def __unicode__(self): #import pdb; pdb.set_trace() return _(u"The \"{path}\" directory cannot be created or found.\n" \ "Fonty cannot run until it exists. " \ "Please create it, and start me again." \ "\nExample:\n\tcd {subpath}\n\tmkdir fontypython" \ "\nThe python error was: {assocerr}\n\n").format( path = self.path, subpath = os.path.dirname(self.path), assocerr = self.associated_err) class NoFontsDir(Errors): def __init__(self,path, associated_err): self.path = path self.associated_err = associated_err def __unicode__(self): return _(u"WARNING:\nThe \"{path}\" directory cannot be created or found.\n" \ "Fonts cannot be installed until it exists. " \ "Please create it, and start me again." \ "\nExample:\n\tcd {subpath}\n\tmkdir fonts" \ "\nThe python error was: {assocerr}\n\n").format( path = self.path, subpath = os.path.dirname(self.path), assocerr = self.associated_err) def short_unicode_of_error(self): """Used in gui; see the statusbar code.""" return _(u"Missing fonts directory. See Help.") class NoFontconfigDir(Errors): def __init__(self, path): self.path = path def __unicode__(self): return _(u"WARNING:\nThe fontconfig \"{path}\" directory " \ "cannot be created or found.\n").format( path = self.path ) def short_unicode_of_error(self): """Used in gui; see the statusbar code.""" return _(u"Missing fontconfig \"{}\" directory. " \ "See Help.".format(self.path)) class UpgradeFail(Errors): """ Any and all UpgradeFail errors should end the app after being caught. Slightly diff in that I pass a message in - because it differs as per context called. """ def __init__(self, msg, associated_err): self.msg = msg self.associated_err = associated_err def __unicode__(self): return _(u"Failure during upgrade:\n{msg}\n\n" \ "The python error was: {assocerr}\n\n").format( msg = self.msg, assocerr = self.associated_err) fontypython-0.5/fontypythonmodules/clifuncs.py0000664000175000017500000002035213212036002022040 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import os, locale import strings import fontybugs import fpsys import fontcontrol def checkfonts( dirtocheck ): # Check fonts if not os.path.exists( dirtocheck ): print _("I can't find %s") % dirtocheck return def printer( pstr = "" ): """A func to print strings to cli, called back from checkFonts.""" if type(pstr) is str: pstr = fpsys.LSP.to_unicode( pstr ) print pstr ##TODO ?? SHOULD this TRY/EXC fpsys.checkFonts( dirtocheck, printer ) def listpogs(): ## List - Quick and dirty. poglist = fpsys.iPC.getPogNames() poglist.sort( cmp=locale.strcoll, key=lambda obj:obj) #28 May 2009. Hope this works for other locales... if len(poglist) == 0: print _("There are no pogs available.") return print _("Listing %d pog(s)") % len(poglist) print _(" * indicates installed pogs") for pog in poglist: paf = fpsys.iPC.appPath() + pog + ".pog" try: f = open(paf, "r" ) # It's a plain byte-string ascii file. installed = f.readline()[:-1] #Strips the \n off the end f.close() except: print _("Could not open (%s).") % paf s = " " if installed.upper() == "INSTALLED": s = "*" print "%s %s" % (s,pog) ## Sept 2017: Added this because I was doing ls in testing so much. def lsfonts(): import subprocess try: p = fpsys.iPC.userFontPath() ls = subprocess.check_output(['ls','--color=always', '-l', p ]) except: print _("Could not ls the font path.") raise print _("Contents of {}:").format(fpsys.LSP.to_unicode(p)) print ls ## is this already unicode? ## Nov 2017 - also helps with dev def cat( pog ): import subprocess try: p = os.path.join(fpsys.iPC.appPath(), "{}.pog".format(pog)) cat_res = subprocess.check_output(['cat', p]) except: print _("Could not cat that pog.") return print cat_res def hush_unhush( pog, switch = None): """ Called from cli2.py A test for XDG_CONFIG_HOME as well as fontconfig/conf.d/ has been done there, and errors were shown, etc. Thus we know fontconfig is installed and we can proceeed. """ def printer( pstr = "", key = None ): pstr = fpsys.LSP.ensure_unicode(pstr) if key: key = key.upper() c = "=" if key == "ERROR": c = "*" print key print c * len(key) print pstr if switch == "hush": buglist = fpsys.hush_with_pog( pog, printer ) else: buglist = fpsys.un_hush( printer ) if buglist: ## All errors end with this text: printer( strings.cant_hush, key="ERROR" ) for bug in buglist: printer( bug ) printer () printer( strings.see_help_hush ) def zip( pog ): ## Sep 2009 : ZIP ## Nov 2017: Much fixing of error handling. if fpsys.isPog( pog ): todir = os.curdir #always where we run this ipog = fontcontrol.Pog( pog ) (bugs, fail, emsgs) = ipog.zip( todir ) if fail: print _("I could not create the zip at all.") print emsgs[0] else: print _("Zipped as \"{}.fonts.zip\" in the \"{}\" directory.").format( pog, os.getcwd()) if bugs: print _("Some bugs happened:") for m in emsgs: print m else: print _("I can't find a pog named %s") % pog def purgepog(pogtopurge): ##Handle purge if fpsys.isPog(pogtopurge): pog = fontcontrol.Pog(pogtopurge) try: #raise fontybugs.PogInvalid #testing pog.genList() except fontybugs.PogInvalid, e: e.print_error_and_quit() try: ## pog.purge() Raises ## PogEmpty ## PogInstalled pog.purge() except (fontybugs.PogEmpty, fontybugs.PogInstalled), e: e.print_error() else: print _("(%s) cannot be found. Try -l to see the names.") % pogtopurge return fpsys.config.Save() print strings.done def installpogs( listofpogs ): #### ## Install: for pogtoinstall in listofpogs: if fpsys.isPog(pogtoinstall): pog = fontcontrol.Pog( pogtoinstall ) try: pog.genList() except fontybugs.PogInvalid, e: e.print_error_and_quit() try: ## pog.install() Raises: ## PogEmpty ## PogAllFontsFailedToInstall ## PogSomeFontsDidNotInstall ## NoFontsDir print _("Installing (%s)") % pogtoinstall pog.install() except ( fontybugs.PogEmpty, fontybugs.PogAllFontsFailedToInstall, fontybugs.PogSomeFontsDidNotInstall, fontybugs.NoFontsDir ), e: e.print_error() else: # not a pogname print _("(%s) cannot be found. Try -l to see the names.") % pogtoinstall return fpsys.config.Save() print strings.done def uninstallpogs( listofpogs ): ## uninstall for pogtouninstall in listofpogs: if fpsys.isPog(pogtouninstall): pog = fontcontrol.Pog(pogtouninstall ) try: pog.genList() except fontybugs.PogInvalid, e: e.print_error_and_quit() try: ## Raises: ## PogEmpty ## PogLinksRemain ## PogNotInstalled print _("Removing (%s)") % pogtouninstall pog.uninstall() except (fontybugs.PogEmpty, fontybugs.PogNotInstalled, fontybugs.PogLinksRemain), e: e.print_error() else: print _("Sorry, can't find (%s). Try -l to see the names.") % pogtouninstall return fpsys.config.Save() print strings.done def installall( FOLDERNAME, POGNAME, recurseflag ): ## Install all fonts in folder to given pog. ## May 2009 : Based on code by another author (names lost in email crash). count = 0 existingPog = False try: folder = fontcontrol.Folder(FOLDERNAME, recurse=recurseflag) except fontybugs.FolderHasNoFonts, e: e.print_error_and_quit() except Exception, e: print e raise SystemExit ipog = fontcontrol.Pog( POGNAME ) # whether it exists or not. ## If it's an unknown POGNAME, make it and write it: if not fpsys.isPog(POGNAME): print _("Creating a new pog: %s") % POGNAME try: ipog.write() except fontybugs.PogWriteError, e: e.print_error_and_quit() ## Fill it with fontitems. ipog.genList() ## get a list of what (in the folder) is NOT already in the ipog (assuming it's non-empty) fl = [fi for fi in folder if str(fi) not in [str(fi2) for fi2 in ipog]] #str(fontItem) returns glyphpaf which has been decoded already. ## Add those fresh items to ipog for f in fl: ipog.append( f ) count += 1 try: ipog.write() except fontybugs.PogWriteError, e: e.print_error_and_quit() del ipog, folder if count: print _("I have placed %(count)s fonts from %(folder)s into %(pog)s.") % {"count":str(count), "folder":FOLDERNAME, "pog":POGNAME } else: print _("The fonts from %(folder)s are *already* in %(pog)s.") % {"folder": FOLDERNAME, "pog":POGNAME } fontypython-0.5/fontypythonmodules/gui_dismissable_panels.py0000664000175000017500000010302713212237744024760 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . """ These classes comprise the "dismissable" panels that appear in the gui on top of the fontview (hide/show trickery). They do: 1. Help 2. About 3. Settings 4. Zip pogs 5. Hush fonts """ import locale, os import strings import fontybugs import fpsys # Global objects import wx #For help and about: import wx.html as html #I need the various flags and id's defined at top of wxgui: from wxgui import button_ids, id_from_flag, \ flag_help, \ flag_about, \ flag_settings, \ flag_choosedir, \ flag_hush_fonts # Tree for use in the zip panel from gui_DirChooser import ATree import fpwx ## --- ## The two basic classes for the DismissablePanels class DismissablePanel(wx.Panel): """ Only for subclassing. Provides a panel with an icon, title and X close button. Under that is.. whatever: usually a sizer. wfunc: Is a function that will return a size. The caller must decide whom it trusts to return a sane value. We use it to set a sane size on the Panel we will soon construct. This, in turn, helps any labels, and paragraphs (various text controls) fit and helps with those that must wrap. """ def __init__(self, parent, flag, someicon = None, somelabel = "...", extra_padding = 0, wfunc = None): id = id_from_flag[flag] self.id = id sz = (-1,-1) if wfunc: sz = wfunc()# seems work.. was:(wfunc()[0],-1) wx.Panel.__init__(self, parent, id, size = sz, style = wx.NO_FULL_REPAINT_ON_RESIZE ) #self.SetMinSize(sz) # necc? Meh. Seems not.. self.parent = parent self.flag = flag ## Go fetch the .. whatever ## Seems I settled on returning a sizer from __post_init__ whatever = self.__post_init__() ## Pad the whole thing some whatever_sizer = wx.BoxSizer( wx.VERTICAL ) whatever_sizer.Add( whatever, 1, wx.EXPAND | wx.ALL, border = 8 + extra_padding ) l = fpwx.h1( self, somelabel ) x_button = wx.BitmapButton(self, -1, fpwx.wxbmp( "icon_X" ), style = wx.NO_BORDER) x_button.SetToolTipString( _("Dismiss. ESC key does the same.") ) #x_button = wx.Button(self, -1, label="X", # style = wx.NO_BORDER | wx.BU_EXACTFIT) self.Bind(wx.EVT_BUTTON, self.__x_pressed, x_button) hbox = wx.BoxSizer(wx.HORIZONTAL) if someicon: hbox.Add( fpwx.icon( self, someicon ), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border = 12 ) else: hbox.Add( (1,1), 0, wx.EXPAND ) # push the label down to better align with the X hbox.Add( l, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.TOP, border = 6 ) hbox.Add( x_button, 0, wx.ALIGN_RIGHT | wx.BOTTOM, border = 4 ) hbox.Add( (8,8),0) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add( hbox, 0, wx.EXPAND | wx.TOP , border = 16 ) #Wanted more space above. self.vbox.Add( whatever_sizer, 1, wx.EXPAND) self.SetSizer( self.vbox ) #self.Fit() self.Layout() self.SetFocus() self._firstshow = True self.Bind(wx.EVT_SHOW, self.__catch_show_or_hide) ## Weirdly public def __post_init__(self): pass ## Private def __x_pressed(self,evt): ## I don't want the button's id skipping-on; ## only the panel's evt.SetId(self.id) evt.Skip() def __catch_show_or_hide(self,evt): if self._firstshow: self._firstshow = False return self._show_or_hide( self.IsShown() ) def _show_or_hide(self, showing): pass class DismissableHTMLPanel(DismissablePanel): """ Collects common stuff that both HTML-based panels use. """ class AnHtmlWindow(html.HtmlWindow): def __init__(self, parent): html.HtmlWindow.__init__(self, parent) if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo: self.SetStandardFonts() def __init__(self, parent, flag, somelabel = "...", someicon = None): DismissablePanel.__init__(self, parent, flag, somelabel = somelabel, someicon = someicon) def __post_init__(self): ## call one: get the HTML paf self.paf = self.post_init_set_paf() self.html = DismissableHTMLPanel.AnHtmlWindow(self) try: f = open( self.paf, "r" ) h = f.read() f.close() except Exception as e: h = u"

Error reading {} file

{}

".format(self.paf, e) ##provide a separator thing sep = "~/~" sep = u"
" \ "{sep}
".format( sep = sep, medium = fpwx.HTMLCOLS["heading1"] ) sd = {"SEP":sep} ## call two: get the replace strings in a dict d = self.post_init_setup_replace_dict() # merge all the dicts. Missing keys will raise. sd.update(**d) sd.update(**fpwx.HTMLCOLS) # IMG SRC # Get a path so we can alter all IMG SRCes to be # absolute since the images were not working after # a setup has been done. sd.update({"THINGS": fpsys.mythingsdir}) ## Make sure the HTML is unicode h = fpsys.LSP.to_unicode(h) ## Format the HTML h = h.format(**sd) self.html.SetPage( h ) return self.html ## Public def post_init_set_paf(self): """Override and return a paf to an html file.""" pass def post_init_setup_replace_dict(self): """Override and return a dict of keys to replace {} in the html.""" pass ## Ends basic classes ## -- class HelpPanel(DismissableHTMLPanel): """Help moved to HTML in Oct/Nov 2017""" def __init__(self, parent): DismissableHTMLPanel.__init__(self, parent, flag_help, somelabel=_("Help! Help! I'm being repressed!"), someicon="fplogo") def post_init_set_paf(self): ## langcode = locale.getlocale()[0] # I must not use getlocale... ## This is suggested by Martin: # use *one* of the categories (not LC_ALL) loc = locale.setlocale(locale.LC_CTYPE) ## returns something like 'en_ZA.UTF-8' if loc is None or len(loc) < 2: langcode = 'en' else: langcode = loc[:2].lower()# May cause bugs ## Find localized help, or default to English. packpath = fpsys.fontyroot helppaf = os.path.join(packpath, "help", langcode, "help.html") if not os.path.exists( helppaf ): helppaf = os.path.join(packpath, "help", "en", "help.html") return helppaf def post_init_setup_replace_dict(self): ## Drop some last-minute info into the html string def header(t,e): return u"
Missing {}
" \ "{}".format( t, unicode(e).replace("\n","
") ) def pccp(t): return u"
{}
".format(t) s_fpdir = pccp( fpsys.LSP.to_unicode(fpsys.iPC.appPath()) ) ## Let's use our fancy error stuff to swap-in ## a message about the user fonts directory, ## should it be missing! e = fpsys.iPC.get_error_or_none("NoFontsDir") if e: s_fontsdir = header(_(u"User Fonts"), e) else: s_fontsdir = pccp( fpsys.LSP.to_unicode( fpsys.iPC.userFontPath())) ## Also fontconfig's directory e = fpsys.iPC.get_error_or_none("NoFontconfigDir") if e: s_fcdir = header(_(u"Fontconfig"), e) s_fcpaf = _(u"No path: Fontconfig is not functioning.") else: s_fcdir = pccp( fpsys.LSP.to_unicode( fpsys.iPC.user_fontconfig_confd())) s_fcpaf = pccp(fpsys.HUSH_PAF) ## Show the home directory too. s_home = fpsys.LSP.to_unicode(fpsys.iPC.home()) d={ "FP_DIR" : s_fpdir, "UF_DIR" : s_fontsdir, "FC_DIR" : s_fcdir, "FC_PAF" : s_fcpaf, "HOME" : s_home, "TICKET_URL" : strings.ticket_url, } return d class AboutPanel(DismissableHTMLPanel): """About moved to HTML in Nov 2017""" def __init__(self, parent): DismissableHTMLPanel.__init__(self, parent, flag_about, somelabel=_("About Fonty"), someicon="fplogo") def post_init_set_paf(self): packpath = fpsys.fontyroot return os.path.join(packpath, "about", "about.html") def post_init_setup_replace_dict(self): return { "warranty": strings.warranty.replace("\n","
"), "copyright": strings.copyright, "contact": strings.contact, "version": strings.version, "ticket" : strings.ticket_url, "GPL" : strings.GPL.replace("\n","
")} class HushPanel(DismissablePanel): """ Shows the form for hushing and unhushing fonts. The whole thing can be in two states: 1. Error -> fontconfig/conf.d is not available. Fatal. The entire show is off. Go home! 2. Ok -> Continue to hush/unhush. Other errors can still happen during that process, and they appear in the printer. When ok, there are two states of hush: 1. Hush on -> offer to turn it on 2. Hush off-> offer to turn it off. Ok state: ========= Displays a large heading of the hush state. Shows some help text. Offers a choice of pog names to hush with. Has a large printer for the call back to report into. Button to hush/unhush. Error state: ============ Display error title. Display some help. Display the error itself, in the printer. """ def __init__(self, parent, wfunc): #state dict self.sd = { "hush_on" :{"h":_("Hushing is on." ), "b":_("Un-hush my fonts")}, "hush_off":{"h":_("Hushing is off." ),"b":_("Hush my fonts")}, "fontconfig_error":{"h": strings.cant_hush ,"b":_("Fonty cannot hush your fonts")} } DismissablePanel.__init__(self,parent, flag_hush_fonts, somelabel = _("Hush Fonts"), someicon = "icon_hush", wfunc = wfunc) def __post_init__(self): sizer = wx.BoxSizer(wx.VERTICAL) ## This decides the error vs ok states: self.fontconfig_error = fpsys.iPC.get_error_or_none("NoFontconfigDir") if not self.fontconfig_error: title = u"xx" else: title = self.sd["fontconfig_error"]["h"] ## Big header announcing Hushed/Not hushed ## Real tortured code to center the fuckin' label text. Jeezuz. ## Half the time the text was chopped-off on first draw. :( hush_heading_panel = wx.Panel(self,size=(-1,150), style=wx.SUNKEN_BORDER) f = wx.BoxSizer(wx.HORIZONTAL) bsp = wx.BoxSizer(wx.VERTICAL) self.hush_state_label = fpwx.h0( hush_heading_panel, title) bsp.Add(self.hush_state_label, 1, wx.ALIGN_CENTER_HORIZONTAL ) f.Add(bsp, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 40) hush_heading_panel.SetSizer( f ) sizer.Add( hush_heading_panel, 0, wx.EXPAND | wx.BOTTOM, border = 5) if not self.fontconfig_error: ## The label to the intro text self.chosen_pog_label = fpwx.h1( self, _("The Hush Pog:") ) sizer.Add( self.chosen_pog_label, 0, wx.ALIGN_TOP) ## The intro text - is wrappable! p1 = fpwx.para( self, _( u"Hushing installs a Pog that you must manage. " \ "Make sure it contains a few system fonts so that " \ "your applications function properly! " \ "Look in /usr/share/fonts for ideas. " \ "See help for details."), wrap = True) sizer.Add( p1, 1, wx.EXPAND | wx.BOTTOM, border = 8 ) h = wx.BoxSizer(wx.HORIZONTAL) ## label to the choice box self.chosen_pog_label = fpwx.label( self, _("Current Hush Pog: ") ) h.Add( self.chosen_pog_label, 0, wx.ALIGN_CENTER_VERTICAL ) ## The pog choice box self.pog_choice = wx.Choice(self, -1, choices = ["-"]) self.pog_choice.SetToolTip( wx.ToolTip( _("Choose your system Pog") ) ) self.pog_choice.Bind(wx.EVT_CHOICE, self._pog_chosen ) h.Add( self.pog_choice, 0, wx.ALIGN_TOP ) sizer.Add(h,0, wx.BOTTOM, border = 5) else: ## Some help re the error - also wrappable! p1 = fpwx.para( self, _( u"Fontconfig is not properly installed; thus " \ "Fonty cannot hush fonts. " \ "Consult your distribution, or " \ "open a ticket so we can try fix it. " \ "See help for details."), wrap = True) sizer.Add( p1, 1, wx.EXPAND | wx.BOTTOM, border = 8 ) ## Area to print into pl = fpwx.label( self, _("Progress report:") ) sizer.Add( pl, 0, wx.BOTTOM, border = 5) self.printer = wx.TextCtrl(self, -1, "", style = wx.TE_READONLY | wx.TE_MULTILINE) font = self.printer.GetFont() font = wx.Font(font.GetPointSize(), wx.TELETYPE, font.GetStyle(), font.GetWeight(), font.GetUnderlined()) self.printer.SetFont(font) sizer.Add (self.printer, 3, wx.EXPAND | wx.BOTTOM, border = 5) if self.fontconfig_error: ## Dump the initial NoFontconfigDir error into the printer self.printout( unicode(self.fontconfig_error), key="ERROR") if not self.fontconfig_error: ## The hush/unhush button self.hb = wx.Button( self, label = self._update_heading("b"), id = button_ids['id_hush_button'] ) ## Make a button. Click also gets caught in MainFrame. self.Bind(wx.EVT_BUTTON, self._do_hushing, id = button_ids['id_hush_button']) sizer.Add(self.hb, 0, wx.EXPAND ) self._update_pog_choice_control() return sizer def _pog_chosen(self,evt): """ The choice control was changed. Forbid index 0 as a valid choice. """ n = evt.GetSelection() if n == 0: s = "" self.hb.Disable() else: s = evt.GetString() self.hb.Enable() ## s is a byte string fpsys.config.hush_pog_name = s def _update_heading(self, key): """ Get strings for either the heading or the button depending on state. """ if self.fontconfig_error: return self.sd["fontconfig_error"][key] if os.path.exists(fpsys.HUSH_PAF): return self.sd["hush_on"][key] else: return self.sd["hush_off"][key] def _update_pog_choice_control(self): """ In case Pogs were added/deleted, we must refresh this list. Refill the choice list, sort and select the last string. We also ensure that there's no invalid choice in the control. If the hush pog, from config, is *not* in the control's list then we set the config to "" and start again. """ ## Empty the choice control. self.pog_choice.Clear() ## Now refill it pl = fpsys.iPC.getPogNames() # pl is all byte strings (encoded) pl.sort(cmp=locale.strcoll) # sort according to locale ## Let's add a "none" choice in index 0 self.pog_choice.Append(_(u"None chosen")) ## then the pogs: self.pog_choice.AppendItems( pl ) # stick it in the control ## get the last used hush Pog name - make sure it's a ## byte, or else.. s = fpsys.LSP.ensure_bytes( fpsys.config.hush_pog_name ) if s not in pl: # ...we get complaints here. # ok - that was not in the control. Something changed. n = 0 # this has the effect of selecting "None chosen" # The choice was invalid, so empty the config too: fpsys.config.hush_pog_name = "" self.hb.Disable() else: # s is ok, let's seek its index in the control n = self.pog_choice.FindString(s) self.hb.Enable() # now set it as selected in the control self.pog_choice.SetSelection( n ) def _show_or_hide(self, showing): """ The entire panel hide/show If in error state, just bail. """ if self.fontconfig_error: return if showing: # I am being shown, so let's update shit: self._update_pog_choice_control() self.hush_state_label.SetLabel(self._update_heading("h")) self.hb.SetLabel(self._update_heading("b")) else: # I am being hidden ( esc, or x) self.printer.Clear() def _do_hushing(self, evt): """ Forward the click on to MainFrame where it's also bound. """ if self.pog_choice.GetCurrentSelection() == 0: return self.printer.Clear() # fresh for new data fpsys.config.hush_pog_name = self.pog_choice.GetStringSelection() ## Skip the event along to the main frame. See Bind there. evt.Skip() ## Public defs def printout(self, msg="\n", key=None): """ A callback for the actual hush code to use as a printer. The key is meant as a way to alter how things display. Only using ERROR really. """ if key: key = key.upper() c = "=" if key == "ERROR": c = "*" self.printer.write(key + "\n") self.printer.write(c * len(key) + "\n") self.printer.write(fpsys.LSP.ensure_unicode(msg) + "\n") def after_do_hushing(self): """ Called after the do_hush_unhush in main frame. Switches state and updates the form without clearing the printer. """ self._update_pog_choice_control() self.hush_state_label.SetLabel(self._update_heading("h")) self.hb.SetLabel(self._update_heading("b")) class ChooseZipDirPanel(DismissablePanel): """ Deals with all the crap the zip functionality needs. """ def __init__(self, parent, wfunc): DismissablePanel.__init__(self,parent, flag_choosedir, somelabel=_("Locate a directory for the zip file(s)"), someicon = "icon_zip", wfunc = wfunc) self._chosen_path = None def __post_init__(self): sizer = wx.BoxSizer(wx.VERTICAL) # A top, shows what pogs are going to be zipped # Because it's writable, we send along a layout # function. See AutoWrapStaticText self.what_pogs_lbl = fpwx.label( self, u"..", Layout_func = self.Layout ) sizer.Add( self.what_pogs_lbl, 0, wx.EXPAND | wx.TOP, border = 10) # The tree to find a path self.treedir = ATree(self, os.getcwd()) tree = self.treedir.GetTreeCtrl() #Clicks on the control will change the button's label tree.Bind(wx.EVT_TREE_SEL_CHANGED, self._on_dir_control_click) sizer.Add(self.treedir, 1, wx.EXPAND | wx.TOP, border = 10) # Label to show the directory chosen (or the default) # Tries to wrap. Paths without spaces don't wrap, so we use # ellipses. (Pass Layout_func bec. we use SetLabel) self.what_dir_lbl = fpwx.label( self, self._make_label(), ellip = wx.ST_ELLIPSIZE_END, Layout_func = self.Layout) sizer.Add( self.what_dir_lbl, 0, wx.EXPAND | wx.TOP, border=10) # A printer that will show when it has to. self.printer = wx.TextCtrl(self, -1, "", style = wx.TE_READONLY | wx.TE_MULTILINE) font = self.printer.GetFont() font = wx.Font(font.GetPointSize(), wx.TELETYPE, font.GetStyle(), font.GetWeight(), font.GetUnderlined()) self.printer.SetFont(font) sizer.Add (self.printer, 1, wx.EXPAND | wx.TOP, border=10 ) self.printer.Hide() ## Make a button. Click also gets caught in MainFrame. btn = wx.Button(self, label = _("Create the zip file"), id = button_ids['id_do_the_actual_zip']) self.Bind(wx.EVT_BUTTON, self._do_actual_zip, id = button_ids['id_do_the_actual_zip']) sizer.Add(btn, 0, wx.TOP | wx.BOTTOM | wx.EXPAND, border=10) return sizer def _show_or_hide(self, showing): """The entire panel hide/show""" if showing: # I am being shown wpogs = u", ".join( self.parent.panelTargetPogChooser.list_of_target_pogs_selected) self.what_pogs_lbl.SetLabel( u"Pog(s) to zip: {}".format(wpogs) ) if self.printer.IsEmpty(): self.printer.Hide() else: self.printer.Show() else: # I am being hidden ( esc, or x) self.printer.Clear() self.printer.Hide() def _make_label(self, p=None): if not p: p = os.getcwd() return _("The zip file(s) will be put into:\n{}").format(p) def _on_dir_control_click(self,e): """ I don't Skip() the event, so it does not continue up into the ATree class. Therefore the little eye icon is not drawn on the selected tree item. """ cp = self.treedir.GetPath() self.what_dir_lbl.SetLabel(self._make_label(cp)) def _do_actual_zip(self, evt): """ Forwards the click on to MainFrame where it's also bound. """ self._chosen_path = self.treedir.GetPath() evt.Skip() ## Public defs def get_path(self): return self._chosen_path def printout(self, msg): self.printer.write(msg + "\n") if not self.printer.IsShown(): self.printer.Show() self.Layout() ##Slider code - maybe for settings form #self.choiceSlider = wx.Slider(self, value=1, minValue=1, # maxValue=1, style=wx.SL_HORIZONTAL | wx.SL_LABELS) #self.choiceSlider.SetTickFreq(1,1) #self.choiceSlider.Bind(wx.EVT_SCROLL, self.OnSliderScroll) ## ... it sucked! class SettingsPanel(DismissablePanel): def __init__(self, parent, wfunc): """The settings form. I went a little mad. It started simple, the old code. A few gets, a few sets. Then I thought, "I can make this generic! Shit yeah!" And so I abstracted and factored and fuck. Now it's this thing. Sorry about that. """ ## This dict is a way to handle the actual form in a ## loopy kind of way self.form = {} self._force_redraw = False self.settings_sizer = wx.FlexGridSizer( cols = 2, hgap = 5, vgap = 20 ) DismissablePanel.__init__(self, parent, flag_settings, somelabel = _("Settings"), someicon = "icon_settings", extra_padding = 12, wfunc = wfunc) def __post_init__(self): """ Happens only once. Draws all the controls, with values *from* config. After this, the panel only hides/shows. The controls all persist. """ ## Sample text k="text" c = wx.TextCtrl( self, -1, self.gv(k), size = (200, -1) ) self.entry( k, _("Sample text:"), c, default = fpsys.Configure.atoz ) ## Point size k = "points" c = self.spinner(k, (1, 500)) self.entry( k, _("Point size:"), c ) ## Page length k = "numinpage" c = self.spinner(k, (1, 5000), tip=_("Beware large numbers!"))# It's your funeral! self.entry( k, _("Page length:"), c ) ## Sept 2009 - Checkbox to ignore/use the font top left adjustment k = "ignore_adjustments" c = wx.CheckBox(self, -1, _("Tick to disable") ) c.SetValue( self.gv(k) ) self.entry( k, _("Disable top-left correction:"), c, extra = _("Disabling this speeds-up\n" \ "font drawing but can\n" \ "cause bad positioning.")) # The Character map choice # CMC is an instance of CharMapController self.CMC = fpsys.config.CMC k = "app_char_map" ## Do we have some char viewer apps? if self.CMC.apps_are_available: app = self.gv(k) c = wx.RadioBox( self, -1, _("Available"), wx.DefaultPosition, wx.DefaultSize, self.CMC.quick_appname_list, 1, wx.RA_SPECIFY_COLS ) c.SetSelection(self.CMC.quick_appname_list.index(app)) ## Prefer explicit "poke" (in dict) to this event: ## self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, c) c.SetToolTip(wx.ToolTip(_("Choose which app to use" \ " as a character map viewer."))) dud_control = False ## No apps, just print a string: else: app = None c = fpwx.para(self, _("None found.\nYou could install: {}".format( self.CMC.list_of_suggested_apps)) ) dud_control = True self.entry( k, _("Character map viewer:"), c, dud = dud_control, redraw = False, peek = lambda c: c.GetStringSelection(), poke = self.poke_app_char_map ) ## Max columns k = "max_num_columns" c = self.spinner(k, (1, 20))# It's your funeral! self.entry( k, _("Max number of columns:"), c, extra = _("The font viewing area\n" \ "will divide into columns\n" \ "which you can control here.") ) ## Nov 2017 - Moving the recurse check box into settings k = "recurseFolders" c = wx.CheckBox(self, -1, _("Tick to include all\n" \ "sub-folders in\nthe source view.") ) c.SetValue( self.gv(k) ) self.entry( k,_("Include sub-folders."), c, extra = _("Caution: This will crash Fonty if\n" \ "your Source folder (directory)\n" \ "is deep."), redraw = True) ## Make an "apply" button. Click also gets caught in MainFrame. btn = wx.Button(self, wx.ID_APPLY) self.Bind(wx.EVT_BUTTON, self.apply_pressed, id=wx.ID_APPLY) #btn.SetDefault() # no joy... self.settings_sizer.Add((1,1),0) #a blank cell self.settings_sizer.Add(btn, 0, wx.ALL | wx.ALIGN_RIGHT, border=10) return self.settings_sizer def settings_force_redraw(self): """Do I have to redraw fitmaps? Used externally in MainFrame""" return self._force_redraw def has_changed(self, key): """Has a thing changed? Used externally in MainFrame""" return self.form[key]["changed"] def _show_or_hide(self, showing):#evt): """ Fires when I hide or show. NOTE: Since __post_init__ only happens once, I need a way to alter the form as it comes and goes. """ if showing:#self.IsShown(): # Most of the controls will "remember" their last setting. # (This is all a show/hide game anyway.) # The only one that can change outside the settings is # point size - by the mouse wheel - hence I update it: self.form["points"]["control"].SetValue( self.gv("points") ) def entry(self, key, title, ctrl, extra = None, dud = False, default = None, redraw = True, peek = None, poke = None ): """ Makes the label. Puts it and the control into the sizer. Manages the form dict: Keys: == default: for when a value is bad, use this instead. redraw : signals if a change to this value would require a fitmap redraw peek : func to get value from the form control poke : func to put the value into fpsys.config dud : is a control that plays no real part """ self.form[key] = {} self.form[key]["control"] = ctrl self.form[key]["dud"] = dud # some ctrls are just info. self.form[key].update({"default":default, "redraw" : redraw, "peek" : peek, "poke" : poke}) lbl = fpwx.boldlabel( self, title ) if extra: ## We have some extra text to stuff in somewhere. sb = wx.BoxSizer(wx.VERTICAL) sb.Add( lbl, 0, wx.ALIGN_RIGHT | wx.ALIGN_TOP ) e = fpwx.parar(self, extra, pointsize = "points_tiny" ) sb.Add( e, 0, wx.ALIGN_RIGHT | wx.ALIGN_TOP ) self.settings_sizer.Add( sb, 0, wx.ALIGN_RIGHT | wx.ALIGN_TOP) else: self.settings_sizer.Add(lbl, 0, wx.ALIGN_RIGHT | wx.ALIGN_TOP) ## text controls need more width. if isinstance(ctrl, wx._controls.TextCtrl): self.settings_sizer.Add(ctrl, 1, wx.EXPAND ) else: self.settings_sizer.Add(ctrl, 1 ) def gv(self, key): """Get a value for the key. It's less typing.""" return fpsys.config.__dict__[key] def spinner(self, key, rnge, tip=None): """There were several, so I did a thing.""" c = wx.SpinCtrl(self, -1, "") c.SetRange(rnge[0], rnge[1]) c.SetValue( self.gv(key) ) if tip: c.SetToolTip( wx.ToolTip( tip ) ) return c def apply_pressed(self,evt): """ Loop through the form dict and connect the dots. Put new values into fpsys.config, and set flags for MainFrame to test when it catches the event. """ redraw = False for key,d in self.form.iteritems(): # A 'dud' is a control that plays no part if not d["dud"]: changed=False # Is there a special func to get value? peek = d.get("peek",None) if peek: # yes ctrlval = peek(d["control"]) else: ctrlval = d["control"].GetValue() # is there a default? getdef = d.get("default", None) if getdef: # truthy test for "no value" (or empty string) if not ctrlval: ctrlval = getdef # so, use default instead # Since the value in the control just failed # and we have to use a default, let's # also plug the fixed value back into the # control. # This one may fail if ctrl has no SetValue # method. I'm not worried right now. d["control"].SetValue(getdef) # now I have the value from the control # Is it different from the config's version? # If so, update config. if ctrlval != self.gv(key): changed=True # If there's a special poke func, use it. poke = d.get("poke",None) if poke: poke(ctrlval) else: fpsys.config.__dict__[key] = ctrlval redraw = d["redraw"] d["changed"]=changed self._force_redraw = redraw ## Pass the event on to the MainFrame, where I use it ## to hide this panel. evt.Skip() def poke_app_char_map(self, v): """poke func. I could have use the event system, but I wanted to keep it all in the apply_pressed method.""" self.CMC.set_current_appname( v ) fontypython-0.5/fontypythonmodules/things/0000775000175000017500000000000013212250216021157 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/things/tick.png0000664000175000017500000001155613211475353022641 0ustar donndonn00000000000000PNG  IHDRXPƲYsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATxyp]W}?'ˊ}IpJSPJ-)LJK43 С)[g)2M@ mhYRhl˲Y}yZwϷ'Yz,߽GG_;w7qW’Kyr@NIOIˇ&ɽ}f!F:7JZIm!w=s9:}xCP?c Ld ܳհueZm$x$}`PNdG OZk?gu7XM?` r{O `"@]z_V7 $H&=x/7<*KcNЪ[q׽q+(&XR546x~=o;l.ws@X$|xii [C-kkvʰ7Jd@f1v#>pbN&k%^^ؽ<|C,AAǾ2:@rK]Y~ GO j7X ǙA5i[n(%TƢ ĤS,[oҋVa2 w,36fA05+ AhMאrY3HVJKc8ll#}b=<ϧm:|ShBO-LIt]D`I/l?2BS鄉aw5C:)+yV%1n*?v,i+$P[xs )e0#=@h33")48uZ;]u%GKcOF |y%~1!p1B]ɚ!oΰ`_$ +Awi&]^+,dӄOAVRޢiYu"5a)4CGGVf.EGb?Ba-lG0rży>d`8O0ܘ)^h*t@VL"~6 Hs %at;M0:<|^| =0;9;Jϻqc{Gd'< *-syƦǡ#Ӳ8嬈IaiB;頼<+8'M>]^#dEZfq8YA.\ %(ȉq.8/D:,:#ԄGIgϙw9)_,َ/@?|Yor 鷁}o/^q` 4؃3=3X4Oja* Z=yw9x")!!@< XƽgMgRhn b"V<++Ҟ4,CV? j0F__$ B`B < 2N${ i/mOxk`F5SGg'5Ԇl=T}}J`I&2{?sQ| VKl!>]Nj [] yf:ԃ*GimMSF]9Xҋkm:沴gX(Xn s*jë>3e_K/Zۚi<t Zb1^$z$@MD;kY`I5ZrKP =Mr䉸f[ Xac̗۩ C>6k{hbڂP&4"&Ip`J,Mr>|xxnuϾUx)c.sQL]V._##6+aLrC"*,Tl=Z)b]}o8_&3^7@vR |x(' y6{ctxy!++d8qpv23!Nr( fi@K<ßN^~)7A n)e nLar_&i|b{`xH=GXSe.c/cA}޼޶EgynL}L5"]>ɑb`FR'8uCu* ,3/~w~9+GGYb`t:𺠟c-s=qħpt,S #T$ JHRKgy׿6Z*97ڃ;Uן$= 7(_/8d#dU :uk(!/tX6HⅿI#D Bƒ%W~g%طG|cyW MPQȦRV I(ЀC7n&Nss X$x|׎/;>n*Uzŕ@Hz.Us>ۚ)7'Bg1sr0?QEqz'llGʇxq܊7./ݶ_,vNV`:C}ytG763[T 6&hŨDE'|HM.1X(3ϝ#: EqMފ7=e(S&^ˤzAHt`TQ3ʌ\P.cLj2lyli5f8-Q>6Bc!C(߼&|`9BVq~Xx=V[YɆ2d|V=~psKeI?r9@Z,JH4!Kcڵ+!ecOAronW|'IpmtYaƇ<+2 K=nwCVykm#/;oum0*ӭZ}ޢ)؟g3Kܾvki+;"ԌQ6A.wc_{ޙNѧϡs~K\~v zO.}4 nGYYƅ9,k%N^*5-p\jU½C t^][~M|y?#?\3AAL笘R3G;%JXf3lxǞ_U.oUV-lY(?;㚕w7Ey2VW(@Y,f Av9hVD9$t^6ra ݶÎ8NuU}K6 1߭vM,/ry^ O=</ΖNBqɧKuTx}ܶ#A\X=0Vvi& |ݹc7rDlWlĝ+84ࡦs׾ ^ P[OP!D[46b#-;AfILowRjb&۹9a,^TyS9CzjkJ'Vh@pN{԰[y`ȌXjwc%Vzp97jc-Xw7݋n [AU8*akƀ!8s]8wK>_A.!VcM8 !a/BMњܹN!I? >='ӊIENDB`fontypython-0.5/fontypythonmodules/things/view16x16.png0000664000175000017500000000144513211475353023363 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8]HaϻwsϥNOKDD C/EA7]T]duQDeМ9VmR8V8} sEF >U\nݹܼHx{} KK 6@jZ: %Ļ`}FIxPd5_Q B$*zAO+T4,PcukFk Ѭod"5o'Vg12v6}H<̲$IRIm6w/AYAMn$KӯِHxY{{cʩ"sfT:0_0,)IENDB`fontypython-0.5/fontypythonmodules/things/icon_open_folder.png0000664000175000017500000000062113211475353025202 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8JQFܽ+D\RJ[SlY+ ; VX b;A1q3ߙQR5FW)XDWs9t[X V4qYJ=;c1ul:QF ~9´3:P1@d ۚY$Sl ;O? ad.OFUkAӧc;KQeLE0@P;{ݭO=IENDB`fontypython-0.5/fontypythonmodules/things/icon_next_page.png0000664000175000017500000000160213211475353024660 0ustar donndonn00000000000000PNG  IHDR ½"sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATHKHTQu4T5fjrzlf-%QЃBvAB+-hFdƱ *Mr̜$2f>Lwν0ٹmM<}nn0DfșyWs1%]| 9().*/ X!l1 +KJJtq4Xփ* ȷ/Mwlʎ0t`HtlbS`HtSmd_z? IdxgOAAr\e=@Agr疍B (,6<ș3OʙGh:SV:̞r6#'>$$UfѲkۆC^DV>\˧k|!irbM_ \YFCHFkN?B£Վht"&Ci5 F1tP6^[j Pyh+ [ 1RI{q`!c,O۬Sc&qNjyOޛ 47܁Hb1 v:^r͹ONjubGS=̉2% n_ŃvwH~J%tw2 0v@ CXO '=|l:0sՙb sEV gp?1MЭhٟ[B%A$n}&6F<"p@*1ig.?zAaqRIENDB`fontypython-0.5/fontypythonmodules/things/splash.png0000664000175000017500000002373413212174765023206 0ustar donndonn00000000000000PNG  IHDRnp9sBIT|d pHYs+tEXtSoftwarewww.inkscape.org< IDATx}y]UosνR@HR5%A[{pp`hhhhh8N(~ pԁՄٺc<WVYqKϟH# i`*; q{UϾ/GO7QZ,0\SoH; s cOo8x`٢W@w *~OX3_.օ k0B`Ι'`3;C. !Cb𐡠P( p">##հ۶ I$% ?ϓZ^W~4b=qC^fcƬ1}l\:2 x=b6o†'~:;;W^hok%MkaE8y y]1 r9? {r^ǣK}0lזM>Rlg?%ܴh4&Jx2pkF-]<Ao.7N|y7+\a""r[hP#qiy$}_4@Mow W_-[tU|>Ҳk-D<ZoyA~1?wB @T~J$s BH@@8gs0B!DE5F_xݐ ҸwQc0? =|![h<~ ]KϭZ~!*ӛL7.?Kܢ7/_gTUUy>tx7!MPJFra|>B||BJ~PBP rUUUYW!_*T!#Krr:}ftB0gTeZӠ|!T a$?W谮nm]\&.nYl[κX ]6i2>/{u/O1- CÐ\>H(*HF BxiTJl!%'O-W;\aFgF.^ dpms %` nMvZ[x+~Uܸh,.z͠Z|s_2usZGb#( @ %V!E4%8c;W@b¤IZHm7*]68Tm]ݏaѧ0^~]_`.b *kp`9@ׂ@H~? /;aa|N{ah]=׸G ;G2L9Ch, H}! dm覎pkmlހ>asBo 4] @GNÖMե5gY77e)_,<_чGrԇҢPϒBL!RR10JBL҉?U044GKw9V@@_-0}lrrVpkPC w RÜ(ov\S@)(Q ,``)! (!2@$ R9|e`G0 |}G&=]Z4@#~؅cƸ#n3 OǛR*| # jq|3{LvGyȷ(ib~B 20*EBc(㑂1ʘ'#p|f %vx.J !9 (*u6?9|w$2i7ϙS qFcMo~F U&XrfDL6A#Tw@U8@ eR%1* ^I7ѿ0p+^'Ζ'd2K}_ph8ރi*Xx P2IM^o}/^װAuu 6bJE WhN)b=LN  \4vwUIjirՀ\R%I !aa-h e d w۵:\G\0D, wPnVBX!#[-8s@') 3\riFWP@m2G(/@ 48碁q~4œZW6/ wWܰSo~R#شyTWW 41(Kw@ź:/8 c cuRռ_fXF5 =#ޕ'ΔzP K ] "$ D A~wnv?( 00#0R&G4xh`D*-`1(([bA+Ϲ|7~\xX/:6@Sb>`0Rmm.E[ܨL8 /hvpαcfԀa81!e":j:j,ELdLAJ([@+@&R*L 1d_VR@Ep;zԺ~=dh‰.X@1?>#7A%KBSxռw@vxNzR%h+&Ҁz*J ;aȑ(!Bk*Qgi۾hMFv=+eQ3R sO9(@Dv9x 7\Fowڈ2+ MʠL֐Rm*.v>tBgl}x)5޶ƛB&:|8&to #@y(h}ZpH|H! ezyo`]@׳})Ӧ{-KEϕ.O*C'-w#q3JK1OKœ@U\?}i &0:qB#P T 1?cf]L/XaH`WϜ?r 򹂉k"`&pGP^]? 5"HύBi3}47"ϩTnhZ{M)t̝|*AX;x(\)r!lݜ}F8jduᇮb0I#F P[.fĿuKfpj;~|;uu͞$֎(P3M:7ȑp:D  uF?Z& "2$Қݮ#GaH,Y:]˧-sYQN-tvjN@ ۝5ɢ}9sD13zgǼ@ma5LTݞ6~PS$aÆa\3#tF#<@LOb= m}M5Uy\g";3 xXѳ @ 3B<ْa󧺪Wg3:_ A]M2}^~i'Rϕ H.|@ȓ~jk\h`i P U{x;Zɳ=i3gyF-2K|Nj7:..Lw >EvxLLf@ 0e YEC WWL ؂Ҭ䨧j ;B`iSܰxޥDs+ 0Ԃ.t鶜 S-<6牢joy>͋ O8̐uڛ,9xMMJ-N[.Ս'[Z >uaޡ*̗6$E$1:S5 BWw5 Ƹ]8=|0hh!d'T,Ay E=Xǵ%0Guv{)r2MRO&rI8@"Q1!'ο[q;f BT:'ZB<' iw54X{M ю\.dW@Yǐ*k)8R+U8kthDBkᇎob6i,?9AX>c\ҡȅ87 &8rh 1`ieJszk@Hb $I&_t|6pB)֚7BSGǒiI-4ܻlv:xY=uup%%e).xLC6?@l.lJORdwA/LO@]~/]b_v}&w5͵ ]&8et/9œ1JqI1,U#?-R$_ƴo>]6%Ǘ?5RLsY^4TݿT&_GJ(TӶ`tX*+/,FMr]58jF͍*v{ZPqTz,efv`e. mMjwfy R+Pɸ\R"1TYV\ ˖-ˋ+{4m?[vX2> c$ښ/^X$sSQܺgt{mW?ʕc&5I/-QTmAKzA9!nͣ^@t4]ؗ-g@ǎFk#w7S;+5HP`;qA,.Ƅl pރ.uVi'% &41oGoPXĪGr~S `b[4#ǩSR;!\ $cgBg"w4svwV+iY9޼Bpi#OIu?AUKmܟ%icfK>]bi${ b+Zpαoy^'U\ MpΕwM.7^1쾙I+[LoT\#P j+bB[za?uT71+<~(ƗP, PB6*h|N/oI*fu| O3_]oC Lǽ&{2ťk8|zԾ=0;X:?7z5FW4#k&=3ӑ=x)#cpjG?P~efe6נQ_5#GU<[>S o67o)e'=d)CL:P]Fu6Tm8F2IBSC+-nMIDATo4j2-wlؗ=EO f e&#JKK3^ۿ)rs6Xj9= T}J7f{ؿw}#_Vk5o_!E/؁RnmN5*೓+n$Q ͼ /%)/ݟLk?oG(p*߆bvY/kYUWxtALN8yh[0etw_{I,:Kz|0Oߺe3ŢqRǽsw{?n+^!&MBuo@~BqWw_}kYoMm{}87w\˶=$FQJhQobnW a>5 65T@܊ 7/>$xc_ L_Z%!Uk=֖+=6/^w\׳h=ժwSkʎzLASft(yU0Yvn^Hԍ_$FNkNCB_,~3SH\gSg ׳ǥN<}=U'`iO(稐Z7f"+Wvf65pNqm˾kWPI~_u^P[[+^|~=]${)E䫵O};<{C=1(BlٴLwG83p@u99ǁ/a]Q ۷v%3{zKݗ,i~{=FSSc`:|9])` Am.kH-d1.oZ؈&46GKs3߇=_ɺp('׽/7|-;Fpa>e@7=Kgng8FQ]Z\*L#6X"u ĭ[6fVhռGSԨbPS^/`nّ@|2_.»l<PU C)Ռ1oZfgx&q.wd`R~;R&y=c;ְbt'o>ĸ&{`sl' }@?[;U F\o4j1Q;OyL2;jBp S^{Cd@WJzWι dTו(NN1l+~&P!UWQISNSMǔi~w(|ay\VM<{ @[=<#o7/3Pc{PO[U@…:߲i#O]uJL:#(Ю 7 @ : p 5_zs}'R,=A݀\X'N .kVx3-IENDB`fontypython-0.5/fontypythonmodules/things/clear.png0000664000175000017500000000121513211475353022764 0ustar donndonn00000000000000PNG  IHDR b sBIT|d pHYs+tEXtSoftwarewww.inkscape.org< IDAT(kSam-|\ tH-jkCEPFJE%MLb'A$~P蠖d-)QHsoE襭g8xpD?73z}m.lR(B*%ܽs{B.̲L#7X[ӦihNѶܮٕ;g0y$G9t8҇m=xgg( j|pOCjo ù'0 J_*yl,7J9,;`Ckm VcEi}xIENDB`fontypython-0.5/fontypythonmodules/things/pog16x16.png0000664000175000017500000000106013211475353023167 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8+Qǿ̲ m-? rfRX_$ cPƄDe@ HzX?y +VW' +-5)`X.'v'ƯvGIENDB`fontypython-0.5/fontypythonmodules/things/button_charmap_over.png0000664000175000017500000000256713211475353025752 0ustar donndonn00000000000000PNG  IHDR ǍsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATHkLTG׾C*M]UH$VQæ?hŴXSmHG҂)[l0KVJѠÅ]{;waWE'̙ssE&EChzܻjU?YkVa?D~%? B0B*Wn>paSCCcwDQD]NX%Ͽͫx=|`ie]ʲϱ,nKqRbc1=×X :{[źKmom~Y2m}z&8,jciPkZg>g^~'lvIwc}ww=dd`P>pLV+Obmkr֍.m~E\JC̜ =7@sЮv͜5bLg`Lrkf}>_3HNy&Hy]\ xkWDihp龣ıoY[C̭o4Z^/ ވ&@Ꮇ=ZurmMぃݺm{Aj k6]2hX!>#$m7kn\$xvP!xYï/,|Qv?ȑR8W|?dw4MyS o..32O|E?{*dd,-olc` dZ"OBϜdyEMHL$;vJ EIV#jS(Sfz~>EBrLӈy0W`Oē1HӴJihql޼biIQ7(,C =:'Hh̶lzj`L&L9,$fgS@l6 ڰ3jXWI0  FxSK+{]`~m""_@Ql "@ev?l!UR<IENDB`fontypython-0.5/fontypythonmodules/things/icon_hush.png0000664000175000017500000000271713211475353023665 0ustar donndonn00000000000000PNG  IHDR;0sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<LIDATHoUݻ f4j`7P+FjAYəۆ^dژ: \)bf .b1TYD ޽ewű̝9<}syÈR!*A5&b\t970$eXP!$6sqtY{Iz3:"p^a`>)FKzS\&ٍhMXwn\7Ddkz8`>fV^1cFvTmo[;A++++:ԝ&)4 2h19g8a$+9 |_nL0 /y؇aUX֯h{x_&Z>yepZˁgp⪡[xuE9]n{cKW ԑ?VIENDB`fontypython-0.5/fontypythonmodules/things/button_charmap.png0000664000175000017500000000177313211475353024715 0ustar donndonn00000000000000PNG  IHDR ǍsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<xIDATHŗVW{jBӊiW2]j#O>FyYmj(k搋kdH={5?K ~uض3YB/x O/T؇3д4 *ZqZswQ$Ắt87 4ZA\~r Q?H?Deٿ=sYQIM\<+S)E6W^`Zk6Vz݁i@ܽKg>g[Yl{8,q"ю$G'p]~o%G|ćozIi^ u^2]5϶On{O?׎2վm `p;wr຾;9/|0ޢv\Uv׼R* +*č$1{_i]ϐX&S( [0@\̣44i4j'12FrtvϚN'`t2TW+e2"Q#5=P[]kKm˪¤wQT`&"wq3m[I̝ J$^!Nwkz5CܙGz6;8!,x,UKOۯhmg"tnE1m, m,x'*nM\%o2.}SϽG[EXr.5{r`hQT1OA;nP{FXBtku_n}[CP6`8-5Șmcux23\Z K/7G8ީ1Fʜ.,^l02ޭ}/@G)gE`WFy^ (|&œnuWĒX^W\$5T' طlpJEŢ:hLzP~_e'DE8NLkgVБ1Eb^ӯ.f|\Έhp@3v؁ՈhTRg & g=xFVfg׆Fc!}61xͫm5?>EoIENDB`fontypython-0.5/fontypythonmodules/things/icon_source_folder_16x16.png0000664000175000017500000000115513211475353026411 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8OhAiM$EjR"*=A= ZڋbAQ))tOb2n {%O IENDB`fontypython-0.5/fontypythonmodules/things/font_cannot_draw.png0000664000175000017500000000270613211475353025231 0ustar donndonn00000000000000PNG  IHDR szzsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<CIDATXVmLSW~ιܖa`A:G*4h`f3Q#D-[%KFe[bbGDEAb&MtS0@K`KK{=!"Ϟ&<}/ApYچfꏏ'xٲeiw F>1ݼ>&_'Gmt^I@"'F<  .n6 ĜSbb9?ɨOC#8)B@0]f]63 vS ҵߕG8fxC_rF&"o$GꁵdSLZzץf[Y\K@c#2 (qBc&(G/&iuݲr*QpÁj3[?/S^!m]~vfOGwo{4y+ν}!URVjO?ȺJV_=NB8z|cdKY!7m'I\Ǣ/Z2ZލLesSvvϼxQ3$7T(|>ϵj"#OGHbxD/@4 VP"?gyw2:A&r}LE{SO7 _MA]'5d_|o "#Rg!Mg/P픪9d jfׂG Nx`RPg(2<|ԛ>ODŰ}6A ,NaEDA yc\#?U(&uIENDB`fontypython-0.5/fontypythonmodules/things/ticksmall.png0000664000175000017500000000130313211475353023657 0ustar donndonn00000000000000PNG  IHDRNFsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<@IDAT8MH`6EME"D&H R +,4:}!)X]/Y!b!fE%Qa!-j[vhf^ . _#-7u/@$Ys,.o#߭1$%He`‘/-IںP식0>sȲ,8ؼ)HY ׼) MOt]/W\ixl!&,8\ U@?QS4&nLpʺ?}p<\d/9iA5~`B6݋Kťj[j K4h(L6HbUi0t,DϹ:*1γq$l *KoT5X(p?M*0&{'EȢ33#I:j1GBAt.V>iuKVFk&ӄgT+N]{-)#: ~R_ȏhy20)6EUWMƘ_!=y| PWx?03t)v7E| 9pp@ؒѥ7k>oIENDB`fontypython-0.5/fontypythonmodules/things/icon_root.png0000664000175000017500000000062213211475353023672 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8JPs(%Nlfq \|q8X88o {`iSw:%.ȡ&~͙s/Ys湬)'QB&Q=!GS&¡e+ϭ ~ (@p/?vrU7c7Pq_-bj'#[ǒ"F{mEh]Pŵw'F1+ 0WPAp66V zP "E$@UQIENDB`fontypython-0.5/fontypythonmodules/things/font_not_found.png0000664000175000017500000000262213211475353024722 0ustar donndonn00000000000000PNG  IHDR szzsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATXlSUǿ׾cp AM)LF1 A@?.md$LDt֮x}^־Ws=9Iؚ5 Q%0^I)2s!\EmhKIF$r:W?;kZR_^ PfGFT#i41> ]a08ѩ> y}邚)q/'JJ-͹712 1kٷO֫;J8#C8ʄ-+쾄4NÞBq_`F3;=몖m3_p&a*R;͔Y"1f8sؚyHEבqڟISK{oumNknn֝05++ϕ[v5w#|AC{{ iDVSUq9ޢk -8=g8aUSkG\બCjzҍx p.è߯F#5qguD7_5ޗS!E093<6_0-hO%iKwK3dc*aݹ~ [.2,|툂j)a C6?f _܇ 8N3 JaTuRRa)'Y0z(LFS3܂ús5;3{.1*/t>eP^Jp:f184ryS0EFd}> zrL9v)C@ `95+cΩ"wu)*%[ݢlT/U/]!Lyg6I!rG~iTǘ/V/R0Lii=<(|IENDB`fontypython-0.5/fontypythonmodules/things/icon_viewing.png0000664000175000017500000000232313211475353024357 0ustar donndonn00000000000000PNG  IHDRsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<PIDATHkLgP@ mAlX!,:1uɜKlHf.ɂ#,-[2 ScnLNL(^R۾>,0sr<$8R,hyH`%YS.y93tJmCx2}?SeJjŖʺpVs(]c;<Ǧ:%Ѧ`qaUZ;Sed` w`HMz.lvFYY+κ)(7i* RgE\PvB"oL+5<̅V& fܷYbUpeMJ>ݢy ,}R4>1o|iH)}sq;jb7bwTl=w+>ݑ/vM"${Bint/t,AFLRR% h!H95y$ *˵l0cFo\^{ 9FW엧Ek2!)-w&|lLVk5v-x,;Yvd\y/]#- ՟@u튦M?Ot| F2F 2acQ5A=~3'1CM@ő#gObaaN, pK d?UҧvXAHIENDB`fontypython-0.5/fontypythonmodules/things/README0000664000175000017500000004441613212036005022046 0ustar donndonn00000000000000Section One : Copyright ======================= The following images are Copyright (C) 2006, .., 2017 Donn.C.Ingle button_charmap_over.png button_charmap.png clear.png cross.png font_cannot_draw.png font_info_item.png font_not_found.png font_segfault.png fplogo.png icon_cdrom.png icon_closed_folder.png icon_drive.png icon_ext_drive.png icon_open_folder.png icon_root.png icon_source_folder_16x16.png icon_source.png icon_source_pog_16x16.png icon_target.png icon_viewing.png pog16x16.installed.png pog16x16.png pog16x16.target.png splash.png tick.png ticksmall.png icon_bold.png icon_italic.png icon_regular.png icon_prev_page.png icon_next_page.png view16x16.png Section Two : License ======================= GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. fontypython-0.5/fontypythonmodules/things/icon_X.png0000664000175000017500000000102313211475353023112 0ustar donndonn00000000000000PNG  IHDR Vu\sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT(m;o`٢6vB!(B@ DRPy * vҽ+bH-A TTENhCyo ׀˜vLqCDq!p,/-&``3UuD1؋£kV(0 0g|z/xy[`elK0.pg"8gFVP'5'?x}ܦ:>vzҹ 7_YfjB^)J(;_e'? p$"+^)oie? {:[ȣ1myopwm|huȝQ3onk{:*g& +tj ĩrW;^W_"R5'y ܟIENDB`fontypython-0.5/fontypythonmodules/things/fplogo.png0000664000175000017500000000221113212237744023162 0ustar donndonn00000000000000PNG  IHDR szzsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATXYhU73ՙlMR.IHg2PhEQkRppAK` U*(D( `Z[44L ,ؘI263LJ/w2I&/Ås=;]j%"<nt 9(| |XKq  ǘ/ ,v0`\A%}*FGsxh/ vA(`P$T=5^x\ݝn+Q~9fL8ҍL͆[Kc{>o½JIM 'YY8RŋvIJ!nMM@5/ ЦjӎĶLbjt:ٜ_WRj3Ij՚ffuH4]%ǨU |ZM7/sUݣi}IENDB`fontypython-0.5/fontypythonmodules/things/icon_prev_page.png0000664000175000017500000000157013211475353024662 0ustar donndonn00000000000000PNG  IHDR ½"sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATHV]HQ=wft-Dub)"%BEC^-( I0T|衞r$]+Z*tq`ItsםUםUp=~a`.7e01fp(&AhR 5h-5g 9Ne*_-GXIlq#Wݚ4lxgƴ94σilZl`>tXn8Q_HXIzs3'ќ5 =WeࢩO~gxZ'Qd=`(=l'R: nI J~$dXNԧ,6Bl㬭2B\nwr0V#w`$Iu0oHYi,Rm,R2ʌ-ۉӆ娈뾋A㭱WƂ ɀ߰fM"_J\ nF0p4f 8 ^Kf)|YM/_pHBOʉ@7^?#s̽ẐU ךaO Ž5zY*IȺ _r>Q'fĨmu8>u-h=q4ӣ4~isi2)u&<d(;CAӝpŠDonND;rR:4e@@םM!Qƿya,3x=<)/г"x0_Lrp13㝘{y̘c, 7qmkvBQe@IENDB`fontypython-0.5/fontypythonmodules/things/icon_ext_drive.png0000664000175000017500000000043613211475353024703 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8푽 0?;D I9Pq;2l`-"m^w},1t&T`wlK51?WsTWV70[`&Iڨ% UL@NB粘L (m:swfq|z/mIENDB`fontypython-0.5/fontypythonmodules/things/icon_source_pog_16x16.png0000664000175000017500000000102213211475353025714 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8;KAϝ2!pD9rpt-D` XfrM<3=xBUU@/MӼ F]&?@;P1 ߑyv"<dh 7ZIENDB`fontypython-0.5/fontypythonmodules/things/cross.png0000664000175000017500000001272613211475353023040 0ustar donndonn00000000000000PNG  IHDRFFq.sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<SIDATxyp}?g0qI"AR"iALu2deI72Id[VV덼vjTI)6qĎG86UFex A38`0sw1$M{HV ՟y~{nS*"R >PVJ ,KU}˾p4+]ΧɧrAZd8#oHjVXzEEG~oGeW^з<ۀ\,v0 M&+qP0}޽zq. {G?SOsge| ^ɜmo]g ~gzk㱬#I;Ou[{($$`Mz. feO7څͷ,l 9sO?Ϭ1j꛷uǖx6IkX3wxf|c{c.RGg\m$ >2ܳg/oeر[ڶp/BH;>Fujh^Jnēӑ$O?_d?kv|kYk>f{68;[ə=6zd|y_^sDiוO|˟z}yy~O;d;^?C&z/uL |>ϫX.וM~7 󷝎$xX?1[_bDylFԭ]Jgb#UzGY ~GoRsz $ʸ3IT9MW^[f\,PĝhJ "b7*-M#i^ɮf V^yy c:6d՟΄3"AcInO]WSRV\ 3ݷp  $7/i ;t,0;hC2~GD>~JQY VWee %P-t@*lP+, ƶg@u5#gkY0@o"̒b^?R6 Ko6az" ̠ȕݝ&59 LS0v=O D\b7^r8jm-&=-ׁo?爐lʢW[QczoWCb @%ٙ.l?aע \^Uݗ@k-D躲KmJ(ILVSP2F0{ Z 'x?{Y:X_CьDZܚPMhO#3V+|jvxQDz=?mFZTp8s߅ t`9H\ huhb9~eJ{L6b%+>ݲ2ا\7g*E,? TJ)jol2ʿP3B_;fC DdMVr:lލ3z:8C0juٿL@S #ƒ~edY~`u;n}[Q皡osu\G l~u(!-}̴'1a,]I:;2c__9T<]7[@mEێ֓"GAG;'Sz7\8]C6.uz32'²3Iu3Î_g[}Kx=]7܏ z0ZKXD $ hm5S.t3dqiI+t9/qL8pd<Η*Jws`(oƛT7?%pzZ/@Ij$$H 0b1О_;a"CJħESpׂ7U3Xm}~mOK |SA>(s݌NTo[B#"4p8JZw`$q^¹iy1ƒUPX`媙3I*~[!ȏޖC "y]ZZ[34 Ҭ)O21FYjނ a&0-ec1Nvw0:i0)-'q>֕NSSCp~q@NYY<1;X ,$<k*@qr^ߩmDkE5:Ta?;7{ͧ01))HLcŪ]/Z]]pm[DjPRn6YH `rRS!E<TʖWiXjq?nCcsؒz6;KA͒F/RTz7S`YPZtBW#FwKLj@FØF Xȍ9n!:]$2JxˠZ:)@נ!tntQ5˓ xW12kAetjN2GAF^\tO 5%i=agFP@}do9a?6Yjj3,y_ץ|dŭLrł9sJ[v5mX{+B35Hs\~#I>D!e?ţB`Y(_xtC99nnu0bݐs%#hzdT访Oqܰ5FDLq^Ҧ\(-<اׯ{w[nr~FDȯ?~X?rPܱ׺}?x8΢k88e{v-p=_3ј>q7;B]E#"Mkw p:G5Nڴd ɏ>;L^f♂s;!  L<μȷW/Gf\1XNb58qbZ蓬E;ië&hlNPH1L T1ˌH֙V|`&PlXTmzL.ܚ< P+̗N e4ע cZ - Pȇ {f˃ӃiB) QΔшO@8> k6>7޹ivYwީJ2==/dgOó#NK"Ԣi@Q4ל[ ԃW&CfwӯhsKV:Ƕ{}yc9foz#.I\,Bh(aTOSC4$/ܺ&NL(@TMG^ A۳6ask_(yVC$xR\nSFh40-hjDh"*Б6/I8U8F:c @JJHcwG86!C1 Oi!&D}#09I֧0b#945d%Vtf /G(8' p5ٙ Jqai ) -B95ד3&9O0Lк؈x m D`M:~ }p-DXVH貏v,+Ye9sQ*йTGgT fH EK>J9 ӈ H}aVu*+HF H-j:>ZP QJDHjqDD5h}~>WpTU&e `ʡ{ JUUBڊn`%@(8J q4}s:DW#: 0XGYfX@0~#%qʈ ;~𫜬IENDB`fontypython-0.5/fontypythonmodules/things/icon_italic.png0000664000175000017500000000050413211475353024153 0ustar donndonn00000000000000PNG  IHDR AW.sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATUɱJQx&-bp8E(@W^I ! ^@C7o|- w|TyfͷVοH}TW)-lsZ}2u|6u tEd*6L>2(nDt DDO5 w`,E^;8IENDB`fontypython-0.5/fontypythonmodules/things/font_segfault.png0000664000175000017500000000300713211475353024537 0ustar donndonn00000000000000PNG  IHDR szzsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATXklU}tڎ]* "РEIHԨ1FL4Tax \M" حl[KalЮҤ9>sNR[oY^V fPȀF,~sexʋgd 1" <B%fB@e8GG Roȭ^*{AIF }Y1F5luTM V9{ ^}2K8^ o٨ޤKO4' Ve3&=NT^TBJgۼvŴ8o]mmmƌEEE$_Y3_J8>=r{k{>v%/x;n*0qʲIV1jonjzLIT.{·,evCfFUeyQZ<-x˓Xls'|=}ȠkǤ/ MC`nLN6@؍!18.5%%ՌMuX+,€x@x1x ʴe٘j6$ gfw b#,9sMm.TDcT+uMD 1r2t"9Ye Y*j{\h CfF1„Y{ ;q8 OUESϔVt8$1`1ٯT++X1]Ue@s͑G/MyӉGWʲثF)%aMk&Р r̢ܝxݵ#El/OiT3E=6\u+f`L!ބ?i1`cf3H;1dROk1>YIܨcO M9"nZ'#iQ=iZZ4-7 쌿LyT&}yZ@ܲu^u kMܔ@k[+ӚG2V.KCL{JIg`GQl3@kG1w~ {VeaY %&zt54JI큃s|slf;zS4|`v|Psty&@'ؽ@ C. r;c8c_dƦ=ep:׭cz56w,0=QdBvB x* @'qr8d0]/Ç/?RQge_inIAɖ&H@>@ۢlj_s/>!LAMƮ0fN3PkG_|ȵTf€D#X?ƇЫj??]jEcDCvzT 'ESIENDB`fontypython-0.5/fontypythonmodules/things/icon_settings.png0000664000175000017500000000154513211475353024554 0ustar donndonn00000000000000PNG  IHDR?~sBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATHOU{ZO)EbgZJZE 1E\D E.ƹ7,(6IѢ [H)AЙ" PJkܱofw3Yy|῎̚x9F6[kvĈ 6̚8U8%=Mmѫb?nMV:iŠ2˺7µĄptSaig G0J u`PQi ̔s Gw,A>rFOm4h8Ne^cvVaҚhX רX+< A,mb@WH@[:' F%6m/31P-ǝUiMDŽ{qC+g !gJR-MwuXb\xWu3h +pLxl xV[Z)ė3(,.. t5R6pA"R9kMOZ_06Dhj3aSt j®VEs٥ 9ki_4Kk[}ZT_݋9yBW.omuC='<&PιE.ElLP`4WZTIg;`҇u;︮y ~;Zgt}k*4#aP1v֪|BOυH캶:h۸[x.r Y`W^rǢbq o?Uݺ:U0yrN!d4Z@R!э@$ц TKvlCyyEČY N|HhÆH6`O@!J,rzL"]#M]f| łZmYeoE'`jA^r-ۯ&+Fja3;] 滊P D/7o?t1A#?w ѶtǶh\ӭp=k&NV~;1mi_Y֟Toy-.խܝ9xnH3n~2i;K*'O4;I knڧ[zںtD 4 ԍF:6*³w)w!uXa#238-0c `^vaMu?uI8C%4<?C0t5z0)̝LVZ\j'-:/xguf<@S$q?D@QQ S$QWsˮSL%HriCn5UVEoYDV%dsg٨,Ɗ٦/s#Gdo?q&)á HYS¯E?|LMw0Di.c $:z';T*'LbP$_3tpc:mAtԦb_ ׫>'PE[yX4p!4&i`ׅCC_L@QNNR̪Ih_ck[fסc'0w} =<8:6zk`t5r-d$ut 6fcg.2xw rḱ<0 dE8(&dhJZ@ȝ 1⤇B54g5Z,<|=E&H^X4( U?c-jBcG{hTt;E9GC$1eS Nڸe>osy$Kx+Vmޙ1L1.MN92 YmdjISY|;Cץ̺⪾o%ڷ[f7/OouwH goaHlRCkED&^;0JJB%׌ܴpٸq}7)7iξ[hs(q8msȨ cJt~ܽsn۷{]irŢwYxvjN%aa(U*Fda> &4t9DA<['9%iI\D6Q- ,_D^z}953V/D0c6ccsw"M׸#ē&>@ BĒe18b.gc OyRLIOtHO5%>OF , #==ϰ#8DSNGynk8iJo$^w6}t;t8hAhx^>!fl(xC5tuiOpיԘiƒ>k.ɨjHvOzN+rw 6@z5|m ^coOS6(ِ8ndzAVDbP\CkzN̜\:{Mp0c|Gr`0 (+<< p8>=R81Y9ud7EkܮUА)W-~lX>]G~"Tk Dpx|&Mx!h{υED:kn!Щ 0ݡ wsEE&©<@c{|XS6S{!^T+]X̽F$8h&/$GEUM AAcc-gegg m|BgOӍhDQ &ʳVK+'⩲Eu|@DAm. AYA0l*`FDAGS AXm޿_n*6>>j'&DX{tL" ˯HGefHwwW9-e]NqW dS}" >=SM"Ng;hokEE Dh9ތucߏ{H5UTk1LמZ /pu~EQd؈N %;A5g'*98ɢpںG8^ܮržv? I]1F #~+; óO>UNrʩX" v͹drĤ$ Ȩh[|<b@WWb!%uuG;IcXǘf*n;,WlC|QI. M, RrY[T4hINIE&Ԗ^CSqqj')ѭTU3lR/Xr*BmGTI2r /?W'eL* {=ti0zk `[O0[zBx*GffE]f\rǟYm'׽4.IwaWDj/06R1F1:w\_ }&\OMpO7&?ll SxmGsr{ 3o"6.py+ slHU M\Two(BLmGSu$':ʎYv1d cKP<}}(+A [uE&L[jKTwGTȺd"0{񳔕fo%KMdu;ghLJ3@]%˪1^uImbeY&sYk(ݎc4MΆP|a{ @&Hfv.c=$CHT~ĸ|RSRKH쇀PvYƦv DDc ї-x~l«g^ ;o&oijUrYZ-kJƚx+F(o"g]B//n >Fs:Lگ䡼&.<鑢.rw\鯏6r"i8fy cލrӻچg"LR ) Щ|䡼seppm~dμ *[$(nKkdZ^^p WM>`{K-^ =fe%pkf_zޓ3a񇝬Y9r=ZhTqDz`5!+I?ΊrI{}鎗=VFsbltrem6+4}D[tԞ 'ѩ.&n#R˯xujbZOV֖O[/=CӁϙ2r)Fl@HD I2Z}UnzCmqWO1 /UrU f9 ,}CosWuPѭh#$5‚mĄH"#߳N V Yb7cwH.}?< 'f$,JIs\XHbwsvJ^9V̑vV%Fl m'}M&csDPP0y*mj^|WF 140h8w֍;'9%{ӊ{@-ON'VU~vN56`^m>YȠA$;L&#ct& rY xd6ob٧I ]">)E$fϽ[N/݉>+.x9H \bT04{H10x0QWXl2ڻnpQCeM(&OszngMJfշkxǛjSƍ{*1YBQ~kҭLny ϛiyje*j`~hm9ʉ"R &>!d2rHKzp,ZOM^!]lA@8*ɘXeGqQ~1vLYr*ٌr]U_~lXK=b ]79v` Hڤ!ߴD""5 (A6HsT3.RBz <8Q1eʣ3]C㖤:6GWWKʰÐB.Su3/<$_ʘ7zض{IJIeúf^:;PzEDFz$&ex#VVS\ZQSovUH}$qΖT*O$&6Aaa B B.(U*^] 'ɛ0GQ Gս(*-~ V~&Y־Ur4gpB?΄^߸AB6~W߭_,I12he[#>|JuG,8.j!WXIENDB`fontypython-0.5/fontypythonmodules/things/icon_drive.png0000664000175000017500000000103113211475353024013 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8=kQ@}Ɲ2˼Tq?-2;1ՈA !*Va`;KY1FXl"f`'b얙bwELSq]w[KtAybx@~|kaLjȱZ6m~5JLFq "TkU\Mz+`HZ(Ke荣 s.wM;Pf]?E"2cYŠ 0ںwb<{yqCxW`ڡXEEG^l?;UT*ĊЬcfj1Aq SYy 4n&\_T.UjKkA_?w=Ty}p)*/W*"OR頤=1RAl|7qn){IENDB`fontypython-0.5/fontypythonmodules/things/pog16x16.target.png0000664000175000017500000000123013211475353024453 0ustar donndonn00000000000000PNG  IHDRasBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDAT8]HSa{># 8C[IFsv ֖`EQoB"F.E6(-"(.rP71sH4Xmssݴ`AyX-Z" Fo=[Zg/qu @5.r}!zI``g2+'G] zoQ^i-o3[YA uzR|5 K(ZlFAa O@Kj13WW. import wx, locale ## June 25th 2016 ## Remarking these two lines because they are causing a segfault: ## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get(): ## create wxApp before calling this ## Segmentation fault (core dumped) ## ## I do not know how to test or fix this, hence simply removing it. ## AFAICT, stock buttons will be in the system language. ## ## Setup wxPython to access translations : enables the stock buttons. ##langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG ##mylocale = wx.Locale( langid ) from pubsub import * #I want all the topics. from wxgui import ps import fpsys # Global objects import fontcontrol import fontybugs from fpwx import wxbmp class PogChooser(wx.ListCtrl) : """ Basic list control for pogs - instanced by TargetPogChooser and in the NoteBook in gui_FontSources. This single class (being used twice) causes all kinds of twisty tests. I'm not sure how better to do it. """ ## CLASS LEVEL variables - Independent of instances. ## i.e. common to all. __poglistCopy = {} # To help in sorting. __TARGET = None __VIEW = None ## turns-out, we can also fetch these via self.xxx icon_normal = 0 # empty P icon_installed = 1 # filled-in P icon_targetted = 2 # triangle icon_viewing = 3 # eye def __init__(self, parent, whoami, select = None) : """ select is None or a Pog that will be selected in the control. """ self.indexselected = -1 self.lastindexselected = -1 self.parent = parent self.whoami = whoami ## Use Class-level attributes to record the history of ## the instantiation of this class. These vars do not ## belong to the instances, but to this one class. ## We keep refs to the two parents of this class. ## __VIEW and __TARGET are useful when I want to ## refer to the *other* one from if whoami == "SOURCEPOG": PogChooser.__VIEW = self style = wx.LC_LIST | wx.LC_SORT_ASCENDING | wx.LC_SINGLE_SEL else: PogChooser.__TARGET = self style = wx.LC_LIST | wx.LC_SORT_ASCENDING il = wx.ImageList( 16, 16, True ) il.Add( wxbmp( 'pog16x16') ) il.Add( wxbmp( 'pog16x16.installed') ) il.Add( wxbmp( 'pog16x16.target') ) # Dec 2007: triangle target il.Add( wxbmp( 'view16x16') ) # Dec 2017: little eye wx.ListCtrl.__init__( self,parent,-1, style=style | wx.SUNKEN_BORDER, name="pog_chooser" ) self.AssignImageList(il, wx.IMAGE_LIST_SMALL) self.fillPogList() ## Highlight the pog selected (the last one, or the ## cli chosen one) ## Done manually because things are still in an __init__ ## state. if select: i = self.FindItem( -1, select ) self.indexselected = i # Set to help initial icon settings self.SetItemImage( i, self.icon_viewing ) self.Select( i, True ) #else: ## Nov 2017 ## == "FichteFoll" hit a bug here. ## When fp starts with zero pogs ... :O ... ## there's an index problem with self.Select ## Fix: Just exlude this else branch. self.ClearBackground() self.items = None self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelect) ## This one is a double click event ## self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.__onActivate) #self.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) ## This subscribe line here will register TWICE ## with the global "ps" - since this PogChooser class ## is instanced twice (view and target). ## I.e. There will be two "self".ChangeIcon funcs ## fired on any one ps.pub(change_pog_icon) call. ps.sub(change_pog_icon, self.ChangeIcon) ##DND: class PogChooser def Sorter(self, key1, key2): """ Fetch the strings from our CLASS LEVEL copy of the pognames so that we can compare them via locale. """ s1,s2 = PogChooser.__poglistCopy[key1], \ PogChooser.__poglistCopy[key2] ## Since the gui is unicode, I *think* I don't have to ## worry about errors here. return locale.strcoll( s1, s2 ) def onSelect(self, e): """ pognochange: means No change to the selected Pog. """ wx.BeginBusyCursor() self.indexselected = e.m_itemIndex pognochange = False if self.indexselected == self.lastindexselected: ## We have clicked on the same Pog as last time ## - ergo do nothing. pognochange = True # Record this for next time around self.lastindexselected = self.indexselected # Gets UNICODE !!! textpogname = self.GetItemText(self.indexselected) if self.whoami=="SOURCEPOG": ps.pub(source_pog_has_been_selected, textpogname, pognochange) else: ps.pub(target_pog_has_been_selected, textpogname, pognochange) self.toggle_list_icons_according_to_selection( pognochange ) wx.EndBusyCursor() def toggle_list_icons_according_to_selection( self, pognochange ): """ Dec 2007 : This took me an entire day to figure out. Man... Dec 2017: Updated and added much remarking. Ten years later... Hello past-Donn; you wrote terrible comments. Determines the images of both list items from the pov of whether we are VIEW or TARGET. (The target control can have multiple selections, this factors-in too.) This is called from: 1. wxgui: __init__ 2. gui_PogTargets: clear button event 3. gui_PogChooser (myself): on select event """ #print "self.indexselected:", self.indexselected ## Is there is an active selection? if self.indexselected > -1: ## Yep - let's work: c = self.GetItemCount() ## A little test of which kind of a McList am I? iAmTargetList = self.whoami=="TARGETPOG" for x in xrange(0, c): #li = self.GetItem(x, 0) # Oddly useless. # WE ARE THE TARGET if iAmTargetList: ## Installed test is for image index 1 #isInstalled = li.GetImage() == 1 isInstalled = self.GetItem(x, 0).GetImage() == 1 # Only if NOT installed do we even try to draw # the "triangle" target icon: if not isInstalled: # We are on the selected item. if x == self.indexselected: # A: pognochange == True # i.e. The same pog is being # clicked again, thus it can't be # the target anymore. (It's toggled off) # Change the icon to normal (0) # B: pognochange == False # i.e. A different pog has been # clicked. It's a new valid selection, so # make it the target icon (2) #n = 0 if pognochange else 2 n = self.icon_normal if pognochange \ else self.icon_targetted self.SetItemImage( x, n ) # This works. # li.SetImage( n ) # This does # not actually set the image. # I can't burn more time on it. # We are on an UNselected item else: # It is also NOT installed. # Make it a normal icon (0) # This is done because we can select # multiple target pogs: we only # want ONE target icon so we must # switch the others off. n = self.icon_normal #0 self.SetItemImage( x, n ) # Go adjust the VIEW as well. # If it's not an 'eye' (3) make # it the same as me: #vi = self.__VIEW.GetItem( x, 0 ) if self.__VIEW.GetItem( x, 0 ).GetImage() != \ self.icon_viewing: self.__VIEW.SetItemImage( x, n ) # WE ARE THE VIEW else: # We are the selected item if x == self.indexselected: # Make it an eye self.SetItemImage( x, self.icon_viewing ) # We are NOT the selected else: # Make me whatever the icon in TARGET is # It's my way to remember what I was. The # target icons are a good reference because # they show: # 1. Installed/Not installed # 2. Targetted item n = self.__TARGET.GetItem( x, 0 ).GetImage() self.SetItemImage( x, n ) def __del__(self) : del self.items def fillPogList(self): """ This is among the very FIRST things we do. Fill the list with pogs. This will CULL any bad pogs (i.e. those with malformed content) Thus the PogInvalid error should not happen any more after a run. """ # pl will always be a BYTE STRING list pl = fpsys.iPC.getPogNames() for p in pl: # 'p' is a byte string. ipog = fontcontrol.Pog(p) try: #catch pogs that are not properly formed # isInstalled opens the pog file. if ipog.isInstalled(): i = self.icon_installed #1 else: i = self.icon_normal #0 except fontybugs.PogInvalid, eInst: ## An "invalid" pog is one that does not have ## installed/not installed on the first line. print _(u"(%s) skipped. It's an invalid pog.") % [p] continue ## Let's try to make a unicode of p so li.SetText(p) ## can display it: try: p = fpsys.LSP.to_unicode( p ) except UnicodeDecodeError: ## We can't convert it under this locale print _(u"(%s) skipped. I can't display this name "\ "under your locale.") % [p] # Irony in print! continue ## Okay, we have a valid pog name to use: li = wx.ListItem() li.SetImage(i) li.SetText(p) ## June 25, 2016: Something in wxPython changed ## and li now needs an Id>0 (Capital "I"d. Weird) li.Id = 1 id = wx.NewId() PogChooser.__poglistCopy[id] = p # record the pog name row = self.InsertItem( li ) # associate back to __poglistCopy self.SetItemData( row, id ) self.SortItems( self.Sorter ) def AddItem(self, pogname): """ Add a pogname to myself, then sort. """ li = wx.ListItem() li.SetImage( self.icon_normal )#0) li.SetText( pogname ) #July 5th, 2016 - wxPython Id fix li.Id = 1 id = wx.NewId() self.__poglistCopy[id] = pogname row = self.InsertItem(li) self.SetItemData( row, id ) self.SortItems( self.Sorter ) def RemoveItem(self, pogname): row = self.FindItem(-1, pogname) id = self.GetItemData(row) self.DeleteItem(row) # cull from our private store too. del( PogChooser.__poglistCopy[id] ) def ClearSelection(self): # removes all selections, even for multi-selections for x in range(self.GetSelectedItemCount()): self.Select(self.GetFirstSelected(), False) self.lastindexselected = -1 def ChangeIcon(self): """ Change a single Pog's icon to installed/uninstalled. ONLY called from InstallPog and UninstallPog. """ #print "ChangeIcon:",self T = fpsys.state.targetobject pn = T.name index = self.FindItem(0, pn) if T.isInstalled(): n = self.icon_installed #1 else: n = self.icon_normal #0 self.SetItemImage( index, n ) ## Found in wxWidgets documentation! def ClearLastIndex(self): """ We need to reset the lastindexselected so that a click on the same item as last time will register. This is used in the Notebook when the page changes back to page 1, we want the user to be able to re-click the item that was clicked last time. """ self.lastindexselected = -1 fontypython-0.5/fontypythonmodules/fpsys.py0000664000175000017500000011340513212243531021407 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . ## fpsys : fonty python system. ## I debated calling it fpglobals. ## This is a common-ground for variables and defs that will be used from ## other modules - so they are global to everything. import sys, os, pickle import linux_safe_path_library import fontybugs import fontcontrol import charmaps import subprocess try: ## Sept 2017 - Trying to get XDG compliance going. ## == ## I tried to use: wx.StandardPaths ## The version I have to work with (3.x) does not support the new Freedesktop stuff. ## Therefore, I must employ GLib.. ## ## === ## Freedesktop specs and GLib. ## https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html ## https://developer.gnome.org/glib/2.40/glib-Miscellaneous-Utility-Functions.html#g-get-user-data-dir ## >>>from gi.repository import GLib ## >>>GLib.get_user_data_dir() ## '/home/donn/.local/share' from gi.repository import GLib XDG_DATA_HOME = GLib.get_user_data_dir() # ?? What kinds of errors can happen here? XDG_CONFIG_HOME = GLib.get_user_config_dir() except: ## Bad things happened. ## Let's try a direct approach: ## I set these to "" (vs None.) ## When os.path.exists happens (later), None chokes. ## os.path.exists("") gives False, which is good. XDG_DATA_HOME = "" XDG_CONFIG_HOME = "" try: home = os.environ["HOME"] # Is a byte string under Linux. try2 = os.path.join(home, ".local", "share") if os.path.exists(try2): XDG_DATA_HOME = try2 try2 = os.path.join(home, ".config") if os.path.exists(try2): XDG_CONFIG_HOME = try2 except: pass #print XDG_DATA_HOME #print XDG_CONFIG_HOME #raise SystemExit ## debug test #XDG_DATA_HOME = "" ## See end of file class PathControl: """ Instanced here, in fpsys, where it is used globally. TASKS: === . Sets an error dict and *returns* on failure, does not raise. . Switches on whether there exists a valid XDG_DATA_HOME directory. No : Falls-back to old ~/.fontypython and ~/.fonts (makes both if needs). Yes: Starts an "upgrade" Makes new fontypython and fonts (if needs). Yes I am going to put all my shit in data_home. Moves all old contents into new fontypython. Moves all symlinks that were in ~/.fonts into new fonts. . Provides methods to look for what errors happened after __init__ . Provide paths for fontypython. . Provide list of pog names (without the .pog extension). """ __FIRSTRUN = True ## All these vars contain/return BYTE STRING paths and files. __HOME = os.environ["HOME"] # Is a byte string under Linux. __fp_dir = "" # "" vs None. When os.path.exists happens, None chokes. "" gives False. __fonts_dir = "" __app_conf = "" __fontconfig_confd = "NOTSETWRONGBADHORRIBLE" def __init__( self, XDG_DATA_HOME, XDG_CONFIG_HOME ): self.__ERROR_STATE={} ## Class var to detect the very first run of this code: if not PathControl.__FIRSTRUN: print "PathControl has been instanced twice." raise SystemExit else: PathControl.__FIRSTRUN = False ## Fontconfig ## == ## According to the spec: ## https://www.freedesktop.org/software/fontconfig/fontconfig-user.html ## This is the user path I am going to use: ## $XDG_CONFIG_HOME/fontconfig/conf.d ## ## If it's not there - I make the path. ## fcp = os.path.join(XDG_CONFIG_HOME, "fontconfig","conf.d") ##TEST: #fcp="/root/fontfoo" if os.path.exists( fcp ): PathControl.__fontconfig_confd = fcp else: try: self.__try_test_make_dir(fcp, "NoFontconfigDir") PathControl.__fontconfig_confd = fcp except: pass ## If the fancy new XDG_DATA_HOME does not actually exist, we want ## to fall back: ## I don't know if this is even a possibility, because the ## docs are horrible.. :| if not os.path.exists(XDG_DATA_HOME): ## We are in fallback to the old fonty dirs etc. fp_dir = os.path.join(PathControl.__HOME, ".fontypython") try: self.__try_test_make_dir(fp_dir, "NoFontypythonDir") except: return #Serious error, bail. else: PathControl.__fp_dir = fp_dir + "/" # Record it for use. fonts_dir = os.path.join(PathControl.__HOME, ".fonts") try: self.__try_test_make_dir(fonts_dir, "NoFontsDir") except: pass # Not too bad. Fonts dir will be None. else: PathControl.__fonts_dir = fonts_dir +"/" ## End of old fonty fallback else: ## We are in valid XDG terrain: ~/.local/share/ (or whatever) exists. ## We may hit perm errors within there, I guess.. x_fp_dir = os.path.join(XDG_DATA_HOME, "fontypython") try: self.__try_test_make_dir(x_fp_dir, "NoFontypythonDir") ##TEST: #self.__try_test_make_dir("/root/bar", "NoFontypythonDir") except: return #Serious error else: PathControl.__fp_dir = x_fp_dir + "/" x_fonts_dir = os.path.join(XDG_DATA_HOME, "fonts") try: ##TEST: #self.__try_test_make_dir("/root/foo", "NoFontsDir") self.__try_test_make_dir(x_fonts_dir, "NoFontsDir") except: pass else: PathControl.__fonts_dir = x_fonts_dir + "/" ## Decide on what can be upgraded.. # If new fp_dir exists *and* old fp_dir exists, then we can upgrade. # Since, by now, x_fp_dir does exist, we need only look for the old. old_fp_dir = os.path.join(PathControl.__HOME, ".fontypython") old_fonts_dir = os.path.join(PathControl.__HOME, ".fonts") ## fontypython dir. ## After an upgrade, the old_fp_dir will be deleted, making ## this a once-off: if os.path.exists(old_fp_dir): try: self.__upgrade_fp_dir( old_fp_dir, x_fp_dir ) except: return #Any errors are fatal. See upstream for handling of it. # if new fonts exists *and* old fonts exists, then we can upgrade # (new fonts *might* not exist...) hasnewfontsdir = "NoFontsDir" not in self.__ERROR_STATE #Rather than another exists test. if hasnewfontsdir and os.path.exists(old_fonts_dir): ## Okay, both dirs exist. ## This method ignores all errors, hence no try: self.__upgrade_fonts_dir( old_fonts_dir, x_fonts_dir ) PathControl.__app_conf = os.path.join(PathControl.__fp_dir, "fp.conf") ## Private Interface: def __try_test_make_dir( self, path, errkey ): """ Path exists? No: make it. Catch and cache errors. Returns nothing or raises the error. """ if not os.path.exists(path): try: os.makedirs(path) except Exception as associated_err: ## Let's decide what to raise if errkey=="NoFontypythonDir": e = fontybugs.NoFontypythonDir(path, associated_err) elif errkey=="NoFontsDir": e = fontybugs.NoFontsDir(path, associated_err) elif errkey=="NoFontconfigDir": e = fontybugs.NoFontconfigDir(path) else: # Unknown key print "Bad key in PathControl.__try_test_make_dir on key:", errkey raise SystemExit self.__ERROR_STATE[errkey] = e raise e # Let's use our error to communicate with the caller. def __raiseOrContinue(self, errkey): e = self.__ERROR_STATE.get( errkey, False ) if e: raise e def __upgrade_fp_dir(self, old_fp, new_fp): """ There are quite a few files to move: fp.conf overlap_counts segfonts *.pog Let's just move all the files! Then, rm the old ~/.fontypython dir. On any error, it records and raises an UpgradeFail error. """ import errno try: ## Start out cocky - just up and kill old_fp ## Only fails if the dir is not empty os.rmdir(old_fp) return except OSError as old_fp_rm_err: ## Ah, it's not empty: ergo upgrade. if old_fp_rm_err.errno == errno.ENOTEMPTY: import shutil try: files = os.listdir(old_fp) f="YetToBegin" for f in files: oldpaf = os.path.join(old_fp, f) newpaf = os.path.join(new_fp, f) ##TESTER: newpaf = os.path.join("/root/", f) shutil.move(oldpaf, newpaf) except Exception as e: self.__ERROR_STATE["UpgradeFail"] = fontybugs.UpgradeFail( _("Could not move \"{what}\" from \"{src}\" to \"{dest}\"\n" \ "Please resolve the problem and start me again.").format( what=f, src=old_fp, dest=new_fp), e) raise except: # unknown sundry pass # We repeat the rmdir soon.. ## Now that we've moved all the guts over to the new fp path.. try: ## Let's, once again, attempt to rm the old fp dir... os.rmdir(old_fp) ##TESTER: os.rmdir("/root/foo") except Exception as e: #Just could not kill the beast! self.__ERROR_STATE["UpgradeFail"] = \ fontybugs.UpgradeFail( _("Could not remove the old \"{oldfontydir}\" directory.\n" \ "Please remove it and start me again.").format( oldfontydir = old_fp), e) raise def __upgrade_fonts_dir(self, old_fonts_dir, new_fonts_dir): """ Find all symlinks in ~/.fonts and re-link them in new_fonts_dir. Delete old link. This method ignores all errors. (I tried to re-link fonts to the new directory for all pogs that are installed, but this is still the __init__ of PathControl and I can't make Pog objects yet.) The ~/.fonts directory will not be removed. Dec 7 2017 == I have found while testing sudo setup and running fonty, that links dangling around can cause weirdnes. I wonder if a better solution would not be to just delete the links? I will leave this for now - mainly becuase the state of what individual Pogs may report is a problem. I would have to loop them and set them to uninstalled. Etc. """ def movelink(src, dst): try: linkto = os.readlink(src) os.symlink(linkto, dst) os.unlink(src) except: pass #don't care links = [ f for f in os.listdir(old_fonts_dir) if os.path.islink( os.path.join(old_fonts_dir, f) ) ] if not links: return for f in links: movelink( os.path.join(old_fonts_dir, f), os.path.join(new_fonts_dir, f) ) ## Public Interface: def probeNoFontsDirError(self): """ For outside probing of missing fonts dir. E.g. see fontcontrol.py """ self.__raiseOrContinue("NoFontsDir") def probeNoFontypythonDirError(self): self.__raiseOrContinue("NoFontypythonDir") def probeAllErrors(self): """ For outsiders to probe these errors. Most serious first. The NoFontsDir one means fonts can be viewed, but not installed. """ self.__raiseOrContinue("NoFontypythonDir") self.__raiseOrContinue("UpgradeFail") self.__raiseOrContinue("NoFontsDir") self.__raiseOrContinue("NoFontconfigDir") def get_error_or_none(self, key): """ General way to fetch an error or None, on a key. Would use this after probing. """ return self.__ERROR_STATE.get( key, None ) def appPath(self): """Supplies the "fontypython" application directory.""" return PathControl.__fp_dir def appConf(self): """Supplies paf of "fp.conf" or empty string.""" if PathControl.__fp_dir=="": return "" return PathControl.__app_conf def userFontPath(self): """Supplies the user's "fonts" directory.""" return PathControl.__fonts_dir def home(self): #Not gonna bother error checking HOME return PathControl.__HOME def user_fontconfig_confd(self): return PathControl.__fontconfig_confd def getPogNames(self, someotherpath=None): """ We pass a byte string path to os.listdir therefore this function returns a LIST OF BYTE STRINGS. """ p = PathControl.__fp_dir if not someotherpath else someotherpath # So, it turns out that during startup (in cli.py), there is a place # that uses this and __fp_dir may be "" because of an error state. # Thus a truthy test helps: if not p: return [] # all okay, make a list: return [ f[0:-4] for f in os.listdir(p) if f.endswith(".pog") ] ## Sept 2009 class Overlaperize(object): ''' Used when uninstalling a pog: If a single font is in *many* pogs, then we count each 'overlap' and control the removal of them until there are no overlaps. i.e. When no other installed pogs are using the font, it is safe to remove the link (should that last pog be removed by the user). ''' def __init__(self): self.OVERLAP_COUNT_DICT = {} self.DISABLE_THIS = False # In case all this makes a horrible mess : users can flip this to True.... def inc(self,key): if self.DISABLE_THIS: return True if key in self.OVERLAP_COUNT_DICT: self.OVERLAP_COUNT_DICT[key] += 1 else: self.OVERLAP_COUNT_DICT[key] = 2 #starts at 2 because there is already one installed. #self.report(key) return True def dec(self,key): ''' Return True means : This font overlaps Return False means : This font can be uninstalled ''' if self.DISABLE_THIS: return False if key in self.OVERLAP_COUNT_DICT: self.OVERLAP_COUNT_DICT[key] -= 1 if self.OVERLAP_COUNT_DICT[key] == 0: del self.OVERLAP_COUNT_DICT[key] return False # it does NOT overlap anymore. else: #self.report(key) return True # It still overlaps # It gets here if the font is totally unknown to the OVERLAP_COUNT_DICT return False #It therefore does NOT overlap. def report(self,key): print "%s has overlap count of %d" % (key, self.OVERLAP_COUNT_DICT[key]) def sleep(self): '''Save the OVERLAP_COUNT_DICT to a file (if it has content). Called when app closes.''' if self.DISABLE_THIS: return if not self.OVERLAP_COUNT_DICT: self.OVERLAP_COUNT_DICT={} # Ensure there is a blank overlap_counts file! ## At app's close, there *must* be a valid appPath. No try/except paf = os.path.join(iPC.appPath(),"overlap_counts") fr = open( paf, 'wb' ) # pickle says use 'binary' files, but only Windows makes this distinction. I use it to be safe... pickle.dump( self.OVERLAP_COUNT_DICT, fr, protocol=pickle.HIGHEST_PROTOCOL ) fr.close() def wakeup(self): '''Restore the OVERLAP_COUNT_DICT from a file (if any). Called as app starts.''' if self.DISABLE_THIS: return ## iPC __init__ may have encountered errors. ## Since this method runs soon after, I should be cautious ## of those errors: so I do a probe: try: iPC.probeNoFontsDirError() except: return paf = os.path.join(iPC.appPath(),"overlap_counts") try: if os.path.exists( paf ): fr = open( paf, "rb" ) self.OVERLAP_COUNT_DICT = pickle.load( fr ) fr.close() except: ##TODO ?? raise def getSegfontsList(): """ On startup, open the 'segfonts' file and keep it handy in a global list. This list is written to 'segfonts' file by the 'checkFonts' func in this module. """ global segfonts try: ## appPath() may be bad. iPC.probeNoFontypythonDirError() except: ## Bail return paf = os.path.join(iPC.appPath(),"segfonts") try: if os.path.exists( paf ): fr = open( paf, 'r' ) # byte string only ascii file segfonts = fr.read().split("\n") fr.close() except: ##TODO ?? raise def checkFonts( dirtocheck, printer ): """ Jan 18 2008 Scan a tree for fonts that can cause segfaults. Writes a file 'segfonts' and creates a list 'segfonts' that gets checked to exclude them. printer is a function of some kind. Can be called from the cli or the gui. """ global segfonts code = """ from PIL import ImageFont try: font=ImageFont.truetype("%s", 24, 0) dud=font.getname() except: pass """ def checkForSegfault( pafbytestring ): ## Uses Ajaksu's idea : 17 Jan 2008. Thanks! segfault_I_hope = False ## I have ignored ALL catchable errors (see code var) ## This is because I want to (try to) only catch SEGFAULTS ## and leave all other flavours of font-related errors to ## the fontcontrol module -- where fonts are still useable ## if not visible. retval = subprocess.call( ["python", '-c', code % pafbytestring] ) if retval != 0: segfault_I_hope = True return segfault_I_hope printer ( _("Checking fonts, this could take some time.") ) printer ( _("Starting in %s:") % dirtocheck ) printer () ## dirtocheck comes-in as unicode - let's stick to byte strings: dirtocheck = LSP.to_bytes( dirtocheck ) seglist = [] # our local list of newly found bad fonts gotsome = False for cwd, dirs, files in os.walk( dirtocheck ): printer(_("Looking in %s...") % os.path.basename(cwd) ) ## We only want certain font files: fontfiles = [f for f in files if f.upper().endswith( tuple( fontcontrol.font_file_extensions_list )) ] #if len(fontfiles) < 1: # printer (_("No supported fonts found there...")) # printer() for file in fontfiles: paf = os.path.join( cwd, file ) bad = checkForSegfault( paf ) #bad = True #TEST if bad: gotsome = True seglist.append( paf ) printer ( _(" Bad font: {}".format(file)) ) # show it on-screen somewhere. ## Now write the segfonts file: if seglist: ## Add the new fonts found to the ones in global segfonts list for bf in seglist: segfonts.append(bf) ## Now remove duplicates tmp = list( set( segfonts ) ) segfonts = tmp del (tmp) ## Now save it. ##TODO ?? try/except on iPC appPath here? paf = os.path.join(iPC.appPath(),"segfonts") fw = open( paf, "w" ) # byte string ascii bytestring = "".join([line + "\n" for line in segfonts if line != ""]) #print "about to write bytestring:" #print [bytestring] #print fw.write( bytestring ) fw.close() if gotsome: printer(_("Bad fonts were found. They have been noted. I will ignore them in future.")) else: printer(_("I could not find any bad fonts.")) printer() printer(_("The process is complete.")) def isFolder(thing): """True if a folder. False if not - but that does not mean it's a pog.""" if os.path.isdir(thing): return True return False def isPog(thing): """True if a Pog. False if not.""" ## thing comes in as UNICODE ## iPC.getPogNames() is a list of BYTE STRINGS ## We must encode thing to a byte string to avoid warnings: if LSP.to_bytes( thing ) in iPC.getPogNames(): #getPogNames contains byte strings! return True if thing == "EMPTY": return True #Special case return False class FPState: """The global vars to hold the state of the situation.""" def __init__(self): ## Contains the Pog or Folder being viewed self.viewobject = None ## Refs the view object *after* the filter has been applied self.filteredViewObject= None ## Contains a Pog (or None) that is the Target self.targetobject = None ## Represents the situation in a letter code ## P for Pog, F for Folder, E for Empty, N for None self.viewpattern = "" self.targetpattern = "" ## Will be "NOTHING_TO_DO", "REMOVE" or "APPEND" (Add fonts to Pog) self.action = "" ## Can an item be ticked self.cantick = None ## The View and Target pogs chosen are the same. self.samepogs = False ## How many tick marks. self.numticks = 0 ## On start, there's a test for fontconfig dir self.fontconfig_confd_exists = False self.main_frame_resized = False #### ## Save and Load the conf file class Configure: """ Makes/Loads the conf file. Supplies size, pos, numinpage, text string and point size to other objects. """ atoz = _("Jump the lazy dog fox") def __init__(self): ## Private vars self.__dontSaveNumInPage = False ## PUBLIC vars : Set some defaults: self.size = (800,600) self.pos = (10, 10) self.numinpage = 10 self.text = Configure.atoz self.points = 64 #Nov 2017 self.max_num_columns = 2 #Beware 0 = divide by zero self.lastview = "EMPTY" # a pog name or a folder path. self.usegui = "wxgui" self.max = True self.lastdir = iPC.home() ## Added June 2009 self.recurseFolders = False # Going to stop saving this one to config. ## Added Sept 2009 self.ignore_adjustments = False ## Added 3 Oct 2009 self.app_char_map = "UNSET" # A string of an app name. ## Nov 2017 self.hush_pog_name = "" # A string of a pog name (byte string) self.__setData() ## Oct 2009 -- The Character Map Controller. self.CMC = charmaps.CharMapController( self.app_char_map_set ) try: iPC.probeNoFontypythonDirError() except: ## Can't access the appConf file at all, so bounce. return if os.path.exists(iPC.appConf()): try: pf = open(iPC.appConf(), "rb" ) # Binary for new pickle protocol. #self.__data = pickle.load( pf ) ## I want to merge-in what may be in pickle self.__data.update( pickle.load( pf ) ) pf.close() except: ## Dec 2007 : Let's try erase and rewind os.unlink(iPC.appConf()) if not os.path.exists(iPC.appConf()): print _("No config file found, creating it with defaults.") self.Save() ## Now get them into the instance vars: try: self.size = self.__data['size'] self.pos = self.__data['pos'] self.numinpage = self.__data['numinpage'] self.text = self.__data['text'] self.points= self.__data['points'] self.max_num_columns= self.__data['max_num_columns'] self.lastview = self.__data['lastview'] self.usegui = self.__data['usegui'] self.max = self.__data['max'] self.lastdir = self.__data['lastdir'] self.ignore_adjustments = self.__data['ignore_adjustments'] self.hush_pog_name = self.__data['hush_pog_name'] self.app_char_map = self.__data['app_char_map'] ## We must also set our instance of the CharMap Controller: ## This can be "UNSET" (default first run) or an appname ## That appname may be valid or not (it may have been uninstalled...) self.CMC.set_current_appname(self.app_char_map) #self.recurseFolders = self.__data['recurseFolders'] except KeyError: ## The conf file has keys that don't work for this version, chances are it's old. ## Let's delete and re-make it. try: os.unlink(iPC.appConf()) except: print _("The fontypython config file is damaged.\nPlease remove it and start again") raise SystemExit self.Save() def dontSaveNumInPage(self, flag): self.__dontSaveNumInPage = flag def __setData(self): self.__data = { "size" : self.size, "pos" : self.pos, "numinpage" : self.numinpage, "text" : self.text, "points" : self.points, "max_num_columns" : self.max_num_columns, "lastview" : self.lastview, "usegui" : self.usegui, "max" : self.max, "lastdir" : self.lastdir, "ignore_adjustments": self.ignore_adjustments, "app_char_map" : self.app_char_map, "hush_pog_name" : self.hush_pog_name, #"recurseFolders": False, # Nov 2017: Force this to always be off on startup #self.recurseFolders, } def app_char_map_set( self, x ): ''' A callback from the CharMapController: when the CURRENT_APPNAME is set, this gets called to keep the config version of the appname current. ''' self.app_char_map = x def Save(self) : #If we are NOT to save the numinpage, then fetch it from what was there before. if self.__dontSaveNumInPage: self.numinpage = self.__data["numinpage"] self.__setData() try: ## At this point, we have a good appPath. No try/except pf = open( iPC.appConf(), "wb" ) pickle.dump(self.__data, pf, protocol = pickle.HIGHEST_PROTOCOL ) pf.close() except IOError: print _("Could not write to the config file.") Overlap.sleep() #sept 2009 : Save the OVERLAP_COUNT_DICT def instantiateViewFolder( foldername, recurse=None ): """ Creates a Folder object and fills it with FontItem objects according to what's in the folder's path. This is the VIEW - i.e. what you are looking at. """ if state.viewobject: del state.viewobject ## Default assumptions in case of raised error. state.viewobject = fontcontrol.EmptyView() state.viewpattern = "E" #July 2016 #========= # Made recurse default to None in the def sig. # This has the effect of allowing THREE states to enter: # None, True, False # None means the call came from gui_FontSources # If so, we want to fetch the recurse from config - # so it becomes either T or F, depending on last state. # This has stopped that initial Schroedinger's Cat state # of the recurse setting. if recurse is None: recurse=config.recurseFolders else: config.recurseFolders = recurse #print "recurse:", recurse ifolder = fontcontrol.Folder(foldername, recurse) #raises : fontybugs.FolderHasNoFonts : BENIGN ERROR. ## Only continues if there is no problem. state.viewobject = ifolder ## Because we have a new view object, we must reset the last filteredViewObject state.filteredViewObject = None config.lastview = foldername state.viewpattern = "F" markInactive() flushTicks() def instantiateViewPog( newpog_name ): """ Given a Pog Name string, make a Pog object. This is the VIEW - i.e. what you are looking at. A VIEW Pog can be EMPTY. This happens on the first run when there is no config file. There are other arcane situations too, but I forget. """ if state.viewobject: state.viewobject = None if newpog_name == "EMPTY": ipog = fontcontrol.EmptyView() else: ipog = fontcontrol.Pog( newpog_name ) ## Test TARGETPOG to see if this is the same pogname ## The not None test is for first run - there is no targetobject yet just after cli.py calls us, so we ## do not want to access it or we get NoneType errors. if state.targetobject is not None and state.targetobject.name == newpog_name: state.samepogs = True else: state.samepogs = False ## Must gen the Pog to get a count of items: ## Errors raised in genList (and company): ## fontybugs.PogInvalid (only valid from cli pov) ## ## We 'handle' this by NOT catching it, pass it up. ipog.genList() ## Continue if all ok. state.viewobject = ipog ## Because we have a new view object, we must reset the last filteredViewObject state.filteredViewObject = None config.lastview = newpog_name if len(state.viewobject) == 0: empty = True state.viewpattern = "E" else: empty = False state.viewpattern = "P" markInactive() flushTicks() return empty # this return is only used in cli.py def instantiateTargetPog( newpog_name ): """ The app could begin with NO TARGET POG chosen. After that (in the gui) either a pog is chosen or NO POG is chosen (i.e. None) Therefore - there can NEVER BE a targetobject called EMPTY The CLI install/uninstall/purge DO NOT use this routine. """ if state.targetobject: del state.targetobject ipog = fontcontrol.Pog(newpog_name) ## Must gen the Pog to get a count of items: ipog.genList() # Raises fontybugs.PogInvalid error THIS ENDS THE APP. ## TEST the viewobject which is the stuff being ## LOOKED AT IN THE MIDDLE OF THE SCREEN (which could be a Pog OR a Folder) ## If it's a Pog then we may have chosen the same Pog (on the right) ## that we are looking at, so check that: state.samepogs = False if isinstance( state.viewobject, fontcontrol.Pog ): if state.viewobject.name == newpog_name: ## The pog clicked in the TARGET is the same as what's ALREADY selected in the VIEW state.samepogs = True quickinstalledflag = False if ipog.isInstalled(): quickinstalledflag = True state.targetpattern = "P" state.targetobject = ipog markInactive() flushTicks() return quickinstalledflag def markInactive(): """ INACTIVE means the font displayed is already inside the chosen target pog. So, it's not 'active', not clickable etc. Mark each font item as inactive, as needs-be. Clear the ticks. Sets the message to display in the fontmap. """ if state.viewobject: state.viewobject.clearInactiveflags() if state.viewobject and state.targetobject: ## What's in TARGET must be inactive in VIEW ## pafBlist is a list of UNICODEs ## glyphpaf_unicode is UNICODE, so I will use it instead ## because we compare it to pafBlist pafBlist = [i.glyphpaf_unicode for i in state.targetobject] for iA in state.viewobject: if iA.glyphpaf_unicode in pafBlist: iA.activeInactiveMsg = _("This font is in %s") % state.targetobject.name iA.inactive = True del pafBlist def SetTargetPogToNone(): state.targetobject = None state.targetpattern = "N" def SetViewPogToEmpty(): state.viewobject = fontcontrol.EmptyView() state.viewpattern = "E" def flushTicks(): for fi in state.viewobject: fi.ticked = False state.numticks = 0 def logSegfaulters( lastPaf ): """ Writes a string to ~/.fontypython/lastFontBeforeSegfault """ ## No need to try/except appPath. paf = os.path.join( iPC.appPath(),"lastFontBeforeSegfault") try: f = open( paf, "w" ) lastPaf = LSP.ensure_bytes( lastPaf ) f.write( lastPaf + "\n" ) f.close() except: ## TODO ?? raise def rm_lastFontBeforeSegfault_file(): paf = os.path.join( iPC.appPath(),"lastFontBeforeSegfault") try: os.remove(paf) except: pass ##Nov 2017 ## Hush code used from clifuncs and wxgui ## def hush_with_pog( pog, printer ): """ The printer func is under dev - aiming for a way to use this same func from the gui and cli The existence of the fontconfig conf.d directory must be confirmed before code gets here. See cli2.py, for example. It happens in a probeAllErrors call. """ bugs = [] printer(_("Trying to hush..."), key="starting") if isPog( pog ): hushpog = fontcontrol.Pog( pog ) ## gen and install it! printer( _(u"Installing (%s)") % pog, key="installing") try: hushpog.genList() ## Aside: it is not an error to ## install again ( > once) - hence I don't need ## to worry about toggling this hush/unhush ## thing. hushpog.install() ##TESTING: raise fontybugs.PogInvalid except (fontybugs.PogInvalid, fontybugs.PogEmpty, fontybugs.PogAllFontsFailedToInstall, fontybugs.PogSomeFontsDidNotInstall, fontybugs.NoFontsDir ), e: bugs.append(e.get_error_string()) ## The arg was not a valid pog. else: bugs.append(_(u"The Pog \"{}\", cannot be found.").format( pog )) ## Only if that was 100% do we hush: ## This process can accrue new bugs too. if not bugs: try: ## Just because I'm nervous: Is my path actually in "fontconfig"? ## This should never happen... if not os.path.dirname(iPC.user_fontconfig_confd()).endswith("fontconfig"): raise fontybugs.NoFontconfigDir(path="**HUSH_PAF WEIRDO ERROR. Please open a ticket on our bug tracker**") ## Write the XML fontconfig .conf file. ## don't care if it's already there. Just overwrite. f = open( HUSH_PAF, "w" ) hxml = LSP.ensure_bytes( HUSH_XML ) f.write( hxml ) f.close() # some new bug.. except Exception as e: bugs.append(unicode(e)) if not bugs: printer( _("Done. A hush settles over your fonts. " \ "Go: work in silence."), key="success" ) return bugs def un_hush( printer ): """ The existence of the fontconfig conf.d directory has to be confirmed before code gets here. See cli2.py, for example. It happens in a probeAllErrors call. """ if not os.path.exists(HUSH_PAF): printer (_("The hush isn't there. Nothing to do.")) return bugs = [] try: printer( _("Trying to unhush..."), key = "starting") os.unlink( HUSH_PAF ) except Exception as e: bugs.append(unicode(e)) if not bugs: printer( _("The noise has returned; the hush is gone."), key="success") return bugs ###### ####### ## Setup globals ## ###### ####### LSP = linux_safe_path_library.linuxSafePath() ## Ensure we have "fontypython" and "fonts" dirs. iPC = PathControl(XDG_DATA_HOME, XDG_CONFIG_HOME) HUSH_XML_FILE="1.fontypythonhusher.conf" HUSH_PAF = os.path.join( iPC.user_fontconfig_confd(), HUSH_XML_FILE) HUSH_XML=""" /usr/share/fonts/* """ ## Borrowed from wxglade.py ## The reason for this is to find the path of this file ## when it's called from an import somewhere else. ## There is no sys.argv[0] in this case. root = __file__ if os.path.islink(root): root = os.path.realpath(root) fontyroot = os.path.dirname(os.path.abspath(root)) ## Where my images and things are. mythingsdir = os.path.join(fontyroot,"things/") ## Instance the Overlaperizer (once) Overlap = Overlaperize() Overlap.wakeup() ## Prepare the list of fonts that have caused segfaults. ## Jan 18 2008 segfonts = []# Global var getSegfontsList() state = FPState() #The only instance of the state object -- app-wide ## Our config instance - it will have one instance across ## all the modules that use it. config = Configure() ##TEST: #print "If you can read this, fpsys just ran." fontypython-0.5/fontypythonmodules/strings.py0000664000175000017500000003107413212036007021733 0ustar donndonn00000000000000# This Python file uses the following encoding: utf-8 ## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import fpversion import os ## Some repeated strings please_use_arg = _("Please use a number for argument %s") ##copyright = "Fonty Python Copyright (C) 2006, 2007, 2008, 2009, 2016, 2017 Donn.C.Ingle" copyright = u"Fonty Python Copyright © 2017 Donn.C.Ingle" contact = "Email: donn.ingle@gmail.com" done = "Done." arguments_amuse = _("Your arguments amuse me :) Please see the help by using -h") ticket_url = "https://savannah.nongnu.org/bugs/?group=fontypython" version = _("Fonty Python version %s") % fpversion.version warranty = "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n" \ "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" \ "See the GNU General Public License for more details." copy_warranty_contact = u"{}\n\n{}\n\n{}".format(copyright, warranty, contact) fonts_supported = _("""Fonts supported: TTF, OTF, TTC, WOFF, Type1 (PFB, PFA).""") yaddayadda = _("""The basic format is: %(c)s [OPTIONS] || [VIEW] [TARGET] OPTIONS: Various flags for use on the command-line. See "-h b" or "--help b" for more details. (Long options can use an "=" sign or a space: --cat=foo or --cat foo) Or: Two arguments which will determine what you see in the graphical user interface: VIEW : A place where fonts are. A Pog or a folder where fonts are located. TARGET : A Pog. If this Pog does not exist, it will be created. Neither argument is required. When there's only one it's assumed to be a VIEW. When there are two, it's VIEW then TARGET. NB: Try not to use spaces in Pog names. If you must, then "quote the name".""" ) % { "c":"fontypython" } basic_idea = _("""Manage your fonts on GNU/Linux ============================== Many designers have collections of font files on their drives. Fonty Python will help you gather and structure them into collections called "Pogs" -- a place to keep tyPOGraphy. Well, why not? Fonty lets you you select fonts visually and place them into Pogs which you can then install or remove as you require. (Your font files never move from where they are. Only links are used.) Example: You create a "logos" Pog where you place logotype fonts. When you want to use them, simply install the "logos" Pog and start your design app! When you're done, uninstall the "logos" Pog; the fonts will go away. Fonty can also "hush" unwanted fonts. This hides system fonts, leaving only those Pogs you want in your apps. The Inkscape font chooser, for example, is more usable after a hush. (This is temporary; an "unhush" will switch the system fonts on again.) Fonty is great for just looking at fonts, wherever they are, without having to install them.""") use = _("""%(yadda)s Please use -e to see more info. %(fonts_supported)s %(basic_idea)s""" ) % { "yadda":yaddayadda, "basic_idea":basic_idea, "fonts_supported":fonts_supported } options=_("""Options: -v, --version Show program's version number and exit. -h b|e|hush, --help b|e|hush Show a help message and exit. "b" is for basic help. "e" to show some %$@#$ examples! "hush" is for more detail on hushing fonts. -d, --dir Show the "fontypython" path. Add this to your backup process! -i Pog, --install Pog Install the fonts in this Pog. -u Pog, --uninstall Pog Uninstall the fonts in this Pog. -l, --list List the names of all your Pogs. -f, --lsfonts Lists the contents of your user fonts directory. Here, you'll find the links that Fonty is managing for you. -s num, --size num Set a new default point size (you'll see it in the gui). -n num, --number num Set a new default for how many fonts to view at one go in the gui. (Don't overdo this.) -p Pog, --purge Pog Clean the Pog of fonts that are missing. -c folder, --check folder Check for bad fonts that crash Fonty. After using this tool you should be able to use Fonty again. * NOTE: The fonts that crash Fonty are probably still perfectly useable in other apps. -a Folder Pog, --all Folder Pog Puts all fonts in Folder into Pog. -A Folder Pog, --all-recurse Folder Pog Puts all fonts in Folder and *all* sub-folders into Pog. -z Pog, --zip Pog All the fonts inside Pog will be zipped and the zipfile will be named after the Pog. The file will be placed in the current directory. --cat Pog Cat the Pog. This will list all the fonts within. --hush HushPog Hush *all* the fonts except the Pogs you install. Uses "HushPog", which you create that must contain a few system fonts; in order to supply a basic set to your desktop apps. I suggest these from "/usr/share/fonts": DejaVu*, Free*, Ubuntu*, Liberation* --unhush Restores all the system fonts after a hush. Leaves your special HushPog installed. It's up to you to manage it. """) examples = _("""%(yadda)s Examples: All using short options, see -h ========= %(c)s /path/to/fonts/ttfs/a This will start off showing the fonts in that path. %(c)s /path/to/fonts/ttfs/b Trouser This will let you view and choose fonts from the path and it will store them in a Pog named Trouser. The Pog will be created if it's not already there. %(c)s Lumberjack This will let you see the fonts in the Pog named Lumberjack. You can also uninstall individual fonts by selecting them. A cross will appear indicating the fonts that will be uninstalled. %(c)s Camelot Spamalot This will let you see and choose fonts in Camelot and it will store them in "Spamalot". It lets you copy fonts between Pogs. %(c)s -i Cheese Will install the fonts in Cheese so you can use them in other apps. %(c)s -u Trouser Will uninstall the fonts listed in Trouser. %(c)s -s 128 Will set the point size in the gui to 128 - Crazy man! %(c)s -n 25 Will show 25 fonts at a time, in the gui. Beware large numbers! %(c)s -s 64 -v 10 Pimple Will set the point size to 64, paging to 10,open the gui and display the fonts in Pimple. %(c)s -p Glutton Purging a font. If there are any fonts in Glutton that are not really on your drive/media anymore (perhaps you deleted them or the cat did) this will go through the Pog and cull them. %(c)s -c /some/path/to/fonts If Fonty keeps crashing on /some/path/to/fonts then you should run a check on that folder. This will mark the dangerous fonts and let you view that folder in the future. %(c)s -a /some/path HolyHandGrenade This will put all the fonts in that path into the Pog called HolyHandGrenade. %(c)s -A /some/path Tutto This will do the same as -a: starting in some path, but it will then walk down through *all* sub-folders too. The fonts will be placed in Tutto. %(c)s --hush mysysfonts Will hush (silence) all the fonts in your system except the ones in "mysysfonts" and any other Pogs you have installed. Other apps will now have fewer fonts to choose from, making life much easier for you. (Use --unhush later to restore all of them.) """) % { "yadda":yaddayadda, "c":"fontypython" } fontyfolder = _("""Your fontypython folder is: {}""") ## These two are used in setup.py description = _("Fonty Python - view and manage fonts on Gnu/Linux") long_description = "%(basic_idea)s\n\n%(fonts_supported)s\n\n%(copy)s\n\n%(contact)s" % {"copy":copyright, "contact":contact, "basic_idea":basic_idea, "fonts_supported":fonts_supported } wxvers="3.0" wxVersionError = _("""I cannot find "python-wxversion" Please install this package - NB: ensure that you use only the "Unicode build". TIP === On my distro I can search for it like this: aptitude search python-wx This returns many results, one of which is: python-wxversion I then install it like this: sudo aptitude install python-wxversion If you get long error messages, you will need to install python-wxgtk*, where the star means the version number and it should be at least %(wxv)s You can also get the latest version from here: http://wxpython.org/download.php """) % {"wxv":wxvers} wxError =_("""I cannot find "python-wxgtkX.Y" Please install this package - NB: ensure that you use only the "Unicode build". TIP === On my distro I can search for it like this: aptitude search python-wx This returns many results, one of which is: python-wxgtk%(wxv)s I then install it like this: sudo aptitude install python-wxgtk%(wxv)s Make sure it's at least version %(wxv)s **NB** It should not be any version greater than 3.0 You can also get the latest version from here: http://wxpython.org/download.php """) % {"wxv":wxvers} PILError = _("""I cannot find "python-pil" Please install this package. NOTE === PIL has been forked by Pillow. The old package was "python-imaging", the new one is "python-pil". TIP === On my distro I can search for it like this: aptitude search python-pil This returns many results, one of which is: python-pil I then install it like this: sudo aptitude install python-pil Make sure it's at least version 1.1.6-1 You can also get the latest version from here: http://www.pythonware.com/products/pil/index.htm """) ##Sept 2017 giError = _("""I cannot find "Python-gi" This package is not required; although if you have it, modern Linux desktop standards can be implemented by Fonty. TIP === Look for "python-gi" in your package manager. """) ## June 2009 : Get the GPL from the COPYING file rather than a copy of it all here again. try: root = __file__ if os.path.islink(root): root = os.path.realpath(root) fontyroot = os.path.dirname(os.path.abspath(root)) p = os.path.join(fontyroot,'COPYING') GPL = open(p,"r").read() except: GPL = """ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 The file "COPYING" cannot be found. Please check the installation directory for the licence. """ ctrl_select_msg = _("Hold SHIFT or CTRL as you select Pogs, if you wish to select many at once.") ## Hush strings cant_hush = _("Can't hush because:") cant_unhush = _("Can't unhush because:") see_help_hush = _("See --help hush") hush_howto = _(""" The idea ======== Often there are too many fonts reported by your system. In your apps, like Inkscape, they clutter the font chooser. This is a way to "hush" that, to quieten the noise. Fonty will install a select Pog of system fonts (which you must pick) and then will reject *all* the system's fonts, leaving only the Pogs which you install. This does no damage and you can "unhush" at any time to reverse it. Hushing ======= 1. Relies on fontconfig, which should be installed on most modern Linux desktops. You can verify if it's there by trying this command: fc-list If that shows no error, you're good. 2. Fontconfig's user directory: The path is {{fcpaf}} Make sure it exists and try fonty again. 3. System fonts: Put some fonts in a Pog that you must create and choose. I suggest those in /usr/share/fonts, like: DejaVu*, Free*, Ubuntu*, Liberation* The way it works is that fonty writes an XML file which rejects all fonts that are on the path: "/usr/share/fonts" This may not work on your particular Linux distribution. Please open a ticket on our site if you have any trouble: {ticket_url} To hush, using your special Pog from the command line do this: {fp} --hush yourpoghere To hush from the gui, ... Unhushing ========= To release the hush, use --unhush from the command line or the gui. The Pog(s) you installed when you hushed will be left installed. Remove it/them if you must.""").format(fp="fontypython", ticket_url=ticket_url) ##{{fcpaf}} is doubled like that so I can swap it in later. fontypython-0.5/fontypythonmodules/charmaps.py0000664000175000017500000001313213211475353022045 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2006 - 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import os, subprocess, errno class CharMapApp(object): ''' Base class for whatever character viewer apps I may support. ''' def __init__( self, appname ): self.appname = appname self.is_installed = self.do_i_exist() def do_i_exist( self ): #return False #test for path in os.environ.get('PATH', '').split(':'): if os.path.exists(os.path.join(path, self.appname)) and \ not os.path.isdir(os.path.join(path, self.appname)): return True #return True #test return False def OpenApp( self, *args ): pass def Cleanup( self ): pass def Run( self, cmd ): try: proc = subprocess.Popen( cmd, shell=False ) except: ## Just bail. return ## gucharmap: Fonty actually holds still and waits here until gucharmap is closed. ## kfontview: Fonty just runs-through. It's a different beast... ## Both still work and Fonty stays active. Multiple instances of the viewers can be opened! proc.wait() class Gucharmap( CharMapApp ): ''' The wiring needed to support gucharmap. It requires a dodge before and after spawning the app -- one must temporarily install the font to be viewed and then remove it again afterwards. ''' def OpenApp( self, *args ): src=args[0] dest=args[1] self.dest = dest fam=args[2] sz=args[3] cmd = [ self.appname, u'--font=%s, %s' % (fam, sz)] ## gucharmap requires the font to be installed already, so fake it: self.already_installed = False try: os.symlink( src, dest ) except OSError, detail: if detail.errno != errno.EEXIST: # Not EEXIST means the link failed, don't open the charmap return False else: # Error EEXIST: file exists. # User may have installed it previously (or something). self.already_installed = True self.Run( cmd ) def Cleanup( self ): # Remove the fake installed font -- if it's a candidate: if not self.already_installed: try: os.unlink( self.dest ) except: # What to do? Start yelling? Nah... pass class Kfontview( CharMapApp ): ''' Wiring for kfontview -- really easy to use. ''' def OpenApp( self, *args ): url=args[0] cmd = [ self.appname, u'%s' % url] self.Run( cmd ) ## Oct 2009 class CharMapController(object): ''' Control the character map viewing objects (above) that Fonty supports. UNSET is always the initial "chosen app" when this instantiates. ''' def __init__( self, config_callback ): self.config_callback = config_callback supported_char_map_apps = { "gucharmap":Gucharmap, "kfontview":Kfontview } self.list_of_suggested_apps=" or ".join('"{}"'.format(n) for n in supported_char_map_apps.keys()) ## Which of the supported apps are actually available? self._available_app_dict = {} for appname, klass in supported_char_map_apps.iteritems(): ## Instantiate an app class: i = klass( appname ) if i.is_installed: self._available_app_dict[appname] = i ## Flag to signify if there are available apps to use. self.apps_are_available = False if len(self._available_app_dict) == 0 else True self.__current_appname = "UNSET" self.quick_appname_list = self._available_app_dict.keys() def set_current_appname(self, x): ## If the new name (x) is UNSET or some appname that is not available ## then give x a new value of the first thing in the list of what is ## actually available. if x not in self.quick_appname_list and self.apps_are_available: x = self.quick_appname_list[0] self.__current_appname = x ## It's possible that x is "UNSET" self.config_callback( x ) ## go set the config's app_char_map var too. #def GET_CURRENT_APPNAME( self ): # ''' # This is only called when apps_are_available Is True: See dialogues.py # Think of this as raising an error if apps_are_available Is False! # ''' # if self.__current_appname == "UNSET": # x = self.quick_appname_list[0] # return x # else: # return self.__current_appname def GetInstance( self ): ''' This is only called when apps_are_available Is True: See gui_Fitmap.py in can_have_button method. Think of this as raising an error if apps_are_available Is False! ''' ## Fetch an instance from my dict return self._available_app_dict[ self.__current_appname ] fontypython-0.5/fontypythonmodules/gui_Fitmap.py0000664000175000017500000010165613211475353022344 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx import colorsys import subprocess,os import threading import wx.lib.statbmp import fontcontrol import fpsys # Global objects from pubsub import * from wxgui import ps ##Oct 2017 - Moved the PIL draw code into Fitmap. from PIL import Image, ImageFont, ImageDraw import collections from fpwx import SYSFONT class OverOutSignal(object): """ Signal an external function when a state has CHANGED from True to False or vice-vera """ def __init__( self, func_to_signal ): self.announce = func_to_signal self.truthstate = False def set( self, newtruth ): if self.truthstate == newtruth: return # no change # implies there's now an actual change, thus: self.truthstate = newtruth # Orwell would be proud! :D self.announce() from wx.lib.wordwrap import wordwrap class Pencil(object): """ Used to store drawing code for DrawText and DrawBitmap. I make them and store them in a dict. This gives an ordering in time and overlapping too. I can loop and draw them all in one go. """ def __init__( self, myid, x = 0, y = 0, fcol = (0,0,0)): self.id = myid; self.x = x; self.y = y self._fcol = fcol def getwidth(self): return 0 def draw(self, memdc): pass class TextPencil(Pencil): """ Text pencils are made over and over, never cached. """ def __init__( self, myid, txt, x = 0, y = 0, fcol = (0,0,0), points = "points_normal", style = wx.NORMAL, weight = wx.NORMAL, split_path_and_wrap = False ): Pencil.__init__(self, myid, x = x, y = y, fcol = fcol) self.txt = txt ## But, get the actual font object every time. ## This avoids weird issues where all the font ## start using "Sans" no matter what the system ## is set to. self.font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) ## I get point sizes from the SYSFONT dict pointsize = SYSFONT[points] self.font.SetPointSize(pointsize) self.font.SetWeight(weight) self.em = self._measure(txt="n") self._measure() #initial size def _measure(self, txt = None ): if not txt: txt = self.txt dc = wx.ScreenDC() dc.SetFont( self.font ) try: w,h,lh = dc.GetMultiLineTextExtent( txt, font=self.font ) sz = (w,h) except: raise sz = (Fitmap.MIN_FITEM_WIDTH,Fitmap.MIN_FITEM_HEIGHT) self._size = sz return sz def getwidth(self): return self._size[0] def getheight(self): return self._size[1] def draw(self, memdc): txt = self.txt ## if we are to split, the size will change: dcw,dch = memdc.GetSize() ## Well ...hell. wx has a wordwrapper! #txt = wordwrap(txt, dcw - self.x, memdc, breakLongWords = True ) txt = wordwrap(txt, dcw - self.x, memdc, breakLongWords = False) memdc.SetTextForeground( self._fcol ) memdc.SetFont( self.font ) memdc.DrawText( txt, self.x, self.y ) class BitmapPencil(Pencil): def __init__( self, id, x=0, y=0, bitmap = None, use_mask = True ): Pencil.__init__(self, id, x, y) self.bitmap = bitmap self.use_mask = use_mask def getwidth(self): return self.bitmap.GetWidth() def getheight(self): return self.bitmap.GetHeight() def draw(self, memdc): memdc.DrawBitmap( self.bitmap, self.x, self.y, self.use_mask ) ndc=(200,190,183) # No Draw Color: colour of background for the fonts I can't draw ndi=(227,226,219) # No Draw Inactive => "ndi" black=(0,0,0) white=(255,255,255) class Fitmap(wx.lib.statbmp.GenStaticBitmap): """ This class is a bitmap of a font - it detects events and displays itself. Sept 2009 Added code to adjust top-left of displayed sample text. Oct 2009 Added a 'button' to open a character map viewer. Sept/Oct 2017 Lots of work. A total overhaul. Arguably worthless. Dunno. """ ## This class-level dict is a kind of "style sheet" to use in fitmap drawing. styles={ 'FILE_NOT_FOUND': { 'backcol': (255,214,57), 'fcol' : black, 'bcol' : white, 'icon' : "NOT_FOUND", 'ndi' : ndi }, 'PIL_SEGFAULT_ERROR': { 'backcol': (152,147,157), #255,140,20), 'fcol' : black, 'bcol' : white, 'icon' : "SEGFAULT", 'ndi' : (216,193,193) }, 'PIL_IO_ERROR': { 'backcol': ndc, 'fcol' : black, 'bcol' : white, 'icon' : "NO_DRAW", 'ndi' : ndi }, 'PIL_UNICODE_ERROR': { 'backcol': ndc, 'fcol' : black, 'bcol' : white, 'icon' : "NO_DRAW", 'ndi' : ndi }, 'PIL_CANNOT_RENDER': { 'backcol': ndc, 'fcol' : black, 'bcol' : white, 'icon' : "NO_DRAW", 'ndi' : ndi }, 'ACTIVE': { 'backcol': white, 'fcol' : black, 'bcol' : (200,200,200), 'icon' : None, }, 'INACTIVE': { 'backcol': white, 'fcol' : (98,98,98), #128,128,128), 'bcol' : white, 'icon' : None, 'ndi' : ndi }, 'INFO_FONT_ITEM': { 'backcol': white, 'fcol' : black, 'icon' : "INFO_ITEM", } } MIN_FITEM_WIDTH = 400 MIN_FITEM_HEIGHT = 10 SPACER = 0 LINEHEIGHT = 0 def __init__( self, parent, fitem ) : self.name = fitem.name self.fitem = fitem Fitmap.styles['INFO_FONT_ITEM']['backcol']=parent.GetBackgroundColour() self.FVP = parent.parent #The Scrolled Font View Panel self.parent = parent self.TICKSMALL = parent.parent.TICKSMALL self.style = {} self.gradientheight = 50 Fitmap.LINEHEIGHT = TextPencil("idX", "X", 0, 0, points = "points_small").getheight() Fitmap.SPACER = Fitmap.LINEHEIGHT * 3 self.face_image_stack = [] self._inactive_images = {} # To keep all the pencils in a stack self.drawDict = collections.OrderedDict() self.height = Fitmap.MIN_FITEM_HEIGHT self.width = 0 self.history_dict = {} self.state = 0 self.bitmap = None self.badfont_dict = {} ## The charmap button self.CHARMAP_BUTTON_OVER = self.FVP.BUTTON_CHARMAP_OVER self.CHARMAP_BUTTON_OUT = self.FVP.BUTTON_CHARMAP ## Point to the handler for the signal re charmap button self.cmb_overout = OverOutSignal( self.charmap_button_signal ) self.cmb_rect = None ## init my parent class ## Give it a fake size. It has issues... wx.lib.statbmp.GenStaticBitmap.__init__(self, parent, -1, self.bitmap, size=(2,2)) ## Fitmap's over out signal self.overout = OverOutSignal( self.overout_signal ) ## Very cool event, gives us life! self.Bind(wx.EVT_LEFT_UP,self.onClick) self.Bind(wx.EVT_MIDDLE_UP, self.onMiddleClick) #self.Bind(wx.EVT_LEFT_DCLICK, self.onDClick) self.Bind( wx.EVT_MOTION, self.onHover ) self.Bind( wx.EVT_LEAVE_WINDOW, self.onLeave) ## Redraw event self.Bind(wx.EVT_PAINT, self.onPaint) self.CURSOR = wx.StockCursor( wx.CURSOR_ARROW ) def has_changed(self, key, something): """ Sets the dict key's value to something and tests if it differs from the last value. Returns: True or False (If first run, it sets and returns true) """ if key not in self.history_dict: tf = True else: tf = self.history_dict[key] != something self.history_dict[key] = something return tf ## Class vars for state stuff blocks = {"A":1,"B":2} flagA = 1 flagB = 2 def determine_draw_state(self): """ Looking at very specific variables which influence how we will draw the font bitmap. We OR the values onto state as we go. Fitmap.flagBecause of the way has_changed works, on first run, the state will be maxed, all blocks are on. "A" is generate glyphs from scratch "B" is draw the bitmap again """ # Experimental: # This forces a re-render when the main frame is resized. # The nature of the true/false onIdle test thing prevents # the use of our has_changed trick. Do a direct test # instead. # This resize->redraw might suck too much juice and # slow the app. # A | B if fpsys.state.main_frame_resized: self.state |= Fitmap.flagA | Fitmap.flagB # The normal ones: # A | B if self.has_changed("pointschanged", fpsys.config.points): self.state |= Fitmap.flagA | Fitmap.flagB # A | B if self.has_changed("textchanged", fpsys.config.text): self.state |= Fitmap.flagA | Fitmap.flagB # B : Nov 2017. When the overall source->target state changes # we can have ticks/crosses that should be redrawn. # See gui_FontView.MainFontViewUpdate() for use. if self.has_changed("stateaction", fpsys.state.action): self.state |= Fitmap.flagB # B if self.has_changed("activechanged", self.fitem.inactive): self.state |= Fitmap.flagB # B if self.has_changed("tickedchanged", self.fitem.ticked): self.state |= Fitmap.flagB # B if self.has_changed("tlchanged", fpsys.config.ignore_adjustments): self.state |= Fitmap.flagB def is_block(self, c): """ This looks at the state and determines which block it's in. E.g. if xx.is_block("A"): """ #print u"state of {} is {}".format(self.name, self.state) return self.state & Fitmap.blocks[c] == Fitmap.blocks[c] def accrue_height(self,n): #h = self.height + n self.height = max(self.height, n) #print "self.height set to:", self.height def add_pencil(self, *pencils): # Beware, this does not preserve the order of the # input list! d = dict((o.id, o) for o in pencils) self.drawDict.update(d) def remove_pencil(self, *ids): [ self.drawDict.pop(id, None) for id in ids ] def gen_info_or_badfont( self, isinfo = False ): """ Draw the Info Font block, or an Error message block. Much clearer than it was before. """ #print "New gen_info_or_badfont for {}".format(self) #Sept 2017: Move it all over by an offset offx = 10 icon = self.style['icon'] iconpencil = None if icon: Icon = self.FVP.__dict__[icon] #See gui_FontView.py ~line 97 if isinfo: ix,iy = (6,10) else: if self.fitem.badstyle == "FILE_NOT_FOUND": ix,iy = (2,18) #"?" else: ix,iy = (2,3) #"A" ix += offx iconpencil = BitmapPencil( "infoicon", ix, iy, Icon) ## Prep and measure the texts to be drawn. Add them to drawlist. fcol = self.style['fcol'] textTup = self.fitem.InfoOrErrorText() ## Text 0: The bold, large text of the message. tx,ty = (76,45) if isinfo else (38 , 15) tx += offx text0 = TextPencil( "tup0", textTup[0], fcol=fcol, x=tx,y=ty, points="points_large", weight=wx.NORMAL) ## Text 1 - under Text 0 ty += text0.getheight() + Fitmap.LINEHEIGHT # if there are newlines in the first text, we need more space if textTup[0].count("\n") == 0: ty += (Fitmap.LINEHEIGHT/3) tx = 76 if isinfo else 5 pnts = "points_normal" if isinfo else "points_small" tx += offx text1 = TextPencil( "tup1", textTup[1], fcol=fcol,x=tx,y=ty, points = pnts)#, #split_path_and_wrap = True ) self.add_pencil( iconpencil, text0, text1 ) h = sum(p.getheight() for p in [iconpencil, text0, text1]) return h def make_inactive_bitmap(self, wxim): if wxim in self._inactive_images: #print u"Cached inactive for {}".format(self.name) return self._inactive_images[wxim] tmp = wxim.AdjustChannels(0,0,0,factor_alpha = 0.5) self._inactive_images[wxim] = tmp#.ConvertToBitmap() return tmp def _gen_glyphs(self): """ NB: Determines the intial measured width of a fitmap. (badfonts don't even get this far.) """ w = 1 paf, points, text = self.fitem.glyphpaf, fpsys.config.points, " " + fpsys.config.text + " " i = 0 del self.face_image_stack[:] glyph_widths = [w] there_are_more_faces=True while (there_are_more_faces): try: ## This access by i can cause an error. font = ImageFont.truetype(paf, points,index = i, encoding = "unicode") w,h = font.getsize( text ) #print u"{} {},{}".format(paf,w,h) ## Some fonts (50SDINGS.ttf) return a 0 width. pilheight = max(1, int(h)) pilwidth = max(1, int(w)) ## Sept 2009 : Fiddled this to produce alpha (ish) images. ## pilimage is of type PIL.Image.Image. ## python ## >>> from PIL import Image ## >>> pi = Image("RGBA",(10,10)) ## >>> dir(pi) pilimage = Image.new("RGBA", (pilwidth, pilheight), (0,0,0,0)) ## Well, I have since discovered that some fonts ## cause a MemoryError on the next command: drawnFont = ImageDraw.Draw( pilimage ) # Draws INTO pilimage drawnFont.text((0,0) , text, font=font, fill=(0,0,0,255)) ## Get the data from RGBA PIL into wx. ## Thx, http://nedbatchelder.com/blog/200801/ \ ## truly_transparent_text_with_pil.html image = wx.EmptyImage(*pilimage.size) image.SetData(pilimage.convert("RGB").tobytes() ) #image.SetAlphaData(pilimage.convert("RGBA").tobytes()[3::4]) image.SetAlphaData(pilimage.tobytes()[3::4]) self.face_image_stack.append(image) #self.accrue_width( pilwidth ) glyph_widths.append(pilwidth) ## All is well, so we step ahead to the next *potential* sub-face i += 1 ## On any kind of error, end the loop. ## IOError happens when i is out of bounds: except IOError: there_are_more_faces = False ## Whatever else goes wrong, just set badfont. except Exception as e: self.fitem.badfontmsg = _("Font causes a memory error, it can't be drawn.\nOriginal error was:\n{}").format(e) self.fitem.badstyle = "PIL_CANNOT_RENDER" self.fitem.badfont = True there_are_more_faces = False return max(glyph_widths) def CalculateTopLeftAdjustments(self, wxi): ## Sept 2009 ## Find the first pixel from the top-left of the image (if it's not stored) ## Using this pixel as the x,y I can draw fonts from where their actual data ## begins and not where the pilimage *thinks* it does (leaving big white spaces ## to the left of many fonts.) wx.BeginBusyCursor() fx,fy=0,0 W,H = wxi.GetSize() fx=fy=0 esc = False # Scan ACROSS WIDTH and repeatedly DOWN looking for a pixel. for tx in xrange(W): for ty in xrange(H): ap=wxi.GetAlpha(tx,ty) if ap != 0: #Found X coord, let's kill both loops fx=tx esc = True break if esc: break # Scan DOWN the HEIGHT and repeatedly ACROSS. esc = False for ty in xrange(H): for tx in xrange(W): ap=wxi.GetAlpha(tx,ty) if ap != 0: fy=ty # Found Y coord esc = True break if esc: break wx.EndBusyCursor() return fx,fy def render_and_measure_glyphs( self ): """ The process is split into "render/measure" and the "assemble" This is step ONE: the render/measure part. Call must happen immediately after instancing a new Fitmap. * This happens in gui_ScrolledFontView.MinimalCreateFitmaps() If the state is appropriate, render the glyphs into wximages. (It's possible to call this on exisiting fitmaps, in which case the state might not hold flagA, so we need not call _gen_glyphs) We return the width so we can calculate the columns and their widths in gui_ScrolledFontView.MinimalCreateFitmaps() """ self.determine_draw_state() ## Toggle the hand/arrow as per if fpsys.state.action in ("REMOVE", "APPEND"): self.CURSOR = wx.StockCursor( wx.CURSOR_HAND ) else: self.CURSOR = wx.StockCursor( wx.CURSOR_ARROW ) self.SetCursor( self.CURSOR ) #print u"measure Draw state: {} for {}".format(self.state,self.name) max_glyph_width = self.width if self.is_block("A"): ## if badfont, just get a generic width if self.fitem.badfont: max_glyph_width = Fitmap.MIN_FITEM_WIDTH else: ## Else go render the glyphs max_glyph_width = self._gen_glyphs() self.state = self.state & ~Fitmap.flagA #Switch off flagA return max_glyph_width def assemble_bitmap( self, colw = None ): """ This is step TWO of the process, the "assemble" part: This checks state and possibly draws into the bitmap. We've have already had render_and_measure_glyphs() run before arriving here; thus the glyphs are ready and waiting. (The only internal call to assemble_bitmap() comes from self.onClick() afer this fitmap already exists and has been measured, therefore we don't need _gen_glyphs in this method.) As it happens, right now, there are only two states: "A" and/or "B", i.e. bit code what 0 "A" gen_glyphs 1 "B" draw_bitmap+use_pencils; """ ## Go determine_draw_state my draw state. self.determine_draw_state() #print u"assemble_bitmap Draw state: {} for {}".format(self.state,self.name) if self.is_block("B"): # Block B: Draw the entire fitmap #print " ..calling draw_bitmap and use_pencils for ", self.name self._draw_bitmap() self._use_pencils( colw ) if self.state > 0: self.Refresh()# force onPaint() self.state = 0 def _draw_bitmap(self): ## Is this a normal FontItem, or an InfoFontItem? ## InfoFontItem is a fake font item for the purposes ## of saying "There are no fonts to see here." if isinstance( self.fitem, fontcontrol.InfoFontItem ): self.style=Fitmap.styles['INFO_FONT_ITEM'] h = self.gen_info_or_badfont( isinfo = True ) self.height = Fitmap.MIN_FITEM_HEIGHT + h + 20 return self.setStyle() fcol = self.style['fcol'] if self.fitem.badfont: bh = self.gen_info_or_badfont() #h = Fitmap.MIN_FITEM_HEIGHT #if self.fitem.inactive: mainy += 5 #Need more space mainy = bh + 5 #self.height = h else: mainy = Fitmap.MIN_FITEM_HEIGHT#10 self.height = mainy #reset the height! for i,wximage in enumerate(self.face_image_stack): #print u"..draw_bitmap loop for {} i is {} wximage is {}".format(self.name,i,wximage) glyphHeight = wximage.GetSize()[1] ## The Face Sample: x = 16 if i > 0: x *= 3 # Shift sub-faces over a little if self.fitem.inactive: image = self.make_inactive_bitmap(wximage) else: image = wximage fx, fy = 0, 0 if not fpsys.config.ignore_adjustments: fx,fy = self.CalculateTopLeftAdjustments(wximage) ## The face bitmap itself: glyph = BitmapPencil("face-{}".format(i), x - fx, mainy - fy, image.ConvertToBitmap() ) ## The Caption: fam, style, name caption = TextPencil( "face-{}-caption".format(i), "{} - {} - [{}]".format( self.fitem.family[i], self.fitem.style[i], self.fitem.name ), 28, mainy + glyphHeight + (Fitmap.SPACER/3), fcol, points = "points_small") self.add_pencil( glyph, caption ) ## Move TOP down to next BOTTOM (for next sub-face) mainy += glyphHeight + Fitmap.SPACER mainy += Fitmap.SPACER self.accrue_height( mainy ) ## The inactive footer if self.fitem.inactive: xx = 40 #x,y=(25,self.height-20) if self.fitem.badfont else (48,self.height-26) #y= self.height-20 if self.fitem.badfont else self.height-26 y = self.height - 30 self.add_pencil( BitmapPencil( "bmpinactive", xx, y, self.TICKSMALL) ) txt = self.fitem.activeInactiveMsg self.add_pencil( TextPencil( "fntinactive", txt, xx + 22 + 4, y + 1, fcol) ) else: self.remove_pencil("bmpinactive", "fntinactive") ## The ticked state ## Draw the tick/cross if it's not a FILE_NOT_FOUND font ## (it's in the pog, but can't be found on paf) ## NB: FILE_NOT_FOUND is not available for installation, but *is* available ## for removal. cannot_append_a_ghost_font = fpsys.state.action == "APPEND" and self.fitem.badstyle == "FILE_NOT_FOUND" if not cannot_append_a_ghost_font: ## We are a normal font. Tick or Cross it: if self.fitem.ticked: self.TICKMAP = self.parent.parent.TICKMAP self.add_pencil( BitmapPencil( "tickmap", 40, 10, self.TICKMAP) ) else: self.remove_pencil("tickmap") else: ## We are a ghost font and the state is APPEND. ## There might have been a tick (cross) on it from last time self.remove_pencil("tickmap") def _use_pencils(self, colw = None): """ Makes a new mem dc with the best size. Loops the drawDict for Pencils to draw text and bitmaps. NOTE ==== (See gui_ScrolledFontView.MinimalCreateFitmaps for more.) I used to tote-up the widths of my pencils to get my overall width. i.e: w = max(p.getwidth() + int(1.5 * p.x) for p in self.drawDict.values()) This caused problems. I discovered that the width of a fitmap is best imposed from without - from the ScrolledFontView where they live. There is one use of assemble_bitmap within myself - in self.onClick() In this one method, we can be certain it's running *after* the fitmap has been created - and thus already has a width imposed. (This use-case is when colw would be None.) """ if colw: w = colw else: w = self.width #We already exist and have a width, so use it. self.width = w h = self.height bitmap = wx.EmptyImage( w, h ).ConvertToBitmap() memDc = wx.MemoryDC() memDc.SelectObject( bitmap ) #memDc.SetBackground( wx.Brush( wx.Colour(255,255,255,wx.ALPHA_OPAQUE), wx.SOLID) ) memDc.Clear() if not isinstance( self.fitem, fontcontrol.InfoFontItem ): ## Backdrop gradient: ## Baptiste's idea! New implementation: Oct 2017 ## "Now a dividing gradient, you can say "wow" ;-)" ## Donn says, "..Wow!" :-D ctx = wx.GraphicsContext.Create(memDc) b = ctx.CreateLinearGradientBrush(0,h,0,0, self.parent.gstops["baptiste"]) ctx.SetBrush (b) ctx.DrawRectangle(0,0,w,h) ## Draw it all - via the pencils for pencil in self.drawDict.values(): pencil.draw(memDc) if not isinstance( self.fitem, fontcontrol.InfoFontItem ): ## Right-hand side gradient, to fade long glyphs fr = w/7 b = ctx.CreateLinearGradientBrush(w-fr,0,w,0, self.parent.gstops["white_to_alpha"] ) ctx.SetBrush (b) ctx.DrawRectangle(w-fr,0,w,h) ## Now a dividing line b = ctx.CreateLinearGradientBrush(0,0,w,0,self.parent.gstops["underline"]) ctx.SetBrush(b) ctx.DrawRectangle(0,h-1,w,h-1) #memDc.DrawCheckMark(50, 50, 20,20) # a liiitle fugly. Not gonna lie. self.bitmap = bitmap #record this for the init # Vital line: I can't tell you ... Man. The suffering. self.SetBestSize((w, h)) def onPaint(self, event): """ Dump the bitmap to the screen. """ if self.bitmap: ## Create a buffered paint DC. It will create the real ## wx.PaintDC and then blit the bitmap to it when dc is ## deleted by leaving this function. dc = wx.BufferedPaintDC(self, self.bitmap, wx.BUFFER_VIRTUAL_AREA) if not self.can_have_button(): return ## The charmap button is not part of the underlying process ## of drawing the bitmap, in that it needs to react to the mouse. ## We call onPaint via self.refresh() and bypass all the ## other drawing code. # x, y, w, h self.cmb_rect=wx.Rect(4,self.height-31, 32, 27) # Draw the charmap button x,y = self.cmb_rect[0],self.cmb_rect[1] #ctx = wx.GraphicsContext.Create( dc ) if self.cmb_overout.truthstate: #ctx.DrawBitmap( self.CHARMAP_BUTTON_OVER, x, y, 27, 27 ) dc.DrawBitmap( self.CHARMAP_BUTTON_OVER, x, y, True ) else: #ctx.DrawBitmap( self.CHARMAP_BUTTON_OUT, x,y, 27, 27 ) dc.DrawBitmap( self.CHARMAP_BUTTON_OUT, x,y, True ) def setStyle( self ): """ Set a copy of the styles key and alter colours as needed. """ # InfoFontItem does not use this, all others do. if self.fitem.badfont: ## Make a copy because I'm going to alter it a bit: self.style=Fitmap.styles[self.fitem.badstyle].copy() if self.fitem.inactive: self.style['fcol'] = Fitmap.styles['INACTIVE']['fcol'] self.style['backcol'] = Fitmap.styles[self.fitem.badstyle]['ndi'] else: # Not bad font, just get vals from style sheet. if self.fitem.inactive: self.style = Fitmap.styles['INACTIVE'] else: self.style = Fitmap.styles['ACTIVE'] def openCharacterMap( self ): fi=self.fitem dirname = os.path.basename( fi.glyphpaf ) dest = os.path.join(fpsys.iPC.userFontPath(), dirname ) ## I don't want to hold an fitem in the thread to come, so I will ## take the essential info out and make a tuple instead: ## (This is mere superstition and ignorance; I fear threads :) ) argstup=(fi.glyphpaf, dest, self.fitem.family[0],fpsys.config.points ) ## Never done threading before. Not really sure if this is kosher... #~ MICHAEL 4.2011: #~ I tried threading myself, too. But I don't really understand it #~ down to the present day. As I see "Popen" in charmaps.py/Run #~ starts his own thread, so we don`t need to make assurance double sure. #~ By the way, this push gucharmap to work as we want. self.run(*argstup) #~ thread = threading.Thread(target=self.run, args=argstup) #~ thread.setDaemon(True) #~ thread.start() def run(self, *args): """ Uses the instance (held in fpsys.config) of the classes in charmaps.py. """ iCM = fpsys.config.CMC.GetInstance() iCM.OpenApp( *args ) iCM.Cleanup( ) def onMiddleClick(self, event): ps.pub( open_settings_panel) def can_have_button( self ): """ Because I just can't guarantee that there is a family name and because bad fonts that can't draw (but do not segfault) are so rare that I can't bloody find any to test with (grrr) I make the sweeping fiat that FILE_NOT_FOUND badfonts will not get a button. Other fitems like info and FILE_NOT_FOUND don't get buttons. """ if not fpsys.config.CMC.apps_are_available: return False if isinstance( self.fitem, fontcontrol.InfoFontItem ): return False if self.fitem.badstyle == "FILE_NOT_FOUND": return False if not self.fitem.family: return False return True def onHover( self, e ): if not self.can_have_button(): self.overout.set ( True ) return if self.cmb_rect: # It's None when a Fitmap is first instanced. if self.cmb_rect.Contains( e.GetPositionTuple() ): self.cmb_overout.set( True ) self.overout.set( False ) #Not 'on' fitmap else: self.cmb_overout.set ( False ) self.overout.set( True ) def charmap_button_signal( self ): if self.cmb_overout.truthstate: self.SetCursor(wx.StockCursor(wx.CURSOR_MAGNIFIER)) self.Refresh() # Force onPaint() def overout_signal( self ): if self.overout.truthstate: self.SetCursor( self.CURSOR ) def onLeave(self, event): """ Catch the leave event for set the charmap button off, if the pointer goes out on the left edge. """ self.onHover(event) def onClick(self, event) : """ Deals with clicks on self. Charmap button is a sub-test on a rect. This refreshes the underlying bitmap and DOES NOT cause the chain update_font_view (in gui_FontView) to run. """ if self.cmb_overout.truthstate and self.can_have_button(): self.openCharacterMap() return ## Prevent a click that would APPEND a ghost font. cannot_tick = fpsys.state.action == "APPEND" and self.fitem.badstyle == "FILE_NOT_FOUND" if cannot_tick: return if fpsys.state.cantick and not self.fitem.inactive: self.fitem.ticked = not(self.fitem.ticked) self.assemble_bitmap() # This only redraws a single font item. self.Refresh() #forces onPaint() ## Inc or dec a counter depending on the tickedness of this item if self.fitem.ticked: fpsys.state.numticks += 1 if not self.fitem.ticked: fpsys.state.numticks -= 1 ps.pub(toggle_main_button) fontypython-0.5/fontypythonmodules/segwrapfonty.py0000664000175000017500000001332613212237733023003 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2006-2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . """ Dec 2017 == This is step 2 in the startup process. We get here from: fontypython Dec 2007 == This wraps fontypython.py and catches any segfaults that kill it. These segfaults happen in PIL when certain bad fonts just break stuff. I can't catch them or stop them in any way - hence this wrapper. A window displays the situation and gives the user some hope. """ if __name__ == "__main__": print "Please run fontypython, not this file." raise SystemExit import subprocess, sys, os ## find the directory from where THIS script ## is actually being run. root = __file__ if os.path.islink(root): root = os.path.realpath(root) fontyroot = os.path.dirname(os.path.abspath(root)) import fontypythonmodules.i18n as i18n # Dec 2017 # == # Added "python" so "fontypythonmodules.fontypython" need not have chmod +x # which should illustrate that only 'fontypython' is the # correct file to run. # NOTE: # ===== # I named this file 'fontypython' too - it's in the modules dir. # I want the window manager to think of it as 'fontypython' # This seems to work. # Try: xprop c1 = [ "python", os.path.join(fontyroot,'fontypython') ] ## Append any args for arg in sys.argv[1:]: c1.append( arg ) p1 = subprocess.call( c1 ) ##TEST: #p1=-11 # to test ## Nov 2017: Simpler plan: if p1 >= 0: raise SystemExit ## This actually works! import fontypythonmodules.fpsys as fpsys import wx import fontypythonmodules.fpwx as fpwx import fontypythonmodules.strings as strings class SegfaultDialog(wx.Dialog): """ Dec 2007, Nov 2017: Moved into this file from dialogues.py Runs from the wrapper script (which runs start_fontypython) so that we can tell the user that there was a segfault and why. """ def __init__(self, context, culprit): wx.Dialog.__init__(self, None, -1, _("Oh boy..."), pos = wx.DefaultPosition ) fs = wx.FlexGridSizer(cols = 1, vgap = 4) labelHeading = fpwx.h1(self, _("Fonty Python, um ... crashed.")) fs.Add(labelHeading, 0, wx.BOTTOM, border = 8 ) if context == "SEGFAULT": segdir = os.path.dirname(culprit) sadStory = _("There's some problem with the font named below.\n" \ "You can do one of two things:\n" \ "1) Manually move this font somewhere else, or\n" \ "2) Use Fonty's command-line (-c) to mark bad fonts.\n" \ " See below for help with this.\n" \ "After you've done these, run me again.") msg = _('The bad font might be:') cmd = "fontypython -c \"{}\"".format(segdir) elif context == "NO_LFBS_FILE": sadStory = _("There's no lastFontBeforeSegfault file; I can't really help.\n" \ "Look at the error (below) for clues." ) msg = _('The error was:') sadStory = fpwx.para( self, sadStory ) fs.Add(sadStory, 0, wx.BOTTOM, border = 8 ) msg = fpwx.label( self, msg ) culprit = wx.TextCtrl(self, -1, culprit, size=(0,80),style = wx.TE_READONLY | wx.TE_MULTILINE ) fs.Add(msg, 0) fs.Add(culprit, 1, wx.EXPAND ) if context == "SEGFAULT": msg1 = fpwx.label(self,_("The command line to seek and mark bad fonts is:")) msgs = fpwx.small_label(self,_("(Copy the text; open a console; paste and press enter.)")) msg2 = wx.TextCtrl(self,-1,cmd, size=(0,80), style = wx.TE_READONLY | wx.TE_MULTILINE ) fs.Add(msg1, 0, wx.TOP, border=8 ) fs.Add(msg2, 1, wx.EXPAND) fs.Add(msgs, 0 ) tickettxt = fpwx.para(self, _("You can get help by opening a ticket on:")) ticketurl = wx.TextCtrl(self, -1, strings.ticket_url, size=(0,40),style = wx.TE_READONLY) fs.Add(tickettxt, 0, wx.TOP, border=8 ) fs.Add(ticketurl, 1, wx.EXPAND ) btn = wx.Button(self, wx.ID_OK) btn.SetDefault() fs.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL| wx.ALIGN_RIGHT | wx.TOP, border = 15 ) b = wx.BoxSizer( wx.HORIZONTAL ) b.Add( fs, 0, wx.ALL, border=10 ) self.SetSizer( b ) b.Fit(self) ## Start the App and then show the Segfault dialog. class App(wx.App): def OnInit(self): culprit = None ## A wide net. Not gonna split hairs. try: paf = os.path.join( fpsys.iPC.appPath(),"lastFontBeforeSegfault") f = open( paf, "r" ) culprit = f.readline()[:-1] f.close() if not culprit:# odball situation. file may have been empty: raise IOError # force error into except else: context="SEGFAULT" except Exception as e: culprit = "{}".format(e) context="NO_LFBS_FILE" fpwx.setup_fonts_and_colours() dlg = SegfaultDialog( context, culprit ) val = dlg.ShowModal() dlg.Destroy() return True app = App(0) app.MainLoop() fontypython-0.5/fontypythonmodules/wxgui.py0000664000175000017500000007742213212237736021430 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . ## Nov 15, 2017 ## -- ## Coding while there's a Coup d'etat in Zimbabwe; our neighbour. ## Feeling of doom in our SA politics. Ruinous criminals in ANC gov; ## my health declining and no income. ## Just keeping my head down and trying to get Fonty working and ## out the door. Good luck Zimbabwe. I hope you kick out the Prick! ## Zuma next. Somehow. Without blood. """ This is the main gui. A good place to start. Look at the bottom of the file first. """ import locale import strings import fontybugs import fpsys # Global objects import fpversion ## Now, bring in all those big modules import wx import wx.html as html ## June 25th 2016 ## Remarking these two lines because they are causing a segfault: ## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get(): ## create wxApp before calling this ## Segmentation fault (core dumped) ## ## I do not know how to test or fix this, hence simply removing it. ## AFAICT, stock buttons will be in the system language. ## ## Setup wxPython to access translations : enables the stock buttons. #langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG #mylocale = wx.Locale( langid ) ## Fetch my own pubsub stuff from pubsub import * #I want all the topics. ps = CPubsub() from gui_FontSources import * from gui_FontView import * from gui_PogTargets import * import fpwx ## Variables to do with the DismissablePanels ## and to map the close (X) button id to the ## state flags we use to show/hide the panels flag_normal = 1 flag_help = 2 flag_about = 4 flag_settings = 8 flag_choosedir = 16 flag_hush_fonts = 32 ## button ids # I put them in a dict so I could more easily import them over in # gui_dismissable_panels button_ids = { 'id_x_button' : wx.NewId(), # close a dism. panel (top right) 'id_zip_pog_button' : wx.NewId(), # the button is in TargetPogChooser 'id_do_the_actual_zip' : wx.NewId(), # button is in the ChooseZipDirPanel 'id_hush_button' : wx.NewId(), # button is in the HushPanel } # Got a flag? get an id. id_from_flag = { flag_help : wx.NewId(), flag_about : wx.NewId(), flag_settings : wx.NewId(), flag_choosedir : button_ids['id_zip_pog_button'], flag_hush_fonts : wx.NewId() } # Got an id? get a flag. flag_from_id = {v:k for k,v in id_from_flag.iteritems()} #invert it! from gui_dismissable_panels import * class StatusBar(wx.StatusBar): """ The status bar """ def __init__(self, parent): wx.StatusBar.__init__(self, parent, -1) # default style is good ##Sept2017 ## Test if there's a need to warn about missing .fonts dir. no_fonts_dir = False e = fpsys.iPC.get_error_or_none("NoFontsDir") if e: no_fonts_dir = True shorterr = e.short_unicode_of_error() ## Field 1 is Welcome... ## Field 2 is normal conversation. ## Field 3 is the warning message. ## Last field "gripper" (32px) self.SetFieldsCount( 4 if no_fonts_dir else 3 ) self.SetStatusText( _("Welcome to Fonty Python, vers %s") % fpversion.version, 0) if no_fonts_dir: self.SetStatusText( shorterr, 2) print shorterr self.SetStatusWidths([300,-2,-2,32]) #self.SetStatusStyles([wx.SB_SUNKEN]*3) #SB_SUNKEN is not available to me. else: self.SetStatusWidths([300,-2,32]) #self.SetStatusStyles([wx.SB_SUNKEN]*2) def Report(self, msg): self.SetStatusText(msg, 1) print msg class MainFrame(wx.Frame): """ The main frame for the app. Start at the bottom of this file. """ def __init__(self, parent, title) : ## Draw the frame title = u"{} - {}".format( title, locale.getpreferredencoding() ) wx.Frame.__init__( self, parent, -1, title, fpsys.config.pos, fpsys.config.size, name = "fontypython") #print "Main frame:", self.GetSizeTuple()[0] ## Try to show an icon ## Oct 2017: Seems Unity (at least) doesn't even bother... try: i = wx.EmptyIcon() i.CopyFromBitmap( fpwx.wxbmp('fplogo')) self.SetIcon(i) except: pass ## STATUS BAR ## --------------------------------------- self.sb = StatusBar(self) self.SetStatusBar(self.sb) ## MENUS ## --------------------------------------- # tools selection help self.menuBar = wx.MenuBar() ## FILE MENU : Changed to "Tools" menu Sep 2009 menu1 = wx.Menu() menu1.Append( id_from_flag[flag_settings], _("&Settings\tCtrl+S"), _("Change settings")) ## Jan 18 2008 ## Nov 2017: retired: menu1.Append( 102, ## _("&Check fonts"), _("Find those fonts that crash Fonty.") ) self.id_purge = wx.NewId() menu1.Append( self.id_purge, _("&Purge Pog.See TogglePurgeMenuItem for actual string."), _("Remove all ghost fonts from the selected Pog.") ) self.MENUPURGE = menu1 ## Nov 2017: Hush fonts menu1.Append( id_from_flag[flag_hush_fonts], _("&Hush fonts\tCtrl+H"), _("Silence all the noisy system fonts and focus only on those you want,")) menu1.AppendSeparator() self.id_exit = wx.NewId() self.exit = menu1.Append(self.id_exit, _("&Exit"), _("Close the app")) ## Tools self.menuBar.Append(menu1, _("&Tools")) ## SELECT MENU: June 2009 menu3 = wx.Menu() self.id_selall = wx.NewId() menu3.Append( self.id_selall, _("&Select ALL the source fonts"), _("Select ABSOLUTELY ALL the fonts in the chosen source.")) self.id_selnone = wx.NewId() menu3.Append( self.id_selnone, _("&Clear ENTIRE selection"), _("Clear the selection completely.") ) self.menuBar.Append(menu3, _("&Selection")) self.MENUSELECTION = menu3 ## HELP MENU menu2 = wx.Menu() menu2.Append(id_from_flag[flag_help], _("H&elp\tF1")) menu2.Append(id_from_flag[flag_about], _("&About")) self.menuBar.Append(menu2, _("&Help")) self.SetMenuBar(self.menuBar) ## Setup the ESC key and the LEFT / RIGHT keys escape_key_id = wx.NewId() # Get a unique id for the ESC key accel = wx.AcceleratorTable([ (wx.ACCEL_NORMAL, wx.WXK_ESCAPE, escape_key_id), # use ESC id here (wx.ACCEL_CTRL, wx.WXK_RIGHT, wx.ID_FORWARD), (wx.ACCEL_CTRL, wx.WXK_LEFT, wx.ID_BACKWARD) ]) self.SetAcceleratorTable(accel) ## Do this generic bind for all MENU EVENTS now. ## Then specific ones afterwards; else this one supercedes them. ## This is for the menus that open DismissablePanels: ## Help, About, Settings self.Bind(wx.EVT_MENU, self.toggle_dismissable_panel) ## Bind the Left and Right key shortcuts. self.Bind(wx.EVT_MENU, self.OnAccelKey, id=wx.ID_FORWARD ) self.Bind(wx.EVT_MENU, self.OnAccelKey, id=wx.ID_BACKWARD ) ## The frame's close window button. self.Bind( wx.EVT_CLOSE, self.endApp ) ## Bind events for the exit menu self.Bind(wx.EVT_MENU, self.endApp, self.exit) ## Bind the ESCAPE key self.Bind(wx.EVT_MENU, self.onHandleESC, id = escape_key_id)# And ESC id here! #NOV 2017: Retiring this menu #I think PILLOW is more stable and I don't want to support the #extra code for the gui of this. The command line already does #a good job (-c) and my crash dialogue tells the user what to do. ##self.Bind(wx.EVT_MENU, self.menuCheckFonts, id = 102 ) self.Bind(wx.EVT_MENU, self.menuPurgePog, id = self.id_purge ) # June 2009 self.Bind(wx.EVT_MENU, self.menuSelectionALL, id=self.id_selall) self.Bind(wx.EVT_MENU, self.menuSelectionNONE, id=self.id_selnone) ## Catch buttons in various panels. The panels have not been ## declared yet. See below. ## NB: THESE BINDS HAPPEN SECOND, *AFTER* toggle_dismissable_panel ## has Skipped. ## The first Bind EVT_BUTTON is last in the code, see just below. ## 1. .toggle_dismissable_panel --> Does a Skip() to ## 2. Here: ## Catch the Apply button in the settings panel. self.Bind(wx.EVT_BUTTON, self.apply_settings, id=wx.ID_APPLY) ## Catch the Zip button in the choose_zipdir_panel self.Bind(wx.EVT_BUTTON, self.do_pog_zip, id=button_ids['id_do_the_actual_zip']) ## Catch the Huch button in hush_panel self.Bind(wx.EVT_BUTTON, self.do_hush_unhush, id=button_ids['id_hush_button']) ## Vague Bind. Not specific to id. ## HAPPENS FIRST even though it's last in the code. ## 1. The close (X) button of the DismissablePanels ## 2. The ZIP button (Skipped to here from TargetPogChooser) self.Bind(wx.EVT_BUTTON, self.toggle_dismissable_panel ) ## THE MAIN GUI ## ------------------------------------------------------------------ MINSCREENWIDTH = 800 #old skool minw = 360 # pretty much the width of the left hand side. fvminw = MINSCREENWIDTH - minw # The width of the rhs. ms = wx.Size( minw, 1 ) ## PRIMARY GUI ## =========== ## No splitters at all. ## Box across: two ## Left box: Box vertical: two (source/target) ## Right box: Fontview ## :- kind of shape. self.panelFontSources = FontSourcesPanel(self) self.panelFontSources.SetMinSize(ms) self.panelTargetPogChooser = TargetPogChooser(self, button_ids['id_zip_pog_button']) self.panelTargetPogChooser.SetMinSize(ms) self.fontViewPanel = FontViewPanel(self) self.fontViewPanel.SetMinSize(wx.Size(fvminw,1)) ## Oct/Nov 2017 ## Moved some dialogues into the app as panels: ## Help self.help_panel = HelpPanel(self) #self.help_panel.Hide() ## About self.about_panel = AboutPanel(self) #self.about_panel.Hide() ## I will use fontViewPanel as the standard to ## measure widths in these DismissablePanels wfunc = self.fontViewPanel.GetSize ## The Settings self.settings_panel = SettingsPanel( self, wfunc ) #self.settings_panel.Hide() ## Zip Pog panel self.choose_zipdir_panel = ChooseZipDirPanel( self, wfunc ) #self.choose_zipdir_panel.Hide() ## Hush panel self.hush_panel = HushPanel( self, wfunc ) stsizer = wx.BoxSizer(wx.VERTICAL) stsizer.Add( self.panelFontSources, 1, wx.EXPAND|wx.ALL,border = 5 ) stsizer.Add( self.panelTargetPogChooser, 1, wx.EXPAND|wx.ALL,border = 5 ) lrsizer = wx.BoxSizer(wx.HORIZONTAL) lrsizer.Add( stsizer, 0, wx.EXPAND) lrsizer.Add( self.fontViewPanel, 1, wx.EXPAND|wx.ALL, border = 5 ) lrsizer.Add( self.help_panel, 1, wx.EXPAND ) lrsizer.Add( self.about_panel, 1, wx.EXPAND ) lrsizer.Add( self.settings_panel, 1, wx.EXPAND ) lrsizer.Add( self.choose_zipdir_panel, 1, wx.EXPAND ) lrsizer.Add( self.hush_panel, 1, wx.EXPAND ) self.SetSizer(lrsizer) ## A system to control the hide/show of these panels. self.panel_state = flag_normal self.panel_dict={ flag_normal : self.fontViewPanel, flag_help : self.help_panel, flag_about : self.about_panel, flag_settings : self.settings_panel, flag_choosedir : self.choose_zipdir_panel, flag_hush_fonts : self.hush_panel, } ## ## Very out of date. Left for future maybes. ## ##splitter window of 2 across ##left: a panel with sizer of two high of: source, then target guis ##right: fontview ##This one freezes the app when you resize to the right... :( ## Hard to reproduce. I used gdb and got it to crash, then ## did a 'bt' and saw some complaints about get text extents ## might be a bug in my font drawing code..? ## self.spw = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) ## This line seems less crashy, but not much less: ## self.spw = wx.SplitterWindow(self) #fvminw = MINSCREENWIDTH #self.spw = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) #self.spw.SetMinimumPaneSize(minw) #p1 = wx.Panel(self.spw) #self.panelFontSources = FontSourcesPanel(p1) #self.panelTargetPogChooser = TargetPogChooser(p1) #stsizer = wx.BoxSizer(wx.VERTICAL) #stsizer.Add( self.panelFontSources, 1, wx.EXPAND|wx.ALL,border = 5 ) #stsizer.Add( self.panelTargetPogChooser, 1, wx.EXPAND|wx.ALL,border = 5 ) #p1.SetSizer(stsizer) #self.fontViewPanel = FontViewPanel(self.spw) #self.fontViewPanel.SetMinSize(wx.Size(fvminw,1)) #self.spw.SplitVertically( p1, self.fontViewPanel)#, self.initpos) ## Thanks to the multiSplitterWindow code from the demo: #self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.onSplitterPosChanging) #self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.onSplitterPosChanged) ##Only used if whatgui != 1 #def onSplitterPosChanging(self,evt): # """ # A Splitter is moving - PRESENT TENSE. Let's do the least work poss. # """ # esp = evt.GetSashPosition() # print esp # if esp > 500: # evt.Veto() # return ##Only used if whatgui != 1 #def onSplitterPosChanged( self, evt ): # """ # A Splitter has been moved - PAST TENSE. # We only want to redraw the fonts when the splitter dragging is over. # """ # ps.pub( update_font_view ) # starts a HUGE chain of calls. ## Frame resizing sanity code self.resized = False self.Bind(wx.EVT_IDLE, self.onIdle) self.Bind(wx.EVT_SIZE, self.onFrameSize) ## GUI ENDS ## ============= self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) ## Now to subscribe to have my various def called from other places: ps.sub(show_error, self.ErrorBox) ps.sub(show_error_and_abort, self.ErrorAbort) ps.sub(show_message, self.MessageBox) ps.sub(print_to_status_bar, self.StatusbarPrint) ## Dec 2007 - Used on middle click in gui_Fitmap.py ps.sub( open_settings_panel, self.open_settings_panel ) ps.sub( toggle_selection_menu_item, self.toggleSelectionMenuItem ) ps.sub( toggle_purge_menu_item, self.TogglePurgeMenuItem ) ps.sub( ensure_fontview_shown, self.ensure_fontview_shown ) ## call the big one - the big chief, the big cheese: ## This eventually draws all the Fitmaps - giving the middle a width. ps.pub( update_font_view ) #See gui_FontView.py under class FontViewPanel self.SetMinSize(wx.Size(MINSCREENWIDTH,600)) #Old Skool: Assuming monitor size... # Don't do Fit. # It makes the FRAME size DOWN to the minimum children's size! ## self.Fit() self.Layout() ## This is to draw the correct icons depending on cli params. self.panelTargetPogChooser.pogTargetlist.toggle_list_icons_according_to_selection(False) ## State stuff to manage the DismissablePanels def flag_state_on(self, flag): self.panel_state |= flag def flag_state_off(self, flag): self.panel_state &= ~flag def flag_state_exclusive_toggle(self, flag): """ Toggle this flag's bit. All other flags will be turned off. """ fs = self.is_state_flagged(flag) self.panel_state = 0 if fs: #swap it self.flag_state_off(flag) else: self.flag_state_on(flag) def is_state_flagged(self,flag): #print "state is: {:08b}".format( self.panel_state) return self.panel_state & flag == flag def hide_or_show_panels(self): if self.panel_state == 0: self.panel_state = flag_normal for flag, pan in self.panel_dict.iteritems(): if self.is_state_flagged(flag): pan.Show() pan.SetFocus() else: pan.Hide() self.flag_state_off(flag) self.Layout() def ensure_fontview_shown(self): ## For use from outside. ## See start of gui_FontView.MainFontViewUpdate() self.panel_state = flag_normal self.hide_or_show_panels() def toggle_dismissable_panel(self, evt): """ Handles events from a few different sources: menus and buttons. Looks for an id in the flag_from_id dict. If found, we know it's to do with a DismissablePanel. """ #print "toggleSelectionMenuItem runs." #print evt.GetId() flag = flag_from_id.get(evt.GetId(),None) #print "got flag:", flag if flag: self.flag_state_exclusive_toggle(flag) self.hide_or_show_panels() ## NB: I have more bindings after this handler is done: evt.Skip() def onFrameSize(self,evt): self.resized = True evt.Skip() def onIdle(self, evt): if self.resized: ## If it's showing the normal (font) view, then: if self.is_state_flagged(flag_normal): # I place this fact into fpsys.state so # that I can read it again down in the # fitmap assemble_bitmap code. fpsys.state.main_frame_resized = True # Go re-draw shit. ps.pub( update_font_view ) # Flag it off self.resized = False # Flag it off in fpsys.state too fpsys.state.main_frame_resized = False def OnAccelKey(self,evt): ps.pub( left_or_right_key_pressed, evt ) #fwd this business on-to a func in gui_FontView.py def toggleSelectionMenuItem(self, onoff): #HIG says to leave top menu alone and only toggle sub-items. self.MENUSELECTION.Enable(self.id_selall,onoff[0]) self.MENUSELECTION.Enable(self.id_selnone,onoff[0]) def StatusbarPrint(self, args): self.sb.Report(args[0]) def MessageBox(self, args): dlg = wx.MessageDialog(self, args[0] , _("Warning"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def ErrorBox(self, args): dlg = wx.MessageDialog(self, args[0], _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() def ErrorAbort(self, args): self.ErrorBox(args) #Pass it along to be displayed self.endApp() def onHandleESC( self, e ): """ ESC key wired to this. If we have a DismissablePanel open, let's close it instead of the app. """ if not self.is_state_flagged(flag_normal): self.ensure_fontview_shown() else: self.endApp(None) def endApp( self, e ) : """ Frame's X is wired to this. Save app's vital statistics and exit. See the end of start.py where it's actually saved. """ ## Dec 2007 - I was using the wrong func and the ## main window kept getting smaller! fpsys.config.size = self.GetSizeTuple() fpsys.config.pos = self.GetScreenPosition() ## Nov 2017: We got here, so there are no segfaults, thus ## we have no need for this file. fpsys.rm_lastFontBeforeSegfault_file() print strings.done self.Destroy() def open_settings_panel(self): """Called from Fitmap on middle click.""" self.flag_state_exclusive_toggle( flag_settings ) self.hide_or_show_panels() def apply_settings(self, e): """ The second stage of the Apply button on the settings panel. (Stage one is within the SettingsPanel class.) We get here after all the values have been checked and recorded into fpsys.config Here we only need to decide on what to redraw. """ #print "apply settings?" if self.settings_panel.settings_force_redraw(): ## If the ignore adjustments checkbos changed: if self.settings_panel.has_changed("ignore_adjustments"): ps.pub( reset_top_left_adjustments ) ## This recurse checkbox is more complex. ## I have to hand over control to that class: if self.settings_panel.has_changed("recurseFolders"): ## This does a redraw, and there it does a ## force-close of the settings panel. ## We have to imitate a click on the dir control ## to kick stuff into gear. ps.pub( fake_click_the_source_dir_control ) # bail! So we don't do another re-draw. return ## Redraw the fitmaps (Will also hide the settings_panel) ps.pub( update_font_view ) else: ## With no changes, we must hide the settings_panel self.ensure_fontview_shown() return def do_hush_unhush(self, e): """ Use the code in fpsys to hush or unhush. """ ## Just paranoid - want to make sure it's the correct button id ## Only want to fire on press of button in the hush_panel: if e.GetId() == button_ids['id_hush_button']: buglist = [] if not os.path.exists(fpsys.HUSH_PAF): ## Hush hush_pog = fpsys.config.hush_pog_name printer = self.hush_panel.printout buglist = fpsys.hush_with_pog( hush_pog, printer ) else: ## Un hush printer = self.hush_panel.printout buglist = fpsys.un_hush( printer ) if buglist: ## All errors end with this text: printer( strings.cant_hush, key="title") for bug in buglist: printer( bug, key="ERROR" ) ## Go refresh the panel to update state self.hush_panel.after_do_hushing() def do_pog_zip(self, e): """ The button in the choose_zipdir_panel was clicked. """ czd = self.choose_zipdir_panel todir = czd.get_path() emsg = "" printer = czd.printout if todir: wx.BeginBusyCursor() for p in self.panelTargetPogChooser.list_of_target_pogs_selected: ipog = fontcontrol.Pog(p) (bugs, fail, emsgs) = ipog.zip( todir ) if fail: printer( _("I could not create the zip for {}").format(ipog) ) printer( emsgs[0]) printer( "" ) else: printer( _("Zipped as \"{}.fonts.zip\" in the \"{}\" directory.").format( p, todir) ) printer( "" ) if bugs: printer( _("Some bugs happened:") ) for m in emsgs: printer( m ) printer( "" ) wx.EndBusyCursor() if bugs: printer(_("Some fonts were skipped, try purging the Pog(s) involved.")) ps.pub(print_to_status_bar,_("Something went wrong.")) else: printer(_("Zip file(s) have been created.")) ps.pub(print_to_status_bar,_("Zip file(s) have been created.") ) ##Retired NOV 2017 #def menuCheckFonts( self, e ): # """ # Added Jan 18 2008 # User can visit suspicious directories with this tool # to gather a list of fonts that kill the app. They will be # marked as such and hereafter be safe to use. # """ # ## Set startdir to the one our own dircontrol is in # if fpsys.state.viewpattern == "F": # startdir = fpsys.state.viewobject.path # else: # ##Let's get it from the config object # startdir = fpsys.config.lastdir # dlg = dialogues.DialogCheckFonts( self, startdir ) # val = dlg.ShowModal() # dlg.Destroy() def menuSelectionALL(self,e): """ Select all the fonts that are FILTERED. Note: This does not do a test for ghost fonts. TODO """ if not fpsys.state.cantick: return # Can't tick if this is False. fpsys.state.numticks=0 vo=fpsys.state.filteredViewObject # We want to select what is FILTERED for fi in vo: if not fi.inactive: fi.ticked=True fpsys.state.numticks += 1 ## Now update the view ps.pub( update_font_view ) def menuSelectionNONE(self,e): """ Deselcts all the fonts. """ fpsys.state.numticks=0 vo=fpsys.state.viewobject # We *REALLY* mean select NONE. So ignore filter. for fi in vo: if not fi.inactive: fi.ticked=False ## Now update the view ps.pub( update_font_view ) def TogglePurgeMenuItem(self, vis): vis=vis[0] #print vis #print fpsys.state.viewobject.name self.MENUPURGE.Enable(self.id_purge, vis) ## July 2016 ## ========= ## Make the label of the menu reflect the view Pog's name ## so it's clear which selection counts for purging. if vis: self.MENUPURGE.SetLabel(self.id_purge, _("&Purge \"%s\"\tCtrl+P" % fpsys.state.viewobject.name ) ) else: self.MENUPURGE.SetLabel(self.id_purge, _("&Purge Pog\tCtrl+P")) #Reflect original string, as it's got translations already. def menuPurgePog(self,e): ##The menu item only becomes active for Pogs that are not installed, ##so we can purge without further tests: pogname = fpsys.state.viewobject.name dlg = wx.MessageDialog(self,_("Do you want to purge %s?\n\nPurging means all the fonts in the pog\nthat are not pointing to actual files\nwill be removed from this pog.") % pogname, _("Purge font?"), wx.YES_NO | wx.ICON_INFORMATION ) if dlg.ShowModal() == wx.ID_YES: ## pog.purge() Raises ## PogEmpty ## PogInstalled try: fpsys.state.viewobject.purge() except(fontybugs.PogEmpty, fontybugs.PogInstalled),e: ps.pub(show_error, unicode( e )) ps.pub(print_to_status_bar, _("%s has not been purged.") % pogname) return ## Update GUI ps.pub(print_to_status_bar, _("%s has been purged.") % pogname) ps.pub(update_font_view) # Code for debugging: ##http://wiki.wxpython.org/Widget%20Inspection%20Tool ## Use ctrl+alt+i to open it. #import wx.lib.mixins.inspection ## Start the main frame and then show it. class App( wx.App ):# , wx.lib.mixins.inspection.InspectionMixin) : """ The main wxPython app starts here """ def OnInit(self): #self.Init() # initialize the inspection tool ## Initial dialogue to inform user about wx unicode version. if not "unicode" in wx.PlatformInfo: wx.MessageBox(_("I am sorry, but Unicode is not supported by this " \ "installation of wxPython. Fonty Python relies on Unicode and will " \ "simply not work without it.\n\nPlease fetch and install the " \ "Unicode version of python-wxgtk."), caption=_("SORRY: UNICODE MUST BE SUPPORTED"), style=wx.OK | wx.ICON_EXCLAMATION ) raise SystemExit ## Probe for delayed errors in PathControl ## and show them in message boxes. try: fpsys.iPC.probeAllErrors() ## App stopping errors: except (fontybugs.NoFontypythonDir, fontybugs.UpgradeFail ) as e: wx.MessageBox( e.unicode_of_error(), caption=_("FATAL ERROR"), style=wx.OK | wx.ICON_ERROR ) ## This one is unrecoverable: raise SystemExit except fontybugs.NoFontconfigDir as e: fpsys.state.fontconfig_confd_exists = False ## Warning only except fontybugs.NoFontsDir as e: ## This looks horrible. I will remark it. ## The app deals with it in context. # wx.MessageBox( e.unicode_of_error(), # caption=_("WARNING"), # style=wx.OK | wx.ICON_ERROR ) pass # Start a splash screen - which then starts the main frame MySplash = FontySplash() return True class FontySplash(wx.Frame): """ Show the splash screen; it's fast and remains there while the frame loads behind it. Borrowing from the wxPython-demo's code. (Code hacked from AdvancedSplash by Andrea Gavana.) """ def __init__( self ): timeout = 2000 # A smaller number then the first timeout mainframetimeout = 500 wx.Frame.__init__(self, None, -1, "", wx.DefaultPosition, wx.DefaultSize, wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP) # Load the FP logo img = wx.Image( os.path.join(fpsys.mythingsdir, 'splash.png') ) img.ConvertAlphaToMask() self.bmp = wx.BitmapFromImage(img) # Calculate the shape self.reg = wx.RegionFromBitmap(self.bmp) # Works on wx.Platform == "__WXGTK__" self.Bind(wx.EVT_WINDOW_CREATE, self.SetSplashShape) w = self.bmp.GetWidth() + 1 h = self.bmp.GetHeight() + 1 # Set frame to the bitmap size self.SetClientSize((w, h)) self.CenterOnScreen() # Starts timer self._splashtimer = wx.PyTimer(self.OnNotify) self._splashtimer.Start(timeout) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) # Nice! Kick the MainFrame off in x milliseconds self.fc = wx.FutureCall( mainframetimeout, self.showMain ) self.Show() def SetSplashShape(self, event=None): self.SetShape(self.reg) if event is not None: event.Skip() def OnPaint(self, event): dc = wx.PaintDC(self) # Draw over frame dc.DrawBitmap(self.bmp, 0, 0, True) def OnNotify(self): self.Close() def OnCloseWindow(self, event): if hasattr(self, "_splashtimer"): self._splashtimer.Stop() del self._splashtimer self.Destroy() event.Skip() # Make sure the default handler runs too... def showMain(self): ## Oct 2017 ## Setup my system fonts and colours fpwx.setup_fonts_and_colours() frame = MainFrame(None, _("Fonty Python: bring out your fonts!")) app.SetTopWindow(frame) frame.Show(True) #Start the app! app = App(0) app.MainLoop() fontypython-0.5/fontypythonmodules/fpwx.py0000664000175000017500000002276113212237737021246 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx import fpsys ## Oct 2017 Default Font Family (System font) ## And colours from the user's gui settings: ## Setup in showMain() in wxgui.py SYSFONT={} SYSCOLS={} HTMLCOLS={} def setup_fonts_and_colours(): SYSCOLS.update( {"dark" : wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT), "gray" : wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT), "shadow": wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNSHADOW), "neutral": wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND), "light" : wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW), "highlight": wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT), }) ##Colours for things that use html hcol = SYSCOLS["highlight"] HTMLCOLS.update({ "logotype":hcol, "dark" :SYSCOLS["dark"], "medium" :SYSCOLS["gray"], "bg" :SYSCOLS["neutral"], "heading1":hcol, "heading2":hcol, "heading3":hcol, "heading4":hcol, "heading5":hcol, "heading6":hcol, }) # I need them all in #RRGGBB format: for k,v in HTMLCOLS.iteritems(): HTMLCOLS[k] = v.GetAsString(flags=wx.C2S_HTML_SYNTAX) # Going with the sys colours. #HTMLCOLS.update({"fontyblue":u"#768b94"}) wxfont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) # I had this in SYSFONT: #"font" : wxfont, # But it acts weirdly later on. Don't store refs to a font. # Point sizes are integers. ps = wxfont.GetPointSize() SYSFONT.update( { "points_tiny" : ps-2, "points_small" : ps-1, "points_normal" : ps, "points_x_normal" : ps+1, "points_large" : ps+2, "points_x_large" : ps+5, "points_xx_large" : ps+8, "points_xxx_large": ps*2, }) class AutoWrapStaticText(wx.PyControl): """ Mostly by Robin Dunn Layout_func: Means we will set the text many times. Is called when SetLabel() happens. Nominate some object in the parent tree which can have .Layout() called on it such that this control will be re-drawn. It's the only way to get this StaticText to fit the space. I can't predict which object will work, so it's left to the caller. """ def __init__(self, parent, ustr, point_size, style, weight, Layout_func = None): pos = wx.DefaultPosition # Tip: # The parent *must* have a legitimate width # To do that: ensure the parent's constructor # has a size argument that makes sense. # Without a width, none of this works. # The -1 on the height seems to be vital, # remove it and nothing works. sz = wx.Size( parent.GetSize()[0], -1) self._lf = Layout_func wx.PyControl.__init__(self, parent, -1, wx.DefaultPosition, sz, wx.NO_BORDER, wx.DefaultValidator) # Make our static text and give it # some default system properties. self.st = wx.StaticText(self, -1, ustr, size=sz, style = style ) # Stuff that can't go into the constructor: f = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) f.SetPointSize(SYSFONT[point_size]) f.SetWeight(weight) self.st.SetFont( f ) self._label = ustr # save the unwrapped text self._rows = 0 # Will be the number of rows after a wrap. # Found a func that gives me pixels! I don't need # the whole dc measure thing. self._lineheight = f.GetPixelSize()[1] + 3 # add some extra padding. self._Rewrap() self.Bind(wx.EVT_SIZE, self.OnSize) def SetLabel(self, label): """ This is the NB one. I need to set different strings - and they can be long or short. I.e. they may need to wrap, or not. """ # What's the new label? self._label = label # Go wrap it: self._Rewrap() # If we have a Layout func, call it: if self._lf: self._lf() def GetLabel(self): return self._label def OnSize(self, evt): # Make the StaticText be my width self.st.SetSize( self.GetSize() ) # Go wrap it again: self._Rewrap() #evt.Skip() def _Rewrap(self): """ Change the StaticText's label to the unwrapped version. Use my width and re-wrap. (This alters the actual string by adding newlines. I've noticed it fails on strings that have no spaces ...) """ self.st.Freeze() self.st.SetLabel( self._label ) w = self.GetSize().width self.st.Wrap( w ) self.st.Thaw() def DoGetBestSize(self): """ Don't ask me. This is a total mystery. I make it return something sensible. A tup of my width, text's height lineheight * rows => +/- the height """ rows = self.st.GetLabel().count("\n") + 1 h = rows * self._lineheight sw = self.GetSize().width sz = wx.Size( sw, h ) self.CacheBestSize(sz) return sz def xlabel(parent, ustr, pointsize = None, weight = None, align = wx.ALIGN_LEFT, ellip = None, Layout_func = None, wrap = False): """ Generic label func. Args: wrap or Layout_func They are exclusive: use either, not both. Either flag means: use AutoWrapStaticText control. AutoWrapStaticText is a live static text that wraps and can have its label set (it will resize properly by calling Layout_func() to force a proper redraw. If there is no Layout_func it implies that SetLabel will never be called. wrap on its own means we can go without the Layout_func - i.e. it will not alter the label's string. It will only wrap in the space it started with. (e.g. the long paragraphs in the HushPanel.) Neither: Defaults to a StaticText which will not wrap. """ s = align if ellip: s |= ellip if wrap or Layout_func: lbl = AutoWrapStaticText( parent, ustr, pointsize, s, weight, Layout_func = Layout_func) else: # This is a single-use static text. No wrapping. lbl = wx.StaticText( parent, -1, u"..", style = s) # I can't feed these in via the constructor, hence # this second stage: f = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) f.SetPointSize(SYSFONT[pointsize]) f.SetWeight(weight) lbl.SetFont(f) # This causes a resize on the label. Weirdly, it still # cuts off some text. I fuckin' give up. lbl.SetLabel(ustr) return lbl # A bunch of funcs that all feed into xlabel # I prefer web concepts like p, h1, to the argument-heavy stuff. def parar( parent, ustr, pointsize="points_normal" ): return xlabel( parent, ustr, pointsize, weight=wx.FONTWEIGHT_NORMAL, align=wx.ALIGN_RIGHT ) def para( parent, ustr, align="wx.ALIGN_TOP", pointsize="points_normal", **args): return xlabel( parent, ustr, pointsize, weight=wx.FONTWEIGHT_NORMAL, **args) def label( parent, ustr, align = wx.ALIGN_LEFT, **args): return xlabel( parent, ustr, pointsize="points_normal", weight=wx.FONTWEIGHT_NORMAL, align = align, **args) def large_label( parent, ustr, **args ): return xlabel( parent, ustr, pointsize="points_x_normal", weight=wx.FONTWEIGHT_NORMAL, **args) def small_label( parent, ustr, **args ): return xlabel( parent, ustr, pointsize="points_small", weight=wx.FONTWEIGHT_NORMAL, **args) def boldlabel( parent, ustr, **args ): return xlabel( parent, ustr, pointsize="points_x_normal", weight=wx.FONTWEIGHT_BOLD, **args) def h0( parent, ustr, **args ): return xlabel( parent, ustr, "points_xxx_large", wx.FONTWEIGHT_BOLD, **args) def h1( parent, ustr, **args): return xlabel( parent, ustr, pointsize="points_large", weight=wx.FONTWEIGHT_BOLD, **args) def h2( parent, ustr, **args ): return xlabel( parent, ustr, pointsize="points_large", weight=wx.FONTWEIGHT_NORMAL, **args) # A quick way to get a file from the things directory: def wxbmp( filename ): return wx.Bitmap( fpsys.mythingsdir + filename+".png", wx.BITMAP_TYPE_PNG ) # I don't even recall... def icon(parent, filename): b = wxbmp( filename ) i = wx.StaticBitmap( parent, -1, b ) return i fontypython-0.5/fontypythonmodules/pofiles/0000775000175000017500000000000013212250216021324 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/pofiles/fr_all.merged.po0000664000175000017500000015312213212036003024365 0ustar donndonn00000000000000# -*- coding: utf8 -*- # French translations for fontypython package # Traduction anglaise du package fontypython. # Copyright (C) 2006 THE fontypython'S COPYRIGHT HOLDER # This file is distributed under the same license as the fontypython package. # Baptiste , 2006. # msgid "" msgstr "" "Project-Id-Version: fontypython 0.2.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-06 20:46+0200\n" "PO-Revision-Date: 2008-01-22 19:46+0200\n" "Last-Translator: Donn Ingle \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: fontypythonmodules/cli2.py:70 msgid "" "I can't decode your argument(s). Please check your LANG variable. Also, " "don't paste text, type it in." msgstr "" #: fontypythonmodules/cli2.py:86 msgid "" "For more help use: \"-h b\" for basic help, \"-h e\" for examples,\n" "or \"-h hush\" for help with hushing fonts." msgstr "" #: fontypythonmodules/cli2.py:197 #, python-format msgid "%s takes two arguments: SOURCE(folder) TARGET(pog)" msgstr "" #: fontypythonmodules/cli2.py:199 msgid "" "NB: If you have spaces in the Pog or Folder names, put \"quotes around the " "names.\"" msgstr "" #: fontypythonmodules/cli2.py:234 msgid "Weirdo error. Keep calm and panic." msgstr "" #: fontypythonmodules/cli2.py:296 msgid "unknown, try: {}" msgstr "" #: fontypythonmodules/cli2.py:372 #, fuzzy msgid "" "Please check your arguments, there seem to be too many.\n" "(Remember: it's one pound for a five minute argument, but only eight pounds " "for a course of ten.)\n" "\n" "NB: If you use spaces in a Pog or Folder name then put \"quotes around the " "names.\"" msgstr "" "Veuillez vérifier vos arguments, il semble y en avoir trop.\n" "\n" "NB : Si vous souhaitez utiliser des espaces dans le nom d'un\n" "pog ou d'un fichier, alors veuillez les entourer de guillemets." #: fontypythonmodules/cli2.py:405 #, python-format msgid "Sorry, (%s) does not exist. Try --list" msgstr "(%s) ne peut être trouvé. essayez -l pour voir les noms disponibles." #: fontypythonmodules/cli2.py:410 msgid "You cannot use a folder as the target argument. Try --help" msgstr "" "Vous ne pouvez pas utiliser un dossier comme un pog cible. Essayez --help" #: fontypythonmodules/cli2.py:462 fontypythonmodules/cli2.py:483 #, python-format msgid "" "The target pog (%s) is currently installed, you can't use it as a target." msgstr "" "Le pog (%s) est actuellement installé, vous ne pouvez pas l'utiliser comme " "une cible." #: fontypythonmodules/cli2.py:468 msgid "Your pogs are the same! Try -e" msgstr "Vos pogs sont les mêmes ! Essayez -e" #: fontypythonmodules/cli2.py:475 msgid "This pog is empty" msgstr "Le pog est vide." #: fontypythonmodules/clifuncs.py:27 #, python-format msgid "I can't find %s" msgstr "" #: fontypythonmodules/clifuncs.py:46 msgid "There are no pogs available." msgstr "Il n'y a pas autant d'éléments." #: fontypythonmodules/clifuncs.py:48 #, python-format msgid "Listing %d pog(s)" msgstr "Affichage de %d pog(s) " #: fontypythonmodules/clifuncs.py:49 msgid " * indicates installed pogs" msgstr " * indique les pogs installés" #: fontypythonmodules/clifuncs.py:57 #, python-format msgid "Could not open (%s)." msgstr "Impossible d'ouvrir (%s)." #: fontypythonmodules/clifuncs.py:71 msgid "Could not ls the font path." msgstr "" #: fontypythonmodules/clifuncs.py:73 msgid "Contents of {}:" msgstr "" #: fontypythonmodules/clifuncs.py:84 msgid "Could not cat that pog." msgstr "" #: fontypythonmodules/clifuncs.py:127 msgid "I could not create the zip at all." msgstr "" #: fontypythonmodules/clifuncs.py:130 fontypythonmodules/wxgui.py:679 msgid "Zipped as \"{}.fonts.zip\" in the \"{}\" directory." msgstr "" #: fontypythonmodules/clifuncs.py:132 fontypythonmodules/wxgui.py:682 msgid "Some bugs happened:" msgstr "" #: fontypythonmodules/clifuncs.py:135 #, python-format msgid "I can't find a pog named %s" msgstr "" #: fontypythonmodules/clifuncs.py:154 fontypythonmodules/clifuncs.py:185 #, python-format msgid "(%s) cannot be found. Try -l to see the names." msgstr "(%s) ne peut être trouvé. essayez -l pour voir les noms disponibles." #: fontypythonmodules/clifuncs.py:177 fontypythonmodules/fpsys.py:975 #, python-format msgid "Installing (%s)" msgstr "Installer le Pog (%s)" #: fontypythonmodules/clifuncs.py:204 #, python-format msgid "Removing (%s)" msgstr "Visualisation de (%s)" #: fontypythonmodules/clifuncs.py:211 #, python-format msgid "Sorry, can't find (%s). Try -l to see the names." msgstr "(%s) ne peut être trouvé. essayez -l pour voir les noms disponibles." #: fontypythonmodules/clifuncs.py:234 #, fuzzy, python-format msgid "Creating a new pog: %s" msgstr "Erreur lors de la création d'une image Wx de %s" #: fontypythonmodules/clifuncs.py:257 #, fuzzy, python-format msgid "I have placed %(count)s fonts from %(folder)s into %(pog)s." msgstr "Les polices sélectionnées sont maintenant dans %s." #: fontypythonmodules/clifuncs.py:259 #, python-format msgid "The fonts from %(folder)s are *already* in %(pog)s." msgstr "" #: fontypythonmodules/fontcontrol.py:146 msgid "" "Font cannot be found. Purge lost fonts from this Pog.\n" "(See the Tools menu.)" msgstr "" #: fontypythonmodules/fontcontrol.py:152 #, python-format msgid "" "Unhandled error:\n" "Please remove (%s) away from here and report this to us." msgstr "" #: fontypythonmodules/fontcontrol.py:164 msgid "Font may be bad and it cannot be drawn." msgstr "" #: fontypythonmodules/fontcontrol.py:179 msgid "Unicode problem. Font may be bad and it cannot be drawn." msgstr "" #: fontypythonmodules/fontcontrol.py:250 msgid "Font causes a segfault. It cannot be drawn." msgstr "" #: fontypythonmodules/fontcontrol.py:295 msgid "There are no fonts to see here, move along." msgstr "Choisissez un dossier ou un Pog," #: fontypythonmodules/fontcontrol.py:296 msgid "" "Stuff to check:\n" "\t1) The filters.\n" "\t2) The \"include sub-folders\"\n" "\t\tcheck box (in Settings).\n" "\t3) The Help file." msgstr "" #: fontypythonmodules/fontcontrol.py:823 #, fuzzy, python-format msgid "%s is already installed." msgstr "Pog est installé." #: fontypythonmodules/fontcontrol.py:977 fontypythonmodules/fontcontrol.py:998 msgid "I can't write to this directory: {}" msgstr "" #: fontypythonmodules/fontcontrol.py:1015 msgid "Correcting timestamp on {}." msgstr "" #: fontypythonmodules/fontcontrol.py:1026 msgid "Zip on {} failed because: {}" msgstr "" #: fontypythonmodules/fontybugs.py:37 msgid "" "\n" "(Also check your file permissions.)" msgstr "" "\n" "(Vérifiez également les permissions.)" #: fontypythonmodules/fontybugs.py:39 msgid "Bad voodoo error. I give up." msgstr "Erreur maléfique vaudou, j'abandonne." #: fontypythonmodules/fontybugs.py:40 msgid "There is no such item." msgstr "Il n'y a pas autant d'éléments." #: fontypythonmodules/fontybugs.py:41 msgid "Pog is empty." msgstr "Le pog est vide." #: fontypythonmodules/fontybugs.py:42 msgid "Pog is already installed." msgstr "Pog est installé." #: fontypythonmodules/fontybugs.py:43 #, python-format msgid "" "Pog cannot be written to.\n" "Check your filesystem.%s" msgstr "" "Le pog ne peut être enregistré.\n" "Vérifiez le système de fichier.%s" #: fontypythonmodules/fontybugs.py:44 msgid "Pog is invalid, please hand-edit it." msgstr "Le pog est invalide, veuillez l'éditer à la main." #: fontypythonmodules/fontybugs.py:45 msgid "" "Some fonts did not install.\n" "Perhaps the original fonts folder has moved or been renamed.\n" "You should purge or hand-edit." msgstr "" "Certaines polices n'ont pas été installées.\n" "Peut-être que le dossier d'origine a été déplacé ou renommé.\n" "Vous devriez le purger (-p) ou l'éditer à la main." #: fontypythonmodules/fontybugs.py:46 msgid "Pog is not installed." msgstr "Le Pog n'est pas installé." #: fontypythonmodules/fontybugs.py:47 #, python-format msgid "" "Some fonts could not be uninstalled.\n" "Please check your home .fonts (with a dot in front) folder for broken links." "%s" msgstr "" "Certaines polices ne peuvent pas être désinstallées.\n" "Veuillez vérifier votre dossier ~/.fonts/ (sans oublier le point).%s" #: fontypythonmodules/fontybugs.py:48 #, python-format msgid "Cannot delete the Pog.%s" msgstr "Impossible de supprimer le Pog.%s" #: fontypythonmodules/fontybugs.py:49 msgid "" "Not a single font in this pog could be installed.\n" "The original font folder has probably moved or been renamed." msgstr "" "Pas la moindre police de ce pog n'a pu être installée.\n" "Le dossier originel a du être supprimé ou renommé." #: fontypythonmodules/fontybugs.py:50 msgid "" "Not a single font in this pog could be uninstalled.\n" "None of the fonts were in your fonts folder, please check your home .fonts " "(with a dot in front) folder for broken links.\n" "The pog has been marked as \"not installed\"." msgstr "" "Pas la moindre police de ce pog n'a pu être désinstallée.\n" "Aucune d'entre elles n'étaient dans votre dossier de polices, veuillez\n" "vérifiez le dossier ~/.fonts/ (sans oublier le point).\n" "Le pog a été marqué comme désinstallé." #: fontypythonmodules/fontybugs.py:51 msgid "This folder has no fonts in it." msgstr "Ce dossier ne contient pas de fichier." #: fontypythonmodules/fontybugs.py:157 #, python-brace-format msgid "" "The \"{path}\" directory cannot be created or found.\n" "Fonty cannot run until it exists. Please create it, and start me again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fontypython\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:173 #, python-brace-format msgid "" "WARNING:\n" "The \"{path}\" directory cannot be created or found.\n" "Fonts cannot be installed until it exists. Please create it, and start me " "again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fonts\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:183 msgid "Missing fonts directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:191 #, python-brace-format msgid "" "WARNING:\n" "The fontconfig \"{path}\" directory cannot be created or found.\n" msgstr "" #: fontypythonmodules/fontybugs.py:196 msgid "Missing fontconfig \"{}\" directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:211 #, python-brace-format msgid "" "Failure during upgrade:\n" "{msg}\n" "\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fpsys.py:275 #, python-brace-format msgid "" "Could not move \"{what}\" from \"{src}\" to \"{dest}\"\n" "Please resolve the problem and start me again." msgstr "" #: fontypythonmodules/fpsys.py:294 #, python-brace-format msgid "" "Could not remove the old \"{oldfontydir}\" directory.\n" "Please remove it and start me again." msgstr "" #: fontypythonmodules/fpsys.py:536 msgid "Checking fonts, this could take some time." msgstr "" #: fontypythonmodules/fpsys.py:537 #, python-format msgid "Starting in %s:" msgstr "" #: fontypythonmodules/fpsys.py:544 #, python-format msgid "Looking in %s..." msgstr "" #: fontypythonmodules/fpsys.py:557 msgid " Bad font: {}" msgstr "" #: fontypythonmodules/fpsys.py:581 msgid "" "Bad fonts were found. They have been noted. I will ignore them in future." msgstr "" #: fontypythonmodules/fpsys.py:583 msgid "I could not find any bad fonts." msgstr "" #: fontypythonmodules/fpsys.py:585 msgid "The process is complete." msgstr "" #: fontypythonmodules/fpsys.py:646 msgid "Jump the lazy dog fox" msgstr "Portez ce vieux whisky au juge blond qui boit" #: fontypythonmodules/fpsys.py:695 msgid "No config file found, creating it with defaults." msgstr "" "Aucun fichier de configuration détecté, création avec les paramètres par " "défaut." #: fontypythonmodules/fpsys.py:727 msgid "" "The fontypython config file is damaged.\n" "Please remove it and start again" msgstr "" "Le fichier ~/.fontypython/fp.conf semble être endommagé.\n" "Veuillez le supprimer puis relancer Fonty Python." #: fontypythonmodules/fpsys.py:769 msgid "Could not write to the config file." msgstr "" #: fontypythonmodules/fpsys.py:914 #, python-format msgid "This font is in %s" msgstr "" #: fontypythonmodules/fpsys.py:971 msgid "Trying to hush..." msgstr "" #: fontypythonmodules/fpsys.py:992 msgid "The Pog \"{}\", cannot be found." msgstr "" #: fontypythonmodules/fpsys.py:1012 msgid "Done. A hush settles over your fonts. Go: work in silence." msgstr "" #: fontypythonmodules/fpsys.py:1024 msgid "The hush isn't there. Nothing to do." msgstr "" #: fontypythonmodules/fpsys.py:1028 msgid "Trying to unhush..." msgstr "" #: fontypythonmodules/fpsys.py:1034 msgid "The noise has returned; the hush is gone." msgstr "" #: fontypythonmodules/gui_Fitmap.py:504 msgid "" "Font causes a memory error, it can't be drawn.\n" "Original error was:\n" "{}" msgstr "" #: fontypythonmodules/gui_FontSources.py:57 msgid "Sources: Folders or Pogs" msgstr "" #: fontypythonmodules/gui_FontSources.py:161 #, fuzzy msgid "Source Folders" msgstr "Dossiers" #: fontypythonmodules/gui_FontSources.py:162 #, fuzzy msgid "Source Pogs" msgstr "Nettoyer le Pog" #: fontypythonmodules/gui_FontView.py:118 msgid "Recent Filters" msgstr "" #: fontypythonmodules/gui_FontView.py:216 msgid "Filter {} fonts" msgstr "" #: fontypythonmodules/gui_FontView.py:237 msgid "Page:" msgstr "" #: fontypythonmodules/gui_FontView.py:505 #, fuzzy msgid "There's nothing much to do." msgstr "Il n'y a pas autant d'éléments." #: fontypythonmodules/gui_FontView.py:506 msgid "Choose some fonts" msgstr "" #: fontypythonmodules/gui_FontView.py:525 #, fuzzy, python-brace-format msgid "Remove fonts from {VIEW}" msgstr "Supprimer les polices de %s" #: fontypythonmodules/gui_FontView.py:526 #, fuzzy msgid "You can remove fonts from this source Pog." msgstr "Placer les polices dans Pog" #: fontypythonmodules/gui_FontView.py:532 #, fuzzy, python-brace-format msgid "Put fonts into {TARGET}" msgstr "Placer les polices dans %s" #: fontypythonmodules/gui_FontView.py:533 #, fuzzy, python-brace-format msgid "You can append fonts to the active target Pog \"{TARGET}\"." msgstr "Placer les polices dans Pog" #: fontypythonmodules/gui_FontView.py:540 msgid " (and all sub-folders.)" msgstr "" #: fontypythonmodules/gui_FontView.py:544 #, python-brace-format msgid "Viewing source Folder \"{VIEW}\"{{RT}}" msgstr "" #: fontypythonmodules/gui_FontView.py:545 #, python-brace-format msgid "Viewing source Pog \"{VIEW}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:546 msgid "Choose a Source Pog or Folder." msgstr "" #: fontypythonmodules/gui_FontView.py:547 #, fuzzy, python-brace-format msgid "The target Pog \"{TARGET}\" is installed. It can't be changed." msgstr "" "Le pog (%s) est actuellement installé, vous ne pouvez pas l'utiliser comme " "une cible." #: fontypythonmodules/gui_FontView.py:555 msgid "There are no fonts in here." msgstr "Aucun fonts disponible." #: fontypythonmodules/gui_FontView.py:562 #, python-brace-format msgid "Source is empty. The active target Pog is \"{TARGET}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:576 #, fuzzy, python-brace-format msgid "Viewing (installed Pog) \"{VIEW}\"" msgstr "Visualisation du Pog (installé): %s" #: fontypythonmodules/gui_FontView.py:577 #, fuzzy msgid "You can't change an installed Pog." msgstr "Vous ne pouverz pas modifier un Pog installé." #: fontypythonmodules/gui_FontView.py:581 #, fuzzy, python-brace-format msgid "Viewing (editable Pog) \"{VIEW}\"" msgstr "Visualisation (editable) de Pog: %s" #: fontypythonmodules/gui_FontView.py:582 #, fuzzy msgid "There is no active target." msgstr "Il n'y a pas autant d'éléments." #: fontypythonmodules/gui_FontView.py:606 #, fuzzy, python-brace-format msgid "Source and Target \"{VIEW}\" are the same." msgstr "Vos pogs sont les mêmes! Essayez -e" #: fontypythonmodules/gui_FontView.py:607 msgid "Clear the target, or choose another Pog." msgstr "" #: fontypythonmodules/gui_FontView.py:692 msgid "FontView state error: Pattern is \"{}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:783 msgid "Selected fonts have been removed." msgstr "Les polices sélectionnées ont été supprimées." #: fontypythonmodules/gui_FontView.py:786 #, fuzzy msgid "There was an error writing the pog to disk. Nothing has been done." msgstr "" "Il y a eu une erreur pendant l'écriture du pog sur le disque. Rien n'a été " "effectué." #: fontypythonmodules/gui_FontView.py:794 #, python-format msgid "Copying fonts from %(source)s to %(target)s" msgstr "Copie des polices de %(source)s vers %(target)s" #: fontypythonmodules/gui_FontView.py:815 #, python-format msgid "Selected fonts are now in %s." msgstr "Les polices sélectionnées sont maintenant dans %s." #: fontypythonmodules/gui_FontView.py:818 msgid "There was an error writing the pog to disk. Nothing has been done" msgstr "" "Il y a eu une erreur pendant l'écriture du pog sur le disque. Rien n'a été " "effectué." #: fontypythonmodules/gui_PogChooser.py:296 #, python-format msgid "(%s) skipped. It's an invalid pog." msgstr "" #: fontypythonmodules/gui_PogChooser.py:305 #, python-format msgid "(%s) skipped. I can't display this name under your locale." msgstr "" #: fontypythonmodules/gui_PogTargets.py:53 msgid "Target Pogs" msgstr "Pogs Cibles" #: fontypythonmodules/gui_PogTargets.py:68 msgid "Clear selection" msgstr "Ne rien sélectionner" #: fontypythonmodules/gui_PogTargets.py:71 #, fuzzy msgid "Deselects any chosen Pogs." msgstr "Déselectionner tous les Pogs choisis." #: fontypythonmodules/gui_PogTargets.py:83 #: fontypythonmodules/gui_PogTargets.py:141 msgid "New Pog" msgstr "Nouveau Pog" #: fontypythonmodules/gui_PogTargets.py:84 msgid "Creates a new, empty Pog" msgstr "" #: fontypythonmodules/gui_PogTargets.py:86 #, fuzzy msgid "Install Pog(s)" msgstr "Installer le Pog" #: fontypythonmodules/gui_PogTargets.py:87 msgid "" "Installs all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:89 #, fuzzy msgid "Uninstall Pog(s)" msgstr "Désinstaller le Pog" #: fontypythonmodules/gui_PogTargets.py:90 msgid "" "Uninstalls all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:92 #, fuzzy msgid "Delete Pog(s)" msgstr "Supprimer le Pog" #: fontypythonmodules/gui_PogTargets.py:93 msgid "Deletes the selected Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:95 #, fuzzy msgid "Zip Pog(s)" msgstr "Désinstaller le Pog" #: fontypythonmodules/gui_PogTargets.py:96 msgid "Save a zip file of the selected Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:140 #, fuzzy msgid "Enter a name for the new Pog" msgstr "Entrez un nom pour le nouveau Pog" #: fontypythonmodules/gui_PogTargets.py:141 msgid "Fonty Python" msgstr "Fonty Python" #: fontypythonmodules/gui_PogTargets.py:147 msgid "A Pog with no name won't be created, however it was a good try!" msgstr "" #: fontypythonmodules/gui_PogTargets.py:152 #, python-format msgid "%s already exists." msgstr "Pog %s est installé." #: fontypythonmodules/gui_PogTargets.py:187 msgid "" "One or more selected Pogs is installed, fix your selection and try again." msgstr "" #: fontypythonmodules/gui_PogTargets.py:203 #, python-format msgid "Remove %s, are you sure?" msgstr "Êtes-vous certain de vouloir supprimer %s ?" #: fontypythonmodules/gui_PogTargets.py:204 msgid "Are you sure?" msgstr "Êtes-vous certain ?" #: fontypythonmodules/gui_dismissable_panels.py:102 msgid "Dismiss. ESC key does the same." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:235 msgid "Help! Help! I'm being repressed!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:276 msgid "User Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:285 msgid "Fontconfig" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:286 msgid "No path: Fontconfig is not functioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:311 #, fuzzy msgid "About Fonty" msgstr "À Propos de Fonty Python" #: fontypythonmodules/gui_dismissable_panels.py:359 msgid "Hushing is on." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:359 msgid "Un-hush my fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:360 msgid "Hushing is off." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:360 msgid "Hush my fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:361 #, fuzzy msgid "Fonty cannot hush your fonts" msgstr "Fonty Python : redécouvrez vos polices de caractères !" #: fontypythonmodules/gui_dismissable_panels.py:366 msgid "Hush Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:399 msgid "The Hush Pog:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:404 msgid "" "Hushing installs a Pog that you must manage. Make sure it contains a few " "system fonts so that your applications function properly!\n" "Look in /usr/share/fonts for ideas. Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:417 msgid "Current Hush Pog: " msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:423 msgid "Choose your system Pog" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:433 msgid "" "Fontconfig is not properly installed; thus Fonty cannot hush fonts.\n" "Consult your distribution's help, or open a ticket so we can try fix it. " "Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:443 msgid "Progress report:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:515 msgid "None chosen" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:597 msgid "Locate a directory for the zip file(s)" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:645 msgid "Create the zip file" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:672 msgid "" "The zip file(s) will be put into:\n" "{}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:724 msgid "Settings" msgstr "Options" #: fontypythonmodules/gui_dismissable_panels.py:738 msgid "Sample text:" msgstr "Texte affiché:" #: fontypythonmodules/gui_dismissable_panels.py:745 msgid "Point size:" msgstr "Longueur de la page:" #: fontypythonmodules/gui_dismissable_panels.py:750 msgid "Beware large numbers!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:751 msgid "Page length:" msgstr "Longueur de la page:" #: fontypythonmodules/gui_dismissable_panels.py:755 msgid "Tick to disable" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:757 msgid "Disable top-left correction:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:758 msgid "" "Disabling this speeds-up\n" "font drawing but can\n" "cause bad positioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:769 msgid "Available" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:776 msgid "Choose which app to use as a character map viewer." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:783 msgid "" "None found.\n" "You could install: {}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:786 msgid "Character map viewer:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:796 msgid "Max number of columns:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:797 msgid "" "The font viewing area\n" "will divide into columns\n" "which you can control here." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:803 msgid "" "Tick to include all\n" "sub-folders in\n" "the source view." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:806 msgid "Include sub-folders." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:807 msgid "" "Caution: This will crash Fonty if\n" "your Source folder (directory)\n" "is deep." msgstr "" #: fontypythonmodules/segwrapfonty.py:87 msgid "Oh boy..." msgstr "" #: fontypythonmodules/segwrapfonty.py:91 msgid "Fonty Python, um ... crashed." msgstr "" #: fontypythonmodules/segwrapfonty.py:96 msgid "" "There's some problem with the font named below.\n" "You can do one of two things:\n" "1) Manually move this font somewhere else, or\n" "2) Use Fonty's command-line (-c) to mark bad fonts.\n" " See below for help with this.\n" "After you've done these, run me again." msgstr "" #: fontypythonmodules/segwrapfonty.py:102 msgid "The bad font might be:" msgstr "" #: fontypythonmodules/segwrapfonty.py:105 msgid "" "There's no lastFontBeforeSegfault file; I can't really help.\n" "Look at the error (below) for clues." msgstr "" #: fontypythonmodules/segwrapfonty.py:107 msgid "The error was:" msgstr "" #: fontypythonmodules/segwrapfonty.py:118 msgid "The command line to seek and mark bad fonts is:" msgstr "" #: fontypythonmodules/segwrapfonty.py:119 msgid "(Copy the text; open a console; paste and press enter.)" msgstr "" #: fontypythonmodules/segwrapfonty.py:125 msgid "You can get help by opening a ticket on:" msgstr "" #: fontypythonmodules/strings.py:25 #, python-format msgid "Please use a number for argument %s" msgstr "" #: fontypythonmodules/strings.py:31 msgid "Your arguments amuse me :) Please see the help by using -h" msgstr "" #: fontypythonmodules/strings.py:34 #, python-format msgid "Fonty Python version %s" msgstr "" #: fontypythonmodules/strings.py:42 msgid "Fonts supported: TTF, OTF, TTC, WOFF, Type1 (PFB, PFA)." msgstr "" #: fontypythonmodules/strings.py:44 #, python-format msgid "" "The basic format is:\n" "%(c)s [OPTIONS] || [VIEW] [TARGET]\n" "\n" "OPTIONS: Various flags for use on the command-line. See \"-h b\" or \"--help " "b\"\n" "for more details. (Long options can use an \"=\" sign or a space: --" "cat=foo \n" "or --cat foo)\n" "\n" "Or:\n" "\n" "Two arguments which will determine what you see in the graphical user " "interface:\n" "VIEW : A place where fonts are. A Pog or a folder where fonts are " "located.\n" "TARGET : A Pog. If this Pog does not exist, it will be created.\n" "\n" "Neither argument is required. When there's only one it's assumed to be a " "VIEW. \n" "When there are two, it's VIEW then TARGET.\n" "\n" "NB: Try not to use spaces in Pog names. If you must, then \"quote the name\"." msgstr "" #: fontypythonmodules/strings.py:66 #, fuzzy msgid "" "Manage your fonts on GNU/Linux\n" "==============================\n" "Many designers have collections of font files on their drives. \n" "Fonty Python will help you gather and structure them into collections \n" "called \"Pogs\" -- a place to keep tyPOGraphy. Well, why not?\n" "\n" "Fonty lets you you select fonts visually and place them into Pogs which " "you \n" "can then install or remove as you require. (Your font files never move \n" "from where they are. Only links are used.)\n" "\n" "Example: You create a \"logos\" Pog where you place logotype fonts.\n" "When you want to use them, simply install the \"logos\" Pog and start your \n" "design app! When you're done, uninstall the \"logos\" Pog; the fonts will \n" "go away.\n" "\n" "Fonty can also \"hush\" unwanted fonts. This hides system fonts, leaving\n" "only those Pogs you want in your apps. The Inkscape font chooser, for \n" "example, is more usable after a hush.\n" "(This is temporary; an \"unhush\" will switch the system fonts on again.)\n" "\n" "Fonty is great for just looking at fonts, wherever they are, without " "having \n" "to install them." msgstr "" "FIXME%(c)s [OPTIONS] [EMPLACEMENT] [CIBLE]\n" "\n" "EMPLACEMENT : L'endroit où sont les polices de caractères. Un pog ou un " "dossier.\n" "CIBLE : Un \"pog\". L'endroit où enregistrer ces polices (seulement " "des références aux fichiers)\n" "\n" "NB : Essayez de ne pas utiliser d'espace dans le nom des pogs. Si vous devez " "le faire, mettez le nom entre guillemets.\n" "\n" "Veuillez utiliser l'option -e ou --example pour avoir plus d'informations.\n" "\n" "%(version)s\n" "\n" "L'idée de base :\n" "===============\n" "Beaucoup de graphistes ont leur collection de fichiers TTF dans\n" "un gros répertoire. Fonty Python va vous permettre de rassembler\n" "vos polices de caractères et de les ranger dans des collections\n" "appelées \"pogs\", qui vient de tyPOGraphie. Pourquoi pas ?\n" "\n" "Vos fichiers ne seront jamais déplacés\n" "(pas d'inquiétude). Tout ce qui se passe est le placement de\n" "références à vos fichiers (que vous sélectionnerez visuellement)\n" "dans un pog, que vous pourrez ensuite installer ou désinstaller\n" "en fonction de vos besoins.\n" "\n" "Par exemple, vous pouvez avoir un pog appelé \"logos\" dans lequel\n" "vous placez tous les fichiers TTF que vous possédez de logos.\n" "Après ça, quand vous aurez besoin de travailler avec ces logos, vous\n" "installez simplement le pog \"logos\" et commencez à travailler !\n" "\n" "Fonty Python est aussi approprié pour visionner vos fichiers TTF\n" "où qu'ils soient sur votre ordinateur.\n" "\n" "%(copy)s\n" "%(warranty)s\n" "%(contact)s\n" #: fontypythonmodules/strings.py:90 #, python-format msgid "" "%(yadda)s\n" "Please use -e to see more info.\n" "\n" "%(fonts_supported)s\n" "\n" "%(basic_idea)s" msgstr "" #: fontypythonmodules/strings.py:97 msgid "" "Options:\n" "\n" " -v, --version Show program's version number and exit.\n" " -h b|e|hush, --help b|e|hush\n" " Show a help message and exit.\n" " \"b\" is for basic help.\n" " \"e\" to show some %$@#$ examples!\n" " \"hush\" is for more detail on hushing fonts.\n" " -d, --dir Show the \"fontypython\" path. Add this to your backup " "process!\n" " -i Pog, --install Pog\n" " Install the fonts in this Pog.\n" " -u Pog, --uninstall Pog\n" " Uninstall the fonts in this Pog.\n" " -l, --list\n" " List the names of all your Pogs.\n" " -f, --lsfonts\n" " Lists the contents of your user fonts directory. Here, " "you'll\n" " find the links that Fonty is managing for you.\n" " -s num, --size num\n" " Set a new default point size (you'll see it in the gui).\n" " -n num, --number num\n" " Set a new default for how many fonts to view at one go in " "the gui.\n" " (Don't overdo this.)\n" " -p Pog, --purge Pog\n" " Clean the Pog of fonts that are missing.\n" " -c folder, --check folder\n" " Check for bad fonts that crash Fonty. After using this tool " "you \n" " should be able to use Fonty again.\n" " * NOTE: The fonts that crash Fonty are probably still " "perfectly\n" " useable in other apps. \n" " -a Folder Pog, --all Folder Pog\n" " Puts all fonts in Folder into Pog.\n" " -A Folder Pog, --all-recurse Folder Pog\n" " Puts all fonts in Folder and *all* sub-folders into Pog.\n" " -z Pog, --zip Pog\n" " All the fonts inside Pog will be zipped and the zipfile will " "be \n" " named after the Pog. The file will be placed in the current\n" " directory.\n" " --cat Pog\n" " Cat the Pog. This will list all the fonts within.\n" " --hush HushPog\n" " Hush *all* the fonts except the Pogs you install.\n" "\n" " Uses \"HushPog\", which you create that must contain a few " "system \n" " fonts; in order to supply a basic set to your desktop apps.\n" "\n" " I suggest these from \"/usr/share/fonts\":\n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" " --unhush\n" " Restores all the system fonts after a hush. Leaves your " "special\n" " HushPog installed. It's up to you to manage it.\n" " " msgstr "" #: fontypythonmodules/strings.py:152 #, fuzzy, python-format msgid "" "%(yadda)s\n" "\n" "Examples: All using short options, see -h\n" "=========\n" "%(c)s /path/to/fonts/ttfs/a\n" " This will start off showing the fonts in that path.\n" "\n" "%(c)s /path/to/fonts/ttfs/b Trouser\n" " This will let you view and choose fonts from the path and it will store " "them \n" " in a Pog named Trouser. The Pog will be created if it's not already " "there.\n" "\n" "%(c)s Lumberjack\n" " This will let you see the fonts in the Pog named Lumberjack. You can " "also \n" " uninstall individual fonts by selecting them. A cross will appear " "indicating \n" " the fonts that will be uninstalled.\n" "\n" "%(c)s Camelot Spamalot\n" " This will let you see and choose fonts in Camelot and it will store them \n" " in \"Spamalot\". It lets you copy fonts between Pogs.\n" "\n" "%(c)s -i Cheese\n" " Will install the fonts in Cheese so you can use them in other apps.\n" "\n" "%(c)s -u Trouser\n" " Will uninstall the fonts listed in Trouser.\n" "\n" "%(c)s -s 128\n" " Will set the point size in the gui to 128 - Crazy man!\n" "\n" "%(c)s -n 25\n" " Will show 25 fonts at a time, in the gui. Beware large numbers!\n" "\n" "%(c)s -s 64 -v 10 Pimple\n" " Will set the point size to 64, paging to 10,open the gui and display the " "fonts\n" " in Pimple.\n" "\n" "%(c)s -p Glutton\n" " Purging a font. If there are any fonts in Glutton that are not really on " "your \n" " drive/media anymore (perhaps you deleted them or the cat did) this will " "go \n" " through the Pog and cull them.\n" "\n" "%(c)s -c /some/path/to/fonts\n" " If Fonty keeps crashing on /some/path/to/fonts then you should run a check " "on\n" " that folder. This will mark the dangerous fonts and let you view that " "folder \n" " in the future.\n" "\n" "%(c)s -a /some/path HolyHandGrenade\n" " This will put all the fonts in that path into the Pog called " "HolyHandGrenade.\n" "\n" "%(c)s -A /some/path Tutto\n" " This will do the same as -a: starting in some path, but it will then " "walk \n" " down through *all* sub-folders too. The fonts will be placed in Tutto.\n" "\n" "%(c)s --hush mysysfonts\n" " Will hush (silence) all the fonts in your system except the ones in \n" " \"mysysfonts\" and any other Pogs you have installed. Other apps will \n" " now have fewer fonts to choose from, making life much easier for you.\n" " (Use --unhush later to restore all of them.)\n" "\n" msgstr "" "FIXMELe format de base est :\n" "%(c)s [EMPLACEMENT] [CIBLE]\n" "EMPLACEMENT : L'endroit où sont les polices de caractères. Un pog ou un " "dossier.\n" "CIBLE : Un \"pog\". L'endroit où enregistrer ces polices (seulement " "des références aux fichiers)\n" "\n" "Astuces :\n" "=====\n" "* N'utilisez pas d'espace dans le nom des pogs. Si\n" " vous en avez impérativement besoin, utilisez\n" " alors des guillemets autour du nom, par exemple\n" " \"Les pogs de Milo\"\n" "* Si votre application de graphisme, par exemple Le Gimp,\n" " ne met pas à jour la liste des polices, relancez là.\n" " Parfois, votre système peut avoir besoin d'un peu de\n" " temps pour refléter les changements.\n" "\n" "Exemples : - la plupart bénéficie d'options courtes, regardez -h\n" "=========\n" "%(c)s /chemin/vers/les/fichiers/ttf/a\n" " Vous permet de voir les polices de ce dossier.\n" " \n" "%(c)s /chemin/vers/les/fichiers/ttf/b Logos\n" " Vous permet d'afficher et de choisir les polices\n" " qui se trouvent dans le dossier, pour les référencer\n" " dans un pog nommé \"Logos\".\n" " Il sera créé s'il n'existe pas.\n" "\n" "%(c)s Dessin\n" " Vous permet de voir les polices du pog nommé\n" " \"Dessin\". Vous pouvez aussi désinstaller\n" " certaines polices une à une en les sélectionnant.\n" " Une croix vous indiquera celles qui seront enlevées.\n" "\n" "%(c)s Kaamelott Spaamelott\n" " Vous permet de voir et de choisir les polices dans\n" " \"Kaamelott\" pour les référencer dans \"Spaamelott\". Ceci vous permet " "de copier les polices entre deux pogs.\n" "\n" "%(c)s -i SaintGraal\n" " Installera les polices du pog SaintGraal pour que vous\n" " puissiez les utiliser dans d'autres applications.\n" "\n" "%(c)s -u Logos\n" " Désinstallera les polices du pog Logos, pour que\n" " vous ne puissiez plus les utiliser.\n" "\n" "%(c)s -t \"Portez ce vieux whisky au juge blond qui fume\"\n" " Change le texte d'exemple (en utilisant un beau pangramme).\n" " Relancez Fonty Python pour voir le changement.\n" " \n" "%(c)s -s 128 \n" " Change la taille du texte d'exemple à 128 (vous êtes fou !).\n" "\n" "%(c)s -n 25\n" " Affiche 25 polices sur une page. Attention aux chiffres élevés.\n" " \n" "%(c)s -s 64 -n 10 Lapin\n" " Change la taille du texte d'exemple à 64, affiche 10 polices\n" " par page et charge le pog Lapin.\n" "\n" "%(c)s -p Chevalier\n" " S'il y a des polices dans Chevalier qui ne sont plus\n" " vraiment sur votre disque, alors elles seront supprimées\n" " du pog.\n" " \n" "Votre dossier Fonty Python est :\n" "%(folder)s\n" "\n" "%(contact)s\n" "%(copy)s" #: fontypythonmodules/strings.py:213 msgid "" "Your fontypython folder is:\n" "{}" msgstr "" #: fontypythonmodules/strings.py:217 msgid "Fonty Python - view and manage fonts on Gnu/Linux" msgstr "" # a comment #: fontypythonmodules/strings.py:222 #, fuzzy, python-format msgid "" "I cannot find \"python-wxversion\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxversion\n" "I then install it like this:\n" "sudo aptitude install python-wxversion\n" "\n" "If you get long error messages, you will need to\n" "install python-wxgtk*, where the star means the\n" "version number and it should be at least %(wxv)s\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" "(String needs new translation)\n" "Impossible de trouver python-wxversion, cela\n" "peut signifier qu'il vous manque des dépendances.\n" "Fonty Python va tout de même essayer de démarrer...\n" "\n" "Sur Ubuntu, vous devriez pouvoir taper :\n" "sudo apt-get install python-wxgtkX.Y\n" "\n" "Si vous obtenez de longs messages d'erreur, vous aurez\n" "\"besoin d'installer python-wxgtk2.6 ou supérieur.\n" "Voyez sur http://wxpython.org/download.php\n" #: fontypythonmodules/strings.py:243 #, fuzzy, python-format msgid "" "I cannot find \"python-wxgtkX.Y\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxgtk%(wxv)s\n" "I then install it like this:\n" "sudo aptitude install python-wxgtk%(wxv)s\n" "\n" "Make sure it's at least version %(wxv)s\n" "**NB** It should not be any version greater\n" "than 3.0\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" "(String needs new translation)Fonty Python dépend de \"wxPython\".\n" "\"Veuillez installer \"python-wxgtkX.Y\" (ou supérieur), voici les " "détails :\n" "Sur Ubuntu, vous devriez pouvoir taper :\n" "sudo apt-get install python-wxgtk2.6\n" "\n" "Voyez sur http://wxpython.org/download.php\n" #: fontypythonmodules/strings.py:265 #, fuzzy msgid "" "I cannot find \"python-pil\"\n" "Please install this package.\n" "\n" "NOTE\n" "===\n" "PIL has been forked by Pillow.\n" "The old package was \"python-imaging\",\n" "the new one is \"python-pil\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-pil\n" "This returns many results, one of which is:\n" "python-pil\n" "I then install it like this:\n" "sudo aptitude install python-pil\n" "\n" "Make sure it's at least version 1.1.6-1\n" "\n" "You can also get the latest version from here:\n" "http://www.pythonware.com/products/pil/index.htm\n" msgstr "" "(String needs new translation)Fonty Python dépend de \"PIL\" - Python " "Imaging Library.\n" "Veuillez installer \"python-imaging\" en utilisant les outils\n" "de votre distribution.\n" "Voyez sur http://www.pythonware.com/products/pil/index.htm\n" #: fontypythonmodules/strings.py:290 msgid "" "I cannot find \"Python-gi\"\n" "This package is not required; although if you\n" "have it, modern Linux desktop standards can be\n" "implemented by Fonty.\n" "\n" "TIP\n" "===\n" "Look for \"python-gi\" in your package manager.\n" msgstr "" #: fontypythonmodules/strings.py:318 msgid "" "Hold SHIFT or CTRL as you select Pogs, if you wish to select many at once." msgstr "" #: fontypythonmodules/strings.py:322 msgid "Can't hush because:" msgstr "" #: fontypythonmodules/strings.py:323 msgid "Can't unhush because:" msgstr "" #: fontypythonmodules/strings.py:324 msgid "See --help hush" msgstr "" #: fontypythonmodules/strings.py:325 #, python-brace-format msgid "" "\n" "The idea\n" "========\n" "Often there are too many fonts reported by your system. In your apps, like " "Inkscape,\n" "they clutter the font chooser. This is a way to \"hush\" that, to quieten " "the noise.\n" "\n" "Fonty will install a select Pog of system fonts (which you must pick) and " "then will\n" "reject *all* the system's fonts, leaving only the Pogs which you install.\n" "\n" "This does no damage and you can \"unhush\" at any time to reverse it.\n" "\n" "Hushing\n" "=======\n" "1. Relies on fontconfig, which should be installed on most modern Linux " "desktops.\n" " You can verify if it's there by trying this command:\n" " fc-list\n" "\n" " If that shows no error, you're good.\n" "\n" "2. Fontconfig's user directory:\n" " The path is {{fcpaf}}\n" " Make sure it exists and try fonty again.\n" "\n" "3. System fonts: Put some fonts in a Pog that you must create and choose.\n" " I suggest those in /usr/share/fonts, like: \n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" "\n" "The way it works is that fonty writes an XML file which rejects all fonts " "that \n" "are on the path: \"/usr/share/fonts\"\n" "\n" "This may not work on your particular Linux distribution. Please open a " "ticket\n" "on our site if you have any trouble: {ticket_url}\n" "\n" "To hush, using your special Pog from the command line do this:\n" "{fp} --hush yourpoghere\n" "\n" "To hush from the gui, ...\n" "\n" "Unhushing\n" "=========\n" "To release the hush, use --unhush from the command line or the gui.\n" "\n" "The Pog(s) you installed when you hushed will be left installed. Remove\n" "it/them if you must." msgstr "" #: fontypythonmodules/wxgui.py:124 #, fuzzy, python-format msgid "Welcome to Fonty Python, vers %s" msgstr "Bienvenue dans Fonty Python %s" #: fontypythonmodules/wxgui.py:181 msgid "&Settings\tCtrl+S" msgstr "&Options\tCtrl+O" #: fontypythonmodules/wxgui.py:181 msgid "Change settings" msgstr "" #: fontypythonmodules/wxgui.py:187 msgid "&Purge Pog.See TogglePurgeMenuItem for actual string." msgstr "" #: fontypythonmodules/wxgui.py:188 msgid "Remove all ghost fonts from the selected Pog." msgstr "" #: fontypythonmodules/wxgui.py:194 msgid "&Hush fonts\tCtrl+H" msgstr "" #: fontypythonmodules/wxgui.py:195 msgid "Silence all the noisy system fonts and focus only on those you want," msgstr "" #: fontypythonmodules/wxgui.py:201 msgid "&Exit" msgstr "" #: fontypythonmodules/wxgui.py:202 msgid "Close the app" msgstr "Quitter Fonty Python" #: fontypythonmodules/wxgui.py:205 msgid "&Tools" msgstr "" #: fontypythonmodules/wxgui.py:212 msgid "&Select ALL the source fonts" msgstr "" #: fontypythonmodules/wxgui.py:213 msgid "Select ABSOLUTELY ALL the fonts in the chosen source." msgstr "" #: fontypythonmodules/wxgui.py:216 #, fuzzy msgid "&Clear ENTIRE selection" msgstr "Ne rien sélectionner" #: fontypythonmodules/wxgui.py:217 #, fuzzy msgid "Clear the selection completely." msgstr "Ne rien sélectionner" #: fontypythonmodules/wxgui.py:218 #, fuzzy msgid "&Selection" msgstr "Ne rien sélectionner" #: fontypythonmodules/wxgui.py:223 msgid "H&elp\tF1" msgstr "&Aide\tF1" #: fontypythonmodules/wxgui.py:224 msgid "&About" msgstr "À &Propos" #: fontypythonmodules/wxgui.py:225 msgid "&Help" msgstr "&Aide" #: fontypythonmodules/wxgui.py:546 msgid "Warning" msgstr "Attention" #: fontypythonmodules/wxgui.py:551 msgid "Error" msgstr "Erreur" #: fontypythonmodules/wxgui.py:674 msgid "I could not create the zip for {}" msgstr "" #: fontypythonmodules/wxgui.py:688 msgid "Some fonts were skipped, try purging the Pog(s) involved." msgstr "" #: fontypythonmodules/wxgui.py:689 msgid "Something went wrong." msgstr "" #: fontypythonmodules/wxgui.py:691 fontypythonmodules/wxgui.py:692 #, fuzzy msgid "Zip file(s) have been created." msgstr "Les polices sélectionnées ont été supprimées." #: fontypythonmodules/wxgui.py:752 #, python-format msgid "&Purge \"%s\"\tCtrl+P" msgstr "" #: fontypythonmodules/wxgui.py:754 #, fuzzy msgid "&Purge Pog\tCtrl+P" msgstr "Nettoyer le Pog" #: fontypythonmodules/wxgui.py:761 #, python-format msgid "" "Do you want to purge %s?\n" "\n" "Purging means all the fonts in the pog\n" "that are not pointing to actual files\n" "will be removed from this pog." msgstr "" "Voulez-vous nettoyer %s ?\n" "\n" "Nettoyer signifie que toutes les polices du Pog qui\n" "ne pointent pas vers des fichiers existants en\n" "seront supprimées." #: fontypythonmodules/wxgui.py:761 msgid "Purge font?" msgstr "Supprimer la police ?" #: fontypythonmodules/wxgui.py:770 #, python-format msgid "%s has not been purged." msgstr "%s n'a pas été nettoyé." #: fontypythonmodules/wxgui.py:774 #, python-format msgid "%s has been purged." msgstr "%s n'a pas été nettoyé." #: fontypythonmodules/wxgui.py:794 msgid "" "I am sorry, but Unicode is not supported by this installation of wxPython. " "Fonty Python relies on Unicode and will simply not work without it.\n" "\n" "Please fetch and install the Unicode version of python-wxgtk." msgstr "" #: fontypythonmodules/wxgui.py:798 msgid "SORRY: UNICODE MUST BE SUPPORTED" msgstr "" #: fontypythonmodules/wxgui.py:811 msgid "FATAL ERROR" msgstr "" #: fontypythonmodules/wxgui.py:909 msgid "Fonty Python: bring out your fonts!" msgstr "Fonty Python : redécouvrez vos polices de caractères !" #~ msgid "About" #~ msgstr "À Propos" #~ msgid "Licence" #~ msgstr "License" #, fuzzy #~ msgid "Quick settings" #~ msgstr "Options" #~ msgid "(Check your filter!)" #~ msgstr "ou videz le filtre ci-dessous." #~ msgid "Pogs" #~ msgstr "Pogs" #~ msgid "Filter:" #~ msgstr "Filtre:" #, fuzzy #~ msgid "Your active Target is %s" #~ msgstr "Source en cours : %s" #~ msgid "Please choose a Source." #~ msgstr "Choisissez un dossier ou un pog." #~ msgid "Please choose a Pog or a Font folder on the left." #~ msgstr "Veuillez choisir un Pog ou un dossier sur la gauche." #, fuzzy #~ msgid "Viewing Folder %s" #~ msgstr "Visualisation de Dossier:%s" #~ msgid "Viewing a folder." #~ msgstr "Visualisation de dossier." #, fuzzy #~ msgid "Append from %(source)s to %(target)s" #~ msgstr "Placer en %(target)s les polices de %(source)s" #, fuzzy #~ msgid "Viewing %(source)s, but Pog %(target)s is installed." #~ msgstr "Visualisation Pog:%(source)s, but Pog:%(target)s is installed." #~ msgid "These two are the same Pog." #~ msgstr "Vos pogs sont les mêmes." #, fuzzy #~ msgid "Append from %(source)s into %(target)s" #~ msgstr "Placer en %(target)s les polices de %(source)s" #~ msgid "Install Pog" #~ msgstr "Installer le Pog" #~ msgid "" #~ "\n" #~ "Couldn't make the .fonts folder in %s\n" #~ "Please check your write permissions and try again." #~ msgstr "" #~ "\n" #~ "Impossible de créer le dossier .fonts dans %s\n" #~ "Please check your write permissions and try again." #~ msgid "" #~ "\n" #~ "Couldn't make the folder in %s\n" #~ "Please check your write permissions and try again." #~ msgstr "" #~ "\n" #~ "Impossible de créer le dossier dans %s\n" #~ "Veuillez vérifier les permissions d'écriture et réessayer." #, fuzzy #~ msgid "" #~ "%(c)s [OPTIONS] [VIEW] [TARGET]\n" #~ "VIEW : A place where fonts are. (A Pog or a Folder.)\n" #~ "TARGET : A \"Pog\". A place to keep those fonts.\n" #~ "\n" #~ "(\"%(c)s\" on it's own will start the GUI.)\n" #~ "\n" #~ "NB: Try not to use spaces in Pog names. If you must, \n" #~ "then \"quote the name.\"\n" #~ "\n" #~ "Please use -e to see more info.\n" #~ "\n" #~ "NEWS : We now support TTF, OTF, Type1 (PFB, PFA) \n" #~ "and TTC fonts.\n" #~ "\n" #~ "%(version)s\n" #~ "\n" #~ "The basic idea:\n" #~ "===============\n" #~ "Many designers have collections of font files in big\n" #~ "directory structures or on other media. Fonty Python\n" #~ "will let you gather your fonts and structure them\n" #~ "into collections -- or what I call \"Pogs\" -- a place\n" #~ "to keep tyPOGraphy. Well, why not?\n" #~ "\n" #~ "Your fonts never move from where they are\n" #~ "(so don't worry). All that happens is that you select \n" #~ "fonts visually and place their names into a Pog,\n" #~ "then you install or uninstall Pogs as you need them.\n" #~ "No copies of your fonts are made, only links to the\n" #~ "original files are used to install the fonts.\n" #~ "\n" #~ "For example, you might have a Pog called 'logos'\n" #~ "into which you place all the fonts you have of\n" #~ "company logos. After that, when you need to work\n" #~ "with those logos, you simply install the 'logos' Pog\n" #~ "and start your design app!\n" #~ "\n" #~ "FP is also great for just looking at fonts wherever\n" #~ "they are on your computer, without having to install\n" #~ "them system-wide.\n" #~ "\n" #~ "Manage your fonts on Gnu/Linux!\n" #~ "===============================\n" #~ "%(copy)s\n" #~ "\n" #~ "%(warranty)s\n" #~ "\n" #~ "%(contact)s\n" #~ msgstr "" #~ "FIXME%(c)s [OPTIONS] [EMPLACEMENT] [CIBLE]\n" #~ "\n" #~ "EMPLACEMENT : L'endroit où sont les polices de caractères. Un pog ou un " #~ "dossier.\n" #~ "CIBLE : Un \"pog\". L'endroit où enregistrer ces polices (seulement " #~ "des références aux fichiers)\n" #~ "\n" #~ "NB : Essayez de ne pas utiliser d'espace dans le nom des pogs. Si vous " #~ "devez le faire, mettez le nom entre guillemets.\n" #~ "\n" #~ "Veuillez utiliser l'option -e ou --example pour avoir plus " #~ "d'informations.\n" #~ "\n" #~ "%(version)s\n" #~ "\n" #~ "L'idée de base :\n" #~ "===============\n" #~ "Beaucoup de graphistes ont leur collection de fichiers TTF dans\n" #~ "un gros répertoire. Fonty Python va vous permettre de rassembler\n" #~ "vos polices de caractères et de les ranger dans des collections\n" #~ "appelées \"pogs\", qui vient de tyPOGraphie. Pourquoi pas ?\n" #~ "\n" #~ "Vos fichiers ne seront jamais déplacés\n" #~ "(pas d'inquiétude). Tout ce qui se passe est le placement de\n" #~ "références à vos fichiers (que vous sélectionnerez visuellement)\n" #~ "dans un pog, que vous pourrez ensuite installer ou désinstaller\n" #~ "en fonction de vos besoins.\n" #~ "\n" #~ "Par exemple, vous pouvez avoir un pog appelé \"logos\" dans lequel\n" #~ "vous placez tous les fichiers TTF que vous possédez de logos.\n" #~ "Après ça, quand vous aurez besoin de travailler avec ces logos, vous\n" #~ "installez simplement le pog \"logos\" et commencez à travailler !\n" #~ "\n" #~ "Fonty Python est aussi approprié pour visionner vos fichiers TTF\n" #~ "où qu'ils soient sur votre ordinateur.\n" #~ "\n" #~ "%(copy)s\n" #~ "%(warranty)s\n" #~ "%(contact)s\n" #~ msgid "" #~ "Your text has been set to \"%s\"\n" #~ "Tip: Did you use quotes to surround your text?\n" #~ "\n" #~ "Please start FontyPython again to see the result." #~ msgstr "" #~ "Votre texte a été assigné à \"%s\"\n" #~ "Idée : Utilisez-vous les guillemets pour encadrer votre texte ?\n" #~ "\n" #~ "Relancez Fonty Python pour voir le résultat." #, fuzzy #~ msgid "Append from Pog %(source)s into Pog %(target)s" #~ msgstr "Placer les polices dans %(target)s from %(source)s" #~ msgid "&File" #~ msgstr "&Fichier" #, fuzzy #~ msgid "License" #~ msgstr "License" #, fuzzy #~ msgid "Sample text" #~ msgstr "Texte affiché:" #, fuzzy #~ msgid "Cove" #~ msgstr "&Quitter" #, fuzzy #~ msgid "Modern" #~ msgstr "Dossiers" #~ msgid "Error creating a wximage of %s" #~ msgstr "Erreur lors de la création d'une image Wx de %s" #~ msgid "%s is to be deleted" #~ msgstr "%s va être supprimé." #~ msgid "%s has been installed." #~ msgstr "Le Pog %s est pas installé." #~ msgid "%s has been uninstalled." #~ msgstr "Le Pog %s n'est pas installé." #~ msgid "" #~ "Options:\n" #~ " -v Show program's version number and exit.\n" #~ " -h Show this help message and exit.\n" #~ " -e Show some %$@#$ examples!\n" #~ " -i pog Install the fonts in this pog to your \n" #~ " fonts folder.\n" #~ " -u pog Uninstall the fonts in this pog.\n" #~ " -l List the names of all the pogs.\n" #~ " -s num Set a new default point size.\n" #~ " -v num Set a new default for how many fonts \n" #~ " to view at one go. Don't overdo this.\n" #~ " -t \"text\" Set a new default sample text. \n" #~ " \"This is an ex-parrot!\", say. \n" #~ " Be sure to use the quotes.\n" #~ " -p pog Purge the pog of ttf files that are no\n" #~ " longer really there." #~ msgstr "" #~ "Options:\n" #~ " -v Show program's version number and exit.\n" #~ " -h Show this help message and exit.\n" #~ " -e Montre des %$@#$ d'exemples !\n" #~ " -i pog Installe les polices de ce pog dans\n" #~ " votre répertoire de polices.\n" #~ " -u pog Désinstalle les polices de ce pog.\n" #~ " -l Liste les noms de tous les pogs.\n" #~ " -s num Modifie la taille par défaut.\n" #~ " -n num Change le nombre de polices à afficher\n" #~ " sur une page. 10 est correct.\n" #~ " -t \"text\" Assigne un nouveau texte d'exemple.\n" #~ " \"Portez ce vieux whisky au juge blond\n" #~ " qui fume\" par exemple. Faîtes\n" #~ " attention de bien utiliser les\n" #~ " guillemets.\n" #~ " -p pog Nettoie le pog des polices qui ne sont\n" #~ " plus présentes." #~ msgid "(%s) skipped" #~ msgstr "(%s) passé" #~ msgid "" #~ "I'm sorry, but something is wrong.\n" #~ "There is no __file__ variable. Please panic." #~ msgstr "" #~ "Désolé, mais quelque chose ne va pas.\n" #~ "There is no __file__ variable. Please panic." #~ msgid "An appropriate GUI could not be found." #~ msgstr "" #~ "Ni l'interface wxgui n'a pu être trouvée. Veuillez consulter l'aide." #~ msgid "Test me %s" #~ msgstr "This is the French tranlslation %s" fontypython-0.5/fontypythonmodules/pofiles/README0000664000175000017500000000454413211475353022225 0ustar donndonn00000000000000Fonty Python Copyright (C) 2006, 2007, 2008 Donn.C.Ingle donn.ingle@gmail.com Fonty Python comes with ABSOLUTELY NO WARRANTY; for details see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; see the COPYING file for details. TRANSLATION README ================== Very rough guide. 1. Assume that the source is more recent than any po/pot file. 2. Use xgettext to make a fresh original: (go into the app root folder, two up from here.) xgettext -o fp_all.pot -L Python fp -L Python fontypython fontypythonmodules/*.py 3. Copy fp_all.pot into fontypythonmodules/pofiles (you can erase the old one.) 4. Merge it with the other po files, one by one. For example, if you are handling French then merge fp_all.pot with fr_all.merged.po and output the new file as fp_all.merged.pot: msgmerge fr_all.merged.po fp_all.pot -o fr_all.merged.pot 5. Make sure it worked (open it and check) and then delete *_all.merged.po (the old files) While you are looking, fix the file header (compare to old file), make sure the charset variable is correct. Example: "Content-Type: text/plain; charset=UTF-8\n" 6. Rename your new files to .po (Why this step is needed totally defeats me.) 7. Open (I like poedit) and edit the file. 8. Generate a .mo file - from poedit or: msgfmt somepofile.po -o somemofile.mo 9. Move the .mo file into ../locales/fr/LC_MESSAGES/all.mo (erasing the old .mo file) 10. Send me your po and mo files ! Using the makefile ================== May 2009 I wrote a makefile to help with translation. It lives in the root of the app. 1. make : Will build the fp_all.pot file. This is the first step after editing the app and adding/changing strings. It takes the app's strings (a POT file) and merges them with the translations (that are in the pofiles dir) with PO extensions. This produces NEW POT files. Old PO files are deleted. make renamepot should be run at this point. 2. make renamepot : Will make the .po files in fontypythonmodules/pofiles. Go edit them. When I receive new translations (PO files) they simply overwrite the current PO files. 3. make mos : Will make the .mo files and put them into the fontypythonmodules/locale/XX/LC_MESSAGES/all.mo If you make a .mo with poedit (or some other app) then that's fine too. Don't run make mos. To test: ======== LANG=langcode_LANGCODE.utf8 ./fontypython fontypython-0.5/fontypythonmodules/pofiles/de_all.merged.po0000664000175000017500000017443213212036004024356 0ustar donndonn00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-06 20:46+0200\n" "PO-Revision-Date: 2009-09-28 10:11+0200\n" "Last-Translator: Donn \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: fontypythonmodules/cli2.py:70 msgid "" "I can't decode your argument(s). Please check your LANG variable. Also, " "don't paste text, type it in." msgstr "" "Ich kann die Argumente nicht dekodieren. Bitte überprüfen Sie die " "Umgebungsvariable LANG. Kopieren Sie nicht den Text, sondern geben ihn " "direkt ein." #: fontypythonmodules/cli2.py:86 msgid "" "For more help use: \"-h b\" for basic help, \"-h e\" for examples,\n" "or \"-h hush\" for help with hushing fonts." msgstr "" #: fontypythonmodules/cli2.py:197 #, python-format msgid "%s takes two arguments: SOURCE(folder) TARGET(pog)" msgstr "%s nimmt zwei Argumente: QUELLE(Ordner) ZIEL(Pog)" #: fontypythonmodules/cli2.py:199 #, fuzzy msgid "" "NB: If you have spaces in the Pog or Folder names, put \"quotes around the " "names.\"" msgstr "" "NB: Wenn Leerzeichen in Pognamen oder Ordnern verwendet werden sollen " "\"setze sie in Anführungszeichen.\" " #: fontypythonmodules/cli2.py:234 msgid "Weirdo error. Keep calm and panic." msgstr "" #: fontypythonmodules/cli2.py:296 msgid "unknown, try: {}" msgstr "" #: fontypythonmodules/cli2.py:372 #, fuzzy msgid "" "Please check your arguments, there seem to be too many.\n" "(Remember: it's one pound for a five minute argument, but only eight pounds " "for a course of ten.)\n" "\n" "NB: If you use spaces in a Pog or Folder name then put \"quotes around the " "names.\"" msgstr "" "Bitte die Argumente prüfen, es scheinen zu viele zu sein.\n" "\n" "TIPP : Wenn Sie Leerzeichen in Pog-Namen oder Ordnern verwenden,\n" "setzen Sie \"Anführungszeichen darum\"." #: fontypythonmodules/cli2.py:405 #, python-format msgid "Sorry, (%s) does not exist. Try --list" msgstr "\"%s\" existiert nicht. Versuche -l oder --list" #: fontypythonmodules/cli2.py:410 msgid "You cannot use a folder as the target argument. Try --help" msgstr "" "Ein Ordner kann nicht als Ziel-Argument verwendet werden. Versuche --help" #: fontypythonmodules/cli2.py:462 fontypythonmodules/cli2.py:483 #, python-format msgid "" "The target pog (%s) is currently installed, you can't use it as a target." msgstr "" "Das Pog \"%s\" ist im Moment installiert und kann daher nicht als Ziel " "verwendet werden." #: fontypythonmodules/cli2.py:468 msgid "Your pogs are the same! Try -e" msgstr "Quell- und Zielpog sind gleich! Versuche -e" #: fontypythonmodules/cli2.py:475 msgid "This pog is empty" msgstr "Das Pog ist leer." #: fontypythonmodules/clifuncs.py:27 #, python-format msgid "I can't find %s" msgstr "Kann %s nicht finden" #: fontypythonmodules/clifuncs.py:46 msgid "There are no pogs available." msgstr "Keine Pogs verfügbar." #: fontypythonmodules/clifuncs.py:48 #, python-format msgid "Listing %d pog(s)" msgstr "Liste %d Pog(s) auf" #: fontypythonmodules/clifuncs.py:49 msgid " * indicates installed pogs" msgstr " (* kennzeichnet installiert Pogs)" #: fontypythonmodules/clifuncs.py:57 #, python-format msgid "Could not open (%s)." msgstr "Kann \"%s\" nicht öffnen." #: fontypythonmodules/clifuncs.py:71 #, fuzzy msgid "Could not ls the font path." msgstr "Konnte die Konfigurationsdatei nicht schreiben." #: fontypythonmodules/clifuncs.py:73 msgid "Contents of {}:" msgstr "" #: fontypythonmodules/clifuncs.py:84 #, fuzzy msgid "Could not cat that pog." msgstr "Konnte die Konfigurationsdatei nicht schreiben." #: fontypythonmodules/clifuncs.py:127 #, fuzzy msgid "I could not create the zip at all." msgstr "Konnte die Konfigurationsdatei nicht schreiben." #: fontypythonmodules/clifuncs.py:130 fontypythonmodules/wxgui.py:679 msgid "Zipped as \"{}.fonts.zip\" in the \"{}\" directory." msgstr "" #: fontypythonmodules/clifuncs.py:132 fontypythonmodules/wxgui.py:682 msgid "Some bugs happened:" msgstr "" #: fontypythonmodules/clifuncs.py:135 #, python-format msgid "I can't find a pog named %s" msgstr "Kann %s nicht finden" #: fontypythonmodules/clifuncs.py:154 fontypythonmodules/clifuncs.py:185 #, python-format msgid "(%s) cannot be found. Try -l to see the names." msgstr "" "\"%s\" nicht gefunden. Versuchen Sie -l zum Anzeigen aller Namen der Pogs." #: fontypythonmodules/clifuncs.py:177 fontypythonmodules/fpsys.py:975 #, python-format msgid "Installing (%s)" msgstr "Installiere \"%s\"" #: fontypythonmodules/clifuncs.py:204 #, python-format msgid "Removing (%s)" msgstr "Entferne \"%s\"" #: fontypythonmodules/clifuncs.py:211 #, python-format msgid "Sorry, can't find (%s). Try -l to see the names." msgstr "" "Entschuldigung,\"%s\" nicht gefunden. Versuche -l für die Anzeige aller " "Namen." #: fontypythonmodules/clifuncs.py:234 #, python-format msgid "Creating a new pog: %s" msgstr "Erstellt ein neues Pog: %s" #: fontypythonmodules/clifuncs.py:257 #, python-format msgid "I have placed %(count)s fonts from %(folder)s into %(pog)s." msgstr "%(count)s Schriften aus %(folder)s nach %(pog)s kopiert." #: fontypythonmodules/clifuncs.py:259 #, python-format msgid "The fonts from %(folder)s are *already* in %(pog)s." msgstr "Die Schriften aus %(folder)s sind *bereits* in %(pog)s." #: fontypythonmodules/fontcontrol.py:146 #, fuzzy msgid "" "Font cannot be found. Purge lost fonts from this Pog.\n" "(See the Tools menu.)" msgstr "Schrift kann nicht gefunden werden, Sie sollten das Pog löschen." #: fontypythonmodules/fontcontrol.py:152 #, fuzzy, python-format msgid "" "Unhandled error:\n" "Please remove (%s) away from here and report this to us." msgstr "" "Nicht abgefangener Fehler:\n" "Bitte entfernen Sie \"%s\" hier und senden uns einen Bericht." #: fontypythonmodules/fontcontrol.py:164 msgid "Font may be bad and it cannot be drawn." msgstr "Schrift könnte beschädigt sein und nicht richtig angezeigt werden." #: fontypythonmodules/fontcontrol.py:179 msgid "Unicode problem. Font may be bad and it cannot be drawn." msgstr "" "Unicode Problem. Schrift könnte beschädigt sein und nicht richtig angezeigt " "werden." #: fontypythonmodules/fontcontrol.py:250 msgid "Font causes a segfault. It cannot be drawn." msgstr "Schrift könnte beschädigt sein und nicht richtig angezeigt werden." #: fontypythonmodules/fontcontrol.py:295 msgid "There are no fonts to see here, move along." msgstr "Hier befinden sich keine Schriften, gehe weiter." #: fontypythonmodules/fontcontrol.py:296 msgid "" "Stuff to check:\n" "\t1) The filters.\n" "\t2) The \"include sub-folders\"\n" "\t\tcheck box (in Settings).\n" "\t3) The Help file." msgstr "" #: fontypythonmodules/fontcontrol.py:823 #, python-format msgid "%s is already installed." msgstr "%s ist bereits installiert." #: fontypythonmodules/fontcontrol.py:977 fontypythonmodules/fontcontrol.py:998 msgid "I can't write to this directory: {}" msgstr "" #: fontypythonmodules/fontcontrol.py:1015 msgid "Correcting timestamp on {}." msgstr "" #: fontypythonmodules/fontcontrol.py:1026 msgid "Zip on {} failed because: {}" msgstr "" #: fontypythonmodules/fontybugs.py:37 msgid "" "\n" "(Also check your file permissions.)" msgstr "" "\n" "(Auch die Nutzerberechtigungen prüfen.)" #: fontypythonmodules/fontybugs.py:39 msgid "Bad voodoo error. I give up." msgstr "Schwerer Fehler, ich gebe auf." #: fontypythonmodules/fontybugs.py:40 msgid "There is no such item." msgstr "Element nicht vorhanden." #: fontypythonmodules/fontybugs.py:41 msgid "Pog is empty." msgstr "Pog ist leer." #: fontypythonmodules/fontybugs.py:42 msgid "Pog is already installed." msgstr "Pog ist bereits installiert." #: fontypythonmodules/fontybugs.py:43 #, python-format msgid "" "Pog cannot be written to.\n" "Check your filesystem.%s" msgstr "" "Es konnte nicht in das Pog geschrieben werden.\n" "Prüfen Sie das Dateisystem. %s" #: fontypythonmodules/fontybugs.py:44 msgid "Pog is invalid, please hand-edit it." msgstr "Pog ist nicht gültig, bearbeiten Sie es bitte von Hand." #: fontypythonmodules/fontybugs.py:45 msgid "" "Some fonts did not install.\n" "Perhaps the original fonts folder has moved or been renamed.\n" "You should purge or hand-edit." msgstr "" "Einige Schriften wurden nicht installiert.\n" "Vielleicht wurden die Original-Schriften verschoben oder umbenannt.\n" "Entweder löschen (-p) oder von Hand bearbeiten." #: fontypythonmodules/fontybugs.py:46 msgid "Pog is not installed." msgstr "Pog ist nicht installiert." #: fontypythonmodules/fontybugs.py:47 #, python-format msgid "" "Some fonts could not be uninstalled.\n" "Please check your home .fonts (with a dot in front) folder for broken links." "%s" msgstr "" "Einige Schriften konnten nicht deinstalliert werden.\n" "Schauen Sie in Ihrem Heimatverzeichnis unter\n" "~/.fonts/ (WICHTIG: versteckter Ordner mit Punkt als erstes Zeichen)\n" "nach verwaisten Verknüpfungen. %s" #: fontypythonmodules/fontybugs.py:48 #, python-format msgid "Cannot delete the Pog.%s" msgstr "Pog konnte nicht gelöscht werden. %s" #: fontypythonmodules/fontybugs.py:49 msgid "" "Not a single font in this pog could be installed.\n" "The original font folder has probably moved or been renamed." msgstr "" "Keine einzige Schrift aus diesem Pog konnte installiert werden.\n" "Möglicherweise wurden die Original-Schriften verschoben oder umbenannt." #: fontypythonmodules/fontybugs.py:50 msgid "" "Not a single font in this pog could be uninstalled.\n" "None of the fonts were in your fonts folder, please check your home .fonts " "(with a dot in front) folder for broken links.\n" "The pog has been marked as \"not installed\"." msgstr "" "Keine einzige Schrift aus diesem Pog konnte deinstalliert werden.\n" "Keine davon befand sich in ihrem Heimatverzeichnis.\n" "Schauen Sie unter ~/.fonts/ (WICHTIG: versteckter Ordner mit Punkt als " "erstes Zeichen)\n" "nach verwaisten Verknüpfungen.\n" "Das Pog wurde als \"nicht installiert\" markiert." #: fontypythonmodules/fontybugs.py:51 msgid "This folder has no fonts in it." msgstr "Es befinden sich keine Schriften in diesem Ordner." #: fontypythonmodules/fontybugs.py:157 #, python-brace-format msgid "" "The \"{path}\" directory cannot be created or found.\n" "Fonty cannot run until it exists. Please create it, and start me again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fontypython\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:173 #, python-brace-format msgid "" "WARNING:\n" "The \"{path}\" directory cannot be created or found.\n" "Fonts cannot be installed until it exists. Please create it, and start me " "again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fonts\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:183 msgid "Missing fonts directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:191 #, python-brace-format msgid "" "WARNING:\n" "The fontconfig \"{path}\" directory cannot be created or found.\n" msgstr "" #: fontypythonmodules/fontybugs.py:196 msgid "Missing fontconfig \"{}\" directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:211 #, python-brace-format msgid "" "Failure during upgrade:\n" "{msg}\n" "\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fpsys.py:275 #, python-brace-format msgid "" "Could not move \"{what}\" from \"{src}\" to \"{dest}\"\n" "Please resolve the problem and start me again." msgstr "" #: fontypythonmodules/fpsys.py:294 #, python-brace-format msgid "" "Could not remove the old \"{oldfontydir}\" directory.\n" "Please remove it and start me again." msgstr "" #: fontypythonmodules/fpsys.py:536 msgid "Checking fonts, this could take some time." msgstr "Prüfe die Schriften, einen Moment Geduld bitte." #: fontypythonmodules/fpsys.py:537 #, python-format msgid "Starting in %s:" msgstr "Beginne in %s:" #: fontypythonmodules/fpsys.py:544 #, python-format msgid "Looking in %s..." msgstr "Suche in %s..." #: fontypythonmodules/fpsys.py:557 msgid " Bad font: {}" msgstr "" #: fontypythonmodules/fpsys.py:581 msgid "" "Bad fonts were found. They have been noted. I will ignore them in future." msgstr "" #: fontypythonmodules/fpsys.py:583 msgid "I could not find any bad fonts." msgstr "Es konnten keine beschädigten Schriften gefunden werden." #: fontypythonmodules/fpsys.py:585 msgid "The process is complete." msgstr "Vorgang abgeschlossen" #: fontypythonmodules/fpsys.py:646 msgid "Jump the lazy dog fox" msgstr "Der rötliche Vogel springt über das bläuliche Faß. " #: fontypythonmodules/fpsys.py:695 msgid "No config file found, creating it with defaults." msgstr "" "Keine Konfigurationsdatei gefunden, wird mit Standardvorgaben erstellt." #: fontypythonmodules/fpsys.py:727 msgid "" "The fontypython config file is damaged.\n" "Please remove it and start again" msgstr "" "Die Datei ~/.fontypython/fp.conf enthält Fehler.\n" "Bitte entfernen und Fonty Python neu starten." #: fontypythonmodules/fpsys.py:769 msgid "Could not write to the config file." msgstr "Konnte die Konfigurationsdatei nicht schreiben." #: fontypythonmodules/fpsys.py:914 #, python-format msgid "This font is in %s" msgstr "Diese Schrift befindet sich in %s" #: fontypythonmodules/fpsys.py:971 msgid "Trying to hush..." msgstr "" #: fontypythonmodules/fpsys.py:992 msgid "The Pog \"{}\", cannot be found." msgstr "" #: fontypythonmodules/fpsys.py:1012 msgid "Done. A hush settles over your fonts. Go: work in silence." msgstr "" #: fontypythonmodules/fpsys.py:1024 msgid "The hush isn't there. Nothing to do." msgstr "" #: fontypythonmodules/fpsys.py:1028 msgid "Trying to unhush..." msgstr "" #: fontypythonmodules/fpsys.py:1034 msgid "The noise has returned; the hush is gone." msgstr "" #: fontypythonmodules/gui_Fitmap.py:504 #, fuzzy msgid "" "Font causes a memory error, it can't be drawn.\n" "Original error was:\n" "{}" msgstr "" "Schrift verursachte einen Speicherfehler, sie konnte nicht angezeigt werden." #: fontypythonmodules/gui_FontSources.py:57 #, fuzzy msgid "Sources: Folders or Pogs" msgstr "Ursprungsordner oder Pog" #: fontypythonmodules/gui_FontSources.py:161 #, fuzzy msgid "Source Folders" msgstr "Ursprungsordner oder Pog" #: fontypythonmodules/gui_FontSources.py:162 #, fuzzy msgid "Source Pogs" msgstr "&Bereinige Pog" #: fontypythonmodules/gui_FontView.py:118 msgid "Recent Filters" msgstr "" #: fontypythonmodules/gui_FontView.py:216 msgid "Filter {} fonts" msgstr "" #: fontypythonmodules/gui_FontView.py:237 msgid "Page:" msgstr "" #: fontypythonmodules/gui_FontView.py:505 #, fuzzy msgid "There's nothing much to do." msgstr "Element nicht vorhanden." #: fontypythonmodules/gui_FontView.py:506 msgid "Choose some fonts" msgstr "Wähle einige Schriften" #: fontypythonmodules/gui_FontView.py:525 #, fuzzy, python-brace-format msgid "Remove fonts from {VIEW}" msgstr "Entferne Schriften von %s" #: fontypythonmodules/gui_FontView.py:526 #, fuzzy msgid "You can remove fonts from this source Pog." msgstr "Sie können die Schriften vom gewählten Pog entfernen." #: fontypythonmodules/gui_FontView.py:532 #, fuzzy, python-brace-format msgid "Put fonts into {TARGET}" msgstr "Lege Schriften in %s ab" #: fontypythonmodules/gui_FontView.py:533 #, fuzzy, python-brace-format msgid "You can append fonts to the active target Pog \"{TARGET}\"." msgstr "Das Pog kann um Schriften erweitert werden." #: fontypythonmodules/gui_FontView.py:540 #, fuzzy msgid " (and all sub-folders.)" msgstr "Unterverzeichnisse einschliessen" #: fontypythonmodules/gui_FontView.py:544 #, python-brace-format msgid "Viewing source Folder \"{VIEW}\"{{RT}}" msgstr "" #: fontypythonmodules/gui_FontView.py:545 #, python-brace-format msgid "Viewing source Pog \"{VIEW}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:546 msgid "Choose a Source Pog or Folder." msgstr "" #: fontypythonmodules/gui_FontView.py:547 #, fuzzy, python-brace-format msgid "The target Pog \"{TARGET}\" is installed. It can't be changed." msgstr "" "Das Pog \"%s\" ist im Moment installiert und kann daher nicht als Ziel " "verwendet werden." #: fontypythonmodules/gui_FontView.py:555 msgid "There are no fonts in here." msgstr "Hier befinden sich keine Schriften." #: fontypythonmodules/gui_FontView.py:562 #, python-brace-format msgid "Source is empty. The active target Pog is \"{TARGET}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:576 #, fuzzy, python-brace-format msgid "Viewing (installed Pog) \"{VIEW}\"" msgstr "Zeige einen (installierten Pog) %s" #: fontypythonmodules/gui_FontView.py:577 #, fuzzy msgid "You can't change an installed Pog." msgstr "Installierte Pogs können nicht verändert werden." #: fontypythonmodules/gui_FontView.py:581 #, fuzzy, python-brace-format msgid "Viewing (editable Pog) \"{VIEW}\"" msgstr "Zeige einen (veränderbaren Pog) %s" #: fontypythonmodules/gui_FontView.py:582 #, fuzzy msgid "There is no active target." msgstr "Element nicht vorhanden." #: fontypythonmodules/gui_FontView.py:606 #, fuzzy, python-brace-format msgid "Source and Target \"{VIEW}\" are the same." msgstr "Ursprung und Ziel sind das gleiche Pog! Versuche -e" #: fontypythonmodules/gui_FontView.py:607 msgid "Clear the target, or choose another Pog." msgstr "" #: fontypythonmodules/gui_FontView.py:692 msgid "FontView state error: Pattern is \"{}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:783 msgid "Selected fonts have been removed." msgstr "Gewählte Schriften wurden entfernt." #: fontypythonmodules/gui_FontView.py:786 msgid "There was an error writing the pog to disk. Nothing has been done." msgstr "" "Ein Fehler trat beim Schreiben des Pogs auf. Es wurde nichts verändert." #: fontypythonmodules/gui_FontView.py:794 #, python-format msgid "Copying fonts from %(source)s to %(target)s" msgstr "Kopiere %(source)s nach %(target)s" #: fontypythonmodules/gui_FontView.py:815 #, python-format msgid "Selected fonts are now in %s." msgstr "Ausgewählte Schriften befindne sich nun in %s." #: fontypythonmodules/gui_FontView.py:818 msgid "There was an error writing the pog to disk. Nothing has been done" msgstr "" "Ein Fehler trat beim Schreiben des Pogs auf. Es wurde nichts verändert." #: fontypythonmodules/gui_PogChooser.py:296 #, python-format msgid "(%s) skipped. It's an invalid pog." msgstr "\"%s\" wurde übersprungen, kein gültiges Pog." #: fontypythonmodules/gui_PogChooser.py:305 #, python-format msgid "(%s) skipped. I can't display this name under your locale." msgstr "" "\"%s\" wurde übersprungen, Name kann mit der eingestellten Lokalisation " "nicht angezeigt werden." #: fontypythonmodules/gui_PogTargets.py:53 msgid "Target Pogs" msgstr "Vorhandene Pogs" #: fontypythonmodules/gui_PogTargets.py:68 msgid "Clear selection" msgstr "Nichts &auswählen" #: fontypythonmodules/gui_PogTargets.py:71 #, fuzzy msgid "Deselects any chosen Pogs." msgstr "Entfernt alle Markierung" #: fontypythonmodules/gui_PogTargets.py:83 #: fontypythonmodules/gui_PogTargets.py:141 msgid "New Pog" msgstr "Neues Pog" #: fontypythonmodules/gui_PogTargets.py:84 msgid "Creates a new, empty Pog" msgstr "Erstellt ein neues, leeres Pog." #: fontypythonmodules/gui_PogTargets.py:86 #, fuzzy msgid "Install Pog(s)" msgstr "Installiere Pog" #: fontypythonmodules/gui_PogTargets.py:87 msgid "" "Installs all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:89 #, fuzzy msgid "Uninstall Pog(s)" msgstr "Deinstalliere Pog" #: fontypythonmodules/gui_PogTargets.py:90 msgid "" "Uninstalls all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:92 #, fuzzy msgid "Delete Pog(s)" msgstr "Lösche Pog" #: fontypythonmodules/gui_PogTargets.py:93 #, fuzzy msgid "Deletes the selected Pog(s)" msgstr "Löscht das zuletzt gewählte Pog" #: fontypythonmodules/gui_PogTargets.py:95 #, fuzzy msgid "Zip Pog(s)" msgstr "Deinstalliere Pog" #: fontypythonmodules/gui_PogTargets.py:96 #, fuzzy msgid "Save a zip file of the selected Pog(s)" msgstr "Alle verwaisten Schriften vom gewählten Pog entfernen." #: fontypythonmodules/gui_PogTargets.py:140 #, fuzzy msgid "Enter a name for the new Pog" msgstr "Einen Namen für das neue Pog eingeben" #: fontypythonmodules/gui_PogTargets.py:141 msgid "Fonty Python" msgstr "Fonty Python" #: fontypythonmodules/gui_PogTargets.py:147 msgid "A Pog with no name won't be created, however it was a good try!" msgstr "" "Ein Pog ohne Namen wird nicht angelegt, aber immerhin ein netter Versuch!" #: fontypythonmodules/gui_PogTargets.py:152 #, python-format msgid "%s already exists." msgstr "%s existiert bereits." #: fontypythonmodules/gui_PogTargets.py:187 #, fuzzy msgid "" "One or more selected Pogs is installed, fix your selection and try again." msgstr "" "Eine oder mehrere Schriften sind installiert, ändere die Auswahl und versuch " "es nochmal." #: fontypythonmodules/gui_PogTargets.py:203 #, python-format msgid "Remove %s, are you sure?" msgstr "Soll %s wirklich gelöscht werden?" #: fontypythonmodules/gui_PogTargets.py:204 msgid "Are you sure?" msgstr "Sind Sie sicher?" #: fontypythonmodules/gui_dismissable_panels.py:102 msgid "Dismiss. ESC key does the same." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:235 msgid "Help! Help! I'm being repressed!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:276 msgid "User Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:285 msgid "Fontconfig" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:286 msgid "No path: Fontconfig is not functioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:311 #, fuzzy msgid "About Fonty" msgstr "Über Fonty Python" #: fontypythonmodules/gui_dismissable_panels.py:359 msgid "Hushing is on." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:359 #, fuzzy msgid "Un-hush my fonts" msgstr "Wähle einige Schriften" #: fontypythonmodules/gui_dismissable_panels.py:360 msgid "Hushing is off." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:360 #, fuzzy msgid "Hush my fonts" msgstr "Wähle einige Schriften" #: fontypythonmodules/gui_dismissable_panels.py:361 #, fuzzy msgid "Fonty cannot hush your fonts" msgstr "Fonty Python : hole mehr aus Deinen Schriften!" #: fontypythonmodules/gui_dismissable_panels.py:366 msgid "Hush Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:399 msgid "The Hush Pog:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:404 msgid "" "Hushing installs a Pog that you must manage. Make sure it contains a few " "system fonts so that your applications function properly!\n" "Look in /usr/share/fonts for ideas. Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:417 msgid "Current Hush Pog: " msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:423 msgid "Choose your system Pog" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:433 msgid "" "Fontconfig is not properly installed; thus Fonty cannot hush fonts.\n" "Consult your distribution's help, or open a ticket so we can try fix it. " "Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:443 msgid "Progress report:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:515 msgid "None chosen" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:597 msgid "Locate a directory for the zip file(s)" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:645 msgid "Create the zip file" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:672 msgid "" "The zip file(s) will be put into:\n" "{}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:724 msgid "Settings" msgstr "Optionen" #: fontypythonmodules/gui_dismissable_panels.py:738 msgid "Sample text:" msgstr "Beispieltext:" #: fontypythonmodules/gui_dismissable_panels.py:745 msgid "Point size:" msgstr "Schriftgröße:" #: fontypythonmodules/gui_dismissable_panels.py:750 msgid "Beware large numbers!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:751 msgid "Page length:" msgstr "Seitenlänge:" #: fontypythonmodules/gui_dismissable_panels.py:755 msgid "Tick to disable" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:757 msgid "Disable top-left correction:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:758 msgid "" "Disabling this speeds-up\n" "font drawing but can\n" "cause bad positioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:769 msgid "Available" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:776 msgid "Choose which app to use as a character map viewer." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:783 msgid "" "None found.\n" "You could install: {}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:786 msgid "Character map viewer:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:796 msgid "Max number of columns:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:797 msgid "" "The font viewing area\n" "will divide into columns\n" "which you can control here." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:803 msgid "" "Tick to include all\n" "sub-folders in\n" "the source view." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:806 msgid "Include sub-folders." msgstr "Unterverzeichnisse einschliessen" #: fontypythonmodules/gui_dismissable_panels.py:807 msgid "" "Caution: This will crash Fonty if\n" "your Source folder (directory)\n" "is deep." msgstr "" #: fontypythonmodules/segwrapfonty.py:87 msgid "Oh boy..." msgstr "Oh Junge..." #: fontypythonmodules/segwrapfonty.py:91 msgid "Fonty Python, um ... crashed." msgstr "Fonty Python, .... ist abgestürzt." #: fontypythonmodules/segwrapfonty.py:96 msgid "" "There's some problem with the font named below.\n" "You can do one of two things:\n" "1) Manually move this font somewhere else, or\n" "2) Use Fonty's command-line (-c) to mark bad fonts.\n" " See below for help with this.\n" "After you've done these, run me again." msgstr "" #: fontypythonmodules/segwrapfonty.py:102 msgid "The bad font might be:" msgstr "" #: fontypythonmodules/segwrapfonty.py:105 msgid "" "There's no lastFontBeforeSegfault file; I can't really help.\n" "Look at the error (below) for clues." msgstr "" #: fontypythonmodules/segwrapfonty.py:107 msgid "The error was:" msgstr "" #: fontypythonmodules/segwrapfonty.py:118 msgid "The command line to seek and mark bad fonts is:" msgstr "" #: fontypythonmodules/segwrapfonty.py:119 msgid "(Copy the text; open a console; paste and press enter.)" msgstr "" #: fontypythonmodules/segwrapfonty.py:125 msgid "You can get help by opening a ticket on:" msgstr "" #: fontypythonmodules/strings.py:25 #, fuzzy, python-format msgid "Please use a number for argument %s" msgstr "Bitte verwenden Sie eine Zahl für %s" #: fontypythonmodules/strings.py:31 msgid "Your arguments amuse me :) Please see the help by using -h" msgstr "" #: fontypythonmodules/strings.py:34 #, python-format msgid "Fonty Python version %s" msgstr "Fonty Python Version %s" #: fontypythonmodules/strings.py:42 msgid "Fonts supported: TTF, OTF, TTC, WOFF, Type1 (PFB, PFA)." msgstr "" #: fontypythonmodules/strings.py:44 #, python-format msgid "" "The basic format is:\n" "%(c)s [OPTIONS] || [VIEW] [TARGET]\n" "\n" "OPTIONS: Various flags for use on the command-line. See \"-h b\" or \"--help " "b\"\n" "for more details. (Long options can use an \"=\" sign or a space: --" "cat=foo \n" "or --cat foo)\n" "\n" "Or:\n" "\n" "Two arguments which will determine what you see in the graphical user " "interface:\n" "VIEW : A place where fonts are. A Pog or a folder where fonts are " "located.\n" "TARGET : A Pog. If this Pog does not exist, it will be created.\n" "\n" "Neither argument is required. When there's only one it's assumed to be a " "VIEW. \n" "When there are two, it's VIEW then TARGET.\n" "\n" "NB: Try not to use spaces in Pog names. If you must, then \"quote the name\"." msgstr "" #: fontypythonmodules/strings.py:66 #, fuzzy msgid "" "Manage your fonts on GNU/Linux\n" "==============================\n" "Many designers have collections of font files on their drives. \n" "Fonty Python will help you gather and structure them into collections \n" "called \"Pogs\" -- a place to keep tyPOGraphy. Well, why not?\n" "\n" "Fonty lets you you select fonts visually and place them into Pogs which " "you \n" "can then install or remove as you require. (Your font files never move \n" "from where they are. Only links are used.)\n" "\n" "Example: You create a \"logos\" Pog where you place logotype fonts.\n" "When you want to use them, simply install the \"logos\" Pog and start your \n" "design app! When you're done, uninstall the \"logos\" Pog; the fonts will \n" "go away.\n" "\n" "Fonty can also \"hush\" unwanted fonts. This hides system fonts, leaving\n" "only those Pogs you want in your apps. The Inkscape font chooser, for \n" "example, is more usable after a hush.\n" "(This is temporary; an \"unhush\" will switch the system fonts on again.)\n" "\n" "Fonty is great for just looking at fonts, wherever they are, without " "having \n" "to install them." msgstr "" "Verwalte Deine Schriften mit GNU/Linux\n" "NEUIGKEITEN: Jetzt auch Unterstützung für TTF, OTF, Type1 (PFB, PFA)\n" "und TTC Schriften.\n" "\n" "Viele Designer habe ihre Schriftarten in großen Verzeichnisbäumen\n" "oder auf externen Speichern verteilt. Fonty Python gibt die Möglichkeit\n" "die Schriften zu sammeln und in Gruppen zu sortieren -- oder \"Pogs\"\n" "wie ich es nenne -- ein Ort für tyPOGrafie. Also, warum nicht?\n" "\n" "Aber keine Sorge, die Dateistruktur der Schriften wird nie verändert.\n" "Es werden nur die Namen der Schriften mit Hilfe einer grafischen Oberfläche\n" "ausgewählt und in einem Pog gespeichert. Danach werden die Schriften je\n" "nach Bedarf installiert oder entfernt, dazu aber nur symbolische " "Verknüpfungen\n" "angelegt, keine Kopien der Schriftdateien.\n" "\n" "Wenn Sie also z.B. ein Pog \"Logos\" angelegt haben, indem alle TrueType-" "Schriften\n" "mit Firmenlogos abgelegt sind, und Sie mit diesen arbeiten wollen, muss nur " "das\n" "Pog \"Logos\" installiert werden, damit diese Schriften allen anderen " "Anwendungen\n" "zur Verfügung stehen.\n" "\n" "Fonty Python eignet sich ebenso gut zum Betrachten aller auf einem Computer\n" "vorhandenen Schriften, ohne dass diese systemweit installiert werden " "müssen.\n" "\n" " %(copy)s\n" " %(contact)s\n" " " #: fontypythonmodules/strings.py:90 #, python-format msgid "" "%(yadda)s\n" "Please use -e to see more info.\n" "\n" "%(fonts_supported)s\n" "\n" "%(basic_idea)s" msgstr "" #: fontypythonmodules/strings.py:97 msgid "" "Options:\n" "\n" " -v, --version Show program's version number and exit.\n" " -h b|e|hush, --help b|e|hush\n" " Show a help message and exit.\n" " \"b\" is for basic help.\n" " \"e\" to show some %$@#$ examples!\n" " \"hush\" is for more detail on hushing fonts.\n" " -d, --dir Show the \"fontypython\" path. Add this to your backup " "process!\n" " -i Pog, --install Pog\n" " Install the fonts in this Pog.\n" " -u Pog, --uninstall Pog\n" " Uninstall the fonts in this Pog.\n" " -l, --list\n" " List the names of all your Pogs.\n" " -f, --lsfonts\n" " Lists the contents of your user fonts directory. Here, " "you'll\n" " find the links that Fonty is managing for you.\n" " -s num, --size num\n" " Set a new default point size (you'll see it in the gui).\n" " -n num, --number num\n" " Set a new default for how many fonts to view at one go in " "the gui.\n" " (Don't overdo this.)\n" " -p Pog, --purge Pog\n" " Clean the Pog of fonts that are missing.\n" " -c folder, --check folder\n" " Check for bad fonts that crash Fonty. After using this tool " "you \n" " should be able to use Fonty again.\n" " * NOTE: The fonts that crash Fonty are probably still " "perfectly\n" " useable in other apps. \n" " -a Folder Pog, --all Folder Pog\n" " Puts all fonts in Folder into Pog.\n" " -A Folder Pog, --all-recurse Folder Pog\n" " Puts all fonts in Folder and *all* sub-folders into Pog.\n" " -z Pog, --zip Pog\n" " All the fonts inside Pog will be zipped and the zipfile will " "be \n" " named after the Pog. The file will be placed in the current\n" " directory.\n" " --cat Pog\n" " Cat the Pog. This will list all the fonts within.\n" " --hush HushPog\n" " Hush *all* the fonts except the Pogs you install.\n" "\n" " Uses \"HushPog\", which you create that must contain a few " "system \n" " fonts; in order to supply a basic set to your desktop apps.\n" "\n" " I suggest these from \"/usr/share/fonts\":\n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" " --unhush\n" " Restores all the system fonts after a hush. Leaves your " "special\n" " HushPog installed. It's up to you to manage it.\n" " " msgstr "" #: fontypythonmodules/strings.py:152 #, fuzzy, python-format msgid "" "%(yadda)s\n" "\n" "Examples: All using short options, see -h\n" "=========\n" "%(c)s /path/to/fonts/ttfs/a\n" " This will start off showing the fonts in that path.\n" "\n" "%(c)s /path/to/fonts/ttfs/b Trouser\n" " This will let you view and choose fonts from the path and it will store " "them \n" " in a Pog named Trouser. The Pog will be created if it's not already " "there.\n" "\n" "%(c)s Lumberjack\n" " This will let you see the fonts in the Pog named Lumberjack. You can " "also \n" " uninstall individual fonts by selecting them. A cross will appear " "indicating \n" " the fonts that will be uninstalled.\n" "\n" "%(c)s Camelot Spamalot\n" " This will let you see and choose fonts in Camelot and it will store them \n" " in \"Spamalot\". It lets you copy fonts between Pogs.\n" "\n" "%(c)s -i Cheese\n" " Will install the fonts in Cheese so you can use them in other apps.\n" "\n" "%(c)s -u Trouser\n" " Will uninstall the fonts listed in Trouser.\n" "\n" "%(c)s -s 128\n" " Will set the point size in the gui to 128 - Crazy man!\n" "\n" "%(c)s -n 25\n" " Will show 25 fonts at a time, in the gui. Beware large numbers!\n" "\n" "%(c)s -s 64 -v 10 Pimple\n" " Will set the point size to 64, paging to 10,open the gui and display the " "fonts\n" " in Pimple.\n" "\n" "%(c)s -p Glutton\n" " Purging a font. If there are any fonts in Glutton that are not really on " "your \n" " drive/media anymore (perhaps you deleted them or the cat did) this will " "go \n" " through the Pog and cull them.\n" "\n" "%(c)s -c /some/path/to/fonts\n" " If Fonty keeps crashing on /some/path/to/fonts then you should run a check " "on\n" " that folder. This will mark the dangerous fonts and let you view that " "folder \n" " in the future.\n" "\n" "%(c)s -a /some/path HolyHandGrenade\n" " This will put all the fonts in that path into the Pog called " "HolyHandGrenade.\n" "\n" "%(c)s -A /some/path Tutto\n" " This will do the same as -a: starting in some path, but it will then " "walk \n" " down through *all* sub-folders too. The fonts will be placed in Tutto.\n" "\n" "%(c)s --hush mysysfonts\n" " Will hush (silence) all the fonts in your system except the ones in \n" " \"mysysfonts\" and any other Pogs you have installed. Other apps will \n" " now have fewer fonts to choose from, making life much easier for you.\n" " (Use --unhush later to restore all of them.)\n" "\n" msgstr "" "Die gewöhnliche Anwendung ist:\n" "%(c)s [ANSICHT] [ZIEL]\n" " ANSICHT = Eine Stelle, an der sich Schriften befinden.\n" " Entweder ein Pog oder Ordner.\n" " ZIEL = Ein Pog, das die Verweise auf die Schriften aufnimmt\n" " Wenn kein Ziel angegeben ist, ist nur die Vorschau/\n" " Bearbeitung möglich.\n" "\n" "TIPPS:\n" "=====\n" "* Verwende keine Leerzeichen in den Namen für die Pogs.\n" " Nur wenn unbedingt nötig setze den Namen in Anführungszeichen,\n" " z.B.:\"Meine Schriften\"\n" "* Wenn andere Anwendungen (z,B. The Gimp) die neuen\n" " Schriften nicht registrieren, starte die Anwendung neu.\n" " Manchmal braucht das System einen Moment, bis die\n" " Schriften im ~/.fonts Ordner eingelesen werden.\n" "\n" "Beispiele für die Anwendung (es werden nur kurze Optionen verwendet, siehe -" "h)\n" "=========\n" "%(c)s /pfad/zur/schrift/ttfs/a\n" " Diese Kommando öffnet die Vorschau der Schriften in Pfad.\n" " \n" "%(c)s /pfad/zur/schrift/ttfs/b Hose\n" " Dies öffnet die Vorschau und wählt die Schriften im Pfad aus,\n" " um sie in dem Pog \"Hose\" zu speichern.\n" " Ist das Pog noch nicht vorhanden, wird es angelegt.\n" "\n" "%(c)s Holzfäller\n" " Die Vorschau aller Schriften im Pog Holzfäller.\n" " Einzelne Schriften können durch Auswahl entfernt\n" " werden. Ein Kreuz zeigt die betreffenden Schriften an.\n" "\n" "%(c)s Camelot Spamalot\n" " Alle Schriften aus \"Camelot\" werden in \"Spamalot\"\n" " gespeichert. Dies ermöglicht den Austausch von Schriften\n" " zwischen verschiedenen Pogs.\n" "\n" "%(c)s -i Käse\n" " Installiert alle Schriften im Pog \"Käse\", damit sie von\n" " anderen Anwendungen benutzt werden können.\n" "\n" "%(c)s -u Hose\n" " Entfernt alle Schriften im Pog \"Hose\",\n" " sie können nun nicht mehr benutzt werden.(Also wirklich...) \n" "\n" "%(c)s -t \"Schweine auf dem Flügel\"\n" " Setzt den Beispieltext und beendet. Es ist aber ein unsauberer Weg.\n" " Starte Fonty neu, um die Veränderung zu sehen.\n" " * Eleganter ist es den Text mit der GUI ohne Neustart zu setzen\n" " \n" "%(c)s -s 128 \n" " Setzt die Schriftgröße auf 128 - Verrückt!\n" "\n" "%(c)s -v 25\n" " Es werden 25 Schriften pro Seite angezeigt. Vermeide zu große Zahlen!\n" " \n" "%(c)s -s 64 -v 10 Pickel\n" " Setzt die Schriftgröße auf 64, die Zahl der angezeigten auf 10\n" " und öffnet schließlich das Pog \"Pickel\".\n" "\n" "%(c)s -p Fresssack\n" " Falls irgendwelche Schriften in \"Fresssack\" nicht mehr\n" " auf der Festplatte/Speichermedium vorhanden sind\n" " (weil sie vielleicht gelöscht wurden), dann wird das Pog\n" " davon bereinigt.\n" "\n" "%(c)s -c /pfad/zu/den/schriften\n" " Wenn Fonty immer wieder beim Öffnen von /pfad/zu/den/schriften\n" " abstürzt, dann sollte dieser Test durchgeführt werden.\n" " Als gefährliche markierte Schriften werden nun ignoriert\n" " und der Ordner kann ohne Probleme genutzt werden.\n" "\n" "Ihr Fonty Python Ordner ist:\n" "%(folder)s\n" "Wenn Sie Sicherheitskopien Ihrer Pogs machen wollen, sind Sie hier richtig.\n" "%(contact)s\n" "\n" "%(copy)s" #: fontypythonmodules/strings.py:213 msgid "" "Your fontypython folder is:\n" "{}" msgstr "" #: fontypythonmodules/strings.py:217 #, fuzzy msgid "Fonty Python - view and manage fonts on Gnu/Linux" msgstr "" "Fonty Python - betrachten und verwalten aller Schriftarten mit GNU/Linux" # a comment #: fontypythonmodules/strings.py:222 #, fuzzy, python-format msgid "" "I cannot find \"python-wxversion\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxversion\n" "I then install it like this:\n" "sudo aptitude install python-wxversion\n" "\n" "If you get long error messages, you will need to\n" "install python-wxgtk*, where the star means the\n" "version number and it should be at least %(wxv)s\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" "Konnte \"python-wxversion\" nicht finden!\n" "Bitte dieses Paket installieren - NB: gehen Sie sicher,\n" "dass diese Version Unicode unterstüzt.\n" "\n" "TIPP\n" "====\n" "Bei meiner Distribution kann ich auf diese Weise suchen:\n" "aptitude search python-wx\n" "In der Liste sollte auch zu finden sein:\n" "python-wxversion \n" "Mit diesem Befehl kann das Paket installiert werden:\n" "sudo aptitude install python-wxversion \n" "\n" "Werden trotzdem noch Fehlermeldungen angezeigt, muss auch\n" "python-wxgtk* installiert werden, der Stern steht für die\n" "Versionsnummer, die mindestens 2.8 sein sollte\n" "\n" "Die neueste Version kann ebenso von hier heruntergeladen werden:\n" "http://wxpython.org/download.php\n" #: fontypythonmodules/strings.py:243 #, fuzzy, python-format msgid "" "I cannot find \"python-wxgtkX.Y\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxgtk%(wxv)s\n" "I then install it like this:\n" "sudo aptitude install python-wxgtk%(wxv)s\n" "\n" "Make sure it's at least version %(wxv)s\n" "**NB** It should not be any version greater\n" "than 3.0\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" "Konnte \"python-wxgtkX.Y\" nicht finden!\n" "Bitte dieses Paket installieren - NB: gehen Sie sicher,\n" "dass diese Version Unicode unterstüzt.\n" "\n" "TIPP\n" "====\n" "Bei meiner Distribution kann ich auf diese Weise suchen:\n" "aptitude search python-wx\n" "In der Liste sollte auch zu finden sein:\n" "python-wxgtk2.8\n" "Mit diesem Befehl kann das Paket installiert werden:\n" "sudo aptitude install python-wxgtk2.8 \n" "\n" "Die Versionsnummer sollte mindestens 2.8.\n" "\n" "Die neueste Version kann ebenso von hier heruntergeladen werden:\n" "http://wxpython.org/download.php\n" #: fontypythonmodules/strings.py:265 #, fuzzy msgid "" "I cannot find \"python-pil\"\n" "Please install this package.\n" "\n" "NOTE\n" "===\n" "PIL has been forked by Pillow.\n" "The old package was \"python-imaging\",\n" "the new one is \"python-pil\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-pil\n" "This returns many results, one of which is:\n" "python-pil\n" "I then install it like this:\n" "sudo aptitude install python-pil\n" "\n" "Make sure it's at least version 1.1.6-1\n" "\n" "You can also get the latest version from here:\n" "http://www.pythonware.com/products/pil/index.htm\n" msgstr "" "Konnte \"python-imaging\" nicht finden!\n" "Bitte dieses Paket installieren.\n" "\n" "TIPP\n" "====\n" "Bei meiner Distribution kann ich auf diese Weise suchen:\n" "aptitude search python-imag\n" "In der Liste sollte auch zu finden sein:\n" "python-imaging\n" "Mit diesem Befehl kann das Paket installiert werden:\n" "sudo aptitude install python-imaging \n" "\n" "Die Versionsnummer sollte mindestens 1.1.6-1.\n" "\n" "Die neueste Version kann ebenso von hier heruntergeladen werden:\n" "http://www.pythonware.com/products/pil/index.htm\n" #: fontypythonmodules/strings.py:290 msgid "" "I cannot find \"Python-gi\"\n" "This package is not required; although if you\n" "have it, modern Linux desktop standards can be\n" "implemented by Fonty.\n" "\n" "TIP\n" "===\n" "Look for \"python-gi\" in your package manager.\n" msgstr "" #: fontypythonmodules/strings.py:318 msgid "" "Hold SHIFT or CTRL as you select Pogs, if you wish to select many at once." msgstr "" #: fontypythonmodules/strings.py:322 msgid "Can't hush because:" msgstr "" #: fontypythonmodules/strings.py:323 msgid "Can't unhush because:" msgstr "" #: fontypythonmodules/strings.py:324 msgid "See --help hush" msgstr "" #: fontypythonmodules/strings.py:325 #, python-brace-format msgid "" "\n" "The idea\n" "========\n" "Often there are too many fonts reported by your system. In your apps, like " "Inkscape,\n" "they clutter the font chooser. This is a way to \"hush\" that, to quieten " "the noise.\n" "\n" "Fonty will install a select Pog of system fonts (which you must pick) and " "then will\n" "reject *all* the system's fonts, leaving only the Pogs which you install.\n" "\n" "This does no damage and you can \"unhush\" at any time to reverse it.\n" "\n" "Hushing\n" "=======\n" "1. Relies on fontconfig, which should be installed on most modern Linux " "desktops.\n" " You can verify if it's there by trying this command:\n" " fc-list\n" "\n" " If that shows no error, you're good.\n" "\n" "2. Fontconfig's user directory:\n" " The path is {{fcpaf}}\n" " Make sure it exists and try fonty again.\n" "\n" "3. System fonts: Put some fonts in a Pog that you must create and choose.\n" " I suggest those in /usr/share/fonts, like: \n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" "\n" "The way it works is that fonty writes an XML file which rejects all fonts " "that \n" "are on the path: \"/usr/share/fonts\"\n" "\n" "This may not work on your particular Linux distribution. Please open a " "ticket\n" "on our site if you have any trouble: {ticket_url}\n" "\n" "To hush, using your special Pog from the command line do this:\n" "{fp} --hush yourpoghere\n" "\n" "To hush from the gui, ...\n" "\n" "Unhushing\n" "=========\n" "To release the hush, use --unhush from the command line or the gui.\n" "\n" "The Pog(s) you installed when you hushed will be left installed. Remove\n" "it/them if you must." msgstr "" #: fontypythonmodules/wxgui.py:124 #, fuzzy, python-format msgid "Welcome to Fonty Python, vers %s" msgstr "Willkommen bei Fonty Python %s" #: fontypythonmodules/wxgui.py:181 msgid "&Settings\tCtrl+S" msgstr "&Optionen\tCtrl+O" #: fontypythonmodules/wxgui.py:181 msgid "Change settings" msgstr "Einstellungen verändern" #: fontypythonmodules/wxgui.py:187 msgid "&Purge Pog.See TogglePurgeMenuItem for actual string." msgstr "" #: fontypythonmodules/wxgui.py:188 msgid "Remove all ghost fonts from the selected Pog." msgstr "Alle verwaisten Schriften vom gewählten Pog entfernen." #: fontypythonmodules/wxgui.py:194 msgid "&Hush fonts\tCtrl+H" msgstr "" #: fontypythonmodules/wxgui.py:195 msgid "Silence all the noisy system fonts and focus only on those you want," msgstr "" #: fontypythonmodules/wxgui.py:201 msgid "&Exit" msgstr "&Verlassen" #: fontypythonmodules/wxgui.py:202 msgid "Close the app" msgstr "Fonty Python beenden" #: fontypythonmodules/wxgui.py:205 msgid "&Tools" msgstr "" #: fontypythonmodules/wxgui.py:212 msgid "&Select ALL the source fonts" msgstr "&ALLE Schriften im Ordner/Pog auswählen" #: fontypythonmodules/wxgui.py:213 msgid "Select ABSOLUTELY ALL the fonts in the chosen source." msgstr "Wählt RESTLOS ALLE Schriften im Ursprungsordner/Pog aus" #: fontypythonmodules/wxgui.py:216 msgid "&Clear ENTIRE selection" msgstr "&GESAMTE Auswahl aufheben" #: fontypythonmodules/wxgui.py:217 msgid "Clear the selection completely." msgstr "Hebt die Auswahl komplett auf." #: fontypythonmodules/wxgui.py:218 msgid "&Selection" msgstr "&Auswahl" #: fontypythonmodules/wxgui.py:223 msgid "H&elp\tF1" msgstr "&Hilfe\tF1" #: fontypythonmodules/wxgui.py:224 msgid "&About" msgstr "Ü&ber" #: fontypythonmodules/wxgui.py:225 msgid "&Help" msgstr "&Hilfe" #: fontypythonmodules/wxgui.py:546 msgid "Warning" msgstr "Achtung" #: fontypythonmodules/wxgui.py:551 msgid "Error" msgstr "Fehler" #: fontypythonmodules/wxgui.py:674 msgid "I could not create the zip for {}" msgstr "" #: fontypythonmodules/wxgui.py:688 msgid "Some fonts were skipped, try purging the Pog(s) involved." msgstr "" #: fontypythonmodules/wxgui.py:689 msgid "Something went wrong." msgstr "" #: fontypythonmodules/wxgui.py:691 fontypythonmodules/wxgui.py:692 #, fuzzy msgid "Zip file(s) have been created." msgstr "Gewählte Schriften wurden entfernt." #: fontypythonmodules/wxgui.py:752 #, python-format msgid "&Purge \"%s\"\tCtrl+P" msgstr "" #: fontypythonmodules/wxgui.py:754 #, fuzzy msgid "&Purge Pog\tCtrl+P" msgstr "&Bereinige Pog" #: fontypythonmodules/wxgui.py:761 #, python-format msgid "" "Do you want to purge %s?\n" "\n" "Purging means all the fonts in the pog\n" "that are not pointing to actual files\n" "will be removed from this pog." msgstr "" "%s soll bereinigt werden?\n" "\n" "Bereinigen bedeutet, dass alle Schriften in diesem Pog,\n" "die nicht auf eine vorhandene Schrift verweisen, entfernt werden." #: fontypythonmodules/wxgui.py:761 msgid "Purge font?" msgstr "Schrift löschen?" #: fontypythonmodules/wxgui.py:770 #, python-format msgid "%s has not been purged." msgstr "%s wurde nicht gelöscht." #: fontypythonmodules/wxgui.py:774 #, python-format msgid "%s has been purged." msgstr "%s wurde gelöscht." #: fontypythonmodules/wxgui.py:794 msgid "" "I am sorry, but Unicode is not supported by this installation of wxPython. " "Fonty Python relies on Unicode and will simply not work without it.\n" "\n" "Please fetch and install the Unicode version of python-wxgtk." msgstr "" "Entschuldigung, aber installierte Version von wxPython unterstützt Unicode " "nicht. Fonty Python ist aber auf Unicode angewiesen und wird ohne nicht " "arbeiten.\n" "\n" "Bitte besorgen Sie sich die Unicode-Version von python-wxgtk." #: fontypythonmodules/wxgui.py:798 msgid "SORRY: UNICODE MUST BE SUPPORTED" msgstr "ENTSCHULDIGUNG, ABER UNICODE MUSS UNTERSTÜTZT WERDEN" #: fontypythonmodules/wxgui.py:811 msgid "FATAL ERROR" msgstr "" #: fontypythonmodules/wxgui.py:909 msgid "Fonty Python: bring out your fonts!" msgstr "Fonty Python : hole mehr aus Deinen Schriften!" #~ msgid "Sorry, only Gnu/Linux is supported at the moment." #~ msgstr "Entschuldigung, nur GNU/Linux wird zur Zeit unterstützt" #~ msgid "" #~ "Please restart Fonty Python after you have moved:\"%s\" to some other " #~ "place." #~ msgstr "" #~ "Bitte starten Sie Fonty Python neu, nachdem Sie \"%s\" verschoben haben." #~ msgid "About" #~ msgstr "Über" #~ msgid "Thanks" #~ msgstr "Danke" #~ msgid "Licence" #~ msgstr "Lizenz" #, fuzzy #~ msgid "Quick settings" #~ msgstr "Optionen" #~ msgid "Oh dear," #~ msgstr "Oh nein,.." #~ msgid "" #~ "There's some problem with the font named below. Please use the Check " #~ "Fonts tool in Fonty\n" #~ "(from the command-line or the Tools menu) to go through this directory " #~ "and mark all the dangerous fonts.\n" #~ "(You could simply move this font elsewhere, but others may remain to " #~ "cause trouble.)\n" #~ msgstr "" #~ "Es gibt Probleme mit den unten aufgeführten Schriften. Bitte das " #~ "\"Überprüfe Schriften\"-Werkzeug in Fonty benutzen.\n" #~ "(von der Kommandozeile oder vom Menü \"Datei\" aus), um alle gefährlichen " #~ "Schriften zu markieren.\n" #~ "(Diese können an einen beliebigen Ort verschoben werden, aber andere " #~ "Schriften können weiterhin Schwierigkeiten verursachen.)\n" #~ msgid "Check for dangerous fonts." #~ msgstr "Auf gefährliche Schriften überprüfen." #~ msgid "Choose a directory and double click it to start" #~ msgstr "Wähle ein Verzeichnis und Doppelklicke darauf" #~ msgid "(Check your filter!)" #~ msgstr "(Filtereinstellungen beachten!)" #~ msgid "No supported fonts found there..." #~ msgstr "Keine unterstützten Schriften gefunden...." #~ msgid "This text cannot be drawn. Hey, it happens..." #~ msgstr "Dieser Text kann nicht angezeigt werden, soll vorkommen...." #~ msgid "Folders" #~ msgstr "Ordner" #~ msgid "Pogs" #~ msgstr "Pogs" #~ msgid "Clear filter" #~ msgstr "Filter leeren" #~ msgid "Filter:" #~ msgstr "Filter:" #~ msgid "Your active Target is %s" #~ msgstr "Aktives Pog ist %s" #~ msgid "Please choose a Source." #~ msgstr "Bitte eine Quelle für das Pog wählen." #~ msgid "Please choose a Pog or a Font folder on the left." #~ msgstr "Bitte ein Pog oder Schriftverzeichnis auf der linken Seite wählen." #~ msgid "Nothing to do" #~ msgstr "Nichts zu tun" #~ msgid "Viewing Folder %s" #~ msgstr "Angezeigter Order %s" #~ msgid "Viewing a folder." #~ msgstr "Zeige einen Ordner." #, fuzzy #~ msgid "Append from %(source)s to %(target)s" #~ msgstr "Erweitere %(target)s um %(source)s" #, fuzzy #~ msgid "Viewing %(source)s, but Pog %(target)s is installed." #~ msgstr "" #~ "Zeige Pog:%(source)s, aber Pog:%(target)s ist installiert (nicht " #~ "veränderbar). " #~ msgid "These two are the same Pog." #~ msgstr "Quell- und Zielpog sind gleich." #, fuzzy #~ msgid "Append from %(source)s into %(target)s" #~ msgstr "Erweitere %(target)s um %(source)s" #~ msgid "Install Pog" #~ msgstr "Installiere Pog" #~ msgid "" #~ "Installs all selected Pogs.\n" #~ "Use SHIFT/CTRL+Click on the list above." #~ msgstr "" #~ "Installiert alle gewählten Pogs.\n" #~ "Benutze SHIFT/CTRL+Klick zur\n" #~ "Mehrfachauswahl in obiger Liste." #~ msgid "" #~ "Uninstalls all selected Pogs.\n" #~ "Use SHIFT/CTRL+Click on the list above." #~ msgstr "" #~ "Deinstalliert alle gewählten Pogs.\n" #~ "Benutze SHIFT/CTRL+Klick zur\n" #~ "Mehrfachauswahl in obiger Liste." #~ msgid "" #~ "\n" #~ "Couldn't make the .fonts folder in %s\n" #~ "Please check your write permissions and try again." #~ msgstr "" #~ "\n" #~ "Konnte den Ordner .fonts in %s nicht erstellen\n" #~ "Bitte die Berechtigung prüfen und noch einmal versuchen." #~ msgid "" #~ "\n" #~ "Couldn't make the folder in %s\n" #~ "Please check your write permissions and try again." #~ msgstr "" #~ "\n" #~ "Konnte den Ordner in %s nicht erstellen\n" #~ "Bitte die Berechtigung prüfen und noch einmal versuchen." #, fuzzy #~ msgid "" #~ "Options:\n" #~ " -v --version Show program's version number and exit.\n" #~ " -h --help\t Show this help message and exit.\n" #~ " -e --examples\n" #~ "\t\t\t\tShow some %$@#$ examples!\n" #~ " -i Pog --install=Pog\n" #~ "\t\t\t\tInstall the fonts in this Pog to your \n" #~ "\t\t\t\tfonts folder.\n" #~ " -u Pog --uninstall=Pog\n" #~ "\t\t\t\tUninstall the fonts in this Pog.\n" #~ " -l --list\t\n" #~ "\t\t\t\tList the names of all the Pogs.\n" #~ " -s num --size=num\n" #~ "\t\t\t\tSet a new default point size.\n" #~ " -n num --number=num\n" #~ "\t\t\t\tSet a new default for how many fonts \n" #~ "\t\t\t\tto view at one go. Don't overdo this.\n" #~ " -p Pog --purge=Pog\n" #~ "\t\t\t\tPurge the Pog of font files that are no\n" #~ "\t\t\t\tlonger really there.\n" #~ " -c folder --check=folder\n" #~ "\t\t\t\tCheck for bad fonts that crash Fonty.\n" #~ "\t\t\t\tIt will recurse through sub-folders.\n" #~ "\t\t\t\tThis will build a file:\n" #~ "\t\t\t\t~/.fontypython/segfonts\n" #~ "\t\t\t\tAfter using this tool you should be\n" #~ "\t\t\t\table to browse folders that crashed\n" #~ "\t\t\t\tFonty. (The reason it's not done\n" #~ "\t\t\t\tby default is that it's very slow.)\n" #~ "\t\t\t\t* NOTE: The fonts that crash Fonty\n" #~ "\t\t\t\tare probably still perfectly good\n" #~ "\t\t\t\tand can be used in other apps. It's\n" #~ "\t\t\t\tsimply a bug in the library we use to\n" #~ "\t\t\t\taccess fonts that chokes things. This\n" #~ "\t\t\t\twill (hopefully) improve in the future.\n" #~ " -a folder Pog --all folder Pog\n" #~ "\t\t\t\tPuts all fonts in this folder into the Pog.\n" #~ "\t\t\t\tIf the Pog already exists, it will add\n" #~ "\t\t\t\tonly *new* fonts, this means fonts are not\n" #~ "\t\t\t\trepeated in that Pog.\n" #~ " -A folder Pog --all-recurse folder Pog\n" #~ "\t\t\t\tPuts all fonts in this folder and *all*\n" #~ "\t\t\t\tsub-folders into the Pog. Rest same as -a.\n" #~ " -z Pog --zip=Pog\n" #~ "\t\t\t\tAll the fonts inside Pog will be zipped\n" #~ "\t\t\t\tand the zipfile will be named after the Pog.\n" #~ "\t\t\t\tThe file will be placed in the current\n" #~ "\t\t\t\tdirectory.\n" #~ "\t\t\t\t" #~ msgstr "" #~ "Optionen:\n" #~ " -v --version\n" #~ "\tZeige die Versionsnummer und beende.\n" #~ " -h --help\n" #~ "\tZeige diese Hilfe und beende.\n" #~ " -e --examples\n" #~ "\tZeigt weitere Beispiele und Informationen!\n" #~ " -i pog --install pog\n" #~ "\tInstalliere die Schriften in diesem pog in das Schriftenverzeichnis\n" #~ " -u pog --uninstall pog\n" #~ "\tDeinstalliere die Schriften in diesem pog\n" #~ " -l --list\n" #~ "\tDie Namen aller pogs anzeigen\n" #~ " -s num --size=num\n" #~ "\tEine neue Schriftgröße setzen.\n" #~ " -t \"text\" --text=\"text\"\n" #~ "\tNeuen Beispieltext setzen\n" #~ "\tUnbedingt Anführungszeichen verwenden!\n" #~ " -p pog --purge=pog\n" #~ "\tEntfernt Schriften aus dem Pog,\n" #~ "\twenn diese nicht mehr vorhanden sind.\n" #~ " -c folder -check=folder\n" #~ "\tPrüfe auf beschädigte Schriften,\n" #~ "\tdie Fonty Python abstürzen lassen.\n" #~ "\tUnterverzeichnisse werden auch berücksichtigt\n" #~ "\tEs wird eine Datei\n" #~ "\t~/.fontypython/segfonts\n" #~ "\terstellt. Nachdem dieses Kommando benutzt wurde,\n" #~ "\tsollten Verzeichnisse, in denen Fonty Python\n" #~ "\tregelmäßig abstürzt, durchsucht werden können.\n" #~ "\t(Dieser Test wird nicht standardmäßig durchgeführt,\n" #~ "\tweil er sehr langsam ist.)\n" #~ "ANMERKUNG: Die Schriften müssen nicht unbedingt beschädigt sein\n" #~ "und können von anderen Anwendungen verwendet werden.\n" #~ "Es ist ein Fehler in der Bibliothek,\n" #~ "den wir (hoffentlich) bald beheben werden." #, fuzzy #~ msgid "" #~ "%(c)s [OPTIONS] [VIEW] [TARGET]\n" #~ "VIEW : A place where fonts are. (A Pog or a Folder.)\n" #~ "TARGET : A \"Pog\". A place to keep those fonts.\n" #~ "\n" #~ "(\"%(c)s\" on it's own will start the GUI.)\n" #~ "\n" #~ "NB: Try not to use spaces in Pog names. If you must, \n" #~ "then \"quote the name.\"\n" #~ "\n" #~ "Please use -e to see more info.\n" #~ "\n" #~ "NEWS : We now support TTF, OTF, Type1 (PFB, PFA) \n" #~ "and TTC fonts.\n" #~ "\n" #~ "%(version)s\n" #~ "\n" #~ "The basic idea:\n" #~ "===============\n" #~ "Many designers have collections of font files in big\n" #~ "directory structures or on other media. Fonty Python\n" #~ "will let you gather your fonts and structure them\n" #~ "into collections -- or what I call \"Pogs\" -- a place\n" #~ "to keep tyPOGraphy. Well, why not?\n" #~ "\n" #~ "Your fonts never move from where they are\n" #~ "(so don't worry). All that happens is that you select \n" #~ "fonts visually and place their names into a Pog,\n" #~ "then you install or uninstall Pogs as you need them.\n" #~ "No copies of your fonts are made, only links to the\n" #~ "original files are used to install the fonts.\n" #~ "\n" #~ "For example, you might have a Pog called 'logos'\n" #~ "into which you place all the fonts you have of\n" #~ "company logos. After that, when you need to work\n" #~ "with those logos, you simply install the 'logos' Pog\n" #~ "and start your design app!\n" #~ "\n" #~ "FP is also great for just looking at fonts wherever\n" #~ "they are on your computer, without having to install\n" #~ "them system-wide.\n" #~ "\n" #~ "Manage your fonts on Gnu/Linux!\n" #~ "===============================\n" #~ "%(copy)s\n" #~ "\n" #~ "%(warranty)s\n" #~ "\n" #~ "%(contact)s\n" #~ msgstr "" #~ "%(c)s [OPTIONEN] [ANSICHT] [ZIEL]\n" #~ "ANSICHT : Ein Pfad, unter sich Schriften befinden (ein Pog oder Ordner)\n" #~ "ZIEL : Ein \"Pog\". Ein Speicherplatz für solche Schriften.\n" #~ "\n" #~ "(\"%(c)s\" allein startet die GUI.)\n" #~ "\n" #~ "TIPP: Vermeiden Sie Leerzeichen in den Namen. Wenn sie doch nötig sind,\n" #~ "\tsetzen Sie \"den Namen\" in Anführungszeichen.\n" #~ "\n" #~ "Verwenden Sie -e, um weitere Informationen und Beispiele zu sehen.\n" #~ "\n" #~ "NEUIGKEITEN: TTF, OTF, Type1 (PFB, PFA) und TTC Schriften\n" #~ "\twerden jetzt unterstützt.\n" #~ "\n" #~ "%(version)s\n" #~ "\n" #~ "Die Grundidee:\n" #~ "==========\n" #~ "Viele Designer habe ihre Schriftarten in großen Verzeichnisbäumen\n" #~ "oder auf externen Speichern verteilt. Fonty Python gibt die Möglichkeit\n" #~ "die Schriften zu sammeln und in Gruppen zu sortieren -- oder \"Pogs\"\n" #~ "wie ich es nenne -- ein Ort für tyPOGrafie. Also, warum nicht?\n" #~ "\n" #~ "Aber keine Sorge, die Dateistruktur der Schriften wird nie verändert.\n" #~ "Es werden nur die Namen der Schriften mit Hilfe einer grafischen " #~ "Oberfläche\n" #~ "ausgewählt und in einem Pog gespeichert. Danach werden die Schriften je\n" #~ "nach Bedarf installiert oder entfernt, dazu aber nur symbolische " #~ "Verknüpfungen\n" #~ "angelegt, keine Kopien der Schriftdateien.\n" #~ "\n" #~ "Wenn Sie also z.B. ein Pog \"Logos\" angelegt haben, indem alle TrueType-" #~ "Schriften\n" #~ "mit Firmenlogos abgelegt sind, und Sie mit diesen arbeiten wollen, muss " #~ "nur das\n" #~ "Pog \"Logos\" installiert werden, damit diese Schriften allen anderen " #~ "Anwendungen\n" #~ "zur Verfügung stehen.\n" #~ "\n" #~ "Fonty Python eignet sich ebenso gut zum Betrachten aller auf einem " #~ "Computer\n" #~ "vorhandenen Schriften, ohne dass diese systemweit installiert werden " #~ "müssen.\n" #~ "\n" #~ "Verwalte Deine Schriften in GNU/Linux!\n" #~ "========================\n" #~ "%(copy)s\n" #~ "\n" #~ "%(warranty)s\n" #~ "\n" #~ "%(contact)s\n" #~ msgid "&Check fonts" #~ msgstr "Über&prüfe Schriften" #~ msgid "Find those fonts that crash Fonty." #~ msgstr "Folgende gefährliche Schriften wurden gefunden." #~ msgid "" #~ "Your text has been set to \"%s\"\n" #~ "Tip: Did you use quotes to surround your text?\n" #~ "\n" #~ "Please start FontyPython again to see the result." #~ msgstr "" #~ "Der Beispieltext lautet jetzt \"%s\"\n" #~ "Tipp : Wurden Anführungszeichen gesetzt?\n" #~ "\n" #~ "Fonty Python erneut starten, um das Ergebnis zu prüfen." #, fuzzy #~ msgid "Append from Pog %(source)s into Pog %(target)s" #~ msgstr "Erweitere Pog: %(target)s um Pog: %(source)s" #~ msgid "Font causes a segfault. Fix or remove it." #~ msgstr "" #~ "Schrift verursachte einen Fehler. Beheben Sie ihn oder entfernen Sie die " #~ "Schrift." #~ msgid "&File" #~ msgstr "&Datei" #~ msgid "Font cannot be drawn." #~ msgstr "Schrift kann nicht angezeigt werden." #, fuzzy #~ msgid "License" #~ msgstr "Lizenz" #, fuzzy #~ msgid "Sample text" #~ msgstr "Beispieltext:" #, fuzzy #~ msgid "Thin" #~ msgstr "Danke" #, fuzzy #~ msgid "Modern" #~ msgstr "Ordner" #~ msgid "Error creating a wximage of %s" #~ msgstr "Fehler beim Erstellen von wximage %s" #~ msgid "Purges the last selected Pog" #~ msgstr "Bereinigt das zuletzt gewählte Pog" #~ msgid "%s is to be deleted" #~ msgstr "%s ist gelöscht." #, fuzzy #~ msgid "All fonts in a (new) Pog" #~ msgstr "Alle Schriften in ein neues Pog" #~ msgid "" #~ "The Source '%s' seems to be saved in\n" #~ "Pog '%s' before!\n" #~ "\n" #~ "\tContinue anyway?" #~ msgstr "" #~ "Der Ordner '%s` scheint bereits im\n" #~ "Pog '%s' gespeichert worden zu sein.\n" #~ "\n" #~ "\tTrotzdem weiter?" #~ msgid "%s has been installed." #~ msgstr "Pog %s wurde installiert." #~ msgid "%s has been uninstalled." #~ msgstr "Pog %s wurde deinstalliert." #~ msgid "Thanks for trying Fonty Python!" #~ msgstr "Vielen Dank für die Nutzung von Fonty Python!" #~ msgid "" #~ "There's some problem with the font named below.\n" #~ "Please *move* it away somewhere else, or this will keep happening. Start " #~ "Fonty Python again when you are done.\n" #~ msgstr "" #~ "Es gibt Probleme mit den unten genannten Schriften.\n" #~ "Bitte verschieben Sie sie an einen anderen Ort oder dieser Fehler wird " #~ "immer wieder auftreten. Starten Sie Fonty Python neu, nachdem alles " #~ "erledigt ist.\n" #~ msgid "Creates a new pog and puts all fonts into" #~ msgstr "Erstellt ein neues Pog und legt alle Schriften darin ab." fontypython-0.5/fontypythonmodules/pofiles/it_all.merged.po0000664000175000017500000017732613212036005024410 0ustar donndonn00000000000000# Fonty Python. # Copyright (C) 2006,2007,2008 Donn.C.Ingle # This file is distributed under the same license as the Fonty Python package. # msgid "" msgstr "" "Project-Id-Version: Fontypython 0.3.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-06 20:46+0200\n" "PO-Revision-Date: 2009-07-07 12:35+0100\n" "Last-Translator: Pietro Battiston \n" "Language-Team: Italian Translation Project \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Italian\n" "X-Poedit-Country: ITALY\n" #: fontypythonmodules/cli2.py:70 msgid "" "I can't decode your argument(s). Please check your LANG variable. Also, " "don't paste text, type it in." msgstr "" "Impossibile decifrare il/gli argomento/i. Verificare la variabile LANG. " "Attenzione: non incollare testo, ma digitarlo direttamente." #: fontypythonmodules/cli2.py:86 msgid "" "For more help use: \"-h b\" for basic help, \"-h e\" for examples,\n" "or \"-h hush\" for help with hushing fonts." msgstr "" #: fontypythonmodules/cli2.py:197 #, python-format msgid "%s takes two arguments: SOURCE(folder) TARGET(pog)" msgstr "%s richiede due argomenti: SORGENTE(cartella) OBIETTIVO(pog)" #: fontypythonmodules/cli2.py:199 #, fuzzy msgid "" "NB: If you have spaces in the Pog or Folder names, put \"quotes around the " "names.\"" msgstr "" "NB: se si vuole utilizzare degli spazi nel nome di un pog o di una cartella " "è necessario metterlo \"tra virgolette\"." #: fontypythonmodules/cli2.py:234 msgid "Weirdo error. Keep calm and panic." msgstr "" #: fontypythonmodules/cli2.py:296 msgid "unknown, try: {}" msgstr "" #: fontypythonmodules/cli2.py:372 #, fuzzy msgid "" "Please check your arguments, there seem to be too many.\n" "(Remember: it's one pound for a five minute argument, but only eight pounds " "for a course of ten.)\n" "\n" "NB: If you use spaces in a Pog or Folder name then put \"quotes around the " "names.\"" msgstr "" "Per favore controlla gli argomenti, sembrano essere troppi.\n" "(Ricorda: un argomento da cinque minuti viene una sterlina, ma se ne compri " "dieci paghi solo otto sterline.)\n" "\n" "NB: Se il nome di un pog o di una cartella contiene spazi, mettilo \"tra " "virgolette\"." #: fontypythonmodules/cli2.py:405 #, python-format msgid "Sorry, (%s) does not exist. Try --list" msgstr "Spiacente, (%s) non esiste. Prova --list." #: fontypythonmodules/cli2.py:410 msgid "You cannot use a folder as the target argument. Try --help" msgstr "Non puoi utilizzare una cartella come destinazione. Prova --help" #: fontypythonmodules/cli2.py:462 fontypythonmodules/cli2.py:483 #, python-format msgid "" "The target pog (%s) is currently installed, you can't use it as a target." msgstr "" "Il pog destinazione (%s) è attualmente installato, non puoi utilizzarlo come " "destinazione." #: fontypythonmodules/cli2.py:468 msgid "Your pogs are the same! Try -e" msgstr "I pog sono lo stesso! Prova -e" #: fontypythonmodules/cli2.py:475 msgid "This pog is empty" msgstr "Questo pog è vuoto" #: fontypythonmodules/clifuncs.py:27 #, python-format msgid "I can't find %s" msgstr "Impossibile trovare %s" #: fontypythonmodules/clifuncs.py:46 msgid "There are no pogs available." msgstr "Nessun pog disponibile." #: fontypythonmodules/clifuncs.py:48 #, python-format msgid "Listing %d pog(s)" msgstr "Lista di %d pog" #: fontypythonmodules/clifuncs.py:49 msgid " * indicates installed pogs" msgstr "* indica i pog installati" #: fontypythonmodules/clifuncs.py:57 #, python-format msgid "Could not open (%s)." msgstr "Impossibile aprire (%s)." #: fontypythonmodules/clifuncs.py:71 #, fuzzy msgid "Could not ls the font path." msgstr "Impossibile modificare il file di configurazione." #: fontypythonmodules/clifuncs.py:73 msgid "Contents of {}:" msgstr "" #: fontypythonmodules/clifuncs.py:84 #, fuzzy msgid "Could not cat that pog." msgstr "Impossibile modificare il file di configurazione." #: fontypythonmodules/clifuncs.py:127 #, fuzzy msgid "I could not create the zip at all." msgstr "Impossibile modificare il file di configurazione." #: fontypythonmodules/clifuncs.py:130 fontypythonmodules/wxgui.py:679 msgid "Zipped as \"{}.fonts.zip\" in the \"{}\" directory." msgstr "" #: fontypythonmodules/clifuncs.py:132 fontypythonmodules/wxgui.py:682 msgid "Some bugs happened:" msgstr "" #: fontypythonmodules/clifuncs.py:135 #, fuzzy, python-format msgid "I can't find a pog named %s" msgstr "Impossibile trovare %s" #: fontypythonmodules/clifuncs.py:154 fontypythonmodules/clifuncs.py:185 #, python-format msgid "(%s) cannot be found. Try -l to see the names." msgstr "Impossibile trovare (%s). Prova -l per vedere i nomi." #: fontypythonmodules/clifuncs.py:177 fontypythonmodules/fpsys.py:975 #, python-format msgid "Installing (%s)" msgstr "Installo (%s)" #: fontypythonmodules/clifuncs.py:204 #, python-format msgid "Removing (%s)" msgstr "Rimuovo (%s)" #: fontypythonmodules/clifuncs.py:211 #, python-format msgid "Sorry, can't find (%s). Try -l to see the names." msgstr "Spiacente, non trovo (%s). Prova -l per vedere i nomi." #: fontypythonmodules/clifuncs.py:234 #, python-format msgid "Creating a new pog: %s" msgstr "Creo un nuovo pog: %s" #: fontypythonmodules/clifuncs.py:257 #, python-format msgid "I have placed %(count)s fonts from %(folder)s into %(pog)s." msgstr "Ho sistemato %(count)s fonts da %(folder)s in %(pog)s." #: fontypythonmodules/clifuncs.py:259 #, python-format msgid "The fonts from %(folder)s are *already* in %(pog)s." msgstr "I font della cartella %(folder)s sono *già* in %(pog)s." #: fontypythonmodules/fontcontrol.py:146 #, fuzzy msgid "" "Font cannot be found. Purge lost fonts from this Pog.\n" "(See the Tools menu.)" msgstr "Impossibile trovare il font, dovresti ripulire questo pog." #: fontypythonmodules/fontcontrol.py:152 #, fuzzy, python-format msgid "" "Unhandled error:\n" "Please remove (%s) away from here and report this to us." msgstr "" "Errore non gestito:\n" "Per favore sposta (%s) da questa posizione e riporta l'errore ai " "programmatori." #: fontypythonmodules/fontcontrol.py:164 msgid "Font may be bad and it cannot be drawn." msgstr "Il font potrebbe essere corrotto, non è possibile raffigurarlo." #: fontypythonmodules/fontcontrol.py:179 msgid "Unicode problem. Font may be bad and it cannot be drawn." msgstr "" "Problema unicode. Il font potrebbe essere corrotto, non è possibile " "raffigurarlo." #: fontypythonmodules/fontcontrol.py:250 #, fuzzy msgid "Font causes a segfault. It cannot be drawn." msgstr "Il font potrebbe essere corrotto, non è possibile raffigurarlo." #: fontypythonmodules/fontcontrol.py:295 msgid "There are no fonts to see here, move along." msgstr "Qui non c'è nessun font da vedere." #: fontypythonmodules/fontcontrol.py:296 msgid "" "Stuff to check:\n" "\t1) The filters.\n" "\t2) The \"include sub-folders\"\n" "\t\tcheck box (in Settings).\n" "\t3) The Help file." msgstr "" #: fontypythonmodules/fontcontrol.py:823 #, fuzzy, python-format msgid "%s is already installed." msgstr "Pog già installato." #: fontypythonmodules/fontcontrol.py:977 fontypythonmodules/fontcontrol.py:998 msgid "I can't write to this directory: {}" msgstr "" #: fontypythonmodules/fontcontrol.py:1015 msgid "Correcting timestamp on {}." msgstr "" #: fontypythonmodules/fontcontrol.py:1026 msgid "Zip on {} failed because: {}" msgstr "" #: fontypythonmodules/fontybugs.py:37 msgid "" "\n" "(Also check your file permissions.)" msgstr "" "\n" "(Controlla anche i permessi dei file.)" #: fontypythonmodules/fontybugs.py:39 msgid "Bad voodoo error. I give up." msgstr "Errore voodoo maligno. Mi arrendo." #: fontypythonmodules/fontybugs.py:40 msgid "There is no such item." msgstr "Non c'è un tale elemento." #: fontypythonmodules/fontybugs.py:41 msgid "Pog is empty." msgstr "Pog vuoto." #: fontypythonmodules/fontybugs.py:42 msgid "Pog is already installed." msgstr "Pog già installato." #: fontypythonmodules/fontybugs.py:43 #, python-format msgid "" "Pog cannot be written to.\n" "Check your filesystem.%s" msgstr "" "Impossibile modificare il pog.\n" "Controlla il filesystem.%s" #: fontypythonmodules/fontybugs.py:44 msgid "Pog is invalid, please hand-edit it." msgstr "Il pog è invalido, modificalo manualmente." #: fontypythonmodules/fontybugs.py:45 msgid "" "Some fonts did not install.\n" "Perhaps the original fonts folder has moved or been renamed.\n" "You should purge or hand-edit." msgstr "" "Non è stato possibile installare alcuni font.\n" "Probabilmente la cartella di origine dei font è stata rimossa o rinominata.\n" "Doversti epurarli o modificare manualmente il pog." #: fontypythonmodules/fontybugs.py:46 msgid "Pog is not installed." msgstr "Pog non installato." #: fontypythonmodules/fontybugs.py:47 #, python-format msgid "" "Some fonts could not be uninstalled.\n" "Please check your home .fonts (with a dot in front) folder for broken links." "%s" msgstr "" "Impossibile disinstallare alcuni font.\n" "Per favore controlla eventuali link interrotti nella cartella .fonts (con un " "punto all'inizio) all'interno della tua home.%s" #: fontypythonmodules/fontybugs.py:48 #, python-format msgid "Cannot delete the Pog.%s" msgstr "Impossibile cancellare il pog.%s" #: fontypythonmodules/fontybugs.py:49 msgid "" "Not a single font in this pog could be installed.\n" "The original font folder has probably moved or been renamed." msgstr "" "Non è stato possibile installare neanche un font di questo pog.\n" "La cartella di origine dei font è stata probabilmente spostata o rinominata." #: fontypythonmodules/fontybugs.py:50 msgid "" "Not a single font in this pog could be uninstalled.\n" "None of the fonts were in your fonts folder, please check your home .fonts " "(with a dot in front) folder for broken links.\n" "The pog has been marked as \"not installed\"." msgstr "" "Non è stato possibile disinstallare neanche un font di questo pog.\n" "Nessuno di questi font era nella tua cartella dei font, per favore controlla " "eventuali link interrotti nella cartella .fonts (con un punto all'inizio) " "all'interno della tua home.\n" "Il pog è stato segnato come \"non installato\"." #: fontypythonmodules/fontybugs.py:51 msgid "This folder has no fonts in it." msgstr "Questa cartella non contiene alcun font." #: fontypythonmodules/fontybugs.py:157 #, python-brace-format msgid "" "The \"{path}\" directory cannot be created or found.\n" "Fonty cannot run until it exists. Please create it, and start me again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fontypython\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:173 #, python-brace-format msgid "" "WARNING:\n" "The \"{path}\" directory cannot be created or found.\n" "Fonts cannot be installed until it exists. Please create it, and start me " "again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fonts\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:183 msgid "Missing fonts directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:191 #, python-brace-format msgid "" "WARNING:\n" "The fontconfig \"{path}\" directory cannot be created or found.\n" msgstr "" #: fontypythonmodules/fontybugs.py:196 msgid "Missing fontconfig \"{}\" directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:211 #, python-brace-format msgid "" "Failure during upgrade:\n" "{msg}\n" "\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fpsys.py:275 #, python-brace-format msgid "" "Could not move \"{what}\" from \"{src}\" to \"{dest}\"\n" "Please resolve the problem and start me again." msgstr "" #: fontypythonmodules/fpsys.py:294 #, python-brace-format msgid "" "Could not remove the old \"{oldfontydir}\" directory.\n" "Please remove it and start me again." msgstr "" #: fontypythonmodules/fpsys.py:536 msgid "Checking fonts, this could take some time." msgstr "Sto controllando i font: potrebbe prendere un po' di tempo." #: fontypythonmodules/fpsys.py:537 #, python-format msgid "Starting in %s:" msgstr "Parto in %s:" #: fontypythonmodules/fpsys.py:544 #, python-format msgid "Looking in %s..." msgstr "Controllo in %s..." #: fontypythonmodules/fpsys.py:557 msgid " Bad font: {}" msgstr "" #: fontypythonmodules/fpsys.py:581 msgid "" "Bad fonts were found. They have been noted. I will ignore them in future." msgstr "" #: fontypythonmodules/fpsys.py:583 msgid "I could not find any bad fonts." msgstr "Non ho trovato alcun font dannoso." #: fontypythonmodules/fpsys.py:585 msgid "The process is complete." msgstr "Il processo è completo." #: fontypythonmodules/fpsys.py:646 msgid "Jump the lazy dog fox" msgstr "Ma la volpe col suo balzo ha raggiunto il quieto fido" #: fontypythonmodules/fpsys.py:695 msgid "No config file found, creating it with defaults." msgstr "Non ho trovato il file di configurazione, ne ricreo uno standard." #: fontypythonmodules/fpsys.py:727 msgid "" "The fontypython config file is damaged.\n" "Please remove it and start again" msgstr "" "Il file di configurazione fontypython è danneggiato.\n" "Per favore rimuovilo e riprova." #: fontypythonmodules/fpsys.py:769 msgid "Could not write to the config file." msgstr "Impossibile modificare il file di configurazione." #: fontypythonmodules/fpsys.py:914 #, python-format msgid "This font is in %s" msgstr "Questo font è in %s" #: fontypythonmodules/fpsys.py:971 msgid "Trying to hush..." msgstr "" #: fontypythonmodules/fpsys.py:992 msgid "The Pog \"{}\", cannot be found." msgstr "" #: fontypythonmodules/fpsys.py:1012 msgid "Done. A hush settles over your fonts. Go: work in silence." msgstr "" #: fontypythonmodules/fpsys.py:1024 msgid "The hush isn't there. Nothing to do." msgstr "" #: fontypythonmodules/fpsys.py:1028 msgid "Trying to unhush..." msgstr "" #: fontypythonmodules/fpsys.py:1034 msgid "The noise has returned; the hush is gone." msgstr "" #: fontypythonmodules/gui_Fitmap.py:504 #, fuzzy msgid "" "Font causes a memory error, it can't be drawn.\n" "Original error was:\n" "{}" msgstr "Il font causa un errore di memoria, non è possibile raffigurarlo." #: fontypythonmodules/gui_FontSources.py:57 #, fuzzy msgid "Sources: Folders or Pogs" msgstr "Cartella sorgente o pog" #: fontypythonmodules/gui_FontSources.py:161 #, fuzzy msgid "Source Folders" msgstr "Cartella sorgente o pog" #: fontypythonmodules/gui_FontSources.py:162 #, fuzzy msgid "Source Pogs" msgstr "&Epura pog" #: fontypythonmodules/gui_FontView.py:118 msgid "Recent Filters" msgstr "" #: fontypythonmodules/gui_FontView.py:216 msgid "Filter {} fonts" msgstr "" #: fontypythonmodules/gui_FontView.py:237 msgid "Page:" msgstr "" #: fontypythonmodules/gui_FontView.py:505 #, fuzzy msgid "There's nothing much to do." msgstr "Non c'è un tale elemento." #: fontypythonmodules/gui_FontView.py:506 msgid "Choose some fonts" msgstr "Scegli i font" #: fontypythonmodules/gui_FontView.py:525 #, fuzzy, python-brace-format msgid "Remove fonts from {VIEW}" msgstr "Rimuovi i font da %s" #: fontypythonmodules/gui_FontView.py:526 #, fuzzy msgid "You can remove fonts from this source Pog." msgstr "Puoi rimuovere dei font dal pog destinazione." #: fontypythonmodules/gui_FontView.py:532 #, fuzzy, python-brace-format msgid "Put fonts into {TARGET}" msgstr "Metti i font in %s" #: fontypythonmodules/gui_FontView.py:533 #, fuzzy, python-brace-format msgid "You can append fonts to the active target Pog \"{TARGET}\"." msgstr "Puoi aggiungere font al tuo pog destinazione." #: fontypythonmodules/gui_FontView.py:540 #, fuzzy msgid " (and all sub-folders.)" msgstr "Includi sottocartelle." #: fontypythonmodules/gui_FontView.py:544 #, python-brace-format msgid "Viewing source Folder \"{VIEW}\"{{RT}}" msgstr "" #: fontypythonmodules/gui_FontView.py:545 #, python-brace-format msgid "Viewing source Pog \"{VIEW}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:546 msgid "Choose a Source Pog or Folder." msgstr "" #: fontypythonmodules/gui_FontView.py:547 #, fuzzy, python-brace-format msgid "The target Pog \"{TARGET}\" is installed. It can't be changed." msgstr "" "Il pog destinazione (%s) è attualmente installato, non puoi utilizzarlo come " "destinazione." #: fontypythonmodules/gui_FontView.py:555 msgid "There are no fonts in here." msgstr "Non ci sono font qui." #: fontypythonmodules/gui_FontView.py:562 #, python-brace-format msgid "Source is empty. The active target Pog is \"{TARGET}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:576 #, fuzzy, python-brace-format msgid "Viewing (installed Pog) \"{VIEW}\"" msgstr "Visualizzazione del pog (installato): %s" #: fontypythonmodules/gui_FontView.py:577 #, fuzzy msgid "You can't change an installed Pog." msgstr "Non puoi modificare un pog installato." #: fontypythonmodules/gui_FontView.py:581 #, fuzzy, python-brace-format msgid "Viewing (editable Pog) \"{VIEW}\"" msgstr "Visualizzazione del pog (modificabile): %s" #: fontypythonmodules/gui_FontView.py:582 #, fuzzy msgid "There is no active target." msgstr "Non c'è un tale elemento." #: fontypythonmodules/gui_FontView.py:606 #, fuzzy, python-brace-format msgid "Source and Target \"{VIEW}\" are the same." msgstr "Il tuo pog origine e quello destinazione sono lo stesso." #: fontypythonmodules/gui_FontView.py:607 msgid "Clear the target, or choose another Pog." msgstr "" #: fontypythonmodules/gui_FontView.py:692 msgid "FontView state error: Pattern is \"{}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:783 msgid "Selected fonts have been removed." msgstr "I font selezionati sono stati rimossi." #: fontypythonmodules/gui_FontView.py:786 #, fuzzy msgid "There was an error writing the pog to disk. Nothing has been done." msgstr "" "C'è stato un errore nella memorizzazione del file. Non è stato fatto nulla." #: fontypythonmodules/gui_FontView.py:794 #, python-format msgid "Copying fonts from %(source)s to %(target)s" msgstr "Copia di font da %(source)s a %(target)s" #: fontypythonmodules/gui_FontView.py:815 #, python-format msgid "Selected fonts are now in %s." msgstr "I font selezionati sono ora in %s." #: fontypythonmodules/gui_FontView.py:818 msgid "There was an error writing the pog to disk. Nothing has been done" msgstr "" "C'è stato un errore nella memorizzazione del file. Non è stato fatto nulla." #: fontypythonmodules/gui_PogChooser.py:296 #, python-format msgid "(%s) skipped. It's an invalid pog." msgstr "(%s) saltato. È un pog non valido." #: fontypythonmodules/gui_PogChooser.py:305 #, python-format msgid "(%s) skipped. I can't display this name under your locale." msgstr "(%s) skipped. Non riesco a mostrarne il nome con la locale attuale." #: fontypythonmodules/gui_PogTargets.py:53 msgid "Target Pogs" msgstr "Pog destinazione" #: fontypythonmodules/gui_PogTargets.py:68 msgid "Clear selection" msgstr "Deseleziona tutto" #: fontypythonmodules/gui_PogTargets.py:71 #, fuzzy msgid "Deselects any chosen Pogs." msgstr "Deseleziona ogni pog selezionato." #: fontypythonmodules/gui_PogTargets.py:83 #: fontypythonmodules/gui_PogTargets.py:141 msgid "New Pog" msgstr "Nuovo pog" #: fontypythonmodules/gui_PogTargets.py:84 msgid "Creates a new, empty Pog" msgstr "Crea un nuovo pog vuoto" #: fontypythonmodules/gui_PogTargets.py:86 #, fuzzy msgid "Install Pog(s)" msgstr "Installa pog" #: fontypythonmodules/gui_PogTargets.py:87 msgid "" "Installs all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:89 #, fuzzy msgid "Uninstall Pog(s)" msgstr "Disinstalla pog" #: fontypythonmodules/gui_PogTargets.py:90 msgid "" "Uninstalls all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:92 #, fuzzy msgid "Delete Pog(s)" msgstr "Cancella pog" #: fontypythonmodules/gui_PogTargets.py:93 #, fuzzy msgid "Deletes the selected Pog(s)" msgstr "Cancella l'ultimo pog selezionato." #: fontypythonmodules/gui_PogTargets.py:95 #, fuzzy msgid "Zip Pog(s)" msgstr "Disinstalla pog" #: fontypythonmodules/gui_PogTargets.py:96 #, fuzzy msgid "Save a zip file of the selected Pog(s)" msgstr "Rimuovi fantasmi dal pog selezionato." #: fontypythonmodules/gui_PogTargets.py:140 #, fuzzy msgid "Enter a name for the new Pog" msgstr "Inserisci un nome per il nuovo pog" #: fontypythonmodules/gui_PogTargets.py:141 msgid "Fonty Python" msgstr "Fonty Python" #: fontypythonmodules/gui_PogTargets.py:147 msgid "A Pog with no name won't be created, however it was a good try!" msgstr "Buon tentativo... ma non creerò un pog senza nome!" #: fontypythonmodules/gui_PogTargets.py:152 #, python-format msgid "%s already exists." msgstr "%s esiste già." #: fontypythonmodules/gui_PogTargets.py:187 #, fuzzy msgid "" "One or more selected Pogs is installed, fix your selection and try again." msgstr "" "Uno o più dei font selezionati sono installati: modificare la selezione e " "riprovare." #: fontypythonmodules/gui_PogTargets.py:203 #, python-format msgid "Remove %s, are you sure?" msgstr "Sei sicuro di voler cancellare %s?" #: fontypythonmodules/gui_PogTargets.py:204 msgid "Are you sure?" msgstr "Sei sicuro?" #: fontypythonmodules/gui_dismissable_panels.py:102 msgid "Dismiss. ESC key does the same." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:235 msgid "Help! Help! I'm being repressed!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:276 msgid "User Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:285 msgid "Fontconfig" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:286 msgid "No path: Fontconfig is not functioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:311 #, fuzzy msgid "About Fonty" msgstr "Informazioni su Fonty Python" #: fontypythonmodules/gui_dismissable_panels.py:359 msgid "Hushing is on." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:359 #, fuzzy msgid "Un-hush my fonts" msgstr "Scegli i font" #: fontypythonmodules/gui_dismissable_panels.py:360 msgid "Hushing is off." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:360 #, fuzzy msgid "Hush my fonts" msgstr "Scegli i font" #: fontypythonmodules/gui_dismissable_panels.py:361 #, fuzzy msgid "Fonty cannot hush your fonts" msgstr "Fonty Python: porta i tuoi font allo scoperto!" #: fontypythonmodules/gui_dismissable_panels.py:366 msgid "Hush Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:399 msgid "The Hush Pog:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:404 msgid "" "Hushing installs a Pog that you must manage. Make sure it contains a few " "system fonts so that your applications function properly!\n" "Look in /usr/share/fonts for ideas. Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:417 msgid "Current Hush Pog: " msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:423 msgid "Choose your system Pog" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:433 msgid "" "Fontconfig is not properly installed; thus Fonty cannot hush fonts.\n" "Consult your distribution's help, or open a ticket so we can try fix it. " "Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:443 msgid "Progress report:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:515 msgid "None chosen" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:597 msgid "Locate a directory for the zip file(s)" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:645 msgid "Create the zip file" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:672 msgid "" "The zip file(s) will be put into:\n" "{}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:724 msgid "Settings" msgstr "Impostazioni" #: fontypythonmodules/gui_dismissable_panels.py:738 msgid "Sample text:" msgstr "Testo di esempio:" #: fontypythonmodules/gui_dismissable_panels.py:745 msgid "Point size:" msgstr "Dimensione (in punti):" #: fontypythonmodules/gui_dismissable_panels.py:750 msgid "Beware large numbers!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:751 msgid "Page length:" msgstr "Lunghezza della pagina:" #: fontypythonmodules/gui_dismissable_panels.py:755 msgid "Tick to disable" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:757 msgid "Disable top-left correction:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:758 msgid "" "Disabling this speeds-up\n" "font drawing but can\n" "cause bad positioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:769 msgid "Available" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:776 msgid "Choose which app to use as a character map viewer." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:783 msgid "" "None found.\n" "You could install: {}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:786 msgid "Character map viewer:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:796 msgid "Max number of columns:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:797 msgid "" "The font viewing area\n" "will divide into columns\n" "which you can control here." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:803 msgid "" "Tick to include all\n" "sub-folders in\n" "the source view." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:806 msgid "Include sub-folders." msgstr "Includi sottocartelle." #: fontypythonmodules/gui_dismissable_panels.py:807 msgid "" "Caution: This will crash Fonty if\n" "your Source folder (directory)\n" "is deep." msgstr "" #: fontypythonmodules/segwrapfonty.py:87 msgid "Oh boy..." msgstr "O cribbio..." #: fontypythonmodules/segwrapfonty.py:91 msgid "Fonty Python, um ... crashed." msgstr "Fonty Python... ehm... ha crashato." #: fontypythonmodules/segwrapfonty.py:96 msgid "" "There's some problem with the font named below.\n" "You can do one of two things:\n" "1) Manually move this font somewhere else, or\n" "2) Use Fonty's command-line (-c) to mark bad fonts.\n" " See below for help with this.\n" "After you've done these, run me again." msgstr "" #: fontypythonmodules/segwrapfonty.py:102 msgid "The bad font might be:" msgstr "" #: fontypythonmodules/segwrapfonty.py:105 msgid "" "There's no lastFontBeforeSegfault file; I can't really help.\n" "Look at the error (below) for clues." msgstr "" #: fontypythonmodules/segwrapfonty.py:107 msgid "The error was:" msgstr "" #: fontypythonmodules/segwrapfonty.py:118 msgid "The command line to seek and mark bad fonts is:" msgstr "" #: fontypythonmodules/segwrapfonty.py:119 msgid "(Copy the text; open a console; paste and press enter.)" msgstr "" #: fontypythonmodules/segwrapfonty.py:125 msgid "You can get help by opening a ticket on:" msgstr "" #: fontypythonmodules/strings.py:25 #, fuzzy, python-format msgid "Please use a number for argument %s" msgstr "Per favore usa un numero per %s" #: fontypythonmodules/strings.py:31 msgid "Your arguments amuse me :) Please see the help by using -h" msgstr "" #: fontypythonmodules/strings.py:34 #, python-format msgid "Fonty Python version %s" msgstr "Fonty Python, versione %s" #: fontypythonmodules/strings.py:42 msgid "Fonts supported: TTF, OTF, TTC, WOFF, Type1 (PFB, PFA)." msgstr "" #: fontypythonmodules/strings.py:44 #, python-format msgid "" "The basic format is:\n" "%(c)s [OPTIONS] || [VIEW] [TARGET]\n" "\n" "OPTIONS: Various flags for use on the command-line. See \"-h b\" or \"--help " "b\"\n" "for more details. (Long options can use an \"=\" sign or a space: --" "cat=foo \n" "or --cat foo)\n" "\n" "Or:\n" "\n" "Two arguments which will determine what you see in the graphical user " "interface:\n" "VIEW : A place where fonts are. A Pog or a folder where fonts are " "located.\n" "TARGET : A Pog. If this Pog does not exist, it will be created.\n" "\n" "Neither argument is required. When there's only one it's assumed to be a " "VIEW. \n" "When there are two, it's VIEW then TARGET.\n" "\n" "NB: Try not to use spaces in Pog names. If you must, then \"quote the name\"." msgstr "" #: fontypythonmodules/strings.py:66 #, fuzzy msgid "" "Manage your fonts on GNU/Linux\n" "==============================\n" "Many designers have collections of font files on their drives. \n" "Fonty Python will help you gather and structure them into collections \n" "called \"Pogs\" -- a place to keep tyPOGraphy. Well, why not?\n" "\n" "Fonty lets you you select fonts visually and place them into Pogs which " "you \n" "can then install or remove as you require. (Your font files never move \n" "from where they are. Only links are used.)\n" "\n" "Example: You create a \"logos\" Pog where you place logotype fonts.\n" "When you want to use them, simply install the \"logos\" Pog and start your \n" "design app! When you're done, uninstall the \"logos\" Pog; the fonts will \n" "go away.\n" "\n" "Fonty can also \"hush\" unwanted fonts. This hides system fonts, leaving\n" "only those Pogs you want in your apps. The Inkscape font chooser, for \n" "example, is more usable after a hush.\n" "(This is temporary; an \"unhush\" will switch the system fonts on again.)\n" "\n" "Fonty is great for just looking at fonts, wherever they are, without " "having \n" "to install them." msgstr "" "Gestisci i tuoi font su Gnu/Linux.\n" "NOVITÀ: Support font TTF, OTF, Typ1 (PFB, PFA) \n" "e TTC.\n" "\n" "Molti grafici hanno collezioni di file di font in grandi\n" "cartelle su dischi o altri supporti. Fonty Python\n" "permette di raccogliere i font ed organizzarli in\n" "collezioni - chiamate \"pog\" - ovvero luoghi in cui\n" "tenere tiPOGrafia. Logico, no?\n" "\n" "Puoi stare tranquillo che i tuoi font non sono mai\n" " effettivamente spostati. È sufficiente selezionare\n" "dei font ed inserirli in un pog, quindi installare e\n" "disinstallare i pog secondo necessità.\n" "Non viene fatta nessuna copia dei font; per\n" "installare i font vengono utilizzati solo dei\n" "collegamenti.\n" "\n" "Per esempio, puoi creare un pog chiamato \"logo\"\n" "e metterci dentro tutti i file ttf con logo di aziende\n" "che hai. A questo punto, quando devi lavorare con\n" "un logo, è sufficiente installare il pog 'logo' ed\n" "avviare la tua applicazione grafica preferita!\n" "\n" "FP è anche un ottimo strumento per passare in\n" "rassegna i font che ci sono sul computer, senza\n" "dover per forza installarli a livello di sistema.\n" "\t\n" "\t%(copy)s\n" "\t%(contact)s\n" "\t" #: fontypythonmodules/strings.py:90 #, python-format msgid "" "%(yadda)s\n" "Please use -e to see more info.\n" "\n" "%(fonts_supported)s\n" "\n" "%(basic_idea)s" msgstr "" #: fontypythonmodules/strings.py:97 msgid "" "Options:\n" "\n" " -v, --version Show program's version number and exit.\n" " -h b|e|hush, --help b|e|hush\n" " Show a help message and exit.\n" " \"b\" is for basic help.\n" " \"e\" to show some %$@#$ examples!\n" " \"hush\" is for more detail on hushing fonts.\n" " -d, --dir Show the \"fontypython\" path. Add this to your backup " "process!\n" " -i Pog, --install Pog\n" " Install the fonts in this Pog.\n" " -u Pog, --uninstall Pog\n" " Uninstall the fonts in this Pog.\n" " -l, --list\n" " List the names of all your Pogs.\n" " -f, --lsfonts\n" " Lists the contents of your user fonts directory. Here, " "you'll\n" " find the links that Fonty is managing for you.\n" " -s num, --size num\n" " Set a new default point size (you'll see it in the gui).\n" " -n num, --number num\n" " Set a new default for how many fonts to view at one go in " "the gui.\n" " (Don't overdo this.)\n" " -p Pog, --purge Pog\n" " Clean the Pog of fonts that are missing.\n" " -c folder, --check folder\n" " Check for bad fonts that crash Fonty. After using this tool " "you \n" " should be able to use Fonty again.\n" " * NOTE: The fonts that crash Fonty are probably still " "perfectly\n" " useable in other apps. \n" " -a Folder Pog, --all Folder Pog\n" " Puts all fonts in Folder into Pog.\n" " -A Folder Pog, --all-recurse Folder Pog\n" " Puts all fonts in Folder and *all* sub-folders into Pog.\n" " -z Pog, --zip Pog\n" " All the fonts inside Pog will be zipped and the zipfile will " "be \n" " named after the Pog. The file will be placed in the current\n" " directory.\n" " --cat Pog\n" " Cat the Pog. This will list all the fonts within.\n" " --hush HushPog\n" " Hush *all* the fonts except the Pogs you install.\n" "\n" " Uses \"HushPog\", which you create that must contain a few " "system \n" " fonts; in order to supply a basic set to your desktop apps.\n" "\n" " I suggest these from \"/usr/share/fonts\":\n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" " --unhush\n" " Restores all the system fonts after a hush. Leaves your " "special\n" " HushPog installed. It's up to you to manage it.\n" " " msgstr "" #: fontypythonmodules/strings.py:152 #, fuzzy, python-format msgid "" "%(yadda)s\n" "\n" "Examples: All using short options, see -h\n" "=========\n" "%(c)s /path/to/fonts/ttfs/a\n" " This will start off showing the fonts in that path.\n" "\n" "%(c)s /path/to/fonts/ttfs/b Trouser\n" " This will let you view and choose fonts from the path and it will store " "them \n" " in a Pog named Trouser. The Pog will be created if it's not already " "there.\n" "\n" "%(c)s Lumberjack\n" " This will let you see the fonts in the Pog named Lumberjack. You can " "also \n" " uninstall individual fonts by selecting them. A cross will appear " "indicating \n" " the fonts that will be uninstalled.\n" "\n" "%(c)s Camelot Spamalot\n" " This will let you see and choose fonts in Camelot and it will store them \n" " in \"Spamalot\". It lets you copy fonts between Pogs.\n" "\n" "%(c)s -i Cheese\n" " Will install the fonts in Cheese so you can use them in other apps.\n" "\n" "%(c)s -u Trouser\n" " Will uninstall the fonts listed in Trouser.\n" "\n" "%(c)s -s 128\n" " Will set the point size in the gui to 128 - Crazy man!\n" "\n" "%(c)s -n 25\n" " Will show 25 fonts at a time, in the gui. Beware large numbers!\n" "\n" "%(c)s -s 64 -v 10 Pimple\n" " Will set the point size to 64, paging to 10,open the gui and display the " "fonts\n" " in Pimple.\n" "\n" "%(c)s -p Glutton\n" " Purging a font. If there are any fonts in Glutton that are not really on " "your \n" " drive/media anymore (perhaps you deleted them or the cat did) this will " "go \n" " through the Pog and cull them.\n" "\n" "%(c)s -c /some/path/to/fonts\n" " If Fonty keeps crashing on /some/path/to/fonts then you should run a check " "on\n" " that folder. This will mark the dangerous fonts and let you view that " "folder \n" " in the future.\n" "\n" "%(c)s -a /some/path HolyHandGrenade\n" " This will put all the fonts in that path into the Pog called " "HolyHandGrenade.\n" "\n" "%(c)s -A /some/path Tutto\n" " This will do the same as -a: starting in some path, but it will then " "walk \n" " down through *all* sub-folders too. The fonts will be placed in Tutto.\n" "\n" "%(c)s --hush mysysfonts\n" " Will hush (silence) all the fonts in your system except the ones in \n" " \"mysysfonts\" and any other Pogs you have installed. Other apps will \n" " now have fewer fonts to choose from, making life much easier for you.\n" " (Use --unhush later to restore all of them.)\n" "\n" msgstr "" "Il formato base è:\n" "%(c)s [VISTA] [DESTINAZIONE]\n" " VISTA = Un posto in cui ci sono dei font. Può\n" "\t\t essere un pog o una cartella.\n" " DESTINAZIONE = Un pog, ovvero un posto\n" " in cui catalogare dei font.\n" " Se non includi una destinazione, puoi\n" " solo guardare/modificare.\n" "\n" "Suggerimenti:\n" "=====\n" "* Non usare spazi nei nomi dei pog. Se devi proprio,\n" " metti i nomi tra virgolette, es. \"Pog di Ni\"\n" "* Se la tua applicazione grafica (es. The Gimp) non\n" " vede i font che hai installato, riavviala. Talvolta un\n" " sistema necessita di un po' di tempo per riconoscere\n" " tutti i nuovi font nella tua cartella dei font.\n" "\n" "Esempi - principalmente usando le opzioni brevi, vedi -h:\n" "=========\n" "%(c)s /percorso/dei/font/ttf/a\n" " Mostra i font presenti a tale indirizzo.\n" " \n" "%(c)s /percorso/dei/font/ttf/b Pantaloni\n" " Visualizza i font presenti all'indirizzo dato e mettili\n" " in un pog chiamato \"Pantaloni\".\n" " Se il pog non esiste, verrà creato.\n" "\n" "%(c)s Felpe\n" " Questo comando di permette di vedere i font\n" " nel pog chiamato \"Felpe\". Puoi anche\n" " disinstallare individualmente i font selezionandoli.\n" " Comparirà una croce ad indicare i font da\n" " disinstallare.\n" "%(c)s Stelle Stalle\n" " Questo comando permette di vedere e scegliere\n" " i font in \"Stelle\" ed aggiungerli in \"Stalle\".\n" " Si può così copiare font tra i pog.\n" "\n" "%(c)s -i Formaggio\n" " Installa i font del pog Formaggio, così da poterli\n" " utilizzare nelle applicazioni.\n" "\n" "%(c)s -u Pantaloni\n" " Disinstalla i font contenuti nel pog Pantaloni,\n" " rendendoli non utilizzabili nelle altre applicazioni.\n" "\n" "%(c)s -t \"Berlusconi? Quiz, tv, paghe da fame\"\n" " Imposta questo testo come esempio.\n" " Riavvia Fonty per vedere il cambiamento.\n" " * Il testo di esempio si può anche modificare\n" " dall'interfaccia grafica, senza dover riavviare.\n" " \n" "%(c)s -s 128 \n" " Imposta la dimensione a 128 punti (troppo!)\n" "\n" "%(c)s -v 25\n" " Mostra 25 font alla volta. Non esagerare!\n" " \n" "%(c)s -s 64 -v 10 Brufoli\n" " Imposta la dimensione a 64 punti, il numero\n" " di font da visualizzare a 10 e mostra il pog\n" " Brufoli.\n" "\n" "%(c)s -p Ingordo\n" " Se ci sono dei font in Ingordo non più presenti\n" " (perché li hai cancellati, o l'ha fatto il tuo gatto) nei tuoi dischi/" "supporti, rimuovili dal pog.\n" "\n" "%(c)s -c /percorso/per/qualche/font\n" " Se Fonty crasha continuamente in /percorso/per/qualche/font,\n" " dovresti avviare un controllo su quella cartella.\n" " I font maligni verranno così \"contrassegnati\", e la cartella\n" " sarà di nuovo utilizzabile.\n" "\n" "%(c)s -a /un/percorso GranataSacra\n" " Metti tutti i font a quell'indirizzo\n" " nel pog chiamato GranataSacra.\n" "\n" "%(c)s -A /un/indirizzo Tutto\n" " Simile ad -a visto sopra: parti da quell'indirizzo,\n" " ma poi visista ricorsivamente tutte le sottocartelle.\n" " I font saranno messi in Tutto.\n" "\n" "La tua cartella di fontypython è:\n" "%(folder)s\n" "Se vuoi fare un backup dei tuoi pog, li trovi lì.\n" "%(contact)s\n" "\n" "%(copy)s" #: fontypythonmodules/strings.py:213 msgid "" "Your fontypython folder is:\n" "{}" msgstr "" #: fontypythonmodules/strings.py:217 #, fuzzy msgid "Fonty Python - view and manage fonts on Gnu/Linux" msgstr "Fonty Python - visualizza e gestisci ogni tipo di font in Gnu/Linux" #: fontypythonmodules/strings.py:222 #, fuzzy, python-format msgid "" "I cannot find \"python-wxversion\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxversion\n" "I then install it like this:\n" "sudo aptitude install python-wxversion\n" "\n" "If you get long error messages, you will need to\n" "install python-wxgtk*, where the star means the\n" "version number and it should be at least %(wxv)s\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" "Impossibile trovare \"python-wxversion\"\n" "Per favore installa questo pacchetto\n" "NB: utilizza un \"build Unicode\".\n" "\n" "Suggerimento\n" "===\n" "Nella mia distribuzione posso cercarlo così:\n" "aptitude search python-wx\n" "Restituisce vari risultati, tra cui:\n" "python-wxversion \n" "Lo installo quindi così:\n" "sudo aptitude install python-wxversion \n" "\n" "Se ricevi lunghi messaggi di errore, devi installare\n" "python-wxgtk*, dove l'asterisco sta per il numero\n" "di versione e dovrebbe essere almeno 2.6.\n" "Puoi sempre ottenere l'ultima versione qui:\n" "http://wxpython.org/download.php\n" #: fontypythonmodules/strings.py:243 #, fuzzy, python-format msgid "" "I cannot find \"python-wxgtkX.Y\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxgtk%(wxv)s\n" "I then install it like this:\n" "sudo aptitude install python-wxgtk%(wxv)s\n" "\n" "Make sure it's at least version %(wxv)s\n" "**NB** It should not be any version greater\n" "than 3.0\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" "Impossibile trovare \"python-wxgtk\"\n" "Per favore installa questo pacchetto \n" "NB: utilizza un \"build Unicode\".\n" "\n" "Suggerimento\n" "===\n" "Nella mia distribuzione posso cercarlo così:\n" "aptitude search python-wx\n" "Restituisce vari risultati, tra cui:\n" "python-wxgtk2.8\n" "Lo installo quindi così:\n" "sudo aptitude install python-wxgtk2.8\n" "\n" "Assicurati che sia la versione 2.6 o più recente.\n" "\n" "Puoi sempre ottenere l'ultima versione qui:\n" "http://wxwidgets.org/downloads\n" #: fontypythonmodules/strings.py:265 #, fuzzy msgid "" "I cannot find \"python-pil\"\n" "Please install this package.\n" "\n" "NOTE\n" "===\n" "PIL has been forked by Pillow.\n" "The old package was \"python-imaging\",\n" "the new one is \"python-pil\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-pil\n" "This returns many results, one of which is:\n" "python-pil\n" "I then install it like this:\n" "sudo aptitude install python-pil\n" "\n" "Make sure it's at least version 1.1.6-1\n" "\n" "You can also get the latest version from here:\n" "http://www.pythonware.com/products/pil/index.htm\n" msgstr "" "Impossibile trovare \"python-imaging\"\n" "Per favore installa questo pacchetto.\n" "\n" "Suggerimento\n" "===\n" "Nella mia distribuzione posso cercarlo così:\n" "aptitude search python-imaging\n" "Restituisce vari risultati, tra cui:\n" "python-imaging\n" "Lo installo quindi così:\n" "sudo aptitude install python-imaging\n" "\n" "Assicurati che sia la versione 1.1.6-1 o\n" "più recente.\n" "\n" "Puoi sempre ottenere l'ultima versione qui:\n" "http://www.pythonware.com/products/pil/index.htm\n" #: fontypythonmodules/strings.py:290 msgid "" "I cannot find \"Python-gi\"\n" "This package is not required; although if you\n" "have it, modern Linux desktop standards can be\n" "implemented by Fonty.\n" "\n" "TIP\n" "===\n" "Look for \"python-gi\" in your package manager.\n" msgstr "" #: fontypythonmodules/strings.py:318 msgid "" "Hold SHIFT or CTRL as you select Pogs, if you wish to select many at once." msgstr "" #: fontypythonmodules/strings.py:322 msgid "Can't hush because:" msgstr "" #: fontypythonmodules/strings.py:323 msgid "Can't unhush because:" msgstr "" #: fontypythonmodules/strings.py:324 msgid "See --help hush" msgstr "" #: fontypythonmodules/strings.py:325 #, python-brace-format msgid "" "\n" "The idea\n" "========\n" "Often there are too many fonts reported by your system. In your apps, like " "Inkscape,\n" "they clutter the font chooser. This is a way to \"hush\" that, to quieten " "the noise.\n" "\n" "Fonty will install a select Pog of system fonts (which you must pick) and " "then will\n" "reject *all* the system's fonts, leaving only the Pogs which you install.\n" "\n" "This does no damage and you can \"unhush\" at any time to reverse it.\n" "\n" "Hushing\n" "=======\n" "1. Relies on fontconfig, which should be installed on most modern Linux " "desktops.\n" " You can verify if it's there by trying this command:\n" " fc-list\n" "\n" " If that shows no error, you're good.\n" "\n" "2. Fontconfig's user directory:\n" " The path is {{fcpaf}}\n" " Make sure it exists and try fonty again.\n" "\n" "3. System fonts: Put some fonts in a Pog that you must create and choose.\n" " I suggest those in /usr/share/fonts, like: \n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" "\n" "The way it works is that fonty writes an XML file which rejects all fonts " "that \n" "are on the path: \"/usr/share/fonts\"\n" "\n" "This may not work on your particular Linux distribution. Please open a " "ticket\n" "on our site if you have any trouble: {ticket_url}\n" "\n" "To hush, using your special Pog from the command line do this:\n" "{fp} --hush yourpoghere\n" "\n" "To hush from the gui, ...\n" "\n" "Unhushing\n" "=========\n" "To release the hush, use --unhush from the command line or the gui.\n" "\n" "The Pog(s) you installed when you hushed will be left installed. Remove\n" "it/them if you must." msgstr "" #: fontypythonmodules/wxgui.py:124 #, fuzzy, python-format msgid "Welcome to Fonty Python, vers %s" msgstr "Benvenuto in Fonty Python versione %s" #: fontypythonmodules/wxgui.py:181 msgid "&Settings\tCtrl+S" msgstr "Preferen&ze\tCtrl+S" #: fontypythonmodules/wxgui.py:181 msgid "Change settings" msgstr "Cambia le preferenze" #: fontypythonmodules/wxgui.py:187 msgid "&Purge Pog.See TogglePurgeMenuItem for actual string." msgstr "" #: fontypythonmodules/wxgui.py:188 msgid "Remove all ghost fonts from the selected Pog." msgstr "Rimuovi fantasmi dal pog selezionato." #: fontypythonmodules/wxgui.py:194 msgid "&Hush fonts\tCtrl+H" msgstr "" #: fontypythonmodules/wxgui.py:195 msgid "Silence all the noisy system fonts and focus only on those you want," msgstr "" #: fontypythonmodules/wxgui.py:201 msgid "&Exit" msgstr "&Esci" #: fontypythonmodules/wxgui.py:202 msgid "Close the app" msgstr "Chiudi il programma" #: fontypythonmodules/wxgui.py:205 msgid "&Tools" msgstr "" #: fontypythonmodules/wxgui.py:212 msgid "&Select ALL the source fonts" msgstr "&Seleziona TUTTI i font sorgente" #: fontypythonmodules/wxgui.py:213 msgid "Select ABSOLUTELY ALL the fonts in the chosen source." msgstr "Seleziona ASSOLUTAMENTE TUTTI i font nella sorgente scelta." #: fontypythonmodules/wxgui.py:216 msgid "&Clear ENTIRE selection" msgstr "&Ripulisci TUTTA la selezione" #: fontypythonmodules/wxgui.py:217 msgid "Clear the selection completely." msgstr "Ripulisci completamente la selezione." #: fontypythonmodules/wxgui.py:218 msgid "&Selection" msgstr "&Selezione" #: fontypythonmodules/wxgui.py:223 msgid "H&elp\tF1" msgstr "A&iuto\tF1" #: fontypythonmodules/wxgui.py:224 msgid "&About" msgstr "I&nformazioni su..." #: fontypythonmodules/wxgui.py:225 msgid "&Help" msgstr "A&iuto" #: fontypythonmodules/wxgui.py:546 msgid "Warning" msgstr "Attenzione" #: fontypythonmodules/wxgui.py:551 msgid "Error" msgstr "Errore" #: fontypythonmodules/wxgui.py:674 msgid "I could not create the zip for {}" msgstr "" #: fontypythonmodules/wxgui.py:688 msgid "Some fonts were skipped, try purging the Pog(s) involved." msgstr "" #: fontypythonmodules/wxgui.py:689 msgid "Something went wrong." msgstr "" #: fontypythonmodules/wxgui.py:691 fontypythonmodules/wxgui.py:692 #, fuzzy msgid "Zip file(s) have been created." msgstr "I font selezionati sono stati rimossi." #: fontypythonmodules/wxgui.py:752 #, python-format msgid "&Purge \"%s\"\tCtrl+P" msgstr "" #: fontypythonmodules/wxgui.py:754 #, fuzzy msgid "&Purge Pog\tCtrl+P" msgstr "&Epura pog" #: fontypythonmodules/wxgui.py:761 #, python-format msgid "" "Do you want to purge %s?\n" "\n" "Purging means all the fonts in the pog\n" "that are not pointing to actual files\n" "will be removed from this pog." msgstr "" "Vuoi epurare %s?\n" "\n" "Epurare significa che tutti i font del\n" "pog che non puntano a file effettivi\n" "saranno rimossi dal pog." #: fontypythonmodules/wxgui.py:761 msgid "Purge font?" msgstr "Epurare font?" #: fontypythonmodules/wxgui.py:770 #, python-format msgid "%s has not been purged." msgstr "%s non è stato epurato." #: fontypythonmodules/wxgui.py:774 #, python-format msgid "%s has been purged." msgstr "%s è stato epurato." #: fontypythonmodules/wxgui.py:794 msgid "" "I am sorry, but Unicode is not supported by this installation of wxPython. " "Fonty Python relies on Unicode and will simply not work without it.\n" "\n" "Please fetch and install the Unicode version of python-wxgtk." msgstr "" "Spiacente, questa installazione di wxpython non supporta l'Unicode. Fonty " "Python necessità di Unicode e semplicemente non può funzionare senza.\n" "\n" "Per favore procurati ed installa la versione Unicode di python-wxgtk." #: fontypythonmodules/wxgui.py:798 msgid "SORRY: UNICODE MUST BE SUPPORTED" msgstr "SPIACENTE: L'UNICODE DEVE ESSERE SUPPORTATO" #: fontypythonmodules/wxgui.py:811 msgid "FATAL ERROR" msgstr "" #: fontypythonmodules/wxgui.py:909 msgid "Fonty Python: bring out your fonts!" msgstr "Fonty Python: porta i tuoi font allo scoperto!" #~ msgid "Sorry, only Gnu/Linux is supported at the moment." #~ msgstr "Spiacente, al momento sono supportati solo sistemi Gnu/Linux." #~ msgid "" #~ "Please restart Fonty Python after you have moved:\"%s\" to some other " #~ "place." #~ msgstr "" #~ "Per favore sposta:\"%s\" in un'altra posizione e riavvia Fonty Python." #~ msgid "About" #~ msgstr "Informazioni su..." #~ msgid "Thanks" #~ msgstr "Grazie" #~ msgid "Licence" #~ msgstr "Licenza" #, fuzzy #~ msgid "Quick settings" #~ msgstr "Impostazioni" #~ msgid "Oh dear," #~ msgstr "Oh caspita," #, fuzzy #~ msgid "" #~ "There's some problem with the font named below. Please use the Check " #~ "Fonts tool in Fonty\n" #~ "(from the command-line or the Tools menu) to go through this directory " #~ "and mark all the dangerous fonts.\n" #~ "(You could simply move this font elsewhere, but others may remain to " #~ "cause trouble.)\n" #~ msgstr "" #~ "C'è qualche problema con il font riportato sotto. Si prega di utilizzare " #~ "lo strumento \"Controlla font\" in Fonty\n" #~ "(dal terminale o dal menu File) per scorrere la cartella e contrassegnare " #~ "i font dannosi.\n" #~ "(In alternativa, è possibile semplicemente spostare altrove il font, ma " #~ "ne potrebbero rimanere altri problematici.)\n" #~ msgid "Check for dangerous fonts." #~ msgstr "Controllo font dannosi." #~ msgid "Choose a directory and double click it to start" #~ msgstr "Doppio click su una cartella per avviare il controllo" #~ msgid "(Check your filter!)" #~ msgstr "(Controlla il filtro!)" #~ msgid "No supported fonts found there..." #~ msgstr "Nessun font supportato qui..." #~ msgid "This text cannot be drawn. Hey, it happens..." #~ msgstr "Impossibile raffigurare questo testo. Oh, capita..." #~ msgid "Folders" #~ msgstr "Cartelle" #~ msgid "Pogs" #~ msgstr "Pog" #~ msgid "Clear filter" #~ msgstr "Ripulisci filtro" #~ msgid "Filter:" #~ msgstr "Filtro:" #, fuzzy #~ msgid "Your active Target is %s" #~ msgstr "Il tuo attuale pog destinazione è:%s" #~ msgid "Please choose a Source." #~ msgstr "Per favore scegli una sorgente." #~ msgid "Please choose a Pog or a Font folder on the left." #~ msgstr "Per favore scegli un pog o una cartella di font sulla sinistra." #~ msgid "Nothing to do" #~ msgstr "Niente da fare" #, fuzzy #~ msgid "Viewing Folder %s" #~ msgstr "Visualizzazione della cartella:%s" #~ msgid "Viewing a folder." #~ msgstr "Visualizzazione di una cartella." #, fuzzy #~ msgid "Append from %(source)s to %(target)s" #~ msgstr "Aggiungi i font da: %(source)s a:%(target)s" #, fuzzy #~ msgid "Viewing %(source)s, but Pog %(target)s is installed." #~ msgstr "Visualizzando il pog:%(source)s, ma il pog:%(target)s è installato." #~ msgid "These two are the same Pog." #~ msgstr "Questi due pog sono lo stesso." #, fuzzy #~ msgid "Append from %(source)s into %(target)s" #~ msgstr "Aggiungi i font da: %(source)s a:%(target)s" #~ msgid "Install Pog" #~ msgstr "Installa pog" #~ msgid "" #~ "Installs all selected Pogs.\n" #~ "Use SHIFT/CTRL+Click on the list above." #~ msgstr "" #~ "Installa tutti i pog selezionati.\n" #~ "Usa SHIFT/CTRL+Click sulla lista sopra." #~ msgid "" #~ "Uninstalls all selected Pogs.\n" #~ "Use SHIFT/CTRL+Click on the list above." #~ msgstr "" #~ "Disinstalla tutti i pog selezionati.\n" #~ "Usa SHIFT/CTRL+Click sulla lista sopra." #~ msgid "" #~ "\n" #~ "Couldn't make the .fonts folder in %s\n" #~ "Please check your write permissions and try again." #~ msgstr "" #~ "\n" #~ "Impossibile creare la cartella .fonts in %s\n" #~ "Per favore verifica i permessi di scrittura e riprova." #~ msgid "" #~ "\n" #~ "Couldn't make the folder in %s\n" #~ "Please check your write permissions and try again." #~ msgstr "" #~ "\n" #~ "Impossibile creare la cartella in %s\n" #~ "Per favore verifica i permessi di scrittura e riprova." #, fuzzy #~ msgid "" #~ "Options:\n" #~ " -v --version Show program's version number and exit.\n" #~ " -h --help\t Show this help message and exit.\n" #~ " -e --examples\n" #~ "\t\t\t\tShow some %$@#$ examples!\n" #~ " -i Pog --install=Pog\n" #~ "\t\t\t\tInstall the fonts in this Pog to your \n" #~ "\t\t\t\tfonts folder.\n" #~ " -u Pog --uninstall=Pog\n" #~ "\t\t\t\tUninstall the fonts in this Pog.\n" #~ " -l --list\t\n" #~ "\t\t\t\tList the names of all the Pogs.\n" #~ " -s num --size=num\n" #~ "\t\t\t\tSet a new default point size.\n" #~ " -n num --number=num\n" #~ "\t\t\t\tSet a new default for how many fonts \n" #~ "\t\t\t\tto view at one go. Don't overdo this.\n" #~ " -p Pog --purge=Pog\n" #~ "\t\t\t\tPurge the Pog of font files that are no\n" #~ "\t\t\t\tlonger really there.\n" #~ " -c folder --check=folder\n" #~ "\t\t\t\tCheck for bad fonts that crash Fonty.\n" #~ "\t\t\t\tIt will recurse through sub-folders.\n" #~ "\t\t\t\tThis will build a file:\n" #~ "\t\t\t\t~/.fontypython/segfonts\n" #~ "\t\t\t\tAfter using this tool you should be\n" #~ "\t\t\t\table to browse folders that crashed\n" #~ "\t\t\t\tFonty. (The reason it's not done\n" #~ "\t\t\t\tby default is that it's very slow.)\n" #~ "\t\t\t\t* NOTE: The fonts that crash Fonty\n" #~ "\t\t\t\tare probably still perfectly good\n" #~ "\t\t\t\tand can be used in other apps. It's\n" #~ "\t\t\t\tsimply a bug in the library we use to\n" #~ "\t\t\t\taccess fonts that chokes things. This\n" #~ "\t\t\t\twill (hopefully) improve in the future.\n" #~ " -a folder Pog --all folder Pog\n" #~ "\t\t\t\tPuts all fonts in this folder into the Pog.\n" #~ "\t\t\t\tIf the Pog already exists, it will add\n" #~ "\t\t\t\tonly *new* fonts, this means fonts are not\n" #~ "\t\t\t\trepeated in that Pog.\n" #~ " -A folder Pog --all-recurse folder Pog\n" #~ "\t\t\t\tPuts all fonts in this folder and *all*\n" #~ "\t\t\t\tsub-folders into the Pog. Rest same as -a.\n" #~ " -z Pog --zip=Pog\n" #~ "\t\t\t\tAll the fonts inside Pog will be zipped\n" #~ "\t\t\t\tand the zipfile will be named after the Pog.\n" #~ "\t\t\t\tThe file will be placed in the current\n" #~ "\t\t\t\tdirectory.\n" #~ "\t\t\t\t" #~ msgstr "" #~ "Opzioni:\n" #~ " -v --version Scrivi il numero di versione del programma ed esci.\n" #~ " -h --help\t Mostra questo messaggio di aiuto ed esci.\n" #~ " -e --examples\n" #~ "\t\t\t\tMostra qualche %$@#$ di esempio!\n" #~ " -i pog --install=pog\n" #~ "\t\t\t\tInstalla i font in questo pog nella tua cartella font \n" #~ " -u pog --uninstall=pog\n" #~ "\t\t\t\tDisinstalla i font in questo pog.\n" #~ " -l --list\t Elenca i nomi di tutti i pog.\n" #~ " -s num --size=num\n" #~ "\t\t\t\tModifica la dimensione standard, in punti tipografici.\n" #~ " -n num --number=num\n" #~ "\t\t\t\tModifica il numero di font da visualizzare per volta. Non " #~ "esagerare.\n" #~ " -t \"text\" --text=\"testo\"\n" #~ "\t\t\t\tModifica il testo di esempio. \n" #~ "\t\t\t\tTipo \"Questo è un ex-pappagallo!\". \n" #~ "\t\t\t\tAttenzione ad utilizzare le virgolette.\n" #~ " -p pog --purge=pog\n" #~ "\t\t\t\tRipulisci il pog dai file ttf che non ci sono più.\n" #~ " -c folder --check=cartella\n" #~ "\t\t\t\tControlla se ci sono font maligni che fanno crashare Fonty.\n" #~ "\t\t\t\tIl controllo riguarderà anche le sottocartelle.\n" #~ "\t\t\t\tIl risultato sarà un file:\n" #~ "\t\t\t\t~/.fontypython/segfonts\n" #~ "\t\t\t\tDopo avere utilizzato questo strumento, dovresti poter\n" #~ "\t\t\t\tnavigare tra i font che fanno crashare Fonty.\n" #~ "\t\t\t\t(Il processo non è effettuato automaticamente\n" #~ "\t\t\t\tperché è molto lento.)\n" #~ "\t\t\t\t* ATTENZIONE: I font che fanno crashare Fonty\n" #~ "\t\t\t\tsono probabilmente a posto ed utilizzabili\n" #~ "\t\t\t\tin altre applicazioni: è semplicemente un bug\n" #~ "\t\t\t\tnella libreria utilizzata per accedere ai font\n" #~ "\t\t\t\tche causa il problema. Ciò sarà (auspicabilmente)\n" #~ "\t\t\t\trisolto in futuro.\n" #~ " -a cartella pog\n" #~ " --all cartella pog\n" #~ "\t\t\t\tInserisci tutti i font della cartella nel pog.\n" #~ "\t\t\t\tSe il pog esiste già, saranno aggiunti solo i\n" #~ "\t\t\t\t*nuovi* font, ovvero le ripetizioni saranno evitate.\n" #~ " -A cartella pog\n" #~ " --all-recurse cartella pog\n" #~ "\t\t\t\tMette tutti i font nella cartella ed in *tutte*\n" #~ "\t\t\t\tle sottocartelle nel pog. Si veda -a.\n" #~ "\n" #~ "\t\t\t\t" #, fuzzy #~ msgid "" #~ "%(c)s [OPTIONS] [VIEW] [TARGET]\n" #~ "VIEW : A place where fonts are. (A Pog or a Folder.)\n" #~ "TARGET : A \"Pog\". A place to keep those fonts.\n" #~ "\n" #~ "(\"%(c)s\" on it's own will start the GUI.)\n" #~ "\n" #~ "NB: Try not to use spaces in Pog names. If you must, \n" #~ "then \"quote the name.\"\n" #~ "\n" #~ "Please use -e to see more info.\n" #~ "\n" #~ "NEWS : We now support TTF, OTF, Type1 (PFB, PFA) \n" #~ "and TTC fonts.\n" #~ "\n" #~ "%(version)s\n" #~ "\n" #~ "The basic idea:\n" #~ "===============\n" #~ "Many designers have collections of font files in big\n" #~ "directory structures or on other media. Fonty Python\n" #~ "will let you gather your fonts and structure them\n" #~ "into collections -- or what I call \"Pogs\" -- a place\n" #~ "to keep tyPOGraphy. Well, why not?\n" #~ "\n" #~ "Your fonts never move from where they are\n" #~ "(so don't worry). All that happens is that you select \n" #~ "fonts visually and place their names into a Pog,\n" #~ "then you install or uninstall Pogs as you need them.\n" #~ "No copies of your fonts are made, only links to the\n" #~ "original files are used to install the fonts.\n" #~ "\n" #~ "For example, you might have a Pog called 'logos'\n" #~ "into which you place all the fonts you have of\n" #~ "company logos. After that, when you need to work\n" #~ "with those logos, you simply install the 'logos' Pog\n" #~ "and start your design app!\n" #~ "\n" #~ "FP is also great for just looking at fonts wherever\n" #~ "they are on your computer, without having to install\n" #~ "them system-wide.\n" #~ "\n" #~ "Manage your fonts on Gnu/Linux!\n" #~ "===============================\n" #~ "%(copy)s\n" #~ "\n" #~ "%(warranty)s\n" #~ "\n" #~ "%(contact)s\n" #~ msgstr "" #~ "FIXME%(c)s [OPZIONI] [VISTA] [DESTINAZIONE]\n" #~ "VISTA : Posizione in cui ci sono dei font.\n" #~ " (Un pog o una cartella.)\n" #~ "DESTINAZIONE : Un \"pog\". Un luogo dove tenere questi font.\n" #~ "\n" #~ "(\"%(c)s\" da solo avvia l'interfaccia grafica.)\n" #~ "\n" #~ "NB: Cerca di non usare spazi nei nomi di pog.\n" #~ "Se è necessario, \"usa le virgolette\".\n" #~ "\n" #~ "Usa il parametro -e per più informazioni.\n" #~ "\n" #~ "NOVITÀ : Sono oramai supportati font\n" #~ "TTF, OTF, Type1 (PFB, PFM) e TTC.\n" #~ "%(version)s\n" #~ "\n" #~ "Idea base:\n" #~ "===============\n" #~ "Molti grafici hanno collezioni di file di font in grandi\n" #~ "cartelle su dischi o altri supporti. Fonty Python\n" #~ "permette di raccogliere i font ed organizzarli in\n" #~ "collezioni - chiamate \"pog\" - ovvero luoghi in cui\n" #~ "tenere tiPOGrafia. Logico, no?\n" #~ "\n" #~ "Puoi stare tranquillo che i tuoi font non sono mai\n" #~ " effettivamente spostati. È sufficiente selezionare\n" #~ "dei font ed inserirli in un pog, quindi installare e\n" #~ " disinstallare i pog secondo necessità.\n" #~ "Non viene fatta nessuna copia dei font; per\n" #~ "installare i font vengono utilizzati solo dei\n" #~ "collegamenti.\n" #~ "Per esempio, puoi creare un pog chiamato \"logo\"\n" #~ "e metterci dentro tutti i file ttf con logo di aziende\n" #~ "che hai. A questo punto, quando devi lavorare con\n" #~ "un logo, è sufficiente installare il pog 'logo' ed\n" #~ "avviare la tua applicazione grafica preferita!\n" #~ "\n" #~ "FP è anche un ottimo strumento per passare in\n" #~ "rassegna i font che ci sono sul computer, senza\n" #~ "dover per forza installarli a livello di sistema.\n" #~ "\n" #~ "Gestisci i tuoi font in Gnu/Linux!\n" #~ "===============================\n" #~ "%(copy)s\n" #~ "\n" #~ "%(warranty)s\n" #~ "\n" #~ "%(contact)s\n" #~ msgid "&Check fonts" #~ msgstr "&Controllo font" #~ msgid "Find those fonts that crash Fonty." #~ msgstr "Trova i font che crashano Fonty." #~ msgid "" #~ "Your text has been set to \"%s\"\n" #~ "Tip: Did you use quotes to surround your text?\n" #~ "\n" #~ "Please start FontyPython again to see the result." #~ msgstr "" #~ "Il tuo testo è stato impostato a \"%s\"\n" #~ "Consiglio: Hai messo il tuo testo tra virgolette?\n" #~ "\n" #~ "Per favore riavvia Fonty Python per vedere il risultato." #, fuzzy #~ msgid "Append from Pog %(source)s into Pog %(target)s" #~ msgstr "Aggiungi dal pog:%(source)s nel pog:%(target)s" #~ msgid "Font causes a segfault. Fix or remove it." #~ msgstr "Il font causa un segfault. È necessario ripararlo o rimuoverlo." #~ msgid "&File" #~ msgstr "&File" #~ msgid "Font cannot be drawn." #~ msgstr "Impossibile raffigurare il font." #, fuzzy #~ msgid "License" #~ msgstr "Licenza" #, fuzzy #~ msgid "Sample text" #~ msgstr "Testo di esempio:" #, fuzzy #~ msgid "Cove" #~ msgstr "&Chiudi" #, fuzzy #~ msgid "Modern" #~ msgstr "Cartelle" #~ msgid "Error creating a wximage of %s" #~ msgstr "Errore nella creazione di una wximage di %s" #~ msgid "%s is to be deleted" #~ msgstr "%s sta per essere cancellato" #~ msgid "%s has been installed." #~ msgstr "%s installato." #~ msgid "%s has been uninstalled." #~ msgstr "%s disinstallato" #~ msgid "Thanks for trying Fonty Python!" #~ msgstr "Grazie per aver provato Fonty Python!" #~ msgid "" #~ "There's some problem with the font named below.\n" #~ "Please *move* it away somewhere else, or this will keep happening. Start " #~ "Fonty Python again when you are done.\n" #~ msgstr "" #~ "C'è qualche problema con il font sottostante.\n" #~ "Per favore *spostalo* da qualche altra parte, o il problema si ripeterà. " #~ "Riavvia Fonty Python quando hai fatto.\n" #~ msgid "" #~ "Options:\n" #~ " -v Show program's version number and exit.\n" #~ " -h Show this help message and exit.\n" #~ " -e Show some %$@#$ examples!\n" #~ " -i pog Install the fonts in this pog to your \n" #~ " fonts folder.\n" #~ " -u pog Uninstall the fonts in this pog.\n" #~ " -l List the names of all the pogs.\n" #~ " -s num Set a new default point size.\n" #~ " -v num Set a new default for how many fonts \n" #~ " to view at one go. Don't overdo this.\n" #~ " -t \"text\" Set a new default sample text. \n" #~ " \"This is an ex-parrot!\", say. \n" #~ " Be sure to use the quotes.\n" #~ " -p pog Purge the pog of ttf files that are no\n" #~ " longer really there." #~ msgstr "" #~ "Opzioni:\n" #~ " -v Mostra la versione del programma ed esci.\n" #~ " -h Mostra questa pagina di aiuto ed esci.\n" #~ " -e Mostra qualche %$@#$ di esempio!\n" #~ " -i pog Installa nella tua cartella dei font i font\n" #~ " contenuti in questo pog.\n" #~ " -u pog Disinstalla i font in questo pog.\n" #~ " -l Mostra la lista dei nomi di tutti i pog.\n" #~ " -s num Modifica la dimensione di default.\n" #~ " -v num Modifica il numero di font visualizzati\n" #~ " alla volta. Non esagerare.\n" #~ " -t \"testo\" Imposta un nuovo testo di esempio. \n" #~ " Ad esempio: \"Sono un ex-pappagallo!\". \n" #~ " Non dimenticare le virgolette.\n" #~ " -p pog Rimuovi dal pog i file ttf non più presenti." #~ msgid "(%s) skipped" #~ msgstr "salto (%s)" #~ msgid "" #~ "I'm sorry, but something is wrong.\n" #~ "There is no __file__ variable. Please panic." #~ msgstr "" #~ "Spiacente, ma qualcosa non va.\n" #~ "Non c'è alcuna variabile __file__. È il momento del panico." #~ msgid "An appropriate GUI could not be found." #~ msgstr "Impossibile trovare un'interfaccia grafica appropriata." fontypython-0.5/fontypythonmodules/pofiles/fp_all.pot0000664000175000017500000010745713212036003023317 0ustar donndonn00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-06 20:46+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: fontypythonmodules/cli2.py:70 msgid "" "I can't decode your argument(s). Please check your LANG variable. Also, " "don't paste text, type it in." msgstr "" #: fontypythonmodules/cli2.py:86 msgid "" "For more help use: \"-h b\" for basic help, \"-h e\" for examples,\n" "or \"-h hush\" for help with hushing fonts." msgstr "" #: fontypythonmodules/cli2.py:197 #, python-format msgid "%s takes two arguments: SOURCE(folder) TARGET(pog)" msgstr "" #: fontypythonmodules/cli2.py:199 msgid "" "NB: If you have spaces in the Pog or Folder names, put \"quotes around the " "names.\"" msgstr "" #: fontypythonmodules/cli2.py:234 msgid "Weirdo error. Keep calm and panic." msgstr "" #: fontypythonmodules/cli2.py:296 msgid "unknown, try: {}" msgstr "" #: fontypythonmodules/cli2.py:372 msgid "" "Please check your arguments, there seem to be too many.\n" "(Remember: it's one pound for a five minute argument, but only eight pounds " "for a course of ten.)\n" "\n" "NB: If you use spaces in a Pog or Folder name then put \"quotes around the " "names.\"" msgstr "" #: fontypythonmodules/cli2.py:405 #, python-format msgid "Sorry, (%s) does not exist. Try --list" msgstr "" #: fontypythonmodules/cli2.py:410 msgid "You cannot use a folder as the target argument. Try --help" msgstr "" #: fontypythonmodules/cli2.py:462 fontypythonmodules/cli2.py:483 #, python-format msgid "" "The target pog (%s) is currently installed, you can't use it as a target." msgstr "" #: fontypythonmodules/cli2.py:468 msgid "Your pogs are the same! Try -e" msgstr "" #: fontypythonmodules/cli2.py:475 msgid "This pog is empty" msgstr "" #: fontypythonmodules/clifuncs.py:27 #, python-format msgid "I can't find %s" msgstr "" #: fontypythonmodules/clifuncs.py:46 msgid "There are no pogs available." msgstr "" #: fontypythonmodules/clifuncs.py:48 #, python-format msgid "Listing %d pog(s)" msgstr "" #: fontypythonmodules/clifuncs.py:49 msgid " * indicates installed pogs" msgstr "" #: fontypythonmodules/clifuncs.py:57 #, python-format msgid "Could not open (%s)." msgstr "" #: fontypythonmodules/clifuncs.py:71 msgid "Could not ls the font path." msgstr "" #: fontypythonmodules/clifuncs.py:73 msgid "Contents of {}:" msgstr "" #: fontypythonmodules/clifuncs.py:84 msgid "Could not cat that pog." msgstr "" #: fontypythonmodules/clifuncs.py:127 msgid "I could not create the zip at all." msgstr "" #: fontypythonmodules/clifuncs.py:130 fontypythonmodules/wxgui.py:679 msgid "Zipped as \"{}.fonts.zip\" in the \"{}\" directory." msgstr "" #: fontypythonmodules/clifuncs.py:132 fontypythonmodules/wxgui.py:682 msgid "Some bugs happened:" msgstr "" #: fontypythonmodules/clifuncs.py:135 #, python-format msgid "I can't find a pog named %s" msgstr "" #: fontypythonmodules/clifuncs.py:154 fontypythonmodules/clifuncs.py:185 #, python-format msgid "(%s) cannot be found. Try -l to see the names." msgstr "" #: fontypythonmodules/clifuncs.py:177 fontypythonmodules/fpsys.py:975 #, python-format msgid "Installing (%s)" msgstr "" #: fontypythonmodules/clifuncs.py:204 #, python-format msgid "Removing (%s)" msgstr "" #: fontypythonmodules/clifuncs.py:211 #, python-format msgid "Sorry, can't find (%s). Try -l to see the names." msgstr "" #: fontypythonmodules/clifuncs.py:234 #, python-format msgid "Creating a new pog: %s" msgstr "" #: fontypythonmodules/clifuncs.py:257 #, python-format msgid "I have placed %(count)s fonts from %(folder)s into %(pog)s." msgstr "" #: fontypythonmodules/clifuncs.py:259 #, python-format msgid "The fonts from %(folder)s are *already* in %(pog)s." msgstr "" #: fontypythonmodules/fontcontrol.py:146 msgid "" "Font cannot be found. Purge lost fonts from this Pog.\n" "(See the Tools menu.)" msgstr "" #: fontypythonmodules/fontcontrol.py:152 #, python-format msgid "" "Unhandled error:\n" "Please remove (%s) away from here and report this to us." msgstr "" #: fontypythonmodules/fontcontrol.py:164 msgid "Font may be bad and it cannot be drawn." msgstr "" #: fontypythonmodules/fontcontrol.py:179 msgid "Unicode problem. Font may be bad and it cannot be drawn." msgstr "" #: fontypythonmodules/fontcontrol.py:250 msgid "Font causes a segfault. It cannot be drawn." msgstr "" #: fontypythonmodules/fontcontrol.py:295 msgid "There are no fonts to see here, move along." msgstr "" #: fontypythonmodules/fontcontrol.py:296 msgid "" "Stuff to check:\n" "\t1) The filters.\n" "\t2) The \"include sub-folders\"\n" "\t\tcheck box (in Settings).\n" "\t3) The Help file." msgstr "" #: fontypythonmodules/fontcontrol.py:823 #, python-format msgid "%s is already installed." msgstr "" #: fontypythonmodules/fontcontrol.py:977 fontypythonmodules/fontcontrol.py:998 msgid "I can't write to this directory: {}" msgstr "" #: fontypythonmodules/fontcontrol.py:1015 msgid "Correcting timestamp on {}." msgstr "" #: fontypythonmodules/fontcontrol.py:1026 msgid "Zip on {} failed because: {}" msgstr "" #: fontypythonmodules/fontybugs.py:37 msgid "" "\n" "(Also check your file permissions.)" msgstr "" #: fontypythonmodules/fontybugs.py:39 msgid "Bad voodoo error. I give up." msgstr "" #: fontypythonmodules/fontybugs.py:40 msgid "There is no such item." msgstr "" #: fontypythonmodules/fontybugs.py:41 msgid "Pog is empty." msgstr "" #: fontypythonmodules/fontybugs.py:42 msgid "Pog is already installed." msgstr "" #: fontypythonmodules/fontybugs.py:43 #, python-format msgid "" "Pog cannot be written to.\n" "Check your filesystem.%s" msgstr "" #: fontypythonmodules/fontybugs.py:44 msgid "Pog is invalid, please hand-edit it." msgstr "" #: fontypythonmodules/fontybugs.py:45 msgid "" "Some fonts did not install.\n" "Perhaps the original fonts folder has moved or been renamed.\n" "You should purge or hand-edit." msgstr "" #: fontypythonmodules/fontybugs.py:46 msgid "Pog is not installed." msgstr "" #: fontypythonmodules/fontybugs.py:47 #, python-format msgid "" "Some fonts could not be uninstalled.\n" "Please check your home .fonts (with a dot in front) folder for broken links." "%s" msgstr "" #: fontypythonmodules/fontybugs.py:48 #, python-format msgid "Cannot delete the Pog.%s" msgstr "" #: fontypythonmodules/fontybugs.py:49 msgid "" "Not a single font in this pog could be installed.\n" "The original font folder has probably moved or been renamed." msgstr "" #: fontypythonmodules/fontybugs.py:50 msgid "" "Not a single font in this pog could be uninstalled.\n" "None of the fonts were in your fonts folder, please check your home .fonts " "(with a dot in front) folder for broken links.\n" "The pog has been marked as \"not installed\"." msgstr "" #: fontypythonmodules/fontybugs.py:51 msgid "This folder has no fonts in it." msgstr "" #: fontypythonmodules/fontybugs.py:157 #, python-brace-format msgid "" "The \"{path}\" directory cannot be created or found.\n" "Fonty cannot run until it exists. Please create it, and start me again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fontypython\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:173 #, python-brace-format msgid "" "WARNING:\n" "The \"{path}\" directory cannot be created or found.\n" "Fonts cannot be installed until it exists. Please create it, and start me " "again.\n" "Example:\n" "\tcd {subpath}\n" "\tmkdir fonts\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fontybugs.py:183 msgid "Missing fonts directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:191 #, python-brace-format msgid "" "WARNING:\n" "The fontconfig \"{path}\" directory cannot be created or found.\n" msgstr "" #: fontypythonmodules/fontybugs.py:196 msgid "Missing fontconfig \"{}\" directory. See Help." msgstr "" #: fontypythonmodules/fontybugs.py:211 #, python-brace-format msgid "" "Failure during upgrade:\n" "{msg}\n" "\n" "The python error was: {assocerr}\n" "\n" msgstr "" #: fontypythonmodules/fpsys.py:275 #, python-brace-format msgid "" "Could not move \"{what}\" from \"{src}\" to \"{dest}\"\n" "Please resolve the problem and start me again." msgstr "" #: fontypythonmodules/fpsys.py:294 #, python-brace-format msgid "" "Could not remove the old \"{oldfontydir}\" directory.\n" "Please remove it and start me again." msgstr "" #: fontypythonmodules/fpsys.py:536 msgid "Checking fonts, this could take some time." msgstr "" #: fontypythonmodules/fpsys.py:537 #, python-format msgid "Starting in %s:" msgstr "" #: fontypythonmodules/fpsys.py:544 #, python-format msgid "Looking in %s..." msgstr "" #: fontypythonmodules/fpsys.py:557 msgid " Bad font: {}" msgstr "" #: fontypythonmodules/fpsys.py:581 msgid "" "Bad fonts were found. They have been noted. I will ignore them in future." msgstr "" #: fontypythonmodules/fpsys.py:583 msgid "I could not find any bad fonts." msgstr "" #: fontypythonmodules/fpsys.py:585 msgid "The process is complete." msgstr "" #: fontypythonmodules/fpsys.py:646 msgid "Jump the lazy dog fox" msgstr "" #: fontypythonmodules/fpsys.py:695 msgid "No config file found, creating it with defaults." msgstr "" #: fontypythonmodules/fpsys.py:727 msgid "" "The fontypython config file is damaged.\n" "Please remove it and start again" msgstr "" #: fontypythonmodules/fpsys.py:769 msgid "Could not write to the config file." msgstr "" #: fontypythonmodules/fpsys.py:914 #, python-format msgid "This font is in %s" msgstr "" #: fontypythonmodules/fpsys.py:971 msgid "Trying to hush..." msgstr "" #: fontypythonmodules/fpsys.py:992 msgid "The Pog \"{}\", cannot be found." msgstr "" #: fontypythonmodules/fpsys.py:1012 msgid "Done. A hush settles over your fonts. Go: work in silence." msgstr "" #: fontypythonmodules/fpsys.py:1024 msgid "The hush isn't there. Nothing to do." msgstr "" #: fontypythonmodules/fpsys.py:1028 msgid "Trying to unhush..." msgstr "" #: fontypythonmodules/fpsys.py:1034 msgid "The noise has returned; the hush is gone." msgstr "" #: fontypythonmodules/gui_Fitmap.py:504 msgid "" "Font causes a memory error, it can't be drawn.\n" "Original error was:\n" "{}" msgstr "" #: fontypythonmodules/gui_FontSources.py:57 msgid "Sources: Folders or Pogs" msgstr "" #: fontypythonmodules/gui_FontSources.py:161 msgid "Source Folders" msgstr "" #: fontypythonmodules/gui_FontSources.py:162 msgid "Source Pogs" msgstr "" #: fontypythonmodules/gui_FontView.py:118 msgid "Recent Filters" msgstr "" #: fontypythonmodules/gui_FontView.py:216 msgid "Filter {} fonts" msgstr "" #: fontypythonmodules/gui_FontView.py:237 msgid "Page:" msgstr "" #: fontypythonmodules/gui_FontView.py:505 msgid "There's nothing much to do." msgstr "" #: fontypythonmodules/gui_FontView.py:506 msgid "Choose some fonts" msgstr "" #: fontypythonmodules/gui_FontView.py:525 #, python-brace-format msgid "Remove fonts from {VIEW}" msgstr "" #: fontypythonmodules/gui_FontView.py:526 msgid "You can remove fonts from this source Pog." msgstr "" #: fontypythonmodules/gui_FontView.py:532 #, python-brace-format msgid "Put fonts into {TARGET}" msgstr "" #: fontypythonmodules/gui_FontView.py:533 #, python-brace-format msgid "You can append fonts to the active target Pog \"{TARGET}\"." msgstr "" #: fontypythonmodules/gui_FontView.py:540 msgid " (and all sub-folders.)" msgstr "" #: fontypythonmodules/gui_FontView.py:544 #, python-brace-format msgid "Viewing source Folder \"{VIEW}\"{{RT}}" msgstr "" #: fontypythonmodules/gui_FontView.py:545 #, python-brace-format msgid "Viewing source Pog \"{VIEW}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:546 msgid "Choose a Source Pog or Folder." msgstr "" #: fontypythonmodules/gui_FontView.py:547 #, python-brace-format msgid "The target Pog \"{TARGET}\" is installed. It can't be changed." msgstr "" #: fontypythonmodules/gui_FontView.py:555 msgid "There are no fonts in here." msgstr "" #: fontypythonmodules/gui_FontView.py:562 #, python-brace-format msgid "Source is empty. The active target Pog is \"{TARGET}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:576 #, python-brace-format msgid "Viewing (installed Pog) \"{VIEW}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:577 msgid "You can't change an installed Pog." msgstr "" #: fontypythonmodules/gui_FontView.py:581 #, python-brace-format msgid "Viewing (editable Pog) \"{VIEW}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:582 msgid "There is no active target." msgstr "" #: fontypythonmodules/gui_FontView.py:606 #, python-brace-format msgid "Source and Target \"{VIEW}\" are the same." msgstr "" #: fontypythonmodules/gui_FontView.py:607 msgid "Clear the target, or choose another Pog." msgstr "" #: fontypythonmodules/gui_FontView.py:692 msgid "FontView state error: Pattern is \"{}\"" msgstr "" #: fontypythonmodules/gui_FontView.py:783 msgid "Selected fonts have been removed." msgstr "" #: fontypythonmodules/gui_FontView.py:786 msgid "There was an error writing the pog to disk. Nothing has been done." msgstr "" #: fontypythonmodules/gui_FontView.py:794 #, python-format msgid "Copying fonts from %(source)s to %(target)s" msgstr "" #: fontypythonmodules/gui_FontView.py:815 #, python-format msgid "Selected fonts are now in %s." msgstr "" #: fontypythonmodules/gui_FontView.py:818 msgid "There was an error writing the pog to disk. Nothing has been done" msgstr "" #: fontypythonmodules/gui_PogChooser.py:296 #, python-format msgid "(%s) skipped. It's an invalid pog." msgstr "" #: fontypythonmodules/gui_PogChooser.py:305 #, python-format msgid "(%s) skipped. I can't display this name under your locale." msgstr "" #: fontypythonmodules/gui_PogTargets.py:53 msgid "Target Pogs" msgstr "" #: fontypythonmodules/gui_PogTargets.py:68 msgid "Clear selection" msgstr "" #: fontypythonmodules/gui_PogTargets.py:71 msgid "Deselects any chosen Pogs." msgstr "" #: fontypythonmodules/gui_PogTargets.py:83 #: fontypythonmodules/gui_PogTargets.py:141 msgid "New Pog" msgstr "" #: fontypythonmodules/gui_PogTargets.py:84 msgid "Creates a new, empty Pog" msgstr "" #: fontypythonmodules/gui_PogTargets.py:86 msgid "Install Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:87 msgid "" "Installs all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:89 msgid "Uninstall Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:90 msgid "" "Uninstalls all selected Pogs.\n" "{}" msgstr "" #: fontypythonmodules/gui_PogTargets.py:92 msgid "Delete Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:93 msgid "Deletes the selected Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:95 msgid "Zip Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:96 msgid "Save a zip file of the selected Pog(s)" msgstr "" #: fontypythonmodules/gui_PogTargets.py:140 msgid "Enter a name for the new Pog" msgstr "" #: fontypythonmodules/gui_PogTargets.py:141 msgid "Fonty Python" msgstr "" #: fontypythonmodules/gui_PogTargets.py:147 msgid "A Pog with no name won't be created, however it was a good try!" msgstr "" #: fontypythonmodules/gui_PogTargets.py:152 #, python-format msgid "%s already exists." msgstr "" #: fontypythonmodules/gui_PogTargets.py:187 msgid "" "One or more selected Pogs is installed, fix your selection and try again." msgstr "" #: fontypythonmodules/gui_PogTargets.py:203 #, python-format msgid "Remove %s, are you sure?" msgstr "" #: fontypythonmodules/gui_PogTargets.py:204 msgid "Are you sure?" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:102 msgid "Dismiss. ESC key does the same." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:235 msgid "Help! Help! I'm being repressed!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:276 msgid "User Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:285 msgid "Fontconfig" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:286 msgid "No path: Fontconfig is not functioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:311 msgid "About Fonty" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:359 msgid "Hushing is on." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:359 msgid "Un-hush my fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:360 msgid "Hushing is off." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:360 msgid "Hush my fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:361 msgid "Fonty cannot hush your fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:366 msgid "Hush Fonts" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:399 msgid "The Hush Pog:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:404 msgid "" "Hushing installs a Pog that you must manage. Make sure it contains a few " "system fonts so that your applications function properly!\n" "Look in /usr/share/fonts for ideas. Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:417 msgid "Current Hush Pog: " msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:423 msgid "Choose your system Pog" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:433 msgid "" "Fontconfig is not properly installed; thus Fonty cannot hush fonts.\n" "Consult your distribution's help, or open a ticket so we can try fix it. " "Please see help for details." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:443 msgid "Progress report:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:515 msgid "None chosen" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:597 msgid "Locate a directory for the zip file(s)" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:645 msgid "Create the zip file" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:672 msgid "" "The zip file(s) will be put into:\n" "{}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:724 msgid "Settings" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:738 msgid "Sample text:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:745 msgid "Point size:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:750 msgid "Beware large numbers!" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:751 msgid "Page length:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:755 msgid "Tick to disable" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:757 msgid "Disable top-left correction:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:758 msgid "" "Disabling this speeds-up\n" "font drawing but can\n" "cause bad positioning." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:769 msgid "Available" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:776 msgid "Choose which app to use as a character map viewer." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:783 msgid "" "None found.\n" "You could install: {}" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:786 msgid "Character map viewer:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:796 msgid "Max number of columns:" msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:797 msgid "" "The font viewing area\n" "will divide into columns\n" "which you can control here." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:803 msgid "" "Tick to include all\n" "sub-folders in\n" "the source view." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:806 msgid "Include sub-folders." msgstr "" #: fontypythonmodules/gui_dismissable_panels.py:807 msgid "" "Caution: This will crash Fonty if\n" "your Source folder (directory)\n" "is deep." msgstr "" #: fontypythonmodules/segwrapfonty.py:87 msgid "Oh boy..." msgstr "" #: fontypythonmodules/segwrapfonty.py:91 msgid "Fonty Python, um ... crashed." msgstr "" #: fontypythonmodules/segwrapfonty.py:96 msgid "" "There's some problem with the font named below.\n" "You can do one of two things:\n" "1) Manually move this font somewhere else, or\n" "2) Use Fonty's command-line (-c) to mark bad fonts.\n" " See below for help with this.\n" "After you've done these, run me again." msgstr "" #: fontypythonmodules/segwrapfonty.py:102 msgid "The bad font might be:" msgstr "" #: fontypythonmodules/segwrapfonty.py:105 msgid "" "There's no lastFontBeforeSegfault file; I can't really help.\n" "Look at the error (below) for clues." msgstr "" #: fontypythonmodules/segwrapfonty.py:107 msgid "The error was:" msgstr "" #: fontypythonmodules/segwrapfonty.py:118 msgid "The command line to seek and mark bad fonts is:" msgstr "" #: fontypythonmodules/segwrapfonty.py:119 msgid "(Copy the text; open a console; paste and press enter.)" msgstr "" #: fontypythonmodules/segwrapfonty.py:125 msgid "You can get help by opening a ticket on:" msgstr "" #: fontypythonmodules/strings.py:25 #, python-format msgid "Please use a number for argument %s" msgstr "" #: fontypythonmodules/strings.py:31 msgid "Your arguments amuse me :) Please see the help by using -h" msgstr "" #: fontypythonmodules/strings.py:34 #, python-format msgid "Fonty Python version %s" msgstr "" #: fontypythonmodules/strings.py:42 msgid "Fonts supported: TTF, OTF, TTC, WOFF, Type1 (PFB, PFA)." msgstr "" #: fontypythonmodules/strings.py:44 #, python-format msgid "" "The basic format is:\n" "%(c)s [OPTIONS] || [VIEW] [TARGET]\n" "\n" "OPTIONS: Various flags for use on the command-line. See \"-h b\" or \"--help " "b\"\n" "for more details. (Long options can use an \"=\" sign or a space: --" "cat=foo \n" "or --cat foo)\n" "\n" "Or:\n" "\n" "Two arguments which will determine what you see in the graphical user " "interface:\n" "VIEW : A place where fonts are. A Pog or a folder where fonts are " "located.\n" "TARGET : A Pog. If this Pog does not exist, it will be created.\n" "\n" "Neither argument is required. When there's only one it's assumed to be a " "VIEW. \n" "When there are two, it's VIEW then TARGET.\n" "\n" "NB: Try not to use spaces in Pog names. If you must, then \"quote the name\"." msgstr "" #: fontypythonmodules/strings.py:66 msgid "" "Manage your fonts on GNU/Linux\n" "==============================\n" "Many designers have collections of font files on their drives. \n" "Fonty Python will help you gather and structure them into collections \n" "called \"Pogs\" -- a place to keep tyPOGraphy. Well, why not?\n" "\n" "Fonty lets you you select fonts visually and place them into Pogs which " "you \n" "can then install or remove as you require. (Your font files never move \n" "from where they are. Only links are used.)\n" "\n" "Example: You create a \"logos\" Pog where you place logotype fonts.\n" "When you want to use them, simply install the \"logos\" Pog and start your \n" "design app! When you're done, uninstall the \"logos\" Pog; the fonts will \n" "go away.\n" "\n" "Fonty can also \"hush\" unwanted fonts. This hides system fonts, leaving\n" "only those Pogs you want in your apps. The Inkscape font chooser, for \n" "example, is more usable after a hush.\n" "(This is temporary; an \"unhush\" will switch the system fonts on again.)\n" "\n" "Fonty is great for just looking at fonts, wherever they are, without " "having \n" "to install them." msgstr "" #: fontypythonmodules/strings.py:90 #, python-format msgid "" "%(yadda)s\n" "Please use -e to see more info.\n" "\n" "%(fonts_supported)s\n" "\n" "%(basic_idea)s" msgstr "" #: fontypythonmodules/strings.py:97 msgid "" "Options:\n" "\n" " -v, --version Show program's version number and exit.\n" " -h b|e|hush, --help b|e|hush\n" " Show a help message and exit.\n" " \"b\" is for basic help.\n" " \"e\" to show some %$@#$ examples!\n" " \"hush\" is for more detail on hushing fonts.\n" " -d, --dir Show the \"fontypython\" path. Add this to your backup " "process!\n" " -i Pog, --install Pog\n" " Install the fonts in this Pog.\n" " -u Pog, --uninstall Pog\n" " Uninstall the fonts in this Pog.\n" " -l, --list\n" " List the names of all your Pogs.\n" " -f, --lsfonts\n" " Lists the contents of your user fonts directory. Here, " "you'll\n" " find the links that Fonty is managing for you.\n" " -s num, --size num\n" " Set a new default point size (you'll see it in the gui).\n" " -n num, --number num\n" " Set a new default for how many fonts to view at one go in " "the gui.\n" " (Don't overdo this.)\n" " -p Pog, --purge Pog\n" " Clean the Pog of fonts that are missing.\n" " -c folder, --check folder\n" " Check for bad fonts that crash Fonty. After using this tool " "you \n" " should be able to use Fonty again.\n" " * NOTE: The fonts that crash Fonty are probably still " "perfectly\n" " useable in other apps. \n" " -a Folder Pog, --all Folder Pog\n" " Puts all fonts in Folder into Pog.\n" " -A Folder Pog, --all-recurse Folder Pog\n" " Puts all fonts in Folder and *all* sub-folders into Pog.\n" " -z Pog, --zip Pog\n" " All the fonts inside Pog will be zipped and the zipfile will " "be \n" " named after the Pog. The file will be placed in the current\n" " directory.\n" " --cat Pog\n" " Cat the Pog. This will list all the fonts within.\n" " --hush HushPog\n" " Hush *all* the fonts except the Pogs you install.\n" "\n" " Uses \"HushPog\", which you create that must contain a few " "system \n" " fonts; in order to supply a basic set to your desktop apps.\n" "\n" " I suggest these from \"/usr/share/fonts\":\n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" " --unhush\n" " Restores all the system fonts after a hush. Leaves your " "special\n" " HushPog installed. It's up to you to manage it.\n" " " msgstr "" #: fontypythonmodules/strings.py:152 #, python-format msgid "" "%(yadda)s\n" "\n" "Examples: All using short options, see -h\n" "=========\n" "%(c)s /path/to/fonts/ttfs/a\n" " This will start off showing the fonts in that path.\n" "\n" "%(c)s /path/to/fonts/ttfs/b Trouser\n" " This will let you view and choose fonts from the path and it will store " "them \n" " in a Pog named Trouser. The Pog will be created if it's not already " "there.\n" "\n" "%(c)s Lumberjack\n" " This will let you see the fonts in the Pog named Lumberjack. You can " "also \n" " uninstall individual fonts by selecting them. A cross will appear " "indicating \n" " the fonts that will be uninstalled.\n" "\n" "%(c)s Camelot Spamalot\n" " This will let you see and choose fonts in Camelot and it will store them \n" " in \"Spamalot\". It lets you copy fonts between Pogs.\n" "\n" "%(c)s -i Cheese\n" " Will install the fonts in Cheese so you can use them in other apps.\n" "\n" "%(c)s -u Trouser\n" " Will uninstall the fonts listed in Trouser.\n" "\n" "%(c)s -s 128\n" " Will set the point size in the gui to 128 - Crazy man!\n" "\n" "%(c)s -n 25\n" " Will show 25 fonts at a time, in the gui. Beware large numbers!\n" "\n" "%(c)s -s 64 -v 10 Pimple\n" " Will set the point size to 64, paging to 10,open the gui and display the " "fonts\n" " in Pimple.\n" "\n" "%(c)s -p Glutton\n" " Purging a font. If there are any fonts in Glutton that are not really on " "your \n" " drive/media anymore (perhaps you deleted them or the cat did) this will " "go \n" " through the Pog and cull them.\n" "\n" "%(c)s -c /some/path/to/fonts\n" " If Fonty keeps crashing on /some/path/to/fonts then you should run a check " "on\n" " that folder. This will mark the dangerous fonts and let you view that " "folder \n" " in the future.\n" "\n" "%(c)s -a /some/path HolyHandGrenade\n" " This will put all the fonts in that path into the Pog called " "HolyHandGrenade.\n" "\n" "%(c)s -A /some/path Tutto\n" " This will do the same as -a: starting in some path, but it will then " "walk \n" " down through *all* sub-folders too. The fonts will be placed in Tutto.\n" "\n" "%(c)s --hush mysysfonts\n" " Will hush (silence) all the fonts in your system except the ones in \n" " \"mysysfonts\" and any other Pogs you have installed. Other apps will \n" " now have fewer fonts to choose from, making life much easier for you.\n" " (Use --unhush later to restore all of them.)\n" "\n" msgstr "" #: fontypythonmodules/strings.py:213 msgid "" "Your fontypython folder is:\n" "{}" msgstr "" #: fontypythonmodules/strings.py:217 msgid "Fonty Python - view and manage fonts on Gnu/Linux" msgstr "" #: fontypythonmodules/strings.py:222 #, python-format msgid "" "I cannot find \"python-wxversion\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxversion\n" "I then install it like this:\n" "sudo aptitude install python-wxversion\n" "\n" "If you get long error messages, you will need to\n" "install python-wxgtk*, where the star means the\n" "version number and it should be at least %(wxv)s\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" #: fontypythonmodules/strings.py:243 #, python-format msgid "" "I cannot find \"python-wxgtkX.Y\"\n" "Please install this package - NB: ensure that\n" "you use only the \"Unicode build\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-wx\n" "This returns many results, one of which is:\n" "python-wxgtk%(wxv)s\n" "I then install it like this:\n" "sudo aptitude install python-wxgtk%(wxv)s\n" "\n" "Make sure it's at least version %(wxv)s\n" "**NB** It should not be any version greater\n" "than 3.0\n" "\n" "You can also get the latest version from here:\n" "http://wxpython.org/download.php\n" msgstr "" #: fontypythonmodules/strings.py:265 msgid "" "I cannot find \"python-pil\"\n" "Please install this package.\n" "\n" "NOTE\n" "===\n" "PIL has been forked by Pillow.\n" "The old package was \"python-imaging\",\n" "the new one is \"python-pil\".\n" "\n" "TIP\n" "===\n" "On my distro I can search for it like this:\n" "aptitude search python-pil\n" "This returns many results, one of which is:\n" "python-pil\n" "I then install it like this:\n" "sudo aptitude install python-pil\n" "\n" "Make sure it's at least version 1.1.6-1\n" "\n" "You can also get the latest version from here:\n" "http://www.pythonware.com/products/pil/index.htm\n" msgstr "" #: fontypythonmodules/strings.py:290 msgid "" "I cannot find \"Python-gi\"\n" "This package is not required; although if you\n" "have it, modern Linux desktop standards can be\n" "implemented by Fonty.\n" "\n" "TIP\n" "===\n" "Look for \"python-gi\" in your package manager.\n" msgstr "" #: fontypythonmodules/strings.py:318 msgid "" "Hold SHIFT or CTRL as you select Pogs, if you wish to select many at once." msgstr "" #: fontypythonmodules/strings.py:322 msgid "Can't hush because:" msgstr "" #: fontypythonmodules/strings.py:323 msgid "Can't unhush because:" msgstr "" #: fontypythonmodules/strings.py:324 msgid "See --help hush" msgstr "" #: fontypythonmodules/strings.py:325 #, python-brace-format msgid "" "\n" "The idea\n" "========\n" "Often there are too many fonts reported by your system. In your apps, like " "Inkscape,\n" "they clutter the font chooser. This is a way to \"hush\" that, to quieten " "the noise.\n" "\n" "Fonty will install a select Pog of system fonts (which you must pick) and " "then will\n" "reject *all* the system's fonts, leaving only the Pogs which you install.\n" "\n" "This does no damage and you can \"unhush\" at any time to reverse it.\n" "\n" "Hushing\n" "=======\n" "1. Relies on fontconfig, which should be installed on most modern Linux " "desktops.\n" " You can verify if it's there by trying this command:\n" " fc-list\n" "\n" " If that shows no error, you're good.\n" "\n" "2. Fontconfig's user directory:\n" " The path is {{fcpaf}}\n" " Make sure it exists and try fonty again.\n" "\n" "3. System fonts: Put some fonts in a Pog that you must create and choose.\n" " I suggest those in /usr/share/fonts, like: \n" " DejaVu*, Free*, Ubuntu*, Liberation*\n" "\n" "The way it works is that fonty writes an XML file which rejects all fonts " "that \n" "are on the path: \"/usr/share/fonts\"\n" "\n" "This may not work on your particular Linux distribution. Please open a " "ticket\n" "on our site if you have any trouble: {ticket_url}\n" "\n" "To hush, using your special Pog from the command line do this:\n" "{fp} --hush yourpoghere\n" "\n" "To hush from the gui, ...\n" "\n" "Unhushing\n" "=========\n" "To release the hush, use --unhush from the command line or the gui.\n" "\n" "The Pog(s) you installed when you hushed will be left installed. Remove\n" "it/them if you must." msgstr "" #: fontypythonmodules/wxgui.py:124 #, python-format msgid "Welcome to Fonty Python, vers %s" msgstr "" #: fontypythonmodules/wxgui.py:181 msgid "&Settings\tCtrl+S" msgstr "" #: fontypythonmodules/wxgui.py:181 msgid "Change settings" msgstr "" #: fontypythonmodules/wxgui.py:187 msgid "&Purge Pog.See TogglePurgeMenuItem for actual string." msgstr "" #: fontypythonmodules/wxgui.py:188 msgid "Remove all ghost fonts from the selected Pog." msgstr "" #: fontypythonmodules/wxgui.py:194 msgid "&Hush fonts\tCtrl+H" msgstr "" #: fontypythonmodules/wxgui.py:195 msgid "Silence all the noisy system fonts and focus only on those you want," msgstr "" #: fontypythonmodules/wxgui.py:201 msgid "&Exit" msgstr "" #: fontypythonmodules/wxgui.py:202 msgid "Close the app" msgstr "" #: fontypythonmodules/wxgui.py:205 msgid "&Tools" msgstr "" #: fontypythonmodules/wxgui.py:212 msgid "&Select ALL the source fonts" msgstr "" #: fontypythonmodules/wxgui.py:213 msgid "Select ABSOLUTELY ALL the fonts in the chosen source." msgstr "" #: fontypythonmodules/wxgui.py:216 msgid "&Clear ENTIRE selection" msgstr "" #: fontypythonmodules/wxgui.py:217 msgid "Clear the selection completely." msgstr "" #: fontypythonmodules/wxgui.py:218 msgid "&Selection" msgstr "" #: fontypythonmodules/wxgui.py:223 msgid "H&elp\tF1" msgstr "" #: fontypythonmodules/wxgui.py:224 msgid "&About" msgstr "" #: fontypythonmodules/wxgui.py:225 msgid "&Help" msgstr "" #: fontypythonmodules/wxgui.py:546 msgid "Warning" msgstr "" #: fontypythonmodules/wxgui.py:551 msgid "Error" msgstr "" #: fontypythonmodules/wxgui.py:674 msgid "I could not create the zip for {}" msgstr "" #: fontypythonmodules/wxgui.py:688 msgid "Some fonts were skipped, try purging the Pog(s) involved." msgstr "" #: fontypythonmodules/wxgui.py:689 msgid "Something went wrong." msgstr "" #: fontypythonmodules/wxgui.py:691 fontypythonmodules/wxgui.py:692 msgid "Zip file(s) have been created." msgstr "" #: fontypythonmodules/wxgui.py:752 #, python-format msgid "&Purge \"%s\"\tCtrl+P" msgstr "" #: fontypythonmodules/wxgui.py:754 msgid "&Purge Pog\tCtrl+P" msgstr "" #: fontypythonmodules/wxgui.py:761 #, python-format msgid "" "Do you want to purge %s?\n" "\n" "Purging means all the fonts in the pog\n" "that are not pointing to actual files\n" "will be removed from this pog." msgstr "" #: fontypythonmodules/wxgui.py:761 msgid "Purge font?" msgstr "" #: fontypythonmodules/wxgui.py:770 #, python-format msgid "%s has not been purged." msgstr "" #: fontypythonmodules/wxgui.py:774 #, python-format msgid "%s has been purged." msgstr "" #: fontypythonmodules/wxgui.py:794 msgid "" "I am sorry, but Unicode is not supported by this installation of wxPython. " "Fonty Python relies on Unicode and will simply not work without it.\n" "\n" "Please fetch and install the Unicode version of python-wxgtk." msgstr "" #: fontypythonmodules/wxgui.py:798 msgid "SORRY: UNICODE MUST BE SUPPORTED" msgstr "" #: fontypythonmodules/wxgui.py:811 msgid "FATAL ERROR" msgstr "" #: fontypythonmodules/wxgui.py:909 msgid "Fonty Python: bring out your fonts!" msgstr "" fontypython-0.5/fontypythonmodules/cli2.py0000664000175000017500000004133113212036007021070 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import sys, locale, os import strings import fontybugs import fpsys import fontcontrol import clifuncs #Split out the hard work to shorten this file ## replaced optparse with this one because optparse chokes on ## Unicode strings. import getopt class situation(object): """ A class that won't instantiate. It's a small packet of values that are set as-per the command line's arguments. """ version = False help = None ls = False lsfonts = False showdir = False points = None numinpage = None text = None purge = False install = None uninstall = None checkdir = False allfromfolder = None alltargetpog=[] allrecurse = None cat = None hush = False unhush = False zip = None ## If non-ascii chars get entered on the cli, say a Japanese word for ## a pog's name, we may have a problem. ## So, I am going to (try to) decode those byte strings into Unicode first: tmp = [] for a in sys.argv[1:]: ## It seems that a is always a BYTE STRING, but I'll just test anyway: #print [a] if type(a) is str: ## This happens when text is PASTED onto the cli when that cli ## is in a LANG that can't handle that text. ## I don't know what other cases may cause this. try: a = fpsys.LSP.to_unicode( a ) except: print _(u"I can't decode your argument(s). Please check your LANG variable. Also, don't paste text, type it in.") raise SystemExit tmp.append(a) uargs = tmp try: opts, remaining_cli_arguments = getopt.gnu_getopt(uargs, "h:vldfc:i:u:s:n:p:a:A:z:", ["help=", "version", "list", "dir", "lsfonts", "check=","install=", "uninstall=","size=","number=","purge=","all=","all-recurse=","zip=", "cat=", "hush=", "unhush" # these have no short opts. ]) except getopt.GetoptError, err: ## Specific help on the help command if err.opt in ("h", "help"): print strings.use print print _("For more help use: \"-h b\" for basic help, \"-h e\" for examples," \ "\nor \"-h hush\" for help with hushing fonts.") raise SystemExit print strings.arguments_amuse print str(err) # will print something like "option -foob not recognized" raise SystemExit ## A context flag so we can determine which code path is going to be ## command line output, and which is going to be the wxgui. strictly_cli_context_only = False class noarg(Exception): pass def requires_arg(argument): """ The long options like --check come in two shapes: 1. --check blah 2. --check=blah In the 2nd option if you drop the argument, so: --check= .. it is not caught as a missing argument. :| Hence this extra cruft to catch that case. """ if not argument: raise noarg() for option, argument in opts: try: if option in ("-v", "--version"): strictly_cli_context_only = True situation.version = True ## Nov 2017 ## Help gets an argument. elif option in ("-h", "--help"): requires_arg(argument) strictly_cli_context_only = True situation.help = argument ## Checkdir will break the loop, skipping other args. It's a big job. elif option in (u"-c", u"--check"): requires_arg(argument) strictly_cli_context_only = True # Turns-out that "check=" on it's own, sans an argument # does not trigger the error test above. Here's a manual one: situation.checkdir = os.path.abspath( argument ) break elif option in ("-l", "--list"): strictly_cli_context_only = True situation.ls = True elif option in ("-f", "--lsfonts"): strictly_cli_context_only = True situation.lsfonts = True elif option in ("-d", "--dir"): strictly_cli_context_only = True situation.showdir = True elif option in ("-i","--install"): requires_arg(argument) strictly_cli_context_only = True situation.install = [argument] if remaining_cli_arguments: ## Any trailing 'words' are taken to be other pognames ## and added to the list. Valid or not. situation.install += remaining_cli_arguments del remaining_cli_arguments[:] #erase contents, now that they're used. elif option in ("-u", "--uninstall"): requires_arg(argument) strictly_cli_context_only = True situation.uninstall = [argument] if remaining_cli_arguments: ## Same as install. situation.uninstall += remaining_cli_arguments del remaining_cli_arguments[:] elif option in ("-p", "--purge"): requires_arg(argument) strictly_cli_context_only = True situation.purge = argument ## This is for a gui context, hence no strictly_cli_context_only elif option in ("-s", "--size"): try: n = int(argument) except: print strings.please_use_arg % option raise SystemExit situation.points = n ## Also a gui context elif option in ("-n", "--number"): try: n = int(argument) except: print strings.please_use_arg % option raise SystemExit situation.numinpage = n elif option in ("-a", "--all", "-A","--all-recurse"): requires_arg(argument) strictly_cli_context_only = True situation.allfromfolder = argument situation.allrecurse = option in ("-A","--all-recurse") if len(remaining_cli_arguments) != 1: print _("%s takes two arguments: SOURCE(folder) " \ "TARGET(pog)") % option print _("NB: If you have spaces in the Pog or " \ "Folder names, put \"quotes around the " \ "names.\"") raise SystemExit situation.alltargetpog = remaining_cli_arguments[0] del remaining_cli_arguments[:] elif option in ("-z","--zip"): requires_arg(argument) strictly_cli_context_only = True # argument is the Pog name we must zip. # This only does one pog, not several at once. # (due to the limits of gnu_getopt) # TODO Unsure why, exactly. Must recheck.. situation.zip = True situation.pog = argument elif option == "--cat": requires_arg(argument) strictly_cli_context_only = True situation.cat = True situation.pog = argument elif option == "--hush": requires_arg(argument) strictly_cli_context_only = True situation.hush = True situation.pog = argument elif option == "--unhush": strictly_cli_context_only = True situation.unhush = True else: ## We should not reach here at all. print _("Weirdo error. Keep calm and panic.") raise SystemExit # Catch any noargs that were raised. except noarg, e: print strings.arguments_amuse raise SystemExit ##Switch on the cli context if strictly_cli_context_only: ## Probe for any delayed fpsys pathcontrol errors ## As it's CLI-only, we can print errors in the normal way. ## Surviving this test means fpsys.PathControl is in a trusted state ## and can be used without worrying about these kinds of errors. try: fpsys.iPC.probeAllErrors() ## These stop the app. except (fontybugs.NoFontypythonDir, fontybugs.UpgradeFail) as e: e.print_error_and_quit() ## This one is a warning only. except fontybugs.NoFontsDir as e: ## Hushing requires installing a certain POG, hence ## must have fonts dir. if situation.hush: print strings.cant_hush e.print_error() print strings.see_help_hush raise SystemExit e.print_error() except fontybugs.NoFontconfigDir as e: if situation.hush or situation.unhush: ## Hushing requires fontconfig etc. if situation.hush: print strings.cant_hush else: print strings.cant_unhush e.print_error() print strings.see_help_hush raise SystemExit ## don't print any error here. if situation.version: print strings.version elif situation.help: # basics if situation.help == "b": print strings.use print print strings.options # examples elif situation.help == "e": print strings.examples # hushing elif situation.help == "hush": ## Format-in some paths to help user: if fpsys.iPC.user_fontconfig_confd() == "": fcpaf = _("unknown, try: {}").format( os.path.join(fpsys.iPC.home(), ".config/fontconfig/conf.d")) else: fcpaf = fpsys.iPC.user_fontconfig_confd() print strings.hush_howto.format(fcpaf = fcpaf) else: print strings.use print "---" print strings.copy_warranty_contact raise SystemExit elif situation.showdir: ## E.g. of PathControl being trusted: we don't need to test appPath for errors here. print strings.fontyfolder.format(fpsys.LSP.to_unicode(fpsys.iPC.appPath())) ## Check fonts elif situation.checkdir: clifuncs.checkfonts( situation.checkdir ) ## List elif situation.ls: clifuncs.listpogs() ## Sep 2017 elif situation.lsfonts: clifuncs.lsfonts() ## Sep 2009: ZIP elif situation.zip: clifuncs.zip( situation.pog ) ## Purge elif situation.purge: clifuncs.purgepog( situation.purge ) ## Install - .install is actually a list in this case elif situation.install: clifuncs.installpogs( situation.install ) ## Uninstall - ditto elif situation.uninstall: clifuncs.uninstallpogs( situation.uninstall ) ## Install ALL fonts in folder to given pog. ## the def wants: 1=foldername, 2=pogname. 3=recurseflag elif situation.allfromfolder: clifuncs.installall( situation.allfromfolder, situation.alltargetpog, situation.allrecurse ) elif situation.cat: clifuncs.cat( situation.pog ) elif situation.hush: clifuncs.hush_unhush( situation.pog, switch = "hush" ) elif situation.unhush: clifuncs.hush_unhush( None, switch = "unhush" ) ## Arguments for the final, right-hand side, [VIEW] [TARGET] in pure cli ## context has no meaning, so we'll simply ignore them. ## Nothing left for the strictly command line only context to do, so: raise SystemExit ## At this point: ## This is a mixed zone: "fontypython" is being run either from ## the cli or from the gui (via a .desktop file). ## ## All flags that trigger a *strictly_cli_context_only* have been dealt with, this leaves ## only some gui options and the remaining_cli_arguments [VIEW] and/or [TARGET] to handle. ## ## Fonty is: ## 1. Definitely from the cli (e.g. fontypython /fonts BAR) if there ARE remaining_cli_arguments ## 2. Possibly * from an icon (.desktop file), if there ARE NO remaining_cli_arguments. ## ## * It's possible to run "fontypython" naked on the cli, thus I can't make assumptions ## about where Fonty is really coming from. For this reason, I will leave all print ## statements (below) to stdout to cover cli useage. ## If there are many remaining_cli_arguments, it's chaos: if len(remaining_cli_arguments) > 2: ## The user may have chosen a pogname with spaces and no quotes print _("Please check your arguments, there seem to be too many.\n(Remember: it's one pound for a five minute argument, but only eight pounds for a course of ten.)\n\nNB: If you use spaces in a Pog or Folder name then put \"quotes around the names.\"") raise SystemExit ## Args that only have meaning in gui context: ## Size of fonts if situation.points > 0: fpsys.config.points = situation.points ## Number in a page if situation.numinpage > 1: fpsys.config.numinpage = situation.numinpage #### VIEW TARGET tests ## These last tests decide the last two [VIEW][TARGET] arguments on the ## command line. (If there isn't a VIEW, one is faked!) ## If there are no arguments, make one: if not remaining_cli_arguments: lv = fpsys.config.lastview # if it's not a valid folder or pog, make it "EMPTY" if not fpsys.isFolder(lv) and not fpsys.isPog(lv): lv = "EMPTY" # A is: the last pog used (from config) or "EMPTY" A = lv B = None else: ## Get the remaining_cli_arguments into simple vars: A = remaining_cli_arguments[0] B = remaining_cli_arguments[1] if len(remaining_cli_arguments) == 2 else None ## Let's ensure that, should A be a pog, that it's valid: if not fpsys.isFolder(A): # If it's not a pog and it's not "EMPTY",then it's a weirdo. if not fpsys.isPog(A) and A != "EMPTY": print _("Sorry, (%s) does not exist. Try --list") % A raise SystemExit ## Disallow Folder in arg B if B and fpsys.isFolder(B): print _("You cannot use a folder as the target argument. Try --help") raise SystemExit ## Let's ensure that B exists, else we must make it. ## This is because when you call VIEW TARGET and ## TARGET gets created (the file) if it's not there. ##TODO: Why? FIXME if B and not fpsys.isPog(B): ipog = fontcontrol.Pog(B) try: ipog.write() except fontybugs.PogWriteError, e: e.print_error_and_quit() del ipog ## Build the fpsys structure ## Calls to instantiateXYZ are vital. They are where the View or Target Objects get ## generated - i.e. where all their fontItems are built-up. ## One arg: if A and not B: if fpsys.isFolder(A): try: fpsys.instantiateViewFolder(A) # creates a state.viewobject globally. except fontybugs.FolderHasNoFonts, e: e.print_error() ## Let it continue fpsys.config.lastdir = os.path.abspath(A) ## The possible "EMPTY" A is a special case: it's a valid Pog. if fpsys.isPog(A): try: fpsys.instantiateViewPog(A)# creates state.targetobject globally except fontybugs.PogInvalid, e: e.print_error_and_quit() ## Because we are catering for a potential full gui, ## we must make an official "targetobject" set to None fpsys.SetTargetPogToNone() ## Two remaining_cli_arguments: if A and B: if fpsys.isFolder(A)and fpsys.isPog(B): ## "FP" try: fpsys.instantiateViewFolder(A) except fontybugs.FolderHasNoFonts, e: ## Let it continue fpsys.config.lastdir = os.path.abspath(A) try: installed = fpsys.instantiateTargetPog(B) except fontybugs.PogInvalid, e: e.print_error_and_quit() if installed: print _("The target pog (%s) is currently installed, you can't use it as a target.") % B raise SystemExit if fpsys.isPog(A)and fpsys.isPog(B): ## "PP" if A == B: print _("Your pogs are the same! Try -e") raise SystemExit try: empty = fpsys.instantiateViewPog(A) except fontybugs.PogInvalid, e: e.print_error_and_quit() if empty: print _("This pog is empty") raise SystemExit try: installed = fpsys.instantiateTargetPog(B) except fontybugs.PogInvalid, e: e.print_error_and_quit() if installed: print _("The target pog (%s) is currently installed, you can't use it as a target.") % B raise SystemExit ## As we're going to run the wxgui, I will do the pathcontrol ## error probes there, and open msgboxes or something to print the errors. fontypython-0.5/fontypythonmodules/gui_FontView.py0000664000175000017500000007512313211475353022664 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx import wx.lib.stattext import wx.lib.buttons as buttons ## June 25th 2016 ## Remarking these two lines because they are causing a segfault: ## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get(): ## create wxApp before calling this ## Segmentation fault (core dumped) ## ## I do not know how to test or fix this, hence simply removing it. ## AFAICT, stock buttons will be in the system language. ## ## Setup wxPython to access translations : enables the stock buttons. ##langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG ##mylocale = wx.Locale( langid ) from pubsub import * from wxgui import ps from gui_ScrolledFontView import * import fpsys # Global objects import fontyfilter import fontybugs import fpwx class SearchFilter(wx.SearchCtrl): """ Borrowed, as always, from the superb wxPython demo. This new control replaces my old combo box for the filtering of font items. Uses two callbacks. """ max_searches = 25 def __init__(self, parent, id=-1, value="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, search_func = None, cancel_func = None): # wx.TE_PROCESS_ENTER is required for # EVT_TEXT_ENTER event to work. style |= wx.TE_PROCESS_ENTER wx.SearchCtrl.__init__(self, parent, id, value, pos, size, style) self.ShowCancelButton(True) self.SetCancelBitmap(fpwx.wxbmp("clear")) self.Bind(wx.EVT_TEXT_ENTER, self.OnTextEntered) self.Bind(wx.EVT_MENU_RANGE, self.OnMenuItem, id=1, id2=self.max_searches) self.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.on_cancel) ## Callbacks self.do_search_func = search_func self.do_clear_func = cancel_func ## History self.searches = [] def on_cancel(self,e): self.do_clear_func() self.SetValue("") def OnTextEntered(self, evt): if self.do_search_func( self.GetValue() ): self.add_to_history() #self.SetValue("") def set_BIR(self,t): """ When one of the Bold, Italic, Regular are clicked, we call this. """ if t: self.SetValue(t) if t not in self.searches: self.add_to_history() else: self.SetValue("") def add_to_history(self): self.searches.append( self.GetValue() ) if len(self.searches) > self.max_searches: del self.searches[0] self.SetMenu( self.make_new_menu() ) def OnMenuItem(self, evt): text = self.searches[evt.GetId()-1] self.SetValue(text) self.do_search_func(text) def make_new_menu(self): menu = wx.Menu() item = menu.Append(-1, _("Recent Filters")) item.Enable(False) for idx, txt in enumerate(self.searches): menu.Append( 1+idx, txt ) return menu class FontViewPanel(wx.Panel): """ Standalone visual control to select fonts. The Panel that holds the ScrolledFontView control as well as the buttons etc. below and the text above. """ def __init__(self, parent): wx.Panel.__init__(self, parent, id = -1) self.firstrun = True self.pageindex = 1 # I start here self.total_number_of_pages = 0 self.filter = "" self.TICKMAP = None self._TICK = fpwx.wxbmp( 'tick' ) self._CROSS = fpwx.wxbmp( 'cross' ) #Sept 2009 ## Bitmaps to be used in the Fitmap drawing. ## Fetched from there as dict items. It got weird. self.SEGFAULT = fpwx.wxbmp( 'font_segfault' ) self.NO_DRAW = fpwx.wxbmp( 'font_cannot_draw' ) self.NOT_FOUND = fpwx.wxbmp( 'font_not_found' ) self.INFO_ITEM = fpwx.wxbmp( 'font_info_item' ) self.TICKSMALL = fpwx.wxbmp( 'ticksmall' ) self.BUTTON_CHARMAP = fpwx.wxbmp( 'button_charmap' ) self.BUTTON_CHARMAP_OVER = fpwx.wxbmp( 'button_charmap_over' ) ## -- ## Dicts for use in state ## self._setup_state_dicts() ## ## START GUI ## === #icon_open_folder = fpwx.wxbmp("icon_open_folder") #icon_pog = fpwx.wxbmp("pog16x16") #icon_pog_installed = fpwx.wxbmp("pog16x16.installed") ## Sizer: to hold all the others main_view_sizer = wx.BoxSizer( wx.VERTICAL ) ## Sizer: Icon and Main Label icon_and_text_sizer = wx.BoxSizer(wx.HORIZONTAL) ## Sizer: Filter and Pager controls filter_and_pager_sizer = wx.BoxSizer(wx.HORIZONTAL) ## Icon view_icon = fpwx.icon(self, 'icon_viewing') # Main heading self.main_font_info_label = fpwx.h1(self, u"..", ellip = wx.ST_ELLIPSIZE_END, Layout_func = self.Layout ) icon_and_text_sizer.Add(view_icon, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.RIGHT, border = 4) icon_and_text_sizer.Add(self.main_font_info_label, 1, wx.EXPAND | wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, border = 6) ## The status label self.status_text = fpwx.label(self, u"Subinfo", ellip = wx.ST_ELLIPSIZE_END, Layout_func = self.Layout ) ## Quick search Bold Italic Regular buttons ## It occurs to me that these are English words... ## Do fonts contain i18n on styles? ## See: https://fontforge.github.io/fontstyles.html idBold = wx.NewId() idItalic = wx.NewId() self.idRegular = wx.NewId() self.BIR = { idBold : {'style': "bold", 'truth': False, 'instance': None}, idItalic: {'style': "italic", 'truth': False, 'instance': None}, self.idRegular: {'style': "regular", 'truth': False, 'instance': None} } toggle_sizer = wx.BoxSizer(wx.HORIZONTAL) for idy, dic in self.BIR.iteritems(): bBIR = wx.ToggleButton( self, idy, size=(32,-1), style=wx.NO_BORDER ) #Remarked label to show icons instead, label=dic['label']) bBIR.Bind( wx.EVT_TOGGLEBUTTON, self.onBIR ) bmp = fpwx.wxbmp( 'icon_{}'.format(dic['style']) ) bBIR.SetBitmap( bmp ) bBIR.SetToolTipString( _("Filter {} fonts").format(dic['style']) ) self.BIR[idy]['instance'] = bBIR toggle_sizer.Add( bBIR, 1, wx.EXPAND ) filter_and_pager_sizer.Add(toggle_sizer, 1, wx.EXPAND ) # Search box - has two callbacks self.search_filter = SearchFilter(self, search_func = self.do_search, cancel_func = self.on_clear_button_click) self.last_filter_string = "" filter_and_pager_sizer.Add( self.search_filter, 5, wx.ALIGN_LEFT | wx.EXPAND \ | wx.RIGHT, border = 6) ## The pager pulldown pager_label = fpwx.label(self, _(u"Page:")) self.pager_combo = wx.ComboBox(self, -1, value="1", choices=["busy"], style = wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER ) self.pager_combo.Bind(wx.EVT_COMBOBOX, self.onPagechoiceClick ) self.pager_combo.Bind(wx.EVT_TEXT_ENTER, self.onPagerChoiceTextEnter ) filter_and_pager_sizer.Add( pager_label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border = 6 ) filter_and_pager_sizer.Add( self.pager_combo, 1 )#, wx.ALIGN_RIGHT ) ## The SCROLLED FONT VIEW panel: self.scrolledFontView = ScrolledFontView(self) ## Sizer: for buttons prev, main, next bottom_buttons_sizer = wx.BoxSizer(wx.HORIZONTAL) #July 2016 #========= # The stock icon on the button was not showing under gtk3. # This stock button has not been translated into Afrikaans yet. (Dec 2007) # I can't tell you how this fkuced me around! # July 2016 - remarked : self.next_button = wx.Button(self, wx.ID_FORWARD) # I have switched to a bitmapbutton. I hope this works... ### # For future: # example = wx.BitmapButton(self, -1, fpwx.wxbmp( "xxx" ), # style = wx.NO_BORDER) # Previous button #self.previous_button = wx.BitmapButton( self, wx.ID_BACKWARD, # wx.ArtProvider.GetBitmap( # wx.ART_GO_BACK, wx.ART_BUTTON, (32,32) )) self.previous_button = wx.BitmapButton( self, wx.ID_BACKWARD, fpwx.wxbmp( 'icon_prev_page')) # Main button self.button_main = wx.Button(self, label=" ") self.buttMainLastLabel=" " # Next button #self.next_button = wx.BitmapButton( self, wx.ID_FORWARD, # wx.ArtProvider.GetBitmap( # wx.ART_GO_FORWARD, wx.ART_BUTTON, (32,32) )) self.next_button = wx.BitmapButton( self, wx.ID_FORWARD, fpwx.wxbmp( 'icon_next_page')) self.previous_button.Enable( False ) # Starts out disabled bottom_buttons_sizer.Add( self.previous_button, 0, wx.EXPAND | wx.RIGHT, border = 8) bottom_buttons_sizer.Add( self.button_main, 1, wx.EXPAND | wx.RIGHT, border = 8) bottom_buttons_sizer.Add( self.next_button, 0, wx.EXPAND) ## Start at the top: the icon and label main_view_sizer.Add(icon_and_text_sizer, 0, wx.EXPAND ) ## Sub label main_view_sizer.Add(self.status_text, 0, wx.EXPAND | wx.TOP, border = 4) ## Fill the Choice and Filter main_view_sizer.Add(filter_and_pager_sizer, 0, wx.EXPAND | wx.TOP, border = 8 ) ## Fill the SIZER FOR THE SCROLLED FONT VIEW main_view_sizer.Add(self.scrolledFontView, 1, wx.EXPAND | wx.TOP, border = 8 ) ## Fill the bottom buttons main_view_sizer.Add(bottom_buttons_sizer, 0, wx.EXPAND | wx.TOP, border = 10) ## Do the voodoo thang self.SetSizer(main_view_sizer) ## This Fit is NB. It sets the width ## for all panels to come. ## Remove it and the various AutoWrapStaticText ## objects fail hard. self.Fit() ## Bind events self.previous_button.Bind(wx.EVT_BUTTON, self.navClick) self.next_button.Bind(wx.EVT_BUTTON, self.navClick) self.Bind(wx.EVT_BUTTON, self.onMainClick, self.button_main)#.GetId() ) ## Advertise some local functions: ps.sub( left_or_right_key_pressed, self.OnLeftOrRightKey ) ##DND: class FontViewPanel ps.sub( toggle_main_button, self.ToggleMainButton ) ##DND: Called in gui_Fitmap ps.sub( update_font_view, self.MainFontViewUpdate ) ##DND: class FontViewPanel ps.sub( reset_to_page_one, self.ResetToPageOne ) ##DND: class FontViewPanel # Tried to implement wrapping on some of the labels. # It flickers and fails. Fuck it. #def on_evt_size(self,e): #w = e.GetSize()[0] #w = max(w+5,200) #self.status_text.Wrap(w) # e.Skip() def on_clear_button_click( self):#, event ): self.filter = "" # Clear the BIR toggle buttons self.setAllBIRFalse() ## Now command a change of the view. ## First, return user to page 1: self.pageindex = 1 self.filterAndPageThenCallCreateFitmaps() # A GTK bug demands this move. Restore the ESC key func. self.button_main.SetFocus() def setOneBIR( self, idy, truth ): self.BIR[idy]['truth'] = truth self.BIR[idy]['instance'].SetValue( truth ) def setAllBIRFalse( self ): for idy in self.BIR.keys(): self.setOneBIR( idy, False ) def onBIR( self, e ): idy=e.GetId() toggstate = self.BIR[idy]['instance'].GetValue() self.BIR[idy]['truth'] = toggstate ss="" if self.BIR[idy]['style'] == "regular": # only if this is toggle on, do we want # action anything: if toggstate is True: # can't have regular with bold/italic self.setAllBIRFalse() # switch all off self.setOneBIR( idy, True ) ss = "regular|normal" else: self.setOneBIR( self.idRegular, False ) for idy, dic in self.BIR.iteritems(): # Builds AND regex (space is and) if dic['truth']: ss += "%s%s" % (dic['style']," ") ss = ss[:-1] # Go alter the search text box self.search_filter.set_BIR(ss) # Start the process self.startSearch( ss ) def do_search(self, sstring): """ SearchFilter control will call this with sstring being the filter term. """ self.startSearch(sstring) self.button_main.SetFocus() return True # to store in history def startSearch(self, terms): self.filter = terms ## First, return user to page 1: self.pageindex = 1 ## Now command a change of the view. self.filterAndPageThenCallCreateFitmaps() def filterAndPageThenCallCreateFitmaps(self): """ Figure out what list of fonts to draw, divide them into pages, then go make Fitmaps out of them. """ self.total_number_of_pages = 1 # A default ## Is there anything there to view? if len(fpsys.state.viewobject) > 0: ## JUNE 2009 : Changes made ## If the filter string changed from last time, signal so. filter_changed = False if self.filter != self.last_filter_string: filter_changed = True self.last_filter_string = self.filter ## If the filter did change OR we have a blank ## filteredViewObject, then make a new one. if not fpsys.state.filteredViewObject or filter_changed: fpsys.state.filteredViewObject = fontyfilter.doFilter( self.filter ) # Uses the external module to filter. ## STEP 2 : Figure out how many pages we have to display current_page = self.pageindex - 1 num_in_one_page = fpsys.config.numinpage total_num_fonts = len(fpsys.state.filteredViewObject) ## Many thanks to Michael Hoeft for this fix! I suck at math :) # I miss the right words to explain this step, therefore an example: # 23 / 10 = 2 # 23 % 10 = 3 > modulo > bool(3) = True = 1 # ----------------------------------------- # 2 + 1 = 3 > 3 pages # # 40 / 10 = 4 # 40 % 10 = 0 > modulo > bool(0) = False = 0 # ------------------------------------------ # 4 + 0 = 4 > 4 pages self.total_number_of_pages = (total_num_fonts / num_in_one_page) \ + bool(total_num_fonts % num_in_one_page) #leaf thru the pages to the one we are on now. start = current_page * num_in_one_page fin = start + num_in_one_page # Make sure we don't overshoot. if fin > len(fpsys.state.filteredViewObject): fin = len(fpsys.state.filteredViewObject) ## Extract a single page of fonts to display sublist = fpsys.state.filteredViewObject[start:fin] ## Empty the choice control. self.pager_combo.Clear() ## Now refill it [self.pager_combo.Append(str(n)) for n in xrange(1, self.total_number_of_pages +1)] self.pager_combo.SetSelection(self.pageindex-1) #self.choiceSlider.SetRange(1,self.total_number_of_pages+1) ## The viewobject is empty anyway. else: sublist = [] if self.total_number_of_pages == 1: self.pager_combo.Enable(False) else: self.pager_combo.Enable(True) # Tell my child to draw the fonts self.scrolledFontView.MinimalCreateFitmaps( sublist ) self.EnableDisablePrevNext() def _setup_state_dicts(self): """ These dicts are used in MainFontViewUpdate. They hold the variables and such for various states of the app i.t.o Source/View and Target. """ # Some common strings nadatd = _("There's nothing much to do.") ntd = _("Choose some fonts") # The "nothing add remove samepogs" dict # Will be used in the main dict below. n_a_r_s = { 'n' : { #Nothing 'btext': ntd, 'action': "NOTHING_TO_DO", 'info': nadatd, 'cantick': False, 'tmap': self._TICK #default, but is not drawn. }, 's' : { #Same 'btext': ntd, 'action': "NOTHING_TO_DO", 'info': nadatd, 'cantick': False, 'tmap': self._TICK }, '-' : { #Remove 'btext': _("Remove fonts from {VIEW}"), 'info': _("You can remove fonts from this source Pog."), 'action': "REMOVE", 'cantick': True, 'tmap': self._CROSS }, '+' : { #Append 'btext': _("Put fonts into {TARGET}"), 'info': _("You can append fonts to the active target Pog \"{TARGET}\"."), 'action': "APPEND", 'cantick': True, 'tmap': self._TICK }} # A way to test for recurse flag later recurse_test = lambda: _(" (and all sub-folders.)") \ if fpsys.config.recurseFolders else "" # Some common strings vF = _("Viewing source Folder \"{VIEW}\"{{RT}}") vP =_("Viewing source Pog \"{VIEW}\"") choose_source = _("Choose a Source Pog or Folder.") nochangetarget = _("The target Pog \"{TARGET}\" is installed. "\ "It can't be changed.") # The main "label" dict. # See remarks in MainFontViewUpdate for details. self.lbl_d = { ## Empty to Nothing 'EN' : { 'lab': _("There are no fonts in here."), 'tip': choose_source, 'nars': n_a_r_s['n'] }, ## Empty to Pog 'EP' : { 'lab': _("Source is empty. The active target Pog is \"{TARGET}\""), 'tip': choose_source, 'nars': n_a_r_s['n'] }, ## Folder to Nothing 'FN' : { 'lab': vF, 'nars': n_a_r_s['n'], 'rtest': recurse_test }, ## Pog to Nothing 'PrN': { 'lab': _("Viewing (installed Pog) \"{VIEW}\""), 'tip': _("You can't change an installed Pog."), 'nars': n_a_r_s['n'] }, 'PwN': { # '-' Remove from source pog 'lab': _("Viewing (editable Pog) \"{VIEW}\""), 'tip': _("There is no active target."), 'nars': n_a_r_s['-'] }, ## Folder to Pog 'FPr': { 'lab': vF, 'tip': nochangetarget, 'nars': n_a_r_s['n'], 'rtest': recurse_test, }, 'FPw': { # Add to target Pog 'lab': vF, 'nars': n_a_r_s['+'], 'rtest': recurse_test, }, ## Pog to Pog 'PPr': { 'lab': vP, 'tip': nochangetarget, 'nars': n_a_r_s['n'], }, 'PPs': { 'lab': _("Source and Target \"{VIEW}\" are the same."), 'tip': _("Clear the target, or choose another Pog."), 'nars': n_a_r_s['s'], }, 'PPw': { # Add to target Pog 'lab': vP, 'nars': n_a_r_s['+'], } } def MainFontViewUpdate(self): """ Vital routine - the heart if the app. This decides what to do based on what has been selected. It draws the controls and the fonts as appropriate. It also sets flags in fpsys.state """ ## If any DismissablePanels are open, hide them: ps.pub( ensure_fontview_shown ) ## Get shorter vars to use. V = fpsys.state.viewobject T = fpsys.state.targetobject VC = fpsys.state.viewpattern # View Char TC = fpsys.state.targetpattern # Target Char P = VC + TC # a two-char flag ## Okay, let's make a key:.. ## [S][rw][T][rws] <-- key's basic shape ## Where S is Source, T is Target: ## E == Empty View/Source - no fonts in chosen Source. ## N == Empty Target - no fonts. ## P is Pog ## F is Folder ## And rw: ## r is read (i.e. only can view) ## w is write (i.e. remove or append) ## s is same (S/T pogs are the same) ## Example: ## PrN -> Source pog+read. No target pog. ## i.e: We are viewing a pog that is installed ## (no write.) ## FPw -> Source folder. Target pog+write ## i.e. We are viewing a folder and have a Pog ## which is *not* installed, so can be 'written' ## i.e. have fonts appended. # EN -> EN (Empty source, No target) # EP -> EP (Empty source, Pog target (weird) ) # FN -> FN (Folder source, No target) if P in ('EN', 'EP', 'FN'): key = P # PN -> PrN or PwN # Pog source, No target. # Because 1) source is a Pog # and 2) there's no target, # the Pog can be: # r = view it only (i.e. it's installed) # w = remove fonts elif P == "PN": key = "PrN" if V.isInstalled() else "PwN" # FP -> FPr or FPw # Folder source, Pog target. Target r or w. # Similar logic. If target pog is installed # it can't be added-to, i.e. it's 'r' only. # else it can be 'w' elif P == "FP": key = "FPr" if T.isInstalled() else "FPw" # PP -> PPr or PPw or PPs # Target pog is either 'r' or 'w' or ... # Target pog 's' means source and target are same. elif P == "PP": if fpsys.state.samepogs: key = "PPs" else: key = "PPr" if T.isInstalled() else "PPw" # Some kind of error else: print _("FontView state error: Pattern is \"{}\"").format( P ) raise SystemExit ## ..and use it to fetch from dict self.lbl_d d = self.lbl_d[key] # Little func to replace substrings. def rep(s): if "VIEW" in s: s = s.format(VIEW=V.label()) if "TARGET" in s: s = s.format(TARGET=T.label()) return s lab = rep(d['lab']) ## Do we add extra text about recursing? rtest = d.get('rtest',None) if rtest: lab = lab.format(RT=rtest()) # yes ## using dict n_a_r_s nars = d['nars'] fpsys.state.cantick = nars['cantick'] fpsys.state.action = nars['action'] self.TICKMAP = nars['tmap'] ## Enable/Disable the Purge menu item ## Switch it off, then: if the view is a Pog ## and it's *not* installed, we can switch it on. ## (Because you can't purge an installed font.) ## This has nothing to do with whatever target ## may be selected. ps.pub( toggle_purge_menu_item, False ) if VC=="P" and not V.isInstalled(): ps.pub( toggle_purge_menu_item, True ) self.buttMainLastLabel = rep(nars['btext']) self.main_font_info_label.SetLabel( lab ) self.main_font_info_label.Show() i = nars['info'] t = d.get('tip',"") st = rep( u"{} {}".format(i,t) ) self.status_text.SetLabel( st ) self.ToggleMainButton() fpsys.markInactive() self.filterAndPageThenCallCreateFitmaps() def onMainClick(self, evt) : """ Removes fonts, or Appends fonts. Depends on situation in fpsys.state """ #Saved by Robin Dunn, once again ! ! ! xPos, yPos = self.scrolledFontView.GetViewStart() wx.BeginBusyCursor() doupdate = False ## Let's determine what kind of thing to do: if fpsys.state.action == "REMOVE": ## We have a pog in viewobject and we must remove the ## selected fonts from it. vo = fpsys.state.viewobject victims = [] dowrite = False for fi in vo: if fi.ticked: victims.append(fi) #Put it into another list dowrite = True for fi in victims: vo.remove(fi) #Now remove it from the vo del victims if dowrite: fpsys.flushTicks() bug = False try: vo.write() except (fontybugs.PogWriteError), e: bug = True ps.pub( show_error, unicode( e ) ) doupdate = True if not bug: ps.pub(print_to_status_bar,_( "Selected fonts have been removed.")) else: ps.pub(print_to_status_bar,_( "There was an error writing the pog "\ "to disk. Nothing has been done.")) ## APPEND - Copy font to a pog. if fpsys.state.action == "APPEND": ## We must append the fonts to the Pog vo = fpsys.state.viewobject to = fpsys.state.targetobject print _("Copying fonts from %(source)s to %(target)s") % { "source":vo.label(), "target":to.label()} dowrite = False for fi in vo: if fi.ticked: to.append(fi) dowrite = True if dowrite: #Ensure we have no more ticks after a succ. xfer. fpsys.flushTicks() bug = False try: to.write() except (fontybugs.PogWriteError), e: bug = True ps.pub( show_error, unicode( e ) ) doupdate = True if not bug: ps.pub(print_to_status_bar,_( "Selected fonts are now in %s.") % to.label()) else: ps.pub(print_to_status_bar,_( "There was an error writing the pog to disk. " \ "Nothing has been done")) self.scrolledFontView.Scroll(xPos, yPos) if doupdate: self.MainFontViewUpdate() # Dec 2017 # I *think* this SetFocus has fixed the "swallowed ESC" issue. # It seems to work. self.SetFocus() wx.EndBusyCursor() def onPagechoiceClick(self,event) : ##cb = event.GetEventObject() n = int( event.GetString() ) wx.BeginBusyCursor() if self.pageindex != n: #Only redraw if actually onto another page. self.pageindex = n self.filterAndPageThenCallCreateFitmaps() wx.EndBusyCursor() def onPagerChoiceTextEnter(self, evt): o=evt.GetEventObject() #print dir(o) try: n = int(evt.GetString()) except: n = 1 #n = n if n <= self.total_number_of_pages else self.total_number_of_pages n = min(n, self.total_number_of_pages) n = max(1,n) o.SetValue(str(n)) wx.BeginBusyCursor() if self.pageindex != n: #Only redraw if actually onto another page. self.pageindex = n self.filterAndPageThenCallCreateFitmaps() wx.EndBusyCursor() def navClick(self,event) : wx.BeginBusyCursor() if event.GetId() == wx.ID_FORWARD: self.pageindex += 1 else: #wx.ID_BACKWARD self.pageindex -= 1 if self.pageindex > self.total_number_of_pages: self.pageindex = self.total_number_of_pages if self.pageindex == 0: self.pageindex = 1 self.filterAndPageThenCallCreateFitmaps() self.button_main.SetFocus() wx.EndBusyCursor() def OnLeftOrRightKey(self, evt): ## This comes along from MainFrame via the AcceleratorTable events. evt=evt[0] # just get around pubsub tuple. id=evt.GetId() ## We can't just pass on to navClick yet because we don't know if ## the button (left/right) is enabled or not. So determine ## that and then pass on to the other handler. if id==wx.ID_FORWARD: #right arrow was pressed if self.next_button.IsEnabled(): self.navClick( evt ) else: if self.previous_button.IsEnabled(): self.navClick( evt ) #evt.Skip() # If this is here, the keyboard shortcuts get really buggy.... def EnableDisablePrevNext(self) : """ Enabled state of PREV/NEXT buttons """ n = True p = True if self.pageindex == self.total_number_of_pages: n = False if self.pageindex == 1: p = False self.next_button.Enable(n) self.previous_button.Enable(p) def ToggleMainButton(self): # both on, then off .. if ps.pub( toggle_selection_menu_item, True ) self.button_main.Enable( True ) self.button_main.SetLabel( self.buttMainLastLabel ) #print "In ToggleMainButton, testing action:", fpsys.state.action if fpsys.state.action == "NOTHING_TO_DO": self.button_main.Enable( False ) ps.pub( toggle_selection_menu_item, False ) return if fpsys.state.numticks == 0: self.button_main.Enable( False ) #self.button_main.SetLabel( _("Choose some fonts") ) def ResetToPageOne(self): self.pageindex = 1 # I start here fontypython-0.5/fontypythonmodules/pubsub.py0000664000175000017500000001020713211475353021547 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . ## Message topics : they identify the functions to run from CPubsub update_font_view = 10 show_error = 20 show_error_and_abort = 30 show_message = 40 reset_to_page_one = 50 add_pog_item_to_source = 60 remove_pog_item_from_source = 70 print_to_status_bar = 80 install_pog = 90 uninstall_pog = 100 main_button_click = 110 toggle_main_button = 120 target_pog_has_been_selected = 130 source_pog_has_been_selected = 135 change_pog_icon = 140 toggle_targetpog_buttons = 150 clear_targetpog_selection = 160 select_no_view_pog = 170 get_font_view_width = 180 open_settings_panel = 190 toggle_selection_menu_item = 200 toggle_purge_menu_item = 210 left_or_right_key_pressed = 1000 ensure_fontview_shown = 1500 reset_top_left_adjustments = 2000 fake_click_the_source_dir_control = 2500 ## A hack to allow values to return from published topics globRetVal = {} ## The thing that is held in the dictionary inside CListener class CTopic: def __init__(self, function, topic, key): self.function = function self.topic = topic self.key = key ## When you have a function you want to make available, sub() it. ## When you want something to happen somewhere else, then pub () it. class CPubsub: def __init__(self): self.__ears = {} self.__key = 0 def __del__(self): del self.__ears ## Makes a topic object and stores it internally. ## Keeps a constantly increasing internal key. ## I used a dictionary, but it prob should just be a list. ## Ah well. def sub(self, topic, function): #SUBSCRIBE (was newEar) t = CTopic(function, topic, self.__key) self.__ears [ self.__key ] = t self.__key += 1 ## Go thru *all* the topics, find any that match and call ## their functions, passing any args too. ## ## NB: *All* the topics are matched. i.e. there's no early ## returning. This mechanism is relied on by ## topic:change_pog_icon in the PogChooser ## (which subscribes TWICE as it is instanced in BOTH ## source and target pog choosers. A single pub of that ## topic will find two functions within the list and ## so will run both. ## ## NOTE: It's possible for this to recurse, if one pub calls ## another. This is why return values are not advised. def pub(self, topic, *args): #PUBLISH (was shout) #global globRetVal #m = CMessage(topic, messagelist) #print "pub called" ret = None #debuggery: if topic not in self.__ears: print "{} not called.".format(topic) for key, top in self.__ears.iteritems(): if top.topic == topic: function = top.function #print "pub to run:", topic if args: function(args) #Pass the args only. else: function() #if ret: #print "ret causes break." #break; #print "pub ends." #if ret: return ret ## Sample of the use of this stuff: if __name__ == "__main__": def dox(*args): print "i run", args def detox(*args): print "yup de too", args top_dox = 1 p = CPubsub() #we subscribe two handlers to one topic p.sub(top_dox, dox) p.sub(top_dox, detox) #we pretend we are in another class/widget and we want to send a message: p.pub(top_dox, 10,20,"AX","BX") fontypython-0.5/fontypythonmodules/linux_safe_path_library.py0000664000175000017500000001007713211475353025151 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2006, 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . ## Linux safe "path" library ## It's really a place to do encode and decode and os.join ## I debated calling it linux safe STRING library, but can't decide. """ LESSONS Linux is Posix and that means all filenames are stored as byte strings "Unlike Windows NT/2000/XP, which always store filenames in Unicode format, POSIX systems (including Linux) always store filenames as binary strings. This is somewhat more flexible, since the operating system itself doesn't have to know (or care) what encoding is used for filenames. The downside is that the user is responsible for setting up their environment ("locale") for the proper coding." On Linux: os.path.supports_unicode_filename is always == True On my system, with LANG=en_ZA.utf8 >>> locale.getpreferredencoding() 'UTF-8' Return the charset that the user is likely using, according to the system configuration. With LANG=C it returns "ANSI****" On my system: >>> sys.getfilesystemencoding() 'UTF-8' This one returns the ENCODING (byte string to unicode) needed to convert filenames from the O/S *to* unicode. os.path.join : If any one part is unicode, it's all unicode. (Order does not matter) If all parts are str, it's str >>> import os >>> a=u"unicode" >>> b="string" >>> type(a) >>> type(b) >>> p=os.path.join(a,b) >>> p u'unicode/string' >>> p=os.path.join(b,a) >>> p u'string/unicode' """ import os import locale class linuxSafePath( object ): def __init__(self): self.PREFENC=locale.getpreferredencoding() ## I am leaving these without error catches. Let the errors be handled higher-up ## or barf to the stdout. Recc. that users run app from the cli if it is ## closing mysteriously. def to_bytes( self, u ): '''Given a known unicode, return a byte string''' return u.encode( self.PREFENC ) def to_unicode( self, b ): '''Given a known byte string, return a unicode''' return b.decode( self.PREFENC,"replace" ) def ensure_bytes( self, anything ): '''Given any unknown, return a byte string''' if type(anything) is unicode: byte_string = self.to_bytes( anything ) else: byte_string = anything return byte_string def ensure_unicode( self, anything ): '''Given any unknown, return a unicode''' if type( anything ) is str: unicode_obj = self.to_unicode( anything ) else: unicode_obj = anything return unicode_obj def _safe_path_join( self, want="bytestring", *mixed_list ): '''Private worker. Join a path cast to want from mixed_list''' list = [] if want == "bytestring": for anything in mixed_list: list.append( self.ensure_bytes(anything) ) else: for anything in mixed_list: list.append( self.ensure_unicode( anything ) ) return os.path.join( *list ) def path_join_ensure_bytestring_result( self, *args ): '''Return a byte string path from the supplied arguments''' return self._safe_path_join( "bytestring", *args) def path_join_ensure_unicode_result( self, *args ): '''Return a unicode path from the supplied arguments''' return self._safe_path_join( "unicode", *args ) fontypython-0.5/fontypythonmodules/fontypython0000664000175000017500000000230413212237736022222 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import fontypythonmodules.i18n ## test modules etc. import sanitycheck import fpsys # The first import means the code in there gets RUN. ## That's where we create iPC (the single instance of PathControl). ## Process the command line stuff... import cli2 ## What keeps the cli and the gui apart is any ## "raise SystemExit" inside cli ## between here and .. ## The GUI import wxgui ## End, clean up fpsys.config.Save() fontypython-0.5/fontypythonmodules/fontyfilter.py0000664000175000017500000000472313211475353022622 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import fpsys # Global objects import re """ June 2009 Created this file with the intention of more complex searching using the FontTools module. This has not come to fruition, but I will keep this module just in-case. """ def doFilter( filter_string ): #print "filter:", filter_string ##filter_string is a unicode object ## STEP 1 : get the current view object (pog or folder) filteredList = fpsys.state.viewobject ## if filter is not empty if filter_string is not "": ## Okay, we have some kind of filter. ## This idea was suggested by user Chris Mohler. filteredList = [] ## We allow regex in the string. Is this wise? test = re.compile(filter_string, re.IGNORECASE) #L=set([set(i.style[0].split(u" ")) for i in fpsys.state.viewobject]) #print L #import pdb; pdb.set_trace() ## Go through each font item and match ## the regex against certain fields. ## EXTEND THIS TO PANOSE AND other fontTools criteria. for fi in fpsys.state.viewobject: #print fi.name, fi.family, fi.style ## July 2016 ## ========= ## There was a None slipping in via fi.style! ## Fixed this up-stream in fontcontrol.py ## print fi.name, fi.family, fi.style ## Make sure we don't try fetch info from a bad font. if not fi.badfont: if test.search( fi.name + fi.family[0] + fi.style[0] ): filteredList.append( fi ) else: if test.search( fi.name ): filteredList.append( fi ) ## We return the filtered-list return filteredList fontypython-0.5/fontypythonmodules/sanitycheck.py0000664000175000017500000000320313212036002022533 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import sys import strings ## Quick tests - which is there? ## Using imp will find a module very quickly, faster than import x import imp ## PIL : Is it there? try: from PIL import Image, ImageFont, ImageDraw except: print strings.PILError raise SystemExit try: import wxversion ## Dec 2007: noticed that it may not be installed along with wxPython.... wxversion.ensureMinimal("3.0") ## June 25, 2016 - wxversion is now 3.0 ## I am remarking out the old line: ##wxversion.ensureMinimal("2.8") except: print strings.wxVersionError print try: imp.find_module("wx") except: print strings.wxError raise SystemExit ## 2017 - Using GLib to detect the XDG_DATA_HOME stuff. ## Not fatal if it's missing - will fall-back to old fonty paths. try: from gi.repository import GLib except: print strings.giError fontypython-0.5/fontypythonmodules/help/0000775000175000017500000000000013212250216020613 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/help/en/0000775000175000017500000000000013212250216021215 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/help/en/help.html0000664000175000017500000004360613212250216023044 0ustar donndonn00000000000000

Fonty Python

Fonty is a font viewer and manager for Gnu/Linux. Use it to view, gather and manage fonts. You can install and uninstall fonts to your user fonts folder for temporary use in other apps.

Upgrade Notice

Due to upgrade issues, if you find odd problems with your fonts, try this:

  1. Uninstall all your Pogs.
  2. Go into your fonts directory.. {UF_DIR} ..and remove all remaining font files.
  3. Using Fonty, install one Pog
  4. Go back into your fonts directory and look for the links which should be there now.
  5. If that all went well, the upgrade worked and Fonty should be fine.

The Idea | User Font Paths | The Layout | Menus | Hushing | Shortcuts | Tips | Localization | Bugs | Licence

Ye Olde Basic Idea

You visually gather fonts into a "Pog", and then install it. All its fonts will be available to other apps. When you finish your work, uninstall the Pog.

I pinched the word "Pog" from "typography". It means "collection", "group", "bunch", "box", "case", "stack" or "pile" — you get the picture.

Your fonts never move from where they live, neither are copies made; only links to the original files are used to install the fonts into your user fonts directory.

For example, you might have a Pog called "Logos" into which you place all the fonts needed to design a logo. When you want to work, install the "Logos" Pog and start your design app. All those fonts will now appear in Inkscape, the Gimp, etc. When you're done, uninstall "Logos" and all those fonts go away. (The links to the original files are removed, not the actual font files!)

Fonty is also great for just looking at fonts, wherever they are on your computer, without having to install them first. She also has a command line, allowing very quick use. You can install/uninstall Pogs without having to start the entire gui, which is neat.

If you have any problems, please open a ticket: {TICKET_URL}

Top {SEP}

User Fonts Paths

Your fontypython directory

Where all your Pogs are kept.

{FP_DIR}

Your user fonts directory

{UF_DIR}

If there's a dot in front (like .local) that means the directory is "hidden". You might not see it in your file manager.

Whatever it's called and wherever it is, any fonts listed in here are "installed". Fonty's job is to shuttle fonts in and out of here so you don't have to.

If your fonts are not working, it may be that you don't have a user fonts directory. You'll have to search around and figure it out.

Your fontconfig directory is

{FC_DIR}

Top {SEP}

Layout

On the left are the Source (top) and Target (bottom) controls. On the right is the Font View.

  The Sources

Font Sources are directories or Pogs. There are tabs for you to choose.

(Beware the include sub-folders option in Settings. When checked, Fonty will look for fonts in all the sub-directories within your chosen Source directory. If there are lots of fonts in there, she might hang. Use this with caution.)

  The Targets

These Pogs are the Targets: you put fonts into them.

  •   Shows a Pog (which is not installed). Such Pogs can be Targets.
  •   Shows an installed Pog. You can't use these as targets. (Uninstall them first.)
  •   Shows current target Pog.

For Targets, you can select many Pogs at once by holding control (Ctrl) as you select them; this is for installing/uninstalling/etc. many Pogs at once.

Pog management buttons

The managements buttons all work with the selected target Pog(s). It's a little counter-intuitive sometimes. Sorry. It was done because you can select multiple targets. (But not multiple sources.)

  • Clear selection: Will unselect whatever Pogs you selected.
  • Install: All the Pogs selected will be installed. I.e. The fonts in them will be available to the system.
  • Uninstall: All those selected will be uninstalled.
  • New Pog: This will ask you for a name and make a new Pog.
  • Delete: All selected Pogs will be deleted. It will ask you if you are sure.
  • Zip: All selected Pogs will have their fonts zipped into individual zip files in a directory you choose.

  The Font View

Fonts in your Source will be visible in the Font View. You can click on the fonts you want to select. At the bottom of the Font View are controls to filter, page and manage the fonts you are looking at.

The Font View will also attempt to display in columns, so you can see many fonts at once. The columns vary by point size and the width of your window. You can control the number of columns in the Settings.

The Fonts themselves

Each font appears with some appropriate information. Here are the basics:

  • Change the Point size by Ctrl + scrolling the mouse wheel up or down.

  •  Character Map Button: If you have a character viewing app installed, this button will open it. (You can choose which character map viewer to use in the Settings. The choices are gucharmap or kfontview — but you must install one first.)

  • Selecting fonts: Clicking anywhere on a font will select it; if it's sensible. For example, if you have only a Source selected, and no Target, then there's no point in selecting fonts.

    • A tick : means the font can be placed into your chosen Target Pog.
    • A cross : means the font will be removed from the Source Pog (The one you are viewing at the moment).
  • Font Info: Under each font you will find the family and style and filename. When you use the filter to search, this is the text that is searched.

  • Greyed-out: Fonts that are already in the Pog (i.e. selected as a target) are disabled.

  •  Bad fonts: An error may appear instead of the expected font glyphs. Such fonts cannot be drawn. You can select, enpog, and install them. Most of the time, these fonts will still work in your design apps, like Inkscape. (See Bugs for more information about font errors.)

Font controls

  • Filter:
    • i,r,b are Italic, Regular and Bold.
    •   Clears any filter.
    • The text box is for custom searching. Type something and hit enter.
  • Pager: On the far right is the pager. Use it to step through the fonts as you like.
  • Left/Right: Arrow buttons for paging one forward or back.

Top {SEP}

 Hushing Fonts

On Linux there are often too many fonts installed; it's hard to choose among them. To work with only the fonts that you install via Fonty, hit Ctrl+H to hush. Your apps will now list only your desired fonts. (Until you un-hush.)

Simply install Pogs via Fonty as normal and start a hush. In your other apps, you should see the difference. (For e.g. go into Inkscape and open the "Text & Font" dialogue.)

The "Hush Pog" and a mild Warning

As you can imagine, a hush could reject many crucial fonts...

In order to make sure that your system has a few it can use, Fonty requires you to choose a Pog that is installed when hushing. Call it a "Hush Pog".

Create a Pog of your own and put some typical system fonts into it. Good choices are: DejaVu, Sans, Serif, Mono, Free-, Liberation-, Ubuntu- and so forth. This depends on your locale and preferences, therefore we leave it to you.

(These kinds of fonts are usually found in "/usr/share/fonts".)

Fonty will ask for a Pog when you start a hush; select the one you prepared.

It's not serious, but you have been warned.

Details

This all requires a working fontconfig setup, which most modern Linux distros have. Fonty looks for the directory:

{HOME}/.config/fontconfig/conf.d 

If it's not found, you can't hush fonts. (If you have more information, please open a ticket.)

Fonty writes a config file which instructs fontconfig to:

  • Reject all files that start with "/usr/share/fonts"
  • Allow all fonts installed in the user fonts directory.

The effect is usually instantaneous, but you may need to restart certain apps for them to notice. (If you find there are still fonts appearing that you do not want to see, please open a ticket.)

Reversing a hush: the Un-hush

To switch all the system fonts on again, go into the hush screen where you can "Un-hush".

Your "Hush Pog" is not uninstalled; do this manually,

If there's a problem, you can also manually delete the config file. Look for it on this path, and delete it:

{FC_PAF} 

Top {SEP}

Menus

  • Tools menu
    •  Settings: Access the settings for the font view. Shortcuts: Ctrl+S or middle-click on the font view.
    • Purge Pog: The Pog you are currently viewing may contain fonts that are not there anymore. Use purge to remove them.
      Explanation: A Pog contains a list of paths. If a font is somehow moved on your hard drive, then the path in the Pog will be old. Purging will remove these ghost fonts.
    •  Hush fonts: See the section on hushing. Shortcut: Ctrl+H
    • Exit: Guess. :-)
  • Selection menu
    • Select ALL the source fonts: While only a few fonts are shown in a page at a time, there may be thousands in the selected source. This will select all of them, in one go.
    • Clear ENTIRE selection: Will clear any selection.

Top

{SEP}

Shortcut keys

If shortcut keys don't work, click in the filter text box. This seems to kick them back to life. Don't ask me what's going on....

  • Esc The Escape key will close any panels that may be open. Used again, it will close the app. Most of the time.
  • Ctrl + LeftArrow/Ctrl + RightArrow will step through fonts like the Next and Previous buttons do.
  • Middle-click (the wheel-button) or Ctrl + S in the font view will open the Settings screen.
  • Ctrl + Scroll mouse wheel up/down will increase/decrease the size of your font previews quickly.
  • Ctrl + H will open the hush panel.

Top

{SEP}

Tips

  • Try to use Fonty from the command-line (from a console). It's easy, simply type: fontypython -h
  • Pog files are merely text files. They are very, very simple and this was intentional. Here are some things you can do with them:

    • Open and edit them in any text editor.
    • Append fonts to the end of them, just include the entire path (ends with the font file name).
    • Note for Type1 fonts: Only include the PFA/B file types, not the various metric files that follow them.
    • If your paths change (say you renamed your folders, or re-installed your O/S) then you can use search/replace to update all the paths to all the fonts in your Pogs. You could do this from the command-line using GNU tools, but any text editor will help you here too.
    • You can backup your Pogs by simply copying them to another folder.
    • One last trick, for those proficient with the Gnu tools, you can do things like this:

      find /home/you/somepath/TTFS/F -iname "Fu*" >> Futura.Pog

Top

{SEP}

Localization Tips

If localization is not working it could be there is none for your language; it can also be a problem with missing packages in your distro. This is what I installed on my system while I was developing: (Replace the last two letters with your own language code.)

  • language-support-fr
  • language-support-en
  • language-pack-gnome-fr (This one is very important, it has many stock translations for GTK.)

ENCODING TIP: Check your LANG variable. Open a console and type: echo $LANG If it reports "C" or "POSIX" or it's blank then you will be running under ANSI (ASCII) encoding only. This means that unusually named fonts and Pogs will likely be invisible to you, function badly, or cause errors. I am putting out fires as fast as I can, but these bugs are hard to find.

To see what other encodings you could be using, type:

 locale -a 

You should see a list of locales. If you see one ending in "utf8" that looks like it fits your language, then change your system to use it. You should do this via your system-settings gui, but you can do it temporarily like this:

 LANG=xx_YY.encoding 

(Where xx_YY and encoding are replaced by you.) After that, start Fonty again.

If you want to help translate, please drop us a ticket on: {TICKET_URL}

Top

{SEP}

Bugs

 Fatal crashes and Dangerous Fonts.

Some fonts stick in Fonty's throat and crash her. If you wait a moment, a window should appear and tell you which font is to blame. You should move that font entirely away from where it is. Start Fonty again to resume.

If you are stuck, go into your "fontypython" folder and open the file named "lastFontBeforeSegfault", that will be the culprit!

To find your fontypython directory, see the Info section in this help. You can also ask Fonty for the path. On the command-line, run:

 fontypython -d 

Checking Fonts

If Fonty will not start, you have a really bad font somewhere. On the command-line, use the -c flag to check all fonts (recursively) on the given path:

 fontypython -c /some/folder 

Any fonts that are likely to kill Fonty will be recorded in a file named "segfonts" (look in your fontypython directory). After you do this, Fonty should work again.

When Fonty starts, she checks your Pog files. If there are any Pogs that cannot be read for whatever reason, then they are renamed to ".badpog". You should go in there and do some sleuthing.

If you are stuck, post a report on https://savannah.nongnu.org/bugs/?group=fontypython. Please run Fonty from the command line so that you can copy any error displayed.

Top

{SEP}

Licence

 Fonty Python is Copyright (C) 2006, 2017 Donn.C.Ingle.
This file is part of Fonty Python.
Fonty Python 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 3 of the License, or
(at your option) any later version.
Fonty Python 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 Fonty Python. If not, see http://www.gnu.org/licenses/

Top

fontypython-0.5/fontypythonmodules/help/en/README0000664000175000017500000004316113211475353022114 0ustar donndonn00000000000000Section Two : License ======================= GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. fontypython-0.5/fontypythonmodules/help/README0000664000175000017500000000060413211475353021505 0ustar donndonn00000000000000Nov 2017 == Now using markdown and the dev files are in the main root under "htmldev". There has been no query from anyone to localize the help, so there's no guide. Contact us if you wish to try. Old == To localize your help file, create a directory here using the two letter code, for example France would be 'fr' (It should be the same as the code used in the locale folder.) :) /d fontypython-0.5/fontypythonmodules/help/COPYING0000664000175000017500000010451313212036007021652 0ustar donndonn00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . fontypython-0.5/fontypythonmodules/i18n.py0000664000175000017500000000415513211475353021033 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2006, 2007, 2008, 2009, 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import locale, gettext, sys, os ## Had to copy this from fpsys. When doing a proper installation ## the relative links to locale stop working. I need to know ## where fontypythonmodules actually lives. root = __file__ if os.path.islink(root): root = os.path.realpath(root) fontyroot = os.path.dirname(os.path.abspath(root)) ## Dec 2007 ## Try to setup the proper locale to get i18n started: localedir = os.path.join(fontyroot, "locale") try: loc = locale.setlocale( locale.LC_ALL, "" ) # This sets the locale to the system's default. except: print "And now for something completely different..." print "setlocale failed. Please report this to us." raise SystemExit ## REMEMBER: ## locale.getlocale() -- DON'T USE getlocale ## ALWAYS use locale.getpreferredencoding() ## On my system when LANG=C or LANG= ## This returns "ANSI_X3.4-1968" ## The .mo file is called "all.mo" domain = "all" gettext.install( domain, localedir, unicode = True ) try: lang = gettext.translation (domain, localedir, languages=[loc])#have to have last param ... lang.install(unicode = True ) except IOError: ## Could not find the domain.mo file. ## I won't print a message because this file runs twice (fontypython and start_fontypython) ## and that dumps two messages, which sucks. pass # default to English. fontypython-0.5/fontypythonmodules/gui_DirChooser.py0000664000175000017500000001056513211475353023163 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx, fpwx class ATree(wx.GenericDirCtrl): """ Nov 2017 == A dir control with my custom icons. Used as a Pog source, and when choosing a zip file directory. So far. Note: Directory names are all UNICODE! The startdir is always going to be some valid path, even if only $HOME. """ def __init__(self, parent, startdir): wx.GenericDirCtrl.__init__(self, parent, -1, dir = startdir, style=wx.DIRCTRL_DIR_ONLY ) self.treectrl = self.GetTreeCtrl() self.SelectPath( startdir, True ) # create the image list: isz = (16,16) il = wx.ImageList(isz[0], isz[1]) # Add images to list. You need to keep this exact order for # this to work! # Dec 2017: Added item # 7, the little eye icon. bmplst=['icon_closed_folder', 'icon_open_folder', 'icon_root', 'icon_drive', 'icon_cdrom', 'icon_ext_drive', 'icon_ext_drive','view16x16'] [il.Add( fpwx.wxbmp(f) ) for f in bmplst] # assign image list: self.il = il self.treectrl.SetImageList(il) # Set the initial icon sid = self.treectrl.GetSelection() self._set_icon(sid) # I can't get it to scroll to the selected dir ## Sept 2017 ## Trying to ensure the tree is scrolled to the start dir. No go so far. #s = self.tree.GetSelection() #print s #print dir(s) #import pdb; pdb.set_trace() #self.tree.EnsureVisible(s) #self.tree.ScrollTo(s) #self.treectrl.ScrollTo(sid), etc. self.treectrl.Bind(wx.EVT_TREE_SEL_CHANGED, self.__OnThing) #self.treectrl.Bind(wx.EVT_SET_FOCUS, self._foo) #def _foo(self,evt): # print evt def __OnThing(self, evt): """ This event happens second; after whatever binding is in FontSources etc. (They must Skip() the event along to me.) If they don't Skip(), this won't run and the icons won't change. I do this in the ChooseZipDirPanel. (See gui_dismissable_panels.py) """ #print '**THING on', self.treectrl.GetItemText(evt.GetItem()) ti = evt.GetItem() self._set_icon(ti) evt.Skip() def _set_icon(self,tid): """ Found this in the docs. Got lucky. It's a way to set an icon on various selection states. It better reflects the little eye in the Pog list controls now. (here it's #7) """ self.treectrl.SetItemImage( tid, 7, which = wx.TreeItemIcon_SelectedExpanded) self.treectrl.SetItemImage( tid, 7, which = wx.TreeItemIcon_Selected) # The item selects, but it flashes from orange # to grey in the background. It's weird. # I can't fix it. #self.treectrl.SetFocusedItem(tid) # fail def _one_down(self): """ Attempt to force the tree to scroll down. Fails. Will leave this here for one day. http://wxpython-users.1045709.n5.nabble.com/\ Cross-platform-issues-Programmatically-Scrolling\ -a-TreeCtrl-td2300200.html """ sp = 100#self.treectrl.GetScrollPos(wx.VERTICAL) srange = 100# self.treectrl.GetScrollRange(wx.VERTICAL) - \ #self.treectrl.GetScrollThumb(wx.VERTICAL) e = wx.ScrollEvent(wx.wxEVT_SCROLLWIN_LINEDOWN, self.treectrl.GetId(), min(sp+1, srange), wx.VERTICAL) print sp, srange self.treectrl.GetEventHandler().ProcessEvent(e) fontypython-0.5/fontypythonmodules/fp_step_4.py0000664000175000017500000000240513211475353022133 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . """ Dec 2017 === This is step 4 in the startup process. We got here from ../fp_step_3.py """ ## test modules etc. import sanitycheck import fpsys # The first import means the code in there gets RUN. ## That's where we create iPC (the single instance of PathControl). ## Process the command line stuff... import cli2 ## What keeps the cli and the gui apart is any ## "raise SystemExit" inside cli ## between here and .. ## The GUI import wxgui ## End, clean up fpsys.config.Save() fontypython-0.5/fontypythonmodules/__init__.py0000664000175000017500000000000113211475353021775 0ustar donndonn00000000000000 fontypython-0.5/fontypythonmodules/about/0000775000175000017500000000000013212250216020775 5ustar donndonn00000000000000fontypython-0.5/fontypythonmodules/about/about.html0000664000175000017500000000347613212250216023007 0ustar donndonn00000000000000

Fonty Python

{copyright}
{version}
Contact me: {contact}
Open a ticket: {ticket}

Written on Gnu\Linux using wxPython, Python and Gvim.

{warranty}

Thanks

Many thanks to:

  • Kartik Mistry - Our esteemed Debian packager!
  • Robin Dunn - wxPython itself, and much sundry help.
  • Martin v. Löwis - Essential concepts regarding unicode and files.
  • Pietro Battiston - Italian translation.
  • Michael Hoeft - For code, friendship and the German translation.
  • savannah.nongnu.org - For the hosting. You guys rule!
  • Michael Moller - For math advice; pointing me in the direction of the "standard-deviation", which I used in the font layout. Also for getting me into Linux all those years ago.
  • FichteFoll - For catching a bug which prevented startup when there are no pogs! Which is... Ye Gods!
  • Akira TAGOH - For help with fontconfig voodoo: rejecting and accepting fonts in the fontconfig XML (on the fontconfig mailing list).
  • Jason Yamada-Hanff - For the old wiki.
  • Baptiste - French translation and many ideas.

Special thanks to:

  • Marie, my mom, who keeps me going. Thanks for supporting me and Fonty!
  • Howard, my late father. He brought computers and code into my world. He died before Linux happened; before the Internet happened. He would have been amazed.

Licence

{GPL}

fontypython-0.5/fontypythonmodules/about/COPYING0000664000175000017500000010451313212036007022034 0ustar donndonn00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . fontypython-0.5/fontypythonmodules/fontcontrol.py0000664000175000017500000011751413211475353022627 0ustar donndonn00000000000000# -*- coding: utf-8 -*- ## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import os, sys, locale, glob, errno import tempfile, shutil, warnings from PIL import ImageFont ## This import will not RUN the code in fpsys.py ## because it's been imported before. (It's a Python thing.) ## This is NB as I don't want it making a new PathControl import fpsys import fontybugs ## Sep 2009 : zip functionality import zipfile zcompress=zipfile.ZIP_STORED #we default to uncompressed. try: import zlib zcompress=zipfile.ZIP_DEFLATED #i.e. we can compress using this formula. except: pass #Font file extensions fexts = { "Truetype" : ["TTF"], "Truetype_collection": ["TTC"], "Opentype" : ["OTF"], "Opentype_collection": ["OTC"], "Web_open_font" : ["WOFF"], "Type1" : ["PFA","PFB"], "Type1_metric_A" : ["AFM"], "Type1_metric_P" : ["PFM"], } ## make it a flat list like [".OTF",".TTC" ...etc. font_file_extensions_list = [] for i in fexts.values(): font_file_extensions_list += [ "." + s for s in i ] class FontItem( object ): """ Represents a single font file. It has the ability to provide a font image and query a font file for the family name and style. Ancestor to the specific classes per font type. Never instantiate one directly. """ def __init__(self, glyphpaf ): ## glyphpaf must be whatever it is. unicode or a byte string. ## This is used to access files themselves. ## When the LANG encoding is utf8, it's Unicode. self.glyphpaf = glyphpaf #print "FontItem init, glyphpaf:", [glyphpaf] ## I want to have a var I can use when I display the glyphpaf ## either in the gui or onto the cli. This should be a unicode ## object, so I must make sure of its type before I do so. self.glyphpaf_unicode = fpsys.LSP.ensure_unicode( glyphpaf ) ## The same goes for name. It *must* be unicode. self.name = os.path.basename ( self.glyphpaf_unicode ) self.name = fpsys.LSP.ensure_unicode( self.name ) self.ticked = False # State of the tick/cross symbol. self.inactive = False # Set in fpsys.markInactive() self.activeInactiveMsg = "" #Say something unique when I draw this item. ## These are lists to cater for sub-faces self.family, self.style = [], [] self.numFaces = 0 self.pilheight, self.pilwidth = 0,0 ## I'm not bad in any way, until I turn bad that is :) self.badfont = False ## If I'm bad, what should I say? self.badfontmsg = "" ## What kind of bad to the bone am I? ## One of FILE_NOT_FOUND, PIL_IO_ERROR, PIL_UNICODE_ERROR, PIL_CANNOT_RENDER self.badstyle = "" ## July 2016 - Used in gui_Fitmap.py self.textExtentsDict = {} ## We need the family name and style to be fetched ## because we have that filter thing in the gui ## and it uses those strings to search for terms. ## ## We also want to know what flavour of bad this item will be ## and we must open the file and query it to know that. self.__queryFontFamilyStyleFlagBad() ## Vars used in the rendering stage. self.fx = [None for i in xrange(self.numFaces)] # Position calculated for best top-left of each face image. self.fy = self.fx[:] #Damn! Make a COPY of that list! self.top_left_adjust_completed = False def __queryFontFamilyStyleFlagBad( self ): """ Get the family, style and size of entire font. If this font has a problem (PIL can't read it) then we set the badfont flag, along with the badstyle & badfontmsg vars. badstyle: FILE_NOT_FOUND, PIL_IO_ERROR, PIL_UNICODE_ERROR The last kind of badstyle is set in generatePilFont() and is set to: PIL_CANNOT_RENDER This is tricky because FontImage.getname() is fragile and apt to segfault. As of Dec 2007 I have reported the bug, and a patch has been written but I don't know how it will be implemented yet. NB: InfoFontItem overrides this so it does not happen in that case. This is why I made this a method and not simply part of the __init__ above. """ i = 0 ## Step through all subfaces. #print "BUILDING:", [self.glyphpaf] while True: try: fileDoesExist = os.path.exists( self.glyphpaf ) if not fileDoesExist: self.badfont = True self.badfontmsg = _("Font cannot be found. Purge lost fonts from this Pog.\n(See the Tools menu.)") self.badstyle = "FILE_NOT_FOUND" ## If the multi face font is damaged after the ## first face, then this won't catch it... break # it's at the end of the sub-faces except: print _("Unhandled error:\nPlease remove (%s) away from here and report this to us.") % self.glyphpaf raise try: font = ImageFont.truetype(self.glyphpaf, 16, index=i, encoding="unicode" ) #Tester: raise IOError except IOError: """ Means the ttf file cannot be opened or rendered by PIL ! NOTE: Sets badfont """ if i == 0: # fubar on the first face: self.badfont = True self.badfontmsg = _("Font may be bad and it cannot be drawn.") self.badstyle = "PIL_IO_ERROR" ## If the multi face font is damaged after the ## first face, then this won't catch it... break # it's at the end of the sub-faces except UnicodeEncodeError: """ NOTE: Sets badfont """ ## Aw man! I thought I had this taped. This error does not *seem* to ## be related to the encoding param passed to ImageFont. I have ## mailed the PIL list about this. ## ## In the meantime, this will have to be flagged as a bad font. self.badfont = True self.badfontmsg = _("Unicode problem. Font may be bad and it cannot be drawn.") self.badstyle = "PIL_UNICODE_ERROR" break except: ## What next on the error pile? print "CORNER CASE in FontItem.__queryFontFamilyStyleFlagBad:", [self.glyphpaf] print sys.exc_info() ## Abort the app because this is an unhandled PIL error of some kind. raise if not self.badfont: ## *If* 'check' is run, there will be a file containing pafs of the ## fonts that segfault PIL. (To my best knowledge, at least.) ## This file is held in the 'segfonts' list - opened in fpsys ## So, before we do a getname and cause a segfault, let's ## see whether that font is in segfonts, and if so, skip it. if self.glyphpaf not in fpsys.segfonts: # This writes to lastFontBeforeSegfault file. Just in case it crashes the # app on the .family call below. ## Nov 2017 ## == ## Update. PIL(LOW) seems much more stable. I have only seen one ## segfault and I can't reproduce it. ## This lastFontBeforeSegfault thing is possibly redundant now. ## I will leave it in, but not that there's no call to "font.family" ## (as the comments speak about) but rather a font.getname call. ## I have also added code to rm the lastFontBeforeSegfault file ## on App exit - just so it doesn't lurk about in the fp dir. fpsys.logSegfaulters( self.glyphpaf ) ##Test the segfault thing. #victim = "/home/donn/Projects/pythoning/fontyPython/dev.svn/fontypython/branches/layoutchange/scraps/fontsfortesting/DF Calligraphic Ornaments LET Plain-1.0.ttf" #if self.glyphpaf == victim: # ## Force a segfault.... to test :| # exec'()'*7**6 ## Sep 2009 ## It has been reported by a user that some fonts have family names (and other info?) that ## are not English. They appear as ???y??? etc. in the font list. On my system Inkscape ## draws tham with squares (holding a unicode number) and a few Eastern characters. ## I am not sure AT ALL what to do about this. Is it a font/locale I should have installed? ## This is bug number: https://savannah.nongnu.org/bugs/index.php?27305 #self.family.append( font.getname()[0] ) # old code ## No point Try-ing here, this segfaults when style/family is Null. ## July 2016 ## ========= ## Font caused an error. Here it is: ## chinese_rocks_rg-webfont.ttf [None] ['\x7f'] ## The None is the problem. n = fpsys.LSP.ensure_unicode( font.getname()[0] ) if n is None: n="" self.family.append( n ) ## July 2016: Let's assure no None in the style too n = font.getname()[1] if n is None: n="" self.style.append( n ) i += 1 else: ## It WAS in the list! So, we can flag it and get on with life :) #print "SKIPPING:",[self.glyphpaf] self.badfont = True self.badfontmsg = _("Font causes a segfault. It cannot be drawn.") self.badstyle = "PIL_SEGFAULT_ERROR" break self.numFaces = i def __str__( self ): return self.glyphpaf def InfoOrErrorText(self): """Used in Fitmap code to draw strings and things.""" l1 = l2 = "Text that should not appear." if self.badfont: l1 = self.badfontmsg l2 = self.glyphpaf_unicode #n = 40 #l2 = u"\n".join([l2[i:i+n] for i in xrange(0,len(l2),n)]) ## Sept 2017: Shortened the paf by subtracting the $HOME dir out. try: l2 = l2.replace( fpsys.iPC.home(), u"…" ) except: # With strings, you never know... # Hopefully some legible vers of l2 will leave this func. pass return ( l1, l2 ) ## Create some subclasses to represent the fonts that we support: class InfoFontItem( FontItem ): """ This class is only instantiated in wxgui.CreateFitmaps It's used to indicate when a Folder or Pog is EMPTY and if a single font is bad in some way. It's the only Font Item in the target or source view list at that time. """ def __init__( self, glyphpaf="" ): FontItem.__init__( self, glyphpaf ) def __queryFontFamilyStyleFlagBad( self ): """Overridden so that it does not happen for this class.""" pass def InfoOrErrorText( self ): """An override : InfoFontItem needs only these words""" l1 = _("There are no fonts to see here, move along.") l2 = _("Stuff to check:\n" \ "\t1) The filters.\n" \ "\t2) The \"include sub-folders\"\n" \ "\t\tcheck box (in Settings).\n" \ "\t3) The Help file.") return ( l1, l2 ) class TruetypeItem( FontItem ): def __init__( self, glyphpaf ): FontItem.__init__( self, glyphpaf ) #Sept 2017: Renamed class. class TruetypeOrOpentypeCollectionItem( FontItem ): def __init__( self, glyphpaf ): FontItem.__init__( self, glyphpaf ) class OpentypeItem( FontItem ): def __init__( self, glyphpaf ): FontItem.__init__( self, glyphpaf ) class Type1Item( FontItem ): def __init__( self, glyphpaf, metricpaf=None ): FontItem.__init__( self, glyphpaf ) self.metricpaf = metricpaf ## Added Sept 2017: class WebOpenFontFormatItem( FontItem ): def __init__( self, glyphpaf ): FontItem.__init__( self, glyphpaf ) ## Sept 2017: Not supported by PIL #class X11PCFItem( FontItem ): #def __init__( self, glyphpaf ): #FontItem.__init__( self, glyphpaf ) ## Sept 2017 - Also not working ... #class WindowsFNTItem( FontItem ): #def __init__( self, glyphpaf ): #FontItem.__init__( self, glyphpaf ) def itemGenerator( fromObj, sourceList ): """ Prepare for hell... This is a *generator* function that yields a FontItem instantiated according to the type of the font. Call it once-off, or in a loop, to get one FontItem after another. Pass it a sourceList that contains pafs. VERY NB: When the app is run from a utf8 locale, this func generates UNICODE glyphpaf vars. When run from C/POSIX/None it generates BYTE STRING glyphpaf vars. sourceList is not a predictable beast. It comes in mixed strings/unicode """ #print "sourceList comes in:",[sourceList] #print def ext(s): return s.split(".")[-1].upper() def stripExt(s): return s[:s.rfind(".")] listOfItemsGenerated = [] ## So, [paf,paf,paf,paf,paf] comes in. ## If it comes from FOLDER then it's full of ALL the files in a single dir. ## NB: It may or may not include 'type1' files and their 'metrics' ## If it comes from POG then it's just pafs of the basic glyph files ## thus it does not include the afm/pfm files. ## So: this is a special case. ## We must "fill-up" the list with the 'metric' files that are matched ## to Type1 files - i.e. AFM and PFM files that belong to the fonts ## of type 'type1' which we are detecting by extension as ".pfb" and ".pfa" if isinstance( fromObj, Pog ): tmp = [] for paf in sourceList: ## paf : /some/path/somefont.pfb (or .ttf, or whatever. Do them all.) tmp.append( paf ) # add it to what will replace sourceList dir = os.path.dirname( paf ) # /some/path filename = os.path.basename( paf ) # somefont.pfb ## Find metric files with his name in his dir wild = os.path.join( dir, stripExt(filename) + ".[PpAa][Ff][Mm]" ) metricfiles = glob.glob( wild ) ## Add what we find (if anything) to the tmp list for metric in metricfiles: tmp.append( metric ) # merge them in ## Replace the sourceList del( sourceList ) sourceList = tmp ## Now we have a sourceList that is complete - full of files ## TYPE1 stuff. 10 Jan 2008 ## Jump through hoops to find the 'metric' files (AFM then PFM) ## for each Type1 font that's in the list ## ## As per advice on the freetype list I am doing this: ## For every PFA/PFB file, I look for a matching path and filename ## starting with AFM extensions, then trying PFM extensions. ## AFM is preferred over PFM. ## Make Type1Item objects and associate the 'metric' file found (or none) ## Filter some lists from sourceList to step through: ## all type1 files PFABs= [[stripExt(e),e] for e in sourceList if ext(e) in fexts["Type1"]] ## all AFM metric files AFMs = [[stripExt(e),e] for e in sourceList if ext(e) in fexts["Type1_metric_A"]] ## all PFM metric files PFMs = [[stripExt(e),e] for e in sourceList if ext(e) in fexts["Type1_metric_P"]] ## Those lists look like this: ## ["/some/path/file", "/some/path/file.pfa"] ## [0] is paf sans extension, [1] is all of it (*) ## (*) We have to worry about case sensitivity, so I store more data. ## Go through the (maybe empty) list of PFA and PFB files for pfab_tup in PFABs: foundAFM = False ## Looking for AFM files for afm_tup in AFMs: if afm_tup[0] == pfab_tup[0]: ## We have found an afm file for this pfa/pfb file ## so make an object fi = Type1Item( pfab_tup[1], metricpaf = afm_tup[1] ) listOfItemsGenerated.append( fi ) foundAFM = True break ## If we found no AFM then try find a PFM foundPFM = False if not foundAFM: ## Looking for PFM files for pfm_tup in PFMs: if pfm_tup[0] == pfab_tup[0]: ## We have found pfm file for it, make an object fi = Type1Item( pfab_tup[1], metricpaf = pfm_tup[1] ) listOfItemsGenerated.append( fi ) foundPFM = True break ## If we found neither: if not foundAFM and not foundPFM: ## Just make an object without a metric file associated. fi = Type1Item( pfab_tup[1], metricpaf = None ) listOfItemsGenerated.append( fi ) ## Do the other font types #TTFList = [ paf for paf in sourceList if ext(paf) == "TTF" ] TTFList = [ paf for paf in sourceList if ext(paf) in fexts["Truetype"] ] for paf in TTFList: fi = TruetypeItem( paf ) listOfItemsGenerated.append( fi ) #OTFList = [ paf for paf in sourceList if ext(paf) == "OTF" ] OTFList = [ paf for paf in sourceList if ext(paf) in fexts["Opentype"] ] for paf in OTFList: fi = OpentypeItem( paf ) listOfItemsGenerated.append(fi) #Sept 2017: Added OTC, hence the "in" test. Also new class name. #TTCandOTCList = [ paf for paf in sourceList if ext(paf) in ( "TTC", "OTC" ) ] TTCandOTCList = [ paf for paf in sourceList if ext(paf) in fexts["Truetype_collection"] + fexts["Opentype_collection"] ] for paf in TTCandOTCList: fi = TruetypeOrOpentypeCollectionItem( paf ) listOfItemsGenerated.append(fi) ##Sept 2017 #WOFFList = [ paf for paf in sourceList if ext(paf) == "WOFF" ] WOFFList = [ paf for paf in sourceList if ext(paf) in fexts["Web_open_font"] ] for paf in WOFFList: fi = WebOpenFontFormatItem( paf ) listOfItemsGenerated.append(fi) ##Sept 2017 - .fnt files AFAICT not supported by PIL ##Sept 2017 - X11 .pcf files. PIL does not seem to support these directly. ##NOV 2017: There's a font filetype list in fpsys.checkFonts(). Keep it ## updated when you change shit here. ## NB: listOfItemsGenerated can contain MIXED byte strings/unicode ## Sort the list: I use the glyphpaf_unicode var becuase it's unicode only. listOfItemsGenerated.sort( cmp=locale.strcoll, key=lambda obj:obj.glyphpaf_unicode ) # Try to sort on that field. ## Supply it: This is pure magic! for fi in listOfItemsGenerated: yield fi class BasicFontList(list): """ Ancestor to the Pog and Folder classes. """ def clear(self): del self[:] # works. It was real touch and go there for a while. def clearInactiveflags(self): for fi in self: fi.inactive = False class EmptyView(BasicFontList): """ Imitates an empty Pog or an empty Folder. """ def __init__(self): BasicFontList.__init__(self) ## Public properties: self.name = "EMPTY" self.installed = False self.empty = True def label(self): return str(self.name) def genList(self): return def isInstalled(self): return False class Folder(BasicFontList): """ Represents an entire Folder (from a path given by user clicking on the GenericDirCtrl or from a command line string.) This is called from fpsys.instantiateViewFolder Contains a list of various FontItem Objects. Supply the start path and an optional recurse T/F param. """ def __init__(self, path, recurse=False): BasicFontList.__init__(self) #print "path:",[path] ## I reckon self.path is always coming in as unicode. ## From the gui, it's unicode anyway cos of the dir control. ## From the cli, I converted args to unicode there. self.path = os.path.abspath(path) # fix relative paths ## Added June 2009 def safeJoin(apath,filelist): ''' It seems filelist cannot be relied on to be anything other than a mixed-bag of unicode and/or bytestrings. I will join each to the apath and force the result to bytestrings. ''' returnList = [] for f in filelist: paf = fpsys.LSP.path_join_ensure_bytestring_result( apath, f ) if os.path.isfile( paf ): returnList.append( paf ) return returnList ## All recursive changes June 2009 if not recurse: ## Note: If self.path DOES NOT EXIST then this raises and OSError ## This can happen when we use the --all cli argument (see cli.py) # Calling os.listdir here is okay because self.path is unicode, but # listOfFilenamesOnly *should* be a list of pure unicode objects as a result. # It's NOT - I have found problems... see safeJoin func just above. listOfFilenamesOnly = os.listdir ( self.path ) # Get the unicode list sourceList = safeJoin(self.path, listOfFilenamesOnly ) else: # Recursive code sourceList=[] # Force P to be BYTE STRING from unicode<-came in as P = fpsys.LSP.ensure_bytes( self.path ) for root, dirs, files in os.walk( P ): ## I need root and each file to be UNICODE, so I must decode them here R = fpsys.LSP.to_unicode( root ) F = [ fpsys.LSP.to_unicode(f) for f in files ] sourceList.extend( safeJoin( R, F ) ) # At this point sourceList is full of PURE BYTE STRINGS ## Now employ the generator magic: ## Makes FontItem objects for each paf in the list. for fi in itemGenerator( self, sourceList ): self.append(fi) if len(self) == 0: #print "EMPTY FOLDER" raise fontybugs.FolderHasNoFonts(self.path) def __str__(self): return str(self.path) def label( self ): """ A handy way to refer to Folders & Pogs in certain circumstances. Pog.label returns the name Folder.label returns the path """ return os.path.basename( self.path ) class Pog(BasicFontList): """ Represents an entire Pog. Contains a list of various FontItems. Dec 2007 - adding OTF and Type 1 Supply the pog name. Must call genList() if you want actual font items in the list. """ def __init__(self, name ): #, progressCallback = None): BasicFontList.__init__(self) ## Public properties: ## ## name always comes in as a byte string because ## we built the path up to .fontypython from byte strings ## Make a unicode of that name: uname = fpsys.LSP.ensure_unicode( name ) ## Stores a unicode for access from other places: self.name = uname self.__installed = "dirty" #am I installed? ## ## NB NOTE: self.paf IS A BYTE STRING ## ## Note, name (not self.name) is used here. It is a byte string. ## appPath() is a bs, name is a bs so join leaves this all as a bs. self.paf = os.path.join( fpsys.iPC.appPath(),name + ".pog") ## OVERKILL : self.paf = fpsys.LSP.path_join_ensure_bytestring_result( fpsys.iPC.appPath(),name + ".pog" ) self.badpog = False #To be used mainly to draw icons and ask user to purge. def label(self): """ A handy way to refer to Folders & Pogs in certain circumstances. Pog.label returns the name (in unicode) Folder.label return the path These are both the full paf of the font. """ return self.name def __openfile(self): """ Open my pog file. Raise PogInvalid error or return a file handle. """ ## NB: NO error is raised if an empty file is opened and read... ## If there is some chronic hard drive problem, I assume Python will quit anyway... try: #print "Trying to open:", [self.paf] ## In theory, any file can *always* be opened - no matter what ## locale. POSIX deals only in byte strings. So, this next ## line will never fail. ## I am going to open it as an ASCII file: f = open( self.paf, 'r' ) # ASCII byte string file only. except: print "CORNER CASE in __openfile on paf:", [self.paf] print sys.exc_info() raise SystemExit ## Let's see what kind of line 1 we have line1 = f.readline()[:-1] self.__installed = "dirty" # unsure as to the status if line1.upper() == "INSTALLED": self.__installed = "yes" if line1.upper() == "NOT INSTALLED": self.__installed = "no" if self.__installed == "dirty": ## We have a bad pog. #print "ABOUT TO RENAME POG" self.__renameBadPog() raise fontybugs.PogInvalid( self.paf ) ## At this point, we have a valid pog file: ## It has a valid line 1 ## It may or may not have paf lines below it. return f def isInstalled(self): """ Passes a raise PogInvalid error through. Any other will abort app. """ if self.__installed == "yes": return True if self.__installed == "no": return False ## Else it == "dirty" and: ## We must open the file to discover the status: ## Will raise an error, so don't handle it, let it propogate upwards. f = self.__openfile() #sets __installed flag f.close() if self.__installed == "yes": return True if self.__installed == "no": return False def setInstalledFlag(self, TF): """ JULY 2016 ========= In a situation where we have two objects of the same Pog, and one is installed we need to set the other one to installed too. See gui_PogTargets multiClick """ self.__installed = TF def __renameBadPog(self): """ This is a bad pog, My plan is to rename it out of the .pog namespace. No error detection ... yet """ newpaf = self.paf[:-4] + ".badpog" #kick out the .pog and append .badpog #print "Invalid Pog : \"%s\"\nRenaming it to \"%s\"" % (self.paf, newpaf) os.rename(self.paf, newpaf) #just going to hope this works... self.paf = newpaf def genList(self): """ Generate the list of font items within myself. Access the disk. Build the object up. All attribs and the list of fonts. Passes any PogInvalid error directly through. """ f = self.__openfile() #sets install flag, raises PogInvalid error. self.clear() #clear is in basicfontlist.py sourceList = [] ## Right, ## If a line of the CONTENT of f is encoded differently to what the locale is ## then the for paf in f: line throws a UnicodeDecodeError ## This means that paf can't be read, but perhaps others can be... try: for paf in f: #This continues from line 2 onwards ... paf = paf[:-1] #Strip the damn \n from the file sourceList.append(paf) f.close() except UnicodeDecodeError: ## I can't even display the paf because it's not been set ## (paf is the last value that was read, since this is an error condition) ## I don't think I have a choice here but to simply pass pass ## Not using this anymore. #raise fontybugs.PogContentEncodingNotMatched( self.paf ) ## Now to make Fontitems out of sourceList #for fi in itemGenerator( self, sourceList): items_generated = itemGenerator( self, sourceList) for fi in items_generated: self.append(fi) # store them in myself. def purge(self): """ Purge method - remove fonts in the pog that are not on disk. Raises PogEmpty PogInstalled """ ## can't purge an empty pog if len(self) == 0: raise fontybugs.PogEmpty(self.name) # RAISED :: PogEmpty ## can't purge an installed pog if self.__installed == "yes": raise fontybugs.PogInstalled(self.name) # RAISED :: PogInstalled else: ## Let's build a new list of all the bad font items. badfonts = [] for i in self: try: #prevent weird errors on path test... if not os.path.exists(i.glyphpaf) : badfonts.append(i) except: pass # it's bad through-and-through! It'll be axed too. ## Now go thru this list and remove the bad items. for bi in badfonts: #print "purging:", bi.name self.remove(bi) self.write() def install(self): """ Install the fonts in myself to the user's fonts folder. NOTE: Even if ONLY ONE font out of a gigazillion in the pog actually installs, the POG == INSTALLED. If we have a font that cannot be sourced, flag BADPOG For Type1 fonts - The choice I have made is: I will ONLY reference the PFA/B in the Pog file. When we install a Pog, the metric file must be sought in the original folder and linked. Raises: PogEmpty PogAllFontsFailedToInstall PogSomeFontsDidNotInstall NoFontsDir """ # This raises NoFontsDir if it's missing fpsys.iPC.probeNoFontsDirError() def linkfont(fi, frompaf, topaf): ## 15 Sept 2009 : Catch situations where the font ## is already installed. try: os.symlink(frompaf, topaf) #Should do the trick. return True except OSError, detail: ## File exists -- this font is already installed, we ## can ignore EEXIST. if detail.errno != errno.EEXIST: raise ## This font has been linked before. # Use the class in fpsys to manage overlaps. fpsys.Overlap.inc(fi.name) return False ## If this is flagged as installed, then just get out. if self.__installed == "yes": print _("%s is already installed." % self.name) return ## We start thinking all is rosey: self.__installed = "yes" ## Now we make sure ... if len(self) == 0: self.__installed = "no" raise fontybugs.PogEmpty(self.name) # RAISED:: PogEmpty ## Now we go through the guts of the pog, font by font: bugs = 0 for fi in self: ## These os.path functions have been performing flawlessly. ## See linux_safe_path_library remarks (at top) for details. dirname = os.path.basename( fi.glyphpaf ) linkDestination = os.path.join(fpsys.iPC.userFontPath(), dirname ) ## Link it if it ain't already there. if os.path.exists(fi.glyphpaf): # link the font and if True, it was not overlapped, so also # do Type1 step 2 if linkfont(fi, fi.glyphpaf, linkDestination): ## Now, the Type1 step 2, link the metric file. if isinstance( fi, Type1Item ): ## It's a Type 1, does it have a metricpaf? if fi.metricpaf: linkDestination = \ os.path.join( fpsys.iPC.userFontPath(), os.path.basename( fi.metricpaf ) ) linkfont( fi, fi.metricpaf, linkDestination ) else: bugs += 1 if bugs == len(self): # There was 100% failure to install fonts. ## We flag ourselves as NOT INSTALLED self.__installed = "no" self.write() # RAISED :: PogAllFontsFailedToInstall raise fontybugs.PogAllFontsFailedToInstall(self.name) elif bugs > 0: ## Some fonts did get installed, but not all. so, we are INSTALLED self.write() #print " semi [INSTALL COMPLETE]" #print self.__installed # RAISED :: PogSomeFontsDidNotInstall raise fontybugs.PogSomeFontsDidNotInstall(self.name) self.write() def uninstall(self): """ Uninstall the fonts. NOTE: If any font is NOT removed POG = INSTALLED Any links that are not found = just ignore: They could have been removed by another pog, or this could have been a bad pog anyway. NO BAD POG flag EVER. Raises: NoFontsDir PogEmpty PogLinksRemain PogNotInstalled """ ## Make sure fonts dir is there: fpsys.iPC.probeNoFontsDirError() if len(self) == 0: raise fontybugs.PogEmpty(self.name) # RAISED :: PogEmpty bugs = 0 if self.__installed == "yes": for fi in self: #print "*Uninstalling candidate %s" % fi.name if fpsys.Overlap.dec(fi.name): #print " Going to leave this one here" continue # If it overlaps then we skip removing it by going to next fi in loop. #print " Going to REMOVE this one" dirname = os.path.basename( fi.glyphpaf ) link = os.path.join(fpsys.iPC.userFontPath(), dirname ) ## Step one - look for the actual file (link) if os.path.exists(link): try: os.unlink(link) ## The Type1 special case - its AFM/PFM may be here... if isinstance( fi, Type1Item ): ## It's a Type 1, does it have a metricpaf? ## It may be None (if this pfb happens not to have had a afm/pfm.) if fi.metricpaf: pfmlink = os.path.join(fpsys.iPC.userFontPath(), os.path.basename(fi.metricpaf)) if os.path.exists( pfmlink ): os.unlink( pfmlink ) except: # e.g. Permission denied [err 13] ## Only bugs that imply that the file is THERE but CANNOT BE REMOVED ## are classified as bugs. We are making a sweeping assumption here. bugs += 1 ## Okay, we are currently INSTALLED, so what is the result of the loop? if bugs > 0: ## We still have fonts in the pog that could NOT be removed, ergo we stay INSTALLED raise fontybugs.PogLinksRemain(self.name) # RAISED :: PogLinksRemain else: ## Okay - there were no problems, so we are now done. self.__installed = "no" self.write() #save to disk #print " [UNINSTALL COMPLETE]" else: ## self.__installed says we are not installed: raise fontybugs.PogNotInstalled(self.name) # RAISED :: PogNotInstalled def write(self) : """ Write a pog to disk. """ try: f = open( self.paf, 'w' ) # Going to make the contents ASCII only. Byte strings. i = "not installed\n" if self.__installed == "yes": i = "installed\n" f.write(i) #Now write the font pafs for i in self: ## since the glyphpaf can vary it's type ## we must encode it to a byte string if it's unicode. gpaf = fpsys.LSP.ensure_bytes( i.glyphpaf ) f.write( gpaf + "\n") f.close() except: raise fontybugs.PogWriteError(self.paf) def delete(self): """ Delete my pogfile, then clean myself up, ready to be destroyed. """ try: os.unlink(self.paf) except: raise fontybugs.PogCannotDelete(self.paf) self.clear() self.__installed = "no" def zip(self, todir): """Sept 2009 : Add all the fonts to a zip file in todir.""" #print "**ZIP" #print "ZIP:",ipog.name bugs = False fail = False emsgs = [] try: ## Start a zip file: I am not sure if a filename should be bytestrings or unicode.... file = zipfile.ZipFile(os.path.join(todir,self.name + ".fonts.zip"), "w") except IOError as er: emsgs.append( _("I can't write to this directory: {}").format(todir) ) bugs = True fail = True except Exception as er: bugs = True fail = True emsgs.append( "{}".format(er) ) if fail: return (bugs, fail, emsgs) self.genList() for fi in self: ## zipfiles have no internal encoding, so I must encode from unicode to a byte string arcfile = fpsys.LSP.ensure_bytes(os.path.basename(fi.glyphpaf)) try: ## Suppress warnings, which .write emits too much of: with warnings.catch_warnings(): warnings.simplefilter("ignore") file.write(fi.glyphpaf, arcfile, zcompress) #var set global at start of this module. except IOError as er: emsgs.append( _("I can't write to this directory: {}").format(todir) ) bugs = True fail = True ##Fatal bug - get out! break except OSError,er: bugs = True # e.errno == errno.ENOENT: # No such file or directory emsgs.append( "{}".format(er) ) ## July 2016 ## ========= ## Randomly saw this error: ValueError('ZIP does not support timestamps before 1980') ## NOV 2017 ## === ## Going to make a tmp copy of the file and try again: except ValueError,er: emsgs.append( _("Correcting timestamp on {}.").format(arcfile) )#print er try: #make a temp, then copy font there temp_dir = tempfile.gettempdir() temp_path = os.path.join(temp_dir,arcfile) shutil.copy(fi.glyphpaf, temp_path)#should touch it to now ## try the zip again: file.write(temp_path, arcfile, zcompress) os.unlink(temp_path) # rm the tmp file except Exception as er: bugs = True emsgs.append( _("Zip on {} failed because: {}").format(arcfile, er)) file.close() return (bugs, fail, emsgs) fontypython-0.5/fontypythonmodules/gui_PogTargets.py0000664000175000017500000003605013211475353023176 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx ## June 25th 2016 ## Remarking these two lines because they are causing a segfault: ## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get(): ## create wxApp before calling this ## Segmentation fault (core dumped) ## ## I do not know how to test or fix this, hence simply removing it. ## AFAICT, stock buttons will be in the system language. ## ## Setup wxPython to access translations : enables the stock buttons. ##langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG ##mylocale = wx.Locale( langid ) from pubsub import * from wxgui import ps from gui_PogChooser import * import fpsys # Global objects import fontyfilter import fontybugs import strings import fpwx class TargetPogChooser(wx.Panel): """ Chooses target pogs. Houses control buttons. """ def __init__(self, parent, id_zip_pog_button ): wx.Panel.__init__(self, parent, id = -1) target_icon = fpwx.icon( self, 'icon_target' ) target_label = fpwx.large_label(self, _("Target Pogs") ) s = None if fpsys.state.targetpattern == "P": s = fpsys.state.targetobject.name ## The actual list control self.pogTargetlist = PogChooser(self, whoami="TARGETPOG", select = s) ## Subscriptions: ps.sub(target_pog_has_been_selected, self.OnPogTargetClick) ##DND: class TargetPogChooser ps.sub(clear_targetpog_selection, self.SelectNoTargetPog) ##DND: class TargetPogChooser ## The "no pog" button self.idnone = wx.NewId() self.buttNoPog = wx.Button(self, label = _("Clear selection"), id = self.idnone) #self.buttNoPog = wx.BitmapButton(self, self.idnone, # fpwx.wxbmp( "icon_X" ) )#, style = wx.NO_BORDER) self.buttNoPog.SetToolTipString(_("Deselects any chosen Pogs.")) ## The buttons under the pog list ## Giving them all id numbers so my single handler can tell them apart. self.idnew = wx.NewId() self.idinstall = wx.NewId() self.iduninstall = wx.NewId() self.iddelete = wx.NewId() ## Buttons will be handled in wxgui, so we pass ids in __init__ self.idzip = id_zip_pog_button self.buttNew = wx.Button(self, label = _("New Pog"), id = self.idnew ) self.buttNew.SetToolTipString(_("Creates a new, empty Pog")) self.buttInstall = wx.Button(self, label = _("Install Pog(s)"), id = self.idinstall ) self.buttInstall.SetToolTipString(_("Installs all selected Pogs.\n{}").format(strings.ctrl_select_msg)) self.buttUninstall = wx.Button(self, label = _("Uninstall Pog(s)"), id = self.iduninstall ) self.buttUninstall.SetToolTipString(_("Uninstalls all selected Pogs.\n{}").format(strings.ctrl_select_msg)) self.buttDelete = wx.Button(self, label = _("Delete Pog(s)") , id = self.iddelete) self.buttDelete.SetToolTipString(_("Deletes the selected Pog(s)")) self.buttZip = wx.Button(self, label = _("Zip Pog(s)") , id = self.idzip) self.buttZip.SetToolTipString(_("Save a zip file of the selected Pog(s)")) self.list_of_target_pogs_selected = None # will be used in wxgui mainvs = wx.BoxSizer(wx.VERTICAL) self.iconandtext = wx.BoxSizer(wx.HORIZONTAL) self.iconandtext.Add(target_icon, 0, wx.TOP | wx.BOTTOM | wx.LEFT, border = 4) self.iconandtext.Add(target_label, 1, wx.LEFT | wx.BOTTOM | wx.ALIGN_BOTTOM, border = 4) mainvs.Add(self.iconandtext, 0, wx.EXPAND) mainvs.Add(self.pogTargetlist, 1, wx.EXPAND) ## The buttons under the target: gs = wx.GridSizer(3,2) gs.AddMany( [ (self.buttNoPog, 1, wx.EXPAND ), (self.buttZip, 1, wx.EXPAND), (self.buttInstall, 1, wx.EXPAND), (self.buttUninstall, 1, wx.EXPAND), (self.buttNew, 1, wx.EXPAND), (self.buttDelete, 1, wx.EXPAND), ]) mainvs.Add(gs, 0, wx.EXPAND) self.SetSizer(mainvs) ## Bind the events: e=wx.EVT_BUTTON # was wx.EVT_LEFT_UP self.buttNoPog.Bind(e, self.multiClick) self.buttNew.Bind(e, self.multiClick) self.buttInstall.Bind(e, self.multiClick) self.buttUninstall.Bind(e, self.multiClick) self.buttDelete.Bind(e, self.multiClick) self.buttZip.Bind(e, self.multiClick) self.toggleButtons() ## Catch all the button clicks on the control. def multiClick(self, e): ## NEW if e.GetId() == self.idnew: ## New Pog button pressed dlg = wx.TextEntryDialog( self, _("Enter a name for the new Pog"), _("New Pog"), _("Fonty Python")) dlg.SetValue("") if dlg.ShowModal() == wx.ID_OK: nam = dlg.GetValue() if nam == "": ps.pub( show_message, _( "A Pog with no name won't be created, "\ "however it was a good try!") ) ## Is it unique? elif fpsys.isPog(nam): ## Nope, it's there already ps.pub(show_message, _("%s already exists.") % nam) else: ## We have a winner. ## Make a pog object and then write it, ipog = fontcontrol.Pog(nam) try: ipog.write() except fontybugs.PogWriteError, e: ps.pub(show_error_and_abort, unicode( e )) del ipog ## Now put it into the list self.pogTargetlist.AddItem(nam) #ps.pub(add_item_to_notebook, nam) ps.pub( add_pog_item_to_source, nam ) ps.pub( update_font_view ) dlg.Destroy() return ## A list of multiple-selected pog names: tl = self.pogTargetlist multipogs=[ tl.GetItemText(i) for i in xrange(tl.GetItemCount()) if tl.IsSelected(i)] ## DELETE if e.GetId() == self.iddelete: ## Selected Pog(s) to be deleted: tokill = multipogs iPogsToKill = [] ##Is any one of those installed? allok=True for p in tokill: ## Michael Hoeft tested pog delete and noticed the bug. Thanks. ## Fixed Oct 2009 iPog = fontcontrol.Pog(p) if iPog.isInstalled(): ps.pub( show_error, _( "One or more selected Pogs is installed, " \ "fix your selection and try again.") ) allok=False break iPogsToKill.append( iPog ) if allok: ## Build a string for reporting in the dialog if len(tokill) > 1: pogname="" for f in tokill[:-1]: pogname += u"%s," % f pogname += tokill[-1] #We want "remove blah,bloop,zoom, are you sure?" else: pogname=tokill[0] dlg = wx.MessageDialog(self, _("Remove %s, are you sure?") % pogname, _("Are you sure?"), wx.YES_NO | wx.ICON_INFORMATION) if dlg.ShowModal() == wx.ID_YES: ## Let's do them in: for victim in iPogsToKill: #tokill: #fpsys.instantiateTargetPog(victim) #Makes the fpsys.state.targetobject ## Now kill the file on disk: try: victim.delete() #fpsys.state.targetobject.delete() except fontybugs.PogCannotDelete, e: ps.pub(show_error, unicode( e )) return ## Remove from the lists: self.pogTargetlist.RemoveItem(victim.name) ps.pub( remove_pog_item_from_source, victim.name) ## What if it was ALSO our view object? if fpsys.state.viewobject.label() == victim.name: ## It was! We must declare it Empty. fpsys.SetViewPogToEmpty() ## Now re-draw things ps.pub(update_font_view) dlg.Destroy() ## Select no pog. self.SelectNoTargetPog() return ## NO POG pressed if e.GetId() == self.idnone: ## Select No Pog button pressed if fpsys.state.targetobject is None: return #Already done. self.SelectNoTargetPog() ps.pub(update_font_view) return #No need to tell mainframe about this. ## Prepare for Install/Uninstall POG ## install or uninstall all selected pogs - caters for multiple pog selections ## the instantiateTargetPog must be called on each pog-name in the list ## to setup the globals in fpsys. This is new from my previous one-selection only ## code which assumed that instantiateTargetPog had been called already (when pog ## was selected by the mouse) ## Install if e.GetId() == self.idinstall: wx.BeginBusyCursor() for p in multipogs: fpsys.instantiateTargetPog(p) # sets up fpsys.state.targetobject ok=True try: fpsys.state.targetobject.install() except (fontybugs.PogSomeFontsDidNotInstall), er: ## Show a warning, but continue. ps.pub( show_error, unicode(er) ) except (fontybugs.PogEmpty, fontybugs.PogAllFontsFailedToInstall), er: ## Either Pog is empty, or ## not a single font in this pog actually installed. ## It has already been flagged as NOT INSTALLED ps.pub( show_error, unicode(er) ) ok=False except (fontybugs.NoFontsDir), er: #import pdb; pdb.set_trace() ps.pub( show_error, unicode(er) ) ok=False if ok: ## Update GUI ## July 2016 ## ========= ## Added this test to sync view and target ## objects IF they happen to be the samePog if fpsys.state.samepogs: # We installed RHS, so need to set that in RHS # which is a sep object. fpsys.state.viewobject.setInstalledFlag(True) #Causes TWO calls to update BOTH choosers. ps.pub( change_pog_icon ) self.toggleButtons() ps.pub( update_font_view ) wx.EndBusyCursor() ## Uninstall if e.GetId() == self.iduninstall: wx.BeginBusyCursor() for p in multipogs: fpsys.instantiateTargetPog(p) ok=True try: fpsys.state.targetobject.uninstall() except (fontybugs.PogEmpty, fontybugs.PogNotInstalled, fontybugs.PogLinksRemain ), er: ## PogNotInstalled is prevented by buttons ## greying-out in the gui. ps.pub( show_error, unicode(er) ) ok=False if ok: ## Update GUI ## July 2016 ## ========= ## Added this test to sync view and target ## objects IF they happen to be the samePog if fpsys.state.samepogs: # We uninstalled RHS, so need to set that in RHS # which is a sep object. fpsys.state.viewobject.setInstalledFlag(False) #Causes TWO calls to update BOTH choosers. ps.pub( change_pog_icon ) self.toggleButtons() ps.pub( update_font_view ) wx.EndBusyCursor() ## Sep 2009 : ZIP POGS if e.GetId() == self.idzip: ## Nov 2017 ## == ## Moved the zip code into wxgui MainFrame ## it's in a DismissablePanel now. self.list_of_target_pogs_selected = multipogs e.Skip() # fwd the event def OnPogTargetClick(self, args): """ args[0] pogname args[1] is pognochange """ ## Made it so a second click on a target pog ## will unselect it. if args[1]: #pognochange = True, so let's deselect this pog self.SelectNoTargetPog() ps.pub(update_font_view) return try: fpsys.instantiateTargetPog(args[0]) except fontybugs.PogInvalid, e: ps.pub(show_error_and_abort, unicode( e )) return ps.pub(update_font_view) self.toggleButtons() def toggleButtons(self): ## If this is a no target pog situation, hide 'em all. if fpsys.state.targetobject is None: self.buttDelete.Enable(False) self.buttInstall.Enable(False) self.buttUninstall.Enable(False) self.buttZip.Enable(False) return installed = fpsys.state.targetobject.isInstalled() self.buttDelete.Enable(not(installed)) # DELETE button is inverse of installed status self.buttInstall.Enable(not(installed)) # INSTALL button is inverse self.buttUninstall.Enable(installed) # UNINSTALL = True if pog is installed. self.buttZip.Enable(True) def SelectNoTargetPog(self): wx.BeginBusyCursor() ## Go figure out what item gets what image #self.pogTargetlist.toggle_list_icons_according_to_selection( pognochange = True ) self.pogTargetlist.toggle_list_icons_according_to_selection( True ) self.pogTargetlist.ClearSelection() #Select nothing. fpsys.SetTargetPogToNone() # Tell fpsys that we have no pog target selected self.toggleButtons() # Disable the buttons on the bottom right. wx.EndBusyCursor() fontypython-0.5/fontypythonmodules/COPYING0000664000175000017500000010451313211475353020734 0ustar donndonn00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . fontypython-0.5/fontypythonmodules/gui_FontSources.py0000664000175000017500000002417413211475353023375 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2006, 2007, 2008, 2009, 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx, os ## June 25th 2016 ## Remarking these two lines because they are causing a segfault: ## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get(): ## create wxApp before calling this ## Segmentation fault (core dumped) ## ## I do not know how to test or fix this, hence simply removing it. ## AFAICT, stock buttons will be in the system language. ## ## Setup wxPython to access translations : enables the stock buttons. ##langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG ##mylocale = wx.Locale( langid ) from pubsub import * #I want all the topics. import fontybugs import fpsys from wxgui import ps from gui_PogChooser import * from gui_DirChooser import ATree import fontyfilter import fpwx class FontSourcesPanel(wx.Panel): """ A panel to represent the entire Source GUI. """ def __init__(self, parent): wx.Panel.__init__(self, parent, id = -1)#, style = wx.BORDER_RAISED) ## Notebook label and icon view_icon = fpwx.icon(self, 'icon_source') view_label = fpwx.large_label(self,_("Sources: Folders or Pogs") ) ## A horiz sizer to hold the icon and text self.sizer_iconandtext = wx.BoxSizer(wx.HORIZONTAL) self.sizer_iconandtext.Add( view_icon, 0, wx.TOP | wx.BOTTOM | wx.LEFT, border = 4 ) self.sizer_iconandtext.Add( view_label, 1, wx.LEFT | wx.BOTTOM | wx.ALIGN_BOTTOM, border = 6 ) ## Now the actual notebook self.nb = NoteBook(self, name="notebook") ## Make a Vertical sizer to hold them. self.sizerNotebook = wx.BoxSizer(wx.VERTICAL) ## Add them to the sizer. self.sizerNotebook.Add(self.sizer_iconandtext, 0, wx.EXPAND) self.sizerNotebook.Add(self.nb,1,wx.EXPAND) self.SetSizer(self.sizerNotebook) self.Layout() class DirControl(ATree): """ The Directory tree view. Note: Directory names are all UNICODE! """ def __init__(self, parent): if fpsys.state.viewpattern == "F": startdir = fpsys.state.viewobject.path else: ##Let's get it from the config object lastdir = fpsys.config.lastdir if os.path.exists(lastdir): startdir = lastdir else: startdir = os.environ['HOME'] ATree.__init__(self, parent, startdir) ## NOTE: The click event is bound in the Notebook. class NoteBook(wx.Notebook): """ THIS IS THE VIEW or SOURCE of fonts. Has two tabs - Folders and Pogs """ def __init__(self, parent, name="notebook_not_named"): wx.Notebook.__init__(self, parent, style=wx.NB_TOP, name = name) self.imlist = wx.ImageList(16, 16) pan1 = wx.Panel(self) ## THE DIR CONTROL self.dircontrol = DirControl(pan1) # Get a ref to the dircontrol. self.tree = self.dircontrol.GetTreeCtrl() ## Add them to a sizer box = wx.BoxSizer(wx.VERTICAL) box.Add( self.dircontrol,1, wx.EXPAND ) pan1.SetSizer(box) box.Layout() self.pogindexselected = 0 ## The SOURCE POG control pan2 = wx.Panel(self) page = 0 s = None if fpsys.state.viewpattern == "P": s = fpsys.state.viewobject.name if s == "EMPTY": s= None #Very first run, the view will be an EMPTY object. page = 1 self.ctrlPogSource = PogChooser(pan2, whoami="SOURCEPOG", select = s) ps.sub( source_pog_has_been_selected, self.OnViewPogClick) ##DND: class NoteBook ps.sub( select_no_view_pog, self.SelectNoView) ##DND: class NoteBook ps.sub( add_pog_item_to_source, self.AddItem ) #DND: class NoteBook ps.sub( remove_pog_item_from_source, self.RemoveItem ) #DND: class NoteBook ## Dud tree events, causing bad behaviour: ## EVT_LIST_ITEM_SELECTED ## EVT_LEFT_UP ## Bind to another event solve the problem of ## EVT_LEFT_UP firing when the little ## open-branch/tree arrow was pressed. ## 5.3.2009 Michael Hoeft ## Nov 2017: Also subscribe this for use in wxgui - since ## I moved the recurseFolders into there. ps.sub( fake_click_the_source_dir_control, self.__onDirCtrlClick ) self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.__onDirCtrlClick) ## Had a context menu, but not using it. #self.tree.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu) box2 = wx.BoxSizer(wx.HORIZONTAL) box2.Add(self.ctrlPogSource,1,wx.EXPAND) pan2.SetSizer(box2) box2.Layout() self.AddPage(pan1, _("Source Folders")) self.AddPage(pan2, _("Source Pogs")) # sadly, the artprovider icons suck, and I can't get access # to the "stock items" either. Fuck it. source_folder_icon = self.imlist.Add( fpwx.wxbmp('icon_source_folder_16x16') ) source_pog_icon = self.imlist.Add( fpwx.wxbmp('icon_source_pog_16x16') ) self.AssignImageList(self.imlist) self.SetPageImage(0, source_folder_icon) self.SetPageImage(1, source_pog_icon) self.SetSelection(page) # Dec 2017: Remarked this Bind. See notes in old handler #self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, # self.onPageChanged) # Bind page changed event ## If the app is started with a Folder as the Source, then ## check if we must recurse. If so, fake a click to kick that off. ## Sept 2017 if fpsys.state.viewpattern == "F": self.__onDirCtrlClick() # Fake an event def onPageChanged(self, e): """ The notebook page change handler. Remarked the Bind Dec 2017. A click on the notebook tabs should not make assumptions about what source to select. By ignoring this, the new eye icon remains on the last selected directory. It's not perfect, because coming back to the dir control shows what was selected before, but you can't click on the same selection and get a result. You must click-off and click-on to get the view to update. I moved the UnselectAll call into OnViewPogClick so that when you click on an actual source Pog, the tree control now moves out of play. I leave this code for the future. """ self.ctrlPogSource.ClearLastIndex() if self.GetSelection() == 0: # The dircontrol #pass ## I want to force the dir control to clear the selection. ## Reason: When you return to this control (from Pog page), ## the selection from last visit is still there. ## Clicking on it again does NOT UPDATE the font view. ## This is wierd. So, clearing the selection makes it moot. ## This actually works: # wx.CallAfter( self.__onDirCtrlClick) # However.. I think it's weird. # When you click a tab in the notebook, it should # not make assumptions about what you mean. self.tree.UnselectAll() # Found this method in the wxpython book. def __onDirCtrlClick(self, evt = None): if evt: # I want this event to eventually arrive in # the Atree class; thus Skip() # (See gui_DirChooser.py) evt.Skip() # Happens when this handler finishes. wx.BeginBusyCursor() #Thanks to Suzuki Alex on the wxpython list! p = self.dircontrol.GetPath() try: fpsys.instantiateViewFolder( p, fpsys.config.recurseFolders ) fpsys.config.lastdir = p except fontybugs.FolderHasNoFonts, err: pass # update_font_view handles this with a std message. ps.pub(reset_to_page_one)# reset before updating! ps.pub(update_font_view) wx.EndBusyCursor() wx.CallAfter( self.SetFocus ) def OnViewPogClick(self, args): """ args[0] is pogname, args[1] is pognochange """ # Dec 2017: Force no-selection in dir control # so the gui's visual "logic" makes sense: I.e we # are now looking at a Pog, not a Folder any more. self.tree.UnselectAll() ## Check pognochange, it means this is the same pog as last time. if args[1]: return ## instantiateViewPog calls pog.genList which bubbles: ## PogInvalid ## BUT - this error only makes sense from the ## cli pov. By the time the gui is running, that ## pog has been renamed .badpog and therefore ## won't even appear in the list. So, don't bother ## catching it. fpsys.instantiateViewPog(args[0]) if fpsys.state.samepogs: #forbid same pogs selection ps.pub(clear_targetpog_selection) else: ps.pub(reset_to_page_one) ps.pub(update_font_view) def AddItem(self, pogname): self.ctrlPogSource.AddItem(pogname[0]) #[0] bit is because pogname is a tuple from pubsub. def RemoveItem(self, pogname): self.ctrlPogSource.RemoveItem(pogname[0]) def SelectNoView(self): ## Purpose: To select no viewobject and clear view pog list selections ## Called when a TARGET item is clicked AND samepogs it True wx.BeginBusyCursor() self.ctrlPogSource.ClearSelection() fpsys.SetViewPogToEmpty() wx.EndBusyCursor() fontypython-0.5/fontypythonmodules/gui_ScrolledFontView.py0000664000175000017500000002647013211475353024355 0ustar donndonn00000000000000## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . import wx import wx.lib.scrolledpanel from pubsub import * ## June 25th 2016 ## Remarking these two lines because they are causing a segfault: ## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get(): ## create wxApp before calling this ## Segmentation fault (core dumped) ## ## I do not know how to test or fix this, hence simply removing it. ## AFAICT, stock buttons will be in the system language. ## ## Setup wxPython to access translations : enables the stock buttons. ##langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG ##mylocale = wx.Locale( langid ) import collections import fpsys # Global objects from gui_Fitmap import * #Also brings in 'ps' variable class ScrolledFontView(wx.lib.scrolledpanel.ScrolledPanel): """ This is the main font control, the child of CLASS FontViewPanel (in gui_FontView.py). Draw a list of fitmaps from a font list object (derived from BasicFontList). """ def __init__(self, parent): self.parent = parent wx.lib.scrolledpanel.ScrolledPanel.__init__(self, parent, -1, style=wx.VSCROLL|wx.SUNKEN_BORDER) ## Stops to use in fitmap drawing code. white_full = wx.Colour(255,255,255,255) white_zero = wx.Colour(255,255,255,0) black_zero = wx.Colour(0,0,0,0) c=255 ucl = wx.Colour(c,c,c,255) ucd = wx.Colour(c-38,c-40,c-41,255) lbrown = wx.Colour(238,235,234,255) self.gstops = { "white_to_alpha" : wx.GraphicsGradientStops( startCol = white_zero, endCol = white_full ), "baptiste" : wx.GraphicsGradientStops( startCol = lbrown, endCol = white_full ), "underline": wx.GraphicsGradientStops( startCol = ucd, endCol = ucl) } self.gstops["white_to_alpha"].Add(wx.Colour(255,255,255,128), 0.5) self.gstops["underline"].Add( ucd, 0.4) self.SetBackgroundColour(white_full) self.wheelValue = fpsys.config.points self.Bind( wx.EVT_MOUSEWHEEL, self.onWheel ) ## July 2016 ## Sep 2017. New hacks. Might not need this... #self.Bind(wx.EVT_SIZE, self.onSize) self.fitmap_sizer = wx.FlexGridSizer(cols = 1, vgap = 0, hgap = 0) self.SetSizer(self.fitmap_sizer) #self.Fit() self.SetupScrolling(rate_y = 5, scroll_x = False) ps.sub( reset_top_left_adjustments, self.ResetTopLeftAdjustFlag ) ##DND: class ScrolledFontView def onSize(self, evt): """ Set my virtual size to be actual size across, by virtual size down. Cleverly solves much pain. Thanks Anon. """ size = self.GetSize() vsize = self.GetVirtualSize() self.SetVirtualSize( (size[0], vsize[1]) ) evt.Skip() def onWheel( self, evt ): """ Added Dec 2007 Change point size with ctrl+scroll """ n = 10 if evt.GetWheelRotation() < 0: n = -10 if evt.ControlDown(): self.wheelValue += n if self.wheelValue < 10: self.wheelValue = 10 if self.wheelValue > 200: self.wheelValue = 200 fpsys.config.points = int(self.wheelValue) ## Tried to restore the scrollbar, but it crashes the app ##xPos, yPos = self.GetViewStart() self.ResetTopLeftAdjustFlag() ## Sept 2009 : size change means we need new values for fitmaps ##fpsys.state.point_size_changed_flag = True #TODO Kill: fpsys.state.reflow_only = False ps.pub( update_font_view ) # starts a chain of calls. ##fpsys.state.point_size_changed_flag = False ##fpsys.state.reflow_only = True return ## Keep the wheel event going evt.Skip() # Sept 2009 def ResetTopLeftAdjustFlag( self ): ''' Each fitem has a top_left_adjust_completed flag. False forces the fitmaps to re-calculate the adjustment for top-left. (Only when a call to update_font_view happens, of course.) ''' for fi in fpsys.state.viewobject: fi.top_left_adjust_completed = False def MinimalCreateFitmaps( self, viewobject): """ Note: I am not rendering the fitmaps when the frame's size changed. """ #print "-------------------------" #print "MinimalCreateFitmaps runs" self.Freeze() panelwidth = max(420,self.GetSize()[0]) #First run it's weird. After that it works. #print self.GetSize()[0] if len(viewobject) == 0: self.fitmap_sizer.Clear(True) # Wipe-out the past empty_fitem = fontcontrol.InfoFontItem() fm = Fitmap( self, empty_fitem ) # force the width down a little. I want # wrapping to happen when window is too # small. #panelwidth = self.GetSize()[0] #print panelwidth #panelwidth = max(360,self.GetSize()[0]) #First run it's weird. After that it works. #if panelwidth < 300 pw = panelwidth - 25#(panelwidth/4)) fm.assemble_bitmap( pw ) self.fitmap_sizer.Add( fm ) else: # Let's compare what we had before (the contents of the sizer!) with what # is coming-in new, i.e. the viewobject list. #print self.fitmap_sizer.GetChildren() td = {} for kid in self.fitmap_sizer.GetChildren(): fitmap = kid.GetWindow() #is the fitmap within fitem = fitmap.fitem if fitem not in viewobject: ## If the fitem is not one we want to show: ## 1. Remove it from the sizer ## 2. Destroy it. #print " ..Murdering:", fitmap.name self.fitmap_sizer.Detach(fitmap) fitmap.Destroy() else: ## This "old" fitmap is okay, let's keep it aside. td[fitem]=fitmap w=[] # widths for fitem in viewobject: # Seek it in the dict we just made: fm = td.get(fitem, None) if not fm: ## the fitmap was not found, it must be instanced fm = Fitmap(self, fitem) td[ fitem ] = fm # Store it for just now ## Since their states may have changed, we do the ## render_and_measure_glyphs on all fitmaps again: wid = fm.render_and_measure_glyphs() ## Record the width, but if it's wider than the panel ## just chop it. It's an asshole anyway. w.append(min(wid, panelwidth)) # Clear the sizer. Docs say this "detaches" all children. # Therefore, the fitmaps that were in there, are no longer in there. # (They are physically laying about in the parent - the FontViewPanel.) # In a moment, we'll re-add all the relevant fitmaps to the sizer, # so everything kind of works-out. I hope... self.fitmap_sizer.Clear() # ..(True) murders the fitmaps. We no like. Hisssssss! self.Scroll(0,0) # Immediately scroll to the top. This fixed a big bug. ## Let's bother with all the math if columns are even a thing: if fpsys.config.max_num_columns > 1: ## Credit to Michael Moller for clueing me onto "standard deviation". ## My soluition: Take the mean of the widths and add a bit "more". lw = len(w) # cannot be 0. I feel confident! sw = sum(w) #print w ## 1. Standard Deviation ## Calc the variance by subtracting each width from the ## average and then taking the square summing along. ## Calc the std deviation by sqrting that variance. a = sw / lw # the average sd = ( sum( ( a - i ) **2 for i in w ) / lw ) ** 0.5 ## 2. I also get av of that std deviation, just to ## shorten it a little bit "more". asd = sd / lw ## 3. My result is the sum of these two. avw = a + asd ## Can we afford some columns? ## ..Also prevent any poss div by 0 cols = max( 1, int(panelwidth / max(avw, 1) ) ) #Nov 2017: New option in settings to control columns" cols = min( cols, fpsys.config.max_num_columns ) ## Get a better actual width for the columns! ## ..Also prevent any poss div by 0 colw = int(panelwidth / max(cols, 1)) else: cols = 1 colw = panelwidth #print "colw:",colw self.fitmap_sizer.SetCols(cols) ## Loop viewobject, get fitmaps, prep them with the new width ## and then plug them into the sizer for fitem in viewobject: fm = td[ fitem ] # we get them from the dict #print fm #print colw fm.assemble_bitmap(colw) self.fitmap_sizer.Add(fm, flag=wx.wx.ALIGN_BOTTOM) # Here we re-add the fitmaps. self.fitmap_sizer.FitInside(self) ## Trying this freeze/thaw thing. Not sure if there's any advantage. self.Thaw() #print "====EXIT MinimalCreateFitmaps=====" """ Unused algorithms in MinimalCreateFitmaps if alg==1: percent = .2 # == 10% def trimmed_mean(data, percent): # sort list data = sorted(data) # number of elements to remove from both ends of list outliers = int(percent * len(data)) # remove elements data = data[outliers:-outliers] return sum(data) / len(data) avw = trimmed_mean(w, percent) elif alg==2: ## A hacky trimmed mean mess l = len(w) if l < 3: avw = sum(w)/l else: ## When the widths are all similar, it's hard to know ## which to discard... Too much math for my head. :( avw_tm = max( 1, (sum(w) - max(w) - min(w)) / l-2 ) avw_foo = sum(w)/l avw = min(avw_foo, avw_tm) # a hack to prefer fewer cols """ fontypython-0.5/fontypythonmodules/fpversion.py0000664000175000017500000000171413211475425022265 0ustar donndonn00000000000000#!/usr/bin/env python # This Python file uses the following encoding: utf-8 ## Fonty Python Copyright (C) 2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . ##I am going to alter this in releases/ dir only. After a branch has been made etc. version="0.5" fontypython-0.5/CHANGELOG0000664000175000017500000003202513211475353015117 0ustar donndonn00000000000000Changelist ========== Latest entries at the bottom. Jan 4 2008 : FP version 0.3.1 * Fixed img height/width bugs in help file. It scrolls smoothly now. * Fixed startup bug when last folder viewed no longer has any fonts. * Fixed some text in strings. * Improved the setup.py system to use i18n, strings and fpversion modules. * Added Italian translation (Thanks to Pietro Battiston) Jan 10 2008 : FP version 0.3.3 * Fixed setup.py bug - should install properly now. * Tweaked some gui things - like spacing. * Added a clear button for the filter. * Major overhaul of the Type1 code in fontcontrol. Jan 18 2008 : FP version 0.3.4 * Did a lot of locale/unicode work to support LANG=C * Added a tool to 'check' fonts - marks segfaulters * Added long command-line options * Repairs to help file * Many bugs fixed, new ones created :) Jan 20 2008 : FP version 0.3.5 * Added a .desktop file and an icon - changes to setup.py Jan 22 2008 : FP version 0.3.6 * Fixed another font bug (0 width). * Bad wxImage badfont catch - draws a yellow block like a segfont. * Made the Check Font dialog work a lot better. feedback & better layout. * Updated the po/mo files, but no new translating has been done. 11 June 2009 1. Changed many button events to wx.EVT_BUTTON for better behaviour ) 2. Fixed Bug 2 (wxgui) -- The Tab->Folder->Last Directory->Show Fonts bug. 3. Changed cli, fontcontrol, strings and wxgui to allow recursive folders. 12 June 2009 1. Adding a Search Assistant panel. It's full of junk from the wxDemo at the moment. 2. Added/Edited ROADMAP after reading email from Michael. 3. Removed Select All button. RIP bad idea :) 4. Added Selection menu and it's sub-items. Wired-them up to the remains of the Select Button code. 5. Fixed the PogChooser issue betwixt source and target. 6. Split-off most of wxgui.py classes into their own gui_xxx.py modules. Trying to make it simpler. We now have gui_Left, gui_Middle and gui_Right for the main sections. 13 June 2009 1. Continued the refactoring. Moved functions to where they made more sense. Cut down on chains of calls. 2. Got rid of shadow functions. At last! 3. Put refs to locale stuff into the new modules, BUT HAVE NOT TESTED i18n yet. HELP! 4. Improved the pubsub a tiny little bit. Also removed the return value -- it was not being used. 5. Fixed strings GPL message. It loads it from the COPYING file. 6. Hacking a search bar together from a combo box and some spare bits :) 14 June 1. Got the search combo box working a little. History is added etc. 16 June 1. Fixed the bug where the first fitmap in the fontview would draw at an odd y value. 2. Fixed the persistent InfoFontItem issue. Now it goes away when it should. 18 June 1. Many visual fixes. Re-factored the drawing code in Fitmap. 2. Many little fixes like toggle selection menu and multi-selection on/off in the lists. 19 June 1. Gave up on the fancy search dream. FontTools and Panose confuse me horribly. Michael can't help dev at the moment, so it's all back to square one. I remarked-out the assistant panel. 2. I got the left and right arrow keys to step through the list - like the buttons do. 3. I (think I) fixed the ESC key to work from anywhere. 20 June 1. Cleaning-up files etc. Lot's of little zipzap commits. Yesterday I merged the branch back into the trunk. 2. Caught an encode and decode problem in Folder.__init__. Had to jump through the usual unicode hoops to fix it. Hope it is fixed now... 3. Added the licence header to a bunch of files it was missing from. 4. Small fixes to README regarding i18n. 5. Fixing some unicode errors and error dialog boxes. 6. Trying to repair the "lost focus" bug when the main button is clicked -- so far no dice. 22 June 1. Rigged the main button so that focus is not lost on click. It's a hack, but what the heck. 26 June 1. Main button focus issue has a hack-fix 2. Delete multiple pogs at once from the gui. 3. Fixed the help text. Changed the app screenshot. 4. Moved the Purge function out to the File menu. It now applies to the VIEW POG selected. 26 June 1. Added a test to prevent fonts re-drawing when a new target Pog is clicked. 2. Added help about the Purge menu item. 26 June 1. Reversed decision to not redraw the target Pog. There are too many subtleties involved for the hammer-and-nail approach I took and I just don't have time to be subtle now. So, it will redraw when you choose another target Pog. Tough. 27 June 1. Changed left/right arrow to pageup/pagedown. Michael Hoeft warned of the damage to editing the search term. 2. Improving the splash image. 27 June 1. Fixed ref to page up/down keys in help. 28 June 1. Upon reflection, the arrow keys are easier than page up/down. So, I added CTRL as a modifier. Now it's ctrl+left/right to step through the pages. (Help updated too.) 29 June 1. Repaired the .desktop file to comply with HIG. 30 June 1. Changed selection menu item toggling system. Recently read a little Gnome HIG :) 1 July 1. Changed logo in help, about and splash. 2. Altered setup.py to remove MANIFEST file if it's there. Unless it's removed, setup.py sdist will potentially miss new files. 6 July 2009 1. Fixed a problem with setup.py that was making ~/.fontypython folder (and as root too). That folder now only gets made when the app is run for the first time, not during setup. Thanks to Pietro for catching this one. 7 July 1. Pietro sent us an Italian .po file. I did "make mos" and I hope that was right. 2. Removed some _() stuff from CORNER CASE error messages. 3. Redacted pofiles/README file somewhat. 24 July 1. A bug was caught by Michael Hoeft - the combo box (for search field) requires wxPython 2.8 -- So we had to shift a few things around. After a false start, I have created version 0.4.1 and am about to upload to the ftp site. 15 Sept 2009 1. Fixed a bug where fonts that are already installed would refuse to install again. It ignores OSError 17 now. 2. Added zip function -- zip all fonts in a pog(s) for easy distribution. 3. Moved to vers 0.4.2 16 Sept 1. Removed irritating message dialogs from zip function. 2. Removed pofiles directory from MANIFEST.in so they do not go into the tarball 3. There is a weird bug in the zip files -- when you unzip one there are odd files that want renaming... Not sure what this is yet. 4. Changed File menu to Tools menu. 5. Added error catch and report to zip. 6. Improved directory dialogue for zip. 7. Fixed help file and image. 18 Sept Added reference counting to fonts that are shared/common among pogs: When a pog is uninstalled *and* another installed pog has the same font(s), those fonts are left installed. 19 Sept 1. A long day of tidying-up and abstracting the unicode/str stuff. 2. Gone a long way to a standard error approach. Still have some loose ends. 21 Sept 1. Adding icons for the various font items that are bad in some way. 2. Tweaking colours and effects to look better 3. Trying to get the widths of fitems to fit the middle panel. Kind of working, but not on first run. 22 Sept 1. Got a workaround for fitem widths going. 2. Improved the rendering of fitems under various conditions. 3. Removed fatfont. 22 Sept 1. Changed button on Check fonts form to 'Close' -- makes more sense now. 24 Sept 1. Major update of help file and graphics. 2. Trying to fancy-up the info label in the font-view. So far no luck. 3. Got the label going! Made a custom control. 25 Sept 1. Improved the drawing of fitmaps and gradients. Still have some precalcing of colours to do. 2. Tweaked the images and icons. 26 Sept 1. Added a sunken border to font view -- better visual containment I think. 27 Sept More gui polishing done. Strings changed -- PO files will be broken :( 28 Sept 1. Seems PO files are quite robust -- the strings are marked as 'fuzzy' and should still translate fairly well. 2. Today I will make a 'release' branch on the SVN and get the tarball for 0.4.2 going. 28 Sept : Feedback from Kartik 1. Removed the Version tag from .desktop file -- it's not required. 2. Removed the .png from the icon key in .desktop file -- it's not wanted. 3. Some confusion as to whether fonty will run 100% on Python 2.5, I developed this year on 2.6 4. Version bumped to 0.4.2.1 29 Sept 1. Working on a way to scan the font images and remove that leading blank space on certain fonts. Done, and included an override in settings dialog. 30 Sept 1. Spent the *ENTIRE* day fighting the damn splitter and sizers. Not really sure why or how, but I got it working okay. I also don't really know what broke from last version! 1 Oct 2009 1. Renamed 'fp' script to 'start_fontypython' - had to edit a bunch of files. 1.1 It turns out that fonty has been running without the segfault catcher all along. This should be remedied as of now. Backported fix to 0.4.2.x as well. 2. Taking-over the maintenance of the man page. I will leave it in the root of the tarball and Kartik will deal with it from there. Backported to 0.4.2.x 2 Oct 1. Spot changes. Made label above font views look better. 2. Started adding threading so that Fonty can spawn gucharmap or kfontview on a given fitmap in the view. 3 Oct 1. Fixed a bug in Delete Pogs -- reported by Michael Hoeft. Backported to 0.4.2.2 as well. 2. Adding an 'Voodoo' tab to Settings dialogue to house the charmap choice and the font adjustment checkbox. Wired it all up and it works! 4 Oct 1. Built a button to spawn the character-map app. Nice rollover and all. 2. Updated the help. 3. Created three buttons Bold, Italic and Regular for quick filtering. 4. Updated man page 5 Oct 1. Segfault dialogue suddenly started causing segfaults of its own... Sheesh. I had to remove a box sizer to get it to work. 2. Fixed bug in character map viewer code. 3. Small repair to BIR toggles. 11 Oct 1. Fixed a config startup bug - whatever charmaps are found, the first in the list is now taken as the default else None. 2. Made the default size 800x600 with left sash 200. 3. Made custom icons for the dir control. 4. New screenshot for the help file. 5. Tweaked zip name to xxxx.fonts.zip so it's obvious what it contains. 6. Adding the design files (Inkscape stuff) to the trunk so that others can use them. 7. "fixed" another wee bug in charmap default choice.I hope... 12 Oct 1. Made a new module to better deal with the charmap viewer wiring. 2. Removed the bitmap toggle buttons for B I R : they sucked. Normal toggle buttons will be used until wxpython can get bitmap buttons right. 13 Oct 1. Removed the -t --text= comand-line option. It was totally useless. 2. Fixed the strings.py file to reflect 1. 3. Fixed the man page too. 2016 ==== June and July ------------- Had issues with new versions of wxPython and PIL. These reflected in various bugs and some code had to be removed, while other parts had to be altered. 1. Removing langid & mylocale from all gui files. This has caused a break (I think) in the stock buttons (e.g. GO_FORWARDS) which no longer display their icons. 2. Bumped minimal version of wxPython test to 3.0 3. Added an "Id" to the all wx list items to keep up with changes in wx. 4. Added a try block to handle changes to new PIL. Old PIL uses tostring, new PIL wants tobytes. 5. Added a new exception for missing ~/.fonts dir. 6. In install(), added a test for missing ~/.fonts dir. 7. ~/.fonts tests in cli.py 8. Fixed the search filter. Bold, Italic, Regular as well as (partial) Family name! 9. Changed the splash screen to appear early and stay for a few seconds. 10. Adjusted help screen's width to be more narrow. Also allow the help window to be resized. 11. Various changes to art (svg, png) as well as help text. 12. Replaced next/prev buttons with bitmapbuttons because stock icons are not working on gtk3. (Could be related to item 1 in this list.) 13. Added test for None where font's name/fam/style are pulled from PIL. 14. Caught a weird exception in zip concerning files older than 1980. 15. Sync installed state between view & target objects IF they are the same Pog: on install and uninstall. 16. Altered the purge menu's label to include the selected Pog name. 17. Edits in README and this file, the CHANGELOG 2017 ==== Sept to Dec ----------- 1. Re-wrote large sections of Fonty. The gui is quite different and looks a lot better. 2. Added the "Hush" functionality after a long time of dreaming about it and then more time trying to hack fontconfig. I got some help on their mailing list and it quickly got done. 3. I moved a lot of dialogues into in-app panels. I think it looks great. 4. Converted all py files from tabs to four spaces. 5. All new icons and logo. A general freshen. 6. Fixes many bugs in the command-line usage. Added new ones like cat, lsfonts and hush. 7. Move to the XDG standard paths: $HOME/.local/share and so forth. Fonty should upgrade the older files into the new locations. All Pogs remain the same - they will simply be moved to the new fontypython directory. 8. Made the font-view show fonts in columns to fit more on a screen. This was extremely hard to do and there are still bugs. Over all, I think it looks good too. The future ========== If wxPython does not release their Python 3 compatible library soon, then Fonty may hit a wall around 2020, when Python 2.x is dropped. I might not have the time or health to code anyway. We'll see. fontypython-0.5/setup.py0000664000175000017500000002057313212237727015426 0ustar donndonn00000000000000#!/usr/bin/env python ## Fonty Python Copyright (C) 2006,2007,2008,2009,2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . """ This is the main setup file for fontypython. Requires a Python less than version 3. Sorry. You should run: python setup.py install --force ..as root in order to use it. Perhaps: sudo python setup.py install --force You can also simply run ./fontypython from this directory and it should work - provided you have all the dependencies installed. See the README file. Much code borrowed from wxPython's setup and config files. Thanks to Robin Dunn for the suggestions. """ #NOTES #== #None of the imports touches fpsys in any way. #Thus, there is no iPC instanced. Thus there should #be no running of the code that upgrades old fonty #to new (and makes files/directories), which is good #because setup is run as root! import fontypythonmodules.i18n import fontypythonmodules.sanitycheck import fontypythonmodules.fpversion import os, shutil, sys, glob, fnmatch from distutils.core import setup#, Command#, Extension import distutils.command.install_data import distutils.command.install_lib def opj(*args): path = os.path.join(*args) return os.path.normpath(path) # Specializations of some distutils command classes class wx_smart_install_data(distutils.command.install_data.install_data): """ By Robin Dunn. Need to change self.install_dir to the actual library dir. """ def run(self): install_cmd = self.get_finalized_command('install') self.install_dir = getattr(install_cmd, 'install_lib') return distutils.command.install_data.install_data.run(self) class fp_smart_install_lib(distutils.command.install_lib.install_lib): """ Happens before the files are copied into dist-packages I hook in here and rm -fr the entire old fontypythonmodules directory. Gulp. """ def run(self): install_cmd = self.get_finalized_command('install') self.install_dir = getattr(install_cmd, 'install_lib') print " > Starting cleanup of old files." last_fpm = opj(self.install_dir, 'fontypythonmodules') # Only do this thing if the file is there: if os.path.exists( last_fpm ): try: print " > Old fontypythonmodules: {}".format( last_fpm ) shutil.rmtree( last_fpm ) except: print " > Failed." # Also kick out the old script that might remain in install_dir start_fp = opj(self.install_dir, 'start_fontypython') if os.path.exists(start_fp): print " > Old start_fontypython script." try: os.unlink(start_fp) except: print " > Failed." old_logo = '/usr/share/pixmaps/fontypython.png' if os.path.exists(old_logo): print " > Old logo." try: os.unlink(old_logo) except: print " > Failed." return distutils.command.install_lib.install_lib.run(self) def find_data_files(srcdir, *wildcards, **kw): """ Get a list of all files under the srcdir matching wildcards, returned in a format to be used for install_data """ ## A list of partials within a filename that would disqualify it ## from appearing in the tarball. badnames=[ ".pyc", "~", "no_", ".svn", "CVS", ".old", ".swp", "who_did_what" ] #has email @ddys in it. def walk_helper(arg, dirname, files): BL=[ bad for bad in badnames if bad in dirname ] L=len( BL ) if L > 0: # There is a bad string in the dirname, so we skip it return names = [] lst, wildcards = arg for wc in wildcards: wc_name = opj(dirname, wc) for f in files: filename = opj(dirname, f) ## This hairy looking line excludes the filename ## if any part of one of badnames is in it: L=len([bad for bad in badnames if bad in filename]) if L == 0: if fnmatch.fnmatch(filename, wc_name) and not os.path.isdir(filename): names.append(filename) if names: lst.append( (dirname, names ) ) file_list = [] recursive = kw.get('recursive', True) if recursive: os.path.walk(srcdir, walk_helper, (file_list, wildcards)) else: walk_helper((file_list, wildcards), srcdir, [os.path.basename(f) for f in glob.glob(opj(srcdir, '*'))]) return file_list ## Remove tmp stuff try: os.remove("MANIFEST") os.remove("PKG-INFO") except: pass # Dec 2017 # == # I simplified the MANIFEST.in file to contain the minimum. # It's a pos anyway. It only cares about the 'setup.py sdist' # command and plays no role in a 'setup.py install'. Ffsks. # The MANIFEST only bothers with the man page and itself. # All other files must be explicitly included in the 'files' # object. # Everything under fontypythonmodules: # Update: '*' casts a wider net. It now catches the README # ======= and COPYING files in the tree. (See badnames too.) # I must keep the contents of this directory very clean! # files = find_data_files('fontypythonmodules/', '*.*') files = find_data_files('fontypythonmodules/', '*') # Jan 20 2008 - Add an icon and .desktop file # Got this info from: # https://specifications.freedesktop.org/icon-theme-spec \ # /icon-theme-spec-latest.html # The standard paths are: # /usr/share/icons/hicolor/.... targetpaf ='/usr/share/icons/hicolor/{}/apps/' localpaf = 'icons/hicolor/{}/apps/' icons = ['32x32', '48x48', '64x64', 'scalable'] for i in icons: _to = targetpaf.format(i) _from = localpaf.format(i) _icon = opj(_from,'fontypython.{}') _icon = _icon.format( 'svg' if i == 'scalable' else 'png' ) files.append( (_to, [_icon]) ) files.append( ('/usr/share/applications',['fontypython.desktop']) ) #files.append( ('/usr/share/pixmaps',['fontypython.png']) ) # Leave the man page up to Kartik. # files.append( ('/usr/share/man/man1',['fontypython.1']) ) # Just put these into the modules dir too. files.append( ('fontypythonmodules',['README', 'CHANGELOG']) ) ##TEST: debug = False if debug: import pprint pprint.pprint (files) print raise SystemExit ## Off we go! setup( name = "fontypython", version = fontypythonmodules.fpversion.version, description = fontypythonmodules.strings.description, author = "Donn.C.Ingle", author_email = fontypythonmodules.strings.contact, license = "GNU GPLv3", url = "https://savannah.nongnu.org/projects/fontypython/", packages = ['fontypythonmodules'], data_files = files, # Borrowed from wxPython too: # Causes the data_files to be installed into the modules # directory. # Also hooking the install_lib phase to clean old files # before the install_data happens. cmdclass = { 'install_lib': fp_smart_install_lib, 'install_data': wx_smart_install_data, }, # 'fontypython' is in the root and is the only executable: scripts = ["fontypython"], long_description = fontypythonmodules.strings.long_description, classifiers = [ 'Development Status :: 6 - Mature', 'Environment :: X11 Applications', 'Intended Audience :: End Users/Desktop', 'License :: OSI Approved :: GNU General Public License (GPL)', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python', 'Topic :: Desktop Environment', 'Topic :: Text Processing :: Fonts', 'Topic :: Multimedia :: Graphics', 'Topic :: Utilities', ] ) fontypython-0.5/fontypython.10000664000175000017500000000662013211475353016372 0ustar donndonn00000000000000.TH "FONTYPYTHON" 1 "2009-2017" "" "" .SH NAME fontypython \- Find, view and manage font files of all kinds. .SH SYNOPSIS .B fontypython [\fIOPTIONS\fR]... [\fIVIEW\fR]... [\fITARGET\fR]... .SH DESCRIPTION .B Fontypython is a GUI utility written in Python and WxPython that will help you do font stuff on GNU/Linux system. You can quickly view and filter arbitrary* TTF, TTC, OTF, OTC, WOFF or Type1 font files and then gather them together into 'Pogs' which can be .B installed or removed as needed. In this way you control which fonts are installed on a per-project basis. Fonty also includes a new "Hush" mechanism for stilling the noise of system fonts. Use this when you want to work with .B only the fonts that you wish to see. .PP If you have .B gucharmap or .B kfontview installed, (there is an option in Settings to choose which one) you can view any font's character maps etc. .PP *Arbitrary means you can .B see and/or use .B any fonts in a local directory (or a mount). They .B do not need to be installed on your system. .PP .SH VIEW TARGET .TP \fB VIEW A place where fonts are. A Pog or a folder someplace. Also called a "source." .TP \fB TARGET A "Pog". A place to keep those fonts (just references to them). .SH OPTIONS Below are some of the main command-line options. See help for all of them. You don't need to use them, but they are handy. The program will run as a GUI if you only invoke 'fontypython'. .TP \fB\-h\fR, \fB\-\-help\fR Show help message and exit. .TP \fB\-h b\fR, \fB\-\-help b\fR Shows the basic help information. .TP \fB\-h e\fR, \fB\-\-help e\fR Shows some %$@#$ examples! .TP \fB\-h hush\fR, \fB\-\-help hush\fR Shows the basic help about hushing system fonts. .TP \fB\-l\fR, \fB\-\-list\fR List the names of all the Pogs. .TP \fB\-i\fR Pog, \fB\-\-install\fR=\fIPog\fR Install the fonts in this Pog to your fonts folder. .TP \fB\-u\fR Pog, \fB\-\-uninstall\fR=\fIPog\fR Uninstall the fonts in this Pog. .TP \fB\-p\fR Pog, \fB\-\-purge\fR=\fIPog\fR Purge the Pog of font files that are no longer really there. .TP \fB\-c\fR folder \fB\-\-check\fR=\fIfolder\fR Check for bad fonts that crash the program. It will recurse through sub-folders. This will build a file named "segfonts" in your fontypython directory. After using this tool, you should be able to browse safely. (The reason it's not done by default is that it's very slow). NOTE: The fonts that crash the program are probably still perfectly good and can be used in other apps. .TP \fB\-a\fR folder Pog, \fB\-\-all\fR=\fIfolder Pog\fR Puts all fonts in this folder into the Pog. If the Pog already exists, it will add only *new* fonts, this means fonts are not repeated in that Pog. .TP \fB\-A\fR folder Pog, \fB\-\-all\-recurse=\fIfolder Pog\fR Puts all fonts in this folder and *all* sub-folders into the Pog. Rest same as \-a. .TP \fB\-z\fR Pog, \fB\-\-zip=\fIPog\fR All the fonts inside Pog will be zipped and the zip file will be named after the Pog. The file will be placed in the current directory. .TP \fB\-\-version\fR Show program's version number and exit. .SH SEE ALSO .BR Homepage: .BR Tickets: https://savannah.nongnu.org/bugs/?group=fontypython .SH AUTHOR fontypython was written by Donn.C.Ingle . .PP This manual page was updated by Donn Ingle in December 2017. It was originally written by Kartik Mistry , for the Debian project (but may be used by others). fontypython-0.5/fontypython0000775000175000017500000000263413212036010016217 0ustar donndonn00000000000000#!/usr/bin/env python ## Fonty Python Copyright (C) 2006-2017 Donn.C.Ingle ## Contact: donn.ingle@gmail.com - I hope this email lasts. ## ## This file is part of Fonty Python. ## Fonty Python 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 3 of the License, or ## (at your option) any later version. ## ## Fonty Python 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 Fonty Python. If not, see . """ This is the main and only executable file for fontypython. This file is kept simple so that it parses as either version 2 or 3 of Python. For that reason there are no imports to fetch i18n etc. """ import sys, os if sys.version_info >= (3, 0): sys.exit( "Sorry, fontypython requires Python 2.x, " \ "you are using Python 3.x.\n" \ "From the command line, try:\n" \ "python2 fontypython" ) if os.name != "posix": sys.exit( "Sorry, only Gnu/Linux is supported." ) if __name__ == "__main__": import fontypythonmodules.segwrapfonty fontypython-0.5/MANIFEST.in0000664000175000017500000000004213212036010015415 0ustar donndonn00000000000000include fontypython.1 MANIFEST.in fontypython-0.5/README0000664000175000017500000001221713212237744014567 0ustar donndonn00000000000000Fonty Python Copyright (C) 2006,2007,2008,2009,2016,2017 Donn.C.Ingle donn.ingle@gmail.com Fonty Python comes with ABSOLUTELY NO WARRANTY; for details see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; see the COPYING file for details. TICKETS ======= https://savannah.nongnu.org/bugs/?group=fontypython Future maintainers ================== Please read DEVNOTES. UPDATED DEC 2017 A Note on Python 3 ============== I want to move to Python 3, but my toolkit (wxPython) has not released their Python 3 compatible wxPython 4.x for Linux. This means I am stuck on Python 2.x for an unknown span. I hear that Python 2.x is being discontinued in 2020. I don't know what that means. If the distros drop Python 2.x at that point, then Fonty will die right there. Let's see. NB: Try to remove the old version BEFORE you install FP. ============== You can find the path by: locate fontypythonmodules If that does not work, then you must update your locate database: As root run: locate -u Go make coffee. Then run the locate command above again. This will give you a directory something like: /usr/lib/python2.5/site-packages/fontypythonmodules Use your root account to remove that folder: cd /usr/lib/python2.5/site-packages sudo rm -fr fontypythonmodules (Be *very* careful what you type!) You should be good to go now. How to install ============== Please see the end of this file if your install fails, there are certain files that FP relies upon. I assume you have extracted the "tarball" already. Change to the directory it created. As the root user enter this command: python setup.py install --force You might need to use sudo: sudo python setup.py install --force * Please do use the --force flag, or there may be old files from the last version of Fonty that can cause bugs. This will create a program called 'fontypython' Alternative installation ======================== Move the entire extracted folder to a folder that is in your PATH, like ~/bin Make a link to the fontypython script like this: (for e.g.) tar -s ~/bin/fontypython-x.x.x/fontypython . Make it executable: chmod u+x fontypython Now you should be good to go. If it does not work, try closing your console and starting it again. Refreshing the icon cache ========================= I found that Fonty's icons don't appear at first. To refresh the cache (on Ubuntu, at least) try: sudo update-icon-caches /usr/share/icons/* (There's also: gtk-update-icon-cache) Running the program =================== To get started on the console: fontypython -h For exmaples ('e'): fontypython -h e For the gui, run fontypython (Hit F1 for in-app help) Troubleshooting the installation ================================ Fonty Python depends on several other libraries: ( These are minimum version numbers ) 1. python2.4 to python2.7 (Not python3) 2. python-dev (odd one this. See notes below) 3. python-pil (The "Pillow" module has replaced the old PIL one.) 4. python-wxgtk3.0 (Not 4.x, which is unreleased.) Items 1 and 3 are usually pre-installed on Gnu\Linux distros. Item 2 is a new twist. I am not sure why it's required for FP (yes - I don't know everything :)) but some users have had problems and installing python2.4-dev fixed them. (replace 2.4 with the actual version of python you are using.) On *buntu: sudo apt-get install python2.4-dev If you cannot install item 2 - try the alternative installation instructions above. Item 3 - python-imaging is known as the PILLOW library. It should be available in your repo. I used vers 3.1.2 to develop. Make that the min. Item 4 may be installed, or it may be in your distro's main repository.To install item 4, try the following: On *buntu/Debian: apt-cache search python-wxgtk Find the latest version in the list, then: sudo apt-get install python-wxgtkX.Y (replacing X.Y with the results of your search) After this has all installed, try to run fontypython again. If you still do not come right, then I advise you to go to the following web sites for help directly from the horse's mouth: http://wxpython.org https://python-pillow.org/ Or open a ticket on our site: https://savannah.nongnu.org/bugs/?group=fontypython LOCALIZATION TIPS ================= Make sure your LANG variable is set properly. To run under a locale, do something like this: LANG=en_ZA.utf8 ./fontypython You can find your locales by: locale -a If localization is not working it could be that there is no translation for your language yet, it can also be a problem with missing packages in your distro. This is what I installed on my system (Kubuntu 7.10 as of December 2007) while I was developing: language-support-fr language-support-en language-pack-gnome-fr (*) (*) This one is VERY important, it has many stock translations for GTK. Without it you likely not see buttons and widgets in the right language. Substitute your language code as you please. TRANSLATION TIPS ================ If you want to help translate, please contact us via the fontypython list: fontypython@googlegroups.com I have included the pot files that I have. Look at fontypythonmodules/pofiles/README (Translation stuff is messy. Headers are all wrong and versions all over the place.) fontypython-0.5/icons/0000775000175000017500000000000013212250216015004 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/0000775000175000017500000000000013212250216016443 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/48x48/0000775000175000017500000000000013212250216017242 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/48x48/apps/0000775000175000017500000000000013212250216020205 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/48x48/apps/fontypython.png0000664000175000017500000000450713212237726023335 0ustar donndonn00000000000000PNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATh{p?K`N$K]M;wFc<#d_Uɤ \cCa,d-̴Zz<miko/z E˗#g_$1J_u!5v:«Z`%@aQ~ -Amq Og?=c13O^8yz_fnV7MH`(BO'X,lxAN?f8nwh:h\p_نȟ9koaAR26cm !5ݦ=N5"]q dctL 7߶r7u5:8:j&vEĎKB`k'ovNNM^:!,ڭz(^ *XG-͜na|wu!q #caaX,H   '"rJJM6>N% 0?2@qk|uI S$jGPV$'őklBVbe@ J`ڠ\ >c#ϕ(B;%H)1"~*9%M@N ._LˮR*RY g-M C)>H)inl/_}Xl!vg67up *hBB¸"1u;ZyS:2S`pjYWAk @sc=HVVVu?PgA]f@Q]v~!DVQA?H2!F?/ٳ|y !jF{TBlTUhsnָxfZ88<7̅DEG;yTdePB%#V<^3͵w?sBYKhէ< qIܭKq0(2L2xm~JsXL+9K,Խ~~Bp- Ab.1xM3\@`(U )2TGu+u7jW.HϠG-H8vaL 2p0O {͍ !#(*vG&_|~3fH,!<'2]]S!N>`y+~=ݔ.}S H\ 0f#E+S~H/=w.`ݡ] G`0܁`͓Toy"#QdÉJa@$=n?`]Ti;Ɗrhg8in7XO.[9A H_zUUOKuOsEb!ggϙˬsFE /:?UV(`A.c= J(qW f pU0Jk \]RrUa6*[հc˺xz=$P-aE~sߤ %%؝~ϫ?%̚5.׷Z$#B z$ :4<,(/gLH2DJ=2CK;/_mE$aIbr5vG&>wn|{N:(З<̚3W3F@urq`Ve% bWO+J"}B.$&{́R:mr0#8s}Sw.z;2{G%IENDB`fontypython-0.5/icons/hicolor/32x32/0000775000175000017500000000000013212250216017224 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/32x32/apps/0000775000175000017500000000000013212250216020167 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/32x32/apps/fontypython.png0000664000175000017500000000221113212237726023305 0ustar donndonn00000000000000PNG  IHDR szzsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATXYhU73ՙlMR.IHg2PhEQkRppAK` U*(D( `Z[44L ,ؘI263LJ/w2I&/Ås=;]j%"<nt 9(| |XKq  ǘ/ ,v0`\A%}*FGsxh/ vA(`P$T=5^x\ݝn+Q~9fL8ҍL͆[Kc{>o½JIM 'YY8RŋvIJ!nMM@5/ ЦjӎĶLbjt:ٜ_WRj3Ij՚ffuH4]%ǨU |ZM7/sUݣi}IENDB`fontypython-0.5/icons/hicolor/64x64/0000775000175000017500000000000013212250216017236 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/64x64/apps/0000775000175000017500000000000013212250216020201 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/64x64/apps/fontypython.png0000664000175000017500000000617213212237726023331 0ustar donndonn00000000000000PNG  IHDR@@iqsBIT|d pHYs+tEXtSoftwarewww.inkscape.org< IDATxypU?羗,@$ dXÖE|,X舨XҢ)qZvʴ]a)65AFdBl/{ y }/3w{;;s !-=7͎G0GBb ϟ=?kkڻYOzDA[> 7S el|i=V4 yOvN x@6Eb h,>!yǑ/پ&>ߋhSYy>#b`G0v UϱGhlh83;'ϊ) d/n`6©d^yy^,GjN(a cy~ëEx& <{T=@lzw,Xb_cc?$7b;/coY"sO}V8d(m~IT_=̮ۑRzf0MT'XqHI"~hx( /UVU(P;b?j{jO "*Ŧd[3 ij+ZŔi\TOy˗c$0|ĈΩ_ $M TDj PUe3`=+DUU6m|MkQ""PK̳Ӂx Ow̳`qI&ಖL ֦j9o񉓘GgT+T~]V-@u X2eKXgnɻBQ.A[wZNQ|dDI;)%vlؖQ Lx0eZ_ؽUpJFpNu B.DB)(.*)>qϽ.$H\a}j_mM΅fӓ8vH`S>z Vsg+h8hod#!iٝ|#PR\d!z%1`44ϟ֯{¼};sN*[(?+W0.)%' 7CAbM-jF!UEuqq * I?NЧ|d0Ru W mpHEDKEyM sj374lqgvؙ# E+x0N@A}#ɂ<ǝGzR/WqZ_E9;G[a0)>g8_@AVS-y=5Bwx`dtVa):}=z@u&(M]Exciilc ό詏U2W8sè(Z[)/=B170bd0W:N@:Y srC3)BPR\f[RRs?OpbTh3fiӟe=@)^Kn[y odpiX=t%d4;^wu'i '_AL4aA'ڮۄfs*atttpN\G&w|UkKßVvo| ,W jkT Rι- 2U'PRO{TWw,qGNRz" taZZ:m4p=KzC\k ״@mI}W;=\u#vsr .`g7v!@gF@br4W-aknt>PY?Y]\,]zy[ܴ|8sQUkn(:ΫeoW8C_h(,y}!Bw?%t#@"&@y%@bXX. '~[Tkv! ##Ä`x/ ]*oxgQC_^۴4h< hp6禅G0=o V+ښj:hZע+*UlCinjs@( 1qEUvI)tttچ_E2rF.H{E']x2$g AP\^X[ܗf8 P7N ~F`رm+oyFv|43;9 Ș)pL<=fu^K! pQA(YCU>k}N(ʽ$@RYl6Ņj͓~C}iZ,- _Ǿv9lHh/e4EGh$φ]Gciiܦ[NkWpRkk(/+Y#"6:tڝRs/.0[{d 3!VîZF;S$KTYtHrJT*/(<άhMT.`>.*Βh6й´䙺ݬmuٝ;090Z-SPp%-cm<cabiH{+n2UmmQNEDk`}b 1 <[IENDB`fontypython-0.5/icons/hicolor/scalable/0000775000175000017500000000000013212250216020211 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/scalable/apps/0000775000175000017500000000000013212250216021154 5ustar donndonn00000000000000fontypython-0.5/icons/hicolor/scalable/apps/fontypython.svg0000664000175000017500000001526513212250216024307 0ustar donndonn00000000000000 fontypython svg logo image/svg+xml fontypython svg logo Dec 2017 Donn C. Ingle GPLv3 Donn C. Ingle English fontypython-0.5/PKG-INFO0000664000175000017500000000410713212250216014770 0ustar donndonn00000000000000Metadata-Version: 1.1 Name: fontypython Version: 0.5 Summary: Fonty Python - view and manage fonts on Gnu/Linux Home-page: https://savannah.nongnu.org/projects/fontypython/ Author: Donn.C.Ingle Author-email: Email: donn.ingle@gmail.com License: GNU GPLv3 Description: Manage your fonts on GNU/Linux ============================== Many designers have collections of font files on their drives. Fonty Python will help you gather and structure them into collections called "Pogs" -- a place to keep tyPOGraphy. Well, why not? Fonty lets you you select fonts visually and place them into Pogs which you can then install or remove as you require. (Your font files never move from where they are. Only links are used.) Example: You create a "logos" Pog where you place logotype fonts. When you want to use them, simply install the "logos" Pog and start your design app! When you're done, uninstall the "logos" Pog; the fonts will go away. Fonty can also "hush" unwanted fonts. This hides system fonts, leaving only those Pogs you want in your apps. The Inkscape font chooser, for example, is more usable after a hush. (This is temporary; an "unhush" will switch the system fonts on again.) Fonty is great for just looking at fonts, wherever they are, without having to install them. Fonts supported: TTF, OTF, TTC, WOFF, Type1 (PFB, PFA). Fonty Python Copyright © 2017 Donn.C.Ingle Email: donn.ingle@gmail.com Platform: UNKNOWN Classifier: Development Status :: 6 - Mature Classifier: Environment :: X11 Applications Classifier: Intended Audience :: End Users/Desktop Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Topic :: Desktop Environment Classifier: Topic :: Text Processing :: Fonts Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Utilities fontypython-0.5/fontypython.desktop0000664000175000017500000000067513211475352017706 0ustar donndonn00000000000000[Desktop Entry] Name=Fonty Python Font Manager GenericName=Font Manager Comment=View and temporarily install all kinds of fonts. Comment[fr]=Fonty Python est aussi approprié pour visionner vos fichiers TTF où qu'ils soient sur votre ordinateur Comment[it]=Vedi e installa temporaneamente tutti i tipi di font Type=Application Categories=Graphics; Exec=fontypython TryExec=fontypython Terminal=false StartupNotify=true Icon=fontypython