diff options
280 files changed, 57290 insertions, 0 deletions
diff --git a/logo/README b/logo/README new file mode 100644 index 0000000..932e836 --- /dev/null +++ b/logo/README @@ -0,0 +1,31 @@ +Developper's corner + +1) To add a language +- class Logo + Update translationLanguage + new String[10] + generateLanguage() + + Update englishLanguage + Update locales + Update getLocale() + +- Config.java public static LANGUAGE_.... + +- Image Flag: + size:150x100 + destination xlogo/Utils/ + +- GPL licence + +- Update language properties files + +2) To add a new primitives +- xlogo/kernel/genericPrimitive + Add the generic name for the primitive, the number of arguments + If this primitive allow a general form --> example: (sum 1 2 3 4) + add a + at the end of the line. +- xlogo/kernel/LaunchPrimitive: add the primitive instruction +If it's a Drawing primitive --> Use DrawPanel.java +If it's a control primitive (loop, break, return ...) ---> use Primitive.java +
\ No newline at end of file diff --git a/logo/build.xml b/logo/build.xml new file mode 100644 index 0000000..d8fcd04 --- /dev/null +++ b/logo/build.xml @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ====================================================================== + 9 févr. 08 15:00:15 + + project: Xlogo + description: Logo Programming Interpreter + + Le Coq Loïc + ====================================================================== --> +<project name="project Xlogo" default="deploy"> + <description> + XLogo: Logo Programming Interpreter + </description> + <!-- Build Properties --> + + <!-- Property signJar ============= + Does the Jar has to be signed ? + ================================--> + + <property name="signJar" value="true" /> + + <!-- Property platform: + ================================================ + * "all": Builds a crossPlatform Jar + * "linux": Builds a Linux specific Jar + * "windows": Builds a Windows specific Jar + * "solaris": Builds a Solaris specific Jar + Note: The built file is always valid for Mac + ===============================================--> + <property name="platform" value="all" /> + + <!-- Build source tarball --> + + <property name="buildSrc" value="true"/> + + <!-- Version for this Build --> + + <property name="version" value="0.9.94beta-2008-08-02"/> + + + <!-- ================================= + default target: deploy + ================================= --> + <target name="deploy" depends="create.jar"> + <condition property="sign.jar"> + <equals arg1="true" arg2="${signJar}"/> + </condition> + <antcall target="sign.xlogo"> + </antcall> + <condition property="build.source.tarball"> + <equals arg1="true" arg2="${buildSrc}" /> + </condition> + <antcall target="create.src.tarball"> + </antcall> + + </target> + + + <!-- - - - - - - - - - - - - - - - - - + target: depends + - - - - - - - - - - - - - - - - - --> + + <!-- Creates the source tarball --> + + <target name="create.src.tarball" if="build.source.tarball"> + <mkdir dir="deploy/xlogo-${version}"/> + <copy todir="deploy/xlogo-${version}"> + <fileset dir="." > + <include name="src/**"/> + <include name="windows/**"/> + <include name="linux/**"/> + <include name="solaris/**"/> + <include name="jh.jar"/> + <include name="j3dcore.jar"/> + <include name="vecmath.jar"/> + <include name="j3dutils.jar"/> + <include name="jl1.0.1.jar"/> + <include name="manifest_xlogo"/> + <include name="manifest_start"/> + <include name="build.xml"/> + <include name="README"/> + </fileset> + </copy> + + <tar destfile="deploy/xlogo-${version}-source.tar.bz2" compression="bzip2"> + <fileset dir="deploy/"> + <include name="xlogo-${version}/**"/> + </fileset> + + </tar> + <delete dir="deploy/xlogo-${version}"/> + </target> + + <!-- Sign the XLogo (Java Web Start) --> + + <target name="sign.xlogo" if="sign.jar"> + <input + message="Password" + addproperty="pwd"/> + <signjar keystore="keystore.ks" storepass="${pwd}" alias="myalias"> + <fileset dir="deploy"> + <include name="xlogo.jar"/> + </fileset> + </signjar> + </target> + + + <target name="create.jar" depends="compile"> + + <!-- Create tmp-xlogo.jar --> + + <jar destfile="deploy/tmp_xlogo.jar" + manifest="manifest_xlogo"> + <fileset dir="deploy/"> + <include name="xlogo/**"/> + <include name="*.properties"/> + </fileset> + </jar> + + <!-- Delete Used files --> + <delete includeemptydirs="true"> + <fileset dir="deploy/"> + <include name="xlogo/**"/> + <include name="*.properties"/> + </fileset> + </delete> + + <!-- Create xlogo.jar --> + + <jar destfile="deploy/xlogo.jar" + manifest="manifest_start"> + <fileset dir="deploy/"> + <include name="**"/> + </fileset> + </jar> + + <!-- Delete Used files --> + <delete includeemptydirs="true"> + <fileset dir="deploy/"> + <exclude name="xlogo.jar"/> + <include name="**"/> + </fileset> + </delete> + </target> + + <!-- Compile all Files --> + + <target name="compile" depends="copy.static.files"> +<!-- <echo> ${ant.java.version}</echo> --> + <javac + source="1.5" encoding="utf8" + target="1.5" + srcdir="src" destdir="deploy/"> + <classpath> + <pathelement location="vecmath.jar"/> + <pathelement location="j3dcore.jar"/> + <pathelement location="j3dutils.jar"/> + <pathelement location="jh.jar"/> + <pathelement location="jl1.0.1.jar"/> + </classpath> + </javac> + </target> + + <!-- Copy all non binaries files (images, properties files... + into the folder "deploy" --> + + <target name="copy.static.files" depends="create.deploy"> + <copy todir="deploy/"> + <fileset dir="."> + <include name="vecmath.jar"/> + <include name="j3dcore.jar"/> + <include name="j3dutils.jar"/> + <include name="jl1.0.1.jar"/> + <include name="jh.jar"/> + </fileset> + <fileset dir="src/"> + <include name="**.properties"/> + <include name="**/*.png"/> + <include name="**/*.html"/> + <include name="**/genericPrimitive"/> + </fileset> + </copy> + + <!-- Copy Specific OS libraries --> + + <condition property="platform.solaris"> + <or> + <equals arg1="${platform}" arg2="all"/> + <equals arg1="${platform}" arg2="solaris"/> + </or> + </condition> + <antcall target="copy.solaris"> + </antcall> + <condition property="platform.linux"> + <or> + <equals arg1="${platform}" arg2="all"/> + <equals arg1="${platform}" arg2="linux"/> + </or> + </condition> + <antcall target="copy.linux"> + </antcall> + <condition property="platform.windows"> + <or> + <equals arg1="${platform}" arg2="all"/> + <equals arg1="${platform}" arg2="windows"/> + </or> + </condition> + <antcall target="copy.windows"> + </antcall> + </target> + + <!-- Copy Solaris specific JAVA3D driver into "deploy" --> + + <target name="copy.solaris" if="platform.solaris"> + <copy todir="deploy/"> + <fileset dir="."> + <include name="solaris/**"/> + </fileset> + </copy> + </target> + + <!-- Copy Linux specific JAVA3D driver into "deploy" --> + + <target name="copy.linux" if="platform.linux"> + <copy todir="deploy/"> + <fileset dir="."> + <include name="linux/**"/> + </fileset> + </copy> + </target> + + <!-- Copy Windows specific JAVA3D driver into "deploy" --> + + <target name="copy.windows" if="platform.windows"> + <copy todir="deploy/"> + <fileset dir="."> + <include name="windows/**"/> + </fileset> + </copy> + </target> + + <!-- Create the folder "deploy", delete if exists --> + + <target name="create.deploy"> + <condition property="delete.deploy"> + <available file="deploy" type="dir"/> + </condition> + <antcall target="clean-deploy"> + </antcall> + <mkdir dir="deploy"/> + </target> + + <!-- Delete the directory "deploy" if exists --> + + <target name="clean-deploy" if="delete.deploy"> + <delete includeemptydirs="true"> + <fileset dir="."> + <include name="deploy/**"/> + </fileset> + </delete> + </target> +</project> diff --git a/logo/j3dcore-ogl.dll b/logo/j3dcore-ogl.dll Binary files differnew file mode 100644 index 0000000..909cc05 --- /dev/null +++ b/logo/j3dcore-ogl.dll diff --git a/logo/j3dcore.jar b/logo/j3dcore.jar Binary files differnew file mode 100644 index 0000000..f28c754 --- /dev/null +++ b/logo/j3dcore.jar diff --git a/logo/j3dutils.jar b/logo/j3dutils.jar Binary files differnew file mode 100644 index 0000000..90201b3 --- /dev/null +++ b/logo/j3dutils.jar diff --git a/logo/jh.jar b/logo/jh.jar Binary files differnew file mode 100644 index 0000000..185d942 --- /dev/null +++ b/logo/jh.jar diff --git a/logo/jl1.0.1.jar b/logo/jl1.0.1.jar Binary files differnew file mode 100644 index 0000000..bd5fb8b --- /dev/null +++ b/logo/jl1.0.1.jar diff --git a/logo/manifest_start b/logo/manifest_start new file mode 100644 index 0000000..8c57194 --- /dev/null +++ b/logo/manifest_start @@ -0,0 +1 @@ +Main-Class: Lanceur diff --git a/logo/manifest_xlogo b/logo/manifest_xlogo new file mode 100644 index 0000000..3753e91 --- /dev/null +++ b/logo/manifest_xlogo @@ -0,0 +1,3 @@ +Main-Class: xlogo.Logo +Class-Path: jh.jar vecmath.jar j3dcore.jar j3dutils.jar jl1.0.1.jar + diff --git a/logo/src/Lanceur.java b/logo/src/Lanceur.java new file mode 100644 index 0000000..ce65803 --- /dev/null +++ b/logo/src/Lanceur.java @@ -0,0 +1,460 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ + +import java.io.*; +import java.util.StringTokenizer; + +import java.util.Calendar; + +/** + * @author loic + * + * This class extracts the file tmp_xlogo.jar from the main archive + * in the temporary file's directory + * and then launch the command: <br> + * java -D-jar -Xmx64m -Djava.library.path=path_to_tmp -cp path_to_tmp + * tmp_xlogo.jar<br> + * <br> + * XLogo executes with a predefined heap size for the Virtual Machine * + * + * @author Marko Zivkovic + * The maximum heap size property is now fixed 128MB. In the future, the application preferences should be used. + * Command line arguments are ignored, because this application is GUI-based and for + * children. I see no reason for a GUI application to have command line arguments. + */ +public class Lanceur +{ + private static String PROPERTIES_PREFIX = "ch.ethz.abz.xlogo4schools"; + private static int DEFAULT_MEMORY_ALLOC = 128; + + /** + * The process which contains the XLogo application + */ + private Process p; + /** + * The temporary folder which contains all files to start XLogo + */ + private File tmpFolder = null; + private File[] files = new File[10]; + + /** + * Main method + * + * @param args + * The path toward "lgo" files + */ + public static void main(String[] args) + { + new Lanceur(); + } + + Lanceur() + { + // Look for old files from XLogo crash + cleanTmp(); + // Look for the memory that should be allocated to the JVM heap size + //Preferences prefs = Preferences.systemRoot().node(PROPERTIES_PREFIX); TODO this does not work ... :-( + //int memory = prefs.getInt("appMemory", DEFAULT_MEMORY_ALLOC); + int memory = DEFAULT_MEMORY_ALLOC; + + // extract application in the java.io.tmp directory + extractApplication(); + startApplicationProcess(memory); + restorePath(); + deleteTmpFiles(); + } + + private void startApplicationProcess(int memoire) + { + try + { + // Add the tmp to the path + String newPath = tmpFolder.getAbsolutePath(); + + String javaLibraryPath = newPath + File.pathSeparatorChar + System.getProperty("java.library.path"); + // Bug when launching under Windows with java webstart + javaLibraryPath = javaLibraryPath.replaceAll("\"", ""); + System.out.println("Path: " + javaLibraryPath + "\n"); + String[] commande = new String[5]; + commande[0] = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; + commande[1] = "-jar"; + commande[2] = "-Xmx" + memoire + "m"; + commande[3] = "-Djava.library.path=" + javaLibraryPath; + commande[4] = files[0].getAbsolutePath(); + + System.out.println("<----- Starting XLogo ---->"); + String cmd = ""; + for (int i = 0; i < commande.length; i++) + { + cmd += commande[i] + " "; + } + System.out.println(cmd + "\n\n"); + p = Runtime.getRuntime().exec(commande); + // Receive Messages from the Process + startStreamForward(p.getInputStream()); + startStreamForward(p.getErrorStream()); + p.waitFor(); + } + catch (Exception e) + { + System.out.println(e); + } + } + + private void deleteTmpFiles() + { + System.out.println("Closing XLogo. Cleaning tmp file"); + for (int i = 0; i < files.length; i++) + { + if (null != files[i]) + files[i].delete(); + } + tmpFolder.delete(); + } + + private void restorePath() + { + String pathToFolder = tmpFolder.getAbsolutePath(); + String path = System.getProperty("java.library.path"); + StringTokenizer st = new StringTokenizer(path, File.pathSeparator); + String newPath = ""; + while (st.hasMoreTokens()) + { + if (!newPath.equals("")) + newPath += File.pathSeparator; + String element = st.nextToken(); + if (!element.equals(pathToFolder)) + newPath += element; + } + System.setProperty("java.library.path", newPath); + } + + /** + * Used to catch application streams and write them to System.out + * @param stream + */ + private void startStreamForward(final InputStream stream) + { + new Thread(){ + public void run() + { + BufferedReader reader = null; + try + { + reader = new BufferedReader(new InputStreamReader(stream)); + String line = ""; + while ((line = reader.readLine()) != null) + System.out.println(line); + } + catch (IOException e) + { + System.out.println(e.toString()); + } + finally + { + if (reader != null) + try + { + reader.close(); + } + catch (IOException e) + {} + } + } + }.start(); + } + + /** + * This method checks for unused old XLogo files in temporary directory<br> + * If it found files older than 24 hours with the prefix tmp_xlogo, these + * files are deleted. + */ + private void cleanTmp() + { + String path = System.getProperty("java.io.tmpdir"); + File f = new File(path); + File[] files = f.listFiles(); + if (null != files) + { + for (int i = 0; i < files.length; i++) + { + try + { + if (files[i].getName().startsWith("tmp_xlogo")) + { + long fileTime = files[i].lastModified(); + long time = Calendar.getInstance().getTimeInMillis(); + // Delete file if it's more than 24 hours old + if (time - fileTime > 24 * 3600 * 1000) + { + if (files[i].isDirectory()) + deleteDirectory(files[i]); + files[i].delete(); + + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + } + + /** + * This method extracts the file tmp_xlogo.jar from the archive and copy it + * into the temporary directory. + */ + private void extractApplication() + { + // Create in the "java.io.tmpdir" a directory called tmp_xlogo + int i = 0; + String tmpPath = System.getProperty("java.io.tmpdir") + File.separator + "tmp_xlogo"; + while (true) + { + tmpFolder = new File(tmpPath + i); + if (!tmpFolder.exists()) + break; + else + i++; + } + boolean b = tmpFolder.mkdir(); + System.out.println("Creating tmp_xlogo directory - success: " + b); + + // extract the file tmp_xlogo.jar in this folder + InputStream src = Lanceur.class.getResourceAsStream("tmp_xlogo.jar"); + files[0] = new File(tmpFolder.getAbsolutePath() + File.separator + "tmp_xlogo.jar"); + b = copier(src, files[0]); + System.out.println("Copying tmp_xlogo.jar - success: " + b); + + // extract the file jh.jar in this folder + src = Lanceur.class.getResourceAsStream("jh.jar"); + files[1] = new File(tmpFolder.getAbsolutePath() + File.separator + "jh.jar"); + b = copier(src, files[1]); + System.out.println("Copying jh.jar - success: " + b); + + // extract the file vecmath.jar in this folder + src = Lanceur.class.getResourceAsStream("vecmath.jar"); + files[2] = new File(tmpFolder.getAbsolutePath() + File.separator + "vecmath.jar"); + b = copier(src, files[2]); + System.out.println("Copying vecmath.jar - success: " + b); + + // extract the file j3dcore.jar in this folder + src = Lanceur.class.getResourceAsStream("j3dcore.jar"); + files[3] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dcore.jar"); + b = copier(src, files[3]); + System.out.println("Copying j3dcore.jar - success: " + b); + + // extract the file j3dutils.jar in this folder + src = Lanceur.class.getResourceAsStream("j3dutils.jar"); + files[4] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dutils.jar"); + b = copier(src, files[4]); + System.out.println("Copying j3dutils.jar - success: " + b); + + // extract the file jl1.0.1 in this folder (JLayer library for mp3 + // playing) + src = Lanceur.class.getResourceAsStream("jl1.0.1.jar"); + files[5] = new File(tmpFolder.getAbsolutePath() + File.separator + "jl1.0.1.jar"); + b = copier(src, files[5]); + System.out.println("Copying jl1.0.1.jar - success: " + b); + + // extract the native driver for java 3d in this folder + String os = System.getProperty("os.name").toLowerCase(); + String arch = System.getProperty("os.arch"); + System.out.println("Operating system: " + os); + System.out.println("Architecture: " + arch); + + // Linux + if (os.indexOf("linux") != -1) + { + if (arch.indexOf("86") != -1) + { + InputStream lib = Lanceur.class.getResourceAsStream("linux/x86/libj3dcore-ogl.so"); + files[6] = new File(tmpFolder.getAbsolutePath() + File.separator + "libj3dcore-ogl.so"); + copier(lib, files[6]); + lib = Lanceur.class.getResourceAsStream("linux/x86/libj3dcore-ogl-cg.so"); + files[7] = new File(tmpFolder.getAbsolutePath() + File.separator + "libj3dcore-ogl-cg.so"); + copier(lib, files[7]); + } + else + { + InputStream lib = Lanceur.class.getResourceAsStream("linux/amd64/libj3dcore-ogl.so"); + files[6] = new File(tmpFolder.getAbsolutePath() + File.separator + "libj3dcore-ogl.so"); + copier(lib, files[6]); + } + } + // windows + else if (os.indexOf("windows") != -1) + { + if (arch.indexOf("86") != -1) + { + InputStream lib = Lanceur.class.getResourceAsStream("windows/x86/j3dcore-d3d.dll"); + files[6] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dcore-d3d.dll"); + b = copier(lib, files[6]); + System.out.println("Copying library 1 - success: " + b); + lib = Lanceur.class.getResourceAsStream("windows/x86/j3dcore-ogl.dll"); + files[7] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dcore-ogl.dll"); + b = copier(lib, files[7]); + System.out.println("Copying library 2 - success: " + b); + lib = Lanceur.class.getResourceAsStream("windows/x86/j3dcore-ogl-cg.dll"); + files[8] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dcore-ogl-cg.dll"); + b = copier(lib, files[8]); + System.out.println("Copying library 3 - success: " + b); + lib = Lanceur.class.getResourceAsStream("windows/x86/j3dcore-ogl-chk.dll"); + files[9] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dcore-ogl-chk.dll"); + b = copier(lib, files[9]); + System.out.println("Copying library 4 - success: " + b); + } + else + { + InputStream lib = Lanceur.class.getResourceAsStream("windows/amd64/j3dcore-ogl.dll"); + files[6] = new File(tmpFolder.getAbsolutePath() + File.separator + "j3dcore-ogl.dll"); + b = copier(lib, files[6]); + System.out.println("Copying library 1 - success: " + b); + } + } + // Mac os + else if (os.indexOf("mac") != -1) + { + + } + // solaris + else if (os.indexOf("sunos") != -1) + { + if (arch.indexOf("86") != -1) + { + InputStream lib = Lanceur.class.getResourceAsStream("solaris/i386/libj3dcore-ogl.so"); + files[6] = new File(tmpFolder.getAbsolutePath() + File.separator + "libj3dcore-ogl.so"); + b = copier(lib, files[6]); + System.out.println("Copying library 1 - success: " + b); + } + else if (arch.indexOf("amd64") != -1) + { + InputStream lib = Lanceur.class.getResourceAsStream("solaris/amd64/libj3dcore-ogl.so"); + files[6] = new File(tmpFolder.getAbsolutePath() + File.separator + "libj3dcore-ogl.so"); + b = copier(lib, files[6]); + System.out.println("Copying library 1 - success: " + b); + } + } + + } + + /** + * This method copy the file tmp_xlogo.jar from the archive to the file + * Destination. + * + * @param destination + * The output file + * @return true if success, false otherwise + */ + private boolean copier(InputStream src, File destination) + { + boolean resultat = false; + // Declaration des flux + java.io.FileOutputStream destinationFile = null; + try + { + // Création du fichier : + destination.createNewFile(); + // Ouverture des flux + + destinationFile = new java.io.FileOutputStream(destination); + // Lecture par segment de 0.5Mo + byte buffer[] = new byte[512 * 1024]; + int nbLecture; + while ((nbLecture = src.read(buffer)) != -1) + { + destinationFile.write(buffer, 0, nbLecture); + } + // Copie réussie + resultat = true; + } + catch (java.io.FileNotFoundException f) + {} + catch (java.io.IOException e) + {} + finally + { + // Quoi qu'il arrive, on ferme les flux + try + { + src.close(); + } + catch (Exception e) + {} + try + { + destinationFile.close(); + } + catch (Exception e) + {} + } + return (resultat); + } + + /** + * Delete a the directory created by Logo in /tmp + * + * @param path + * The Directory path + * @return true if success + */ + private boolean deleteDirectory(File path) + { + boolean resultat = true; + if (path.exists()) + { + File[] files = path.listFiles(); + if (null != files) + { + for (int i = 0; i < files.length; i++) + { + if (files[i].isDirectory()) + { + resultat &= deleteDirectory(files[i]); + } + else + { + resultat &= files[i].delete(); + } + } + } + } + resultat &= path.delete(); + return (resultat); + } +} diff --git a/logo/src/langage.properties b/logo/src/langage.properties new file mode 100644 index 0000000..9204e31 --- /dev/null +++ b/logo/src/langage.properties @@ -0,0 +1,437 @@ +3d.fog.backdistance= +3d.fog.density= +3d.fog.exponential= +3d.fog.frontdistance= +3d.fog.linear= +3d.fog.none= +3d.fog.type= +3d.fog= +3d.light= +3d.light.ambient= +3d.light.angle= +3d.light.apply= +3d.light.direction= +3d.light.directional= +3d.light.none= +3d.light.point= +3d.light.position= +3d.light.spot= +3d.light.type= +3d.viewer= +active_grid= +active_xaxis= +active_yaxis= +ajouter=Ajouter +animation_active = Le mode animation est activ\u00e9. +apercu = Aper\u00e7u +attend_positif = attend un argument positif. +backward= +bas = Basse +bleu = Bleu +bordermotif= +caractere_special_variable = Les noms de variable ne doivent pas +caractere_special1=Les noms de proc\u00e9dures ne doivent pas +caractere_special2=contenir de caract\u00e8res comme \ + - * / ( ) [ ] = < > & | : +caractere_special3=Renommez +carre = Carr\u00e9 +chaine_trop_longue = Je ne peux afficher une liste ou un mot ayant plus de 32000 caract\u00e8res. +chat=Discussion +chemin=Chemin +color_3_arguments= +commande=Commande : +comme_parametre = ] comme param\u00e8tre. +couleur_du_crayon=Couleur du crayon +couleur_du_fond=Couleur du fond +dans=Dans +definir=Vous venez de d\u00e9finir +depassement_memoire = L'application occupe \u00e0 pr\u00e9sent plus de 90% de la place m\u00e9moire disponible.\nLa commande lanc\u00e9e va donc \u00eatre stopp\u00e9e afin de pr\u00e9venir un \u00e9ventuel d\u00e9bordement de m\u00e9moire.\nV\u00e9rifiez que votre programme ne boucle pas ind\u00e9finiment, sinon augmentez la capacit\u00e9 de m\u00e9moire allou\u00e9e \u00e0 XLogo. +dernier = Dernier +direction= +division_par_zero = Vous ne pouvez effectuer une division par 0 ! +dossier_parent = Remonte d'un niveau +draw_grid= +echantillon = Echantillons +echantillon_texte = Echantillon de texte +editeur=Editeur +editor.redo= +editor.undo= +effacer_editeur= Effacer la zone de dessin lorsqu'on quitte l'\u00e9diteur +element_dans_liste= \u00e9l\u00e9ments dans la liste [ +enlever=Enlever +enregistreimage=Enregistrer l'image sous ... +enregistrer_espace = Effacer l'espace de travail ? +entre_zero_un = doit \u00eatre compris entre 0 et 1. +epaisseur_crayon = Epaisseur maximale du crayon +erreur_compteur = Pas de compteur en dehors d'une boucle repete. +erreur_crochet=Erreur de crochets : ] attendu +erreur_editeur=Impossible d'enregistrer toutes les proc\u00e9dures.\nV\u00e9rifiez les blocs POUR .... FIN et\nla bonne d\u00e9finitions des variables :a :b etc +erreur_fixestyle = fixestyle n'accepte que les valeurs suivantes pour arguments: aucun, gras, souligne, italique, exposant ou indice. +erreur_format_image=Les seuls fichiers image accept\u00e9s sont les fichiers *.png et *.jpg +erreur_memoire = XLogo ne dispose pas de la m\u00e9moire suffisante pour cr\u00e9er l'image demand\u00e9e.\nDans l'onglet Options, augmenter la taille de la m\u00e9moire \u00e0: +erreur_nom_nombre_procedure = Le nom d'une proc\u00e9dure ne peut \u00eatre un nombre ! +erreur_nom_nombre_variable = Le nom d'une variable ne peut \u00eatre un nombre ! +erreur_pas_repertoire = n'est pas un r\u00e9pertoire valide ! +erreur_repetepour = ne peut contenir que trois ou quatre \u00e9l\u00e9ments. [variable debut fin incr\u00e9ment] +erreur_retourne = retourne ne peut \u00eatre employ\u00e9 en dehors d'une proc\u00e9dure ! +erreur_sortie1=La tortue est sortie de la zone de dessin. +erreur_sortie2=Nombre de pas avant de sortir: +erreur_stop = stop doit \u00eatre employ\u00e9 \u00e0\u00a0 l'int\u00e9rieur d'une proc\u00e9dure ou \u00e0\u00a0 l'int\u00e9rieur d'une boucle ! +erreur_tcp=Probl\u00e8me de communication r\u00e9seau. +erreur_variable = n'est pas une variable valide! +erreur=ERREUR +error_bad_values=accepte seulement les valeurs suivantes: +error.3d.3vertex= +error.3d.emptypolygon= +error.ioecriture= +error.iolecture= +error.ne_peut_etre= +error.novalue= +error.primitive2D= +error.primitive3D= +error.procedure.must.be= +error.whattodo= +error.word= +existe_deja= existe d\u00e9j\u00e0\u00a0. +faux="faux +ferme_editeur=Fermez tout d'abord l'\u00e9diteur. +fichier_du_type = Fichiers du type +fichiers = Fichier(s) +fichiers_logo=Fichiers Logo +fichiers_rtf = Fichiers RTF +file_100K= +fin_flux = Il n'y a plus de caract\u00e8res \u00e0 lire dans le flux n\u00b0 +fin=fin +find_replace= +find= +flux_ecriture = Ce flux ouvert n'est pas utilisable en \u00e9criture. +flux_existant = d\u00e9signe d\u00e9j\u00e0 un flux ouvert. Commencer par fermer ce flux avant de pouvoir r\u00e9utiliser cet identifiant. +flux_lecture = Ce flux ouvert n'est pas utilisable en lecture. +flux_non_disponible = Aucun flux ouvert ne poss\u00e8de l'identifiant +forme_crayon = Forme de la mine du crayon +forward= +gui_exists= +haut = Haute +hollandais = Hollandais +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile= +images= +imprimer_editeur=Imprimer l'\u00e9diteur +interrompre_execution=Interrompre l'ex\u00e9cution en cours +je_ne_sais_pas=Je ne sais pas comment faire +line= +lire_editeur=Enregistrer les modifications et quitter +liste_vide=La liste est vide. +mainCommand= +memoire = M\u00e9moire allou\u00e9e \u00e0 XLogo (Mo): +menu.edition.copy= +menu.edition.cut= +menu.edition.paste= +menu.edition.selectall = Tout s\u00e9lectionner +menu.edition= +menu.file.captureimage.clipboard= +menu.file.captureimage.print= +menu.file.captureimage= +menu.file.open= +menu.file.quit= +menu.file.save= +menu.file.saveas= +menu.file.textzone.rtf= +menu.file.textzone= +menu.file= +menu.help.about= +menu.help.licence= +menu.help.online= +menu.help.translatedlicence= +menu.help.translatexlogo= +menu.help= +menu.tools.eraser= +menu.tools.pencolor= +menu.tools.preferences= +menu.tools.screencolor= +menu.tools.startup=D\u00e9finir les fichiers de d\u00e9marrage... +menu.tools.translate= +menu.tools= +message_a_propos1=XLOGO version : +message_a_propos2=Site web: +message_a_propos3=N'h\u00e9sitez pas \u00e0\u00a0 me contacter \u00e0\u00a0 +messages= +mot_vide = Le mot doit contenir au moins un caract\u00e8re. +n_aime_pas = n'aime pas [ +nb_tortues = Nombre maximum de tortues +ne_renvoie_pas= ne renvoie pas de valeur \u00e0\u00a0 +no_gui= +no_host=Probl\u00e8me de communication avec l'ordinateur situ\u00e9 \u00e0 l'adresse: +nom_du_fichier = Nom du Fichier : +nombre_unicode = doit \u00eatre compris entre 0 et 65535. +normal = Normale +note.do= +note.fa= +note.la= +note.mi= +note.re= +note.si= +note.sol= +nouveau = Nouveau +nouveau_dossier = Cr\u00e9 un nouveau dossier +ouvrir_editeur=Ouvrir l'\u00e9diteur +parcourir=Parcourir... +parenthese_fermante= Une parenth\u00e8se ) est attendue. +parenthese_ouvrante=Une parenth\u00e8se ( est attendue. +parenthese_vide=Le contenu des parenth\u00e8ses est vide ! +pas_argument= n'est pas un argument valide. +pas_assez_de=Pas assez de donn\u00e9es pour +pas_entier= n'est pas un entier ! +pas_liste = n'est pas une liste. +pas_nombre = n'est pas un nombre ! +pas_predicat= doit \u00eatre \u00e9gal \u00e0\u00a0 vrai ou faux. +pas= +pb_port=Impossible d'�couter sur le port: +pencolor=Couleur du crayon (par d\u00e9faut) +pour=pour +pref.cancel= +pref.font= +pref.general.arabic= +pref.general.aspect= +pref.general.asturian= +pref.general.catalan= +pref.general.english=Anglais +pref.general.esperanto= +pref.general.fast= +pref.general.french=Francais +pref.general.galician= +pref.general.german= +pref.general.greek= +pref.general.hungarian= +pref.general.italian= +pref.general.lang=Langue +pref.general.metal= +pref.general.motif= +pref.general.portuguese= +pref.general.slow= +pref.general.spanish= +pref.general.speed= +pref.general.windows= +pref.general= +pref.highlight.comment= +pref.highlight.enabled= +pref.highlight.example= +pref.highlight.init= +pref.highlight.operand= +pref.highlight.other= +pref.highlight.parenthesis= +pref.highlight.primitive = +pref.highlight= +pref.options.tcp= +pref.ok= +pref.options= +pref.options.eraseVariables= +pref.sound.instruments= +pref.sound.problem= +pref.sound= +pref.turtles= +primitives= +probleme_sequence = La s\u00e9quence musicale n'est pas compr\u00e9hensible: corrigez les erreurs ! +procedure_demarrage=Commande \u00e0 ex\u00e9cuter au d\u00e9marrage: +procedure_list=Liste des proc\u00e9dures: +procedure_vide = Le nom d'une proc\u00e9dure ne peut pas \u00eatre vide. +qualite_dessin = Pr\u00e9cision du trac\u00e9: +quit_editeur=Quitter l'\u00e9diteur sans enregistrer les modifications +quitter? = D\u00e9sirez vous quitter? +rechercher_dans = Rechercher dans : +relancer = Puis relancer l'application pour prendre en compte les modifications. +repertoire_accueil= R\u00e9pertoire d'accueil +repertoires = R\u00e9pertoire(s) +replace= +replaceall= +replacewith= +restaurer = Restaurer +rgb = RVB +rond= Rond +rouge = Rouge +screencolor=Couleur de l'\u00e9cran (par d\u00e9faut) +seule_tortue_dispo= Vous ne pouvez \u00e9liminer la seule tortue active ! +stop_chat=<<<<< Fin de communication >>>>> +stop= Stop +string_not_found= +style.bold= +style.exposant= +style.italic= +style.none= +style.strike= +style.subscript= +style.underline= +taille_dessin = Taille de la zone de dessin +title_axis= +titredialogue2=Ecriture de l'image en cours +too_much_arguments=Trop d'arguments dans les parenth�ses. +tortue_inaccessible= Il est impossible de cr\u00e9er une tortue avec le num\u00e9ro indiqu\u00e9 ! +traduire = Traduire! +traduire_de = Traduire de: +translatecomplete= +translateconsult= +translatecreate= +translatemessage= +translatemodify= +translatewant= +un_caractere = doit contenir un seul caract\u00e8re. +uniform_color= +variable_vide = Le nom d'une variable ne peut pas \u00eatre vide. +vers = Vers: +vert = Vert +vrai="vrai +xgrid= +y_a_pas = Il n'y a pas +ygrid= +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +bug.dialog.title=Thank you! You just uncovered a nasty Bug! +bug.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +bug.illegal.name=Something wanted to give one of my files an empty name + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_ar_MA.properties b/logo/src/langage_ar_MA.properties new file mode 100644 index 0000000..21a8477 --- /dev/null +++ b/logo/src/langage_ar_MA.properties @@ -0,0 +1,437 @@ +3d.fog=\u0636\u0628\u0627\u0628 +3d.fog.backdistance=\u0645\u0633\u0627\u0641\u0629 \u062a\u0639\u062a\u064a\u0645 \u0643\u0644\u064a\u0629 +3d.fog.density=\u0643\u062b\u0627\u0641\u0629 +3d.fog.exponential=\u0636\u0628\u0627\u0628 \u0643\u062b\u064a\u0641 +3d.fog.frontdistance=\u0628\u062f\u0627\u064a\u0629 \u0627\u0644\u0636\u0628\u0627\u0628 +3d.fog.linear=\u0636\u0628\u0627\u0628 \u062a\u062f\u0631\u064a\u062c\u064a +3d.fog.none=\u0628\u062f\u0648\u0646 +3d.fog.type=\u0646\u0648\u0639 \u0627\u0644\u0636\u0628\u0627\u0628 +3d.light=\u0636\u0648\u0621 +3d.light.ambient=\u0636\u0648\u0621 \u0627\u0644\u0645\u062d\u064a\u0637 +3d.light.angle=\u0632\u0627\u0648\u064a\u0629: +3d.light.apply=\u0637\u0628\u0642 +3d.light.direction=\u0627\u062a\u062c\u0627\u0647 +3d.light.directional=\u0645\u0635\u062f\u0631 \u0623\u062d\u0627\u062f\u064a \u0627\u0644\u0625\u062a\u062c\u0627\u0647 +3d.light.none=\u0628\u062f\u0648\u0646 \u0636\u0648\u0621 +3d.light.point=\u0646\u0642\u0637\u0629 \u0636\u0648\u0621 +3d.light.position=\u0645\u0648\u0642\u0639 +3d.light.spot=\u0628\u0642\u0639\u0629 +3d.light.type=\u0646\u0648\u0639 \u0627\u0644\u0625\u0636\u0627\u0621\u0629 +3d.viewer=\u0645\u0646\u0638\u0648\u0631 \u062b\u0644\u0627\u062b\u064a \u0627\u0644\u0623\u0628\u0639\u0627\u062f +active_grid=\u0645\u0641\u0639\u0644 +active_xaxis=\u0645\u062d\u0648\u0631 \u0627\u0644\u0623\u0641\u0627\u0635\u064a\u0644 +active_yaxis=\u0645\u062d\u0648\u0631 \u0627\u0644\u0623\u0641\u0627\u0635\u064a\u0644 +ajouter=\u0623\u0636\u0627\u0641\u0629 +animation_active = \u0627\u0644\u062a\u0646\u0634\u064a\u0637 \u0645\u0641\u0639\u0644. +apercu = \u0644\u0645\u062d\u0629 +attend_positif = \u0627\u0646\u062a\u0638\u0631 \u0645\u062f\u062e\u0644 \u0645\u0648\u062c\u0628. +backward=\u0648\u0631\u0627\u0621 +bas = \u0633\u0641\u0644\u0649e +bleu = \u0627\u0632\u0631\u0642 +bordermotif=\u0646 +caractere_special_variable = \u0627\u0633\u0645\u0627\u0621 \u0627\u0644\u0645\u062a\u063a\u064a\u0631\u0629 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 s +caractere_special1= \u0627\u0623\u0633\u0645\u0627\u0621 \u0627\u0644\u0628\u0631\u0627\u0645\u062c \u064a\u062c\u0628 \u0623\u0646 \u0644\u0627 +caractere_special2= \u062a\u062d\u062a\u0648\u064a \u0639\u0644\u0649 \u0645\u062b\u0644 \u0627\u0644\u062d\u0631\u0648\u0641 \u0627\u0644\u062b\u0627\u0644\u064a\u0629: : \ + - * / ( ) [ ] = < > & | +caractere_special3=\u0623\u0639\u062f \u062a\u0633\u0645\u064a\u0629 +carre = \u0645\u0631\u0628\u0639 +chaine_trop_longue = \u0644\u0627 \u064a\u0645\u0643\u0646 \u0644\u064a \u0637\u0628\u0639 \u0639\u0628\u0631 \u0627\u0644\u0634\u0627\u0634\u0629 \u0627\u0643\u062b\u0631 \u0645\u0646 32000 \u0643\u0644\u0645\u0629. +chat=\u062f\u0631\u062f\u0634\u0629 +chemin=\u0637\u0631\u064a\u0642 +color_3_arguments=\u064a\u062d\u062a\u0627\u062c \u0627\u0644\u0649 3 \u0645\u062d\u062f\u062f\u0627\u062a +commande=\u0627\u0645\u0631 +comme_parametre = ] \u0643\u0645\u062f\u062e\u0644. +couleur_du_crayon=\u0644\u0648\u0646 \u0627\u0644\u0642\u0644\u0645 +couleur_du_fond=\u0644\u0648\u0646 \u0627\u0644\u062e\u0644\u0641\u064a\u0629 +dans=Dans +definir=\u0627\u062a\u0645\u0645\u062a\u0645 \u062a\u062d\u062f\u064a\u062f +depassement_memoire = \u0645\u0646 \u0627\u0644\u062a\u0637\u0628\u064a\u0642\u0627\u062a \u062a\u0633\u062a\u0647\u0644\u0643 \u0645\u0627 \u064a\u0646\u0627\u0647\u0632 90 \u0645\u0646 \u0627\u0644\u062f\u0627\u0643\u0631\u0629 \u0627\u0644\u0645\u0648\u062c\u0648\u062f\u0629. +dernier = \u0622\u062e\u0631 +direction=\u0627\u062a\u062c\u0627\u0647 +division_par_zero = \u0644\u0627 \u064a\u0645\u0643\u0646 \u0627\u0644\u0642\u0633\u0645\u0629 \u0639\u0644\u0649 0 ! +dossier_parent = \u0627\u0644\u0649 \u0645\u0633\u062a\u0648\u0649 \u0623\u0639\u0644\u0649 +draw_grid=\u0634\u0628\u0643\u0629 \u0645\u0646 \u0648\u0631\u0627\u0621 \u0627\u0644\u0634\u0627\u0634\u0629 +echantillon = \u0639\u064a\u0646\u0627\u062a +echantillon_texte = \u0639\u064a\u0646\u0629 \u0643\u062a\u0627\u0628\u064a\u0629 +editeur=\u0646\u0627\u0634\u0631 +editor.undo=\u062a\u062e\u0644\u0635 \u0645\u0646 \u0622\u062e\u0631 \u0641\u0639\u0644 +editor.redo=\u0627\u0631\u062c\u0639 \u0627\u0644\u0641\u0639\u0644 \u0627\u0644\u0649 \u0623\u0635\u0644\u0647 +effacer_editeur= \u0627\u0645\u0633\u062d \u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0631\u0633\u0645 \u0639\u0646\u062f\u0645\u0627 \u0646\u062e\u0631\u062c \u0645\u0646 \u0627\u0644\u062d\u0641\u0638 +element_dans_liste= \u0639\u0646\u0635\u0631 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 [ +enlever=\u0625\u0632\u0627\u0644\u0629 +enregistreimage=\u062d\u0641\u0638 \u0627\u0644\u0635\u0648\u0631\u0629 \u062a\u062d\u062a ... +enregistrer_espace = \u0647\u0644 \u0623\u0645\u0633\u062d \u0641\u0636\u0627\u0621 \u0627\u0644\u0639\u0645\u0644 ? +entre_zero_un = \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0628\u064a\u0646 0 \u0648 1. +epaisseur_crayon = \u0627\u0644\u0633\u0645\u0643 \u0627\u0644\u0623\u0642\u0635\u0649 \u0644\u0644\u0642\u0644\u0645 +erreur_compteur = \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0639\u062f\u0627\u062f\u0627 \u062e\u0627\u0631\u062c \u0627\u0644\u062a\u0643\u0631\u0627\u0631. +erreur_crochet=\u063a\u0644\u0637 \u0641\u064a : ] \u0627\u0644\u0642\u0648\u0633 \u0627\u0644\u0645\u0646\u062a\u0638\u0631 +erreur_editeur=\u0645\u0646 \u0627\u0644\u0645\u0633\u062a\u062d\u064a\u0644 \u062d\u0641\u0638 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c.\n\u0645\u0646 \u0641\u0636\u0644\u0643\u060c \u0631\u0627\u062c\u0639 \u0627\u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u0646 \u0627\u0644\u0623\u0648\u0627\u0645\u0644\u0631 \u0645\u0627 \u0628\u064a\u0646 \u0628\u062f\u0627\u064a\u0629 ....\u0646\u0647\u0627\u064a\u0629 \u0648\n\u0627\u0644\u062a\u062d\u062f\u064a\u062f \u0627\u0644\u062c\u064a\u062f \u0644\u0644\u0645\u062a\u063a\u064a\u0631\u0627\u062a :a :b \u0648 c +erreur_fixestyle = \u062d\u062f\u062f\u0633\u062a\u064a\u0644 \u0644\u0627 \u064a\u0642\u0628\u0644 \u0627\u0644\u0642\u064a\u0645 \u0627\u0644\u062b\u0627\u0644\u064a\u0629 \u0643\u0645\u062f\u0627\u062e\u0644: \u0628\u062f\u0648\u0646, \u062f\u0627\u0643\u0646, \u062a\u062e\u0637\u064a\u0637, \u0623\u0633\u064a, \u0623\u0646\u062f\u064a\u0633: +erreur_format_image=\u062c\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u0642\u0628\u0648\u0644\u0629 \u0644\u0647\u0627 \u0627\u0644\u0631\u0645\u0632 *.png \u0648 *.jpg +erreur_memoire = XLogo \u0644\u064a\u0633 \u0644\u0647 \u0627\u0644\u062f\u0627\u0643\u0631\u0629 \u0644\u0643\u064a \u064a\u062e\u0644\u0642 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u0637\u0644\u0648\u0628\u0629 .\n\u062f\u0627\u062e\u0644 \u0627\u062e\u062a\u064a\u0627\u0631\u0627\u062a, \u062d\u0627\u0648\u0644 \u0627\u0644\u0632\u064a\u0627\u062f\u0629 \u0641\u064a \u0627\u0644\u062f\u0627\u0643\u0631\u0629: +erreur_memoire=XLogo \u0644\u064a\u0633 \u0644\u0647 \u0627\u0644\u062f\u0627\u0643\u0631\u0629 \u0644\u0643\u064a \u064a\u062e\u0644\u0642 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u0637\u0644\u0648\u0628\u0629 .\n\u062f\u0627\u062e\u0644 \u0627\u062e\u062a\u064a\u0627\u0631\u0627\u062a, \u062d\u0627\u0648\u0644 \u0627\u0644\u0632\u064a\u0627\u062f\u0629 \u0641\u064a \u0627\u0644\u062f\u0627\u0643\u0631\u0629: +erreur_nom_nombre_procedure = \u0627\u0633\u0645 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0639\u062f\u062f\u0627 ! +erreur_nom_nombre_variable = \u0627\u0633\u0645 \u0645\u062a\u063a\u064a\u0631\u0629 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 \u062a\u0643\u0648\u0646 \u0639\u062f\u062f\u0627! +erreur_pas_repertoire = \u0645\u062c\u0644\u062f \u063a\u064a\u0631 \u0645\u0642\u0628\u0648\u0644 ! +erreur_repetepour = \u0644\u0627 \u064a\u0645\u0643\u0646 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u0627\u0643\u062b\u0631 \u0645\u0646 4 \u0645\u062f\u0627\u062e\u0644. +erreur_retourne = \u0623\u0639\u062f \u0644\u0627 \u064a\u0645\u0643\u0646 \u0627\u0633\u062a\u0639\u0645\u0627\u0644\u0647\u0627 \u062e\u0627\u0631\u062c \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c ! +erreur_sortie1=\u062e\u0631\u062c\u062a \u0627\u0644\u0633\u0644\u062d\u0641\u0627\u0629 \u0639\u0646 \u0625\u0637\u0627\u0631\u0647\u0627. +erreur_sortie2=\u0639\u062f\u062f \u0627\u0644\u062e\u0637\u0648\u0627\u062a \u0642\u0628\u0644 \u0627\u0644\u062e\u0631\u0648\u062c: +erreur_stop = \u0642\u0641 \u064a\u062c\u0628 \u0623\u0646 \u062a\u0633\u062a\u0639\u0645\u0644 \u062f\u0627\u062e\u0644 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c \u0623\u0648 \u062f\u0627\u062e\u0644 \u0627\u0644\u062d\u0644\u0642\u0629 ! +erreur_tcp=\u0645\u0634\u0627\u0643\u0644 \u0627\u0644\u062a\u0648\u0627\u0635\u0644 \u0627\u0644\u0634\u0628\u0643\u064a. +erreur_variable = \u0644\u064a\u0633\u062a \u0645\u062a\u063a\u064a\u0631\u0629 \u0645\u0642\u0628\u0648\u0644\u0629! +erreur=\u063a\u0640\u0640\u0644\u0640\u0640\u0637 +error.3d.3vertex=\u064a\u062c\u0628 \u0639\u0644\u0649 \u0645\u0636\u0644\u0639 \u0623\u0646 \u064a\u062d\u0633\u0628 \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644 +error.3d.emptypolygon=\u064a\u062c\u0628 \u0639\u0644\u0649 \u0645\u0636\u0644\u0639 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0644\u0647 \u0645\u0633\u0627\u062d\u0629 \u0628\u062f\u0648\u0646 +error.ioecriture=\u0645\u0634\u0643\u0644 \u0645\u062f\u062e\u0644 \u0623\u0648 \u0645\u062e\u0631\u062c : \u062d\u0641\u0638 \u063a\u064a\u0631 \u0645\u0645\u0643\u0646 . +error.iolecture=\u0642\u0631\u0627\u0621\u0629 \u0627\u0644\u062c\u062f\u0627\u062f\u0629 \u063a\u064a\u0631 \u0645\u0645\u0643\u0646\u0629 +error.ne_peut_etre= \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 \u064a\u0648\u0636\u0639 \u0643\u062f\u0644\u0643. +error.novalue= \u0628\u062f\u0648\u0646 \u0642\u064a\u0645\u0629. +error.primitive2D=\u0644\u0627 \u064a\u0633\u062a\u0639\u0645\u0644 \u0625\u0644\u0627 \u0641\u064a \u0634\u0643\u0644 \u062b\u0646\u0627\u0626\u064a \u0627\u0644\u0623\u0628\u0639\u0627\u062f +error.primitive3D=\u0644\u0627 \u064a\u0633\u062a\u0639\u0645\u0644 \u0625\u0644\u0627\u0641\u064a \u0634\u0643\u0644 \u062b\u0644\u0627\u062b\u064a \u0627\u0644\u0623\u0628\u0639\u0627\u062f +error.procedure.must.be=\u064a\u062c\u0628 \u0623\u0646 \u062a\u0643\u0648\u0646 \u0628\u0631\u0645\u062c\u064a\u0629 +error.whattodo=\u0645\u0627\u062f\u0627 \u0623\u0641\u0639\u0644 \u0628 +error.word= \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0643\u0644\u0645\u0629 +existe_deja= \u064a\u0648\u062c\u062f \u0645\u0646 \u0642\u0628\u0644 +faux="\u063a\u0644\u0637 +ferme_editeur=\u0627\u0642\u0641\u0644 \u0627\u0644\u0646\u0627\u0634\u0631 \u0642\u0628\u0644 \u0643\u0644 \u0634\u064a\u0626. +fichier_du_type = \u062c\u062f\u0627\u062f\u0629 \u0645\u0646 \u0646\u0648\u0639 +fichiers = \u062c\u062f\u0627\u062f\u0629 \u0623\u0648 \u062c\u062f\u0627\u062f\u0627\u062a +fichiers_logo=\u062c\u062f\u0627\u062f\u0627\u062a Logo +fichiers_rtf = \u062c\u062f\u0627\u062f\u0627\u062as RTF +file_100K=\u0644\u062a\u0641\u0627\u062f\u064a \u062a\u062c\u0627\u0648\u0632 \u0633\u0639\u0629 \u0627\u0644\u062f\u0627\u0643\u0631\u0629\u060c \u0627\u0644\u0645\u0644\u0641\u0627\u062a +fin_flux = \u0644\u064a\u0633 \u0647\u0646\u0627\u0643 \u062d\u0631\u0641 \u0644\u0644\u0642\u0631\u0627\u0629 \u0645\u0646 \u062f\u0627\u062e\u0644 \u0627\u0644\u0625\u0646\u062f\u0641\u0627\u0642 +fin=\u0646\u0647\u0627\u064a\u0629 +find_replace=\u0627\u0633\u062a\u0628\u062f\u0644/\u0627\u0628\u062d\u062b +find=\u0627\u0628\u062d\u062b +flux_ecriture = \u0647\u062f\u0627 \u0627\u0644\u0625\u0646\u062f\u0641\u0627\u0642 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0627\u0633\u062a\u0639\u0645\u0627\u0644\u0647 \u0627\u062b\u0646\u0627\u0621 \u0627\u0644\u0643\u062a\u0627\u0628\u0629. +flux_existant =\u064a\u0645\u062b\u0644 \u0627\u0646\u062f\u0641\u0627\u0642 \u0645\u0641\u062a\u0648\u062d . \u0627\u0628\u062f\u0623 \u0628\u0625\u063a\u0644\u0627\u0642 \u0647\u062f\u0627 \u0627\u0644\u0625\u0646\u062f\u0641\u0627\u0642 . +flux_lecture = \u0647\u062f\u0627 \u0627\u0644\u0625\u0646\u062f\u0641\u0627\u0642 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0627\u0633\u062a\u0639\u0645\u0627\u0644\u0647 \u0627\u062b\u0646\u0627\u0621 \u0627\u0644\u0642\u0631\u0627\u0621\u0629. +flux_non_disponible = \u0627\u064a \u0627\u0646\u062f\u0641\u0627\u0642 \u0644\u0627 \u064a\u0634\u0645\u0644 \u062a\u0639\u0631\u064a\u0641 +forme_crayon = \u0634\u0643\u0644 \u0645\u0627\u062f\u0629 \u0627\u0644\u0631\u0633\u0645 \u0644\u0644\u0642\u0644\u0645 +forward=\u0623\u0645\u0627\u0645 +gui_exists=\u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u0628\u064a\u0627\u0646\u064a \u0627\u0644\u062b\u0627\u0644\u064a \u0645\u0648\u062c\u0648\u062f +haut = \u0623\u0639\u0644\u0649 +hollandais = \u0647\u0648\u0644\u0646\u062f\u0627 +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=\u0645\u0644\u0641\u0627\u062a \u0635\u0648\u0631\u0629 +images=\u0635\u0648\u0631 +imprimer_editeur=\u0637\u0628\u0627\u0639\u0629 \u0627\u0644\u0646\u0627\u0634\u0631 +interrompre_execution=\u0627\u0648\u0642\u0641 \u0627\u0644\u0639\u0645\u0644\u064a\u0629 +je_ne_sais_pas=\u0644\u0627 \u0627\u0639\u0631\u0641 \u0645\u0627\u062f\u0627 \u0623\u0641\u0639\u0644 \u0628 +line=\u062e\u0640\u0637 +lire_editeur=\u062d\u0641\u0638 \u0627\u0644\u0645\u062a\u063a\u064a\u0631\u0627\u062a \u0648 \u0627\u062e\u0631\u062c +liste_vide=\u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0641\u0627\u0631\u063a\u0629. +mainCommand=\u0627\u0645\u0631 \u0627\u0633\u0627\u0633\u064a +memoire = \u0627\u0644\u062f\u0627\u0643\u0631\u0629 \u0627\u0644\u062e\u0627\u0635\u0629 \u0628 XLogo (Mo): +menu.edition.copy=\u0646\u0633\u062e Ctl-C +menu.edition.cut=\u0642\u0637\u0639 Ctl-X +menu.edition.paste=\u0644\u0635\u0642 Ctl-V +menu.edition.selectall = \u0627\u062e\u062a\u0631 \u0627\u0644\u0643\u0644 +menu.edition=\u0646\u0634\u0631 +menu.file.captureimage.clipboard = \u0646\u0633\u062e \u0627\u0644\u0635\u0648\u0631\u0629 \u0641\u064a \u0627\u062a\u062c\u0627\u0647 \u0627\u0644\u062d\u0627\u0641\u0638\u0629 +menu.file.captureimage.print=\u0637\u0628\u0639 \u0635\u0648\u0631\u0629 +menu.file.captureimage=\u0627\u0644\u062a\u0642\u0641 \u0635\u0648\u0631\u0629 +menu.file.open=\u0641\u062a\u062d +menu.file.quit=\u062e\u0631\u0648\u062c +menu.file.save=\u062d\u0641\u0638 +menu.file.saveas=\u062d\u0641\u0638 \u062a\u062d\u062a +menu.file.textzone = \u0645\u0646\u0637\u0642\u0629 \u0646\u0635\u064a\u0629 +menu.file.textzone.rtf = \u062d\u0641\u0638 \u062a\u062d\u062a RTF +menu.file=\u062c\u062f\u0627\u062f\u0629 +menu.help.about=\u062d\u0648\u0644... +menu.help.licence=\u0631\u062e\u0635\u0629 +menu.help.online=\u0643\u062a\u0627\u0628 \u0639\u0644\u0649 \u0627\u0644\u062e\u0637 +menu.help.translatedlicence=\u062a\u0631\u062c\u0645\u0629 \u0627\u0644\u0631\u062e\u0635\u0629 +menu.help.translatexlogo=\u062a\u0631\u062c\u0645 XLogo +menu.help=\u0645\u0633\u0627\u0639\u062f\u0629 +menu.tools.eraser=\u062a\u062f\u0628\u064a\u0631 \u0627\u0644\u0628\u0631\u0627\u0645\u062c +menu.tools.pencolor=\u0627\u062e\u062a\u0631 \u0644\u0648\u0646 \u0627\u0644\u0642\u0644\u0645 +menu.tools.preferences=\u0627\u062e\u062a\u064a\u0627\u0631\u0627\u062a +menu.tools.screencolor=\u062e\u062a\u0631 \u0644\u0648\u0646 \u0627\u0644\u062e\u0644\u0641\u064a\u0629 +menu.tools.startup=\u062a\u062d\u062f\u064a\u062f \u062c\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u0625\u0646\u0637\u0644\u0627\u0642 ... +menu.tools.translate = \u0627\u0642\u062a\u0628\u0633 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c +menu.tools=\u0623\u062f\u0648\u0627\u062a +message_a_propos1=XLOGO \u0646\u0633\u062e\u0629 : +message_a_propos2=\u0645\u0648\u0642\u0639 \u0648\u064a\u0628: +message_a_propos3=\u064a\u0645\u0643\u0646\u0643\u0645 \u0627\u0644\u0625\u062a\u0635\u0627\u0644 \u0628\u0646\u0627 +messages=\u0625\u0634\u0627\u0631\u0627\u062a +mot_vide = \u0627\u0644\u0643\u0644\u0645\u0629 \u064a\u062c\u0628 \u0623\u0646 \u062a\u062d\u062a\u0648\u064a \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644 \u0639\u0644\u0649 \u062d\u0631\u0641 \u0648\u0627\u062d\u062f. +n_aime_pas = \u0644\u0627 \u064a\u062d\u0628 [ +nb_tortues = \u0627\u0644\u0639\u062f\u062f \u0627\u0644\u0623\u0642\u0635\u0649 \u0645\u0646 \u0627\u0644\u0633\u0644\u062d\u0641\u0627\u0629 +ne_renvoie_pas= \u0644\u0627 \u064a\u0633\u0644\u0645 \u0627\u064a \u0642\u064a\u0645\u0629 +no_gui=\u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u0628\u064a\u0627\u0646\u064a \u0627\u0644\u062b\u0627\u0644\u0640\u064a +no_host=\u0645\u0634\u0643\u0644 \u0641\u064a \u0627\u0644\u0646\u0648\u0627\u0635\u0644 \u0627\u0644\u0634\u0628\u0643\u064a \u0628\u0627\u0644\u062d\u0627\u0633\u0648\u0628 \u0648\u0627\u0644\u062f\u064a \u0639\u0646\u0648\u0627\u0646\u0647 \u0647\u0648 +nom_du_fichier = \u0627\u0633\u0645 \u062c\u062f\u0627\u062f\u0629 : +nombre_unicode = \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0628\u064a\u0646 0 \u0648 65535 . +normal = \u0639\u0627\u062f\u064a\u0629 +note.do = \u062f\u0648 +note.fa = \u0641\u0627 +note.la = \u0644\u0627 +note.mi = \u0645\u064a +note.re = \u0631\u064a +note.si = \u0633\u064a +note.sol = \u0635\u0644 +nouveau = \u062c\u062f\u064a\u062f +nouveau_dossier = \u062e\u0644\u0642 \u0645\u062c\u0644\u062f \u062c\u062f\u064a\u062f +ouvrir_editeur=\u0627\u0641\u062a\u062d \u0627\u0644\u0646\u0634\u0631 +parcourir=\u062a\u0635\u0641\u062d... +parenthese_fermante= \u0645\u0639\u062a\u0631\u0636\u0629 ) \u0645\u0646\u062a\u0636\u0631\u0629. +parenthese_ouvrante=\u0645\u0639\u062a\u0631\u0636\u0629 ( \u0645\u0646\u062a\u0636\u0631\u0629. +parenthese_vide=\u0645\u062d\u062a\u0648\u0649 \u0627\u0644\u0645\u0639\u062a\u0631\u0636\u0627\u062a \u0641\u0627\u0631\u063a ! +pas_argument= \u0644\u064a\u0633 \u0628\u0642\u064a\u0627\u0633 \u0645\u0642\u0628\u0648\u0644 +pas_assez_de=\u0644\u064a\u0633 \u0647\u0646\u0627\u0643 \u0639\u062f\u062f \u0645\u0639\u0637\u064a\u0627\u062a \u0643\u0627\u0645\u0644\u0629 \u0644 +pas_entier= \u0644\u064a\u0633 \u0628\u0639\u062f\u062f \u0635\u062d\u064a\u062d ! +pas_liste = \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f \u0641\u064a \u0627\u0644\u0642\u0627\u0626\u0645\u0629. +pas_nombre = \u0644\u064a\u0633 \u0628\u0639\u062f\u062f ! +pas_predicat= \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0645\u0633\u0627\u0648\u064a\u0627 \u0644 \u0635\u062d\u064a\u062d \u0623\u0648 \u062e\u0637\u0623 . +pas=\u062e\u0637\u0648\u0629 +pb_port=\u0627\u0644\u0631\u0628\u0637 \u0628\u0627\u0644\u0645\u0646\u0641\u062f \u063a\u064a\u0631 \u0645\u0645\u0643\u0646: +pencolor=\u0644\u0648\u0646 \u0627\u0644\u0642\u0644\u0645 (\u0636\u0645\u0646\u064a\u0627 ) +pour=\u0628\u062f\u0627\u064a\u0629 +pref.cancel=\u0627\u0644\u063a\u0627\u0621 +pref.font= \u0644\u0627\u0626\u062d\u0629 \u062d\u0631\u0648\u0641 +pref.general.arabic=\u0639\u0631\u0628\u064a\u0629 +pref.general.aspect=\u0645\u0646\u0638\u0631 +pref.general.asturian=\u0623\u0633\u062a\u0631\u0627\u0644\u064a\u0627 +pref.general.catalan=\u0643\u062a\u0644\u0646 +pref.general.english=\u0627\u0646\u0643\u0644\u064a\u0632\u064a +pref.general.esperanto=\u0627\u0633\u0628\u0631\u0627\u0646\u062a\u0648 +pref.general.fast=\u0633\u0631\u064a\u0639 +pref.general.french=\u0641\u0631\u0646\u0633\u064a +pref.general.galician=\u0643\u0627\u0644\u064a\u0633\u064a\u0627\u0646 +pref.general.german=\u0623\u0644\u0645\u0627\u0646\u064a\u0627 +pref.general.greek=\u064a\u0648\u0646\u0627\u0646 +pref.general.hungarian=\u0647\u0646\u063a\u0627\u0631\u064a +pref.general.italian=\u0625\u064a\u0637\u0627\u0644\u064a +pref.general.lang=\u0644\u063a\u0629 +pref.general.metal=\u0645\u0639\u062f\u0646 +pref.general.motif=\u0646\u0645\u0648\u062f\u062c +pref.general.portuguese= \u0628\u0631\u062a\u063a\u0627\u0644\u064a +pref.general.slow=\u0628\u0637\u064a\u0626 +pref.general.spanish=\u0627\u0633\u0628\u0627\u0646\u064a\u0627 +pref.general.speed=\u0633\u0631\u0639\u0629 \u0627\u0644\u062a\u062a\u0627\u0628\u0639 +pref.general.windows=\u0637\u0628\u064a\u0639\u064a +pref.general=\u0639\u0627\u0645 +pref.highlight.comment= \u0645\u0644\u0627\u062d\u0638\u0629 +pref.highlight.enabled= \u062a\u0641\u0639\u064a\u0644 \u0627\u0644\u0623\u0644\u0648\u0627\u0646 \u0641\u064a \u0627\u0644\u0643\u062a\u0627\u0628\u0629 +pref.highlight.example= # \u0647\u062f\u0647 \u0645\u0644\u0627\u062d\u0638\u0629\n \u0643\u0631\u0631 4[\u062a\u0642\u062f\u0645 100 \u064a\u0645\u064a\u0646 90]\n +pref.highlight.init= \u0625\u0639\u0627\u062f\u0629 +pref.highlight.operand= \u0645\u062a\u063a\u064a\u0631\u0627\u062a, \u0643\u0627\u0645\u0627\u062a, \u0623\u0639\u062f\u0627\u062f +pref.highlight.other= \u0622\u062e\u0631... +pref.highlight.parenthesis= \u0642\u0648\u0633, \u0645\u0639\u062a\u0631\u0636\u0629 +pref.highlight.primitive= \u0623\u0645\u0631 +pref.highlight= \u062a\u0644\u0648\u064a\u0646 +pref.ok=\u062d\u0633\u0646\u0627 +pref.options=\u062e\u064a\u0627\u0631\u0627\u062a +pref.options.eraseVariables= \u0627\u0645\u0633\u062d \u0627\u0644\u0645\u062a\u063a\u064a\u0631\u0627\u062a +pref.options.tcp=\u0631\u0642\u0645 \u0645\u064a\u0646\u0627\u0621 TCP +pref.sound = \u0635\u0648\u062a +pref.sound.instruments= \u0627\u0644\u0623\u062f\u0648\u0627\u062a \u0627\u0644\u062d\u0627\u0636\u0631\u0629 +pref.sound.problem= \u0645\u0634\u0643\u0644 \u0631\u0635\u062f \u0623\u062f\u0627\u0629 MIDI +pref.turtles= \u0627\u062e\u062a\u064a\u0627\u0631 \u0634\u0643\u0644 \u0627\u0644\u0633\u0644\u062d\u0641\u0627\u0629 +primitives=\u0627\u0648\u0627\u0645\u0631 \u0623\u0635\u0644\u064a\u0629 +probleme_sequence = \u0627\u0644\u0645\u0642\u0637\u0639 \u0627\u0644\u0645\u0648\u0633\u064a\u0642\u064a \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f: \u0635\u062d\u062d \u0627\u0644\u0623\u062e\u0637\u0627\u0621 ! +procedure_demarrage=\u0623\u0645\u0631 \u064a\u0646\u062c\u0632 \u0641\u064a \u0627\u0644\u0628\u062f\u0627\u064a\u0629: +procedure_list=\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0628\u0631\u0627\u0645\u062c: +procedure_vide = \u0627\u0633\u0645 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0641\u0627\u0631\u063a\u0627. +qualite_dessin = \u062a\u062f\u0642\u064a\u0642 \u0627\u0644\u062a\u062e\u0637\u064a\u0637: +quit_editeur=\u062e\u0631\u0648\u062c \u0628\u062f\u0648\u0646 \u062d\u0641\u0638 +quitter? = \u0623 \u062a\u0631\u063a\u0628\u0648\u0646 \u0641\u064a \u0627\u0644\u062e\u0631\u0648\u062c? +rechercher_dans = \u0627\u0628\u062d\u062b \u062f\u0627\u062e\u0644 : +relancer = \u062b\u0645 \u0641\u0639\u0644 \u0627\u0644\u062a\u0637\u0628\u064a\u0642\u0629 +repertoire_accueil= \u0645\u062c\u0644\u062f \u0627\u0644\u0625\u0633\u062a\u0642\u0628\u0627\u0644 +repertoires = \u0645\u062c\u0644\u062f \u0623\u0648 \u0645\u062c\u0644\u062f\u0627\u062a +replace=\u0627\u0633\u062a\u0628\u062f\u0644 +replaceall=\u0627\u0633\u062a\u0628\u062f\u0644 \u0627\u0644\u0643\u0644 +replacewith=\u0627\u0633\u062a\u0628\u062f\u0644 \u0628\u0640 +restaurer = \u0627\u0633\u062a\u0639\u0627\u062f\u0629 +rgb = RVB +rond= \u062f\u0627\u0626\u0631\u064a +rouge = \u0627\u062d\u0645\u0631 +screencolor=\u0644\u0648\u0646 \u0627\u0644\u0634\u0627\u0634\u0629(\u0636\u0645\u0646\u064a\u0627) +seule_tortue_dispo= \u0644\u0627 \u064a\u0645\u0643\u0646 \u062d\u062f\u0641 \u0627\u0644\u0633\u0644\u062d\u0627\u0629 \u0627\u0644\u0648\u062d\u064a\u062f\u0629 ! +stop_chat=<<<<< \u0646\u0647\u0627\u064a\u0629 \u0627\u0644\u062f\u0631\u062f\u0634\u0629 >>>>> +stop= \u0642\u0641 +string_not_found=\u0639\u0646\u0635\u0631 \u063a\u064a\u0644\u0631 \u0645\u0648\u062c\u0648\u062f +style.bold= \u062f\u0627\u0643\u0646 +style.exposant= \u0623\u0633 +style.italic= \u0645\u0646\u062d\u0631\u0641 +style.none= \u0628\u062f\u0648\u0646 +style.strike= \u062d\u0627\u062c\u0632 +style.subscript= \u0639\u0644\u0627\u0645\u0629 +style.underline= \u0633\u0637\u0631 +taille_dessin = \u0645\u0642\u064a\u0627\u0633 \u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0631\u0633\u0645 +title_axis=\u0645\u062d\u0648\u0631 \u062e\u0644\u0641\u064a\u0629 \u0627\u0644\u0634\u0627\u0634\u0629 +titredialogue2=\u0643\u062a\u0627\u0628\u0629 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u062c\u0627\u0631\u064a\u0629 +too_much_arguments=\u0639\u062f\u062f \u0627\u0644\u0645\u062f\u0627\u062e\u064a\u0644 \u0628\u064a\u0646 \u0627\u0644\u0642\u0648\u0633\u064a\u0646 \u0623\u0643\u062b\u0631 \u0645\u0645\u0627 \u064a\u0646\u0628\u063a\u064a +tortue_inaccessible= \u0645\u0646 \u0627\u0644\u0645\u0633\u062a\u062d\u064a\u0644 \u062e\u0644\u0642 \u0633\u0644\u062d\u0641\u0627\u0629 \u0628\u0647\u062f\u0627 \u0627\u0644\u0631\u0642\u0645 ! +traduire = \u0627\u0642\u062a\u0628\u0633! +traduire_de = \u0645\u0642\u062a\u0628\u0633 \u0645\u0646: +translatecomplete=\u0627\u062a\u0645\u0645 \u062a\u0631\u062c\u0645\u0629 +translateconsult=\u0627\u0637\u0644\u0639\u0648\u0627 \u0639\u0644\u0649 \u0645\u062e\u062a\u0644\u0641 \u0627\u0644\u062a\u0631\u062c\u0645\u0627\u062a +translatecreate=\u0627\u062d\u062f\u0627\u062b \u062a\u0631\u062c\u0645\u0629 \u062c\u062f\u064a\u062f\u0629 +translatemessage=\u0641\u064a \u062d\u0627\u0644\u0629 \u0627\u062a\u0645\u0627\u0645 \u0643\u0644 \u0627\u0644\u062d\u0642\u0648\u0644 +translatemodify=\u062a\u063a\u064a\u064a\u0631 \u062a\u0631\u062c\u0645\u0629 +translatewant=\u062a\u0631\u063a\u0628\u0648\u0646 \u0641\u064a +un_caractere = \u064a\u062c\u0628 \u0623\u0646 \u062a\u062d\u062a\u0648\u064a \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644 \u0639\u0644\u0649 \u062d\u0631\u0641 \u0648\u0627\u062d\u062f. +uniform_color=\u0644\u0648\u0646 \u0648\u062d\u064a\u062f +variable_vide = \u0627\u0633\u0645 \u0645\u062a\u063a\u064a\u0631\u0629 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0623\u0646 \u062a\u0643\u0648\u0646 \u0641\u0627\u0631\u063a\u0627. +vers = \u0627\u062a\u062c\u0627\u0647: +vert = \u0627\u062e\u0636\u0631 +vrai="\u0635\u062d\u064a\u062d +xgrid=\u0639\u0631\u0636 \u062a\u0631\u0628\u064a\u0639\u0629 +y_a_pas = \u0644\u064a\u0633 \u0647\u0646\u0627\u0643 +ygrid=\u0627\u0631\u062a\u0641\u0627\u0639 \u062a\u0631\u0628\u064a\u0639\u0629 +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_as_ES.properties b/logo/src/langage_as_ES.properties new file mode 100644 index 0000000..86552f7 --- /dev/null +++ b/logo/src/langage_as_ES.properties @@ -0,0 +1,437 @@ +3d.fog=Niebla +3d.fog.backdistance=Distancia ensin lluz +3d.fog.density=Densidad: +3d.fog.exponential=Niebla espesa +3d.fog.frontdistance=Distancia a la bruma +3d.fog.linear=Nublina +3d.fog.none=Nenguna +3d.fog.type=Tipu de niebla: +3d.light=Lluz +3d.light.ambient=Lluz ambiental +3d.light.angle=\u00c1ngulu: +3d.light.apply=Aplicar +3d.light.direction=Direici\u00f3n +3d.light.directional=Lluz direicional +3d.light.none=Apagar la lluz +3d.light.point=Puntu de lluz +3d.light.position=Posici\u00f3n +3d.light.spot=Focu +3d.light.type=Tipu de lluz: +3d.viewer = Visor 3D +active_grid = Activa +active_xaxis = Exa d'abscises (Exa X) +active_yaxis = Exa d'ordenaes (Exa Y) +ajouter = Amosar +animation_active = El mou animaci\u00f3n ta activu +apercu = Idea xeneral +attend_positif = espera por un n\u00famberu positivu. +backward = P'atr\u00e1s +bas = Baxu +bleu = Azul +bordermotif = Marcu d'adornu +caractere_special_variable = El nome d'una variable nun pue incluyir +caractere_special1 = Los procedimientos nun pue llamase con +caractere_special2 = caracteres como \ + - * / ( ) [ ] = < > & | : +caractere_special3 = Cambia'l nome del procedimientu. +carre = Cuadr\u00e1u +chaine_trop_longue = Nun pueo emprentar una pallabra o una llista con m\u00e1s de 32000 caracteres +chat = Chat +chemin = Cam\u00edn +color_3_arguments = necesita una llista de tres elementos, [color\u00e1u, verde azul] +commande = Comandu +comme_parametre = ] como argumentu. +couleur_du_crayon = Color del llapiceru +couleur_du_fond = Color de fondu (fueya) +dans = En +definir = Acaba de definir +depassement_memoire = Esta aplicaci\u00f3n garr\u00f3 un 90% de la memoria dedicada a XLogo. La so aici\u00f3n foi parada pa nun rebasar la pila datos. Ha d'asegurase que'l so programa nun tien un bucle infinitu o aumenta'l tama\u00f1u de memoria disponible. +dernier = =daltimu +direction = Direici\u00f3n +division_par_zero = \u00a1Nun pues dividir por cero! +dossier_parent = Directoriu padre +draw_grid = Cuadr\u00edcula nel fondu (fueya) +echantillon = Muestra +echantillon_texte = Muestra del testu +editeur = Asoleyar +editor.redo=Refacer +editor.undo=Desfacer +effacer_editeur = Borrar la pantalla al salir del editor +element_dans_liste = pallabres na llista [ +enlever = Eliminar +enregistreimage = Guardar imaxe como ... +enregistrer_espace = \u00bfDesaniciar les variables y los procedimientos? +entre_zero_un = Debe tar ente 0 y 1. +epaisseur_crayon = Tama\u00f1u m\u00e1simu del llapiceru +erreur = ERROR +erreur_compteur = Nun pue usase cuentarepite fuera d'un bucle repite. +erreur_crochet = Error de corchete: se esperaba ] +erreur_editeur = Imposible guardar tolos procedimientos.\nComprueba los bloques PA .... FIN\ny la correuta definici\u00f3n de les variables :a :b etc +erreur_fixestyle = ponestilo puede aceptar solamente estos valores: nengunu, negrina, subray\u00e1o, tach\u00e1o, super\u00edndice, sub\u00edndice. +erreur_format_image = Los \u00fanicos archivos para imagen son los de formato *.png y *.jpg +erreur_memoire = XLogo nun tien memoria suficiente para facer la aici\u00f3n deseada.\nPon un valor mayor pal tama\u00f1u de memoria. +erreur_nom_nombre_procedure = \u00a1El nome d'un procedimientu nun pue ser un n\u00famberu! +erreur_nom_nombre_variable = \u00a1El nome d'una variable nun pue ser un n\u00famberu! +erreur_pas_repertoire = nun ye un directoriu correutu +erreur_repetepour = Ha de tener tres o cuatro elementos: [variable min max incrementu] +erreur_retourne = Pues emplegar devuelve solo dientro d'un procedimientu +erreur_sortie1 = La tortuga sal de la pantalla. +erreur_sortie2 = N\u00famberu de pasos anantes de salir: +erreur_stop = Pues emplegar alto solo dientro d'un procedimientu o d'un bucle! +erreur_tcp = Problemes de comunicaci\u00f3n na rede +erreur_variable = \u00a1Nun ye una variable afayadiza! +error_bad_values = S\u00f3lo aceuta valores +error.3d.3vertex = Un pol\u00edgonu ha de tener, polo menos, tres v\u00e9rtices. +error.3d.emptypolygon = L'\u00e1rea d'un pol\u00edgonu nun pue ser cero +error.ioecriture = Problema de entrada-salida: Nun se pue guardar +error.iolecture = Nun se pue lleer l'archivu desy\u00e1u +error.ne_peut_etre = nun pue tar asiti\u00e1u equ\u00ed +error.novalue = nun tien valir +error.primitive2D = S\u00f3lo pue usase en 2D +error.primitive3D = S\u00f3lo pue usase en 3D +error.procedure.must.be=ha de ser el nome d'un procedimientu! +error.whattodo = \u00bfQu\u00e9 facer con +error.word = debe ser una pallabra. +existe_deja = ya ta defin\u00edu +faux = "falso +ferme_editeur = Zarra'l ventanu del editor +fichier_du_type = Archivos de formatu +fichiers = Archivu +fichiers_logo = Archivos Logo +fichiers_rtf = Archivos RTF +file_100K = Pa nun gastar la memoria, la imaxe nun pue ocupar m\u00e1s de 100 kb +fin = fin +fin_flux = Nun hai m\u00e1s carauteres para lleer nel fluxu n\u00b0 +find = Atopar +find_replace = Atopar/Reemplazar +flux_ecriture = Nun se pue escribir n'esti fluxu +flux_existant = ya designa un fluxu abiertu. Zarra el fluxu abiertu anantes d'emplegar esti identificador. +flux_lecture = Nun se pue lleer dende esti fluxu +flux_non_disponible = Neng\u00fan fluxu abiertu tien esti identificador +forme_crayon = Forma del llapiceru +forward = P'alantre +gui_exists = El componente gr\u00e1ficu ya esiste/ ya foi defin\u00edu +haut = Altu +hollandais = Holand\u00e9s +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile = Archivos d'imaxe +images = Im\u00e1xenes +imprimer_editeur = Emprentar l'editor +interrompre_execution = Parar el trabayu en cursu +je_ne_sais_pas = Nun s\u00e9 c\u00f3mo facer +line = ll\u00ednia +lire_editeur = Guardar les modificaciones y salir +liste_vide = La llista ta vac\u00eda. +mainCommand = Comandu d'aniciu: +memoire = Memoria pa XLogo (Mb) +menu.edition = Edici\u00f3n +menu.edition.copy = Copiar Ctl-C +menu.edition.cut = Cortar Ctl-X +menu.edition.paste = Pegar Ctl-V +menu.edition.selectall = Seleccionar too +menu.file = Archivu +menu.file.captureimage = Garrar la imaxe +menu.file.captureimage.clipboard = Copiar al portafueyes +menu.file.captureimage.print = Emprentar imaxe +menu.file.open = Abrir +menu.file.quit = Salir +menu.file.save = Guardar +menu.file.saveas = Guardar como +menu.file.textzone = Fastera de testu +menu.file.textzone.rtf = Guardar en formatu RTF +menu.help = Ayuda +menu.help.about = Sobre XLogo ... +menu.help.licence = Llicencia +menu.help.online=Manual en ll\u00ednia +menu.help.translatedlicence = Torna de la llicencia +menu.help.translatexlogo = Tornar XLogo +menu.tools = Ferramientes +menu.tools.eraser = Borra procedimientu +menu.tools.pencolor = Escoyer color del llapiceru +menu.tools.preferences = Preferencies +menu.tools.screencolor = Escoyer color de fondu (fueya) +menu.tools.startup = Definir los archivos d'ainiciu... +menu.tools.translate = Tornar procedimientos +message_a_propos1 = Versi\u00f3n de XLogo: +message_a_propos2 = Sitiu web: +message_a_propos3 = Pues escribime a: +messages = Mensaxes +mot_vide = La pallabra ha de tener polo menos un caracter +n_aime_pas = nun aceuta [ +nb_tortues = N\u00famberu m\u00e1simu de tortugues +ne_renvoie_pas = nun fizo salir a +no_gui = El componente gr\u00e1ficu nun esiste/ nun foi defin\u00edu +no_host = Problemes na comunicaci\u00f3n en rede col ordenador en direcci\u00f3n: +nom_du_fichier = Nome del archivu: +nombre_unicode = debe tar ente 0 y 65535. +normal = Normal +note.do = do +note.fa = fa +note.la = la +note.mi = mi +note.re = re +note.si = si +note.sol = sol +nouveau = Nuevu +nouveau_dossier = Facer nuevu directoriu +ouvrir_editeur = Entrar nel editor +parcourir = Alcontrar... +parenthese_fermante = ) nun pue tar equ\u00ed +parenthese_ouvrante = esper\u00e1base u par\u00e9ntesis ( +parenthese_vide = \u00a1Nun hai nada ente par\u00e9ntesis! +pas = Escala +pas_argument = nun ye la entrada correuta +pas_assez_de = Nun hai datos bastantes pa +pas_entier = nun ye un n\u00famberu enteru +pas_liste = nun ye una llista. +pas_nombre = nun ye un n\u00famberu +pas_predicat = ha de ser verdadero o falso +pb_port = Nun se pue conectar el puertu +pencolor = Color del llapiceru predetermin\u00e1u +pour = pa +pref.cancel = Cancelar +pref.font = Fonte +pref.general = Xeneral +pref.general.arabic = \u00c1rabe +pref.general.aspect = Aspeutu +pref.general.asturian =Asturianu +pref.general.catalan=Catal\u00e1n +pref.general.english = Ingl\u00e9s +pref.general.esperanto = Esperanto +pref.general.fast = R\u00e1pido +pref.general.french = Franc\u00e9s +pref.general.galician = Gallegu +pref.general.german = Alem\u00e1n +pref.general.greek=Griego +pref.general.hungarian=H\u00fangaro +pref.general.italian=Italianu +pref.general.lang = Llingua +pref.general.metal = Metal +pref.general.motif = Motif +pref.general.portuguese = Portugu\u00e9s +pref.general.slow = Lento +pref.general.spanish = Espa\u00f1ol +pref.general.speed = Velocid\u00e1 de la tortuga +pref.general.windows = Windows +pref.highlight = Resaltao +pref.highlight.comment = Comentarios +pref.highlight.enabled = Activa'l resalt\u00e1o de sintaxis +pref.highlight.example = # Esto ye un comentariu\n repite 4 [avanza 100 giraderecha 90] +pref.highlight.init = Defeutu +pref.highlight.operand = Variables, pallabres, n\u00famberos +pref.highlight.other = Otru... +pref.highlight.parenthesis = Par\u00e9ntesis, corchetes +pref.highlight.primitive = Primitiva +pref.ok = Si +pref.options = Opciones +pref.options.eraseVariables=Borra les variables cuando zarra l'editor. +pref.options.tcp=n�mberu del puertu TCP: +pref.sound = son\u00edu +pref.sound.instruments = Instrumentos disponibles +pref.sound.problem = Problemes col MIDI del ordenador +pref.turtles = Escoyeta de la tortuga +primitives = Primitives +probleme_sequence = \u00a1Nun pueo entender la serie de notes. corrixe los errores! +procedure_demarrage = Comandu fechu al principiu: +procedure_list = Llista de procedimientos +procedure_vide = \u00a1El nome d'un procedimientu nun pue ser nulu! +qualite_dessin = Calid\u00e1 que s'emplega nel dibuxu +quit_editeur = Salir del editor ensin guardar les modificaciones +quitter? = \u00bfQui\u00e9s salir? +rechercher_dans = Atopar en +relancer = Llueu re-anicia XLogo pa aplicar los cambios. +repertoire_accueil = Directoriu de dest\u00edn +repertoires = Directoriu +replace = Reemplazar +replaceall = Reemplazar too +replacewith = Reemplaza con: +restaurer = Restaurar +rgb = CVA +rond = Redondu +rouge = Colorao +screencolor = Color de la fueya predeterminada +seule_tortue_dispo = \u00a1Nun se pue desaniciar la \u00fanica tortuga disponible! +stop = Alto +stop_chat = <<<<< Fin del chat >>>>> +string_not_found = Elementu nun atop\u00e1u +style.bold = Negrina +style.exposant = Super\u00edndice +style.italic = Cursiva +style.none = Nengunu +style.strike = Tach\u00e1o +style.subscript = Sub\u00edndice +style.underline = Subray\u00e1o +taille_dessin = Tama\u00f1u del ventanu pa dibuxar +title_axis = Exes cartesianes +titredialogue2 = Escritura d'imaxe en cursu +too_much_arguments = Demasiaos argumentos ente par\u00e9ntesis +tortue_inaccessible = \u00a1Ye imposible facer una tortuga con esi n\u00famberu! +traduire = \u00a1Tornar! +traduire_de = Tornar de: +translatecomplete = Completar una torna +translateconsult = Consultar les tornes qu'esistan +translatecreate = Crear una torna nueva +translatemessage = Cuando tolos campos tean enllenos nes dos tables, fai click nel bot\u00f3n ok. M\u00e1ndame l'archivu xener\u00e1u a [email protected] +translatemodify = Camudar una torna +translatewant = Ust\u00e9 deseya +un_caractere = ha de tener un caracter +uniform_color = Color s\u00f3lidu +variable_vide = \u00a1El nome d'una variable nun pue ser nulu! +vers = Hacia: +vert = Verde +vrai = "cierto +xgrid = Ancho de la cuadr\u00edcula +y_a_pas = No hai +ygrid = Altor de la cuadr\u00edcula +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_ca_ES.properties b/logo/src/langage_ca_ES.properties new file mode 100644 index 0000000..8e76ee9 --- /dev/null +++ b/logo/src/langage_ca_ES.properties @@ -0,0 +1,437 @@ +3d.fog=Boira +3d.fog.backdistance=Dist\u00e0ncia d'opacitat total +3d.fog.density=Densitat: +3d.fog.exponential=Boira densa +3d.fog.frontdistance=Dist\u00e0ncia a la boira +3d.fog.linear=Boira lineal +3d.fog.none=Cap +3d.fog.type=Tipus de boira: +3d.light=Llum +3d.light.ambient=Llum ambient +3d.light.angle=Angle: +3d.light.apply=Aplicar +3d.light.direction=Direcci\u00f3 +3d.light.directional=Llum direccional +3d.light.none=Apagar el llum +3d.light.point=Punt de llum +3d.light.position=Posici\u00f3 +3d.light.spot=Focus de llum +3d.light.type=Tipus de llum: +3d.viewer=Visor 3D +active_grid=Activa +active_xaxis=Eix d'abscisses (Eix x) +active_yaxis=Eix d'ordenades (Eix y) +ajouter=Afegir +animation_active=El mode animaci\u00f3 est\u00e0 activat. +apercu=Vista pr\u00e8via +attend_positif=espera un nombre positiu. +backward=Endarrera +bas=Baix +bleu=Blau +bordermotif=Motiu del marc: +caractere_special1=Els noms dels procediments no poden incloure +caractere_special2=car\u00e0cters com + - * / ( ) [ ] = < > & | : +caractere_special3=Reanomena +caractere_special_variable=Els noms de les variables no poden incloure +carre=Quadrat +chaine_trop_longue=No puc imprimir una paraula o una llista que tingui m\u00e9s de 32000 car\u00e0cters. +chat=Xat +chemin=Cam\u00ed +color_3_arguments=necessita una llista de 3 arguments: [vermell verd blau] +commande=Comanda: +comme_parametre=] com a par\u00e0metre +couleur_du_crayon=Color del llapis +couleur_du_fond=Color del fons +dans=En +definir=Acabes de definir +depassement_memoire=XLogo est\u00e0 usant el 90% de la mem\u00f2ria disponible. La comanda en curs ser\u00e0 aturada per a prevenir un eventual desbordament de la mem\u00f2ria. Verifiqueu que el vostre programa no entra en un bucle infinit. Si no \u00e9s el cas, augmenteu la mem\u00f2ria dedicada a XLogo. +dernier=\u00daltim +direction=Sentit +division_par_zero=No pots dividir per zero! +dossier_parent=Directori pare +draw_grid=Quadr\u00edcula en el fons de pantalla +echantillon=Mostra +echantillon_texte=Mostra de text +editeur=Editor +editor.redo=Refer +editor.undo=Desfer +effacer_editeur=Borra la pantalla al sortir de l'editor +element_dans_liste=paraules en la llista [ +enlever=Eliminar +enregistreimage=Desar la imatge com... +enregistrer_espace=Eliminar les variables i els procediments? +entre_zero_un=Ha d'estar compr\u00e8s entre 0 i 1. +epaisseur_crayon=Tamany m\u00e0xim del llapis +erreur=ERROR +erreur_compteur=comptarepeteix no \u00e9s v\u00e0lid fora d'un bucle repeteix +erreur_crochet=Error de claud\u00e0tors: s'esperava ] +erreur_editeur=Impossible desar tots els procediments. Verifica els blocs PER...FI, i la definici\u00f3 correcta de variables :a :b etc +erreur_fixestyle=fixaestil nom\u00e9s accepta les valors seg\u00fcents com a arguments: cap, negreta, subratllat, cursiva, barrat, sub\u00edndex, super\u00edndex +erreur_format_image=Les extensions acceptades per a desar imatges s\u00f3n: *.png i *.jpg +erreur_memoire=XLogo no t\u00e9 mem\u00f2ria suficient per crear la imatge requerida. En el tabulador "Opcions", augmenta el tamany dedicat a XLogo. +erreur_nom_nombre_procedure=El nom d'un procediment no pot ser un nombre! +erreur_nom_nombre_variable=El nom d'una variable no pot ser un nombre! +erreur_pas_repertoire=no \u00e9s un directori v\u00e0lid! +erreur_repetepour=ha de contenir tres o quatre elements [variable inici fi increment] +erreur_retourne=No pots utilitzar retornar fora d'un procediment! +erreur_sortie1=La tortuga ha sortit de la zona de dibuix. +erreur_sortie2=Nombre de passos abans de sortir: +erreur_stop=No pots utilitzar atura fora d'un procediment o d'un bucle! +erreur_tcp=Problema de comunicaci\u00f3 de xarxa. +erreur_variable=no \u00e9s una variable v\u00e0lida! +error_bad_values=accepta nom\u00e9s els valors seg\u00fcents: +error.3d.3vertex=Un pol\u00edgon ha de tenir almenys tres v\u00e8rtexs! +error.3d.emptypolygon=L'\u00e0rea d'un pol\u00edgon ha de ser diferent de zero! +error.ioecriture=Problema d'entrada-sortida, no puc gravar... +error.iolecture=Impossible llegir el fitxer demanat. +error.ne_peut_etre=no pot estar situat aqu\u00ed. +error.novalue=no t\u00e9 valor. +error.primitive2D=nom\u00e9s est\u00e0 disponible en mode 2D. +error.primitive3D=nom\u00e9s est\u00e0 disponible en mode 3D. +error.procedure.must.be=ha de ser el nom d'un procediment! +error.whattodo=No s\u00e9 qu\u00e8 fer amb +error.word=ha de ser una paraula. +existe_deja=ja est\u00e0 definit. +faux="fals +ferme_editeur=Tanca la finestra de l'editor +fichier_du_type=Arxius de format +fichiers=Arxiu(s) +fichiers_logo=Arxius Logo +fichiers_rtf=Arxius RTF +file_100K=Per evitar desbordaments de mem\u00f2ria, el tamany del fitxer no pot superar els 100kb +fin=fi +fin_flux=No hi ha m\u00e9s car\u00e0cters per llegir en el flux n. +find=Cercar +find_replace=Cercar/Reempla\u00e7ar +flux_ecriture=No es pot escriure en aquest flux. +flux_existant=ja designa un flux obert. Tanca el flux obert abans de reutilitzar aquest identificador. +flux_lecture=No es pot llegir en aquest flux. +flux_non_disponible=Aquest identificador no es correspon a cap flux obert. +forme_crayon=Forma del llapis. +forward=Endavant +gui_exists=La component gr\u00e0fica seg\u00fcent ja ha estat definida: +haut=Alt +hollandais=Holand\u00e8s +hsb=HSB +hsbbleu=B +hsbrouge=H +hsbvert=S +imagefile=Arxius d'imatges +images=Imatges +imprimer_editeur=Imprimeix l'editor +interrompre_execution=Atura l'execuci\u00f3 en curs +je_ne_sais_pas=No s\u00e9 com fer +line=l\u00ednia +lire_editeur=Desar els canvis i sortir +liste_vide=La llista est\u00e0 buida. +mainCommand=Comanda d'inici: +memoire=Mem\u00f2ria destinada a XLogo (Mb): +menu.edition=Edici\u00f3 +menu.edition.copy=Copiar Ctrl+C +menu.edition.cut=Retallar Ctrl+X +menu.edition.paste=Enganxar Ctrl+V +menu.edition.selectall=Seleccionar tot Ctrl+A +menu.file=Fitxer +menu.file.captureimage=Capturar la imatge +menu.file.captureimage.clipboard=Copiar al portapapers +menu.file.captureimage.print=Imprimir la imatge +menu.file.open=Obrir +menu.file.quit=Sortir +menu.file.save=Desar +menu.file.saveas=Anomenar i desar +menu.file.textzone=Zona de text +menu.file.textzone.rtf=Desar en format RTF +menu.help=Ajuda +menu.help.about=Sobre XLogo... +menu.help.licence=Llic\u00e8ncia +menu.help.online=Manual en l\u00ednia +menu.help.translatedlicence=Traducci\u00f3 de la llic\u00e8ncia +menu.help.translatexlogo=Traduir XLogo +menu.tools=Eines +menu.tools.eraser=Esborra procediment +menu.tools.pencolor=Escollir color del llapis +menu.tools.preferences=Prefer\u00e8ncies +menu.tools.screencolor=Escollir color de fons +menu.tools.startup=Definir els arxius d'inici +menu.tools.translate=Traduir procediments +message_a_propos1=Versi\u00f3 de XLogo: +message_a_propos2=Lloc web: +message_a_propos3=Pots escriure'm a: +messages=Missatges +mot_vide=La paraula ha de contenir almenys un car\u00e0cter +n_aime_pas=no accepta [ +nb_tortues=Nombre m\u00e0xim de tortugues +ne_renvoie_pas=no d\u00f3na cap valor a +no_gui=La component gr\u00e0fica seg\u00fcent no existeix o no s'ha definit +no_host=Problema de comunicaci\u00f3 de xarxa amb l'ordinador d'adre\u00e7a: +nom_du_fichier=Nom del fitxer: +nombre_unicode=ha d'estar compr\u00e8s entre 0 i 65535. +normal=Normal +note.do=do +note.fa=fa +note.la=la +note.mi=mi +note.re=re +note.si=si +note.sol=sol +nouveau=Nou +nouveau_dossier=Crear un nou directori +ouvrir_editeur=Obrir l'editor +parcourir=Cercar... +parenthese_fermante=S'esperava un par\u00e8ntesi ) +parenthese_ouvrante=S'esperava un par\u00e8ntesi ( +parenthese_vide=No hi ha res entre els par\u00e8ntesis! +pas=Escala +pas_argument=no \u00e9s un argument v\u00e0lid +pas_assez_de=No hi ha suficient dades per +pas_entier=no \u00e9s un enter! +pas_liste=no \u00e9s una llista. +pas_nombre=no \u00e9s un nombre! +pas_predicat=ha de ser cert o fals. +pb_port=Impossible connectar-se al port: +pencolor=Color de llapis predeterminat +pour=per +pref.cancel=Cancel.lar +pref.font=Font +pref.general=General +pref.general.arabic=\u00c0rab +pref.general.aspect=Aspecte +pref.general.asturian=Asturi\u00e0 +pref.general.catalan=Catal\u00e0 +pref.general.english=Angl\u00e8s +pref.general.esperanto=Esperanto +pref.general.fast=R\u00e0pid +pref.general.french=Franc\u00e8s +pref.general.galician=Gallec +pref.general.german=Alemany +pref.general.greek=Grec +pref.general.hungarian=Hongar\u00e8s +pref.general.italian=Itali\u00e0 +pref.general.lang=Idioma +pref.general.metal=Metall +pref.general.motif=Motif +pref.general.portuguese=Portugu\u00e8s +pref.general.slow=Lent +pref.general.spanish=Castell\u00e0 +pref.general.speed=Velocitat de la tortuga +pref.general.windows=Windows +pref.highlight=Ressaltat +pref.highlight.comment=Comentaris +pref.highlight.enabled=Activa el ressaltat de la sintaxis +pref.highlight.example=# Aix\u00f2 \u00e9s un comentari\nrepeteix 4 [avan\u00e7a 100 gd 90] +pref.highlight.init=Predeterminat +pref.highlight.operand=Variables, paraules, nombres +pref.highlight.other=Un altre... +pref.highlight.parenthesis=Par\u00e8ntesis, claud\u00e0tors +pref.highlight.primitive=Primitives +pref.options.tcp=Nombre del Port TCP +pref.options.eraseVariables=Esborra les variables quan es tanca l'editor. +pref.ok=D'acord +pref.options=Opcions +pref.sound=So +pref.sound.instruments=Instruments disponibles +pref.sound.problem=Problema al detectar el MIDI de l'ordinador +pref.turtles=Tria de la tortuga +primitives=Primitives +probleme_sequence=No puc entendre la seq\u00fc\u00e8ncia musical, repassa-la! +procedure_demarrage=Comanda per executar a l'inici: +procedure_list=Llista de procediments: +procedure_vide=El nom d'un procediment no pot ser buit! +qualite_dessin=Qualitat de dibuix +quit_editeur=Sortir de l'editor sense desar els canvis +quitter?=Segur que vols sortir? +rechercher_dans=Buscar a: +relancer=Reinicia XLogo per aplicar els canvis. +repertoire_accueil=Directori de dest\u00ed +repertoires=Directori(s) +replace=Reempla\u00e7ar +replaceall=Reempla\u00e7ar tot +replacewith=Reempla\u00e7ar per: +restaurer=Restaurar +rgb=VVB (RGB) +rond=Rod\u00f3 +rouge=Vermell +screencolor=Color del fons de pantalla (predeterminat) +seule_tortue_dispo=No pots eliminar l'\u00fanica tortuga activa! +stop=Atura +stop_chat=<<<<< Fi del xat >>>>> +string_not_found=Element no trobat +style.bold=Negreta +style.exposant=Super\u00edndex +style.italic=Cursiva +style.none=Cap +style.strike=Barrat +style.subscript=Sub\u00edndex +style.underline=Subratllat +taille_dessin=Tamany de la finestra per dibuixar +title_axis=Eixos cartesians +titredialogue2=Guardant la imatge... +too_much_arguments=Massa arguments entre els par\u00e8ntesis. +tortue_inaccessible=Impossible crear una tortuga amb aquest nombre! +traduire=Traduir! +traduire_de=Traduir de: +translatecomplete=Completar una traducci\u00f3 +translateconsult=Consultar les traduccions existents +translatecreate=Crear una nova traducci\u00f3 +translatemessage=Quan tots els camps estiguin complerts en les dues taules, clica el bot\u00f3 "D'acord". Envia'm el fitxer generat a [email protected] +translatemodify=Modificar una traducci\u00f3 +translatewant=Desitges: +un_caractere=ha de contenir nom\u00e9s un car\u00e0cter. +uniform_color=Color s\u00f2lid: +variable_vide=El nom d'una variable no pot ser buit. +vers=Cap a: +vert=Verd +vrai="cert +xgrid=Amplada de la quadr\u00edcula: +y_a_pas=No hi ha +ygrid=Al\u00e7ada de la quadr\u00edcula: +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_de_DE.properties b/logo/src/langage_de_DE.properties new file mode 100644 index 0000000..5d6d875 --- /dev/null +++ b/logo/src/langage_de_DE.properties @@ -0,0 +1,437 @@ +3d.fog.backdistance=Abstand Gesamttransparenz +3d.fog.density=Dichte +3d.fog.exponential=Dichter Nebel +3d.fog.frontdistance=Abstand vorne +3d.fog.linear=Linearer Nebel +3d.fog.none=Keine +3d.fog.type=Nebeltyp: +3d.fog=Nebel +3d.light.ambient=Umgebungslicht +3d.light.angle=Winkel: +3d.light.apply=Anwenden +3d.light.direction=Richtung +3d.light.directional=Gerichtetes Licht +3d.light.none=Ohne Licht +3d.light.point=Punktlicht +3d.light.position=Position +3d.light.spot=Spotlicht +3d.light.type=Beleuchtungstyp: +3d.light=Licht +3d.viewer=3D Betrachter +active_grid=Aktiv +active_xaxis=X-Achse +active_yaxis=Y-Achse +ajouter=F\u00fcge hinzu +animation_active = Du bist zur Zeit im Animations Modus.. +apercu = Vorschau +attend_positif = wartet auf ein positives Argument. +backward=R\u00fcckw\u00e4rts +bas = Schlecht +bleu = Blau +bordermotif=Randmotiv +caractere_special_variable = Variablennamen enthalten nie +caractere_special1=Namen von Prozeduren d\u00fcrfen folgende Zeichen +caractere_special2=Zeichen wie + - * / ( ) [ ] = < > & | : +caractere_special3=Gebe einen neuen Namen +carre=Quadrat +chaine_trop_longue=Ich kann kein Wort oder Liste mit mehr als 32000 Zeichen schreiben. +chat=Chat +chemin=Pfad +color_3_arguments=muss eine drei-elementige Liste haben, [rot gr\u00fcn blau] +commande=Kommando : +comme_parametre = ] als Angaben. +couleur_du_crayon=Stiftfarbe +couleur_du_fond=Hintergrundfarbe +dans=In +definir=Du definierst +depassement_memoire=Die Anwendung benutzt 90% des freien Speichers.\nDein Programm wird beendet, damit der Stapel nicht \u00fcberl\u00e4uft.\nSehe bitte nach, dass Dein Programm keine Endlosschleife enth\u00e4lt, ansonsten weise XLogo mehr Speicherplatz zu(im Men\u00fc bei Optionen). +dernier = Letzter +direction=Richtung +division_par_zero = Man darf nicht durch Null teilen! +dossier_parent=Eltern-Ordner +draw_grid=Hintergrund-Gitter +echantillon = Beispiel +echantillon_texte = Dies ist eine Vorschau +editeur=Editor +editor.redo=Wiederherstellen +editor.undo=R\u00fcckg\u00e4ngig +effacer_editeur= L\u00f6sche den Bildschirm beim Verlassen des Editors +element_dans_liste= Elemente in der Liste [ +enlever=Entferne +enregistreimage=Speichere Bild unter... +enregistrer_espace = Arbeitsfl\u00e4che leeren? +entre_zero_un = muss zwischen 0 und 1 sein. +epaisseur_crayon = Maximale Stiftdicke +erreur_compteur=Du darfst whzahl nicht aus einer Wiederhole Schleife benutzen. +erreur_crochet=Fehler: ] erwartet +erreur_editeur=Ich kann die Prozeduren nicht speichern.\nBitte sehe nach, ob F\u00fcr ...immer ein Ende hat und\nkontrolliere, ob alle Variablen :a :b usw. richtig angelegt sind. +erreur_fixestyle=Setzestil akzeptiert nur folgende Werte: Kein, Fett, Unterstrichen, Kursiv, Hochgestellt oder Tiefgestellt. +erreur_format_image=Kann nur *.png und *.jpg Bilder benutzen. +erreur_memoire = XLogo hat nicht genug Speicher um dieses Bild erstellen zu k\u00f6nnen.\n Gebe unter Optionen einen gr\u00f6\u00dferen Wert f\u00fcr den Speicher ein. +erreur_nom_nombre_procedure=Prozedurnamen d\u00fcrfen nicht nur aus Zahlen bestehen ! +erreur_nom_nombre_variable = Variablennamen d\u00fcrfen nicht nur aus Zahlen bestehen ! +erreur_pas_repertoire = ist kein g\u00fcltiger Ordner ! +erreur_repetepour = muss drei oder vier Parameter enthalten. [Variable Anfang Ende Z\u00e4hler] +erreur_retourne=Du darfst nicht R\u00fcckgabe benutzen au\u00dferhalb einer Prozedur ! +erreur_sortie1=Igel verl\u00e4\u00dft den Zeichenbereich. +erreur_sortie2=Du kannst noch so viele Schritte gehen: +erreur_stop=Du darfst Stoppe nicht am Ende einer Schleife oder Prozedur benutzen ! +erreur_tcp=Problem in der Netzwerk Kommunikation +erreur_variable = ist keine g\u00fcltige Variable ! +erreur=FEHLER +error_bad_values=akzeptiert nur die Werte +error.3d.3vertex=Ein Vieleck muss haben +error.3d.emptypolygon=Eine Vieleckfl\u00e4che +error.ioecriture=Input-Output Fehler: Entschuldigung, ich kann nicht speichern... +error.iolecture=Kann diese Datei nicht lesen. +error.ne_peut_etre= kann ich hier nicht finden. +error.novalue=hat keinen Wert. +error.primitive2D=ist nur verf\u00fcgbar in 2D +error.primitive3D=ist nur verf\u00fcgbar in 3D +error.procedure.must.be=muss eine Prozedur sein +error.whattodo=Ich weiss nicht, was ich machen soll mit +error.word=muss ein Wort sein. +existe_deja= gibt es schon. +faux="falsch +ferme_editeur=Schlie\u00dfe das Editor-Fenster. +fichier_du_type = Dateiformat +fichiers = Datei(en) +fichiers_logo=Logo Dateien +fichiers_rtf=RTF-Dateien +file_100K=Zum Verhindern von Speicher\u00fcberlauf kann Dateigr\u00f6\u00dfe nur kleiner 100 KB sein. +fin_flux = Es gibt keine zu lesenden Zeichen in diesem Fluss n\u00b0 +fin=Ende +find_replace=Ersetze/Suche +find=Suche +flux_ecriture = Ich kann in diesem Fluss nicht schreiben. +flux_existant=ist ein Fluss, der schon offen ist. Du musst ihn erst schlie\u00dfen, bevor Du diesen Namen benutzen kannst. +flux_lecture = Ich kann in diesem Fluss nicht lesen. +flux_non_disponible=Kein Fluss hat diesen Namen +forme_crayon = Form des Stiftes +forward=Vor +gui_exists=Die folgende graphische Komponente gibt es schon: +haut = Sehr gut +hollandais = Niederl\u00e4ndisch +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=Bild-Dateien +images=Bilder +imprimer_editeur=Drucke den Text. +interrompre_execution=Stoppe die laufende Aufgabe +je_ne_sais_pas=Ich weiss nicht, wie ich +line=Zeile +lire_editeur=Speichere und schlie\u00dfe den Editor +liste_vide = Die Liste ist leer. +mainCommand=Hauptkommando +memoire=Zugewiesener Speicher f\u00fcr XLogo (MB): +menu.edition.copy=Kopiere Strg-C +menu.edition.cut=Ausschneide Strg-X +menu.edition.paste=Einf\u00fcge Strg-V +menu.edition.selectall=Markiere alles +menu.edition=Bearbeiten +menu.file.captureimage.clipboard=Kopiere in die Zwischenablage +menu.file.captureimage.print=Drucke Bild +menu.file.captureimage=Bild +menu.file.open=\u00d6ffne +menu.file.quit=Beende +menu.file.save=Speichere +menu.file.saveas=Speichere unter ... +menu.file.textzone = Textbereich +menu.file.textzone.rtf=Speichere im RTF Format +menu.file=Datei +menu.help.about=\u00fcber... +menu.help.licence= Lizenz +menu.help.online=Online-Handbuch +menu.help.translatedlicence=\u00dcbersetzte Lizenz +menu.help.translatexlogo=\u00dcbersetze XLogo +menu.help=Hilfe +menu.tools.eraser=L\u00f6sche Prozeduren +menu.tools.pencolor=W\u00e4hle Stiftfarbe +menu.tools.preferences=Einstellungen +menu.tools.screencolor=W\u00e4hle Hintergrundfarbe +menu.tools.startup=Definiere Startdatei +menu.tools.translate=\u00dcbersetze den Quelltext... +menu.tools=Hilfsmittel +message_a_propos1=XLogo Version: +message_a_propos2=Website: +message_a_propos3=Du kannst mir schreiben: +messages=Meldungen +mot_vide=Das Wort mu\u00df mindestens ein Zeichen enthalten. +n_aime_pas = mag nicht [ +nb_tortues=Anzahl Igel +ne_renvoie_pas=gibt nichts aus nach +no_gui=Die folgende graphische Komponente gibt es nicht: +no_host=Kommunikationsprobleme mit der Netzwerkadresse: +nom_du_fichier=Dateiname: +nombre_unicode = muss zwischen 0 und 65535 sein. +normal = Normal +note.do = do +note.fa = fa +note.la = la +note.mi=mich +note.re = re +note.si = si +note.sol = sol +nouveau = Neu +nouveau_dossier=Erstelle einen neuen Ordner +ouvrir_editeur=\u00d6ffne den Editor +parcourir=Durchsuche... +parenthese_fermante= ) konnte hier nicht eingef\u00fcgt werden. +parenthese_ouvrante=Ich warte auf (. +parenthese_vide=Da steht nichts zwischen ( und ) ! +pas_argument=ist kein g\u00fcltiges Argument. +pas_assez_de=Nicht genug Eingaben zu +pas_entier=ist keine ganze Zahl ! +pas_liste = ist keine Liste. +pas_nombre = ist keine Zahl ! +pas_predicat= muss wahr oder falsch sein. +pas=Abstand +pb_port=Kann den Port nicht erreichen +pencolor=Standard-Schriftfarbe +pour=lerne +pref.cancel=Abbreche +pref.font= Schriftart +pref.general.arabic=Arabisch +pref.general.aspect=Erscheinungsbild +pref.general.asturian=Asturisch +pref.general.catalan=Katalanisch +pref.general.english=Englisch +pref.general.esperanto = Esperanto +pref.general.fast=Schnell +pref.general.french=Franz\u00f6sisch +pref.general.galician=Galizisch +pref.general.german=Deutsch +pref.general.greek=Griechisch +pref.general.hungarian=Ungarisch +pref.general.italian=Italienisch +pref.general.lang=Sprache +pref.general.metal=Metall +pref.general.motif=Motif +pref.general.portuguese= Portugiesisch +pref.general.slow=Langsam +pref.general.spanish=Spanisch +pref.general.speed=Geschwindigkeit des Igel +pref.general.windows=Nativ +pref.general=Allgemein +pref.highlight.comment= Kommentare +pref.highlight.enabled=Aktiviere Farbhervorhebung +pref.highlight.example=# Dies ist ein Kommentar\n wiederhole 4[vorw�rts 100 rechts 90]\n +pref.highlight.init= Standardwerte +pref.highlight.operand= Variablen, Worte, Zahlen +pref.highlight.other=Andere... +pref.highlight.parenthesis= Klammern, eckige Klammern +pref.highlight.primitive= Befehle +pref.highlight=Farbhervorhebung +pref.ok = OK +pref.options.eraseVariables=L\u00f6sche Variablen beim Schlie\u00dfen des Editor +pref.options.tcp=TCP Portnummer: +pref.options=Optionen +pref.sound.instruments= verf\u00fcgbare Instrumente +pref.sound.problem=Ich kann die MIDI Schnittstelle nicht finden ! +pref.sound= Sound +pref.turtles=W\u00e4hle den Igel +primitives=Befehle +probleme_sequence=Ich verstehe Deine musikalische Sequenz nicht. Bitte kontrolliere sie ! +procedure_demarrage=Kommando, das beim Start ausgef\u00fchrt wird: +procedure_list=Prozeduren-Liste +procedure_vide=Prozedurennamen d\u00fcrfen nicht leer sein ! +qualite_dessin = Qualit\u00e4t der Zeichnung: +quit_editeur=Schlie\u00dfe den Editor ohne zu speichern +quitter? = M\u00f6chtest Du das Programm beenden? +rechercher_dans=Sehe in: +relancer=Danach beende und starte XLogo, damit die \u00c4nderung wirksam wird. +repertoire_accueil= Heimordner +repertoires = Ordner +replace=Ersetze +replaceall=Ersetze alles +replacewith=Ersetze mit +restaurer=resette +rgb = RGB +rond= rund +rouge = Rot +screencolor=Standard Hintergrundfarbe +seule_tortue_dispo=Du kannst den aktiven Igel nicht l\u00f6schen ! +stop_chat=<<<<< Ende des Chats >>>>> +stop=Stop +string_not_found=Zeichenkette nicht gefunden. +style.bold= Fett +style.exposant = Hochgestellt +style.italic= Kursiv +style.none= Kein +style.strike= Durchgestrichen +style.subscript= Tiefgestellt +style.underline= Unterstrichen +taille_dessin=Bildschirmgr\u00f6\u00dfe zum Zeichnen +title_axis=Hintergrund-Achse +titredialogue2=Speichere gerade das Bild... +too_much_arguments=Zu viele Argumente in +tortue_inaccessible=Ich kann keinen Igel mit dieser Nummer erzeugen ! +traduire_de=\u00dcbersetze von: +traduire=\u00dcbersetze! +translatecomplete=Komplettiere eine \u00dcbersetzung +translateconsult=Konsultiere verhandene \u00dcbersetzungen +translatecreate=Schaffe eine neue \u00dcbersetzung +translatemessage=Wenn alle Felder vollst\u00e4ndig sind f\u00fcr +translatemodify=Modifiziere eine \u00dcbersetzung +translatewant=Du willst: +un_caractere = darf nur ein Zeichen enthalten. +uniform_color=Gleiche Farbe: +variable_vide = Variablennamen d\u00fcrfen nicht leer sein. +vers=Nach: +vert = Gr\u00fcn +vrai="wahr +xgrid=X-Gitter: +y_a_pas = Es gibt kein +ygrid=Y-Gitter: +ws.settings.require_password=Sch�tze diese Einstellungen mit einem Passwort +ws.settings.password=Passwort +ws.settings.retype.password=Wiederhole das Passwort +ws.settings.save.password=Passwort speichern +ws.settings.workspace=Arbeitsplatz: +ws.settings.location=Ort: +ws.settings.language=Sprache: +ws.settings.backups=Anzahl Backups: +ws.settings.user=Benutzer: +ws.settings.add=Hinzuf�gen +ws.settings.remove=Entfernen +ws.settings.import=Importieren +ws.settings.enable.user.account.creation=Erlaube Benutzern Kontos hinzuzuf�gen? +ws.settings.save.and.close=Spechern und Schliessen +ws.settings.title=XLogo4Schools - Arbeitsplatzeinstellungen +ws.settings.global=Global +ws.settings.global.settings=Globale Einstellungen +ws.settings.workspace=Arbeitsplatz +ws.settings.global.settings=Arbeitsplatzeinstellungen +ws.settings.cannot.store.pw=Konnte das Passwort nicht speichern: +ws.settings.pw.must.be.equal=Die Passw�rter m�ssen gleich sein +ws.settings.virtual.ws.not.stored=Ein virtueller Arbeitsplatz wird nicht auf dem Dateisystem gespeichert +ws.settings.could.not.enter.wp=Konnte den Arbeitsplatz nicht betreten: +ws.settings.create.new.wp=Erstelle einen neuen Arbeitsplatz +ws.settings.wp.name.non.empty=Der Name darf nicht leer sein +ws.settings.wp.exists.already=Dieser Arbeitsplatz existiert bereits +ws.settings.could.not.create.directory=Der Ordner konnte nicht erstellt werden. +ws.settings.need.dir.not.file=Es muss ein Ordner angegeben werden, keine Datei. +ws.settings.could.not.create.ws=Der Arbeitsplatz konnte nicht auf dem Dateisystem erstellt werden. +ws.settings.want.delete.dir.1=M�chten Sie den Ordner ' +ws.settings.want.delete.dir.2=' und seine Inhalte f�r vom Dateisystem l�schen? +ws.settings.could.not.enter.virtual.ws=Der virtuelle Arbeitsplatz konnte nicht betreten werden +ws.settings.delete.from.fs=Vom Dateisystem l�schen? +ws.settings.not.legal.ws.dir= ist kein Arbeitsplatzverzeichnis. +ws.settings.enter.user.name=Benutzernamen eingeben +ws.settings.create.new.user=Neuen Benutzer erstellen +ws.settings.user.exists.already=Dieser Benutzer existiert bereits im Arbeitsplatz +ws.settings.remove.user=Den Benutzer vom Dateisystem l�schen? +ws.settings.not.legal.user.dir= ist kein korrektes Benutzerverzeichnis. +ws.settings.choose.other.name= exisitiert bereits im Arbeitsplatz. W�hle einen neuen Namen. +ws.settings.name.conflict=Namenskonflikt +ws.settings.could.not.import.user=Der Benutzer konnte nicht importiert werden: +ws.creation.panel.name=Arbeitsplatzname +ws.creation.panel.location=Ort +ws.creation.panel.browse=Durchsuchen +welcome.workspace=Arbeitsplatz +welcome.username=Benutzer +welcome.settings=Einstellungen +welcome.enter=Eintreten +welcome.title=XLogo4Schools +welcome.wrong.pw=Falsches Passwort. +welcome.enter.pw=Passwort eingeben. +welcome.could.not.enter.user=Der Benutzer konnte nicht angemeldet werden: +storage.could.not.store.gc=Die globalen Einstellungen konnten nicht gespeichert werden. +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=Das Programm wurde nicht richtig erzeugt +procedure.executable=Das Programm ist ausf�hrbar +procedure.not.executable=Das Programm ist nicht ausf�hrbar +procedure.error=Das Programm enth�lt fehler. +error.proc.does.not.exist=Das Programm existiert nicht. +ws.generated.procedure=generierte_prozeduren +ws.redefine.ambiguous.procedure= ist mehrmals definiert. Ich weiss nicht welches Programm ich �berschreiben soll. +error.call.ambiguous.procedure.name=ist mehrmals definiert. Ich weiss nicht welches Programm ich ausf�hren soll. +ws.could.not.create.file=Ich konnte folgendes Dokument nicht erstellen: + +ws.error.title=Fehler im Arbeitsplatz +ws.error.could.not.load.logo.files=Ich konnte einige Dateien nicht laden: +i.am.sorry=Es tut mir leid, aber... +ws.error.userdir.not.dir=Der ausgew�hlte Ordner ist kein Quellordner und er konnte auch nicht eingerichtet werden. +ws.error.could.not.store.configs=Ich konnte die Konfigurationsdateien nicht speichern. +ws.error.could.not.create.logo.file=Leider konnte ich aus folgendem Grund keine neue Datei erzeugen: +new.file=Neues Dokument + +contest.error.could.not.record.file=Ich konnte die j�ngsten �nderungen nicht protokollieren. Bitte zeige diese Meldung den Organisatoren. +contest.mode.start=Aufzeichnungsmodus starten +contest.mode.stop=Aufzeichnungsmodus beenden +contest.mode.filename=Aufgabe +contest.mode.bonus.filename=Bonusaufgabe +contest.error.title=Danke, du has einen hinterh�ltigen Fehler entdeckt! +contest.could.not.create=Leider konnte ich die Dateien f�r den Aufzeichnungsmodus nicht anlegen. Bitte zeige diese Meldung den Organisatoren. +contest.could.not.store=Leider konnte ich deine Eingabe nicht protokollieren. Bitte zeige diese Meldung den Organisatoren. + +ws.filename.exists.already=Dieser Name existiert bereits. Bitte w�hle einen anderen. +ws.attempt.open.inexistent.file=Ich habe versucht ein Dokument zu �ffnen, welches nicht im Arbeitsplatz ist: +ws.attempt.close.not.open.file=Komisch... Ich habe gerade versuch eine Datei zu schliessen, die nie offen war. +ws.automatic.save.failed=Leider konnte ich deine �nderungen aus folgendem Grund nicht speichern: +general.error.title=Uuups +editor.display.procedure.not.found= ist nicht definiert. + +name.error.dialog.title=Uuuups +name.error.rename.inexistent.file=Leider kann ich dieses Dokument nicht umbenennen, weil ich denke, dass dieses gar nicht existiert. +name.error.empty.name=Ich kann einem Dokument nicht einen leeren Namen geben. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Violet +color.red=Rot +color.yellow=Gelb +logo.file.has.error=Dieses Dokument enth�lt Fehler und dessen Programme k�nnen nicht ausgef�hrt werden. + +error.while.creating.editor=Leider konnte ich aus folgendem Grund den Editor nicht �ffnen: + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=Ein Logo-Dokument muss immer mit "lerne" beginnen +error.missing.name=Ich habe einen Programmnamen erwartet, aber keinen gefunden. +error.name.is.number=Ein Name eines Programms darf keine Zahl sein. +error.name.special=Ein Name eines Programms darf keine Sonderzeichen enthalten. +error.var.white.after.colon=Ich habe einen Abstand zwischen dem Doppelpunkt und dem Namen einer Variable entdeckt. +error.var.special=Variablennamen d�rfen keine Sonderzeichen enthalten. +error.var.is.number=Variablennamen d�rfen keine Zahlen sein. +error.var.missing.colon=Ich kann keinen Doppelpunkt finden. +error.opt.var.bracket=Da ist etwas mit der Klammerung bei den optionalen Parametern schief gelaufen. +error.var.extra.chars=Ich verstehe nicht, was am Ende der Variablendeklaration steht. +error.missing.expr=Ich vermisse einen Standardwert f�r einen optionalen Parameter. +error.more.chars.after.end="Ende" sollte alleine auf einer Zeile stehen. +error.missing.end=Deins letztes Programm besitzt kein "Ende". +error.to.before.end= hat kein end. +error.name.is.key.word=Einer der von dir gew�hlten Namen ist ein reserviertes Schl�sselwort, das ich nicht �berschreiben kann. +error.procedure.ambiguous=Es gibt ein anderes Programm mit demselben Namen. + +hist.msg.procedures.undefined= Ich habe vergessen : + +error.network.context=Ich verstehe die Daten nicht, welche ich aus dem Netzwerk erhalten habe. + +dialog.yes=Ja +dialog.no=Nein +us.could.not.store.recent.data=Ich konnte die j�ngsten �nderungen nicht speichern: +illegal.name.msg=Der gew�hlte Name enth�lt ung�ltige Zeichen +ws.does.not.exist=Der angegebenee Arbeitsplatz existiert nicht +ws.not.a.workspace.dir=ist kein g�ltiger Arbeitsplatz zum Importieren +app.hello= Hallo + +file.contains.errors=enth�lt Fehler. + +us.import=Datei importieren +us.export=Datei exportieren +us.save.image=Bild speichern + +us.export.msg=Choose a file to export: + +contest.number.of.files=Anzahl Aufgaben: +contest.number.of.bonus.files =Anzahl Bonusaufgaben: +ws.settings.syntax=Syntaxhervorhebung +ws.settings.contest=Wettbewerb- / Aufzeichnungsmodus
\ No newline at end of file diff --git a/logo/src/langage_el_GR.properties b/logo/src/langage_el_GR.properties new file mode 100644 index 0000000..3ea4423 --- /dev/null +++ b/logo/src/langage_el_GR.properties @@ -0,0 +1,437 @@ +3d.fog.backdistance=\u03a0\u03af\u03c3\u03c9 \u03b1\u03c0\u03cc\u03c3\u03c4\u03b1\u03c3\u03b7 +3d.fog.density=\u03a0\u03c5\u03ba\u03bd\u03cc\u03c4\u03b7\u03c4\u03b1: +3d.fog.exponential=\u0395\u03ba\u03b8\u03b5\u03c4\u03b9\u03ba\u03ae \u039f\u03bc\u03af\u03c7\u03bb\u03b7 +3d.fog.frontdistance=\u039c\u03c0\u03c1\u03bf\u03c3\u03c4\u03ac \u03b1\u03c0\u03cc\u03c3\u03c4\u03b1\u03c3\u03b7 +3d.fog.linear=\u0393\u03c1\u03b1\u03bc\u03bc\u03b9\u03ba\u03ae \u039f\u03bc\u03af\u03c7\u03bb\u03b7 +3d.fog.none=\u039a\u03b1\u03bd\u03b5\u03af\u03c2 +3d.fog.type=\u03a4\u03cd\u03c0\u03bf\u03c2 \u03bf\u03bc\u03af\u03c7\u03bb\u03b7\u03c2: +3d.light=\u03a6\u03ce\u03c4\u03b1 +3d.fog=\u039f\u03bc\u03af\u03c7\u03bb\u03b7 +3d.light.ambient=\u03a0\u03b5\u03c1\u03b9\u03b2\u03ac\u03bb\u03bb\u03bf\u03bd \u03a6\u03ce\u03c2 +3d.light.angle=\u0393\u03c9\u03bd\u03af\u03b1: +3d.light.apply=\u0395\u03c6\u03ac\u03c1\u03bc\u03bf\u03c3\u03b5 +3d.light.direction=\u039a\u03b1\u03c4\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 +3d.light.directional=\u039a\u03b1\u03c4\u03b5\u03c5\u03b8\u03c5\u03bd\u03c4\u03b9\u03ba\u03cc \u03a6\u03ce\u03c2 +3d.light.none=\u03a3\u03b2\u03b7\u03c3\u03c4\u03cc +3d.light.point=\u03a3\u03b7\u03bc\u03b5\u03b9\u03b1\u03ba\u03bf \u03a6\u03ce\u03c2 +3d.light.position=\u0398\u03ad\u03c3\u03b7 +3d.light.spot=\u03a3\u03c0\u03cc\u03c4 \u03a6\u03ce\u03c2 +3d.light.type=\u03a4\u03cd\u03c0\u03bf\u03c2 \u03a6\u03c9\u03c4\u03cc\u03c2 : +3d.viewer=3\u0394 \u03b8\u03b5\u03b1\u03c4\u03ae\u03c2 +active_grid=\u0394\u03c1\u03b1\u03c3\u03c4\u03ae\u03c1\u03b9\u03bf\u03c2 +active_xaxis=X \u0386\u03be\u03bf\u03bd\u03b1\u03c2 +active_yaxis=\u03a8 \u0386\u03be\u03bf\u03bd\u03b1\u03c2 +ajouter=\u03a0\u03c1\u03cc\u03c3\u03b8\u03b5\u03c3\u03b5 +animation_active=\u0397 \u03c4\u03c1\u03ad\u03c7\u03bf\u03c5\u03c3\u03b1 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03ba\u03af\u03bd\u03b7\u03c3\u03b7\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03bb\u03b7\u03b8\u03ae\u03c2. +apercu=\u03a0\u03c1\u03bf\u03b5\u03c0\u03b9\u03c3\u03ba\u03cc\u03c0\u03b7\u03c3\u03b7 +attend_positif=\u03c0\u03b5\u03c1\u03b9\u03bc\u03ad\u03bd\u03b5\u03b9 \u03b5\u03bd\u03b1 \u03b8\u03b5\u03c4\u03b9\u03ba\u03cc \u03cc\u03c1\u03b9\u03c3\u03bc\u03b1. +backward=\u03a0\u03af\u03c3\u03c9 +bas=\u03a7\u03b1\u03bc\u03b7\u03bb\u03ac +bleu=\u039c\u03c0\u03bb\u03ad +bordermotif=\u039c\u03bf\u03c4\u03af\u03b2\u03bf \u03a0\u03b5\u03c1\u03b9\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2 +caractere_special1=\u03a4\u03b1 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03b9\u03ce\u03bd \u03b4\u03b5\u03bd \u03c5\u03c0\u03bf\u03c3\u03c4\u03b7\u03c1\u03af\u03b6\u03bf\u03c5\u03bd +caractere_special2=\u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b5\u03c2 \u03cc\u03c0\u03c9\u03c2 + - * / ( ) [ ] = < > & | : +caractere_special3=\u039c\u03b5\u03c4\u03bf\u03bd\u03bf\u03bc\u03b1\u03c3\u03af\u03b1 +caractere_special_variable=\u03a4\u03b1 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03b1 \u03c4\u03ce\u03bd \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ce\u03bd \u03b4\u03b5\u03bd \u03c5\u03c0\u03bf\u03c3\u03c4\u03b7\u03c1\u03af\u03b6\u03bf\u03c5\u03bd +carre=\u03a4\u03b5\u03c4\u03c1\u03ac\u03b3\u03c9\u03bd\u03bf +chaine_trop_longue=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03c4\u03c5\u03c0\u03ce\u03c3\u03c9 \u03bc\u03b9\u03b1 \u03bb\u03ad\u03be\u03b7 \u03ae \u03bc\u03b9\u03b1 \u03bb\u03af\u03c3\u03c4\u03b1 \u03bc\u03b5 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03bf\u03c5\u03c2 \u03b1\u03c0\u03bf 32000 \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b5\u03c2. +chat=\u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1 +chemin=\u039c\u03bf\u03bd\u03bf\u03c0\u03ac\u03c4\u03b9 +color_3_arguments=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03bc\u03b9\u03b1 \u03bb\u03af\u03c3\u03c4\u03b1 \u03c4\u03c1\u03b9\u03ce\u03bd \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03b9\u03c9\u03bd, [\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf \u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf \u03bc\u03c0\u03bb\u03ad] +commande=\u0395\u03bd\u03c4\u03bf\u03bb\u03ae: +comme_parametre=] \u03c3\u03b1\u03bd \u03bf\u03c1\u03af\u03c3\u03bc\u03b1\u03c4\u03b1. +couleur_du_crayon=\u03a7\u03c1\u03ce\u03bc\u03b1 \u03a3\u03c4\u03c5\u03bb\u03cc +couleur_du_fond=\u03a7\u03c1\u03ce\u03bc\u03b1 \u039f\u03b8\u03cc\u03bd\u03b7\u03c2 +dans=\u039c\u03ad\u03c3\u03b1 +definir=\u0395\u03c3\u03b5\u03af\u03c2 \u03bf\u03c1\u03af\u03c3\u03b1\u03c4\u03b5 +depassement_memoire=XLogo \u03ad\u03c7\u03b5\u03b9 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03b9 \u03c4\u03bf 90% \u03c4\u03ae\u03c2 \u03b4\u03b9\u03b1\u03b8\u03ad\u03c3\u03b9\u03bc\u03b7\u03c2 \u03bc\u03bd\u03ae\u03bc\u03b7\u03c2. \u0397 \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae \u03c3\u03b1\u03c2 \u03b8\u03b1 \u03c3\u03c4\u03b1\u03bc\u03b1\u03c4\u03ae\u03c3\u03b5\u03b9 \u03c0\u03c1\u03bf\u03b5\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03c6\u03b5\u03c5\u03c7\u03b8\u03b5\u03af \u03bc\u03b9\u03b1 \u03c5\u03c0\u03b5\u03c1\u03c7\u03b5\u03af\u03bb\u03b9\u03c3\u03b7 \u03c3\u03c4\u03bf\u03af\u03b2\u03b1\u03c2. \u0395\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03c4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03c3\u03b1\u03c2 \u03b1\u03bd \u03c0\u03b5\u03c1\u03b9\u03ad\u03c7\u03b5\u03b9 \u03b1\u03c4\u03ad\u03c1\u03bc\u03bf\u03bd \u03b2\u03c1\u03cc\u03c7\u03bf. \u0394\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03ac \u03b1\u03c5\u03be\u03ae\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03bc\u03bd\u03ae\u03bc\u03b7 \u03c0\u03bf\u03c5 \u03b1\u03c0\u03bf\u03b4\u03af\u03b4\u03b5\u03c4\u03b1\u03b9 \u03c3\u03c4\u03b7\u03bd XLogo. +dernier=\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03bf +direction=\u039a\u03b1\u03c4\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 +division_par_zero=\u0394\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b9\u03c1\u03ad\u03c3\u03b5\u03c4\u03b5 \u03bc\u03b5 \u03c4\u03bf \u03bc\u03b7\u03b4\u03ad\u03bd! +dossier_parent=\u0393\u03bf\u03bd\u03b9\u03ba\u03cc\u03c2 \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 +draw_grid=\u03a0\u03bb\u03ad\u03b3\u03bc\u03b1 \u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b7\u03bd\u03af\u03bf\u03c5 +echantillon=\u0394\u03b5\u03af\u03b3\u03bc\u03b1 +echantillon_texte=\u0391\u03c5\u03c4\u03ae \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03b9\u03b1 \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03c3\u03ba\u03cc\u03c0\u03b7\u03c3\u03b7 +editeur=\u039a\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf\u03c2 +editor.redo=\u0395\u03c0\u03b1\u03bd\u03ac\u03bb\u03b1\u03b2\u03b5 \u03c4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b1 \u03c0\u03c1\u03ac\u03be\u03b7 +editor.undo=\u0391\u03bd\u03b5\u03c1\u03b1\u03b9\u03c3\u03b5 \u03c4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b1 \u03c0\u03c1\u03ac\u03be\u03b7 +effacer_editeur=\u039a\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b5 \u03c4\u03b7\u03bd \u03bf\u03b8\u03cc\u03bd\u03b7 \u03cc\u03c4\u03b1\u03bd \u03ba\u03bb\u03b5\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03bd \u03ba\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf +element_dans_liste=\u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c3\u03c4\u03b7\u03bd \u03bb\u03af\u03c3\u03c4\u03b1 [ +enlever=\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b5 +enregistreimage=\u0395\u03b9\u03ba\u03cc\u03bd\u03b1 \u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03b5\u03c4\u03b1\u03b9 \u03c3\u03b1\u03bd... +enregistrer_espace=\u0394\u03b9\u03ad\u03b3\u03c1\u03b1\u03c8\u03b5 \u03c4\u03bf\u03bd \u03c7\u03ce\u03c1\u03bf \u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2? +entre_zero_un=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03b5\u03c4\u03b1\u03be\u03cd 0 \u03ba\u03b1\u03b9 1. +epaisseur_crayon=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf \u03c0\u03bb\u03ac\u03c4\u03bf\u03c2 \u03c3\u03c4\u03c5\u03bb\u03cc +erreur=\u03a3\u03a6\u0391\u039b\u039c\u0391 +erreur_compteur=You can't use repcount outside a repeat loop. +erreur_crochet=\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1: ] \u03b1\u03bd\u03b1\u03bc\u03b5\u03bd\u03cc\u03c4\u03b1\u03bd. +erreur_editeur=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c3\u03c9 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b5\u03c2. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03c9 \u03bd\u03b1 \u03b5\u03af\u03c3\u03c4\u03b5 \u03c0\u03c1\u03bf\u03c3\u03b5\u03ba\u03c4\u03b9\u03ba\u03bf\u03af \u03bc\u03b5 \u03c4\u03b1 \u03c4\u03bc\u03ae\u03bc\u03b1\u03c4\u03b1 To .... End. \u0395\u03c0\u03af\u03c3\u03b7\u03c2 \u03b5\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03b3\u03b9\u03b1 \u03ba\u03b1\u03ba\u03cc \u03bf\u03c1\u03b9\u03c3\u03bc\u03cc \u03c4\u03ce\u03bd \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ce\u03bd. +erreur_fixestyle=setstyle \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b4\u03b5\u03c7\u03c4\u03b5\u03af \u03bc\u03bf\u03bd\u03bf\u03bd \u03b1\u03c5\u03c4\u03ad\u03c2 \u03c4\u03b9\u03c2 \u03c4\u03b9\u03bc\u03ad\u03c2: none, bold, underline, italic, superscript or subscript. +erreur_format_image=\u03a4\u03b1 \u03b1\u03c0\u03bf\u03b4\u03b5\u03ba\u03c4\u03ac \u03b1\u03c1\u03c7\u03b5\u03af\u03b1 \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1\u03c2 \u03ad\u03c7\u03bf\u03c5\u03bd \u03ba\u03b1\u03c4\u03ac\u03bb\u03b7\u03be\u03b7 *.png \u03ba\u03b1\u03b9 *.jpg +erreur_memoire=XLogo \u03b4\u03b5\u03bd \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c1\u03ba\u03b5\u03c4\u03ae \u03bc\u03bd\u03ae\u03bc\u03b7 \u03c0\u03c1\u03bf\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03b9 \u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03b8\u03c5\u03bc\u03b7\u03c4\u03ae \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1.\n\u03a3\u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae "Options" tab, \u03b1\u03c5\u03be\u03ae\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03bc\u03bd\u03ae\u03bc\u03b7 \u03c0\u03bf\u03c5 \u03b1\u03c0\u03bf\u03b4\u03af\u03b4\u03b5\u03c4\u03b1\u03b9 \u03c3\u03c4\u03b7\u03bd XLogo. +erreur_nom_nombre_procedure=\u03a4\u03b1 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03b9\u03ce\u03bd \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c1\u03b9\u03b8\u03bc\u03bf\u03af ! +erreur_nom_nombre_variable=\u03a4\u03b1 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03b1 \u03c4\u03ce\u03bd \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ce\u03bd \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c1\u03b9\u03b8\u03bc\u03bf\u03af ! +erreur_pas_repertoire=\u03b1\u03c5\u03c4\u03cc \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03bd\u03b1\u03c2 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf\u03c2 \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 ! +erreur_repetepour=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03b5\u03c1\u03b9\u03ad\u03c7\u03b5\u03b9 \u03c4\u03c1\u03af\u03b1 \u03ae \u03c4\u03ad\u03c3\u03c3\u03b5\u03c1\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 , [variable start end increment] +erreur_retourne=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 return \u03ad\u03be\u03c9 \u03b1\u03c0\u03bf \u03bc\u03b9\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1 ! +erreur_sortie1=\u0397 \u03c7\u03b5\u03bb\u03ce\u03bd\u03b1 \u03b1\u03c6\u03ae\u03bd\u03b5\u03b9 \u03c4\u03b7\u03bd \u03c3\u03c7\u03b5\u03b4\u03b9\u03b1\u03c3\u03c4\u03ba\u03ae \u03b6\u03ce\u03bd\u03b7. +erreur_sortie2=\u039f \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03c4\u03ce\u03bd \u03b2\u03b7\u03bc\u03ac\u03c4\u03c9\u03bd \u03c0\u03b1\u03c1\u03ad\u03c7\u03b5\u03c4\u03b1\u03b9 \u03c0\u03c1\u03af\u03bd \u03b1\u03c6\u03ae\u03c3\u03b5\u03c4\u03b5: +erreur_stop=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 stop \u03ad\u03be\u03c9 \u03b1\u03c0\u03bf \u03bc\u03b9\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1 \u03ae \u03ad\u03bd\u03b1\u03bd \u03b2\u03c1\u03cc\u03c7\u03bf ! +erreur_tcp=\u03a0\u03c1\u03cc\u03b2\u03bb\u03b7\u03bc\u03b1 \u03c3\u03c4\u03b7\u03bd \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03c4\u03c5\u03b1\u03ba\u03ae \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1. +erreur_variable=\u03b1\u03c5\u03c4\u03ae \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03b9\u03b1 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ae ! +error.3d.3vertex=\u0388\u03bd\u03b1 \u03c0\u03bf\u03bb\u03cd\u03b3\u03c9\u03bd\u03bf \u03b8\u03b1 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03c4\u03c1\u03b5\u03af\u03c2 vertices! +error.3d.emptypolygon=\u039c\u03b9\u03b1 \u03b5\u03c0\u03b9\u03c6\u03ac\u03bd\u03b5\u03b9\u03b1 \u03c0\u03bf\u03bb\u03c5\u03b3\u03ce\u03bd\u03bf\u03c5 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03af\u03c3\u03b7 \u03bc\u03b5 \u03c4\u03bf \u03bc\u03b7\u03b4\u03ad\u03bd! +error.ioecriture=\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03b5\u03b9\u03c3\u03cc\u03b4\u03bf\u03c5/\u03b5\u03be\u03cc\u03b4\u03bf\u03c5: \u039b\u03c5\u03c0\u03ac\u03bc\u03b1\u03b9 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03bc\u03c0\u03bf\u03c1\u03ce Sorry, I can't save... +error.iolecture=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03c9 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b2\u03ac\u03c3\u03c9 \u03c4\u03bf \u03c3\u03c5\u03b3\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf! +error.ne_peut_etre=\u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03bf\u03cd\u03c3\u03b5 \u03bd\u03b1 \u03b2\u03c1\u03b5\u03b8\u03b5\u03af \u03b5\u03b4\u03ce. +error.novalue=\u03b4\u03b5\u03bd \u03ad\u03c7\u03b5\u03b9 \u03c4\u03b9\u03bc\u03ae. +error.primitive2D=\u03c0\u03b1\u03c1\u03ad\u03c7\u03b5\u03c4\u03b1\u03b9 \u03bc\u03cc\u03bd\u03bf\u03bd \u03b4\u03b5 2\u0394 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7. +error.primitive3D=\u03c0\u03b1\u03c1\u03ad\u03c7\u03b5\u03c4\u03b1\u03b9 \u03bc\u03cc\u03bd\u03bf\u03bd \u03c3\u03b5 3\u0394 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03c3\u03c3\u03b7. +error.procedure.must.be=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03bd\u03b1 \u03cc\u03bd\u03bf\u03bc\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1\u03c2 +error.whattodo=\u0394\u03b5\u03bd \u03be\u03ad\u03c1\u03c9 \u03c4\u03b9 \u03bd\u03b1 \u03ba\u03b1\u03bd\u03c9 \u03bc\u03ad +error.word=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03b9\u03b1 \u03bb\u03ad\u03be\u03b7. +error_bad_values=\u03bc\u03cc\u03bd\u03bf\u03bd \u03b4\u03ad\u03c7\u03b5\u03c4\u03b1\u03b9 +existe_deja=\u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7. +faux="\u03c8\u03b5\u03c5\u03b4\u03ad\u03c2 +ferme_editeur=\u039a\u03bb\u03b5\u03af\u03c3\u03c4\u03b5 \u03c4\u03bf \u03c0\u03b1\u03c1\u03ac\u03b8\u03c5\u03c1\u03bf \u03ba\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf\u03c5. +fichier_du_type=\u039c\u03bf\u03c1\u03c6\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5: +fichiers=\u0391\u03c1\u03c7\u03b5\u03af\u03bf(\u03b1) +fichiers_logo=\u0391\u03c1\u03c7\u03b5\u03af\u03b1 Logo +fichiers_rtf=\u0391\u03c1\u03c7\u03b5\u03af\u03b1 RTF +file_100K=\u03a0\u03c1\u03bf\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03c6\u03cd\u03b3\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b7\u03bd \u03c5\u03c0\u03b5\u03c1\u03c7\u03b5\u03af\u03bb\u03b9\u03c3\u03b7 \u03bc\u03bd\u03ae\u03bc\u03b7\u03c2, \u03c4\u03bf \u03bc\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c5\u03c0\u03b5\u03c1\u03b2\u03b1\u03af\u03bd\u03b5\u03b9 \u03c4\u03b1 100 KB. +fin=\u03c4\u03ad\u03bb\u03bf\u03c2 +fin_flux=\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b5\u03c2 \u03c0\u03c1\u03bf\u03c2 \u03b1\u03bd\u03ac\u03b3\u03bd\u03c9\u03c3\u03b7 \u03c3\u03c4\u03bf \u03c1\u03b5\u03cd\u03bc\u03b1 n\u00b0 +find=\u0395\u03cd\u03c1\u03b5\u03c3\u03b7 +find_replace=\u0391\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7/\u0395\u03cd\u03c1\u03b5\u03c3\u03b7 +flux_ecriture=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03b3\u03c1\u03b1\u03c8\u03c9 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c1\u03b5\u03cd\u03bc\u03b1. +flux_existant=\u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b1 \u03c1\u03b5\u03cd\u03bc\u03b1 \u03ae\u03b4\u03b7 \u03b1\u03bd\u03bf\u03b9\u03c7\u03c4\u03cc. \u03a0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03ba\u03bb\u03b5\u03af\u03c3\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c1\u03b5\u03cd\u03bc\u03b1 \u03c0\u03c1\u03bf\u03c4\u03bf\u03c5 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03ae identifier. +flux_lecture=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b2\u03ac\u03c3\u03c9 \u03b1\u03c5\u03c4\u03bf \u03c4\u03bf \u03c1\u03b5\u03cd\u03bc\u03b1. +flux_non_disponible=\u039a\u03b1\u03bd\u03ad\u03bd\u03b1 \u03c1\u03b5\u03cd\u03bc\u03b1 \u03b4\u03b5\u03bd \u03b5\u03c7\u03b5\u03b9 \u03c4\u03bf\u03bd \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03ae identifier +forme_crayon=\u03a3\u03c7\u03ae\u03bc\u03b1 \u03a3\u03c4\u03c5\u03bb\u03cc +forward=\u039c\u03c0\u03c1\u03bf\u03c3\u03c4\u03ac +gui_exists=\u039f \u03b5\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2 \u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc\u03c2 \u03c0\u03b1\u03c1\u03ac\u03b3\u03bf\u03bd\u03c4\u03b1\u03c2 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7: +haut=\u03a8\u03b7\u03bb\u03ac +hollandais=\u039f\u03bb\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac +hsb=HSB +hsbbleu=B +hsbrouge=H +hsbvert=S +imagefile=\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1\u03c2 +images=\u0395\u03b9\u03ba\u03cc\u03bd\u03b5\u03c2 +imprimer_editeur=\u03a4\u03cd\u03c0\u03c9\u03c3\u03b5 \u03c4\u03bf\u03bd \u03ba\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf +interrompre_execution=\u03a3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5 \u03c4\u03bf \u03c4\u03c1\u03ad\u03c7\u03bf\u03bd \u03ad\u03c1\u03b3\u03bf +je_ne_sais_pas=\u0394\u03b5\u03bd \u03be\u03ad\u03c1\u03c9 \u03c0\u03ce\u03c2 \u03bd\u03b1 \u03ba\u03ac\u03bd\u03c9 +line=\u03b3\u03c1\u03b1\u03bc\u03bc\u03ae +lire_editeur=\u0395\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b5 \u03ba\u03b1\u03b9 \u03ba\u03bb\u03b5\u03af\u03c3\u03b5 \u03c4\u03bf\u03bd \u03ba\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf +liste_vide=\u0397 \u03bb\u03af\u03c3\u03c4\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03ac\u03b4\u03b5\u03b9\u03b1. +mainCommand=\u039a\u03cd\u03c1\u03b9\u03b1 \u0395\u03bd\u03c4\u03bf\u03bb\u03ae: +memoire=\u0391\u03c0\u03cc\u03b4\u03bf\u03c3\u03b7 \u03bc\u03bd\u03ae\u03bc\u03b7\u03c2 (MB) +menu.edition=\u0395\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1 +menu.edition.copy=\u0391\u03bd\u03c4\u03ad\u03b3\u03c1\u03b1\u03c8\u03b5 Ctrl+C +menu.edition.cut=\u039a\u03cc\u03c8\u03b5 Ctrl+X +menu.edition.paste=\u0395\u03c0\u03b9\u03ba\u03cc\u03bb\u03bb\u03b7\u03c3\u03b7 Ctrl+V +menu.edition.selectall=\u0395\u03c0\u03ad\u03bb\u03b5\u03be\u03b5 \u03cc\u03bb\u03b1 Ctrl+A +menu.file=\u0391\u03c1\u03c7\u03b5\u03af\u03bf +menu.file.captureimage=\u0395\u03b9\u03ba\u03cc\u03bd\u03b1 +menu.file.captureimage.clipboard=\u0391\u03bd\u03c4\u03ad\u03b3\u03c1\u03b1\u03c8\u03b5 \u03c3\u03c4\u03bf \u03c0\u03c1\u03cc\u03c7\u03b5\u03b9\u03c1\u03bf +menu.file.captureimage.print=\u03a4\u03cd\u03c0\u03c9\u03c3\u03b5... +menu.file.open=\u0386\u03bd\u03bf\u03b9\u03be\u03b5 +menu.file.quit=\u03a0\u03b1\u03c1\u03b1\u03af\u03c4\u03b7\u03c3\u03b7 +menu.file.save=\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b5 +menu.file.saveas=\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b5 \u03ce\u03c2 +menu.file.textzone=\u039a\u03b5\u03af\u03bc\u03b5\u03bd\u03bf +menu.file.textzone.rtf=\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b5 \u03ce\u03c2... (RTF \u03bc\u03bf\u03c1\u03c6\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7) +menu.help=\u0392\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1 +menu.help.about=\u0393\u03b9\u03b1 \u03c4\u03b7\u03bd XLogo +menu.help.licence=\u0386\u03b4\u03b5\u03b9\u03b1 +menu.help.online=\u0395\u03b3\u03c7\u03b5\u03b9\u03c1\u03af\u03b4\u03b9\u03bf \u03c3\u03c4\u03bf \u0394\u03b9\u03b1\u03b4\u03af\u03ba\u03c4\u03c5\u03bf +menu.help.translatedlicence=\u039c\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b7 \u0386\u03b4\u03b5\u03b9\u03b1\u03c2 +menu.help.translatexlogo=\u039c\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b5 XLogo +menu.tools=\u0395\u03c1\u03b3\u03b1\u03bb\u03b5\u03af\u03b1 +menu.tools.eraser=\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ad\u03b1\u03c2 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03b9\u03ce\u03bd +menu.tools.pencolor=\u03a7\u03c1\u03ce\u03bc\u03b1 \u03a3\u03c4\u03c5\u03bb\u03cc +menu.tools.preferences=\u03a0\u03c1\u03bf\u03c4\u03b9\u03bc\u03ae\u03c3\u03b5\u03b9\u03c2 +menu.tools.screencolor=\u03a7\u03c1\u03ce\u03bc\u03b1 \u03bf\u03b8\u03cc\u03bd\u03b7\u03c2 +menu.tools.startup=\u0391\u03c1\u03c7\u03b5\u03af\u03bf \u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7\u03c2 +menu.tools.translate=\u039c\u03b5\u03c4\u03b1\u03c6\u03c1\u03b1\u03c3\u03c4\u03ae\u03c2 \u03ba\u03ce\u03b4\u03b9\u03ba\u03b1 +message_a_propos1=XLogo \u03ad\u03ba\u03b4\u03bf\u03c3\u03b7: +message_a_propos2=\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03c4\u03cd\u03bf\u03c5: +message_a_propos3=\u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03ad\u03c1\u03b8\u03b5\u03c4\u03b5 \u03c3\u03b5 \u03b5\u03c0\u03b1\u03c6\u03ae \u03bc\u03b1\u03b6\u03af \u03bc\u03bf\u03c5 \u03c3\u03c4\u03b7\u03bd \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7: +messages=\u039c\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03b1 +mot_vide=\u0397 \u03bb\u03ad\u03be\u03b7 \u03b8\u03b1 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03b5\u03c1\u03b9\u03ad\u03c7\u03b5\u03b9 \u03c4\u03bf\u03c5\u03bb\u03b1\u03c7\u03b9\u03c3\u03c4\u03bf\u03bd \u03ad\u03bd\u03b1 \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b1. +n_aime_pas=\u03b4\u03b5\u03bd \u03c4\u03bf\u03cd \u03b1\u03c1\u03ad\u03c3\u03b5\u03b9 [ +nb_tortues=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf\u03c2 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03c7\u03b5\u03bb\u03ce\u03bd\u03c9\u03bd +ne_renvoie_pas=\u03b4\u03b5\u03bd \u03ba\u03ac\u03bd\u03b5\u03b9 \u03ad\u03be\u03bf\u03b4\u03bf \u03c3\u03b5 +no_gui=\u039f \u03b5\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2 \u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc\u03c2 \u03c0\u03b1\u03c1\u03ac\u03b3\u03bf\u03bd\u03c4\u03b1\u03c2 \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9: +no_host=\u03a0\u03c1\u03cc\u03b2\u03bb\u03b7\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b4\u03b9\u03ac\u03c1\u03ba\u03b5\u03b9\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03c4\u03c5\u03b1\u03ba\u03b7\u03c2 \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1\u03c2 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03c4\u03ae \u03c4\u03bf\u03cd \u03bf\u03c0\u03bf\u03af\u03bf\u03c5 \u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9: +nom_du_fichier=\u038c\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5: +nombre_unicode=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03b5\u03c4\u03b1\u03be\u03cd 0 \u03ba\u03b1\u03af 65535. +normal=\u039a\u03b1\u03bd\u03bf\u03bd\u03b9\u03ba\u03cc +note.do=\u03bd\u03c4\u03cc +note.fa=\u03c6\u03ac +note.la=\u03bb\u03ac +note.mi=\u03bc\u03af +note.re=\u03c1\u03ad +note.si=\u03c3\u03af +note.sol=\u03c3\u03cc\u03bb +nouveau=\u039d\u03ad\u03bf +nouveau_dossier=\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5 \u03bd\u03ad\u03bf \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf +ouvrir_editeur=\u0386\u03bd\u03bf\u03b9\u03be\u03b5 \u03c4\u03bf\u03bd \u03ba\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf +parcourir=\u03a6\u03c5\u03bb\u03bb\u03bf\u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b5... +parenthese_fermante=) \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03bf\u03cd\u03c3\u03b5 \u03bd\u03b1 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c4\u03b7\u03b8\u03b5\u03af \u03b5\u03b4\u03ce. +parenthese_ouvrante=\u03a0\u03b5\u03c1\u03b9\u03bc\u03ad\u03bd\u03c9 \u03b3\u03b9\u03ac (. +parenthese_vide=\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03c4\u03af\u03c0\u03bf\u03c4\u03b1 \u03bc\u03b5\u03c4\u03b1\u03be\u03cd ( \u03ba\u03b1\u03af ) ! +pas=\u0391\u03c0\u03cc\u03c3\u03c4\u03b1\u03c3\u03b7 +pas_argument=\u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03bd\u03b1 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf \u03cc\u03c1\u03b9\u03c3\u03bc\u03b1. +pas_assez_de=\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03b1\u03c1\u03ba\u03b5\u03c4\u03ad\u03c2 \u03b5\u03b9\u03c3\u03bf\u03b4\u03bf\u03b9 \u03c3\u03c4\u03bf +pas_entier=\u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03bd\u03b1\u03c2 \u03b1\u03ba\u03ad\u03c1\u03b1\u03b9\u03bf\u03c2! +pas_liste=\u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03bc\u03b9\u03b1 \u03bb\u03af\u03c3\u03c4\u03b1. +pas_nombre=\u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03bd\u03b1\u03c2 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 ! +pas_predicat=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03bb\u03b7\u03b8\u03b5\u03c2 \u03ae \u03c8\u03b5\u03c5\u03b4\u03ad\u03c2. +pb_port=\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b9\u03ba\u03b1\u03bd\u03cc \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af \u03bc\u03b5 \u03c4\u03b7\u03bd \u03c0\u03cc\u03c1\u03c4\u03b1: +pencolor=\u0395\u03be\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd \u03c7\u03c1\u03ce\u03bc\u03b1 \u03c3\u03c4\u03c5\u03bb\u03cc +pour=\u03b3\u03b9\u03b1 +pref.cancel=\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b5 +pref.font=\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac +pref.general=\u0393\u03b5\u03bd\u03b9\u03ba\u03ac +pref.general.arabic=\u0391\u03c1\u03b1\u03b2\u03b9\u03ba\u03ac +pref.general.aspect=\u0395\u03bc\u03c6\u03ac\u03bd\u03b9\u03c3\u03b7 +pref.general.asturian=\u0391\u03c1\u03c4\u03bf\u03c5\u03c1\u03b9\u03b1\u03bd\u03ac +pref.general.catalan=\u039a\u03b1\u03c4\u03b1\u03bb\u03b1\u03bd\u03b9\u03ba\u03ac +pref.general.english=\u0391\u03b3\u03b3\u03bb\u03b9\u03ba\u03ac +pref.general.esperanto=\u0395\u03c3\u03c0\u03b5\u03c1\u03ac\u03bd\u03c4\u03bf +pref.general.fast=\u0393\u03c1\u03ae\u03b3\u03bf\u03c1\u03b1 +pref.general.french=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac +pref.general.galician=Galician +pref.general.german=\u0393\u03b5\u03c1\u03bc\u03b1\u03bd\u03b9\u03ba\u03ac +pref.general.greek=\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac +pref.general.hungarian=\u039f\u03c5\u03b3\u03b3\u03c1\u03b9\u03ba\u03ac +pref.general.italian=\u0399\u03c4\u03b1\u03bb\u03b9\u03ba\u03ac +pref.general.lang=\u0393\u03bb\u03ce\u03c3\u03c3\u03b1 +pref.general.metal=\u039c\u03b5\u03c4\u03b1\u03bb\u03bb\u03b9\u03ba\u03cc +pref.general.motif=Motif +pref.general.portuguese=\u03a0\u03bf\u03c1\u03c4\u03bf\u03b3\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac +pref.general.slow=\u0391\u03c1\u03b3\u03ac +pref.general.spanish=\u0399\u03c3\u03c0\u03b1\u03bd\u03b9\u03ba\u03ac +pref.general.speed=\u03a4\u03b1\u03c7\u03cd\u03c4\u03b7\u03c4\u03b1 \u03a7\u03b5\u03bb\u03ce\u03bd\u03b1\u03c2 +pref.general.windows=\u03a4\u03bf\u03c0\u03b9\u03ba\u03cc\u03c2/Native +pref.highlight=Highlighter +pref.highlight.comment=\u03a3\u03c7\u03cc\u03bb\u03b9\u03b1 +pref.highlight.enabled=\u0395\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b5 \u03a3\u03c5\u03bd\u03c4\u03b1\u03ba\u03c4\u03b9\u03ba\u03ae Highlighting +pref.highlight.example=# \u0391\u03c5\u03c4\u03cc \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03bd\u03b1 \u03c3\u03c7\u03cc\u03bb\u03b9\u03bf\n repeat 4 [forward 100 right 90] +pref.highlight.init=\u0395\u03be\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 +pref.highlight.operand=\u039c\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ad\u03c2 , \u03bb\u03ad\u03be\u03b5\u03b9\u03c2, \u03b1\u03c1\u03b9\u03b8\u03bc\u03bf\u03af +pref.highlight.other=\u0386\u03bb\u03bb\u03b1... +pref.highlight.primitive=\u03a3\u03c4\u03bf\u03b9\u03c7\u03b5\u03b9\u03ce\u03b4\u03b7 +pref.highlight.parenthesis=\u0386\u03b3\u03ba\u03b9\u03c3\u03c4\u03c1\u03b1, \u0391\u03b3\u03ba\u03cd\u03bb\u03b5\u03c2 +pref.ok=\u0395\u039d\u03a4\u0391\u039e\u0395\u0399 +pref.options=\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 +pref.options.eraseVariables=\u039a\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b5 \u03c4\u03b9\u03c2 \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ad\u03c2 \u03cc\u03c4\u03b1\u03bd \u03ba\u03bb\u03b5\u03af\u03c3\u03b5\u03b9\u03c2 +pref.options.tcp=\u0391\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03c0\u03cc\u03c1\u03c4\u03b1\u03c2 TCP +pref.sound=\u0389\u03c7\u03bf\u03c2 +pref.sound.instruments=\u03a0\u03b1\u03c1\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03b1 \u038c\u03c1\u03b3\u03b1\u03bd\u03b1: +pref.sound.problem=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03c9 \u03bd\u03b1 \u03b2\u03c1\u03ce \u03b4\u03b9\u03b5\u03c0\u03b1\u03c6\u03ae MIDI interface ! +pref.turtles=\u03a7\u03b5\u03bb\u03ce\u03bd\u03b1 +primitives=\u03a3\u03c4\u03bf\u03b9\u03c7\u03b5\u03b9\u03ce\u03b4\u03b7 +probleme_sequence=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03ba\u03b1\u03c4\u03b1\u03bb\u03ac\u03b2\u03c9 \u03c4\u03b7\u03bd \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c3\u03b1\u03c2 \u03b1\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03af\u03b1, \u03c0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b5\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 ! +procedure_demarrage=\u0395\u03bd\u03c4\u03bf\u03bb\u03ae \u03b3\u03b9\u03b1 \u03b5\u03ba\u03c4\u03b5\u03bb\u03b5\u03c3\u03b7 \u03c3\u03c4\u03b7\u03bd \u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7: +procedure_list=\u0394\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b5\u03c2: +procedure_vide=\u03a4\u03b1 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03b1 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03b9\u03bb\u03c9\u03bd \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03ba\u03b5\u03bd\u03ac ! +qualite_dessin=\u03a3\u03c7\u03b5\u03b4\u03b9\u03b1\u03c3\u03c4\u03b9\u03ba\u03ae \u03c0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 +quit_editeur=\u039a\u03bb\u03b5\u03af\u03c3\u03c4\u03b5 \u03c4\u03bf\u03bd \u03ba\u03b5\u03b9\u03bc\u03b5\u03bd\u03bf\u03b3\u03c1\u03ac\u03c6\u03bf \u03c7\u03c9\u03c1\u03af\u03c2 \u03b5\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 +quitter?=\u0395\u03af\u03c3\u03c4\u03b5 \u03b2\u03ad\u03b2\u03b1\u03b9\u03bf\u03c2 \u03bf\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03b9\u03c4\u03b7\u03b8\u03b5\u03af\u03c4\u03b5 \u03b1\u03c0\u03bf \u03c4\u03b7\u03bd XLogo? +rechercher_dans=\u039a\u03bf\u03af\u03c4\u03b1\u03be\u03b5 \u03bc\u03ad\u03c3\u03b1 \u03c3\u03b5 : +relancer=\u0388\u03c0\u03b5\u03b9\u03c4\u03b1 \u03c0\u03b1\u03c1\u03b1\u03b9\u03c4\u03ae\u03c3\u03bf\u03c5 \u03b1\u03c0\u03bf \u03c4\u03b7\u03bd XLogo \u03ba\u03b1\u03b9\u03be\u03b1\u03bd\u03b1\u03be\u03b5\u03ba\u03b9\u03bd\u03b1 \u03b3\u03b9\u03b1 \u03b5\u03bd\u03b7\u03bc\u03ad\u03c1\u03c9\u03c3\u03b7 \u03c4\u03ce\u03bd \u03b1\u03bb\u03bb\u03b1\u03b3\u03ce\u03bd. +repertoire_accueil=\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 Home +repertoires=\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03b9 +replace=\u0391\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ad\u03c3\u03c4\u03b7\u03c3\u03b5 +replaceall=\u0391\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ad\u03c3\u03c4\u03b7\u03c3\u03b5 \u03cc\u03bb\u03b1 +replacewith=\u0391\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ad\u03c3\u03c4\u03b7\u03c3\u03b5 \u03bc\u03b5 : +restaurer=\u0395\u03c0\u03b1\u03bd\u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7 +rgb=RGB +rond=\u03a3\u03c4\u03c1\u03bf\u03b3\u03b3\u03c5\u03bb\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 +rouge=\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf +screencolor=\u0395\u03be\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd \u03c7\u03c1\u03ce\u03bc\u03b1 \u03bf\u03b8\u03cc\u03bd\u03b7\u03c2 +seule_tortue_dispo=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03c4\u03b7\u03bd \u03bc\u03bf\u03bd\u03b1\u03b4\u03b9\u03ba\u03b7 \u03b5\u03bd\u03b5\u03c1\u03b3\u03ae \u03c7\u03b5\u03bb\u03ce\u03bd\u03b1 ! +stop=\u03a3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1 +stop_chat=<<<<< \u03a4\u03ad\u03bb\u03bf\u03c2 \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1\u03c2 >>>>> +string_not_found=\u03a4\u03bf \u03b1\u03bb\u03c6\u03b1\u03c1\u03b9\u03b8\u03bc\u03b7\u03c4\u03b9\u03ba\u03cc \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5. +style.bold=\u0388\u03bd\u03c4\u03bf\u03bd\u03b1 +style.exposant=\u0395\u03ba\u03b8\u03ad\u03c4\u03b7\u03c2 +style.italic=\u03a0\u03bb\u03ac\u03b3\u03b9\u03b1 +style.none=\u03a4\u03af\u03c0\u03bf\u03c4\u03b1 +style.strike=Strike +style.subscript=\u0394\u03b5\u03af\u03ba\u03c4\u03b7\u03c2 +style.underline=\u03a5\u03c0\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b9\u03c3\u03b7 +taille_dessin=\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2 \u03bf\u03b8\u03cc\u03bd\u03b7\u03c2 +title_axis=Background Axis +titredialogue2=\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1\u03c2 \u03c4\u03ce\u03c1\u03b1... +too_much_arguments=\u03a5\u03c0\u03b5\u03c1\u03b2\u03bf\u03bb\u03b9\u03ba\u03ac \u03c0\u03bf\u03bb\u03bb\u03ac \u03bf\u03c1\u03af\u03c3\u03bc\u03b1\u03c4\u03b1 \u03bc\u03ad\u03c3\u03b1 \u03c3\u03c4\u03b9\u03c2 \u03c0\u03b1\u03c1\u03b5\u03bd\u03b8\u03b5\u03c3\u03b5\u03b9\u03c2. +tortue_inaccessible=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03c9 \u03bc\u03b9\u03b1 \u03c7\u03b5\u03bb\u03ce\u03bd\u03b1 \u03bc\u03b5 \u03b1\u03c5\u03c4\u03bf\u03bd \u03c4\u03bf\u03bd \u03c3\u03c5\u03b3\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03bf \u03b1\u03c1\u03b9\u03b8\u03bc\u03bf ! +traduire=\u039c\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b5 ! +traduire_de=\u039c\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b5 \u03b1\u03c0\u03cc : +translatecomplete=\u039f\u03bb\u03bf\u03ba\u03bb\u03ae\u03c1\u03c9\u03c3\u03b5 \u03bc\u03b9\u03b1 \u03bc\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b7 +translateconsult=\u03a3\u03c5\u03bc\u03b2\u03bf\u03c5\u03bb\u03ad\u03c8\u03bf\u03c5 \u03c0\u03b1\u03c1\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03b5\u03c2 \u03bc\u03b5\u03c4\u03b1\u03c6\u03c1\u03ac\u03c3\u03b5\u03b9\u03c2 +translatecreate=\u0394\u03b7\u03bc\u03b9\u03bf\u03cd\u03c1\u03b3\u03b7\u03c3\u03b5 \u03bc\u03b9\u03b1 \u03bd\u03b5\u03b1 \u03bc\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b7 +translatemessage=\u038c\u03c4\u03b1\u03bd \u03bf\u03bb\u03b1 \u03c4\u03b1 \u03c0\u03b5\u03b4\u03af\u03b1 \u03ad\u03c7\u03bf\u03c5\u03bd \u03c3\u03c5\u03bc\u03c0\u03bb\u03b7\u03c1\u03c9\u03b8\u03b5\u03af \u03b3\u03b9\u03b1 \u03ba\u03b1\u03b8\u03b5 +translatemodify=\u039c\u03b5\u03c4\u03ac\u03b2\u03b1\u03bb\u03bb\u03b5 \u03bc\u03b9\u03b1 \u03bc\u03b5\u03c4\u03ac\u03c6\u03c1\u03b1\u03c3\u03b7 +translatewant=\u0398\u03ad\u03bb\u03b5\u03b9\u03c2 \u03bd\u03b1 : +un_caractere=\u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03b5\u03c1\u03b9\u03ad\u03c7\u03b5\u03b9 \u03b1\u03ba\u03c1\u03b9\u03b2\u03ce\u03c2 \u03ad\u03bd\u03b1\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b1. +uniform_color=\u039f\u03bc\u03bf\u03b9\u03cc\u03bc\u03bf\u03c1\u03c6\u03bf \u03c7\u03c1\u03ce\u03bc\u03b1 +variable_vide=\u03a4\u03b1 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03b1 \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ce\u03bd \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03ba\u03b5\u03bd\u03ac ! +vers=\u03a0\u03c1\u03cc\u03c2: +vert=\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf +vrai="\u03b1\u03bb\u03b7\u03b8\u03ad\u03c2 +xgrid=\u03a7 \u03c0\u03bb\u03ad\u03b3\u03bc\u03b1 +y_a_pas=\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 +ygrid=Y Grid +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_en_DE.properties b/logo/src/langage_en_DE.properties new file mode 100644 index 0000000..e547689 --- /dev/null +++ b/logo/src/langage_en_DE.properties @@ -0,0 +1,437 @@ +3d.fog.backdistance=Abstand Gesamttransparenz +3d.fog.density=Dichte +3d.fog.exponential=Dichter Nebel +3d.fog.frontdistance=Abstand vorne +3d.fog.linear=Linearer Nebel +3d.fog.none=Keine +3d.fog.type=Nebeltyp: +3d.fog=Nebel +3d.light.ambient=Umgebungslicht +3d.light.angle=Winkel: +3d.light.apply=Anwenden +3d.light.direction=Richtung +3d.light.directional=Gerichtetes Licht +3d.light.none=Ohne Licht +3d.light.point=Punktlicht +3d.light.position=Position +3d.light.spot=Spotlicht +3d.light.type=Beleuchtungstyp: +3d.light=Licht +3d.viewer=3D Betrachter +active_grid=Aktiv +active_xaxis=X-Achse +active_yaxis=Y-Achse +ajouter=F\u00fcge hinzu +animation_active = Du bist zur Zeit im Animations Modus.. +apercu = Vorschau +attend_positif = wartet auf ein positives Argument. +backward=R\u00fcckw\u00e4rts +bas = Schlecht +bleu = Blau +bordermotif=Randmotiv +caractere_special_variable = Variablennamen enthalten nie +caractere_special1=Namen von Prozeduren d\u00fcrfen folgende Zeichen +caractere_special2=Zeichen wie + - * / ( ) [ ] = < > & | : +caractere_special3=Gebe einen neuen Namen +carre=Quadrat +chaine_trop_longue=Ich kann kein Wort oder Liste mit mehr als 32000 Zeichen schreiben. +chat=Chat +chemin=Pfad +color_3_arguments=muss eine drei-elementige Liste haben, [rot gr\u00fcn blau] +commande=Kommando : +comme_parametre = ] als Angaben. +couleur_du_crayon=Stiftfarbe +couleur_du_fond=Hintergrundfarbe +dans=In +definir=Du definierst +depassement_memoire=Die Anwendung benutzt 90% des freien Speichers.\nDein Programm wird beendet, damit der Stapel nicht \u00fcberl\u00e4uft.\nSehe bitte nach, dass Dein Programm keine Endlosschleife enth\u00e4lt, ansonsten weise XLogo mehr Speicherplatz zu(im Men\u00fc bei Optionen). +dernier = Letzter +direction=Richtung +division_par_zero = Man darf nicht durch Null teilen! +dossier_parent=Eltern-Ordner +draw_grid=Hintergrund-Gitter +echantillon = Beispiel +echantillon_texte = Dies ist eine Vorschau +editeur=Editor +editor.redo=Wiederherstellen +editor.undo=R\u00fcckg\u00e4ngig +effacer_editeur= L\u00f6sche den Bildschirm beim Verlassen des Editors +element_dans_liste= Elemente in der Liste [ +enlever=Entferne +enregistreimage=Speichere Bild unter... +enregistrer_espace = Arbeitsfl\u00e4che leeren? +entre_zero_un = muss zwischen 0 und 1 sein. +epaisseur_crayon = Maximale Stiftdicke +erreur_compteur=Du darfst whzahl nicht aus einer Wiederhole Schleife benutzen. +erreur_crochet=Fehler: ] erwartet +erreur_editeur=Ich kann die Prozeduren nicht speichern.\nBitte sehe nach, ob to ...immer ein end hat und\nkontrolliere, ob alle Variablen :a :b usw. richtig angelegt sind. +erreur_fixestyle=Setzestil akzeptiert nur folgende Werte: Kein, Fett, Unterstrichen, Kursiv, Hochgestellt oder Tiefgestellt. +erreur_format_image=Kann nur *.png und *.jpg Bilder benutzen. +erreur_memoire = XLogo hat nicht genug Speicher um dieses Bild erstellen zu k\u00f6nnen.\n Gebe unter Optionen einen gr\u00f6\u00dferen Wert f\u00fcr den Speicher ein. +erreur_nom_nombre_procedure=Prozedurnamen d\u00fcrfen nicht nur aus Zahlen bestehen ! +erreur_nom_nombre_variable = Variablennamen d\u00fcrfen nicht nur aus Zahlen bestehen ! +erreur_pas_repertoire = ist kein g\u00fcltiger Ordner ! +erreur_repetepour = muss drei oder vier Parameter enthalten. [Variable Anfang Ende Z\u00e4hler] +erreur_retourne=Du darfst nicht R\u00fcckgabe benutzen au\u00dferhalb einer Prozedur ! +erreur_sortie1=Igel verl\u00e4\u00dft den Zeichenbereich. +erreur_sortie2=Du kannst noch so viele Schritte gehen: +erreur_stop=Du darfst 'stop' nicht am Ende einer Schleife oder Prozedur benutzen ! +erreur_tcp=Problem in der Netzwerk Kommunikation +erreur_variable = ist keine g\u00fcltige Variable ! +erreur=FEHLER +error_bad_values=akzeptiert nur die Werte +error.3d.3vertex=Ein Vieleck muss haben +error.3d.emptypolygon=Eine Vieleckfl\u00e4che +error.ioecriture=Input-Output Fehler: Entschuldigung, ich kann nicht speichern... +error.iolecture=Kann diese Datei nicht lesen. +error.ne_peut_etre= kann ich hier nicht finden. +error.novalue=hat keinen Wert. +error.primitive2D=ist nur verf\u00fcgbar in 2D +error.primitive3D=ist nur verf\u00fcgbar in 3D +error.procedure.must.be=muss eine Prozedur sein +error.whattodo=Ich weiss nicht, was ich machen soll mit +error.word=muss ein Wort sein. +existe_deja= gibt es schon. +faux="falsch +ferme_editeur=Schlie\u00dfe das Editor-Fenster. +fichier_du_type = Dateiformat +fichiers = Datei(en) +fichiers_logo=Logo Dateien +fichiers_rtf=RTF-Dateien +file_100K=Zum Verhindern von Speicher\u00fcberlauf kann Dateigr\u00f6\u00dfe nur kleiner 100 KB sein. +fin_flux = Es gibt keine zu lesenden Zeichen in diesem Fluss n\u00b0 +fin=end +find_replace=Ersetze/Suche +find=Suche +flux_ecriture = Ich kann in diesem Fluss nicht schreiben. +flux_existant=ist ein Fluss, der schon offen ist. Du musst ihn erst schlie\u00dfen, bevor Du diesen Namen benutzen kannst. +flux_lecture = Ich kann in diesem Fluss nicht lesen. +flux_non_disponible=Kein Fluss hat diesen Namen +forme_crayon = Form des Stiftes +forward=forward +gui_exists=Die folgende graphische Komponente gibt es schon: +haut = Sehr gut +hollandais = Niederl\u00e4ndisch +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=Bild-Dateien +images=Bilder +imprimer_editeur=Drucke den Text. +interrompre_execution=Stoppe die laufende Aufgabe +je_ne_sais_pas=Ich weiss nicht, wie ich +line=Zeile +lire_editeur=Speichere und schlie\u00dfe den Editor +liste_vide = Die Liste ist leer. +mainCommand=Hauptkommando +memoire=Zugewiesener Speicher f\u00fcr XLogo (MB): +menu.edition.copy=Kopiere Strg-C +menu.edition.cut=Ausschneiden Strg-X +menu.edition.paste=Einf\u00fcgen Strg-V +menu.edition.selectall=Markiere alles +menu.edition=Bearbeiten +menu.file.captureimage.clipboard=Kopiere in die Zwischenablage +menu.file.captureimage.print=Drucke Bild +menu.file.captureimage=Bild +menu.file.open=\u00d6ffnen +menu.file.quit=Beenden +menu.file.save=Speichern +menu.file.saveas=Speichern unter ... +menu.file.textzone = Textbereich +menu.file.textzone.rtf=Speichere im RTF Format +menu.file=Datei +menu.help.about=\u00fcber... +menu.help.licence= Lizenz +menu.help.online=Online-Handbuch +menu.help.translatedlicence=\u00dcbersetzte Lizenz +menu.help.translatexlogo=\u00dcbersetze XLogo +menu.help=Hilfe +menu.tools.eraser=L\u00f6sche Prozeduren +menu.tools.pencolor=W\u00e4hle Stiftfarbe +menu.tools.preferences=Einstellungen +menu.tools.screencolor=W\u00e4hle Hintergrundfarbe +menu.tools.startup=Definiere Startdatei +menu.tools.translate=\u00dcbersetze den Quelltext... +menu.tools=Hilfsmittel +message_a_propos1=XLogo Version: +message_a_propos2=Website: +message_a_propos3=Du kannst mir schreiben: +messages=Meldungen +mot_vide=Das Wort mu\u00df mindestens ein Zeichen enthalten. +n_aime_pas = mag nicht [ +nb_tortues=Anzahl Igel +ne_renvoie_pas=gibt nichts aus nach +no_gui=Die folgende graphische Komponente gibt es nicht: +no_host=Kommunikationsprobleme mit der Netzwerkadresse: +nom_du_fichier=Dateiname: +nombre_unicode = muss zwischen 0 und 65535 sein. +normal = Normal +note.do = do +note.fa = fa +note.la = la +note.mi= mi +note.re = re +note.si = si +note.sol = sol +nouveau = Neu +nouveau_dossier=Erstelle einen neuen Ordner +ouvrir_editeur=\u00d6ffne den Editor +parcourir=Durchsuche... +parenthese_fermante= ) konnte hier nicht eingef\u00fcgt werden. +parenthese_ouvrante=Ich warte auf (. +parenthese_vide=Da steht nichts zwischen ( und ) ! +pas_argument=ist kein g\u00fcltiges Argument. +pas_assez_de=Nicht genug Eingaben zu +pas_entier=ist keine ganze Zahl ! +pas_liste = ist keine Liste. +pas_nombre = ist keine Zahl ! +pas_predicat= muss wahr oder falsch sein. +pas=Abstand +pb_port=Kann den Port nicht erreichen +pencolor=Standard-Schriftfarbe +pour=to +pref.cancel=Abbrechen +pref.font= Schriftart +pref.general.arabic=Arabisch +pref.general.aspect=Erscheinungsbild +pref.general.asturian=Asturisch +pref.general.catalan=Katalanisch +pref.general.english=Englisch +pref.general.esperanto = Esperanto +pref.general.fast=Schnell +pref.general.french=Franz\u00f6sisch +pref.general.galician=Galizisch +pref.general.german=Deutsch +pref.general.greek=Griechisch +pref.general.hungarian=Ungarisch +pref.general.italian=Italienisch +pref.general.lang=Sprache +pref.general.metal=Metall +pref.general.motif=Motif +pref.general.portuguese= Portugiesisch +pref.general.slow=Langsam +pref.general.spanish=Spanisch +pref.general.speed=Geschwindigkeit des Igel +pref.general.windows=Nativ +pref.general=Allgemein +pref.highlight.comment= Kommentare +pref.highlight.enabled=Aktiviere Farbhervorhebung +pref.highlight.example=# Dies ist ein Kommentar\n repeat 4[forward 100 right 90]\n +pref.highlight.init= Standardwerte +pref.highlight.operand= Variablen, Worte, Zahlen +pref.highlight.other=Andere... +pref.highlight.parenthesis= Klammern, eckige Klammern +pref.highlight.primitive= Befehle +pref.highlight=Farbhervorhebung +pref.ok = OK +pref.options.eraseVariables=L\u00f6sche Variablen beim Schlie\u00dfen des Editor +pref.options.tcp=TCP Portnummer: +pref.options=Optionen +pref.sound.instruments= verf\u00fcgbare Instrumente +pref.sound.problem=Ich kann die MIDI Schnittstelle nicht finden ! +pref.sound= Sound +pref.turtles=W\u00e4hle den Igel +primitives=Befehle +probleme_sequence=Ich verstehe Deine musikalische Sequenz nicht. Bitte kontrolliere sie ! +procedure_demarrage=Kommando, das beim Start ausgef\u00fchrt wird: +procedure_list=Prozeduren-Liste +procedure_vide=Prozedurennamen d\u00fcrfen nicht leer sein ! +qualite_dessin = Qualit\u00e4t der Zeichnung: +quit_editeur=Schlie\u00dfe den Editor ohne zu speichern +quitter? = M\u00f6chtest Du das Programm beenden? +rechercher_dans=Sehe in: +relancer=Danach beende und starte XLogo, damit die \u00c4nderung wirksam wird. +repertoire_accueil= Heimordner +repertoires = Ordner +replace=Ersetze +replaceall=Ersetze alles +replacewith=Ersetze mit +restaurer=resette +rgb = RGB +rond= rund +rouge = Rot +screencolor=Standard Hintergrundfarbe +seule_tortue_dispo=Du kannst den aktiven Igel nicht l\u00f6schen ! +stop_chat=<<<<< Ende des Chats >>>>> +stop=Stop +string_not_found=Zeichenkette nicht gefunden. +style.bold= Fett +style.exposant = Hochgestellt +style.italic= Kursiv +style.none= Kein +style.strike= Durchgestrichen +style.subscript= Tiefgestellt +style.underline= Unterstrichen +taille_dessin=Bildschirmgr\u00f6\u00dfe zum Zeichnen +title_axis=Hintergrund-Achse +titredialogue2=Speichere gerade das Bild... +too_much_arguments=Zu viele Argumente in +tortue_inaccessible=Ich kann keinen Igel mit dieser Nummer erzeugen ! +traduire_de=\u00dcbersetze von: +traduire=\u00dcbersetze! +translatecomplete=Komplettiere eine \u00dcbersetzung +translateconsult=Konsultiere verhandene \u00dcbersetzungen +translatecreate=Schaffe eine neue \u00dcbersetzung +translatemessage=Wenn alle Felder vollst\u00e4ndig sind f\u00fcr +translatemodify=Modifiziere eine \u00dcbersetzung +translatewant=Du willst: +un_caractere = darf nur ein Zeichen enthalten. +uniform_color=Gleiche Farbe: +variable_vide = Variablennamen d\u00fcrfen nicht leer sein. +vers=Nach: +vert = Gr\u00fcn +vrai="wahr +xgrid=X-Gitter: +y_a_pas = Es gibt kein +ygrid=Y-Gitter: +ws.settings.require_password=Sch�tze diese Einstellungen mit einem Passwort +ws.settings.password=Passwort +ws.settings.retype.password=Wiederhole das Passwort +ws.settings.save.password=Passwort speichern +ws.settings.workspace=Arbeitsplatz: +ws.settings.location=Ort: +ws.settings.language=Sprache: +ws.settings.backups=Anzahl Backups: +ws.settings.user=Benutzer: +ws.settings.add=Hinzuf�gen +ws.settings.remove=Entfernen +ws.settings.import=Importieren +ws.settings.enable.user.account.creation=Erlaube Benutzern Kontos hinzuzuf�gen? +ws.settings.save.and.close=Spechern und Schliessen +ws.settings.title=XLogo4Schools - Arbeitsplatzeinstellungen +ws.settings.global=Global +ws.settings.global.settings=Globale Einstellungen +ws.settings.workspace=Arbeitsplatz +ws.settings.global.settings=Arbeitsplatzeinstellungen +ws.settings.cannot.store.pw=Konnte das Passwort nicht speichern: +ws.settings.pw.must.be.equal=Die Passw�rter m�ssen gleich sein +ws.settings.virtual.ws.not.stored=Ein virtueller Arbeitsplatz wird nicht auf dem Dateisystem gespeichert +ws.settings.could.not.enter.wp=Konnte den Arbeitsplatz nicht betreten: +ws.settings.create.new.wp=Erstelle einen neuen Arbeitsplatz +ws.settings.wp.name.non.empty=Der Name darf nicht leer sein +ws.settings.wp.exists.already=Dieser Arbeitsplatz existiert bereits +ws.settings.could.not.create.directory=Der Ordner konnte nicht erstellt werden. +ws.settings.need.dir.not.file=Es muss ein Ordner angegeben werden, keine Datei. +ws.settings.could.not.create.ws=Der Arbeitsplatz konnte nicht auf dem Dateisystem erstellt werden. +ws.settings.want.delete.dir.1=M�chten Sie den Ordner ' +ws.settings.want.delete.dir.2=' und seine Inhalte f�r vom Dateisystem l�schen? +ws.settings.could.not.enter.virtual.ws=Der virtuelle Arbeitsplatz konnte nicht betreten werden +ws.settings.delete.from.fs=Vom Dateisystem l�schen? +ws.settings.not.legal.ws.dir= ist kein Arbeitsplatzverzeichnis. +ws.settings.enter.user.name=Benutzernamen eingeben +ws.settings.create.new.user=Neuen Benutzer erstellen +ws.settings.user.exists.already=Dieser Benutzer existiert bereits im Arbeitsplatz +ws.settings.remove.user=Den Benutzer vom Dateisystem l�schen? +ws.settings.not.legal.user.dir= ist kein korrektes Benutzerverzeichnis. +ws.settings.choose.other.name= exisitiert bereits im Arbeitsplatz. W�hle einen neuen Namen. +ws.settings.name.conflict=Namenskonflikt +ws.settings.could.not.import.user=Der Benutzer konnte nicht importiert werden: +ws.creation.panel.name=Arbeitsplatzname +ws.creation.panel.location=Ort +ws.creation.panel.browse=Durchsuchen +welcome.workspace=Arbeitsplatz +welcome.username=Benutzer +welcome.settings=Einstellungen +welcome.enter=Eintreten +welcome.title=XLogo4Schools +welcome.wrong.pw=Falsches Passwort. +welcome.enter.pw=Passwort eingeben. +welcome.could.not.enter.user=Der Benutzer konnte nicht angemeldet werden: +storage.could.not.store.gc=Die globalen Einstellungen konnten nicht gespeichert werden. +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=Das Programm wurde nicht richtig erzeugt +procedure.executable=Das Programm ist ausf�hrbar +procedure.not.executable=Das Programm ist nicht ausf�hrbar +procedure.error=Das Programm enth�lt fehler. +error.proc.does.not.exist=Das Programm existiert nicht. +ws.generated.procedure=generierte_prozeduren +ws.redefine.ambiguous.procedure= ist mehrmals definiert. Ich weiss nicht welches Programm ich �berschreiben soll. +error.call.ambiguous.procedure.name=ist mehrmals definiert. Ich weiss nicht welches Programm ich ausf�hren soll. +ws.could.not.create.file=Ich konnte folgendes Dokument nicht erstellen: + +ws.error.title=Fehler im Arbeitsplatz +ws.error.could.not.load.logo.files=Ich konnte einige Dateien nicht laden: +i.am.sorry=Es tut mir leid, aber... +ws.error.userdir.not.dir=Der ausgew�hlte Ordner ist kein Quellordner und er konnte auch nicht eingerichtet werden. +ws.error.could.not.store.configs=Ich konnte die Konfigurationsdateien nicht speichern. +ws.error.could.not.create.logo.file=Leider konnte ich aus folgendem Grund keine neue Datei erzeugen: +new.file=Neues Dokument + +contest.error.could.not.record.file=Ich konnte die j�ngsten �nderungen nicht protokollieren. Bitte zeige diese Meldung den Organisatoren. +contest.mode.start=Aufzeichnungsmodus starten +contest.mode.stop=Aufzeichnungsmodus beenden +contest.mode.filename=Aufgabe +contest.mode.bonus.filename=Bonusaufgabe +contest.error.title=Danke, du has einen hinterh�ltigen Fehler entdeckt! +contest.could.not.create=Leider konnte ich die Dateien f�r den Aufzeichnungsmodus nicht anlegen. Bitte zeige diese Meldung den Organisatoren. +contest.could.not.store=Leider konnte ich deine Eingabe nicht protokollieren. Bitte zeige diese Meldung den Organisatoren. + +ws.filename.exists.already=Dieser Name existiert bereits. Bitte w�hle einen anderen. +ws.attempt.open.inexistent.file=Ich habe versucht ein Dokument zu �ffnen, welches nicht im Arbeitsplatz ist: +ws.attempt.close.not.open.file=Komisch... Ich habe gerade versuch eine Datei zu schliessen, die nie offen war. +ws.automatic.save.failed=Leider konnte ich deine �nderungen aus folgendem Grund nicht speichern: +general.error.title=Uuups +editor.display.procedure.not.found= ist nicht definiert. + +name.error.dialog.title=Uuups +name.error.rename.inexistent.file=Leider kann ich dieses Dokument nicht umbenennen, weil ich denke, dass dieses gar nicht existiert. +name.error.empty.name=Ich kann nicht einem Dokument einen leeren Namen geben. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Violet +color.red=Rot +color.yellow=Gelb +logo.file.has.error=Dieses Dokument enth�lt Fehler und dessen Programme k�nnen nicht ausgef�hrt werden. + +error.while.creating.editor=Leider konnte ich aus folgendem Grund den Editor nicht �ffnen: + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=Ein Logo-Dokument muss immer mit "to" beginnen +error.missing.name=Ich habe einen Programmnamen erwartet, aber keinen gefunden. +error.name.is.number=Ein Name eines Programms darf keine Zahl sein. +error.name.special=Ein Name eines Programms darf keine Sonderzeichen enthalten. +error.var.white.after.colon=Ich habe einen Abstand zwischen dem Doppelpunkt und dem Namen einer Variable entdeckt. +error.var.special=Variablennamen d�rfen keine Sonderzeichen enthalten. +error.var.is.number=Variablennamen d�rfen keine Zahlen sein. +error.var.missing.colon=Ich kann keinen Doppelpunkt finden. +error.opt.var.bracket=Da ist etwas mit der Klammerung bei den optionalen Parametern schief gelaufen. +error.var.extra.chars=Ich verstehe nicht, was am Ende der Variablendeklaration steht. +error.missing.expr=Ich vermisse einen Standardwert f�r einen optionalen Parameter. +error.more.chars.after.end="End" sollte alleine auf einer Zeile stehen. +error.missing.end=Deins letztes Programm besitzt kein "end". +error.to.before.end= hat kein end. +error.name.is.key.word=Einer der von dir gew�hlten Namen ist ein reserviertes Schl�sselwort, das ich nicht �berschreiben kann. +error.procedure.ambiguous=Es gibt ein anderes Programm mit demselben Namen. + +hist.msg.procedures.undefined= Ich habe vergessen : + +error.network.context=Ich verstehe die Daten nicht, welche ich aus dem Netzwerk erhalten habe. + +dialog.yes=Ja +dialog.no=Nein +us.could.not.store.recent.data=Ich konnte die j�ngsten �nderungen nicht speichern: +illegal.name.msg=Der gew�hlte Name enth�lt ung�ltige Zeichen +ws.does.not.exist=Der angegebenee Arbeitsplatz existiert nicht +ws.not.a.workspace.dir=ist kein g�ltiger Arbeitsplatz zum Importieren +app.hello= Hallo + +file.contains.errors=enth�lt Fehler. + +us.import=Datei importieren +us.export=Datei exportieren +us.save.image=Bild speichern + +us.export.msg=W�hle eine Datei zum Exportieren: + +contest.number.of.files=Anzahl Aufgaben: +contest.number.of.bonus.files =Anzahl Bonusaufgaben: +ws.settings.syntax=Syntaxhervorhebung +ws.settings.contest=Wettbewerb- / Aufzeichnungsmodus
\ No newline at end of file diff --git a/logo/src/langage_en_US.properties b/logo/src/langage_en_US.properties new file mode 100644 index 0000000..e5aa726 --- /dev/null +++ b/logo/src/langage_en_US.properties @@ -0,0 +1,437 @@ +3d.viewer=3D Viewer +3d.fog=Fog +3d.fog.density=Density: +3d.fog.none=None +3d.fog.exponential=Exponential Fog +3d.fog.linear=Linear fog +3d.fog.frontdistance=Front distance +3d.fog.backdistance=Back distance +3d.fog.type=Fog type: +3d.light=Light +3d.light.type=Light type: +3d.light.ambient=Ambient Light +3d.light.directional=Directionnal Light +3d.light.point=Point Light +3d.light.none=Off +3d.light.spot=Spot Light +3d.light.position=Position +3d.light.direction=Direction +3d.light.angle=Angle: +3d.light.apply=Apply +active_grid=Active +active_xaxis=X Axis +active_yaxis=Y Axis +ajouter=Add +animation_active = Animation mode is currently true. +apercu = Preview +attend_positif = is waiting for a positive argument. +backward=Backward +bas = Low +bleu = Blue +bordermotif=Border motif +caractere_special_variable = Variable names don't support +caractere_special1=Procedure names don't support +caractere_special2=characters like \ + - * / ( ) [ ] = < > & | : +caractere_special3=Rename +carre = Square +chaine_trop_longue = I can't print a word or a list with more than 32000 characters. +chat=Chat +chemin=Path +color_3_arguments=must have a 3 element list, [red green blue] +commande=Command: +comme_parametre = ] as arguments. +couleur_du_crayon=Pen Color +couleur_du_fond=Screen Color +dans=In +definir=You defined +depassement_memoire =XLogo has used 90% of available memory space.\nYour command will be stopped to prevent a stack overflow.\nCheck your program doesn't contain an infinite loop. Else increase the memory allocated to XLogo. +dernier = Last +direction=Direction +division_par_zero =You can't divide by zero ! +dossier_parent = Parent folder +draw_grid=Background Grid +echantillon = Sample +echantillon_texte = This is a preview +editeur=Editor +editor.redo=Redo last action +editor.undo=Undo last action +effacer_editeur=Clear screen when closing the editor +element_dans_liste= elements in the list [ +enlever=Remove +enregistreimage=Image Save As... +enregistrer_espace = Delete the workspace? +entre_zero_un = must be between 0 and 1. +epaisseur_crayon = Maximum pen width +erreur_compteur =You can't use repcount outside a repeat loop. +erreur_crochet=Error: ] expected. +erreur_editeur=I can't save procedures.\nPlease be careful with blocks To .... End.\nAlso check for bad definition of variables. +erreur_fixestyle =setstyle can only accept these values: none, bold, underline, italic, superscript or subscript. +erreur_format_image=Image files accepted are *.png and *.jpg +erreur_memoire=XLogo doesn't have enough memory to create the desired image.\nIn "Options" tab, increase the memory allocated to XLogo. +erreur_nom_nombre_procedure = Procedure names can't be numbers ! +erreur_nom_nombre_variable = Variable names can't be numbers ! +erreur_pas_repertoire = isn't a valid directory ! +erreur_repetepour=must contain three or four elements, [variable start end increment] +erreur_retourne =You can't use return outside a procedure ! +erreur_sortie1=Turtle is leaving the drawing zone. +erreur_sortie2=Number of steps available before leaving: +erreur_stop =You can't use stop outside a procedure or a loop ! +erreur_tcp=Problem in network communication. +erreur_variable = isn't a valid variable ! +erreur=ERROR +error_bad_values=only accepts +error.3d.3vertex=A polygon must have three vertices! +error.3d.emptypolygon=A polygon surface cannot be equal to zero! +error.ioecriture=Input/Output error: Sorry, I can't save... +error.iolecture=Unable to read the specified file. +error.ne_peut_etre= couldn't be found here. +error.novalue= has no value. +error.primitive2D=is only available in 2D mode. +error.primitive3D=is only available in 3D mode. +error.procedure.must.be=must be a procedure name! +error.whattodo=I don't know what to do with +error.word= must be a word. +existe_deja= already exists. +faux="false +ferme_editeur=Close the editor window. +fichier_du_type=File format: +fichiers = File(s) +fichiers_logo=Logo Files +fichiers_rtf = Files RTF +file_100K=To prevent memory overflow, file\nsize can't exceed 100 KB. +fin=end +fin_flux = There's no characters to read in the flow n\u00b0 +find_replace=Replace/Find +find=Find +flux_ecriture = I can't write in this flow. +flux_existant =is a flow already open. You must close this flow before using this identifier. +flux_lecture = I can't read this flow. +flux_non_disponible =No flow has the identifier +forme_crayon = Pen shape +forward=Forward +gui_exists=The following graphical component already exists: +haut = High +hollandais=Dutch +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=Image Files +images=Images +imprimer_editeur=Print the editor +interrompre_execution=Stop the current task +je_ne_sais_pas=I don't know how to do +line=line +lire_editeur=Update and close editor +liste_vide = The list is empty. +mainCommand=Main Command: +memoire=Memory allocation (MB) +menu.edition.copy=Copy Ctrl+C +menu.edition.cut=Cut Ctrl+X +menu.edition.paste=Paste Ctrl+V +menu.edition.selectall = Select All Ctrl+A +menu.edition=Edit +menu.file.captureimage.clipboard = Copy To Clipboard +menu.file.captureimage.print=Print... +menu.file.captureimage=Image +menu.file.open=Open +menu.file.quit=Quit +menu.file.save=Save +menu.file.saveas=Save As +menu.file.textzone = Text +menu.file.textzone.rtf = Save As... (RTF format) +menu.file=File +menu.help.about=About XLogo +menu.help.licence=Licence +menu.help.online=Online manual +menu.help.translatedlicence=Translation of Licence +menu.help.translatexlogo=Translate XLogo +menu.help=Help +menu.tools.eraser=Procedure Eraser +menu.tools.pencolor=Pen Color +menu.tools.preferences=Preferences +menu.tools.screencolor=Screen Color +menu.tools.startup=Start Up File +menu.tools.translate = Code Translator +menu.tools=Tools +message_a_propos1=XLogo version: +message_a_propos2=Web site: +message_a_propos3=You can contact me at: +messages=Messages +mot_vide = The word must contain at least one character. +n_aime_pas = doesn't like [ +nb_tortues = Maximum number of turtles +ne_renvoie_pas= doesn't output to +no_gui=The following graphical component doesn't exist: +no_host=Problem during network communication with the computer whose address is: +nom_du_fichier=File name: +nombre_unicode = must be between 0 and 65535. +normal = Normal +note.do = doh +note.fa = fah +note.la = lah +note.mi = me +note.re = ray +note.si = te +note.sol = soh +nouveau = New +nouveau_dossier = Create a new folder +ouvrir_editeur=Open the editor +parcourir=Browse... +parenthese_fermante= ) couldn't be placed here. +parenthese_ouvrante=I'm waiting for (. +parenthese_vide=There's nothing between ( and ) ! +pas_argument= is not a valid argument. +pas_assez_de=Not enough inputs to +pas_entier= isn't an integer ! +pas_liste = is not a list. +pas_nombre = isn't a number ! +pas_predicat= must be true or false. +pas=Distance +pb_port=Unable to connect to the port: +pencolor=Default pen color +pour=to +pref.cancel=Cancel +pref.font=Font +pref.general=General +pref.general.arabic=Arabic +pref.general.aspect=Skin +pref.general.asturian = Asturian +pref.general.catalan=Catalan +pref.general.english=English +pref.general.esperanto= Esperanto +pref.general.fast=Fast +pref.general.french=French +pref.general.galician=Galician +pref.general.german=German +pref.general.greek=Greek +pref.general.hungarian=Hungarian +pref.general.italian=Italian +pref.general.lang=Language +pref.general.metal=Metal +pref.general.motif=Motif +pref.general.portuguese= Portuguese +pref.general.slow=Slow +pref.general.spanish=Spanish +pref.general.speed=Turtle's speed +pref.general.windows=Native +pref.highlight.comment= Comments +pref.highlight.enabled=Activate Syntax Highlighting +pref.highlight.example=# This is a comment\n repeat 4 [forward 100 right 90] +pref.highlight.init= Defaults +pref.highlight.operand= Variables, words, numbers +pref.highlight.other= Other... +pref.highlight.parenthesis= Brackets, square brackets +pref.highlight.primitive= Primitives +pref.highlight=Highlighter +pref.ok= OK +pref.options.tcp=TCP port number: +pref.options=Options +pref.options.eraseVariables=Clear variables when closing the editor +pref.sound.instruments=Available instruments: +pref.sound.problem= I can't detect the MIDI interface ! +pref.sound=Sound +pref.turtles=Turtle +primitives=Primitives +probleme_sequence =I can't understand your musical sequence, please verify it ! +procedure_demarrage=Command to execute on startup: +procedure_list=Procedures: +procedure_vide =Procedure names can't be empty ! +qualite_dessin=Drawing quality +quit_editeur=Close the editor without updating +quitter? = Are you sure you want to quit? +rechercher_dans=Look in: +relancer =Then quit XLogo and relaunch to update changes. +repertoire_accueil= Home directory +repertoires = Folder(s) +replace=Replace +replaceall=Replace all +replacewith=Replace with: +restaurer = Reset +rgb = RGB +rond= Round +rouge = Red +screencolor=Default screen color +seule_tortue_dispo=You can't delete the only active turtle ! +stop_chat=<<<<< End of chat >>>>> +stop=Stop +string_not_found=String not found. +style.bold= Bold +style.exposant = Superscript +style.italic= Italic +style.none= None +style.strike= Strike +style.subscript= Subscript +style.underline= Underline +taille_dessin = Screen size +title_axis=Background Axis +titredialogue2=Saving image now... +too_much_arguments=Too many arguments within parenthesis. +tortue_inaccessible=I can't create a turtle with the specified number ! +traduire =Translate ! +traduire_de=Translate from: +translatecomplete=Complete a translation +translateconsult= Consult available translations +translatecreate= Create a new translation +translatemessage=When all fields are completed for each tab, click on the button "OK". Send me the generated file at [email protected] +translatemodify= Modify a translation +translatewant=You want to: +un_caractere = must contain exactly one character. +uniform_color=Uniform Color +variable_vide=Variable names can't be empty ! +vers=To: +vert = Green +vrai="true +xgrid=X Grid +y_a_pas = There isn't +ygrid=Y Grid +ws.settings.require_password=Protect workspace settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace_label=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.workspace.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Thank you! You just uncovered a nasty Bug! +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand the variables declaration. Maybe there is a ":" missing? +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_eo_EO.properties b/logo/src/langage_eo_EO.properties new file mode 100644 index 0000000..881d94c --- /dev/null +++ b/logo/src/langage_eo_EO.properties @@ -0,0 +1,437 @@ +3d.viewer=3D-vidilo +3d.fog=Nebulo +3d.fog.backdistance=Tuta opakeca distanco +3d.fog.density=Denseco +3d.fog.exponential=Densa nebulo +3d.fog.frontdistance=Bruma komenco +3d.fog.linear=Grada nebulo +3d.fog.none=Neniu +3d.fog.type=Nebuleco: +3d.light=Lumo +3d.light.ambient=Media lumo +3d.light.angle=Angulo: +3d.light.apply=Efektivigu +3d.light.direction=Direkto +3d.light.directional=Unudirekta fonto +3d.light.none=Neniu lumo +3d.light.point=Punkta fonto +3d.light.position=Situo +3d.light.spot=Lummakulo +3d.light.type=Lumeco +active_grid=Funkciante +active_xaxis=X-akso +active_yaxis=Y-akso +ajouter=Almetu +animation_active = La movada moduso estas aganta. +apercu=Vido +attend_positif=Bezonas pozitivan valoron. +backward=Malanta\u016den +bas = Eta +bleu=Blua +bordermotif=Bordera motivo: +caractere_special_variable = Varianta nomo ne povas +caractere_special1=En la programeraj nomoj ne eblas +caractere_special2=havi tielajn tipojn \ + - * / ( ) [ ]=< > & | : +caractere_special3=Alie nomu +carre=kvadrata +chaine_trop_longue = Ne eblas afi\u015di liston a\u016d vorton enhavantan pli ol 32000 literojn. +chat=Diskutilo +chemin=Vojo +color_3_arguments=necesas tri argumentojn: [ru\u011da verda blua] +commande=Komando : +comme_parametre=] kiel parametro. +couleur_du_crayon=Skribila koloro +couleur_du_fond=Fona koloro +dans=En +definir=Vi \u0135us difinis +depassement_memoire = La programaro nun okupas pli ol 90 % en la disponebla memorejo. La mendata komando estas haltonta por preventi memoran troplenigon. Kontrolu : eble via programo senfine turni\u011das. Se ne, pligrandigu la memoran enhavecon atribuatan al XLogo. +dernier=Lasta +direction=Direkto +division_par_zero=Ne eblas dividi per 0 ! +dossier_parent=Supreniras unu nivelon +draw_grid=Dratreto en ekranfono +echantillon_texte=Teksta specimeno +echantillon=Specimenoj +editeur=Programpa\u011do +effacer_editeur=Vi\u015di la grafikejon elirante la programpa\u011don +element_dans_liste=eroj en la listo [ +enlever=Formetu +enregistreimage=Konservu la bildon nome de ... +enregistrer_espace=\u0108u vi volas vi\u015di la programpa\u011don ? +entre_zero_un = devas intervalori 0 kaj 1. +epaisseur_crayon=Maksimuma skribila diko +erreur_compteur = Ne estas komputebla el ripeta proceduro. +erreur_crochet=Krampa eraro : ] atendata +erreur_editeur=Ne eblas konservi \u0109iujn programerojn.\nKontrolu la arojn POR ... FINO kaj\nla korektan difinadon de la variantoj :a :b , ktp. +erreur_fixestyle = stilon_provizu nur ekajn argumentojn: Neniun, Dikigu, Substreke, Kursive, eksponente a\u016d indice. +erreur_format_image=Nur estas akcepteblaj la bildaj dosieroj *.png et *.jpg dosieroj +erreur_memoire = XLogo ne havas sufi\u0109an memoron por krei la mendatan bildon. En la langeto Elektebloj, pligrandigu la memorejon \u011dis : +erreur_nom_nombre_procedure = Programera nomo ne povas esti nombro ! +erreur_nom_nombre_variable = Varianta nomo ne povas esti nombro ! +erreur_pas_repertoire=ne estas valida registro ! +erreur_repetepour = nur tri a\u016d kvar erojn povas enhavi [variablon, komencon, finon, alkalkuleron]. +erreur_retourne= \u00ab\u00a0sendu\u00a0\u00bb ne estas uzebla ekster programero ! +erreur_sortie1=La testudo transpa\u015dis la desegnujon. +erreur_sortie2=Kiom da pa\u015doj anta\u016d eliro : +erreur_stop=Bezonas uzi \u00ab\u00a0haltu\u00a0\u00bb interne de programero a\u016d de ripetujo ! +erreur_tcp = La reta komuniko problemas. +erreur_variable=ne estas valida varianto ! +erreur=ERARO +error_bad_values=nur akceptas la jenajn valora\u0135ojn: +error.3d.3vertex=Poligono devas esti almena\u016d trivertica! +error.3d.emptypolygon=Poligona areo devas esti nenula! +error.ioecriture=Eniga/eliga problemo : ne estas konservebla. +error.iolecture=Neeblas legi la mendatan dosieron. +error.ne_peut_etre=ne povas esti tiel lokata. +error.novalue=ne havas valoron. +error.primitive2D=nur estas uzebla en 2D moduso. +error.primitive3D=nur estas uzebla en 3D moduso. +error.procedure.must.be=devas esti programero +error.whattodo=Kiel uzi +error.word=devas esti vorto. +existe_deja=jam ekzistas. +faux="malvera +ferme_editeur=Unue fermu la programpa\u011don. +fichier_du_type=Dosiera speco +fichiers_logo=LOGOaj dosieroj +fichiers_rtf = RTF dosierojn +fichiers=Dosiero(j) +file_100K=Por eviti memorajn troplenigojn, la bildaj dosieroj ne devas plivaloras 100 ko. +fin_flux=Neniu legota litero estas en la flukso numero +fin=fino +find_replace=Ser\u0109u/Anstata\u016digu +find=Ser\u0109u +flux_ecriture=Tiu malferma flukso ne estas uzebla dum skribado. +flux_existant=Jam dezignas malferman flukson. Komencu fermi tiun flukson anta\u016d povi reuzi tiun identigilon. +flux_lecture=Tiu malferma flukso ne estas uzebla dum legado. +flux_non_disponible=Neniu malferma flukso havas la identigilon +forme_crayon=Formo de la skribila pinto +forward=Anta\u016den +gui_exists=La jena grafikero jam ekzistas: +haut = Ega +hollandais = Nederlanda +hsb=HSB +hsbbleu=B +hsbrouge=H +hsbvert=S +imagefile=Bildaj dosieroj +images=Bildoj +imprimer_editeur=Presu la programpa\u011don +interrompre_execution=Interrompu la farantan ekzekutadon +je_ne_sais_pas=Mi ne scias kiel fari : +line=linio +lire_editeur=Konservu la \u015dangojn kaj adia\u016du +liste_vide=La listo estas malplena. +mainCommand=Startiga komando: +memoire = Memorejo atribuata al XLogo (Mo) : +menu.edition.copy=Kopiu Ctl-C +menu.edition.cut=Fortran\u0109u Ctl-X +menu.edition.paste=Algluu Ctl-V +menu.edition.selectall = Selektu \u0109ion. +menu.edition=Tekstaj iloj +menu.file.captureimage.clipboard=Kopiu la bildon en la kopidosiero. +menu.file.captureimage.print=Presu la bildon +menu.file.captureimage=Kaptu la bildon +menu.file.open=Malfermu +menu.file.quit=Adia\u016do +menu.file.save=Konservu +menu.file.saveas=Konservu subnome ... +menu.file.textzone = Teksta zono +menu.file.textzone.rtf = Registru la\u016d RTF formo +menu.file=Dosiero +menu.help.about=Rilate... +menu.help.licence=Permesilo +menu.help.online=Reta lernolibro +menu.help.translatedlicence=Esperanta traduko de la permesilo +menu.help.translatexlogo=Traduku XLOGon +menu.help=Helpo +menu.tools.eraser=Programa administrilo +menu.tools.pencolor=Elektu la skribilan koloron +menu.tools.preferences=Preferoj +menu.tools.screencolor=Elektu la fonan koloron +menu.tools.startup=Difini la startajn dosierojn... +menu.tools.translate=Traduku programerojn +menu.tools=Agordaj iloj +message_a_propos1=XLOGOa versio : +message_a_propos2=TTT-pa\u011daro : +message_a_propos3= Ne hezitu kontakti min : +messages=Mesa\u011doj +mot_vide = Almena\u016d unu literon devas havi la vorto. +n_aime_pas=ne \u015datas [ +nb_tortues=Maksimuma nombro de testudoj +ne_renvoie_pas=ne sendas valoron. +no_gui=La jena grakikero ne ekzistas: +no_host=Komunikada problemo kun la komputilo adrese de: +nom_du_fichier=Dosiera nomo : +nombre_unicode = devas intervalori 0 kaj 65535. +normal = Normala +note.do=C +note.fa=F +note.la=A +note.mi=E +note.re=D +note.si=B +note.sol=G +nouveau_dossier=Kreas novan dosieron +nouveau=Nova +ouvrir_editeur=Malfermu la programpa\u011don +parcourir=Trarigardu... +parenthese_fermante=) ne povas esti lokata tie. +parenthese_ouvrante=Necesas krampon ( . +parenthese_vide=La enhavo de la krampoj estas malplena ! +pas_argument=ne estas akceptebla parametro. +pas_assez_de=Mankas parametroj por +pas_entier=ne estas entjero ! +pas_liste=ne estas listo. +pas_nombre=ne estas nombro ! +pas_predicat=Necesas egali \u00ab\u00a0vera\u00a0\u00bb a\u016d \u00ab\u00a0malvera\u00a0\u00bb. +pas=Skalo +pb_port=Ne eblas a\u016dskulti en la pordo: +pencolor = Prefera skribkoloro +pour=por +pref.cancel=Nuligu +pref.font=Tiparo +pref.general.arabic=Araba +pref.general.aspect=Aspekto +pref.general.asturian = Astura +pref.general.catalan=Kataluna +pref.general.english=Angla +pref.general.esperanto=Esperanta +pref.general.fast=Rapida +pref.general.french=Franca +pref.general.galician=Galega +pref.general.german=Germana +pref.general.greek=Greka +pref.general.hungarian=Hungara +pref.general.italian=Itala +pref.general.lang=Lingvo +pref.general.metal=Metale +pref.general.motif=Motivo +pref.general.portuguese=Portugala +pref.general.slow=Malrapida +pref.general.spanish=Hispana +pref.general.speed=Movebleco +pref.general.windows=Denaske +pref.general=\u0108efaj elektoj +pref.highlight.comment= Komentigu +pref.highlight.enabled= Sintakse kolorigu +pref.highlight.example= # Tio estas komento \n ripetu 4[avance 100 td 90]\n +pref.highlight.init= Rekomencigu +pref.highlight.operand= Variablojn, vortojn, nombrojn... +pref.highlight.other= Alian... +pref.highlight.parenthesis= Krampigu +pref.highlight.primitive= Primitivigu +pref.highlight= Kolorigu +pref.ok=Validigu +pref.options=Elektebloj +pref.options.tcp=TCP konekteja numero: +pref.options.eraseVariables=Vi\u015du la variablojn kiam oni eliras la programpa\u011don. +pref.sound.instruments=Disponeblaj instrumentoj +pref.sound.problem=Detektoproblemo de la MIDI interfaco +pref.sound=Sono +pref.turtles=Elektu vian testudon +primitives=Bazaj programeroj +probleme_sequence=La muzika sekvenco estas nekomprenebla: korektu la erarojn ! +procedure_demarrage=Starta komando : +procedure_list = Programa listo +procedure_vide = Programera nomo ne povas esti senenhava. +qualite_dessin = Desegna precizeco : +quit_editeur=Fermu la programpa\u011don sen registri +quitter?=Tuja adia\u016do... +rechercher_dans=Ser\u0109u en : +relancer = Poste, restartigu la programaron por validigi la \u015dan\u011dojn. +repertoire_accueil=Akcepteja registro +repertoires=Registroj +replace=Anstata\u016digu +replaceall=Anstata\u016digu \u0109ion +replacewith=Anstata\u016digu per: +restaurer=Riparu +rgb=RVB +rond=ronda +rouge=Ru\u011da +screencolor = Prefera fonkoloro +seule_tortue_dispo=Vi ne povas elimini la solan aktivan testudon ! +stop_chat=<<<<< Komunikada fino >>>>> +stop=Haltu +string_not_found=Ne estas trovebla. +style.bold= Dike +style.exposant = Eksponente +style.italic= Kursive +style.none=Simple +style.strike=Forstreke +style.subscript= Indice +style.underline= Substreke +taille_dessin=Grafikeja grandeco +title_axis=Ekranfona akso +titredialogue2=La bildo estas skribata +too_much_arguments=Estas troaj parametroj inter la krampoj. +tortue_inaccessible=Ne eblas krei testudon per la indikita nombro ! +traduire_de=Traduku el : +traduire=Traduku ! +translatecomplete=Kompletigi tradukeron +translateconsult=Konsulti la diversajn tradukojn +translatecreate=Krei novan tradukeron +translatemessage=Kiam la kampoj estas kompletigaj en la du langetoj, alklaku en la validiga butono, kaj sendu la generatan dosieron al la mia adreso: [email protected] +translatemodify=\u015can\u011di tradukeron +translatewant=Vi deziras: +un_caractere = devas enhavi unu leteron. +uniform_color=Unukolora bordero: +variable_vide = Varianta nomo ne povas esti senenhava. +vers=Al : +vert=Verda +vrai="vera +xgrid=\u0108ela amplekso: +y_a_pas=Ne estas +ygrid=\u0108ela alteco: +editor.redo=Refaru +editor.undo=Nuligu +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_es_ES.properties b/logo/src/langage_es_ES.properties new file mode 100644 index 0000000..c7b49a6 --- /dev/null +++ b/logo/src/langage_es_ES.properties @@ -0,0 +1,437 @@ +3d.fog.backdistance=Distancia de opacidad total +3d.fog.density=Densidad: +3d.fog.exponential=Niebla densa +3d.fog.frontdistance=Distancia a la bruma +3d.fog.linear=Niebla lineal +3d.fog.none=Ninguna +3d.fog.type=Tipo de niebla: +3d.fog=Niebla +3d.light.ambient=Luz ambiental +3d.light.angle=\u00c1ngulo: +3d.light.apply=Aplicar +3d.light.direction=Direcci\u00f3n +3d.light.directional=Luz direccional +3d.light.none=Apagar la luz +3d.light.point=Punto de luz +3d.light.position=Posici\u00f3n +3d.light.spot=Foco +3d.light.type=Tipo de luz: +3d.light=Iluminaci\u00f3n +3d.viewer = Visor 3D +active_grid = Activa +active_xaxis = Eje de abscisas (Eje X) +active_yaxis = Eje de ordenadas (Eje Y) +ajouter = A\u00f1adir +animation_active = El modo Animaci\u00f3n ya est\u00e1 activo. +apercu = Idea general +attend_positif = espera un n\u00famero positivo. +backward = Hacia atr\u00e1s +bas = Bajo +bleu = Azul +bordermotif = Marco de adorno +caractere_special_variable = El nombre de una variable no puede incluir +caractere_special1 = Los nombres de procedimiento no pueden incluir +caractere_special2 = caracteres como \ + - * / ( ) [ ] = < > & | : +caractere_special3 = Cambia el nombre del procedimiento. +carre = Cuadrado +chaine_trop_longue = No puedo imprimir una palabra o una lista con m\u00e1s de 32000 caracteres. +chat = Chat +chemin = Ruta +color_3_arguments = necesita una lista de tres elementos, [rojo verde azul] +commande = Comando +comme_parametre = ] como argumento. +couleur_du_crayon = Color del l\u00e1piz +couleur_du_fond = Color de fondo (papel) +dans = En +definir = Acaba de definir +depassement_memoire = Esta aplicaci\u00f3n ha tomado un 90% de la memoria disponible.\n La secuencia ha sido detenida para no desbordar la pila de datos.\n Aseg\u00farate de que el programa no tiene un bucle infinito, o aumenta la cantidad de memoria disponible. +dernier = Ultimo +direction = Sentido +division_par_zero = \u00a1No puedes dividir por cero! +dossier_parent = Directorio padre +draw_grid = Cuadr\u00edcula en el fondo (papel) +echantillon = Muestra +echantillon_texte = Muestra de texto +editeur = Editar +editor.redo=Rehacer +editor.undo=Deshacer +effacer_editeur = Borrar la pantalla al salir del editor +element_dans_liste = palabras en la lista [ +enlever = Eliminar +enregistreimage = Guardar la imagen como ... +enregistrer_espace = \u00bfEliminar las variables y los procedimientos ? +entre_zero_un = Debe estar comprendido entre 0 y 1. +epaisseur_crayon = Tama\u00f1o m\u00e1ximo del l\u00e1piz +erreur = ERROR +erreur_compteur = cuentarepite no es v\u00e1lido fuera de un bucle repite. +erreur_crochet = Error de corchete: se esperaba ] +erreur_editeur = Imposible guardar todos los procedimientos.\nComprueba los bloques PARA .... FIN\ny la correcta definici\u00f3n de las variables :a :b etc +erreur_fixestyle=ponestilo s\u00f3lo puede aceptar los valores: ninguno, negrita, subrayado, cursiva, tachado, super\u00edndice, sub\u00edndice. +erreur_format_image = Los \u00fanicos archivos para imagen son los de formato *.png y *.jpg +erreur_memoire = XLogo no tiene suficiente memoria para crear la imagen deseada.\nAumenta el tama\u00f1o de memoria disponible. +erreur_nom_nombre_procedure = El nombre de un procedimiento no puede ser un n\u00famero +erreur_nom_nombre_variable = El nombre de una variable no puede ser un n\u00famero +erreur_pas_repertoire = no es un directorio correcto! +erreur_repetepour = Debe contener tres o cuatro elementos: [variable min max incremento] +erreur_retourne = S\u00f3lo puedes usar devuelve dentro de un procedimiento. +erreur_sortie1 = La tortuga sale de la pantalla. +erreur_sortie2 = N\u00famero de pasos antes de salir: +erreur_stop = S\u00f3lo puedes usar alto \u00fanicamente dentro de un procedimiento o de un bucle +erreur_tcp = Problema en comunicaci\u00f3n de red +erreur_variable = no es una variable v\u00e1lida! +error_bad_values = S\u00f3lo acepta valores +error.3d.3vertex = Un pol\u00edgono debe tener, al menos, tres v\u00e9rtices +error.3d.emptypolygon = El \u00e1rea de un pol\u00edgono no puede ser cero. +error.ioecriture = Problema de entrada-salida: No es posible guardar. +error.iolecture = Imposible leer el archivo deseado. +error.ne_peut_etre = no puede estar situado aqu\u00ed. +error.novalue = no tiene valor. +error.primitive2D = S\u00f3lo puede usarse en 2D +error.primitive3D = S\u00f3lo puede usarse en 3D +error.procedure.must.be=debe ser el nombre de un procedimiento! +error.whattodo = \u00bfQu\u00e9 hacer con +error.word = debe ser una palabra. +existe_deja = ya est\u00e1 definido. +faux = "falso +ferme_editeur = Cierra la ventana del editor. +fichier_du_type = Archivos de formato +fichiers = Archivo(s) +fichiers_logo = Archivos Logo +fichiers_rtf = Archivos RTF +file_100K = Para no superar la memoria disponible, la imagen no puede ocupar m\u00e1s de 100 kb. +fin = fin +fin_flux = No hay m\u00e1s caracteres para leer en el flujo n\u00b0 +find = Buscar +find_replace = Buscar/Reemplazar +flux_ecriture = No se puede escribir en este flujo. +flux_existant = ya designa un flujo abierto. Cierra el flujo abierto antes de reutilizar este identificador. +flux_lecture = No se puede leer desde este flujo. +flux_non_disponible = Este identificador no corresponde a ning\u00fan flujo abierto. +forme_crayon = Forma del l\u00e1piz +forward = Hacia delante +gui_exists = El componente gr\u00e1fico siguiente ya existe / ha sido definido +haut = Alto +hollandais = Holand\u00e9s +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile = Archivos de imagen +images = Im\u00e1genes +imprimer_editeur = Imprimir el editor +interrompre_execution = Detener la ejecuci\u00f3n en curso +je_ne_sais_pas = No s\u00e9 c\u00f3mo hacer +line = l\u00ednea +lire_editeur = Guardar los cambios y salir +liste_vide = La lista est\u00e1 vac\u00eda. +mainCommand = Comando de Inicio: +memoire = Memoria destinada a XLogo (Mb) +menu.edition = Edici\u00f3n +menu.edition.copy = Copiar Ctl-C +menu.edition.cut = Cortar Ctl-X +menu.edition.paste = Pegar Ctl-V +menu.edition.selectall = Seleccionar todo Ctrl +A +menu.file = Archivo +menu.file.captureimage = Capturar la imagen +menu.file.captureimage.clipboard = Copiar al portapapeles +menu.file.captureimage.print = Imprimir la imagen +menu.file.open = Abrir +menu.file.quit = Salir +menu.file.save = Guardar +menu.file.saveas = Guardar como +menu.file.textzone = Zona de texto +menu.file.textzone.rtf = Guardar en formato RTF +menu.help = Ayuda +menu.help.about = Acerca de XLogo ... +menu.help.licence = Licencia +menu.help.online=Manual en l\u00ednea +menu.help.translatedlicence = Traducci\u00f3n de la licencia +menu.help.translatexlogo = Traducir XLogo +menu.tools = Herramientas +menu.tools.eraser = Borra procedimiento +menu.tools.pencolor = Elegir color de l\u00e1piz +menu.tools.preferences = Preferencias +menu.tools.screencolor = Elegir color de fondo (papel) +menu.tools.startup = Definir los archivos de inicio... +menu.tools.translate = Traducir procedimientos +message_a_propos1 = Versi\u00f3n de XLogo: +message_a_propos2 = Sitio web: +message_a_propos3 = Puedes escribirme a: +messages = Mensajes +mot_vide = La palabra debe contener al menos un caracter. +n_aime_pas = no acepta [ +nb_tortues = N\u00famero m\u00e1ximo de tortugas +ne_renvoie_pas = no di\u00f3 ning\u00fan valor a +no_gui = El componente gr\u00e1fico siguiente no existe / no ha sido definido +no_host = Problemas durante la comunicaci\u00f3n en red con el ordenador en direcci\u00f3n: +nom_du_fichier = Nombre del archivo: +nombre_unicode = debe estar comprendido entre 0 y 65535. +normal = Normal +note.do = do +note.fa = fa +note.la = la +note.mi = mi +note.re = re +note.si = si +note.sol = sol +nouveau = Nuevo +nouveau_dossier = Crear un nuevo directorio +ouvrir_editeur = Entrar en el editor +parcourir = Buscar... +parenthese_fermante = ) no puede estar aqu\u00ed. +parenthese_ouvrante = Se esperaba un par\u00e9ntesis ( +parenthese_vide = No hay nada entre par\u00e9ntesis! +pas = Escala +pas_argument = no es una entrada correcta. +pas_assez_de = No hay suficientes datos para +pas_entier = no es un n\u00famero entero! +pas_liste = no es una lista. +pas_nombre = no es un n\u00famero! +pas_predicat = debe ser cierto o falso. +pb_port = Imposible conectarse en el puerto: +pencolor = Color de l\u00e1piz predeterminado +pour = para +pref.cancel = Cancelar +pref.font = Fuente +pref.general = General +pref.general.arabic = \u00c1rabe +pref.general.aspect = Aspecto +pref.general.asturian=Asturiano +pref.general.catalan=Catal\u00e1n +pref.general.english = Ingl\u00e9s +pref.general.esperanto = Esperanto +pref.general.fast = R\u00e1pido +pref.general.french = Franc\u00e9s +pref.general.galician = Gallego +pref.general.german = Alem\u00e1n +pref.general.greek=Griego +pref.general.hungarian=H\u00fangaro +pref.general.italian=Italiano +pref.general.lang = Idioma +pref.general.metal = Metal +pref.general.motif = Motif +pref.general.portuguese = Portugu\u00e9s +pref.general.slow = Lento +pref.general.spanish = Espa\u00f1ol +pref.general.speed = Velocidad de la tortuga +pref.general.windows = Windows +pref.highlight = Resaltado +pref.highlight.comment = Comentarios +pref.highlight.enabled = Activa el resaltado de sintaxis +pref.highlight.example = # Esto es un comentario\n repite 4 [avanza 100 giraderecha 90]\n +pref.highlight.init = Predeterminado +pref.highlight.operand = Variables, palabras, n\u00fameros +pref.highlight.other = Otro... +pref.highlight.parenthesis = Par\u00e9ntesis, corchetes +pref.highlight.primitive = Primitiva +pref.options.tcp=n�mero del puerto TCP: +pref.options.eraseVariables=Borra las variables cuando se cierra el editor. +pref.ok = Si +pref.options = Opciones +pref.sound = sonido +pref.sound.instruments = Instrumentos disponibles +pref.sound.problem = Problema con el MIDI del ordenador +pref.turtles = Elecci\u00f3n de la tortuga +primitives = Primitivas +probleme_sequence = No puedo entender la serie de notas: corrige los errores +procedure_demarrage = Comando ejecutado al inicio: +procedure_list = Lista procedimientos +procedure_vide = El nombre de un procedimiento no puede ser nulo +qualite_dessin = Calidad que se aplica al dibujo +quit_editeur = Salir del editor sin guardar los cambios +quitter? = \u00bfDeseas salir? +rechercher_dans = Buscar en: +relancer = Luego reinicia XLogo para aplicar los cambios. +repertoire_accueil = Directorio de destino +repertoires = Directorio(s) +replace = Reemplazar +replaceall = Reemplazar todo +replacewith = Reemplaza con: +restaurer = Restaurar +rgb = RVA +rond = Redondo +rouge = Rojo +screencolor = Color de papel predeterminado +seule_tortue_dispo = \u00a1No puedes eliminar la \u00fanica tortuga disponible! +stop = Alto +stop_chat = <<<<< Fin del chat >>>>> +string_not_found = Elemento no encontrado +style.bold = Negrita +style.exposant =Super\u00edndice +style.italic = Cursiva +style.none = Ninguno +style.strike = Tachado +style.subscript =Sub\u00edndice +style.underline = Subrayado +taille_dessin = Tama\u00f1o de la ventana para dibujar +title_axis = Ejes cartesianos +titredialogue2 = Escritura de la imagen en curso. +too_much_arguments = Demasiados argumentos entre los par\u00e9ntesis +tortue_inaccessible = \u00a1Es imposible crear una tortuga con ese n\u00famero! +traduire = Traducir! +traduire_de = Traducir de: +translatecomplete = Completar una traducci\u00f3n +translateconsult = Consultar las traducciones existentes +translatecreate = A\u00f1ade /Crea una nueva traducci\u00f3n +translatemessage = Cuando todos los campos est\u00e9n completos en las dos tablas, haz "click" en el bot\u00f3n "OK". Env\u00edame el archivo generado a [email protected] +translatemodify = Modificar una traducci\u00f3n +translatewant = Usted desea: +un_caractere = debe contener un caracter. +uniform_color = Color s\u00f3lido +variable_vide = El nombre de una variable no puede ser nulo. +vers = Hacia: +vert = Verde +vrai = "cierto +xgrid = Anchura de la cuadr\u00edcula +y_a_pas = No hay +ygrid = Altura de la cuadr\u00edcula +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_fr_FR.properties b/logo/src/langage_fr_FR.properties new file mode 100644 index 0000000..5939302 --- /dev/null +++ b/logo/src/langage_fr_FR.properties @@ -0,0 +1,437 @@ +3d.fog=Brouillard +3d.fog.density=Densit\u00e9 +3d.fog.none=Aucun +3d.fog.exponential=Brouillard dense +3d.fog.linear=Brouillard progressif +3d.fog.frontdistance=D�but de la brume +3d.fog.backdistance=Distance d'opacit� totale +3d.fog.type=Type de brouillard: +3d.light=Lumi\u00e8re +3d.light.type=Type d'\u00e9clairage: +3d.light.ambient=Lumi\u00e8re ambiante +3d.light.directional=Source unidirectionnelle +3d.light.point=Source ponctuelle +3d.light.none=Aucune lumi\u00e8re +3d.light.spot=Spot +3d.light.position=Position +3d.light.direction=Direction +3d.light.angle=Angle: +3d.light.apply=Appliquer +3d.viewer=Vue 3D +active_grid=Active +active_xaxis=Axe des abscisses +active_yaxis=Axe des ordonn�es +ajouter=Ajouter +animation_active = Le mode animation est activ\u00e9. +apercu = Aper\u00e7u +attend_positif = attend un argument positif. +backward=Arri�re +bas = Basse +bleu = Bleu +bordermotif=Motif de la bordure: +caractere_special_variable = Les noms de variable ne doivent pas +caractere_special1=Les noms de proc\u00e9dures ne doivent pas +caractere_special2=contenir de caract\u00e8res comme \ + - * / ( ) [ ] = < > & | : +caractere_special3=Renommez +carre = Carr\u00e9 +chaine_trop_longue = Je ne peux afficher une liste ou un mot ayant plus de 32000 caract\u00e8res. +chat=Discussion +chemin=Chemin +color_3_arguments= n\u00e9cessite trois arguments: [red green blue] +commande=Commande : +comme_parametre = ] comme param\u00e8tre. +couleur_du_crayon=Couleur du crayon +couleur_du_fond=Couleur du fond +dans=Dans +definir=Vous venez de d\u00e9finir +depassement_memoire = L'application occupe \u00e0 pr\u00e9sent plus de 90% de la place m\u00e9moire disponible.\nLa commande lanc\u00e9e va donc \u00eatre stopp\u00e9e afin de pr\u00e9venir un \u00e9ventuel d\u00e9bordement de m\u00e9moire.\nV\u00e9rifiez que votre programme ne boucle pas ind\u00e9finiment, sinon augmentez la capacit\u00e9 de m\u00e9moire allou\u00e9e \u00e0 XLogo. +dernier = Dernier +direction=Sens +division_par_zero = Vous ne pouvez effectuer une division par 0 ! +dossier_parent = Remonte d'un niveau +draw_grid=Grille en fond d'\u00e9cran +echantillon = Echantillons +echantillon_texte = Echantillon de texte +editeur=Editeur +editor.undo=Annuler la derni\u00e8re action +editor.redo=R�tablir +effacer_editeur= Effacer la zone de dessin lorsqu'on quitte l'\u00e9diteur +element_dans_liste= \u00e9l\u00e9ments dans la liste [ +enlever=Enlever +enregistreimage=Enregistrer l'image sous ... +enregistrer_espace = Effacer l'espace de travail ? +entre_zero_un = doit \u00eatre compris entre 0 et 1. +epaisseur_crayon = Epaisseur maximale du crayon +erreur=ERREUR +erreur_compteur = Pas de compteur en dehors d'une boucle repete. +erreur_crochet=Erreur de crochets : ] attendu +erreur_editeur=Impossible d'enregistrer toutes les proc\u00e9dures.\nV\u00e9rifiez les blocs POUR .... FIN et\nla bonne d\u00e9finitions des variables :a :b etc +erreur_fixestyle = fixestyle n'accepte que les valeurs suivantes pour arguments: aucun, gras, souligne, italique, exposant ou indice. +erreur_format_image=Les seuls fichiers image accept\u00e9s sont les fichiers *.png et *.jpg +erreur_memoire = XLogo ne dispose pas de la m\u00e9moire suffisante pour cr\u00e9er l'image demand\u00e9e.\nDans l'onglet Options, augmenter la taille de la m\u00e9moire \u00e0: +erreur_nom_nombre_procedure = Le nom d'une proc\u00e9dure ne peut \u00eatre un nombre ! +erreur_nom_nombre_variable = Le nom d'une variable ne peut \u00eatre un nombre ! +erreur_pas_repertoire = n'est pas un r\u00e9pertoire valide ! +erreur_repetepour = ne peut contenir que trois ou quatre \u00e9l\u00e9ments. [variable debut fin incr\u00e9ment] +erreur_retourne = retourne ne peut \u00eatre employ\u00e9 en dehors d'une proc\u00e9dure ! +erreur_sortie1=La tortue est sortie de la zone de dessin. +erreur_sortie2=Nombre de pas avant de sortir: +erreur_stop = stop doit \u00eatre employ\u00e9 \u00e0\u00a0 l'int\u00e9rieur d'une proc\u00e9dure ou \u00e0\u00a0 l'int\u00e9rieur d'une boucle ! +erreur_tcp=Probl\u00e8me de communication r\u00e9seau. +erreur_variable = n'est pas une variable valide! +error_bad_values=accepte seulement les valeurs suivantes: +error.3d.3vertex=Un polygone doit compter au moins trois sommets! +error.3d.emptypolygon=Un polygone doit poss\u00e9der une aire non nulle! +error.ioecriture=Probl\u00e8me d'entr\u00e9e-sortie : enregistrement impossible. +error.iolecture=Impossible de lire le fichier demand\u00e9. +error.ne_peut_etre= ne peut \u00eatre plac\u00e9 ainsi. +error.novalue= n'a pas de valeur. +error.primitive2D=n'est utilisable qu'en mode 2D. +error.primitive3D=n'est utilisable qu'en mode 3D. +error.procedure.must.be=doit \u00eatre une proc\u00e9dure! +error.whattodo=Que faire de +error.word= doit \u00eatre un mot. +existe_deja= existe d\u00e9j\u00e0\u00a0. +faux="faux +ferme_editeur=Fermez tout d'abord l'\u00e9diteur. +fichier_du_type = Fichiers du type +fichiers = Fichier(s) +fichiers_logo=Fichiers Logo +fichiers_rtf = Fichiers RTF +file_100K=Pour \u00e9viter des d\u00e9passements de m\u00e9moire, les fichiers\nimages ne doivent pas d\u00e9passer 100 Ko. +fin_flux = Il n'y a plus de caract\u00e8res \u00e0 lire dans le flux n\u00b0 +fin=fin +find_replace=Remplacer/Chercher +find=Chercher +flux_ecriture = Ce flux ouvert n'est pas utilisable en \u00e9criture. +flux_existant = d\u00e9signe d\u00e9j\u00e0 un flux ouvert. Commencer par fermer ce flux avant de pouvoir r\u00e9utiliser cet identifiant. +flux_lecture = Ce flux ouvert n'est pas utilisable en lecture. +flux_non_disponible = Aucun flux ouvert ne poss\u00e8de l'identifiant +forme_crayon = Forme de la mine du crayon +forward=Avant +gui_exists=Le composant graphique suivant existe d\u00e9j�: +haut = Haute +hollandais = Hollandais +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=Fichiers Image +images=Images +imprimer_editeur=Imprimer l'\u00e9diteur +interrompre_execution=Interrompre l'ex\u00e9cution en cours +je_ne_sais_pas=Je ne sais pas comment faire +line=ligne +lire_editeur=Enregistrer les modifications et quitter +liste_vide=La liste est vide. +mainCommand=Commande principale: +memoire = M\u00e9moire allou\u00e9e \u00e0 XLogo (Mo): +menu.edition.copy=Copier Ctl-C +menu.edition.cut=Couper Ctl-X +menu.edition.paste=Coller Ctl-V +menu.edition.selectall= Tout s\u00e9lectionner +menu.edition=Edition +menu.file.captureimage.clipboard=Copier l'image vers le presse-papiers +menu.file.captureimage.print=Imprimer l'image +menu.file.captureimage=Capturer l'image +menu.file.open=Ouvrir +menu.file.quit=Quitter +menu.file.save=Enregistrer +menu.file.saveas=Enregistrer sous +menu.file.textzone = Zone de texte +menu.file.textzone.rtf = Enregistrer au format RTF +menu.file=Fichier +menu.help.about=A propos... +menu.help.licence=Licence +menu.help.online=Manuel en ligne +menu.help.translatedlicence=Traduction francaise de la licence +menu.help.translatexlogo=Traduire XLogo +menu.help=Aide +menu.tools.eraser=Gestionnaire de proc\u00e9dures +menu.tools.pencolor=Choisir la couleur du crayon +menu.tools.preferences=Pr\u00e9f\u00e9rences +menu.tools.screencolor=Choisir la couleur du fond +menu.tools.startup=D\u00e9finir les fichiers de d\u00e9marrage... +menu.tools.translate=Traduire des proc\u00e9dures +menu.tools=Outils +message_a_propos1=XLOGO version : +message_a_propos2=Site web: +message_a_propos3=N'h\u00e9sitez pas \u00e0\u00a0 me contacter \u00e0\u00a0 +messages=Messages +mot_vide = Le mot doit contenir au moins un caract\u00e8re. +n_aime_pas = n'aime pas [ +nb_tortues = Nombre maximum de tortues +ne_renvoie_pas= ne renvoie pas de valeur \u00e0\u00a0 +no_gui=Le composant graphique suivant n'existe pas: +no_host=Probl\u00e8me de communication avec l'ordinateur situ\u00e9 \u00e0 l'adresse: +nom_du_fichier = Nom du Fichier : +nombre_unicode = doit \u00eatre compris entre 0 et 65535. +normal = Normale +note.do= do +note.fa = fa +note.la = la +note.mi = mi +note.re = re +note.si = si +note.sol = sol +nouveau = Nouveau +nouveau_dossier = Cr\u00e9 un nouveau dossier +ouvrir_editeur=Ouvrir l'\u00e9diteur +parcourir=Parcourir... +parenthese_fermante= Une parenth\u00e8se ) est attendue. +parenthese_ouvrante=Une parenth\u00e8se ( est attendue. +parenthese_vide=Le contenu des parenth\u00e8ses est vide ! +pas_argument= n'est pas un argument valide. +pas_assez_de=Pas assez de donn\u00e9es pour +pas_entier= n'est pas un entier ! +pas_liste = n'est pas une liste. +pas_nombre = n'est pas un nombre ! +pas_predicat= doit \u00eatre \u00e9gal \u00e0\u00a0 vrai ou faux. +pas=Pas +pb_port=Impossible d'�couter sur le port: +pencolor=Couleur du crayon (par d\u00e9faut) +pour=pour +pref.cancel=Annuler +pref.font= Police +pref.general.arabic=Arabe +pref.general.aspect=Aspect +pref.general.asturian = Asturien +pref.general.catalan=Catalan +pref.general.english=Anglais +pref.general.esperanto= Esperanto +pref.general.fast=Rapide +pref.general.french=Francais +pref.general.galician=Galicien +pref.general.german=Allemand +pref.general.greek=Grec +pref.general.hungarian=Hongrois +pref.general.italian=Italien +pref.general.lang=Langue +pref.general.metal=Metal +pref.general.motif=Motif +pref.general.portuguese= Portugais +pref.general.slow=Lent +pref.general.spanish=Espagnol +pref.general.speed=Vitesse de d\u00e9filement +pref.general.windows=Natif +pref.general=G\u00e9n\u00e9ral +pref.highlight.comment= Commentaires +pref.highlight.enabled= Activer la coloration syntaxique +pref.highlight.example= # Ceci est un commentaire\n repete 4[avance 100 td 90]\n +pref.highlight.init= R\u00e9initialiser +pref.highlight.operand= Variables, mots, nombres +pref.highlight.other= Autre... +pref.highlight.parenthesis= Crochets, parenth\u00e8ses +pref.highlight.primitive= Primitives +pref.highlight= Coloration +pref.options.tcp=Num�ro de port TCP: +pref.ok= OK +pref.options=Options +pref.options.eraseVariables=Effacer les variables lorsqu'on quitte l'\u00e9diteur +pref.sound.instruments= Instruments disponibles +pref.sound.problem= Probl\u00e8me de d\u00e9tection de l'interface MIDI +pref.sound= Son +pref.turtles= Choix de tortue +primitives=Primitives +probleme_sequence = La s\u00e9quence musicale n'est pas compr\u00e9hensible: corrigez les erreurs ! +procedure_demarrage=Commande \u00e0 ex\u00e9cuter au d\u00e9marrage: +procedure_list=Liste des proc\u00e9dures: +procedure_vide = Le nom d'une proc\u00e9dure ne peut pas \u00eatre vide. +qualite_dessin = Pr\u00e9cision du trac\u00e9: +quit_editeur=Quitter l'\u00e9diteur sans enregistrer les modifications +quitter? = D\u00e9sirez vous quitter? +rechercher_dans = Rechercher dans : +relancer = Puis relancer l'application pour prendre en compte les modifications. +repertoire_accueil= R\u00e9pertoire d'accueil +repertoires = R\u00e9pertoire(s) +replace=Remplacer +replaceall=Remplacer tout +replacewith=Remplacer par: +restaurer = Restaurer +rgb = RVB +rond= Rond +rouge = Rouge +screencolor=Couleur de l'\u00e9cran (par d\u00e9faut) +seule_tortue_dispo= Vous ne pouvez \u00e9liminer la seule tortue active ! +stop_chat=<<<<< Fin de communication >>>>> +stop= Stop +string_not_found=El\u00e9ment non trouv\u00e9. +style.bold= Gras +style.exposant = exposant +style.italic= Italique +style.none= Aucun +style.strike= barre +style.subscript= indice +style.underline= Souligne +taille_dessin = Taille de la zone de dessin +title_axis=Axe en fond d'�cran +titredialogue2=Ecriture de l'image en cours +too_much_arguments=Trop d'arguments dans les parenth�ses. +tortue_inaccessible= Il est impossible de cr\u00e9er une tortue avec le num\u00e9ro indiqu\u00e9 ! +traduire = Traduire! +traduire_de = Traduire de: +translatecomplete=Compl�ter une traduction +translateconsult= Consulter les diff�rentes traductions +translatecreate= Cr�er une nouvelle traduction +translatemessage=Une fois que les champs sont compl�t�s pour chacun des deux onglets, cliquez sur le bouton "OK". Envoyez moi le fichier g�n�r� � [email protected] +translatemodify= Modifier une traduction +translatewant=Vous d�sirez: +un_caractere = doit contenir un seul caract\u00e8re. +uniform_color=Couleur unie: +variable_vide = Le nom d'une variable ne peut pas \u00eatre vide. +vers = Vers: +vert = Vert +vrai="vrai +xgrid=Largeur d'un carreau: +y_a_pas = Il n'y a pas +ygrid=Hauteur d'un carreau: +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_gl_ES.properties b/logo/src/langage_gl_ES.properties new file mode 100644 index 0000000..1f1a56e --- /dev/null +++ b/logo/src/langage_gl_ES.properties @@ -0,0 +1,437 @@ +3d.fog=N\u00e9boa +3d.fog.backdistance=Distancia de opacidade total +3d.fog.density=Densidade: +3d.fog.exponential=N\u00e9boa mesta +3d.fog.frontdistance=Distancia \u00e1 br\u00e9tema +3d.fog.linear=N\u00e9boa li\u00f1al +3d.fog.none=Ningunha +3d.fog.type=Tipo de n\u00e9boa: +3d.light=Iluminaci\u00f3n +3d.light.ambient=Luz ambiente +3d.light.angle=\u00c1ngulo: +3d.light.apply=Aplicar +3d.light.direction=Direci\u00f3n +3d.light.directional=Luz direcional +3d.light.none=Apagar luz +3d.light.point=Punto de luz +3d.light.position=Posici\u00f3n +3d.light.spot=Foco +3d.light.type=Tipo de luz: +3d.viewer=Visor 3D +active_grid=Activa +active_xaxis=Eixo de abscisas (Eixo X) +active_yaxis=Eixo de ordenadas (Eixo Y) +ajouter=Engadir +animation_active=O modo Animaci\u00f3n xa est\u00e1 activo. +apercu=Idea xeral +attend_positif=espera por un n\u00famero positivo. +backward=Cara a atr\u00e1s +bas=Baixo +bleu=Azul +bordermotif=Marco de adorno +caractere_special_variable=O nome dunha variable non pode inclu\u00edr +caractere_special1=O nome dos procedementos non pode levar +caractere_special2=caracteres como \ + - * / ( ) [ ] = < > & | : +caractere_special3=Cambia o nome do procedemento +carre=Cadrado +chaine_trop_longue=Non podo imprimir unha palabra ou unha lista con m\u00e1is de 32000 car\u00e1cteres.\n +chat=Chat +chemin=Ruta +color_3_arguments=precisa unha lista de tres elementos +commande=Comando : +comme_parametre=] como argumento. +couleur_du_crayon=Cor do lapis +couleur_du_fond=Cor do fondo +dans=En +definir=Acaba de definir +depassement_memoire=Esta aplicaci\u00f3n tomou un 90% do espazo libre de memoria.\nA s\u00faa acci\u00f3n foi detida con obxecto de previr exceder o stack.\nAseg\u00farese que o seu programa non ten un lazo infinito ou asigne un valor maior para o tama\u00f1o de memoria. +dernier=\u00daltimo +direction=Senso +division_par_zero=Divisi\u00f3n entre cero! +dossier_parent=Directorio pai +draw_grid=Debuxa grella +echantillon_texte=Mostra texto +echantillon=Mostra +editeur=Editar +effacer_editeur=Borrar a pantalla ao sa\u00edr do editor +element_dans_liste=palabras na lista [ +enlever=Eliminar +enregistreimage=Gardar imaxe como... +enregistrer_espace=Eliminar as variables e os procedementos? +entre_zero_un=Debe estar comprendido entre 0 e 1 +epaisseur_crayon=Tama\u00f1o m\u00e1ximo do lapis +erreur_compteur=Erro en contador +erreur_crochet=Erro de corchete: esper\u00e1base ] +erreur_editeur=Imposible gardar todos os procedementos.\nComproba os bloques PARA .... FIN\na correcta definici\u00f3n das variables :a :b etc +erreur_fixestyle=ponestilo pode aceptar soamente estes valores: ning\u00fan, negrita, subli\u00f1ado, it\u00e1lica, tachado, super\u00edndice, sub\u00edndice. +erreur_format_image=Os \u00fanicos arquivos para imaxe son os de formato *.png e *.jpg +erreur_memoire=XLogo non ten suficiente memoria para crear a imaxe desexada.\nPo\u00f1a un valor maior para o tama\u00f1o de memoria.\n " +erreur_nom_nombre_procedure=Erro no nome dun procedemento +erreur_nom_nombre_variable=Erro no nome dunha variable +erreur_pas_repertoire=non \u00e9 un nome de directorio axeitado +erreur_repetepour=Te que conter tres ou catro elementos: [variable min max incremento]" +erreur_retourne=Podes usar devolve unicamente dentro dun procedemento. +erreur_sortie1=A tartaruga sae da pantalla. +erreur_sortie2=N\u00famero de pasos antes de sa\u00edr:\n +erreur_stop=Podes usar alto unicamente dentro dun +erreur_tcp=Problema en comunicaci\u00f3n de rede +erreur_variable=non \u00e9 unha variable v\u00e1lida! +erreur=Erro +error_bad_values=S\u00f3 acepta valores num\u00e9ricos +error.3d.3vertex=Un pol\u00edgono debe ter alomenos tres +error.3d.emptypolygon=A \u00e1rea dun pol\u00edgono non pode ser cero +error.ioecriture=Problema de entrada/sa\u00edda: Non se pode gardar +error.iolecture=Imposible ler o arquivo desexado. +error.ne_peut_etre=non pode estar situado aqu\u00ed. +error.novalue=non ten valor. +error.primitive2D=S\u00f3 pode usarse en 2D +error.primitive3D=S\u00f3 pode usarse en 3D +error.procedure.must.be = ten que ser o nome dun procedemento +error.whattodo=Que facer con +error.word=ten que ser unha palabra +existe_deja=xa est\u00e1 definido +faux="falso +ferme_editeur=Pecha o editor +fichier_du_type=Arquivo do tipo +fichiers_logo=Arquivos logo +fichiers_rtf=Arquivos RTF +fichiers=Arquivo(s) +file_100K=Para non superar a memoria dispo\u00f1ible, a imaxe non pode ocupar m\u00e1is de 100 kb. +fin_flux=Non hai m\u00e1is car\u00e1cteres para ler no fluxo n\u00b0 +fin=fin +find_replace=Buscar / Substituir +find=Buscar +flux_ecriture=Este fluxo aberto non \u00e9 utilizable en escritura. +flux_existant=xa designa un fluxo aberto. Comeza por pechar o fluxo aberto antes de reutilizar este identificador. +flux_lecture=Este fluxo aberto non \u00e9 utilizable en lectura. +flux_non_disponible=Fluxo non dispo\u00f1ible +forme_crayon=Forma do lapis +forward=Avanza +gui_exists=O compo\u00f1ente gr\u00e1fico seguinte xa existe /ou xa foi definido\n " +haut=Alto +hollandais=Holand\u00e9s +hsb=HSB +hsbbleu=B +hsbrouge=H +hsbvert=S +imagefile=Arquivos de imaxe +images=Imaxes +imprimer_editeur=imprimir o editor +interrompre_execution=Deter a execuci\u00f3n en curso +je_ne_sais_pas=Non sei como facer +line=li\u00f1a +lire_editeur=Gardar as modificaci\u00f3n \u00e9 sa\u00edr +liste_vide=A lista est\u00e1 baleira +mainCommand=Comando de Inicio: +memoire=Memoria +menu.edition.copy=Copiar Ctl-C +menu.edition.cut=Cortar Ctl-X +menu.edition.paste=Pegar Ctl-V +menu.edition.selectall=Seleccionar todo +menu.edition=Edici\u00f3n +menu.file.captureimage.clipboard=Copiar ao portapapeis +menu.file.captureimage.print=Imprimir a imaxe +menu.file.captureimage=Capturar a imaxe +menu.file.open=Abrir +menu.file.quit=Sair +menu.file.save=Gardar +menu.file.saveas=Gardar como +menu.file.textzone.rtf=Gardar como rtf +menu.file.textzone=Zona de texto +menu.file=Arquivo +menu.help.about=Sobre XLogo... +menu.help.licence=Licenza +menu.help.online=Manual en li\u00f1a +menu.help.translatedlicence=Traduci\u00f3n da licenza +menu.help.translatexlogo=Traducir XLogo +menu.help=Axuda +menu.tools.eraser=Borra procedemento +menu.tools.pencolor=Elixir cor de lapis +menu.tools.preferences=Preferencias +menu.tools.screencolor=Cor de fondo +menu.tools.startup=Definir os arquivos de inicio... +menu.tools.translate=Traducir procedementos +menu.tools=Ferramentas +message_a_propos1=Versi\u00f3n de XLOGO : +message_a_propos2=Sitio web: +message_a_propos3=Podes escribirme a : +messages=Mensaxes +mot_vide=Palabra baleira +n_aime_pas=non acepta [ +nb_tortues=N\u00famero m\u00e1ximo de tartarugas +ne_renvoie_pas=non fixo sa\u00edr a +no_gui=O compo\u00f1ente gr\u00e1fico seguinte non existe / non foi definido +no_host=Problemas durante a comunicaci\u00f3n en rede co computador en direcci\u00f3n: +nom_du_fichier=Nome do arquivo? +nombre_unicode=debe estar comprendido entre 0 e 65535 +normal=Normal +note.do=do +note.fa=fa +note.la=la +note.mi=mi +note.re=re +note.si=si +note.sol=sol +nouveau_dossier=Crear un novo directorio +nouveau=Novo +ouvrir_editeur=Abrir o editor +parcourir=Procurar +parenthese_fermante=) non pode estar aqu\u00ed. +parenthese_ouvrante=Esperabase un parentese ( +parenthese_vide=Non hai nada entre par\u00e9ntese!. +pas_argument=non \u00e9 unha entrada correcta. +pas_assez_de=Non hai suficientes datos para +pas_entier=non \u00e9 un n\u00famero enteiro +pas_liste=non \u00e9 unha lista +pas_nombre=non \u00e9 un n\u00famero +pas_predicat=debe ser certo ou falso. +pas=Escala +pb_port=Imposible a conexi\u00f3n co porto +pencolor=Cor de lapis preasignado +pour=para +pref.cancel=Cancelar +pref.font=Fonte +pref.general.arabic=\u00e1rabe +pref.general.aspect=Aspecto +pref.general.asturian = Asturiano +pref.general.catalan=Catal\u00e1n +pref.general.english=ingl\u00e9s +pref.general.esperanto=Esperanto +pref.general.fast=R\u00e1pido +pref.general.french=Franc\u00e9s +pref.general.galician=Galego +pref.general.german=Aleman +pref.general.greek=Grego +pref.general.hungarian=H\u00fangaro +pref.general.italian=Italiano +pref.general.lang=Idioma +pref.general.metal=Metal +pref.general.motif=Motif +pref.general.portuguese=Portugu\u00e9s +pref.general.slow=Lento +pref.general.spanish=Espa\u00f1ol +pref.general.speed=Velocidade da tartaruga +pref.general.windows=Windows +pref.general=Xeral +pref.highlight.comment=Comentarios +pref.highlight.enabled=Activa o resaltado de sintaxe +pref.highlight.example=#Isto \u00e9 un comentario\nrepite 4[avanza 100 xiradereita 90] +pref.highlight.init=Reinicializar +pref.highlight.operand=Variables, palabras, n\u00fameros +pref.highlight.other=Outro... +pref.highlight.parenthesis=Par\u00e9ntese, corchetes +pref.highlight.primitive=Primitiva +pref.highlight=Resaltado +pref.options.tcp=N�mero de porto TCP +pref.options.eraseVariables=Borra as variables cando pecha o editor +pref.ok=Si +pref.options=Opci\u00f3ns +pref.sound.instruments=Instrumentos dispo\u00f1ibles +pref.sound.problem=Problema co MIDI do computador +pref.sound=Son +pref.turtles=Elecci\u00f3n da tartaruga +primitives=Primitivas +probleme_sequence=Non podo entender a serie de notas: corrixe os erros! +procedure_demarrage=Comando executado ao comezo: +procedure_list=Lista de procedementos +procedure_vide=O nome dun procedemento non pode ser baleiro +qualite_dessin=Precisi\u00f3n do trazo +quit_editeur=Sair do editor sen gardar +quitter?=Desexas sa\u00edr? +rechercher_dans=Buscar en: +relancer=Logo peche XLogo e int\u00e9nteo novamente para que os cambios sexan efectivos. +repertoire_accueil=Directorio de destino +repertoires=Directorio(s) +replace=Substitu\u00edr +replaceall=Substitu\u00edr todo +replacewith=Substit\u00fae con: +restaurer=Restaurar +rgb=VVA +rond=Redondo +rouge=Vermello +screencolor=Cor de papel preasignado +seule_tortue_dispo=Non podes eliminar a \u00fanica tartaruga dispo\u00f1ible! +stop_chat=<<<<<Fin da comunicaci\u00f3n>>>>> +stop=Alto +string_not_found=Elemento non atopado +style.bold=Negrita +style.exposant=Superindice +style.italic=Italica +style.none=Ning\u00fan +style.strike=Tachado +style.subscript=Subindice +style.underline=Subli\u00f1ado +taille_dessin=Tama\u00f1o da fiestra para debuxar +title_axis=Eixos cartesianos +titredialogue2=Escritura da imaxe en curso +too_much_arguments=Demasiados argumentos entre os par\u00e9ntese +tortue_inaccessible=Imposible crear unha tartaruga con ese n\u00famero +traduire=Traducir! +traduire_de=Traducir de +translatecomplete=Completar unha traduci\u00f3n +translateconsult=Consultar as traduci\u00f3ns existentes +translatecreate=Engade /Crea unha nova traduci\u00f3n +translatemessage=Cando todos os campos estean completos nas d\u00faas t\u00e1boas, fai "click" no bot\u00f3n "OK" e env\u00edame o arquivo xerado a [email protected] +translatemodify=Modificar unha traduci\u00f3n +translatewant=Vostede desexa: +un_caractere=debe conter un car\u00e1cter +uniform_color=Cor s\u00f3lida +variable_vide=O nome dunha variable non pode ser nulo. +vers=Cara a: +vert=Verde +vrai="certo +xgrid=Anchura da grella +y_a_pas=non hai +ygrid=Altura da grella +editor.undo=Desfacer a \u00faltima acci\u00f3n +editor.redo=Refacer +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_hu_HU.properties b/logo/src/langage_hu_HU.properties new file mode 100644 index 0000000..28e65bb --- /dev/null +++ b/logo/src/langage_hu_HU.properties @@ -0,0 +1,437 @@ +3d.viewer=3D n\u00e9zet +3d.fog=K\u00f6d +3d.fog.density=S\u0171r\u0171s\u00e9g: +3d.fog.none=Nincs +3d.fog.exponential=Hatv\u00e1nyozottan n\u00f6vekv\u0151 k\u00f6d +3d.fog.linear=Ar\u00e1nyos k\u00f6d +3d.fog.frontdistance=El\u0151t\u00e9r t\u00e1vols\u00e1g +3d.fog.backdistance=H\u00e1tt\u00e9r t\u00e1vols\u00e1g +3d.fog.type=K\u00f6d t\u00edpusa: +3d.light=Megvil\u00e1g\u00edt\u00e1s +3d.light.type=Megvil\u00e1g\u00edt\u00e1s t\u00edpusa: +3d.light.ambient=H\u00e1tt\u00e9rvil\u00e1g\u00edt\u00e1s +3d.light.directional=Ir\u00e1ny\u00edtott f\u00e9nyforr\u00e1s +3d.light.point=Pontszer\u0171 f\u00e9nyforr\u00e1s +3d.light.none=Kikapcsolva +3d.light.spot=reflektor +3d.light.position=Poz\u00edci\u00f3 +3d.light.direction=Ir\u00e1ny +3d.light.angle=sz\u00f6g: +3d.light.apply=Alkalmaz +active_grid=Akt\u00edv +active_xaxis=X tengely +active_yaxis=Y tengely +ajouter=Hozz\u00e1ad +animation_active = Anim\u00e1ci\u00f3s m\u00f3d bekapcsolva. +apercu = El\u0151n\u00e9zet +attend_positif = pozit\u00edv sz\u00e1mot v\u00e1r. +backward=H\u00e1tra +bas = Kicsi +bleu = k\u00e9k +bordermotif=Keret minta +caractere_special_variable = V\u00e1ltoz\u00f3 n\u00e9v nem t\u00e1mogatja a +caractere_special1=Elj\u00e1r\u00e1s n\u00e9v nem t\u00e1mogatja a +caractere_special2=karakterke, mint \ + - * / ( ) [ ] = < > & | : +caractere_special3=\u00c1tnevez\u00e9s +carre = N\u00e9gyzet +chaine_trop_longue = 32000 karaktern\u00e9l hosszabb sz\u00f3t vagy list\u00e1t nem lehet nyomtatni. +chat=Cseveg\u00e9s +chemin=El\u00e9r\u00e9si \u00fat +color_3_arguments=3 elemb\u0151l \u00e1ll\u00f3 lista kell, [v\u00f6r\u00f6s z\u00f6ld k\u00e9k] +commande=Parancs: +comme_parametre = ] argumentumk\u00e9nt. +couleur_du_crayon=Toll sz\u00edn +couleur_du_fond=Rajzlap sz\u00edn +dans=Az elj\u00e1r\u00e1sodban +definir=Defini\u00e1ltad a +depassement_memoire =Az XLogo t\u00f6lti be a marad\u00e9k mem\u00f3ria 90%-\u00e1t.\nLe\u00e1ll\u00edtom a parancs fut\u00e1s\u00e1t.\nNincs v\u00e9letlen\u00fcl v\u00e9gtelen ciklus a programodban?. K\u00fcl\u00f6nben n\u00f6veld meg az XLogo sz\u00e1m\u00e1ra a mem\u00f3ri\u00e1t. +dernier = Utols\u00f3 +direction=Ir\u00e1ny +division_par_zero =Null\u00e1val nem lehet osztani! +dossier_parent = Sz\u00f6l\u0151 mappa +draw_grid=H\u00e1tt\u00e9r r\u00e1cs +echantillon = Minta +echantillon_texte = Ez egy el\u0151n\u00e9zet +editeur=Editor +editor.redo=Ism\u00e9t +editor.undo=Visszavon\u00e1s +effacer_editeur=K\u00e9perny\u0151 t\u00f6rl\u00e9se a szerkeszt\u0151 ablak z\u00e1r\u00e1sakor +element_dans_liste= elemek a list\u00e1ban [ +enlever=Elt\u00e1vol\u00edt\u00e1s +enregistreimage=K\u00e9p ment\u00e9se m\u00e1s n\u00e9ven... +enregistrer_espace = Let\u00f6r\u00f6ljem a munkater\u00fcletet? +entre_zero_un = 0 \u00e9s 1 k\u00f6z\u00f6tti \u00e9rt\u00e9k kell. +epaisseur_crayon = Maxim\u00e1lis toll sz\u00e9less\u00e9g +erreur_compteur =ismsz\u00e1m (repcount) csak cikluson bel\u00fcl haszn\u00e1lhat\u00f3. +erreur_crochet=Hiba: ] sz\u00fcks\u00e9ges. +erreur_editeur=Az elj\u00e1r\u00e1st nem lehet elmenteni.\n\u00d3vatosan haszn\u00e1ld a (To).... (End) parancsot.\nEllen\u0151rizd a helyes v\u00e1ltoz\u00f3 haszn\u00e1latot. +erreur_fixestyle = bet\u0171st\u00edlus (setstyle) csak az al\u00e1bbi tulajdons\u00e1gokat fogadja el: nincs (none), f\u00e9lk\u00f6v\u00e9r (bold), al\u00e1h\u00faz\u00e1s (underline), d\u0151lt (italic), fels\u0151index (superscript) or als\u00f3index (subscript). +erreur_format_image=Csak *.png \u00e9s *.jpg k\u00e9pf\u00e1jlokat fogad el +erreur_memoire=XLogo nem tudja el\u0151\u00e1ll\u00edtani a k\u00edv\u00e1nt k\u00e9pet, kifogyott a mem\u00f3ria.\nA "Be\u00e1ll\u00edt\u00e1sok" lapon n\u00f6veld meg az XLogo-nak adott mem\u00f3ri\u00e1t. +erreur_nom_nombre_procedure = Az elj\u00e1r\u00e1s nevek nem lehetnek sz\u00e1mok ! +erreur_nom_nombre_variable = A v\u00e1ltoz\u00f3 nevek nem lehetnek sz\u00e1mok ! +erreur_pas_repertoire = nem l\u00e9tez\u0151 alk\u00f6nyvt\u00e1r ! +erreur_repetepour= h\u00e1rom vagy n\u00e9gy elem\u0171 lista kell, [v\u00e1ltoz\u00f3 kezd\u0151\u00e9rt\u00e9k v\u00e9g\u00e9rt\u00e9k n\u00f6vekm\u00e9ny] +erreur_retourne =Elj\u00e1r\u00e1son k\u00edv\u00fcl a return parancs nem haszn\u00e1lhat\u00f3 ! +erreur_sortie1=A tekn\u0151s elhagyta a rajzter\u00fcletet. +erreur_sortie2=Number of steps available before leaving: +erreur_stop =cikluson vagy elj\u00e1r\u00e1son k\u00edv\u00fcl a visszat\u00e9r (stop) parancs nem haszn\u00e1lhat\u00f3 ! +erreur_tcp=H\u00e1l\u00f3zati kapcsolat hiba. +erreur_variable = \u00e9rv\u00e9nytelen v\u00e1ltoz\u00f3 ! +erreur=HIBA +error_bad_values= helyeset fogad el +error.3d.3vertex=Egy soksz\u00f6gnek legal\u00e1bb h\u00e1rom cs\u00facsa legyen! +error.3d.emptypolygon=Soksz\u00f6g fel\u00fclete nem lehet \u00fcres! +error.ioecriture=F\u00e1jl \u00edr\u00e1si hiba: Sajnos nem tudom elmenteni... +error.iolecture=A megadott f\u00e1jl nem olvashat\u00f3. +error.ne_peut_etre= nem tal\u00e1lhat\u00f3. +error.novalue= nincs megadott \u00e9rt\u00e9ke. +error.primitive2D=csak 3D m\u00f3dban el\u00e9rhet\u0151. +error.primitive3D=csak 3D m\u00f3dban el\u00e9rhet\u0151. +error.procedure.must.be=elj\u00e1r\u00e1s n\u00e9vnek kell lennie! +error.whattodo=Nem tudom, mit kezdjek vele +error.word= sz\u00f3nak kell lennie. +existe_deja= m\u00e1r l\u00e9tezik. +faux="hamis +ferme_editeur=Szerkeszt\u0151 ablak bez\u00e1r\u00e1sa. +fichier_du_type=F\u00e1jl form\u00e1tum: +fichiers = F\u00e1jl(ok) +fichiers_logo=Logo f\u00e1jlok +fichiers_rtf = RTF f\u00e1jlok +file_100K=A mem\u00f3ria t\u00falcsordul\u00e1st elker\u00fclend\u0151, a f\u00e1jl\n m\u00e9ret nem haladhatja meg a 100 KB-ot. +fin=v\u00e9ge +fin_flux = Az adatfolyamban nincs olvashat\u00f3 karakter n\u00b0 +find_replace=Keres\u00e9s/csere +find=Keres\u00e9s +flux_ecriture = Adatfolyam nem \u00edrhat\u00f3. +flux_existant =adatfolyam nyitott. el\u0151sz\u00f6r z\u00e1rd le, ha olvasni akarod. +flux_lecture = Nem olvashat\u00f3 adatfolyam. +flux_non_disponible =Nem l\u00e9tezik adatfolyam a megadott azonos\u00edt\u00f3val +forme_crayon = Toll alak +forward=El\u0151re +gui_exists=M\u00e1r l\u00e9tezik ez a grafikai komponens: +haut = Magas +hollandais=Holland +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=K\u00e9p f\u00e1jlok +images=K\u00e9pek +imprimer_editeur=Szerkesztett sz\u00f6veg nyomtat\u00e1sa +interrompre_execution=AKtu\u00e1lis program meg\u00e1ll\u00edt\u00e1sa +je_ne_sais_pas=Nem tudom, hogy hajtsam v\u00e9gre a +line=sor +lire_editeur=Program friss\u00edt\u00e9s, majd a szerkeszt\u0151 bez\u00e1r\u00e1sa +liste_vide = \u00dcres lista. +mainCommand=F\u0151 parancs: +memoire=Mem\u00f3ria foglal\u00e1s (MB) +menu.edition.copy=M\u00e1sol\u00e1s Ctrl+C +menu.edition.cut=Kiv\u00e1g\u00e1s Ctrl+X +menu.edition.paste=Beilleszt\u00e9s Ctrl+V +menu.edition.selectall = Mindet kijel\u00f6l Ctrl+A +menu.edition=Szerkeszt\u00e9s +menu.file.captureimage.clipboard = M\u00e1sol\u00e1s a v\u00e1g\u00f3lapra +menu.file.captureimage.print=Nyomtat\u00e1s... +menu.file.captureimage=K\u00e9p +menu.file.open=Megnyit\u00e1s +menu.file.quit=Kil\u00e9p\u00e9s +menu.file.save=Ment\u00e9s +menu.file.saveas=Ment\u00e9s m\u00e1sk\u00e9nt +menu.file.textzone = Sz\u00f6veg +menu.file.textzone.rtf = Ment\u00e9s m\u00e1sk\u00e9nt... (RTF form\u00e1tumba) +menu.file=F\u00e1jl +menu.help.about=XLogo n\u00e9vjegye +menu.help.licence=Licencszerz\u0151d\u00e9s +menu.help.online=Online k\u00e9zik\u00f6nyv +menu.help.translatedlicence=Licencszerz\u0151d\u00e9s ford\u00edt\u00e1sa +menu.help.translatexlogo= XLogo ford\u00edt\u00e1sa +menu.help=Seg\u00edts\u00e9g +menu.tools.eraser=Elj\u00e1r\u00e1s t\u00f6rl\u00e9se +menu.tools.pencolor=Toll sz\u00edn +menu.tools.preferences=Tulajdons\u00e1gok +menu.tools.screencolor=H\u00e1tt\u00e9r sz\u00edn +menu.tools.startup=Ind\u00edt\u00e1si f\u00e1jl +menu.tools.translate = K\u00f3d ford\u00edt\u00f3 +menu.tools=Eszk\u00f6z\u00f6k +message_a_propos1=XLogo verzi\u00f3sz\u00e1m: +message_a_propos2=Web lap c\u00edme: +message_a_propos3=Kapcsolat: +messages=\u00dczenetek +mot_vide = A sz\u00f3nak legal\u00e1bb egy karaktert tartalmaznia kell. +n_aime_pas = nem illeszkedik [ +nb_tortues = tekn\u0151s\u00f6k maxim\u00e1lis sz\u00e1ma +ne_renvoie_pas= nem \u00edrhat\u00f3 +no_gui=Nem l\u00e9tez\u0151 grafikai komponens: +no_host=Kommunik\u00e1ci\u00f3s probl\u00e9ma az al\u00e1bbi c\u00edm\u0171 sz\u00e1m\u00edt\u00f3g\u00e9ppel: +nom_du_fichier=F\u00e1jl n\u00e9v: +nombre_unicode = 0 \u00e9s 65535 k\u00f6z\u00f6tti sz\u00e1m kell. +normal = Norm\u00e1l +note.do = d\u00f3 +note.fa = f\u00e1 +note.la = l\u00e1 +note.mi = mi +note.re = r\u00e9 +note.si = ti +note.sol = sz\u00f3 +nouveau = \u00daj +nouveau_dossier = \u00daj mappa l\u00e9trehoz\u00e1sa +ouvrir_editeur=Szerkeszt\u0151 megnyit\u00e1sa +parcourir=B\u00f6ng\u00e9sz\u00e9s... +parenthese_fermante= ) hib\u00e1s ezen a helyen. +parenthese_ouvrante=Egy (-re v\u00e1rok. +parenthese_vide=\u00dcres ( \u00e9s ) ! +pas_argument= nem \u00e9rv\u00e9nyes argumentum. +pas_assez_de=Kev\u00e9s bemen\u0151 param\u00e9ter +pas_entier= eg\u00e9sz sz\u00e1mnak kell lennie ! +pas_liste = list\u00e1nak kell lennie. +pas_nombre = sz\u00e1mnak kell lennie ! +pas_predicat= igaz vagy hamis \u00e9rt\u00e9k lehet. +pas=T\u00e1vols\u00e1g +pb_port=Nem tud kapcsol\u00f3dni a porthoz: +pencolor=Alap\u00e9rtelmezett toll sz\u00edn +pour=tudd +pref.cancel=Megszak\u00edt +pref.font=Bet\u0171 +pref.general=\u00c1ltal\u00e1nos +pref.general.arabic=Arab +pref.general.aspect=Fel\u00fclet +pref.general.asturian = Aszt\u00fariai +pref.general.catalan=Katal\u00e1n +pref.general.english=Angol +pref.general.esperanto= Eszperant\u00f3 +pref.general.fast=Gyors +pref.general.french=Francia +pref.general.galician=Gal\u00edcia\u00ed +pref.general.german=N\u00e9met +pref.general.greek=G\u00f6r\u00f6g +pref.general.italian=Olasz +pref.general.lang=Nyelv +pref.general.metal=Met\u00e1l +pref.general.motif=Motif +pref.general.hungarian=Magyar +pref.general.portuguese= Portug\u00e1l +pref.general.slow=Lass\u00fa +pref.general.spanish=Spanyol +pref.general.speed=Tekn\u0151s sebess\u00e9ge +pref.general.windows=Nat\u00edv +pref.highlight.comment= Megjegyz\u00e9sek +pref.highlight.enabled=Szintaxis kiemel\u00e9s bekapcsol\u00e1sa +pref.highlight.example=# Megjegyz\u00e9s \n ism\u00e9tl\u00e9s 4 [el\u0151re 100 jobbra 90] +pref.highlight.init= Alap\u00e9rtelmezett \u00e9rt\u00e9kek +pref.highlight.operand= V\u00e1ltoz\u00f3k, szavak, sz\u00e1mok +pref.highlight.other= Egy\u00e9b... +pref.highlight.parenthesis= Z\u00e1r\u00f3jelek, kapcsos z\u00e1r\u00f3jelek +pref.highlight.primitive= Alapszavak +pref.highlight=Kiemel\u0151 +pref.ok= OK +pref.options.tcp=TCP port sz\u00e1ma: +pref.options=Be\u00e1ll\u00edt\u00e1sok +pref.options.eraseVariables=V\u00e1ltoz\u00f3k t\u00f6rl\u00e9se a szerkeszt\u0151 bez\u00e1r\u00e1sakor +pref.sound.instruments=L\u00e9tez\u0151 hangszerek: +pref.sound.problem= Nem tal\u00e1lok a MIDI eszk\u00f6zt ! +pref.sound=Hang +pref.turtles=Tekn\u0151s +primitives= Alapszavak +probleme_sequence = Nem tudom \u00e9rtelmezni a kapott zenei dallamot ! +procedure_demarrage=Indul\u00e1skor v\u00e9grehajtand\u00f3 parancs: +procedure_list=Elj\u00e1r\u00e1sok: +procedure_vide =Elj\u00e1r\u00e1s n\u00e9v nem lehet \u00fcres ! +qualite_dessin=Rajz felbont\u00e1s +quit_editeur=Szerkeszt\u0151 bez\u00e1r\u00e1sa a friss\u00edt\u00e9sek telep\u00edt\u00e9se n\u00e9lk\u00fcl +quitter? = Biztosan kil\u00e9psz? +rechercher_dans=Keres\u00e9s helye: +relancer =L\u00e9pj\u00e9l ki az xLogo-b\u00f3l \u00e9s ind\u00edtsd \u00fajra, hogy a friss\u00edt\u00e9sek \u00e9letbe l\u00e9pjenek. +repertoire_accueil= Kezd\u0151 mappa +repertoires = Mapp\u00e1(k) +replace=Cser\u00e9l +replaceall=Mindet cser\u00e9l +replacewith=Helyettes\u00edt\u00e9s: +restaurer = \u00dajraind\u00edt\u00e1s +rgb = RGB +rond= Kerek +rouge = V\u00f6r\u00f6s +screencolor=Alap\u00e9rtelmezett h\u00e1tt\u00e9r sz\u00edn +seule_tortue_dispo=Nem t\u00f6r\u00f6lhet\u0151 az egyetlen akt\u00edv tekn\u0151s ! +stop_chat=<<<<< Cseveg\u00e9s v\u00e9ge >>>>> +stop=Stop +string_not_found=Nem l\u00e9tez\u0151 karakterek. +style.bold= F\u00e9lk\u00f6v\u00e9r +style.exposant = Fels\u0151index +style.italic= D\u0151lt +style.none= Alap +style.strike= \u00c1th\u00fazott +style.subscript= Als\u00f3index +style.underline= Al\u00e1h\u00faz\u00e1s +taille_dessin = Lap m\u00e9ret +title_axis=H\u00e1tt\u00e9r tengelyek +titredialogue2=K\u00e9p ment\u00e9se... +too_much_arguments=T\u00fal sok argumentum a z\u00e1r\u00f3jelek k\u00f6z\u00f6tt. +tortue_inaccessible=Nem tudom l\u00e9trehozni az adott sz\u00e1m\u00fa tekn\u0151st ! +traduire =Ford\u00edt\u00e1s ! +traduire_de=Ford\u00edtand\u00f3 nyelv: +translatecomplete=Ford\u00edt\u00e1s befejez\u00e9se +translateconsult= L\u00e9tez\u0151 ford\u00edt\u00e1sok b\u00f6ng\u00e9sz\u00e9se +translatecreate= \u00daj ford\u00edt\u00e1s k\u00e9sz\u00edt\u00e9se +translatemessage=Ha mindegyik lapon minden mez\u0151t kit\u00f6lt\u00f6tt\u00e9l, akkor, nyomd meg az "OK" gombot. A gener\u00e1lt f\u00e1jlt k\u00fcldd el a [email protected] c\u00edmre. +translatemodify= Ford\u00edt\u00e1s m\u00f3dos\u00edt\u00e1sa +translatewant=Azt szeretn\u00e9d, hogy: +un_caractere = pontosan egy karaktert kell tartalmaznia. +uniform_color=Egys\u00e9ges sz\u00edn +variable_vide=V\u00e1ltoz\u00f3 n\u00e9v nem lehet \u00fcres ! +vers=C\u00edmzett: +vert = Z\u00f6ld +vrai="igaz +xgrid=X R\u00e1cs +y_a_pas = Nincs +ygrid=Y R\u00e1cs +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_it_IT.properties b/logo/src/langage_it_IT.properties new file mode 100644 index 0000000..df5729c --- /dev/null +++ b/logo/src/langage_it_IT.properties @@ -0,0 +1,437 @@ +3d.fog=Nebbia +3d.fog.backdistance=?? +3d.fog.density=Densit\u00e0 +3d.fog.exponential=Nebbia densa +3d.fog.frontdistance=?? +3d.fog.linear=Nebbia progressiva +3d.fog.none=Nessuna +3d.fog.type=Tipo di nebbia: +3d.light=Illuminazione +3d.light.ambient=Illuminazione ambiente +3d.light.angle=Angolo: +3d.light.apply=Applica +3d.light.direction=Direzione +3d.light.directional=Sorgente di luce unidirezionale +3d.light.none=Spegni illuminazione +3d.light.point=Sorgente di luce puntiforme +3d.light.position=Posizione +3d.light.spot=Illuminazione spot +3d.light.type=Tipo di illuminazione: +3d.viewer=Visualizzatore 3D +active_grid=Attivo +active_xaxis=Asse X +active_yaxis=Asse Y +ajouter=Aggiungi +animation_active=La modalit\u00e0 animazione \u00e8 attiva. +apercu=Anteprima +attend_positif=\u00e8 in attesa di un argomento di segno positivo. +backward=Indietro +bas=Basso +bleu=Blu +bordermotif=Motivo del bordo +caractere_special1=I nomi delle procedure non possono +caractere_special2=contenere caratteri quali + - * / ( ) [ ] & | : +caractere_special3=Rinomina +caractere_special_variable=I nomi delle variabili non possono +carre=Quadrato +chaine_trop_longue=Non posso visualizzare una parola o una lista pi\u00f9 lunga di 32.000 caratteri. +chat=Chat +chemin=Percorso +color_3_arguments=necessita una lista di 3 elementi [red green blue] +commande=Comando: +comme_parametre=] come parametro. +couleur_du_crayon=Colore della penna +couleur_du_fond=Colore dello sfondo +dans=In +definir=Hai definito +depassement_memoire=Il programma (XLogo) ha utilizzato il 90% della memoria disponibile. Fermo il comando lanciato perch\u00e9 potrebbe eccedere tale limite. +dernier=Ultimo +direction=Direzione +division_par_zero=Non puoi dividere per 0! +dossier_parent=Directory a monte +draw_grid=Griglia di sfondo +echantillon=Anteprima +echantillon_texte=Questa \u00e8 una anteprima +editeur=Editor +editor.redo=Riesegui l'ultima azione +editor.undo=Annulla l'ultima azione +effacer_editeur=Pulisci lo schermo quando si chiude l'editor +element_dans_liste=elementi nella lista [ +enlever=Rimuovi +enregistreimage=Salva l'immagine come ... +enregistrer_espace=Cancello l'area di lavoro? +entre_zero_un=deve essere compreso tra 0 e 1. +epaisseur_crayon=Massima ampiezza della pena +erreur=ERRORE +erreur_compteur=Non puoi usare ContaRipetizioni fuori da un ciclo Conta +erreur_crochet=Errore di parentesi, attendo una ] +erreur_editeur=Non posso salvare su disco le procedure.\nVerifica i blocchi Ripeti ... Fine\ne se ci sono errori nella definizione delle variabili. +erreur_fixestyle=ImpostaStile accetta solo i seguenti valori: nessuno, marcato, sottolineato, corsivo, apice, pedice +erreur_format_image=Formati immagine sopportati: jpg, png +erreur_memoire=Il programma (XLogo) non dispone di memoria sufficiente per creare l'immagine richiesta. Nel tab "Opzioni", aumenta la quantit\u00e0 di memoria a sua disposizione. +erreur_nom_nombre_procedure=Il nome di una procedura non pu\u00f2 essere un numero! +erreur_nom_nombre_variable=Il nome di una variabile non pu\u00f2 essere un numero! +erreur_pas_repertoire=non \u00e8 una directory valida! +erreur_repetepour=Deve contenere solo tre o quattro +erreur_retourne Non puoi usare Ritorna fuori da una procedura! +erreur_sortie1=La tartaruga \u00e8 uscita dall'area del disegno +erreur_sortie2=Numero di passi prima di uscire: +erreur_stop=Non puoi usare Ferma fuori da una procedura o da un ciclo! +erreur_tcp=Problema di comunicazione nella rete +erreur_variable=non \u00e8 una variabile valida! +error.3d.3vertex=Un poligono deve avere almeno tre vertici! +error.3d.emptypolygon=Un poligono deve avere un'area non nulla +error.ioecriture=Errore di Input/Output: sono spiacente, non posso registrare. +error.iolecture=Non sono in grado di leggere il file specificato. +error.ne_peut_etre=non pu\u00f2 essere situato qui. +error.novalue=non ha un valore. +error.primitive2D=\u00e8 disponibile esclusivamente in modalit\u00e0 2D. +error.primitive3D=\u00e8 disponibile esclusivamente in modalit\u00e0 3D. +error.procedure.must.be=deve essere un nome di procedura! +error.whattodo=Non so cosa fare con +error.word=deve essere una parola +error_bad_values=Accetta esclusivamente i valori seguenti: +existe_deja=gi\u00e0 esiste. +faux="falso +ferme_editeur=Chiudi la finestra Editor +fichier_du_type=Formato file: +fichiers=File +fichiers_logo=File Logo +fichiers_rtf=File RTF +file_100K=Per evitare di eccedere il limite della memoria disponibile, la grandezza del file non pu\u00f2 superare i 100kB. +fin=fine +fin_flux=Non ci sono altri caratteri da leggere nel flusso n\u00b0 +find=Cerca +find_replace=Cerca/Sostituisci +flux_ecriture=Non posso registrare in questo flusso. +flux_existant=\u00e8 un flusso gi\u00e0 aperto. Devi chiuderlo prima di utilizzare questo identificatore. +flux_lecture=Non posso leggere da questo flusso. +flux_non_disponible=Nessun flusso aperto \u00e8 associato all'identificatore +forme_crayon=Forma della punta della penna +forward=Avanti +gui_exists=Il componente grafico seguente \u00e8 gi\u00e0 esistente: +haut=Alto +hollandais=Olandese +hsb=HSB +hsbbleu=B +hsbrouge=H +hsbvert=S +imagefile=File immagine +images=Immagini +imprimer_editeur=Stampa il programma +interrompre_execution=Interrompi l'esecuzione in corso +je_ne_sais_pas=Non so come fare +line=Linea +lire_editeur=Aggiorna e chiudi l'editor +liste_vide=La lista \u00e8 vuota +mainCommand=Comando principale: +memoire=Memoria allocata a XLogo (MB): +menu.edition=Modifica +menu.edition.copy=Copia Ctrl+C +menu.edition.cut=Taglia Ctrl+X +menu.edition.paste=Incolla Ctrl+V +menu.edition.selectall=Seleziona tutto Ctrl+A +menu.file=File +menu.file.captureimage=Cattura +menu.file.captureimage.clipboard=Copia Appunti +menu.file.captureimage.print=Stampa... +menu.file.open=Apri +menu.file.quit=Abbandona +menu.file.save=Registra +menu.file.saveas=Registra come... +menu.file.textzone=Testo +menu.file.textzone.rtf=Registra come... (formato RTF) +menu.help=Aiuto +menu.help.about=Informazioni su XLogo +menu.help.licence=Licenza +menu.help.online=Manuale on-line +menu.help.translatedlicence=Traduzione della licenza +menu.help.translatexlogo=Traduci XLogo +menu.tools=Strumenti +menu.tools.eraser=Gestione procedure +menu.tools.pencolor=Colore penna +menu.tools.preferences=Preferenze +menu.tools.screencolor=Colore sfondo +menu.tools.startup=File di partenza +menu.tools.translate=Traduttore primitive +message_a_propos1=Versione XLogo: +message_a_propos2=Sito Web +message_a_propos3=Sono raggiungibile a: +messages=Messaggi +mot_vide=La parola deve contenere almeno un carattere +n_aime_pas=non accetta [ +nb_tortues=Numero massimo di tartarughe +ne_renvoie_pas=non restituisce il valore a +no_gui=Il componente grafico seguente non esiste: +no_host=Problema di comunicazione con il computer all'indirizzo: +nom_du_fichier=Nome del file +nombre_unicode=deve essere compreso tra 0 e 65535 (2^16) +normal=Normale +note.do=do +note.fa=fa +note.la=la +note.mi=mi +note.re=re +note.si=si +note.sol=sol +nouveau=Nuovo +nouveau_dossier=Crea nuova directory +ouvrir_editeur=Apri l'editor +parcourir=Sfoglia... +parenthese_fermante=Mi aspetto una parentesi chiusa ) +parenthese_ouvrante=Mi aspetto una parentesi aperta ( +parenthese_vide=Il contenuto fra le parentesi () \u00e8 assente! +pas=Distanza +pas_argument=non \u00e8 un argomento valido +pas_assez_de=Non ho dati sufficienti per +pas_entier=non \u00e8 un numero intero! +pas_liste=non \u00e8 una lista. +pas_nombre=non \u00e8 un numero! +pas_predicat=deve essere vero o falso. +pb_port=Non riesco a connettermi alla porta: +pencolor=Colore della penna (di default) +pour=per +pref.cancel=Annulla +pref.font=Font +pref.general=Generale +pref.general.arabic=Arabico +pref.general.aspect=Aspetto +pref.general.asturian=Asturiano +pref.general.catalan=Catalano +pref.general.english=Inglese +pref.general.esperanto=Esperanto +pref.general.fast=Veloce +pref.general.french=Francese +pref.general.galician=Galiziano +pref.general.german=Tedesco +pref.general.greek=Greco +pref.general.hungarian=Ungherese +pref.general.italian=Italiano +pref.general.lang=Lingua +pref.general.metal=Metal +pref.general.motif=Motif +pref.general.portuguese=Portoghese +pref.general.slow=Lento +pref.general.spanish=Spagnolo +pref.general.speed=Velocit\u00e0 della tartaruga +pref.general.windows=Nativo +pref.highlight=Colorazione +pref.highlight.comment=Commenti +pref.highlight.enabled=Attiva la colorazione sintattica +pref.highlight.example=# Questo \u00e8 un commento\nRipeti 4 [Avanti 100 RuotaDestra 90] +pref.highlight.init=Riporta a valori di default +pref.highlight.operand=Variabili, parole, numeri +pref.highlight.other=Altro... +pref.highlight.parenthesis=Parentesi, parentesi quadre +pref.highlight.primitive=Primitive +pref.ok=OK +pref.options=Opzioni +pref.options.eraseVariables=Cancella le variabili quando chiudi l'editor +pref.options.tcp=Numero porta TCP: +pref.sound=Suono +pref.sound.instruments=Strumenti disponibili: +pref.sound.problem=Non trovo l'interfaccia MIDI! +pref.turtles=Scelta della tartaruga +primitives=Primitive +probleme_sequence=Non comprendo la tua sequenza musicale, corregila! +procedure_demarrage=Comando da eseguire durante la partenza: +procedure_list=Procedure: +procedure_vide=I nomi delle procedure non possono essere vuoti! +qualite_dessin=Qualit\u00e0 della traccia da disegno +quit_editeur=Chiudi l'editor senza aggiornare +quitter?=Sei sicuro di voler chiudere? +rechercher_dans=Cerca in: +relancer=Poi chiudi e rilancia XLogo per aggiornare i cambiamenti +repertoire_accueil=Directory iniziale +repertoires=Directory +replace=Rimpiazza +replaceall=Rimpiazza tutti +replacewith=Rimpiazza con: +restaurer=Inizializza Resetta +rgb=RGB +rond=Rotondo +rouge=Rosso +screencolor=Colore dello schermo (di default) +seule_tortue_dispo=Non puoi cancellare l'unica tartaruga attiva! +stop=Stop +stop_chat=<<<< Fine della chat >>>> +string_not_found=Elemento non trovato +style.bold=Grassetto +style.exposant=Apice +style.italic=Corsivo +style.none=Nessuno +style.strike=Barrato +style.subscript=Pedice +style.underline=Sottolineato +taille_dessin=Dimensione dell'area di disegno +title_axis=Asse sullo sfondo dello schermo +titredialogue2=Registrazione dell'immagine in corso... +too_much_arguments=Troppi argomenti fra le parentesi. +tortue_inaccessible=Non posso creare una tartaruga con il numero indicato! +traduire=Traduci! +traduire_de=Traduzione da: +translatecomplete=Completa una traduzione +translateconsult=Consulta le traduzioni disponibili +translatecreate=Crea una nuova traduzione +translatemessage=Quando hai completato tutti i campi per ambedue i tab, clicca sul bottone "OK". Spediscimi il file generato a [email protected] +translatemodify=Modifica una traduzione +translatewant=Desideri: +un_caractere=deve contenere esattamente un carattere +uniform_color=Colore uniforme: +variable_vide=I nomi delle variabili non possono essere vuoti! +vers=A: +vert=Verde +vrai="vero +xgrid=Griglia X +y_a_pas=Non c'\u00e8 +ygrid=Griglia Y +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/langage_pt_BR.properties b/logo/src/langage_pt_BR.properties new file mode 100644 index 0000000..d791c4d --- /dev/null +++ b/logo/src/langage_pt_BR.properties @@ -0,0 +1,437 @@ +3d.fog.backdistance=Dist\u00e2ncia de opacidade +3d.fog.density=Densidade +3d.fog.exponential=Neblina densa +3d.fog.frontdistance=Dist\u00e2ncia da bruma +3d.fog.linear=Neblina progressiva +3d.fog.none=Nenhuma +3d.fog.type=Tipo de neblina: +3d.fog=Neblina +3d.light.ambient=Luz ambiente +3d.light.angle=\u00c2ngulo: +3d.light.apply=Aplicar +3d.light.direction=Dire\u00e7\u00e3o +3d.light.directional=Luz unidirecional +3d.light.none=Sem luz +3d.light.point=Ponto de luz +3d.light.position=Posi\u00e7\u00e3o +3d.light.spot=Foco +3d.light.type=Tipo de luz: +3d.light=Luz +3d.viewer=Visor 3D +active_grid=Ativo +active_xaxis=Eixo X +active_yaxis=Eixo Y +ajouter=Adicionar +animation_active=O modo de anima\u00e7\u00e3o est\u00e1 ativo. +apercu = Pr\u00e9via +attend_positif = esperava um argumento positivo. +backward=Acima +bas = Baixa +bleu = Azul +bordermotif=Moldura +caractere_special_variable = Nomes de vari\u00e1veis n\u00e3o podem conter +caractere_special1=Nomes de procedimentos n\u00e3o podem conter +caractere_special2=caracteres \ + - * / ( ) [ ] = < > & | : +caractere_special3=Renomear +carre = quadrado +chaine_trop_longue = N\u00e3o posso imprimir palavra ou lista com mais de 32000 caracteres. +chat=Bate-papo (Chat) +chemin=Caminho +color_3_arguments=necessita uma lista com 3 argumentos: [vermelho verde azul] +commande=Comando: +comme_parametre = ] como argumentos. +couleur_du_crayon=Cor do l\u00e1pis +couleur_du_fond=Cor do fundo +dans=Em +definir=Voc\u00EA definiu +depassement_memoire=O aplicativo tomou 90% de mem\u00f3ria livre.\nSeu comando ser\u00e1 interrompido para prevenir sobrecarga na pilha ("stackoverflow").\nAssegure-se que seu programa n\u00e3o tem um la\u00e7o ("loop") infinito; se n\u00e3o, coloque um valor maior para a mem\u00f3ria alocada para o XLogo. +dernier = \u00daltimo +direction=Dire\u00e7\u00e3o +division_par_zero = N\u00e3o \u00e9 poss\u00edvel dividir por zero +dossier_parent = Diret\u00f3rio pai +draw_grid=Grade de fundo +echantillon = mostra +echantillon_texte = Isto \u00e9 uma pr\u00e9via +editeur=Editor +editor.redo=Refaz \u00faltima a\u00e7\u00e3o +editor.undo=Desfaz \u00faltima a\u00e7\u00e3o +effacer_editeur= limpar tela ao deixar o editor +element_dans_liste= elementos na lista [ +enlever=Remover +enregistreimage=Guardar imagem como... +enregistrer_espace = Eliminar vari\u00e1veis e procedimentos? +entre_zero_un = deve ser entre 0 e 1. +epaisseur_crayon = espessura m\u00e1xima do l\u00e1pis +erreur_compteur = sem contevezes fora de um repita. +erreur_crochet=Erro: faltou o ] +erreur_editeur=N\u00e3o posso salvar procedimentos.\nPor favor, verifique os pares APRENDA... FIM e\ntamb\u00e9m as defini\u00e7\u00f0es das vari\u00e1veis :a :b etc +erreur_fixestyle = mudeestilo s\u00f3 pode aceitar estes valores: nenhum, negrito, sublinhado, it\u00e1lico, riscado, sobreescrito ou subescrito. +erreur_format_image=Aceita imagens *.png e *.jpg +erreur_memoire = XLogo n\u00e3o tem mem\u00f3ria suficiente para criar a imagem desejada.\nEm "Op\u00e7\u00f0es", escolha um valor maior para a mem\u00f3ria. +erreur_nom_nombre_procedure = Nomes de procedimentos n\u00e3o podem ser n\u00fameros! +erreur_nom_nombre_variable = Nomes de vari\u00e1veis n\u00e3o podem ser n\u00fameros ! +erreur_pas_repertoire = diret\u00f3rio inv\u00e1lido ! +erreur_repetepour = deve conter 3 ou 4 elementos. [vari\u00e1vel min m\u00e1x incremento] +erreur_retourne = N\u00e3o \u00e9 poss\u00edvel usar devolve fora de um procedimento ! +erreur_sortie1=Tartaruga saiu da tela. +erreur_sortie2=N\u00famero de passos antes de sair: +erreur_stop = N\u00e3o \u00e9 poss\u00edvel usar pare fora de um procedimento ou recurs\u00e3o ! +erreur_tcp=Problema na comunica\u00e7\u00e3o de rede +erreur_variable = N\u00e3o \u00e9 uma vari\u00e1vel v\u00e1lida! +erreur=ERRO +error_bad_values=aceita apenas +error.3d.3vertex=Um pol\u00edgono deve ter ao menos 3 v\u00e9rtices! +error.3d.emptypolygon=A \u00e1rea de um pol\u00edgono n\u00e3o pode ser nula (zero)! +error.ioecriture=Erro de entrada-sa\u00edda (I/O): Desculpe, n\u00e3o \u00e9 poss\u00edvel guardar... +error.iolecture=Imposs\u00edvel ler arquivo especificado. +error.ne_peut_etre= n\u00e3o deveria estar aqui. +error.novalue= sem valor. +error.primitive2D=dispon\u00edvel apenas no modo 2D. +error.primitive3D=dispon\u00edvel apenas no modo 3D. +error.procedure.must.be=deve ser um procedimento +error.whattodo=Que devo fazer com +error.word= esperava uma palavra. +existe_deja= j\u00e1 existe. +faux="falso +ferme_editeur=Fechar janela do editor. +fichier_du_type = Arquivo do tipo +fichiers = Arquivo(s) +fichiers_logo=Arquivos Logo +fichiers_rtf = Arquivos RTF +file_100K=Escolha imagens de at\u00e9 100kb para evitar que esgote a mem\u00f3ria dispon\u00edvel. +fin_flux = N\u00e3o h\u00e1 mais caracteres para ler no fluxo n\u00b0 +fin=fim +find_replace=Substituir/Localizar +find=Localizar +flux_ecriture = N\u00e3o \u00e9 poss\u00edvel escrever nesse fluxo. +flux_existant = Fluxo j\u00e1 aberto. Feche-o antes de poder reutilizar este identificador. +flux_lecture = N\u00e3o \u00e9 poss\u00edvel ler esse fluxo. +flux_non_disponible = Nenhum fluxo aberto com esse identificador. +forme_crayon = Estilo do l\u00e1pis +forward=Abaixo +gui_exists=O seguinte componente gr\u00e1fico j\u00e1 existe: +haut = Alta +hollandais = Holand\u00eas +hsb = HSB +hsbbleu = B +hsbrouge = H +hsbvert = S +imagefile=Arquivos de Imagem +images=Imagens +imprimer_editeur=Imprimir procedimentos +interrompre_execution=Interromper a tarefa +je_ne_sais_pas=N\u00e3o sei como fazer +line=linha +lire_editeur=Guardar e sair do editor +liste_vide = A lista est\u00e1 vazia. +mainCommand=Comando principal: +memoire = Mem\u00f3ria alocada para XLogo (Mb): +menu.edition.copy=Copiar Ctl-C +menu.edition.cut=Recortar Ctl-X +menu.edition.paste=Colar Ctl-V +menu.edition.selectall = Selecione tudo +menu.edition=Edi\u00E7\u00E3o +menu.file.captureimage.clipboard = Copiar para clipboard +menu.file.captureimage.print=Imprimir imagem +menu.file.captureimage=Capturar imagem +menu.file.open=Abrir +menu.file.quit=Sair +menu.file.save=Guardar +menu.file.saveas=Guardar como... +menu.file.textzone = Zona de texto +menu.file.textzone.rtf = Guardar em formato RTF +menu.file=Arquivo +menu.help.about=Sobre... +menu.help.licence=Licen\u00e7a +menu.help.online=Manual +menu.help.translatedlicence=Tradu\u00E7\u00E3o da licen\u00e7a +menu.help.translatexlogo=Traduza o xLogo +menu.help=Ajuda +menu.tools.eraser=Apaga procedimentos +menu.tools.pencolor=Mudar cor do l\u00e1pis +menu.tools.preferences=Prefer\u00EAncias +menu.tools.screencolor=Mudar cor do fundo +menu.tools.startup=Arquivo inicial... +menu.tools.translate = Traduzir procedimentos +menu.tools= Ferramentas +message_a_propos1=XLOGO vers\u00e3o: +message_a_propos2=S\u00edtio: +message_a_propos3=Escreva para: +messages=Mensagens +mot_vide = A palavra deve conter pelo menos um caracter. +n_aime_pas = n\u00e3o aceita [ +nb_tortues = n\u00famero de tartarugas +ne_renvoie_pas= n\u00e3o \u00e9 sa\u00edda para +no_gui=O seguinte componente gr\u00e1fico n\u00e3o existe: +no_host=Problema na comunica\u00e7\u00e3o em rede com o computador com endere\u00e7o: +nom_du_fichier=Nome do arquivo: +nombre_unicode = deve ser entre 0 e 65535. +normal = Normal +note.do = d\u00f3 +note.fa = f\u00e1 +note.la = l\u00e1 +note.mi = mi +note.re = r\u00e9 +note.si = si +note.sol = sol +nouveau = Novo +nouveau_dossier = Criar nova pasta +ouvrir_editeur=Abrir o editor +parcourir=Examinar... +parenthese_fermante= ) n\u00e3o deveria estar aqui. +parenthese_ouvrante=Esperava por (. +parenthese_vide=N\u00e3o h\u00e1 nada entre ( e ) ! +pas_argument= argumento inv\u00e1lido. +pas_assez_de=Faltam dados para +pas_entier=n\u00e3o \u00e9 um inteiro! +pas_liste = n\u00e3o \u00e9 uma lista. +pas_nombre=n\u00e3o \u00e9 um n\u00famero! +pas_predicat= deve ser verdadeiro ou falso. +pas=Dist\u00e2ncia +pb_port=N\u00e3o foi poss\u00edvel conectar-se \u00e0 porta: +pencolor=Cor padr\u00e3o do l\u00e1pis +pour=aprenda +pref.cancel=Cancelar +pref.font= Fonte +pref.general.arabic=\u00c1rabe +pref.general.aspect=Apar\u00EAncia +pref.general.asturian=Asturiano +pref.general.catalan=Catal\u00e3o +pref.general.english=Ingl\u00EAs +pref.general.esperanto= Esperanto +pref.general.fast=R\u00e1pida +pref.general.french=Franc\u00EAs +pref.general.galician=Galego +pref.general.german=Alem\u00e3o +pref.general.greek=Grego +pref.general.hungarian=H\u00fangaro +pref.general.italian=Italiano +pref.general.lang=Idioma +pref.general.metal=Metal +pref.general.motif=Motivo +pref.general.portuguese=Portugu\u00EAs +pref.general.slow=Lenta +pref.general.spanish=Espanhol +pref.general.speed=Velocidade da Tartaruga +pref.general.windows=Windows +pref.general=Geral +pref.highlight.comment= Coment\u00e1rios +pref.highlight.enabled= Ative realce para sintaxe +pref.highlight.example= # Isto \u00e9 um coment\u00e1rio\n repita 4[pf 100 pd 90]\n +pref.highlight.init= Padr\u00f5es +pref.highlight.operand= Vari\u00e1veis, palavras, n\u00fameros +pref.highlight.other= Outro... +pref.highlight.parenthesis= Par\u00eanteses, colchetes +pref.highlight.primitive= Primitivas +pref.highlight= Realce +pref.ok= OK +pref.options.eraseVariables=Apagar as vari\u00e1veis ao fechar o editor +pref.options.tcp=N\u00famero da porta TCP +pref.options=Op\u00e7\u00f0es +pref.sound.instruments= instrumentos dispon\u00edveis +pref.sound.problem= N\u00e3o pude detectar interface MIDI! +pref.sound= Som +pref.turtles= Roupa da Tartaruga +primitives=Primitivas +probleme_sequence = N\u00e3o pude entender sua seq\u00fc\u00EAncia musical. Verifique-a! +procedure_demarrage=Comando a executar ao iniciar : +procedure_list=Procedimentos: +procedure_vide = Nomes de procedimentos n\u00e3o podem estar vazias! +qualite_dessin = Qualidade da imagem: +quit_editeur=Sair do editor sem guardar +quitter? = Deseja sair? +rechercher_dans=Examinar em: +relancer = As mudan\u00e7as ter\u00e3o efeito na pr\u00f3xima vez que iniciar o xLogo. +repertoire_accueil= Diret\u00f3rio inicial +repertoires = Pasta(s) +replace=Substituir +replaceall=Substituir tudo +replacewith=Substituir por: +restaurer = Restaurar +rgb = RGB +rond= circular +rouge = Vermelho +screencolor=Cor padr\u00e3o de fundo +seule_tortue_dispo= N\u00e3o \u00e9 poss\u00edvel deletar a \u00fanica tat ativa! +stop_chat=<<<<< Fim do bate-papo >>>>> +stop=Pare +string_not_found=Elemento n\u00e3o encontrado. +style.bold= Negrito +style.exposant = Sobreescrito +style.italic= It\u00e1lico +style.none= Nenhum +style.strike= Riscado +style.subscript= Subscrito +style.underline= Sublinhado +taille_dessin = Tamanho da janela gr\u00e1fica +title_axis=Eixo no fundo +titredialogue2=Guardando a imagem... +too_much_arguments=Muitos argumentos entre par\u00eanteses. +tortue_inaccessible= N\u00e3o posso criar uma tat com esse n\u00famero ! +traduire = Traduza! +traduire_de = Traduzir de: +translatecomplete=Completar uma tradu\u00e7\u00e3o +translateconsult=Consulta dispon\u00edvel +translatecreate=Criar uma nova tradu\u00e7\u00e3o +translatemessage=Ap\u00f3s completar os campos em uma guia (primitivas ou mensagens), clique no bot\u00e3o "OK" e envie o arquivo gerado para [email protected] +translatemodify=Modificar uma tradu\u00e7\u00e3o +translatewant=Voc\u00ea deseja: +un_caractere = deve conter um caracter. +uniform_color=Cor uniforme +variable_vide = Nomes de vari\u00e1veis n\u00e3o podem estar vazias. +vers = Para: +vert = Verde +vrai="verd +xgrid=Largura da quadr\u00edcula +y_a_pas = N\u00e3o h\u00e1 +ygrid=Altura da quadr\u00edcula +ws.settings.require_password=Protect these settings with a password. +ws.settings.password=Password +ws.settings.retype.password=Retype Password +ws.settings.save.password=Save Password +ws.settings.workspace=Workspace: +ws.settings.location=Location: +ws.settings.language=Language: +ws.settings.backups=Number of Backups: +ws.settings.user=User: +ws.settings.add=Add +ws.settings.remove=Remove +ws.settings.import=Import +ws.settings.enable.user.account.creation=Allow the users to create new user accounts? +ws.settings.save.and.close=Save and close +ws.settings.title=XLogo4Schools - Workspace Settings +ws.settings.global=Global +ws.settings.global.settings=Global Settings +ws.settings.workspace=Workspace +ws.settings.global.settings=Workspace Settings +ws.settings.cannot.store.pw=Cannot store new password: +ws.settings.pw.must.be.equal=Passwords must be equal. +ws.settings.virtual.ws.not.stored=A virtual workspace is not stored on the file system. +ws.settings.could.not.enter.wp=Could not enter workspace +ws.settings.create.new.wp=Create a new workspace +ws.settings.wp.name.non.empty=The workspace name cannot be empty. +ws.settings.wp.exists.already=The specified workspace exists already. +ws.settings.could.not.create.directory=Could not create the specified directory. +ws.settings.need.dir.not.file=You need to specify a directory, not a file. +ws.settings.could.not.create.ws=Could not create the workspace on the file system. +ws.settings.want.delete.dir.1=Do you want to delete the directory ' +ws.settings.want.delete.dir.2=' and its contents from the file system? +ws.settings.could.not.enter.virtual.ws=Could not enter virtual workspace +ws.settings.delete.from.fs=Delete from file system? +ws.settings.not.legal.ws.dir= is not a legal workspace directory. +ws.settings.enter.user.name=Enter user name +ws.settings.create.new.user=Create new user account +ws.settings.user.exists.already=The specified user exists in the workspace already. +ws.settings.remove.user="Remove user from file system?" +ws.settings.not.legal.user.dir= is not a legal user directory. +ws.settings.choose.other.name= already exists in the workspace. Choose another name. +ws.settings.name.conflict=Name Conflict +ws.settings.could.not.import.user=Could not import user: +ws.creation.panel.name=Workspace Name +ws.creation.panel.location=Location +ws.creation.panel.browse=Browse +welcome.workspace=Workspace +welcome.username=User +welcome.settings=Settings +welcome.enter=Enter +welcome.title=XLogo4Schools +welcome.wrong.pw=Wrong password. +welcome.enter.pw=Enter Password +welcome.could.not.enter.user=Could not enter user space: +storage.could.not.store.gc=Could not store global configurations +pref.general.abz.german.english=ABZ: English/German +ws.settings.damaged=Workspace directory is damaged or missing: + +procedure.unititialized=The procedure is uninitialized +procedure.executable=The procedure is executable +procedure.not.executable=The procedure is not executable +procedure.error=The procedure contains errors +error.proc.does.not.exist=The procedure does not exist. + +ws.generated.procedure=generated_procedures +ws.redefine.ambiguous.procedure= has more than one definition. I don't know which one to redefine. +error.call.ambiguous.procedure.name= has more than one definition. I don't know which one to execute. +ws.could.not.create.file=I could not create the file +ws.error.title=Workspace Error +ws.error.could.not.load.logo.files=Could not load some Logo files: +i.am.sorry=I'm sorry, but... +ws.error.userdir.not.dir=The specified source directory is not a directory and it could not be created. +ws.error.could.not.store.configs=I Could not store the configuration files: +ws.error.could.not.create.logo.file=Unfortunately I could not create a new file for the following reason: +new.file=New File + +contest.error.could.not.record.file=I could not record your recent changes. Please show this message to the contest organizers. +contest.mode.start=Start Contest Mode +contest.mode.stop=Stop Contest Mode +contest.mode.filename=Exercise +contest.mode.bonus.filename=Bonus Exercise +contest.error.title=Thank you! You just uncovered a nasty Bug! +contest.could.not.create=Unfortunately I could not create the files for the Contest. Please show this message to the contest organizers. +contest.could.not.store=Unfortunately I could not record your input. Please show this message to the contest organizers. + +ws.filename.exists.already=This file name exists already. please choose another one. +ws.attempt.open.inexistent.file=Attempt to open file that cannot be found in user space: +ws.attempt.close.not.open.file=Curious... I just tried to close a file which was never opened. +ws.automatic.save.failed=Unfortunately I was not able to automatically save your file for the following reason: +general.error.title=Oooops +editor.display.procedure.not.found= is not defined. + +name.error.dialog.title=Oooops +name.error.rename.inexistent.file=Unfortunately I cannot rename this file because I think that the file does not exist. +name.error.empty.name=A file cannot have an empty name. + +color.blue=Blue +color.dark=Dark +color.gray=Gray +color.green=Green +color.light=Light +color.orange=Orange +color.purple=Purple +color.red=Red +color.yellow=Yellow +logo.file.has.error=This file contains errors and it cannot be executed. + +error.while.creating.editor=Unfortunately I could not create the editor for the following reason : + +error.no.error=Hurray, the Procedure has no errors. Why do I bother you? Just to be consistent with my enum. +error.missing.to=The document should always start with 'to' +error.missing.name=I'm missing a procedure name. +error.name.is.number=A procedure name cannot be a number. +error.name.special=Procedure names should not contain special characters. +error.var.white.after.colon=There is a white space after the colon of one of your variables. +error.var.special=Variable names should not contain special characters. +error.var.is.number=Variable names cannot be numbers. +error.var.missing.colon=I'm missing a colon in the variable declaration. +error.opt.var.bracket=There is a problem with the brackets for optional variables. +error.var.extra.chars=I don't understand what you have written after the variable declaration. +error.missing.expr=I am missing a default value for one of the optional variables. +error.more.chars.after.end='End' should be alone on a new line. +error.missing.end=Your last procedure is missing an end. +error.to.before.end=I cannot find 'end' for the procedure +error.name.is.key.word=One of your names is a reserved key word. +error.procedure.ambiguous=There is another procedure with the same name. Every procedure should be called differently. + +hist.msg.procedures.undefined= I have forgotten : + +error.network.context=I don't understand the data received from the network. + +dialog.yes=Yes +dialog.no=no +us.could.not.store.recent.data=I could not store the recent user data : +illegal.name.msg=The chosen name contains illegal characters. +ws.does.not.exist=The specified workspace does not exist. +ws.not.a.workspace.dir=is not a legal workspace directory for import. +app.hello= Hello + +file.contains.errors=contains errors. + +us.import=Import File +us.export=Export File +us.save.image=Save Image + +us.export.msg=Choose a file to export: + +contest.number.of.files=Number of exercises: +contest.number.of.bonus.files = Number of bonus exercises: +ws.settings.syntax=Syntax Highlighting +ws.settings.contest=Contest / Record Mode
\ No newline at end of file diff --git a/logo/src/primitives.properties b/logo/src/primitives.properties new file mode 100644 index 0000000..4e25fc3 --- /dev/null +++ b/logo/src/primitives.properties @@ -0,0 +1,292 @@ +3d.downpitch= +3d.leftroll= +3d.lineend= +3d.linestart= +3d.orientation +3d.perspective= +3d.pitch= +3d.pointend= +3d.pointstart= +3d.polyend= +3d.polystart= +3d.polyview= +3d.rightroll= +3d.roll= +3d.setorientation= +3d.setpitch= +3d.setroll= +3d.setxyz= +3d.setz= +3d.textend= +3d.textstart= +3d.uppitch= +ajoute = ajoute +ajouteligneflux = ajouteligneflux +animation = animation +arithmetic.absolue= +arithmetic.acos= +arithmetic.arrondi = +arithmetic.asin= +arithmetic.atan= +arithmetic.cos= +arithmetic.difference = +arithmetic.div = +arithmetic.hasard= +arithmetic.inf= +arithmetic.infequal= +arithmetic.log10 = +arithmetic.moins = +arithmetic.pi= +arithmetic.produit = +arithmetic.puissance = +arithmetic.quotient= +arithmetic.racine= +arithmetic.reste = +arithmetic.sin= +arithmetic.somme = +arithmetic.sup= +arithmetic.supequal= +arithmetic.tan= +arithmetic.tronque= +attends = attends +axis= +axiscolor= +bc = bc baissecrayon +bc? = bc? baissecrayon? +bye= +cap = cap +caractere = car caractere +cat = cat catalogue +cc = cc couleurcrayon +cf = cf couleurfond +changedossier = cd changedossier +chattcp=chattcp +choix = choix +ci = ci chargeimage +clos = clos +color.blanc= +color.bleu= +color.bleufonce= +color.cyan= +color.gris= +color.grisclair= +color.jaune= +color.magenta= +color.marron= +color.noir= +color.orange= +color.rose= +color.rouge= +color.rougefonce= +color.vert= +color.vertfonce= +color.violet= +compte = compte +controls.compteur= +controls.repete = +controls.repetepour= +controls.stop = +controls.stoptout= +controls.tantque= +couleurtexte = ctexte couleurtexte +ct = ct cachetortue +date = date +de = de dessine +debuttemps = debuttemps +dernier = dernier der +distance = distance +drawing.arc= +drawing.av= +drawing.cercle= +drawing.etiquette = +drawing.fixecap= +drawing.fixex= +drawing.fixexy= +drawing.fixey= +drawing.fpos= +drawing.longueuretiquette= +drawing.origine= +drawing.point= +drawing.re= +drawing.saveimage= +drawing.td= +drawing.tg= +drawingquality= +ec = ec ecris +ecoutetcp=ecoutetcp +ecrisligneflux = ecrisligneflux +efseq = efseq effacesequence +egal? = egal? +enleve = enleve +enr = enr enroule +entier? = entier? +envoietcp=envoietcp +et = et +executetcp=executetcp +faux = faux +fcc = fcc fixecouleurcrayon +fcfg = fcfg fixecouleurfondgraphique +fct = fct fixecouleurtexte +fen = fen fenetre +fermeflux = fermeflux +findseq = findseq fixeindexsequence +finflux? = finflux? +finstr = finstr fixeinstrument +fintemps? = fintemps? +fixenompolice = fnp fixenompolice +fixenompolicetexte = fnpt fixenompolicetexte +fixeseparation = fsep fixeseparation +fixestyle = fsty fixestyle +fpolice = fixetaillepolice ftp +fpt = fixetaillepolicetexte ftpt +frep = frep fixerepertoire +ftc = ftc fixetaillecrayon +ftortue = ftortue fixetortue +go = go gomme +grid?= +gridcolor= +grille= +guiaction= +guibutton= +guidraw= +guimenu= +guiposition= +guiremove= +heure = heure +ic = ic inversecrayon +indseq = indseq indexsequence +instr = instr instrument +inverse = inverse +item = item +joue = joue +lc = lc levecrayon +lis = lis +liscar = liscar +liscarflux = liscarflux +lisligneflux = lisligneflux +lissouris = lissouris +liste = liste +liste? = liste? +listeflux = listeflux +md = md metsdernier +membre = membre +membre? = membre? +message = msg message +mot = mot +mot? = mot? +mp = mp metspremier +mt = mt montretortue +nettoie = nettoie +nombre? = nombre? +nompolice = np nompolice +nompolicetexte = npt nompolicetexte +non = non +ou = ou +ouvreflux = ouvreflux +penshape= +penwidth= +ph = ph phrase +police = taillepolice tp +pos = pos +possouris = possouris +precede? = precede? +premier = premier prem +prim? = prim? primtive? +proc? = proc? procedure? +ptexte = taillepolicetexte tpt +rafraichis = rf rafraichis +ramene = ramene +remplace = remplace +remplis = remplis +rempliszone = rempliszone +rep = rep repertoire +resetall= +ret = ret retourne +sauve = sauve +sauved = sauved +sd = sd saufdernier +separation = sep separation +seq = seq sequence +setaxiscolor= +setdrawingquality= +setgridcolor= +setpenshape= +setscreensize= +setturtlesnumber= +si = si +sound.mp3play= +sound.mp3stop= +souris? = souris? +sp = sp saufpremier +stopanimation= +stopaxis= +stopgrille= +style = sty style +taillefenetre=tf taillefenetre +tailleimage=tailledessin +tape = tape +tc = tc trouvecouleur +temps =temps +tortue = tortue +tortues = tortues +touche? = touche? +tuetortue = tuetortue +turtle.fforme= +turtle.forme= +turtlesnumber= +unicode = unicode +var?= +ve = ve videecran +vers = vers +vide? = vide? +visible? = visible? +vrai = vrai +vt = vt videtexte +workspace.chose = +workspace.def = +workspace.donne= +workspace.donnelocale= +workspace.efn= +workspace.efns= +workspace.efv= +workspace.exec = exec execute +workspace.gprop= +workspace.imts = imts +workspace.listevariables= +workspace.locale= +workspace.plist= +workspace.pprop= +workspace.remprop= +workspace.stoptrace= +workspace.trace= +xaxis?= +xaxis= +yaxis?= +yaxis= +zoom= +workspace.primitives= +workspace.propertylists= +workspace.content= +workspace.erpl= +arithmetic.exp= +arithmetic.log= +controls.ifelse= +workspace.ed= +workspace.edall= +controls.foreach= +controls.forever= +arithmetic.setdigits= +arithmetic.digits= +workspace.text= +workspace.externalcommand= +setzoom= +drawing.x= +drawing.y= +drawing.z= +drawing.fillpolygon= +arithmetic.alea= +loop.dountil= +loop.dowhile= +aritmetic.modulo= +drawing.setfontjustify= +drawing.fontjustify=
\ No newline at end of file diff --git a/logo/src/primitives_ar_MA.properties b/logo/src/primitives_ar_MA.properties new file mode 100644 index 0000000..a65813f --- /dev/null +++ b/logo/src/primitives_ar_MA.properties @@ -0,0 +1,288 @@ +3d.downpitch=\u062f\u0648\u0631\u0627\u0646\u0645\u0633\u062a\u0639\u0631\u0636 +3d.leftroll=\u062f\u0648\u0631\u0627\u0646\u0637\u0648\u0644\u064a\u064a\u0633\u0627\u0631 +3d.lineend=\u0646\u0647\u0627\u064a\u0629\u062e\u0637 +3d.linestart=\u0628\u062f\u0627\u064a\u0629\u062e\u0637 +3d.orientation=\u0627\u062a\u062c\u0627\u0647 +3d.perspective=\u0645\u0646\u0638\u0648\u0631 +3d.pitch=\u0627\u0646\u062d\u0646\u0627\u0621\u0645\u062d\u0648\u0631\u0623\u0641\u0627\u0635\u064a\u0644 +3d.pointend=\u0646\u0647\u0627\u064a\u0629\u0646\u0642\u0637\u0629 +3d.pointstart=\u0628\u062f\u0627\u064a\u0629\u0646\u0642\u0637\u0629 +3d.polyend=\u0646\u0647\u0627\u064a\u0629\u0645\u0636\u0644\u0639 +3d.polystart=\u0628\u062f\u0627\u064a\u0629\u0645\u0636\u0644\u0639 +3d.polyview=\u0639\u0631\u0636\u0645\u0636\u0644\u06393 +3d.rightroll=\u062f\u0648\u0631\u0627\u0646\u0637\u0648\u0644\u064a\u064a\u0645\u064a\u0646 +3d.roll=\u062f\u0648\u0631\u0627\u0646\u0637\u0648\u0644\u064a +3d.setorientation=\u062d\u062f\u062f\u0627\u062a\u062c\u0627\u0647 +3d.setpitch=\u062d\u062f\u062f\u0645\u062d\u0648\u0631\u062a\u0645\u0648\u062c \u062d\u0645\u062a +3d.setroll=\u062d\u062f\u062f\u062f\u0648\u0631\u0627\u0646\u0637\u0648\u0644\u064a \u062d\u062f\u0637 +3d.setxyz=\u062d\u062f\u062fxyz +3d.setz=\u062a\u062d\u062f\u064a\u062f\u0627\u062a +3d.textend=\u0646\u0647\u0627\u064a\u0629\u0646\u0635 +3d.textstart=\u0628\u062f\u0627\u064a\u0629\u0646\u0635 +3d.uppitch=\u062f\u0648\u0631\u0627\u0646\u0645\u0633\u062a\u0639\u0631\u0636\u0641\u0648\u0642 +ajoute = \u0623\u0636\u0641 +ajouteligneflux = \u0627\u0636\u0641\u0633\u0637\u0631\u0627\u0646\u062f\u0641\u0627\u0642 +animation = \u062a\u0646\u0634\u064a\u0637 +arithmetic.absolue = \u0645\u0637\u0644\u0642 +arithmetic.acos = acos arccosinus +arithmetic.arrondi = \u062c\u0628\u0631 +arithmetic.asin = asin arcsinus +arithmetic.atan = atan arctangente +arithmetic.cos = \u062c\u064a\u0628\u062a\u0645\u0627\u0645 +arithmetic.difference = \u0637\u0631\u062d +arithmetic.digits=\u0639\u0634\u0631\u064a +arithmetic.div = \u0642\u0633\u0645\u0629 +arithmetic.exp=exp +arithmetic.hasard = \u0639\u0634\u0648\u0627\u0626\u064a +arithmetic.log=log +arithmetic.log10 = log10 +arithmetic.moins = \u0646\u0627\u0642\u0635 +arithmetic.pi = pi +arithmetic.produit = \u062c\u062f\u0627\u0621 +arithmetic.puissance = \u0642\u062f\u0631\u0629 +arithmetic.quotient = \u0642\u0627\u0633\u0645 +arithmetic.racine = \u062c\u062f\u0631 +arithmetic.reste = \u0628\u0627\u0642\u064a +arithmetic.setdigits=\u062b\u0628\u062a\u0639\u0634\u0631\u064a +arithmetic.sin = \u062c\u064a\u0628 +arithmetic.somme=\u062c\u0645\u0639 +arithmetic.tan = tan tangente +arithmetic.tronque = \u0627\u0642\u0637\u0639 +attends = \u0627\u0646\u062a\u0638\u0631 +axis=\u0645\u062d\u0627\u0648\u0631 +axiscolor=\u0644\u0648\u0646\u0645\u062d\u0627\u0648\u0631 +bc = \u062e\u0642 \u062e\u062f\u0642\u0644\u0645 +bc? = \u0628\u0627\u0644\u0642\u0644\u0645 +bye=\u0648\u062f\u0627\u0639\u0627 +cap = \u0631\u0623\u0633 +caractere = \u062d\u0631\u0641 +cat = \u0628\u064a\u0627\u0646\u0627\u062a +cc = \u0644\u0642 \u0644\u0648\u0646\u0642\u0644\u0645 +cf = \u0644\u062e \u0644\u0648\u0646\u062e\u0644\u0641\u064a\u0629 +changedossier = \u063a\u0645 \u063a\u064a\u0631\u0645\u062c\u0644\u062f +chattcp=\u062f\u0631\u062f\u0634\u0629tcp +choix = \u0627\u062e\u062a\u064a\u0627\u0631 +ci = \u062d\u0635 \u062d\u0645\u0644\u0635\u0648\u0631\u0629 +clos = \u0645\u0633\u064a\u062c +color.blanc = \u0623\u0628\u064a\u0636 +color.bleu = \u0623\u0632\u0631\u0642 +color.bleufonce = \u0623\u0632\u0631\u0642\u063a\u0627\u0644\u0642 +color.cyan = \u0633\u0645\u0627\u0621 +color.gris = \u0631\u0645\u0627\u062f\u064a +color.grisclair = \u0631\u0645\u0627\u062f\u064a\u0628\u0627\u0647\u062a +color.jaune = \u0623\u0635\u0641\u0631 +color.magenta =\u0641\u0646\u062f\u064a +color.marron = \u0642\u0647\u0648\u064a +color.noir = \u0623\u0633\u0648\u062f +color.orange = \u0628\u0631\u062a\u0642\u0627\u0644\u064a +color.rose = \u0648\u0631\u062f\u064a +color.rouge = \u0623\u062d\u0645\u0631 +color.rougefonce = \u0623\u062d\u0645\u0631\u063a\u0627\u0644\u0642 +color.vert = \u0623\u062e\u0636\u0631 +color.vertfonce = \u0623\u062e\u0636\u0631\u063a\u0627\u0644\u0642 +color.violet = \u0641\u064a\u0648\u0644\u064a +compte = \u0627\u062d\u0633\u0628 +controls.compteur = \u0639\u062f\u0627\u062f +controls.foreach=\u0644\u0643\u0644\u0648\u0627\u062d\u062f\u0629 +controls.forever=\u0627\u0639\u062f\u0645\u0627\u0644\u0627\u0646\u0647\u064a\u0629 +controls.ifelse=\u0625\u0630\u0627\u0644\u0627 +controls.repete = \u0623\u0639\u062f +controls.repetepour = \u0623\u0639\u062f\u0645\u0646\u0623\u062c\u0644 +controls.stop = \u0642\u0641 +controls.stoptout = \u0623\u0642\u0641\u0627\u0644\u0643\u0644 +controls.tantque = \u0645\u0627\u062f\u0627\u0645 +couleurtexte = \u0644\u0648\u0646\u062d\u0631\u0641 \u0644\u062d +ct = \u062e\u0628\u0623 +date = \u064a\u0648\u0645 +de = \u0627\u0631\u0633\u0645 +debuttemps = \u0628\u0632 \u0628\u062f\u0627\u064a\u0629\u0632\u0645\u0646 +dernier = \u0622\u062e\u0631 +distance = \u0645\u0633\u0627\u0641\u0629 +drawing.arc = \u0642\u0648\u0633 +drawing.av = \u062a\u0642\u062f\u0645 +drawing.cercle = \u062f\u0627\u0626\u0631\u0629 +drawing.etiquette = \u0628\u0637\u0627\u0642\u0629 +drawing.fixecap = \u062d\u062f\u062f\u0631\u0623\u0633 \u062d\u0631 +drawing.fixex = \u062d\u062f\u062fx +drawing.fixexy = \u062d\u062f\u062fxy +drawing.fixey = \u062d\u062f\u062fy +drawing.fpos = \u062d\u062f\u062fxy +drawing.longueuretiquette= \u0637\u0628 \u0637\u0648\u0644\u0628\u0637\u0627\u0642\u0629 +drawing.origine = \u0627\u0644\u0623\u0635\u0644 +drawing.point = \u0646\u0642\u0637\u0629t +drawing.re = \u062a\u0631\u0627\u062c\u0639 +drawing.saveimage=\u0627\u062d\u0641\u0638\u0635\u0648\u0631\u0629 +drawing.td = \u064a\u0645\u064a\u0646 +drawing.tg = \u064a\u0633\u0627\u0631 +drawingquality= \u062c\u0648\u062f\u0629\u0631\u0633\u0645 \u062c\u0631 +ec = \u0627\u0643\u062a\u0628 +ecoutetcp=\u0639\u0627\u064a\u0646tcp +ecrisligneflux = \u0627\u0643\u062a\u0628\u0633\u0637\u0631\u0627\u0646\u062f\u0641\u0627\u0642 +efseq = \u0627\u0645 \u0627\u0645\u0633\u062d\u0645\u062a\u062b\u0627\u0644\u064a\u0629 +egal? = \u064a\u0633\u0627\u0648\u064a? +enleve = \u0627\u0631\u0641\u0639 +enr = \u0643\u0648\u0631 +entier? = \u0635\u062d\u064a\u062d? +envoietcp=\u0627\u0631\u0633\u0644 +et = \u0648 +executetcp=\u0646\u0641\u062ftcp +faux = \u062e\u0637\u0623 +fcc = \u062d\u0644\u0642 \u062d\u062f\u062f\u0644\u0648\u0646\u0642\u0644\u0645 +fcfg = \u062d\u0644\u062e \u062d\u062f\u062f\u0644\u0648\u0646\u062e\u0644\u0641\u064a\u0629 +fct = \u062d\u0644\u062d \u062d\u062f\u062f\u0644\u0648\u0646\u062d\u0631\u0641 +fen = \u0646\u0627\u0641\u0630\u0629 +fermeflux = \u0627\u0642\u0641\u0644\u0627\u0646\u062f\u0641\u0627\u0642 +findseq = \u062d\u0631\u0645 \u062d\u062f\u062f\u0631\u0642\u0645\u0645\u062a\u062b\u0627\u0644\u064a\u0629 +finflux? = \u0646\u0647\u0627\u064a\u0629\u0627\u0646\u062f\u0641\u0627\u0642? +finstr = \u062d\u0623 \u062d\u062f\u062f\u0623\u062f\u0627\u0629 +fintemps? = \u0646\u0647\u0627\u064a\u0629\u0632\u0645\u0646? +fixenompolice = \u062d\u0625\u062d \u062d\u062f\u062f\u0623\u0633\u0645\u062d\u0631\u0641 +fixenompolicetexte = \u062d\u0625\u0646 \u062d\u062f\u062f\u0625\u0633\u0645\u0646\u0635 +fixeseparation = \u062d\u062f\u062f\u0627\u0644\u0641\u0635\u0644 +fixestyle = \u062d\u0633 \u062d\u062f\u062f\u0633\u062a\u064a\u0644 +fpolice = \u062d\u0637\u062d \u062d\u062f\u062f\u0637\u0648\u0644\u062d\u0631\u0641 +fpt = \u062d\u062f\u062f\u0637\u0648\u0644\u062d\u0631\u0641 \u062d\u0637\u062d +frep = \u062d\u0645 \u062d\u062f\u062f\u0645\u062c\u0644\u062f +ftc = \u062d\u0642\u0642 \u062d\u062f\u062f\u0642\u0627\u0645\u0629\u0642\u0644\u0645 +ftortue = \u062d\u0633 \u062d\u062f\u062f\u0633\u0644\u062d\u0641\u0627\u0629 +go = \u0645\u0645\u0633\u062d\u0629 +grid?=\u0634\u0628\u0643\u0629\u061f +gridcolor=\u0644\u0648\u0646\u0634\u0628\u0643\u0629 +grille=\u0634\u0628\u0643\u0629 +guiaction=\u0627\u0631\u0633\u0645\u0641\u0639\u0644 +guibutton=\u0627\u0631\u0633\u0645\u0632\u0631 +guidraw=\u0627\u0631\u0633\u0645\u0631\u0633\u0645 +guimenu=\u0627\u0631\u0633\u0645\u0642\u0627\u0626\u0645\u0629 +guiposition=\u0627\u0631\u0633\u0645\u0645\u0648\u0642\u0639 +guiremove=\u0627\u0631\u0633\u0645\u0645\u0633\u062d +heure = \u0633\u0627\u0639\u0629 +ic = \u0639\u0642 \u0639\u0643\u0633\u0642\u0644\u0645 +indseq = \u0631\u0645 \u0631\u0642\u0645\u0645\u062a\u062b\u0627\u0644\u064a\u0629 +instr = \u0623\u062f\u0627\u0629 +inverse = \u0639\u0643\u0633 +item = \u0633\u0624\u0627\u0644 +joue = \u0627\u0644\u0639\u0628 +lc = \u062f\u0642 \u062f\u0648\u0646\u0642\u0644\u0645 +lis = \u0627\u0642\u0631\u0623 +liscar = \u0627\u0642\u0631\u0623\u062d\u0631\u0641 +liscarflux = \u0627\u0642\u0631\u0623\u0627\u0646\u062f\u0641\u0627\u0642\u062d\u0631\u0641 +lisligneflux = \u0627\u0642\u0631\u0623\u0627\u0646\u062f\u0641\u0627\u0642\u0633\u0637\u0631 +lissouris = \u0627\u0641 \u0627\u0642\u0631\u0623\u0641\u0623\u0631\u0629 +liste = \u0642\u0627\u0626\u0645\u0629 +liste? = \u0642\u0627\u0626\u0645\u0629? +listeflux = \u0642\u0627\u0626\u0645\u0629\u0627\u0646\u062f\u0641\u0627\u0642 +md = \u0636\u0646 \u0636\u0639\u0646\u0647\u0627\u064a\u0629 +membre = \u0639\u0636\u0648 +membre? = \u0639\u0636\u0648? +message = \u0625\u0634\u0627\u0631\u0629 +mot = \u0643\u0644\u0645\u0629 +mot? = \u0643\u0644\u0645\u0629? +mp = \u0636\u0628 \u0636\u0639\u0628\u062f\u0627\u064a\u0629 +mt = \u0627\u0638\u0647\u0631 +nettoie = \u0646\u0638\u0641 +nombre? = \u0639\u062f\u062f? +nompolice = \u0625\u0633\u0645\u062d\u0631\u0641 \u0625\u062d +nompolicetexte = \u0625\u0646 \u0625\u0633\u0645\u0646\u0635 +non = \u0644\u0627 +ou = \u0623\u0648 +ouvreflux = \u0627\u0641\u062a\u062d\u0627\u0646\u062f\u0641\u0627\u0642 \u0627\u0627 +penshape= \u0634\u0643\u0644\u0642\u0644\u0645 \u0634\u0642 +penwidth= \u0642\u064a\u0627\u0633\u0642\u0644\u0645 \u0642\u0642 +ph = \u062c\u0645\u0644\u0629 +police = \u0637\u0648\u0644\u062d\u0631\u0641 +pos = \u0645\u0648\u0642\u0639 +possouris = \u0645\u0648\u0642\u0639\u0641\u0623\u0631\u0629 +precede? = \u0633\u0627\u0628\u0642? +premier = \u0623\u0648\u0644 +prim? = \u0623\u0645\u0631? +proc? = \u0628\u0631\u0646\u0627\u0645\u062c? +ptexte = \u0637\u062d \u0637\u0648\u0644\u062d\u0631\u0641 +rafraichis = \u0627\u0646\u062a\u0639\u0627\u0634 +ramene = \u0631\u062f +remplace = \u0628\u062f\u0644 +remplis = \u0627\u0645\u0644\u0623 +rempliszone = \u0627\u0645\u0644\u0623\u0645\u0646\u0637\u0642\u0629 +rep = \u0645\u062c\u0644\u062f +resetall= \u0628\u062f\u0627\u064a\u0629 +ret = \u0627\u0639\u0637 +sauve = \u0627\u062d\u0641\u0638 +sauved = \u0645\u062d\u0641\u0648\u0638 +sd = \u062f\u0622 \u062f\u0648\u0646\u0622\u062e\u0631 +separation = \u0641\u0635\u0644 +seq = \u0645\u062a\u062b\u0627\u0644\u064a\u0629 +setaxiscolor=\u062d\u062f\u062f\u0644\u0648\u0646\u0645\u062d\u0627\u0648\u0631 +setdrawingquality= \u062d\u062f\u062f\u062c\u0648\u062f\u0629\u0631\u0633\u0645 \u062d\u062c\u0631 +setgridcolor=\u062d\u062f\u062f\u0644\u0648\u0646\u0634\u0628\u0643\u0629 +setpenshape= \u062d\u062f\u062f\u0634\u0643\u0644\u0642\u0644\u0645 \u062d\u0634\u0642 +setscreensize= \u062d\u062f\u062f\u0642\u064a\u0627\u0633\u0631\u0633\u0645 \u062d\u0642\u0631 +setturtlesnumber= \u062d\u062f\u062f\u0639\u062f\u062f\u0623\u0642\u0635\u0649 \u062d\u0639\u0623 +setzoom=\u062d\u062f\u062f\u062a\u0643\u0628\u064a\u0631 \u062d\u062a +si = \u0625\u0630\u0627 +sound.mp3play=\u0627\u0644\u0639\u0628mp3 +sound.mp3stop=\u0623\u0642\u0641mp3 +souris? = \u0641\u0623\u0631\u0629? +sp = \u062f\u0623 \u062f\u0648\u0646\u0623\u0648\u0644 +stopanimation=\u0623\u0642\u0641\u062a\u0646\u0634\u064a\u0637 \u0623\u062a +stopaxis=\u0627\u0642\u0641\u0645\u062d\u0627\u0648\u0631 +stopgrille=\u0623\u0642\u0641\u0634\u0628\u0643\u0629 \u0623\u0634 +style = \u0633\u062a\u064a\u0644 +taillefenetre=\u0637\u0646 \u0637\u0648\u0644\u0646\u0627\u0641\u0630\u0629 +tailleimage= \u0642\u064a\u0627\u0633\u0631\u0633\u0645 +tape = \u0627\u0636\u063a\u0637 +tc = \u0623\u0644 \u0623\u062c\u062f\u0644\u0648\u0646 +temps =\u0632\u0645\u0646s +tortue = \u0633\u0644\u062d\u0641\u0627\u0629 +tortues = \u0633\u0644\u0627\u062d\u0641 +touche? = \u0644\u0645\u0633? +tuetortue = \u0627\u0642\u062a\u0644\u0633\u0644\u062d\u0641\u0627\u0629 +turtle.fforme = \u062d\u0634 \u062d\u062f\u062f\u0634\u0643\u0644 +turtle.forme = \u0634\u0643\u0644 +turtlesnumber= \u0639\u062f\u062f\u0623\u0642\u0635\u0649 +unicode = \u0643\u0648\u062f +var?=\u0645\u062a\u063a\u064a\u0631\u061f +ve = \u0627\u0645\u0633\u062d +vers = \u0627\u062a\u062c\u0627\u0647s +vide? = \u0641\u0627\u0631\u063a? +visible? = \u0638\u0627\u0647\u0631? +vrai = \u0635\u062d\u064a\u062d +vt = \u0627\u0646 \u0627\u0641\u0631\u063a\u0646\u0635 +workspace.chose = \u0634\u064a\u0626 +workspace.content=\u0645\u0636\u0645\u0648\u0646 +workspace.def = \u062d\u062f\u062f +workspace.donne = \u0627\u0639\u0637 +workspace.donnelocale = \u0627\u0639\u0637\u0645\u062d\u0644\u064a \u0644\u064a\u0643\u0646 +workspace.ed=\u0646\u0633\u062e +workspace.edall=\u0646\u0633\u062e\u0643\u0644 +workspace.efn = \u0627\u0625 \u0627\u0645\u0633\u062d\u0625\u0633\u0645 +workspace.efns = \u0627\u0623 \u0627\u0645\u0633\u062d\u0623\u0633\u0645\u0627\u0621 +workspace.efv = \u0627\u0645 \u0627\u0645\u0633\u062d\u0645\u062a\u063a\u064a\u0631\u0629 +workspace.erpl=\u0627\u062d\u062f\u0641\u062e\u0627\u0635\u064a\u0629 +workspace.externalcommand=\u0627\u0645\u0631\u062e\u0627\u0631\u062c\u064a +workspace.exec = \u0646\u0641\u062f +workspace.gprop=\u0627\u0631\u062c\u0639\u062e\u0627\u0635\u064a\u0629 +workspace.imts = \u0627\u0637\u0628\u0639 +workspace.listevariables = \u0627\u0642\u0631\u0623\u0645\u062a\u063a\u064a\u0631\u0629 +workspace.locale = \u0645\u062d\u0644\u064a\u0629 +workspace.plist=\u0642\u0627\u0626\u0645\u0629\u062e\u0627\u0635\u064a\u0627\u062a +workspace.pprop=\u0627\u0636\u0641\u062e\u0627\u0635\u064a\u0629 +workspace.primitives=\u0627\u0644\u0623\u0648\u0627\u0645\u0631 \u0627\u0644\u0623\u0635\u0644\u064a\u0629 +workspace.propertylists=\u0642 +workspace.remprop=\u0627 +workspace.stoptrace=\u0623\u0642\u0641 +workspace.text=\u0646\u0635 +workspace.trace = \u0633\u0637\u0631 +xaxis?=\u0645\u062d\u0648\u0631\u0627\u0641\u0627\u0635\u064a\u0644\u061f +xaxis=\u0645\u062d\u0648\u0631\u0627\u0641\u0627\u0635\u064a\u0644 +yaxis?=\u0645\u062d\u0648\u0631\u0627\u0631\u0627\u062a\u0628\u061f +yaxis=\u0645\u062d\u0648\u0631\u0627\u0631\u0627\u062a\u064a\u0628 +zoom=\u0632\u0648\u0645 +drawing.x=x +drawing.y=y +drawing.z=z +drawing.fillpolygon=\u0645\u0636\u0644\u0639\u0645\u0645\u0644\u0648\u0621 +arithmetic.alea=\u0639\u0634\u0648\u0627\u0626\u064a +loop.dountil=\u0627\u0641\u0639\u0644\u062d\u062a\u0649 \u0643\u0631\u0631\u062d\u062a\u0649 +loop.dowhile=\u0627\u0641\u0639\u0644\u0645\u0627\u062f\u0627\u0645 \u0643\u0631\u0631\u0645\u0627\u062f\u0627\u0645 +aritmetic.modulo=\u0645\u0648\u062f \u0645\u0648\u062f\u0648\u0644\u0648 +drawing.setfontjustify=\u0627\u0644\u062e\u0637\u0645\u0644\u0623\u0627\u0644\u0633\u0637\u0631 +drawing.fontjustify=\u0644\u062e\u0637\u0645\u0644\u0623\u0627\u0644\u0633\u0637
\ No newline at end of file diff --git a/logo/src/primitives_as_ES.properties b/logo/src/primitives_as_ES.properties new file mode 100644 index 0000000..96f6d7a --- /dev/null +++ b/logo/src/primitives_as_ES.properties @@ -0,0 +1,288 @@ +3d.downpitch = bn cabeceaabaxo baxanariz +3d.leftroll = bi balanceaizquierda +3d.lineend = finllinia finll\u00ednia +3d.linestart = defllinia definellinia entamallinia entamall\u00ednia definell\u00ednia +3d.orientation = orientacion orientaci\u00f3n +3d.perspective = perspeutiva +3d.pitch = cabeceu cabec\u00e9u +3d.pointend = finptu finpuntu +3d.pointstart = defptu definepuntu entamapuntu +3d.polyend = finpoli finpoligonu finpol\u00edgonu +3d.polystart = defpoli definepoligonu definepol\u00edgonu entamapoligonu entamapol\u00edgonu +3d.polyview = vistapoligonu vistapol\u00edgonu vista3d +3d.rightroll = bd balanceadrecha +3d.roll = balanceu balanc\u00e9u +3d.setorientation = ponorientacion ponorientaci\u00f3n +3d.setpitch = poncabeceu poncabec\u00e9u +3d.setroll = ponbalanceu ponbalanc\u00e9u +3d.setxyz = ponxyz +3d.setz = ponz +3d.textend = fintxt fintestu +3d.textstart = deftxt entamatestu definetestu +3d.uppitch = sn cabeceaarriba subenariz +ajoute = axunta +ajouteligneflux = axuntalliniafluxu +animation = animacion animaci\u00f3n +arithmetic.absolue = abs absolutu +arithmetic.acos = acos arcucosenu +arithmetic.arrondi = arredondia +arithmetic.asin = asen arcusenu +arithmetic.atan = atan arcutanxente +arithmetic.cos = cos cosenu +arithmetic.difference = diferencia +arithmetic.digits=decimales +arithmetic.div = div division divisi\u00f3n +arithmetic.exp=exp +arithmetic.hasard = azar +arithmetic.log=ln logneperiano +arithmetic.log10 = log10 log +arithmetic.moins = cs cambiasignu camudasignu +arithmetic.pi = pi +arithmetic.produit = productu +arithmetic.puissance = potencia +arithmetic.quotient = cociente +arithmetic.racine = rc raizcuadrada +arithmetic.reste = restu +arithmetic.setdigits=pondecimales +arithmetic.sin = sen senu +arithmetic.somme = suma +arithmetic.tan = tan tanxente +arithmetic.tronque = trunca truncar +attends = espera +axis = axes exes +axiscolor = colorexes +bc = bl baxallapiceru +bc? = bl? baxallapiceru? +bye = adios adi\u00f3s +cap = rumbu +caractere = car caracter +cat = cat catalogu cat\u00e1logu +cc = cl colorllapiceru +cf = cf colorfueya +changedossier = cd camudadireutoriu +chattcp = chattcp +choix = escueye +ci = ci cargaimaxe +clos = mouxaula +color.blanc = blanco +color.bleu = azul +color.bleufonce = azuloscuru +color.cyan = cyan cian +color.gris = gris +color.grisclair = grisclaru +color.jaune = mariello +color.magenta = maxenta +color.marron = marron marr\u00f3n +color.noir = negro +color.orange = naranxa +color.rose = rosa +color.rouge = colorao +color.rougefonce = coloraooscuru +color.vert = verde +color.vertfonce = verdeoscuru +color.violet = morao +compte = cuenta +controls.compteur = cuentarepite contador +controls.foreach=pacada +controls.forever=repitisiempre +controls.ifelse=sisinon +controls.repete = repite +controls.repetepour = repitepa +controls.stop = alto +controls.stoptout = aparatoo +controls.tantque = mientres mentantu +couleurtexte = colortestu +ct = gt guardatortuga +date = fecha +de = plla ponllapiceru +debuttemps = crono cronometru cron\u00f3metru +dernier = ultimu \u00faltimu +distance = distancia +drawing.arc = arcu +drawing.av = av avanza alantre +drawing.cercle = circulu c\u00edrculu +drawing.etiquette = rotula +drawing.fixecap = ponr ponrumbu +drawing.fixex = ponx +drawing.fixexy = ponxy +drawing.fixey = pony +drawing.fpos = ponpos ponposicion ponposici\u00f3n +drawing.longueuretiquette = le llargoretiqueta +drawing.origine = centru +drawing.point = puntu +drawing.re = re recula +drawing.saveimage=guardaimaxe +drawing.td = xd xiradrecha +drawing.tg = xi xiraizquierda +drawingquality = cdib calidadibuxu calid\u00e1dibuxu +ec = es escribi +ecoutetcp = escuchatcp +ecrisligneflux = escribilliniafluxu +efseq = bos borrasecuencia +egal? = iguales? +enleve = quita +enr = mouvuelta +entier? = enteru? +envoietcp = mtcp mandatcp +et = y +executetcp = executatcp +faux = falso +fcc = poncl poncolorllapiceru +fcfg = poncf poncolorfueya +fct = pctestu poncolortestu +fen = mouventanu +fermeflux = zarrafluxu piesllafluxu +findseq = pindsec ponindizsecuencia +finflux? = finfluxu? +finstr = pinstr poninstrumentu +fintemps? = fincrono? fincronometru? fincron\u00f3metru? +fixenompolice = pnf ponnomefonte +fixenompolicetexte = pnft ponnomefontetestu +fixeseparation = ponsep ponseparacion ponseparaci\u00f3n ponsepartacion ponsepartaci\u00f3n +fixestyle = pest ponestilu +fpolice = pf ponfonte +fpt = pft ponfontetestu +frep = pondir pondireutoriu +ftc = pongrosor +ftortue = ptortuga pontortuga +go = go goma +grid? = cuadricula? cuadr\u00edcula? +gridcolor = colorcuadricula colorcuadr\u00edcula +grille = cuadricula cuadr\u00edcula +guiaction = aicionigu +guibutton = botonigu +guidraw = dibuxaigu +guimenu = menuigu +guiposition = posicionigu +guiremove = eliminaigu +heure = hora +ic = illa inviertellapiceru +indseq = indsec indizsecuencia +instr = instr instrumentu +inverse = invierte +item = elementu +joue = tocamusica tocam\u00fasica +lc = sl subellapiceru +lis = lleeteclau lleetecl\u00e1u lleellista +liscar = lleecar lleetecla +liscarflux = lleecarfluxu +lisligneflux = lleelliniafluxu +lissouris = lleemur lleeraton lleerat\u00f3n +liste = llista +liste? = llista? +listeflux = llistafluxos +md = pu ponultimu pon\u00faltimo +membre = miembru +membre? = miembru? +message = msx mensaxe +mot = pallabra +mot? = pallabra? +mp = pp ponprimeru +mt = et ense\u00f1atortuga amuesatortuga +nettoie = llimpia +nombre? = numberu? n\u00famberu? +nompolice = nf nomefonte +nompolicetexte = nft nomefontetestu +non = no +ou = o +ouvreflux = abrefluxu +penshape = fl formallapiceru +penwidth = gl grosorllapiceru +ph = fr frase fras +police = fonte +pos = pos posicion posici\u00f3n +possouris = posmur posraton posrat\u00f3n +precede? = enantes? anterior? +premier = pr primeru +prim? = prim? primitiva? +proc? = proc? procedimientu? +ptexte = ftestu fontetestu +rafraichis = refresca refrescar +ramene = carga +remplace = cambia +remplis = enllena +rempliszone = enllenazona +rep = dir direutoriu +resetall = inicializa aniciatoo +ret = dev devuelve +sauve = guarda +sauved = guardatoo +sd = mu menosultimu menos\u00faltimu +separation = separacion separaci\u00f3n separtacion separtaci\u00f3n +seq = sec secuencia +setaxiscolor = pce poncoloraxes poncolorexes +setdrawingquality = pcd poncalidadibuxu poncalid\u00e1dibuxu +setgridcolor = pcc poncolorcuadricula poncolorcuadr\u00edcula +setpenshape = pfl ponformallapiceru +setscreensize = ptp pontama\u00f1upantalla +setturtlesnumber = pmt ponmasimestortugues +setzoom=ponzoom ponlupa +sound.mp3play=tocamp3 +sound.mp3stop=aparamp3 +si = si +souris? = mur? raton? rat\u00f3n? +sp = mp menosprimeru menosprimeru +stopanimation = aparaanimacion aparanimaci\u00f3n +stopaxis = borraaxes borraexes +stopgrille = borracuadricula borracuadr\u00edcula +style = est estilu +taillefenetre = tv tama\u00f1uventanu requexosventanu +tailleimage = tpant tama\u00f1upantalla +tape = tipea mecanografia mecanograf\u00eda +tc = ac alcuentracolor +temps = tiempu +tortue = tortuga +tortues = tortugues +touche? = tecla? +tuetortue = eliminatortuga +turtle.fforme = pforma ponforma +turtle.forme = forma +turtlesnumber = mast masimestortugues +unicode = unicode +var? = var? variable? +ve = bp borrapantalla +vers = hacia +vide? = vaciu? vac\u00edu? +visible? = visible? +vrai = cierto +vt = bt borratestu +workspace.chose = oxetu cosa +workspace.content=conteniu conten\u00edu +workspace.def = def define +workspace.donne = fai +workspace.donnelocale = failocal +workspace.ed=ed edita +workspace.edall=edtoo editatoo +workspace.efn = bo borra +workspace.efns = borratoo +workspace.efv = bov borravariable +workspace.erpl=bollistprop borrallistapropiedaes +workspace.exec = executa +workspace.externalcommand=comanduesternu +workspace.gprop = lleeprop devprop lleepropiedad devuelvepropiedad +workspace.imts = imts llistaprocs +workspace.listevariables = imvars llistavars +workspace.locale = local +workspace.plist = llistaprop llistapropiedaes +workspace.pprop = ponprop ponpropiedad +workspace.primitives = primitives +workspace.propertylists=llistesprop llistespropiedaes +workspace.remprop = boprop borrapropiedad +workspace.stoptrace = aparatrazau aparatraz\u00e1u +workspace.text=testu +workspace.trace = trazau traz\u00e1u +xaxis = axex exex +xaxis? = axex? exex? +yaxis = exay exey +yaxis? = exey? +zoom = zoom lupa +drawing.x=x +drawing.y=y +drawing.z=z +drawing.fillpolygon=rellenapol\u00edgonu rellenapoligonu +arithmetic.alea=aleatoriu +loop.dountil=repitehasta +loop.dowhile=repitemientres +aritmetic.modulo=mod modulu m\u00f3dulu +drawing.setfontjustify=ponxustificaofonte +drawing.fontjustify=xustificaofonte
\ No newline at end of file diff --git a/logo/src/primitives_ca_ES.properties b/logo/src/primitives_ca_ES.properties new file mode 100644 index 0000000..3386af7 --- /dev/null +++ b/logo/src/primitives_ca_ES.properties @@ -0,0 +1,288 @@ +3d.downpitch=bn baixanas capcinejaavall +3d.leftroll=be balancejaesquerra +3d.lineend=fil\u00ednia filinia +3d.linestart=defineixl\u00ednia defineixlinia +3d.orientation=orientaci\u00f3 orientacio +3d.perspective=perspectiva +3d.pitch=capcineig +3d.pointend=fipunt +3d.pointstart=defineixpunt +3d.polyend=fipol\u00edgon fipoligon +3d.polystart=defineixpol\u00edgon defineixpoligon +3d.polyview=vistapol\u00edgon vistapoligon vista3d +3d.rightroll=balancejadreta +3d.roll=balanceig +3d.setorientation=fixaorientaci\u00f3 fixaorientacio +3d.setpitch=fixacapcineig +3d.setroll=fixabalanceig +3d.setxyz=fixaxyz +3d.setz=fixaz +3d.textend=fitext +3d.textstart=defineixtext +3d.uppitch=pn pujanas capcinejaamunt +ajoute=afegeix +ajouteligneflux=afegeixl\u00edniaflux afegeixliniaflux +animation=animaci\u00f3 animacio +arithmetic.alea=aleatori +arithmetic.absolue=abs absolut +arithmetic.acos=arccosinus acos arccos +arithmetic.arrondi=arrodoneix +arithmetic.asin=arcsinus asin arcsin +arithmetic.atan=arctangent atan arctg +arithmetic.cos=cos cosinus +arithmetic.difference=difer\u00e8ncia diferencia +arithmetic.digits=decimals +arithmetic.div=divideix div divisi\u00f3 divisio +arithmetic.exp=exp +arithmetic.hasard=atzar +arithmetic.log=ln logneperi\u00e0 logneperia +arithmetic.log10=log log10 logaritme +aritmetic.modulo=mod m\u00f2dul modul +arithmetic.moins=menys cs canviasigne +arithmetic.pi=pi +arithmetic.produit=producte +arithmetic.puissance=pot\u00e8ncia potencia +arithmetic.quotient=quocient +arithmetic.racine=aq arrelquadrada +arithmetic.reste=reste m\u00f2dul modul +arithmetic.setdigits=fixadecimals +arithmetic.sin=sin sinus +arithmetic.somme=suma +arithmetic.tan=tan tg tangent +arithmetic.tronque=truncar trunca partentera +attends=espera +axis=eixos +axiscolor=coloreixos +bc=bll baixallapis +bc?=bll? baixallapis? +bye=ad\u00e9u adeu areveure +cap=rumb +caractere=car car\u00e0cter caracter +cat=cat cat\u00e0leg cataleg +cc=cll colorllapis +cf=colorfons colorpaper +changedossier=cd canviadirectori +chattcp=chattcp +choix=escull tria +ci=ci carregaimatge +clos=modeg\u00e0bia modegabia +color.blanc=blanc +color.bleu=blau +color.bleufonce=blaufosc +color.cyan=cyan cian +color.gris=gris +color.grisclair=grisclar +color.jaune=groc +color.magenta=magenta +color.marron=marr\u00f3 marro +color.noir=negre +color.orange=taronja +color.rose=rosa +color.rouge=vermell roig +color.rougefonce=vermellfosc roigfosc +color.vert=verd +color.vertfonce=verdfosc +color.violet=violeta +compte=compte +controls.compteur=comptador +controls.foreach=percada peracada +controls.forever=repeteixsempre +controls.ifelse=sisin\u00f3 sisino +controls.repete=repeteix +controls.repetepour=repeteixper +controls.stop=atura +controls.stoptout=aturatot +controls.tantque=mentre +couleurtexte=ctext colortext +ct=ot ocultatortuga +date=data +de=llapis agafallapis +debuttemps=cron\u00f2metre cronometre +dernier=\u00faltim ultim +distance=dist\u00e0ncia distancia +drawing.arc=arc +drawing.av=av avan\u00e7a +drawing.cercle=cercle +drawing.etiquette=etiqueta rotula +drawing.fixecap=fixarumb +drawing.fixex=fixax +drawing.fixexy=fixaxy +drawing.fixey=fixay +drawing.fillpolygon=omplepol\u00edgon omplepoligon +drawing.fpos=fpos fixaposici\u00f3 fixaposicio +drawing.fontjustify=fontjustificada +drawing.longueuretiquette=le longitudetiqueta +drawing.origine=centre origen +drawing.point=punt +drawing.re=re recula retrocedeix +drawing.saveimage=desaimatge +drawing.setfontjustify=fixajustificaciofont justificafont +drawing.td=gd giradreta +drawing.tg=ge giraesquerra +drawing.x=x +drawing.y=y +drawing.z=z +drawingquality=qdib qualitatdibuix +ec=es escriu +ecoutetcp=escoltatcp +ecrisligneflux=escriul\u00edniaflux escriuliniaflux +efseq=esborraseq\u00fc\u00e8ncia esborrasequencia +egal?=iguals? +enleve=treu +enr=enrotlla embolica +entier?=enter? +envoietcp=enviatcp +et=i +executetcp=executatcp +faux=fals +fcc=fixacl fixacolorllapis +fcfg=fixacf fixacp fixacolorfons fixacolorpaper +fct=fixact fixacolortext +fen=modefinestra +fermeflux=tancaflux +findseq=fixa\u00edndexseq\u00fc\u00e8ncia fixaindexsequencia +finflux?=fiflux? +finstr=fixainstr fixainstrument +fintemps?=fitemps? +fixenompolice=fixanomfont +fixenompolicetexte=fixanomfonttext +fixeseparation=fixaseparaci\u00f3 fixaseparacio +fixestyle=fixaestil +fpolice=fixamidafont +fpt=fixamidafonttext +frep=fixadir fixadirectori +ftc=fixagruixllapis fixamidallapis +ftortue=fixatortuga +go=goma agafagoma +grid?=quadr\u00edcula? quadricula +gridcolor=colorquadr\u00edcula colorquadricula +grille=quadr\u00edcula quadricula +guiaction=acci\u00f3igu accioigu +guibutton=bot\u00f3igu botoigu +guidraw=dibuixaigu +guimenu=men\u00faigu menuigu +guiposition=posici\u00f3igu posicioigu +guiremove=eliminaigu +heure=hora +ic=ill inverteixllapis +indseq=\u00edndexseq\u00fc\u00e8ncia indexsequencia \u00edndexseq indexseq +instr=instr instrument +inverse=invers inverteix +item=element +joue=tocam\u00fasica tocamusica +lc=pll pujallapis aixecallapis +lis=llegeix llegeixteclat llegeixllista +liscar=llegeixcar llegeixcar\u00e0cter llegeixcaracter +liscarflux=llegeixcarflux llegeixcar\u00e0cterflux llegeixcaracterflux +lisligneflux=llegeixl\u00edniaflux llegeixliniaflux +lissouris=llegeixratol\u00ed llegeixratoli +liste=llista +liste?=llista? +listeflux=llistaflux +loop.dountil=repeteixfinsque +loop.dowhile=repeteixmentre +md=pu posa\u00faltim posaultim +membre=membre +membre?=membre? +message=msg missatge +mot=paraula +mot?=paraula? +mp=pp posaprimer +mt=mt mostratortuga +nettoie=neteja +nombre?=nombre? +nompolice=nf nomfont +nompolicetexte=nft nomfonttext +non=no +ou=o \u00f3 +ouvreflux=obreflux +penshape=fll formallapis +penwidth=gll grossorllapis +ph=fr frase +police=mf midafont +pos=pos posici\u00f3 posicio +possouris=posratoli posici\u00f3ratol\u00ed posicioratoli +precede?=abans? anterior? +premier=pr primer +prim?=prim? primitiva? +proc?=proc? procediment? +ptexte=mt midatext +rafraichis=refresca repinta +ramene=carrega +remplace=reempla\u00e7a +remplis=reomple omple +rempliszone=reomplezona omplezona +rep=dir directori +resetall=init inicialitza +ret=torna +sauve=desa salva guarda +sauved=desat salvat guardat guardatot +sd=mu menys\u00faltim menysultim +separation=sep separaci\u00f3 separacio +seq=seq seq\u00fc\u00e8ncia sequencia +setaxiscolor=fixacoloreixos +setdrawingquality=fixaqualitatdibuix +setgridcolor=fixacolorquadr\u00edcula fixacolorquadricula +setpenshape=fixaformallapis +setscreensize=fixatamanypantalla fixatamanydibuix +setturtlesnumber=fmt fixam\u00e0ximtortugues fixamaximtortugues +setzoom=fixazoom +si=si +sound.mp3play=reprodueixmp3 +sound.mp3stop=aturamp3 +souris?=ratol\u00ed? ratoli? +sp=mp menysprimer +stopanimation=aturaanimaci\u00f3 aturaanimacio +stopaxis=aturaeixos esborraeixos +stopgrille=aturaquadr\u00edcula aturaquadricula esborraquadr\u00edcula esborraquadricula +style=est estil +taillefenetre=tf tamanyfinestra +tailleimage=tp tamanypantalla tamanydibuix +tape=escriu +tc=trobacolor +temps=temps tempspassat +tortue=tortuga +tortues=tortugues +touche?=tecla? +tuetortue=esborratortuga eliminatortuga +turtle.fforme=fixaforma +turtle.forme=forma +turtlesnumber=maxtortugues m\u00e0ximtortugues maximtortugues +unicode=unicode +var?=var? variable? +ve=ep esborrapantalla esborradibuix +vers=cap envers capa +vide?=buit? +visible?=visible? +vrai=cert veritable +vt=et esborratext +workspace.chose=cosa objecte +workspace.content=contingut +workspace.def=def defineix +workspace.donne=fes sigui +workspace.donnelocale=feslocal siguilocal +workspace.ed=ed edita +workspace.edall=edt editatot +workspace.efn=esbp esborraprocediment +workspace.efns=esborratot +workspace.efv=esbv esborravariable +workspace.erpl=esbllp esborrallistapropietats +workspace.exec=executa +workspace.externalcommand=comandaexterna instrucci�externa instruccioexterna +workspace.gprop=llprop llegeixpropietat +workspace.imts=procs procediments llistaprocs llistaprocediments +workspace.listevariables=vars variables +workspace.locale=local +workspace.plist=llprop llistapropietats +workspace.pprop=posapropietat +workspace.primitives=primitives +workspace.propertylists=llistespropietats +workspace.remprop=esbprop esborrapropietat +workspace.stoptrace=aturatra\u00e7 aturatra\u00e7ar +workspace.text=text +workspace.trace=tra\u00e7 tra\u00e7a +xaxis=eixx +xaxis?=eixx? +yaxis=eixy +yaxis?=eixy? +zoom=zoom
\ No newline at end of file diff --git a/logo/src/primitives_de_DE.properties b/logo/src/primitives_de_DE.properties new file mode 100644 index 0000000..26cd23b --- /dev/null +++ b/logo/src/primitives_de_DE.properties @@ -0,0 +1,278 @@ +3d.downpitch=runter +3d.leftroll=rl rollelinks +3d.lineend=linienende +3d.linestart=linienanfang +3d.orientation=orientierung +3d.perspective=perspektivisch +3d.pitch=neigung +3d.pointend=punkteende +3d.pointstart=punkteanfang +3d.polyend=vieleckende +3d.polystart=vieleckanfang +3d.polyview=vieleckansicht +3d.rightroll=rr rollerechts +3d.roll=rollwinkel +3d.setorientation=setzeorientierung +3d.setpitch=setzeneigung +3d.setroll=setzerollwinkel +3d.setxyz=setzexyz +3d.setz=setzez +3d.textend=textende +3d.textstart=textanfang +3d.uppitch=rauf +ajoute=fez f\u00fcgeelementzu +ajouteligneflux=h\u00e4ngezeileanfluss +animation=anim animation +arithmetic.absolue=ovz ohnevorzeichen betrag +arithmetic.acos=acos arccos +arithmetic.arrondi=runde +arithmetic.asin=asin arcsin +arithmetic.atan=atan arctan +arithmetic.cos=cos cosin +arithmetic.difference=differenz +arithmetic.digits = ziffern +arithmetic.div = teile +arithmetic.exp=exp +arithmetic.hasard=zz zufallszahl +arithmetic.log=log +arithmetic.log10 = log10 +arithmetic.moins = minus +arithmetic.pi = pi +arithmetic.produit = produkt +arithmetic.puissance=potenz +arithmetic.quotient = quotient +arithmetic.racine=qw +arithmetic.reste = rest +arithmetic.setdigits = setzeziffern +arithmetic.sin = sin sinus +arithmetic.somme=summe +arithmetic.tan=tan +arithmetic.tronque=ganzezahl +attends = warte +axis=achsen +axiscolor=achsenfarbe +bc = sa stiftab +bc?=sa? stiftab? +bye=ade +cap = kurs +caractere=zeichen +cat=dateien +cc = sf stiftfarbe +cf = bf bildfarbe +changedossier=wo wechsleordner +chattcp=chattcp +choix=nehme nehmewas +ci=ladebild +clos=zaun +color.blanc=wei\u00df +color.bleu = blau +color.bleufonce = dunkelblau +color.cyan = cyan +color.gris = grau +color.grisclair = hellgrau +color.jaune = gelb +color.magenta = magenta +color.marron = braun +color.noir = schwarz +color.orange = orange +color.rose=rosa +color.rouge = rot +color.rougefonce = dunkelrot +color.vert=gr\u00fcn +color.vertfonce=dunkelgr\u00fcn +color.violet=violett +compte=z\u00e4hle +controls.compteur=whzahl +controls.foreach=f\u00fcrjedes +controls.forever=f\u00fcrimmer +controls.ifelse=wennsonst +controls.repete=wh wiederhole +controls.repetepour=f\u00fcr +controls.stop = stoppe +controls.stoptout=stoppealles +controls.tantque=solange +couleurtexte=textfarbe +ct=vi versteckeigel +date = datum +de = ns normalstift +debuttemps=zr z\u00e4hlerunter +dernier=lz letztes +distance=abstand +drawing.arc=arc bogen +drawing.av=vw vorw\u00e4rts +drawing.cercle=kreis +drawing.etiquette=igeltext +drawing.fixecap = ak aufkurs +drawing.fixex=sx setzex +drawing.fixexy=sxy setzexy +drawing.fixey=sy setzey +drawing.fpos=aufpos +drawing.longueuretiquette=litext l\u00e4ngeigeltext +drawing.origine = heim +drawing.point = punkt +drawing.re=rw r\u00fcckw\u00e4rts +drawing.saveimage=speichereBild +drawing.td = re rechts +drawing.tg = li links +drawingquality=zq zeichnungsqualit\u00e4t +ec=dz druckezeile +ecoutetcp=h\u00f6retcp +ecrisligneflux=schreibezeilenfluss +efseq=lfol l\u00f6schefolge +egal?=gleich? +enleve=entferne +enr = rspr randsprung +entier?=ganzezahl? +envoietcp=sendetcp +et=und alle? +executetcp=ausf\u00fchretcp +faux = falsch +fcc=sstf setzestiftfarbe +fcfg=sbf sbildfarbe setzebildfarbe +fct=stf setzetextfarbe +fen = fen fenster +fermeflux=schlie\u00dfefluss +findseq=ffol findefolge +finflux?=endefluss? +finstr=sinstr setzeinstrument +fintemps?=ezr? endez\u00e4hlerunter? +fixenompolice=sfn setzefontname +fixenompolicetexte=stn setzetextname +fixeseparation=stren setzetrenner +fixestyle=sstil setzestil +fpolice=sfg setzefontgr\u00f6\u00dfe +fpt=stg setzetextgr\u00f6\u00dfe +frep=sordner setzeordner +ftc=sstb stiftbreite +ftortue=sigel setzeigel +go = rd radiere +grid?=gitter? +gridcolor=gitterfarbe +grille=gitter +guiaction=guiaktion +guibutton=guitaste +guidraw=guizeichne +guimenu=guimen\u00fc +guiposition=guiposition +guiremove=guientferne +heure = zeit +ic=umkehrestift +indseq = indfol indexfolge +instr = instr instrument +inverse=umdreheliste +item = element +joue = spiele +lc = sh stifthoch +lis=lese +liscar=lz lesezeichen +liscarflux=lesebuchstabenfluss +lisligneflux=lesezeilenfluss +lissouris=lesemaus +liste = liste +liste?=liste? +listeflux=listefluss +md=ml mitletztem +membre?=element? +membre=elementab +message=nricht nachricht +mot = wort +mot?=wort? +mp = me miterstem +mt=zi zeigeigel +nettoie = wasche +nombre?=zahl? +nompolice=fontname +nompolicetexte=tn textname +non=nicht +ou=oder eines? +ouvreflux=\u00f6ffnefluss +penshape=stiftform +penwidth=sb stiftbreite +ph = satz +police=fontgr\u00f6\u00dfe +pos = pos +possouris=mauspos mausposition +precede?=vorher? +premier=er erstes +prim?=grundwort? +proc?=proz? prozedur? +ptexte=tg textgr\u00f6\u00dfe +rafraichis=af auffrischen +ramene = lade +remplace=selem setzeelement +remplis=f\u00fclle +rempliszone=f\u00fclleform +rep=ord ordner +resetall=resette +ret=rg r\u00fcckgabe +sauve=speichere +sauved = gespeichert +sd = ol ohneletztes +separation=trenner +seq = fol folge +setaxiscolor=saf setzeachsenfarbe +setdrawingquality=szq szeichnungsqualit\u00e4t +setgridcolor=sgf setzegitterfarbe +setpenshape=sstform setzestiftform +setscreensize=sbg setzebildgr\u00f6\u00dfe +setturtlesnumber=setzeigelmax +setzoom=setzezoom +si = wenn +sound.mp3play=mp3spiele +sound.mp3stop=mp3stoppe +souris?=maus? +sp = oe ohneerstes +stopanimation=stoppeanim stoppeanimation +stopaxis=stoppeachsen +stopgrille=stoppegitter +style = stil +taillefenetre=fenstergr\u00f6\u00dfe +tailleimage=bildgr\u00f6\u00dfe +tape=schreibe +tc=ff findefarbe +temps = vz vergangenezeit +tortue=igel +tortues=igelliste +touche?=taste? +tuetortue=ligel l\u00f6scheigel +turtle.fforme=sform setzeform +turtle.forme = form +turtlesnumber=igelmax +unicode = unicode +var?=var? variable? +ve=lb l\u00f6schebild +vers = ri richtung +vide? = leer? +visible?=sichtbar? +vrai = wahr +vt=lt l\u00f6schetext +workspace.chose = wert +workspace.content=inhalt +workspace.def = def definiere +workspace.donne=setze +workspace.donnelocale=lokalsetze +workspace.ed=ed editiere +workspace.edall=edalles editierealles +workspace.efn=vgp vgproz +workspace.efns=vga vergessealles +workspace.efv=vgv vergessevar +workspace.erpl=vgegliste vergesseegliste +workspace.exec=starte +workspace.externalcommand=externerbefehl +workspace.gprop=gebeeg +workspace.imts=zga zeigealles +workspace.listevariables=variablen +workspace.locale = lokal +workspace.plist=egliste +workspace.pprop=setzeeg +workspace.primitives=primitive +workspace.propertylists=eglisten +workspace.remprop=entferneeg +workspace.stoptrace=stoppeverfolge +workspace.text=text +workspace.trace = verfolge +xaxis?=xachse? +xaxis=xachse +yaxis?=yachse? +yaxis=yachse +zoom=zoom
\ No newline at end of file diff --git a/logo/src/primitives_el_GR.properties b/logo/src/primitives_el_GR.properties new file mode 100644 index 0000000..b4750eb --- /dev/null +++ b/logo/src/primitives_el_GR.properties @@ -0,0 +1,288 @@ +3d.downpitch=\u03b3\u03c9\u03bd\u03af\u03b1\u039a\u03ac\u03c4\u03c9\u0391\u03c0\u03cc\u039f\u03a7 +3d.leftroll=\u03b1\u03c1\u03b9\u03c3\u03c4\u03b5\u03c1\u03ac\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u03a8 +3d.lineend=\u03c4\u03ad\u03bb\u03bf\u03c2\u0393\u03c1\u03b1\u03bc\u03bc\u03ae\u03c2 +3d.linestart=\u03b1\u03c1\u03c7\u03ae\u0393\u03c1\u03b1\u03bc\u03bc\u03ae\u03c2 +3d.orientation=\u03c0\u03c1\u03bf\u03c3\u03b1\u03bd\u03b1\u03c4\u03bf\u03bb\u03b9\u03c3\u03bc\u03cc\u03c2 +3d.perspective=\u03c0\u03c1\u03bf\u03bf\u03c0\u03c4\u03b9\u03ba\u03ae3\u0394 +3d.pitch=\u03b3\u03c9\u03bd\u03af\u03b1\u03b3\u03cd\u03c1\u03c9\u03b1\u03c0\u03cc\u039f\u03a7 +3d.pointend=\u03c3\u03b7\u03bc\u03b5\u03af\u03bf\u03a4\u03ad\u03bb\u03bf\u03c2 +3d.pointstart=\u03c3\u03b7\u03bc\u03b5\u03af\u03bf\u0391\u03c1\u03c7\u03ae +3d.polyend=\u03c0\u03bf\u03bb\u03cd\u03b3\u03c9\u03bd\u03bf\u03a4\u03ad\u03bb\u03bf\u03c2 +3d.polystart=\u03c0\u03bf\u03bb\u03cd\u03b3\u03c9\u03bd\u03bf\u0391\u03c1\u03c7\u03ae +3d.polyview=\u03c0\u03bf\u03bb\u03cd\u03b3\u03c9\u03bd\u03bf\u0398\u03ad\u03b1 \u03b8\u03ad\u03b13\u0394 +3d.rightroll=\u03b4\u03b5\u03be\u03b9\u03ac\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u03a8 +3d.roll=\u03b3\u03c9\u03bd\u03af\u03b1\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u03a8 +3d.setorientation=\u03b8\u03ad\u03c3\u03b5\u03a0\u03c1\u03bf\u03c3\u03b1\u03bd\u03b1\u03c4\u03bf\u03bb\u03b9\u03c3\u03bc\u03cc +3d.setpitch=\u03b8\u03ad\u03c3\u03b5\u0393\u03c9\u03bd\u03af\u03b1\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u03a7 +3d.setroll=\u03b8\u03ad\u03c3\u03b5\u0393\u03c9\u03bd\u03af\u03b1\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u03a8 +3d.setxyz=\u03b8\u03ad\u03c3\u03b5\u03a7\u03a8\u0396 +3d.setz=\u03b8\u03ad\u03c3\u03b5\u0396 +3d.textend=\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03bf\u03a4\u03ad\u03bb\u03bf\u03c2 +3d.textstart=\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03bf\u0391\u03c1\u03c7\u03ae +3d.uppitch=\u03b3\u03c9\u03bd\u03af\u03b1\u03a0\u03ac\u03bd\u03c9\u0391\u03c0\u03cc\u039f\u03a7 +ajoute=\u03c0\u03c1\u03cc\u03c3\u03b8\u03b5\u03c3\u03b5\u03a3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03bf +ajouteligneflux=\u03c0\u03c1\u03cc\u03c3\u03b8\u03b5\u03c3\u03b5\u03a1\u03bf\u03ae\u0393\u03c1\u03b1\u03bc\u03bc\u03ae\u03c2 +animation=\u03ba\u03b9\u03bd \u03ba\u03af\u03bd\u03b7\u03c3\u03b7 +arithmetic.absolue=\u03b1\u03c0\u03cc\u03bb\u03c5\u03c4\u03b7\u03a4\u03b9\u03bc\u03ae +arithmetic.acos=acos \u03c4\u03cc\u03be\u03bf\u03a3\u03c5\u03bd\u03b7\u03bc\u03b9\u03c4\u03cc\u03bd\u03bf\u03c5 +arithmetic.arrondi=\u03c3\u03c4\u03c1\u03bf\u03b3\u03b3\u03c5\u03bb\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b5 +arithmetic.asin=asin \u03c4\u03cc\u03be\u03bf\u0397\u03bc\u03b9\u03c4\u03cc\u03bd\u03bf\u03c5 +arithmetic.atan=atan \u03c4\u03cc\u03be\u03bf\u0395\u03c6\u03b1\u03c0\u03c4\u03bf\u03bc\u03ad\u03bd\u03b7\u03c2 +arithmetic.cos=\u03c3\u03c5\u03bd \u03c3\u03c5\u03bd\u03b7\u03bc\u03af\u03c4\u03bf\u03bd\u03bf +arithmetic.difference=\u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03ac +arithmetic.digits=\u03b4\u03b5\u03ba\u03b1\u03b4\u03b9\u03ba\u03ac\u03c8\u03b7\u03c6\u03af\u03b1 +arithmetic.div=\u03b4\u03b9\u03b1\u03af\u03c1\u03b5\u03c3\u03b5 +arithmetic.exp=exp +arithmetic.hasard=\u03c4\u03c5 \u03c4\u03c5\u03c7\u03b1\u03af\u03bf +arithmetic.log=\u03bb\u03bf\u03b3 +arithmetic.log10=\u03bb\u03bf\u03b310 +aritmetic.modulo=mod +arithmetic.moins=\u03bc\u03b5\u03af\u03bf\u03bd +arithmetic.pi=\u03c0 +arithmetic.produit=\u03b3\u03b9\u03bd\u03cc\u03bc\u03b5\u03bd\u03bf +arithmetic.puissance=\u03b4\u03cd\u03bd\u03b1\u03bc\u03b7 +arithmetic.quotient=\u03c0\u03b7\u03bb\u03af\u03ba\u03bf +arithmetic.racine=\u03c4\u03b5\u03a1\u03b9 \u03c4\u03b5\u03c4\u03c1\u03b1\u03b3\u03c9\u03bd\u03b9\u03ba\u03ae\u03a1\u03af\u03b6\u03b1 +arithmetic.reste=\u03c5\u03c0\u03cc\u03bb\u03bf\u03b9\u03c0\u03bf +arithmetic.setdigits=\u03b8\u03ad\u03c3\u03b5\u03b4\u03b5\u03ba\u03b1\u03b4\u03b9\u03ba\u03ac\u03c8\u03b7\u03c6\u03af\u03b1 +arithmetic.sin=\u03b7\u03bc\u03b9 \u03b7\u03bc\u03af\u03c4\u03bf\u03bd\u03bf +arithmetic.somme=\u03ac\u03b8\u03c1\u03bf\u03b9\u03c3\u03bc\u03b1 +arithmetic.tan=\u03b5\u03c6\u03b1\u03c0\u03c4\u03cc\u03bc\u03b5\u03bd\u03b7 +arithmetic.tronque=\u03b1\u03ba\u03ad\u03c1\u03b1\u03b9\u03bf\u03c2 +attends=\u03c0\u03b5\u03c1\u03af\u03bc\u03b5\u03bd\u03b5 +axis=\u03ac\u03be\u03bf\u03bd\u03b1\u03c2 +axiscolor=\u03c7\u03c1\u03ce\u03bc\u03b1\u0386\u03be\u03bf\u03bd\u03b1 +bc=\u03c3\u03c4\u03c5\u03bb\u03cc\u039a\u03ac\u03c4\u03c9 +bc?=\u03c3\u03c4\u03c5\u03bb\u03cc\u039a\u03ac\u03c4\u03c9? +bye=\u03b1\u03bd\u03c4\u03af\u03bf +cap=\u03b3\u03c9\u03bd\u03af\u03b1\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u0396 +caractere=\u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b1\u03c2 +cat=\u03b1\u03c1\u03c7\u03b5\u03af\u03b1 +cc=\u03c7\u03c1\u03ce\u03bc\u03b1\u03a3\u03c4\u03c5\u03bb\u03cc +cf=\u03c7\u03c1\u03ce\u03bc\u03b1\u039f\u03b8\u03cc\u03bd\u03b7\u03c2 +changedossier=\u03ac\u03bb\u03bb\u03b1\u03be\u03b5\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf +chattcp=\u03bc\u03af\u03bb\u03b7\u03c3\u03b5tcp +choix=\u03c0\u03ac\u03c1\u03b5 +ci=\u03c6\u03cc\u03c1\u03c4\u03c9\u03c3\u03b5\u0395\u03b9\u03ba\u03cc\u03bd\u03b1 +clos=\u03c6\u03c1\u03ac\u03c7\u03c4\u03b7\u03c2 +color.blanc=\u03bb\u03b5\u03c5\u03ba\u03cc +color.bleu=\u03bc\u03c0\u03bb\u03ad +color.bleufonce=\u03b2\u03b1\u03b8\u03cd\u039c\u03c0\u03bb\u03ad +color.cyan=\u03ba\u03c5\u03b1\u03bd\u03cc +color.gris=\u03b3\u03ba\u03c1\u03af +color.grisclair=\u03b1\u03c0\u03b1\u03bb\u03cc\u0393\u03ba\u03c1\u03af +color.jaune=\u03ba\u03af\u03c4\u03c1\u03b9\u03bd\u03bf +color.magenta=\u03bc\u03b1\u03c4\u03b6\u03ad\u03bd\u03c4\u03b1 +color.marron=\u03ba\u03b1\u03c6\u03ad +color.noir=\u03bc\u03b1\u03cd\u03c1\u03bf +color.orange=\u03c0\u03bf\u03c1\u03c4\u03bf\u03ba\u03b1\u03bb\u03af +color.rose=\u03c1\u03cc\u03b6 +color.rouge=\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf +color.rougefonce=\u03b2\u03b1\u03b8\u03cd\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf +color.vert=\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf +color.vertfonce=\u03b2\u03b1\u03b8\u03cd\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf +color.violet=\u03bc\u03ce\u03b2 +compte=\u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b5 +controls.compteur=\u03b4\u03b5\u03af\u03ba\u03c4\u03b7\u03c2\u0395\u03c0\u03b1\u03bd\u03ac\u03bb\u03b7\u03c8\u03b7\u03c2 +controls.foreach=\u03b3\u03b9\u03b1\u039a\u03ac\u03b8\u03b5 +controls.forever=\u03b3\u03b9\u03b1\u03a0\u03ac\u03bd\u03c4\u03b1 +controls.ifelse=\u03b1\u03bd\u0394\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03ac +controls.repete=\u03b5\u03c0\u03b1\u03bd\u03ac\u03bb\u03b1\u03b2\u03b5 +controls.repetepour=\u03b5\u03c0\u03b1\u03bd\u03ac\u03bb\u03b1\u03b2\u03b5\u0393\u03b9\u03ac +controls.stop=\u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1 +controls.stoptout=\u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1\u03c4\u03b1\u038c\u03bb\u03b1 +controls.tantque=\u03b5\u03bd\u03ce +couleurtexte=\u03c7\u03c1\u03ce\u03bc\u03b1\u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 +ct=\u03ba\u03c1\u03cd\u03c8\u03b5\u03a7\u03b5\u03bb\u03ce\u03bd\u03b1 +date=\u03b7\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 +de=\u03c3\u03c4\u03c5\u0396\u03c9 \u03c3\u03c4\u03c5\u03bb\u03cc\u0396\u03c9\u03b3\u03c1\u03ac\u03c6\u03b9\u03c3\u03b5 +debuttemps=\u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b5\u03a0\u03c1\u03cc\u03c2\u03a4\u03b1\u039a\u03ac\u03c4\u03c9 +dernier=\u03c4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03bf +distance=\u03b1\u03c0\u03cc\u03c3\u03c4\u03b1\u03c3\u03b7 +drawing.arc=arc +drawing.av=\u03bc\u03c0 \u03bc\u03c0\u03c1\u03bf\u03c3\u03c4\u03ac +drawing.cercle=\u03ba\u03cd\u03ba\u03bb\u03bf\u03c2 +drawing.etiquette=\u03b5\u03c4\u03b9\u03ba\u03ad\u03c4\u03c4\u03b1 +drawing.fillpolygon=\u03b3\u03ad\u03bc\u03b9\u03c3\u03b5\u03a0\u03bf\u03bb\u03cd\u03b3\u03c9\u03bd\u03bf +drawing.fixecap=\u03b8\u03ad\u03c3\u03b5\u0393\u03c9\u03bd\u03af\u03b1\u0393\u03cd\u03c1\u03c9\u0391\u03c0\u03cc\u039f\u0396 +drawing.fixex=\u03b8\u03ad\u03c3\u03b5\u03c7 +drawing.fixexy=\u03b8\u03ad\u03c3\u03b5\u03c7\u03c8 +drawing.fixey=\u03b8\u03ad\u03c3\u03b5\u03c8 +drawing.fontjustify=\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u0395\u03c5\u03b8\u03c5\u03b3\u03c1\u03ac\u03bc\u03bc\u03b9\u03c3\u03b5 +drawing.fpos=\u03b8\u03ad\u03c3\u03b5\u0398\u03ad\u03c3\u03b7 +drawing.longueuretiquette=\u03bc\u03ae\u03ba\u03bf\u03c2\u0395\u03c4\u03b9\u03ba\u03ad\u03c4\u03c4\u03b1\u03c2 +drawing.origine=\u03c3\u03c0\u03af\u03c4\u03b9 +drawing.point=\u03c3\u03b7\u03bc\u03b5\u03af\u03bf +drawing.re=\u03c0\u03b9 \u03c0\u03af\u03c3\u03c9 +drawing.saveimage=\u03b1\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b5\u0395\u03b9\u03ba\u03cc\u03bd\u03b1 +drawing.setfontjustify=\u03b8\u03ad\u03c3\u03b5\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u0395\u03c5\u03b8\u03c5\u03b3\u03c1\u03ac\u03bc\u03bc\u03b9\u03c3\u03b7 +drawing.td=\u03b4\u03b5 \u03b4\u03b5\u03be\u03b9\u03ac +drawing.tg=\u03b1\u03c1 \u03b1\u03c1\u03b9\u03c3\u03c4\u03b5\u03c1\u03ac +drawing.x=\u03a7 +drawing.y=\u03a8 +drawing.z=\u0396 +drawingquality=\u03c0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1\u03a3\u03c7\u03b5\u03b4\u03af\u03b1\u03c3\u03b7\u03c2 +ec=\u03c4\u03c5\u03c0 \u03c4\u03cd\u03c0\u03c9\u03c3\u03b5 +ecoutetcp=\u03ac\u03ba\u03bf\u03c5\u03c3\u03b5tcp +ecrisligneflux=\u03b3\u03c1\u03ac\u03c8\u03b5\u03a1\u03b5\u03cd\u03bc\u03b1\u0393\u03c1\u03b1\u03bc\u03bc\u03ae\u03c2 +efseq=\u03b4\u03b9\u03b5\u0391\u03ba \u03b4\u03b9\u03ad\u03b3\u03c1\u03b1\u03c8\u03b5\u0391\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03af\u03b1 +egal?=\u03af\u03c3\u03bf? \u03b5\u03af\u03bd\u03b1\u03b9\u038a\u03c3\u03bf? +enleve=\u03b1\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b5 +enr=\u03c4\u03cd\u03bb\u03b9\u03be\u03b5 +entier?=\u03b1\u03ba\u03ad\u03c1\u03b1\u03b9\u03bf\u03c2? +envoietcp=\u03c3\u03c4\u03b5\u03af\u03bb\u03b5tcp +et=\u03ba\u03b1\u03af +executetcp=\u03b5\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b5tcp +faux=\u03c8\u03b5\u03c5\u03b4\u03ad\u03c2 +fcc=\u03b8\u03b5\u03a7\u03c1\u03c9\u03a3\u03c4\u03c5 \u03b8\u03ad\u03c3\u03b5\u03a7\u03c1\u03ce\u03bc\u03b1\u03a3\u03c4\u03c5\u03bb\u03cc +fcfg=\u03b8\u03b5\u03a7\u03c1\u03c9\u039f\u03b8 \u03b8\u03ad\u03c3\u03b5\u03a7\u03c1\u03ce\u03bc\u03b1\u039f\u03b8\u03cc\u03bd\u03b7\u03c2 +fct=\u03b8\u03b5\u03a7\u03c1\u03c9\u039a\u03b5\u03b9 \u03b8\u03ad\u03c3\u03b5\u03a7\u03c1\u03ce\u03bc\u03b1\u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 +fen=\u03c0\u03b1\u03c1\u03ac\u03b8\u03c5\u03c1\u03bf +fermeflux=\u03ba\u03bb\u03b5\u03af\u03c3\u03b5\u03a1\u03b5\u03cd\u03bc\u03b1 +findseq=\u03b8\u03ad\u03c3\u03b5\u0394\u03b5\u03af\u03ba\u03c4\u03b7\u0391\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03af\u03b1\u03c2 +finflux?=\u03c4\u03ad\u03bb\u03bf\u03c2\u03a1\u03bf\u03ae\u03c2? +finstr=\u03b8\u03b5\u039f\u03c1\u03b3 \u03b8\u03ad\u03c3\u03b5\u038c\u03c1\u03b3\u03b1\u03bd\u03bf +fintemps?=\u03c4\u03ad\u03bb\u03bf\u03c2\u039c\u03ad\u03c4\u03c1\u03b7\u03c3\u03b7\u03c2\u03a0\u03c1\u03cc\u03c2\u03a4\u03b1\u039a\u03ac\u03c4\u03c9? +fixenompolice=\u03b8\u03b5\u039f\u03bd\u0393\u03c1\u03b1 \u03b8\u03ad\u03c3\u03b5\u038c\u03bd\u03bf\u03bc\u03b1\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u03c2 +fixenompolice=\u03b8\u03b5\u039f\u03bd\u0393\u03c1\u03b1 \u03b8\u03ad\u03c3\u03b5\u038c\u03bd\u03bf\u03bc\u03b1\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u03c2 +fixenompolicetexte=\u03b8\u03b5\u039f\u03bd\u039a\u03b5\u03b9 \u03b8\u03ad\u03c3\u03b5\u038c\u03bd\u03bf\u03bc\u03b1\u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 +fixeseparation=\u03b8\u03b5\u0394\u03b9\u03b1 \u03b8\u03ad\u03c3\u03b5\u0394\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03cc +fixestyle=\u03b8\u03b5\u03a3\u03c4\u03c5 \u03b8\u03ad\u03c3\u03b5\u03a3\u03c4\u03cd\u03bb +fpolice=\u03b8\u03b5\u039c\u03b5\u0393\u03c1\u03b1 \u03b8\u03ad\u03c3\u03b5\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u03c2 +fpt=\u03b8\u03b5\u039c\u03b5\u039a\u03b5\u03b9 \u03b8\u03ad\u03c3\u03b5\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 +frep=\u03b8\u03b5\u039a\u03b1\u03c4 \u03b8\u03ad\u03c3\u03b5\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf +ftc=\u03b8\u03ad\u03c3\u03b5\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u03a3\u03c4\u03c5\u03bb\u03cc \u03b8\u03b5\u039c\u03b5\u03a3\u03c4\u03c5 +ftortue=\u03b8\u03b5\u03a7\u03b5 \u03b8\u03ad\u03c3\u03b5\u03a7\u03b5\u03bb\u03ce\u03bd\u03b1 +go=\u03c3\u03b2\u03ae\u03c3\u03b5\u03a3\u03c4\u03c5\u03bb\u03cc +grid?=\u03c0\u03bb\u03ad\u03b3\u03bc\u03b1? +gridcolor=\u03c7\u03c1\u03ce\u03bc\u03b1\u03a0\u03bb\u03ad\u03b3\u03bc\u03b1\u03c4\u03bf\u03c2 +grille=\u03c0\u03bb\u03ad\u03b3\u03bc\u03b1 +guiaction=\u03b4\u03c1\u03ac\u03c3\u03b7\u0393\u03c1\u03b1\u03c6\u03b9\u03ba\u03bf\u03cd +guibutton=\u03ba\u03bf\u03c5\u03bc\u03c0\u03af\u0393\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc +guidraw=\u03c3\u03c7\u03b5\u03b4\u03af\u03b1\u03c3\u03b5\u0393\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc +guimenu=\u03bc\u03b5\u03bd\u03bf\u03cd\u0393\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc +guiposition=\u03b8\u03ad\u03c3\u03b7\u0393\u03c1\u03b1\u03c6\u03b9\u03ba\u03bf\u03cd +guiremove=\u03b1\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b5\u0393\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc +heure=\u03ce\u03c1\u03b1 +ic=\u03b1\u03bd\u03a3\u03c4\u03c5 \u03b1\u03bd\u03b1\u03c3\u03c4\u03c1\u03bf\u03c6\u03ae\u03a3\u03c4\u03c5\u03bb\u03cc +indseq=\u03b4\u03b5\u03af\u03ba\u03c4\u03b7\u03c2\u0391\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03af\u03b1\u03c2 +instr=\u03bf\u03c1\u03b3 \u03cc\u03c1\u03b3\u03b1\u03bd\u03bf +inverse=\u03b1\u03bd\u03ac\u03c3\u03c4\u03c1\u03b5\u03c8\u03b5 +item=\u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03bf +joue=\u03c0\u03b1\u03af\u03be\u03b5 +lc=\u03c3\u03c4\u03c5\u03a0\u03b1 \u03c3\u03c4\u03c5\u03bb\u03cc\u03a0\u03ac\u03bd\u03c9 +lis=\u03b4\u03b9\u03ac\u03b2\u03b1\u03c3\u03b5 +liscar=\u03b4\u03b9\u03b1\u03a7\u03b1\u03c1 \u03b4\u03b9\u03ac\u03b2\u03b1\u03c3\u03b5\u03a7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b1 +liscarflux=\u03b4\u03b9\u03ac\u03b2\u03b1\u03c3\u03b5\u03a1\u03b5\u03cd\u03bc\u03b1\u03a7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd +lisligneflux=\u03b4\u03b9\u03ac\u03b2\u03b1\u03c3\u03b5\u03a1\u03b5\u03cd\u03bc\u03b1\u03a3\u03b5\u03b9\u03c1\u03ce\u03bd +lissouris=\u03b4\u03b9\u03ac\u03b2\u03b1\u03c3\u03b5\u03a0\u03bf\u03bd\u03c4\u03af\u03ba\u03b9 +liste=\u03bb\u03af\u03c3\u03c4\u03b1 +liste?=\u03bb\u03af\u03c3\u03c4\u03b1? +listeflux=\u03c1\u03b5\u03cd\u03bc\u03b1\u039b\u03af\u03c3\u03c4\u03b1\u03c2 +loop.dountil=\u03b5\u03c0\u03b1\u03bd\u03ac\u03bb\u03b1\u03b2\u03b5\u039c\u03ad\u03c7\u03c1\u03b9 +loop.dowhile=\u03b5\u03c0\u03b1\u03bd\u03ac\u03bb\u03b1\u03b2\u03b5\u0395\u03bd\u03ce +md=\u03b2\u03ac\u03bb\u03b5\u03a4\u03ad\u03bb\u03bf\u03c2\u039b\u03af\u03c3\u03c4\u03b1\u03c2 +mp=\u03b2\u03ac\u03bb\u03b5\u0391\u03c1\u03c7\u03ae\u039b\u03af\u03c3\u03c4\u03b1\u03c2 +membre=\u03bc\u03ad\u03bb\u03bf\u03c2 +membre?=\u03bc\u03ad\u03bb\u03bf\u03c2? +message=\u03bc\u03b7\u03bd \u03bc\u03ae\u03bd\u03c5\u03bc\u03b1 +mot=\u03bb\u03ad\u03be\u03b7 +mot?=\u03bb\u03ad\u03be\u03b7? +mt=\u03b5\u03bc\u03c6\u03ac\u03bd\u03b9\u03c3\u03b5\u03a7\u03b5\u03bb\u03ce\u03bd\u03b1 +nettoie=\u03c0\u03bb\u03cd\u03bd\u03b5 +nombre?=\u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2? +nompolice=\u03cc\u03bd\u03bf\u03bc\u03b1\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u03c2 +nompolicetexte=\u03bf\u03bd\u039a\u03b5\u03b9 \u03cc\u03bd\u03bf\u03bc\u03b1\u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 +non=\u03cc\u03c7\u03b9 +ou=\u03ae +ouvreflux=\u03ac\u03bd\u03bf\u03b9\u03be\u03b5\u03a1\u03b5\u03cd\u03bc\u03b1 +penshape=\u03c3\u03c7\u03b7\u03a3\u03c4\u03c5 \u03c3\u03c7\u03ae\u03bc\u03b1\u03a3\u03c4\u03c5\u03bb\u03cc +penwidth=\u03c0\u03bb\u03b1\u03a3\u03c4\u03c5 \u03c0\u03bb\u03ac\u03c4\u03bf\u03c2\u03a3\u03c4\u03c5\u03bb\u03cc +ph=\u03c0\u03c1\u03bf \u03c0\u03c1\u03cc\u03c4\u03b1\u03c3\u03b7 +police=\u03bc\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u0393\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c3\u03b5\u03b9\u03c1\u03ac\u03c2 +pos=\u03b8\u03ad\u03c3\u03b7 +possouris=\u03b8\u03b5\u03a0\u03bf \u03b8\u03ad\u03c3\u03b7\u03a0\u03bf\u03bd\u03c4\u03b9\u03ba\u03b9\u03bf\u03cd +precede?=\u03c0\u03c1\u03af\u03bd? +premier=\u03c0\u03c1\u03ce\u03c4\u03bf +prim?=\u03c3\u03c4\u03bf\u03b9\u03c7? \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03b9\u03ce\u03b4\u03b5\u03c2? +proc?=\u03b4\u03b9\u03b1? \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1? +ptexte=\u03bc\u03b5\u039a\u03b5\u03b9 \u03bc\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 +rafraichis=\u03b1\u03bd\u03b1\u03bd\u03ad\u03c9\u03c3\u03b7 \u03b5\u03c0\u03b1\u03bd\u03b1\u03c3\u03c7\u03b5\u03b4\u03af\u03b1\u03c3\u03b7 +ramene=\u03c6\u03cc\u03c1\u03c4\u03c9\u03c3\u03b5 +remplace=\u03b1\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ad\u03c3\u03c4\u03b7\u03c3\u03b5 +remplis=\u03b3\u03ad\u03bc\u03b9\u03c3\u03b5 +rempliszone=\u03b3\u03ad\u03bc\u03b9\u03c3\u03b5\u0396\u03ce\u03bd\u03b7 +rep=\u03ba\u03b1\u03c4 \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 +resetall=\u03b5\u03c0\u03b1\u03bd\u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b5\u038c\u03bb\u03b1 +ret=\u03b5\u03be \u03ad\u03be\u03bf\u03b4\u03bf\u03c2 +sauve=\u03b1\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b5 +sauved=\u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03bf +sd=\u03b5\u03ba\u03a4\u03b5 \u03b5\u03ba\u03c4\u03cc\u03c2\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03bf\u03c5 +separation=\u03b4\u03b9\u03b1\u03c7 \u03b4\u03b9\u03b1\u03c7\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03cc +seq=\u03b1\u03ba \u03b1\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03af\u03b1 +setaxiscolor=\u03b8\u03b5\u03a7\u03c1\u03c9\u0391\u03be \u03b8\u03ad\u03c3\u03b5\u03a7\u03c1\u03ce\u03bc\u03b1\u0386\u03be\u03bf\u03bd\u03b1 +setdrawingquality=\u03b8\u03b5\u03a3\u03c7\u03b5\u03a0\u03bf\u03b9 \u03b8\u03ad\u03c3\u03b5\u03a3\u03c7\u03b5\u03b4\u03b9\u03b1\u03c3\u03c4\u03b9\u03ba\u03ae\u03a0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 +setgridcolor=\u03b8\u03b5\u03a7\u03c1\u03c9\u03a0\u03bb\u03b5 \u03b8\u03ad\u03c3\u03b5\u03a7\u03c1\u03ce\u03bc\u03b1\u03a0\u03bb\u03ad\u03b3\u03bc\u03b1\u03c4\u03bf\u03c2 +setpenshape=\u03b8\u03b5\u03a3\u03c7\u03a3\u03c4\u03c5 \u03b8\u03ad\u03c3\u03b5\u03a3\u03c7\u03ae\u03bc\u03b1\u03a3\u03c4\u03c5\u03bb\u03cc +setscreensize=\u03b8\u03b5\u039c\u03b5\u039f\u03b8 \u03b8\u03ad\u03c3\u03b5\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u039f\u03b8\u03cc\u03bd\u03b7\u03c2 +setturtlesnumber=\u03b8\u03b5\u039c\u03b5\u03b3\u03a7\u03b5\u03bb \u03b8\u03ad\u03c3\u03b5\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf\u03a7\u03b5\u03bb\u03ce\u03bd\u03b5\u03c2 +setzoom=\u03b8\u03ad\u03c3\u03b5\u039c\u03b5\u03b3\u03ad\u03b8\u03c5\u03bd\u03c3\u03b7 +si=\u03b5\u03ac\u03bd +sound.mp3play=\u03c0\u03b1\u03af\u03be\u03b5mp3 +sound.mp3stop=\u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1mp3 +souris?=\u03c0\u03bf\u03bd\u03c4\u03af\u03ba\u03b9? +sp=\u03b5\u03ba\u03a0\u03c1\u03c9 \u03b5\u03ba\u03c4\u03cc\u03c2\u03a0\u03c1\u03ce\u03c4\u03bf\u03c5 +stopanimation=\u03c3\u03c4\u03b1\u039a\u03b9\u03bd \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1\u039a\u03af\u03bd\u03b7\u03c3\u03b7 +stopaxis=\u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5\u0386\u03be\u03bf\u03bd\u03b5\u03c2 +stopgrille=\u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1\u03a0\u03bb\u03ad\u03b3\u03bc\u03b1 +style=\u03c3\u03c4\u03c5 \u03c3\u03c4\u03cd\u03bb +taillefenetre=\u03bc\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u0396\u03ce\u03bd\u03b7\u03c2 +tailleimage=\u03bc\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2\u039f\u03b8\u03cc\u03bd\u03b7\u03c2 +tape=\u03b3\u03c1\u03ac\u03c8\u03b5 +tc=\u03b2\u03c1\u03ad\u03c2\u03a7\u03c1\u03ce\u03bc\u03b1 +temps=\u03c0\u03b5\u03c1\u03b1\u03c3\u03bc\u03ad\u03bd\u03bf\u03c2\u03a7\u03c1\u03cc\u03bd\u03bf\u03c2 +tortue=\u03c7\u03b5\u03bb\u03ce\u03bd\u03b1 +tortues=\u03c7\u03b5\u03bb\u03ce\u03bd\u03b5\u03c2 +touche?=\u03ba\u03bf\u03c5\u03bc\u03c0\u03af? +tuetortue=\u03c3\u03ba\u03cc\u03c4\u03c9\u03c3\u03b5\u03a7\u03b5\u03bb\u03ce\u03bd\u03b1 +turtle.fforme=\u03b8\u03ad\u03c3\u03b5\u03a3\u03c7\u03ae\u03bc\u03b1 +turtle.forme=\u03c3\u03c7\u03ae\u03bc\u03b1 +turtlesnumber=\u03bc\u03b5\u03b3\u03a7\u03b5\u03bb \u03bc\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf\u03a7\u03b5\u03bb\u03ce\u03bd\u03b5\u03c2 +unicode=unicode +var?=\u03bc\u03b5\u03c4? \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ae? +ve=\u03ba\u03b1\u039f\u03b8 \u03ba\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b5\u039f\u03b8\u03cc\u03bd\u03b7 +vers=\u03c0\u03c1\u03cc\u03c2 +vide?=\u03ac\u03b4\u03b5\u03b9\u03bf? +visible?=\u03bf\u03c1\u03b1\u03c4\u03cc? +vrai=\u03b1\u03bb\u03b7\u03b8\u03ad\u03c2 +vt=\u03ba\u03b1\u039a\u03b5\u03b9 \u03ba\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b5\u039a\u03b5\u03af\u03bc\u03b5\u03bd\u03bf +workspace.chose=\u03b1\u03bd\u03c4\u03b9\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03bf +workspace.def=\u03ba\u03b1\u03b8 \u03ba\u03b1\u03b8\u03cc\u03c1\u03b9\u03c3\u03b5 +workspace.content=\u03c0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03b1 +workspace.donne=\u03ba\u03ac\u03bd\u03b5 +workspace.donnelocale=\u03c4\u03bf\u03c0\u03b9\u03ba\u03cc\u039a\u03ac\u03bd\u03b5 +workspace.ed=\u03b4\u03b9\u03bf \u03b4\u03b9\u03cc\u03c1\u03b8\u03c9\u03c3\u03b5 +workspace.edall=\u03b4\u03b9\u03cc\u03c1\u03b8\u03c9\u03c3\u03b5\u038c\u03bb\u03b1 +workspace.efn=\u03c3\u03b2\u03b7 \u03c3\u03b2\u03ae\u03c3\u03b5 +workspace.efns=\u03c3\u03b2\u03b7\u039f\u03bb \u03c3\u03b2\u03ae\u03c3\u03c4\u03b1\u038c\u03bb\u03b1 +workspace.efv=\u03c3\u03b2\u03ae\u03c3\u03b5\u039c\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ae +workspace.erpl=\u03c3\u03b2\u03b7\u039b\u03b9\u0399\u03b4 \u03c3\u03b2\u03ae\u03c3\u03b5\u039b\u03af\u03c3\u03c4\u03b1\u0399\u03b4\u03b9\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd +workspace.exec=\u03b5\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b5 +workspace.externalcommand=\u03b5\u03be\u03c9\u03c4\u03b5\u03c1\u03b9\u03ba\u03ae\u0395\u03bd\u03c4\u03bf\u03bb\u03ae \u03b5\u03be\u0395\u03bd +workspace.gprop=\u03c0\u03b1\u0399\u03b4 \u03c0\u03ac\u03c1\u03b5\u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 +workspace.imts=\u03c4\u03c5\u039f\u03bb \u03c4\u03cd\u03c0\u03c9\u03c3\u03b5\u038c\u03bb\u03b1 +workspace.listevariables=\u03bc\u03b5\u03c4 \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ad\u03c2 +workspace.locale=\u03c4\u03bf\u03c0\u03b9\u03ba\u03cc +workspace.plist=\u03bb\u03b9\u0399\u03b4 \u03bb\u03af\u03c3\u03c4\u03b1\u0399\u03b4\u03b9\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd +workspace.pprop=\u03b2\u03ac\u03bb\u03b5\u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 +workspace.primitives=\u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03b9\u03ce\u03b4\u03b7\u03c2 +workspace.propertylists=\u03bb\u03af\u03c3\u03c4\u03b5\u03c2\u0399\u03b4\u03b9\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd +workspace.remprop=\u03b1\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b5\u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 +workspace.stoptrace=\u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b1\u03a0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03cd\u03b8\u03b7\u03c3\u03b7 +workspace.text=\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03bf +workspace.trace=\u03c0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03cd\u03b8\u03b7\u03c3\u03b5 +xaxis=\u03ac\u03be\u03bf\u03bd\u03b1\u03c2\u03c7 +xaxis?=\u03ac\u03be\u03bf\u03bd\u03b1\u03c2\u03c7? +yaxis=\u03ac\u03be\u03bf\u03bd\u03b1\u03c2\u03c8 +yaxis?=\u03ac\u03be\u03bf\u03bd\u03b1\u03c2\u03c8? +zoom=\u03bc\u03b5\u03b3\u03ad\u03b8\u03c5\u03bd\u03c3\u03b7
\ No newline at end of file diff --git a/logo/src/primitives_en_DE.properties b/logo/src/primitives_en_DE.properties new file mode 100644 index 0000000..715b1b6 --- /dev/null +++ b/logo/src/primitives_en_DE.properties @@ -0,0 +1,288 @@ +drawing.av = fd forward +drawing.re = bk back +drawing.td = rt right +drawing.tg = lt left +arithmetic.puissance = power +controls.repete = repeat +ve = cs clearscreen +ct = ht hideturtle +mt = st showturtle +ec = pr print +si = if +controls.stop = stop +drawing.origine = home +drawing.fpos = setpos setposition +drawing.fixex = setx +drawing.fixey = sety +drawing.fixexy = setxy +drawing.fixecap =seth setheading +drawing.saveimage=saveimage +drawing.fillpolygon=fillpolygon +drawing.x=x +drawing.y=y +drawing.z=z +lc = pu penup +bc = pd pendown +go = pe penerase +ic = px penreverse +de = ppt penpaint +arithmetic.somme = sum +arithmetic.difference = diff difference +arithmetic.moins = minus +arithmetic.produit = product +arithmetic.quotient = quotient +arithmetic.reste = rem remainder +ret = op output +pos = pos position +cap = heading +arithmetic.arrondi = rnd round +arithmetic.log10 = log10 +arithmetic.sin = sin sine +arithmetic.cos = cos cosine +ou = or +et = and +non = not +liste = list +ph = se sentence +mp = fput +md = lput +inverse = reverse +choix = pick +enleve = remove +item = item +sd = bl butlast +sp = bf butfirst +dernier = last +premier = first +compte = count +mot? = word? wordp +nombre? = number? numberp +liste? = list? listp +vide? = empty? emptyp +egal? = equal? equalp +precede? = before? beforep +membre? = member? memberp +arithmetic.racine = sqrt squareroot +membre = member +workspace.donne = make globalmake +workspace.locale = local +workspace.donnelocale = localmake +fcc = setpc setpencolor +fcfg = setsc setscreencolor +arithmetic.hasard = ran random +attends = wait +workspace.imts = procs procedures +workspace.efn = erp eraseprocedure +workspace.efv = erv erasevariable +workspace.efns = erall eraseall +mot = word +drawing.etiquette = label +tc = fc findcolor +fen = window +enr = wrap +clos = fence +vt = ct cleartext +ci = li loadimage +ftc = setpw setpenwidth +controls.tantque = while +lis = read +touche? = key? +liscar = readchar readcharacter +remplis = fill +drawing.point = dot +vers = towards +distance = distance +cc = pc pencolor +cf = sc screencolor +bc? = pd? pendown? +visible? = visible? +prim? = prim? primitive? +proc? = proc? procedure? +workspace.exec = run +frep = setdir setdirectory +cat = files +rep = dir directory +sauve = save +sauved = saved +ramene = load +arithmetic.pi = pi +arithmetic.tan = tan tangent +arithmetic.acos = acos arccosine +arithmetic.asin = asin arcsine +arithmetic.atan = atan arctangent +vrai = true +faux = false +turtle.forme = shape +turtle.fforme = setshape +tortue = turtle +tortues = turtles +ftortue = sturtle setturtle +police = fontsize +fpolice = setfontsize setfs +workspace.def = def define +tuetortue = ert eraseturtle +seq = seq sequence +joue = play +finstr = sinstr setinstrument +instr = instr instrument +efseq = delseq deletesequence +indseq = indseq indexsequence +findseq = sindseq setindexsequence +fpt=setts settextsize +ptexte = ts textsize +fct=settc settextcolor +couleurtexte= tc textcolor +lissouris = readmouse +possouris = mousepos mouseposition +message=msg message +date = date +heure = time +temps = pasttime +debuttemps = countdown +fintemps? = endcountdown? +fixenompolice=setfn setfontname +nompolice = fontname +fixenompolicetexte = settn settextname +nompolicetexte = tn textname +ouvreflux = openflow +listeflux = listflow +lisligneflux = readlineflow +liscarflux = readcharflow +ecrisligneflux = writelineflow +finflux? = endflow? +fermeflux = closeflow +ajouteligneflux = appendlineflow +souris? = mouse? +workspace.listevariables =vars variables +workspace.chose = thing +nettoie = wash +tape = write +drawing.cercle = circle +drawing.arc = arc +rempliszone = fillzone +animation = anim animation +rafraichis = refresh repaint +tailleimage=screensize +arithmetic.div = divide div +entier? = integer? +fixeseparation = setseparation setsep +separation = separation sep +arithmetic.tronque = integer int +workspace.trace = trace +changedossier = changedirectory cd +unicode = unicode +caractere = character char +controls.stoptout = stopall +controls.compteur = repcount +controls.repetepour = for +arithmetic.absolue = abs absolute +remplace = setitem replace +ajoute = additem +color.gris = gray +color.grisclair = lightgray +color.rougefonce = darkred +color.vertfonce = darkgreen +color.bleufonce = darkblue +color.orange = orange +color.rose = pink +color.violet = purple +color.marron = brown +color.noir = black +color.rouge = red +color.vert = green +color.jaune = yellow +color.bleu = blue +color.magenta =magenta +color.cyan = cyan +color.blanc = white +fixestyle=setsty setstyle +style = sty style +taillefenetre=zonesize +drawing.longueuretiquette=labellength +envoietcp=sendtcp +ecoutetcp=listentcp +executetcp=executetcp +chattcp=chattcp +resetall=resetall +penwidth=pw penwidth +setpenshape=setps setpenshape +penshape=ps penshape +setdrawingquality=setdq setdrawingquality +drawingquality=dq drawingquality +setturtlesnumber=settm setturtlesmax +turtlesnumber=tm turtlesmax +setscreensize=setscreensize +guibutton=guibutton +guiaction=guiaction +guiremove=guiremove +guiposition=guiposition +guidraw=guidraw +zoom=zoom +grille=grid +stopgrille=stopgrid +stopanimation=stopanim stopanimation +workspace.stoptrace=stoptrace +guimenu=guimenu +axis=axis +xaxis=xaxis +yaxis=yaxis +stopaxis=stopaxis +bye=bye +var?=var? variable? +axiscolor= axiscolor +gridcolor=gridcolor +grid?=grid? +xaxis?=xaxis? +yaxis?=yaxis? +setgridcolor=sgc setgridcolor +setaxiscolor=sac setaxiscolor +3d.perspective=perspective 3d +3d.rightroll=rr rightroll +3d.uppitch=up uppitch +3d.leftroll=lr leftroll +3d.downpitch=down downpitch +3d.roll=roll +3d.pitch=pitch +3d.setroll=setroll +3d.setpitch=setpitch +3d.setorientation=setorientation +3d.orientation=orientation +3d.setxyz=setxyz +3d.setz=setz +workspace.pprop=pprop putproperty +workspace.gprop=gprop getproperty +workspace.remprop=rprop removeproperty +workspace.plist=plist propertylist +3d.polystart=polystart +3d.polyend=polyend +3d.polyview=polyview view3d +3d.linestart=linestart +3d.lineend=lineend +3d.pointstart=pointstart +3d.pointend=pointend +3d.textstart=textstart +3d.textend=textend +workspace.primitives=primitives +workspace.propertylists=pls propertylists +workspace.content=contents +workspace.erpl=erpl erasepropertylist +arithmetic.exp=exp +arithmetic.log=log +controls.ifelse=ifelse +workspace.ed=ed edit +workspace.edall=edall editall +controls.foreach=foreach +controls.forever=forever +arithmetic.digits=digits +arithmetic.setdigits=setdigits +workspace.text=text +workspace.externalcommand=externalcommand +sound.mp3play=mp3play +sound.mp3stop=mp3stop +setzoom=setzoom +arithmetic.alea=alea +loop.dountil=repeatuntil dountil +loop.dowhile=repeatwhile dowhile +aritmetic.modulo=mod modulo +drawing.setfontjustify=setfontjustify +drawing.fontjustify=fontjustify
\ No newline at end of file diff --git a/logo/src/primitives_en_US.properties b/logo/src/primitives_en_US.properties new file mode 100644 index 0000000..715b1b6 --- /dev/null +++ b/logo/src/primitives_en_US.properties @@ -0,0 +1,288 @@ +drawing.av = fd forward +drawing.re = bk back +drawing.td = rt right +drawing.tg = lt left +arithmetic.puissance = power +controls.repete = repeat +ve = cs clearscreen +ct = ht hideturtle +mt = st showturtle +ec = pr print +si = if +controls.stop = stop +drawing.origine = home +drawing.fpos = setpos setposition +drawing.fixex = setx +drawing.fixey = sety +drawing.fixexy = setxy +drawing.fixecap =seth setheading +drawing.saveimage=saveimage +drawing.fillpolygon=fillpolygon +drawing.x=x +drawing.y=y +drawing.z=z +lc = pu penup +bc = pd pendown +go = pe penerase +ic = px penreverse +de = ppt penpaint +arithmetic.somme = sum +arithmetic.difference = diff difference +arithmetic.moins = minus +arithmetic.produit = product +arithmetic.quotient = quotient +arithmetic.reste = rem remainder +ret = op output +pos = pos position +cap = heading +arithmetic.arrondi = rnd round +arithmetic.log10 = log10 +arithmetic.sin = sin sine +arithmetic.cos = cos cosine +ou = or +et = and +non = not +liste = list +ph = se sentence +mp = fput +md = lput +inverse = reverse +choix = pick +enleve = remove +item = item +sd = bl butlast +sp = bf butfirst +dernier = last +premier = first +compte = count +mot? = word? wordp +nombre? = number? numberp +liste? = list? listp +vide? = empty? emptyp +egal? = equal? equalp +precede? = before? beforep +membre? = member? memberp +arithmetic.racine = sqrt squareroot +membre = member +workspace.donne = make globalmake +workspace.locale = local +workspace.donnelocale = localmake +fcc = setpc setpencolor +fcfg = setsc setscreencolor +arithmetic.hasard = ran random +attends = wait +workspace.imts = procs procedures +workspace.efn = erp eraseprocedure +workspace.efv = erv erasevariable +workspace.efns = erall eraseall +mot = word +drawing.etiquette = label +tc = fc findcolor +fen = window +enr = wrap +clos = fence +vt = ct cleartext +ci = li loadimage +ftc = setpw setpenwidth +controls.tantque = while +lis = read +touche? = key? +liscar = readchar readcharacter +remplis = fill +drawing.point = dot +vers = towards +distance = distance +cc = pc pencolor +cf = sc screencolor +bc? = pd? pendown? +visible? = visible? +prim? = prim? primitive? +proc? = proc? procedure? +workspace.exec = run +frep = setdir setdirectory +cat = files +rep = dir directory +sauve = save +sauved = saved +ramene = load +arithmetic.pi = pi +arithmetic.tan = tan tangent +arithmetic.acos = acos arccosine +arithmetic.asin = asin arcsine +arithmetic.atan = atan arctangent +vrai = true +faux = false +turtle.forme = shape +turtle.fforme = setshape +tortue = turtle +tortues = turtles +ftortue = sturtle setturtle +police = fontsize +fpolice = setfontsize setfs +workspace.def = def define +tuetortue = ert eraseturtle +seq = seq sequence +joue = play +finstr = sinstr setinstrument +instr = instr instrument +efseq = delseq deletesequence +indseq = indseq indexsequence +findseq = sindseq setindexsequence +fpt=setts settextsize +ptexte = ts textsize +fct=settc settextcolor +couleurtexte= tc textcolor +lissouris = readmouse +possouris = mousepos mouseposition +message=msg message +date = date +heure = time +temps = pasttime +debuttemps = countdown +fintemps? = endcountdown? +fixenompolice=setfn setfontname +nompolice = fontname +fixenompolicetexte = settn settextname +nompolicetexte = tn textname +ouvreflux = openflow +listeflux = listflow +lisligneflux = readlineflow +liscarflux = readcharflow +ecrisligneflux = writelineflow +finflux? = endflow? +fermeflux = closeflow +ajouteligneflux = appendlineflow +souris? = mouse? +workspace.listevariables =vars variables +workspace.chose = thing +nettoie = wash +tape = write +drawing.cercle = circle +drawing.arc = arc +rempliszone = fillzone +animation = anim animation +rafraichis = refresh repaint +tailleimage=screensize +arithmetic.div = divide div +entier? = integer? +fixeseparation = setseparation setsep +separation = separation sep +arithmetic.tronque = integer int +workspace.trace = trace +changedossier = changedirectory cd +unicode = unicode +caractere = character char +controls.stoptout = stopall +controls.compteur = repcount +controls.repetepour = for +arithmetic.absolue = abs absolute +remplace = setitem replace +ajoute = additem +color.gris = gray +color.grisclair = lightgray +color.rougefonce = darkred +color.vertfonce = darkgreen +color.bleufonce = darkblue +color.orange = orange +color.rose = pink +color.violet = purple +color.marron = brown +color.noir = black +color.rouge = red +color.vert = green +color.jaune = yellow +color.bleu = blue +color.magenta =magenta +color.cyan = cyan +color.blanc = white +fixestyle=setsty setstyle +style = sty style +taillefenetre=zonesize +drawing.longueuretiquette=labellength +envoietcp=sendtcp +ecoutetcp=listentcp +executetcp=executetcp +chattcp=chattcp +resetall=resetall +penwidth=pw penwidth +setpenshape=setps setpenshape +penshape=ps penshape +setdrawingquality=setdq setdrawingquality +drawingquality=dq drawingquality +setturtlesnumber=settm setturtlesmax +turtlesnumber=tm turtlesmax +setscreensize=setscreensize +guibutton=guibutton +guiaction=guiaction +guiremove=guiremove +guiposition=guiposition +guidraw=guidraw +zoom=zoom +grille=grid +stopgrille=stopgrid +stopanimation=stopanim stopanimation +workspace.stoptrace=stoptrace +guimenu=guimenu +axis=axis +xaxis=xaxis +yaxis=yaxis +stopaxis=stopaxis +bye=bye +var?=var? variable? +axiscolor= axiscolor +gridcolor=gridcolor +grid?=grid? +xaxis?=xaxis? +yaxis?=yaxis? +setgridcolor=sgc setgridcolor +setaxiscolor=sac setaxiscolor +3d.perspective=perspective 3d +3d.rightroll=rr rightroll +3d.uppitch=up uppitch +3d.leftroll=lr leftroll +3d.downpitch=down downpitch +3d.roll=roll +3d.pitch=pitch +3d.setroll=setroll +3d.setpitch=setpitch +3d.setorientation=setorientation +3d.orientation=orientation +3d.setxyz=setxyz +3d.setz=setz +workspace.pprop=pprop putproperty +workspace.gprop=gprop getproperty +workspace.remprop=rprop removeproperty +workspace.plist=plist propertylist +3d.polystart=polystart +3d.polyend=polyend +3d.polyview=polyview view3d +3d.linestart=linestart +3d.lineend=lineend +3d.pointstart=pointstart +3d.pointend=pointend +3d.textstart=textstart +3d.textend=textend +workspace.primitives=primitives +workspace.propertylists=pls propertylists +workspace.content=contents +workspace.erpl=erpl erasepropertylist +arithmetic.exp=exp +arithmetic.log=log +controls.ifelse=ifelse +workspace.ed=ed edit +workspace.edall=edall editall +controls.foreach=foreach +controls.forever=forever +arithmetic.digits=digits +arithmetic.setdigits=setdigits +workspace.text=text +workspace.externalcommand=externalcommand +sound.mp3play=mp3play +sound.mp3stop=mp3stop +setzoom=setzoom +arithmetic.alea=alea +loop.dountil=repeatuntil dountil +loop.dowhile=repeatwhile dowhile +aritmetic.modulo=mod modulo +drawing.setfontjustify=setfontjustify +drawing.fontjustify=fontjustify
\ No newline at end of file diff --git a/logo/src/primitives_eo_EO.properties b/logo/src/primitives_eo_EO.properties new file mode 100644 index 0000000..5ba6673 --- /dev/null +++ b/logo/src/primitives_eo_EO.properties @@ -0,0 +1,288 @@ +3d.downpitch=msn malsupren +3d.leftroll=mdfn maldekstraflanken +3d.lineend=linia_difinhalto +3d.linestart=linia_difino +3d.orientation=orientadon +3d.perspective=perspektive +3d.pitch=frontklinon +3d.pointend=punkta_difinhalto +3d.pointstart=punkta_difino +3d.polyend=fino_edro +3d.polystart=por_edro +3d.polyview=tridimensie_vidigu +3d.rightroll=dfn dekstraflanken +3d.roll=flankklinon +3d.setorientation=orientadon_provizu +3d.setpitch=frontklinon_provizu +3d.setroll=flankklinon_provizu +3d.setxyz=xyzp xyz_provizu +3d.setz=zp z_provizu +3d.textend=teksta_difinhalto +3d.textstart=teksta_difino +3d.uppitch=sn supren +ajoute = almetu +ajouteligneflux=flulinald flukslinion_aldonu +animation = movado +arithmetic.absolue = absolute abs +arithmetic.acos=akos arkokosinuson +arithmetic.arrondi=entjeran +arithmetic.asin=asin arkosinuson +arithmetic.atan=atan arkotangenton +arithmetic.cos=kos kosinuson +arithmetic.difference=sub subtrahon +arithmetic.digits=decimalojn +arithmetic.div=div dividon +arithmetic.exp=eksp +arithmetic.hasard=hzd hazardon +arithmetic.log=log +arithmetic.log10=log10 +arithmetic.moins=mns minusigan +arithmetic.pi=pi +arithmetic.produit=prod produton +arithmetic.puissance=pot potencon +arithmetic.quotient=kvoc kvocienton +arithmetic.racine=rdk radikon +arithmetic.reste=rest reston +arithmetic.setdigits=decimalojn_provizu +arithmetic.sin=sin sinuson +arithmetic.somme=sum sumon +arithmetic.tan=tan tangenton +arithmetic.tronque = entjeran_parton +attends=atnd atendu +axis=aksigu +axiscolor=akskoloron +bc?=ml? mallevata? +bc=ml mallevu +bye=adia\u016d adiau adia\u00fb adiaw adia\u0175 adiaux +cap=dir direkton +caractere=lit literige +cat=ktlg katalogon +cc=skol skribkoloron +cf=fkol fonkoloron +changedossier = cd celu_dosieron +chattcp=diskutilotcp +choix=elkt elekton +ci=bild bildon_\u015dargu +clos=f ferme +color.blanc=blankan +color.bleu=bluan +color.bleufonce=malhele_bluan +color.cyan=verdbluan +color.gris=grizan +color.grisclair=hele_grizan +color.jaune=flavan +color.magenta=violru\u011dan +color.marron=maronan +color.noir=nigran +color.orange=oran\u011dkoloran +color.rose=rozan +color.rouge=ru\u011dan +color.rougefonce=malhele_ru\u011dan +color.vert=verdan +color.vertfonce=malhele_verdan +color.violet=violan +compte=nombru +controls.compteur=nombrilon +controls.foreach=por_\u0109iu +controls.forever=\u0109iam_ripetu +controls.ifelse=se_sene +controls.repete=rpt ripetu +controls.repetepour = ripetupor +controls.stop=haltu +controls.stoptout = haltu +controls.tantque=dum +couleurtexte=tkol tekstkoloron +ct=tdk testudon_ka\u015du +date=daton +de=dsg desegne +debuttemps=tmpko tempokomencon +dernier=last lastan +distance=dist distancon +drawing.arc=ark arkon_desegnu +drawing.av=an antauen antawen antauxen anta\u016den +drawing.cercle=rond rondon_desegnu +drawing.etiquette=etik etiketu +drawing.fixecap=dirp direkton_provizu +drawing.fixex=xp x_provizu +drawing.fixexy=xyp xy_provizu +drawing.fixey=yp y_provizu +drawing.fpos=sitp situon_provizu +drawing.longueuretiquette=etikedlongon etikl +drawing.origine=o originen +drawing.point=punkt punkton_montru +drawing.re=man malantauen malantawen malantauxen malanta\u016den +drawing.saveimage=bildon_konservu +drawing.td=dn dekstren +drawing.tg=mdn maldekstren +drawingquality=dsgc desegnecon +ec=s skribu +ecoutetcp=tcp_a\u016dskultu tcp_auskultu tcp_a\u00fbskultu tcp_awskultu tcp_a\u0175skultu tcp_auxskultu +ecrisligneflux=flulins flukslinion_skribu +efseq=sekvv sekvencon_vi\u015du +egal?=eg? egala? +enleve=for forigu +enr=vlv volve +entier? = entjera? +envoietcp=sendutcp +et=k kaj +executetcp=ekzekucutcp +faux=mvera malvera +fcc=skolp skribkoloron_provizu +fcfg=fkolp fonkoloron_provizu +fct=tkolp tekstkoloron_provizu +fen=fen fenestre +fermeflux=fluf flukson_fermu +findseq=sekvindp sekvencindekson_provizu +finflux?=flufin? fluksfine? +finstr=instrp instrumenton_provizu +fintemps?=tmpfi tempofine? +fixenompolice=tipnp tiparnomon_provizu +fixenompolicetexte=ttipnp teksttiparnomon_provizu +fixeseparation = ekranon_disigu +fixestyle = stip stilon_provizu +fpolice=tipp tiparon_provizu +fpt=ttipp teksttiparon_provizu +frep=dosp dosierujon_provizu +ftc=sdikp skribdikon_provizu +ftortue=tdp testudon_provizu +go=gum gumskrapu +grid?=dratreta? +gridcolor=dratreta_koloron +grille=dratretu +guiaction=gui_agadon +guibutton=gui_butonon +guidraw=gui_desegnu +guimenu=gui_menuon +guiposition=gui_koordinatojn +guiremove=gui_forigu +heure=horon +ic=si strekon_inversu +indseq=sekvind sekvencindekson +instr=instr instrumenton +inverse=inv inversan +item=er eron +joue=muziku +lc=l levu +lis=leg legu +liscar=litleg literon_legu +liscarflux=flulitleg fluksliteron_legu +lisligneflux=flulinleg flukslinion_legu +lissouris=musleg muson_legu +liste?=list? lista? +liste=list liston +listeflux=flulist fluksliston +md=lastk kunlastan +membre?=mbr? membra? +membre=mbr membron +message=avrt avertu +mot?=vort? vorta? +mot=vort vorton +mp=unk kununuan +mt=tdm testudon_montru +nettoie=pur purigu +nombre?=nb? nombra? +nompolice=tipn tiparnomon +nompolicetexte=ttipn teksttiparnomon +non=ne +ou=a au aw aux a\u016d +ouvreflux=flumf flukson_malfermu +penshape=sform skribformon +penwidth=sdik skribdikon +ph=fr frazon +police=tip tiparon +pos=sit situon +possouris=mussit mussituon +precede?=\u0109u_anta\u016das? +premier=un unuan +prim?=prim? primitiva? +proc?=prog? programera? +ptexte=ttip teksttiparon +rafraichis = novigu +ramene=ramenu +remplace=anstata\u016digu +remplis=plenigu +rempliszone = kovru +rep=reg registron +resetall=pradif pradifine +ret=snd sendu +sauve=ksrv konservu +sauved=pa\u011don_registru +sd=ls senlastan +separation = ekranon_disigon +seq=sek sekvencon +setaxiscolor=akskoloron_provizu +setdrawingquality=dsgcp desegnecon_provizu +setgridcolor=dratretkoloron_provizu +setpenshape=sformp skribformon_provizu +setscreensize=dsgamplp desegnamplekson_provizu +setturtlesnumber=tdkiomp testudkiomon_provizu +setzoom=zomu +si=se +sound.mp3play=mp3legu +sound.mp3stop=neplu_mp3legu +souris?=muse? +sp=us senunuan +stopanimation=neplu_movigu +stopaxis=aksojn_vi\u015du +stopgrille=neplu_dratretu +style = sti stilon +taillefenetre=fenestramplekson fenampl +tailleimage=dsgampl desegnamplekson +tape=tajpu +tc=kol koloron +temps=tmp tempon +tortue=td testudon +tortues=tdj testudojn +touche?=klave? +tuetortue=tdb testudon_bu\u0109u +turtle.fforme=formp formon_provizu +turtle.forme=form formon +turtlesnumber=tdkiomp testudkiomon +unicode = u unikode +var?=var? variabla? +ve=ev ekranon_vi\u015du +vers=diral aldirektu +vide?=mpl? malplena? +visible?=videbla? +vrai=vera +vt=tv tekston_vi\u015du +workspace.chose=enhv enhavon +workspace.content=enhavon +workspace.def=dif difinu +workspace.donne=p provizu +workspace.donnelocale=lokp loke_provizu +workspace.ed=eldonu +workspace.edall=\u0109ion_eldonu +workspace.efn=nv nomon_vi\u015du +workspace.efns=njv nomojn_vi\u015du +workspace.efv=varv varianton_vi\u015du +workspace.erpl=ecan_liston_vi\u015du +workspace.exec=ekzek ekzekutu +workspace.externalcommand=startigu +workspace.gprop=econ_sendu +workspace.imts=progcit programerojn_citu +workspace.listevariables=varlist variantliston +workspace.locale=lokvark lokan_varianton_kreu +workspace.plist=ecan_liston +workspace.pprop=econ_provizu +workspace.primitives=programeraro +workspace.propertylists=ecajn_listojn +workspace.remprop=econ_vi\u015du +workspace.stoptrace=programon_kontrolu +workspace.text=difinon +workspace.trace = programon_kontrolu +xaxis?=x_aksa? +xaxis=x_aksigu +yaxis?=y_aksa? +yaxis=y_aksigu +zoom=zomon +drawing.x=x +drawing.y=y +drawing.z=z +drawing.fillpolygon=remplispolygone +arithmetic.alea=alea +loop.dountil=repetejusqua +loop.dowhile=repetetantque +aritmetic.modulo=mod modulo +drawing.setfontjustify=fixealignementpolice +drawing.fontjustify=alignementpolice
\ No newline at end of file diff --git a/logo/src/primitives_es_ES.properties b/logo/src/primitives_es_ES.properties new file mode 100644 index 0000000..cfb1fae --- /dev/null +++ b/logo/src/primitives_es_ES.properties @@ -0,0 +1,292 @@ +drawing.av = av avanza +drawing.re = re retrocede +drawing.td = gd giraderecha +drawing.tg = gi giraizquierda +arithmetic.puissance = potencia +controls.repete = repite +ve = bp borrapantalla +ct = ot ocultatortuga +mt = mt muestratortuga +ec = es escribe +si = si +controls.stop = alto +drawing.origine = centro +drawing.fpos = ponpos ponposicion ponposici\u00f3n +drawing.fixex = ponx +drawing.fixey = pony +drawing.fixexy = ponxy +drawing.fixecap = ponr ponrumbo +lc = sl subelapiz subel\u00e1piz +bc = bl bajalapiz bajal\u00e1piz +go = go goma +ic = ila inviertelapiz inviertel\u00e1piz +de = pla ponlapiz ponl\u00e1piz +arithmetic.somme = suma +arithmetic.difference = diferencia +arithmetic.moins = cs cambiasigno +arithmetic.produit = producto +arithmetic.quotient = cociente +arithmetic.reste = resto +arithmetic.digits = decimales digitos d\u00edgitos +arithmetic.setdigits = pondecimales pondigitos pond\u00edgitos +ret = dev devuelve +pos = pos posicion posici\u00f3n +cap = rumbo +arithmetic.arrondi = redondea +arithmetic.log10 = log log10 logaritmo +arithmetic.sin = sen seno +arithmetic.cos = cos coseno +ou = o +et = y +non = no +liste = lista +mot = palabra +ph = fr frase +mp = pp ponprimero +md = pu ponultimo pon\u00faltimo +inverse = invierte +choix = elige +enleve = quita +item = elemento +sd = mu menosultimo menos\u00faltimo +sp = mp menosprimero +dernier = ultimo \u00faltimo +premier = pr primero +compte = cuenta +mot? = palabra? +nombre? = numero? n\u00famero? +liste? = lista? +vide? = vacio? vac\u00edo? +egal? = iguales? +precede? = antes? anterior? +membre? = miembro? +arithmetic.racine = rc raizcuadrada +membre = miembro +workspace.donne = haz +workspace.locale = local +workspace.donnelocale = hazlocal +fcc = poncl poncolorlapiz poncolorl\u00e1piz +fcfg = poncp poncolorpapel +arithmetic.hasard = azar +attends = espera +workspace.imts = imts listaprocs +workspace.efn = bo borra +workspace.efv = bov borravariable +workspace.efns = borratodo +drawing.etiquette = rotula +tc = ec encuentracolor +fen = modoventana +enr = modovuelta +clos = modojaula +vt = bt borratexto +ci = ci cargaimagen +ftc = pongr pongrosor +controls.tantque = mientras +lis = leeteclado leelista +touche? = tecla? +liscar = leecar leetecla +remplis = rellena +drawing.point = punto +vers = hacia +distance = distancia +cc = cl colorlapiz colorl\u00e1piz +cf = colorpapel +bc? = bl? bajalapiz? bajal\u00e1piz? +visible? = visible? +prim? = prim? primitiva? +proc? = proc? procedimiento? +workspace.exec = ejecuta +frep = pondir pondirectorio +cat = cat catalogo cat\u00e1logo +rep = dir directorio +sauve = guarda +sauved = guardatodo +ramene = carga +arithmetic.pi = pi +arithmetic.tan = tan tg tangente +arithmetic.acos = acos arccos arcocoseno +arithmetic.asin = asen arcsen arcoseno +arithmetic.atan = atan arctg arcotangente +vrai = cierto +faux = falso +turtle.forme = forma +turtle.fforme = pforma ponforma +tortue = tortuga +tortues = tortugas +ftortue = ptortuga pontortuga +police = fuente +fpolice = pf ponfuente +workspace.def = def define +tuetortue = eliminatortuga +seq = sec secuencia +joue = tocamusica tocam\u00fasica +finstr = pinstr poninstrumento +instr = instr instrumento +efseq = bos borrasecuencia +indseq = indsec indicesecuencia +findseq = pindsec ponindicesecuencia +fpt = pft ponfuentetexto +ptexte = ftexto fuentetexto +fct = pctexto poncolortexto +couleurtexte = colortexto +lissouris = leeraton leerat\u00f3n +possouris = posraton posrat\u00f3n +message = msj mensaje +date = fecha +heure = hora +temps = tiempo +debuttemps = crono cronometro cron\u00f3metro +fintemps? = fincrono? fincronometro? fincron\u00f3metro? +fixenompolice = pnf ponnombrefuente +nompolice = nf nombrefuente +fixenompolicetexte = pnft ponnombrefuentetexto +nompolicetexte = nft nombrefuentetexto +ouvreflux = abreflujo +listeflux = listaflujos +lisligneflux = leelineaflujo +liscarflux = leecarflujo +ecrisligneflux = escribelineaflujo +finflux? = finflujo? +fermeflux = cierraflujo +ajouteligneflux = agregalineaflujo +souris? = raton? rat\u00f3n? +workspace.listevariables = imvars listavars +workspace.chose = objeto cosa +nettoie = limpia +tape = tipea mecanografia mecanograf\u00eda +drawing.cercle = circulo c\u00edrculo +drawing.arc = arco +drawing.saveimage = guardaimagen +rempliszone = rellenazona +animation = animacion animaci\u00f3n +rafraichis = refrescar refresca +tailleimage = tpant tama\u00f1opantalla +arithmetic.div = div division divisi\u00f3n +entier? = entero? +fixeseparation = ponsep ponseparacion ponseparaci\u00f3n +separation = separacion separaci\u00f3n +arithmetic.tronque = truncar trunca +workspace.trace = trazado +changedossier = cd cambiadirectorio +unicode = unicode +caractere = car caracter +controls.stoptout = detienetodo +controls.compteur = cuentarepite contador +controls.repetepour = repitepara +arithmetic.absolue = absoluto abs +remplace = reemplaza +ajoute = agrega +color.gris = gris +color.grisclair = grisclaro +color.rougefonce = rojooscuro +color.vertfonce = verdeoscuro +color.bleufonce = azuloscuro +color.orange = naranja +color.rose = rosa +color.violet = violeta +color.marron = marron marr\u00f3n +color.noir = negro +color.rouge = rojo +color.vert = verde +color.jaune = amarillo +color.bleu = azul +color.magenta = magenta +color.cyan = cyan +color.blanc = blanco +fixestyle = pest ponestilo +style = est estilo +taillefenetre = tv tama\u00f1oventana esquinasventana +drawing.longueuretiquette = le largoetiqueta +envoietcp = etcp enviatcp +ecoutetcp = escuchatcp +executetcp = ejecutatcp +chattcp = chattcp +resetall = inicializa reponetodo +penwidth = gl grosorlapiz grosorl\u00e1piz +setpenshape = pfl ponformalapiz ponformal\u00e1piz +penshape = fl formalapiz formal\u00e1piz +setdrawingquality = pcd poncalidaddibujo +drawingquality = cdib calidaddibujo +setturtlesnumber = pmt ponmaximastortugas +turtlesnumber = maxt maximastortugas +setscreensize = ptp pontama\u00f1opantalla +stopanimation = detieneanimacion detieneanimaci\u00f3n +guibutton = botonigu +guiaction = accionigu +guiremove = eliminaigu +guimenu = menuigu +guiposition = posicionigu +workspace.stoptrace = detienetrazado +guidraw = dibujaigu +grille = cuadricula cuadr\u00edcula +gridcolor = colorcuadricula colorcuadr\u00edcula +stopaxis = borraejes detieneejes +stopgrille = borracuadricula detienecuadricula borracuadr\u00edcula detienecuadr\u00edcula +yaxis? = ejey? +axiscolor = colorejes +yaxis = ejey +grid? = cuadricula? cuadr\u00edcula? +axis = ejes +setaxiscolor = pce poncolorejes +var? = var? variable? +setgridcolor = pcc poncolorcuadricula poncolorcuadr\u00edcula +xaxis? = ejex? +bye = adios adi\u00f3s +xaxis = ejex +3d.downpitch = bn bajanariz cabeceaabajo +3d.leftroll = bi balanceaizquierda +3d.lineend = finlinea finl\u00ednea +3d.linestart = definelinea empiezalinea definel\u00ednea empiezal\u00ednea +3d.orientation = orientacion orientaci\u00f3n +3d.perspective = perspectiva +3d.pitch = cabeceo +3d.pointend = finpto finpunto +3d.pointstart = defpto definepunto empiezapunto +3d.polyend = finpoli finpoligono finpol\u00edgono +3d.polystart = defpoli definepoligono empiezapoligono definepol\u00edgono empiezapol\u00edgono +3d.polyview = vista3d vistapoligono vistapol\u00edgono +3d.rightroll = bd balanceaderecha +3d.roll = balanceo +3d.setorientation = ponorientacion ponorientaci\u00f3n +3d.setpitch = poncabeceo +3d.setroll = ponbalanceo +3d.setxyz = ponxyz +3d.setz = ponz +3d.textend = fintxt fintexto +3d.textstart = deftxt definetexto empiezatexto +3d.uppitch = sn subenariz cabeceaarriba +workspace.gprop = leeprop leepropiedad devuelvepropiedad +workspace.plist = listaprop listapropiedades +workspace.pprop = ponprop ponpropiedad +workspace.remprop = boprop borrapropiedad +workspace.primitives = primitivas +arithmetic.exp = exp +arithmetic.log = logneperiano ln +controls.foreach = paracada +controls.forever = repitesiempre +controls.ifelse = sisino +workspace.content = contenido +workspace.ed = ed edita +workspace.edall = edtodo editatodo +workspace.erpl = bolistprop borralistapropiedades +workspace.propertylists = listasprop listaspropiedades +workspace.text = texto +workspace.externalcommand = comandoexterno +sound.mp3play = escuchamp3 +sound.mp3stop = detienemp3 +zoom = zoom lupa +setzoom = ponzoom ponlupa +drawing.x = coordx coordenadax +drawing.y = coordy coordenaday +drawing.z = coordz coordenadaz +drawing.fillpolygon = rellenapol\u00edgono rellenapoligono +arithmetic.alea = aleatorio +loop.dountil = repitehasta +loop.dowhile = repitemientras +aritmetic.modulo = mod modulo m\u00f3dulo +drawing.setfontjustify = ponjustificadofuente +drawing.fontjustify = justificadofuente +arithmetic.inf = menor? +arithmetic.infequal = menoroigual? +arithmetic.sup = mayor? +arithmetic.supequal = mayoroigual?
\ No newline at end of file diff --git a/logo/src/primitives_fr_FR.properties b/logo/src/primitives_fr_FR.properties new file mode 100644 index 0000000..6fa046d --- /dev/null +++ b/logo/src/primitives_fr_FR.properties @@ -0,0 +1,292 @@ +3d.downpitch=pique +3d.leftroll=rg roulisgauche +3d.lineend=lignefin +3d.linestart=lignedef +3d.orientation=orientation +3d.perspective=perspective +3d.pitch=cabrement tangage +3d.pointend=pointfin +3d.pointstart=pointdef +3d.polyend=polyfin +3d.polystart=polydef +3d.polyview=polyaf vue3d +3d.rightroll=rd roulisdroite +3d.roll=roulis +3d.setorientation=fixeorientation +3d.setpitch=fixetangage +3d.setroll=fixeroulis +3d.setxyz=fixexyz +3d.setz=fixez +3d.textend=textefin +3d.textstart=textedef +3d.uppitch=cabre +ajoute = ajoute +ajouteligneflux = ajouteligneflux +arithmetic.alea=alea +animation = animation +arithmetic.absolue = abs absolue +arithmetic.acos = acos arccosinus +arithmetic.arrondi = arrondi +arithmetic.asin = asin arcsinus +arithmetic.atan = atan arctangente +arithmetic.cos = cos cosinus +arithmetic.difference = difference +arithmetic.digits=decimales +arithmetic.div = divise div +arithmetic.exp=exp +arithmetic.hasard = hasard +arithmetic.inf=inf? +arithmetic.infequal=infegal? +arithmetic.log=log +arithmetic.log10 = log10 +aritmetic.modulo=mod modulo +arithmetic.moins = moins +arithmetic.pi = pi +arithmetic.produit = produit +arithmetic.puissance = puissance +arithmetic.quotient = quotient +arithmetic.racine = rac racine +arithmetic.reste = reste +arithmetic.setdigits=fixedecimales +arithmetic.sin = sin sinus +arithmetic.somme = somme +arithmetic.sup=sup? +arithmetic.supequal=supegal? +arithmetic.tan = tan tangente +arithmetic.tronque = tronque +attends = attends +axis=axes +axiscolor= couleuraxes +bc = bc baissecrayon +bc? = bc? baissecrayon? +bye=bye aurevoir +cap = cap +caractere = car caractere +cat = cat catalogue +cc = cc couleurcrayon +cf = cf couleurfond +changedossier = cd changedossier +chattcp=chattcp +choix = choix +ci = ci chargeimage +clos = clos +color.blanc = blanc +color.bleu = bleu +color.bleufonce = bleufonce +color.cyan = cyan +color.gris = gris +color.grisclair = grisclair +color.jaune = jaune +color.magenta =magenta +color.marron = marron +color.noir = noir +color.orange = orange +color.rose = rose +color.rouge = rouge +color.rougefonce = rougefonce +color.vert = vert +color.vertfonce = vertfonce +color.violet = violet +compte = compte +controls.compteur = compteur +controls.ifelse=sisinon +controls.foreach=pourchaque +controls.forever=repetetjs repetetoujours +controls.repete = repete +controls.repetepour = repetepour +controls.stop = stop +controls.stoptout = stoptout +controls.tantque = tantque +couleurtexte = ctexte couleurtexte +ct = ct cachetortue +date = date +de = de dessine +debuttemps = debuttemps +dernier = dernier der +distance = distance +drawing.arc = arc +drawing.av = av avance +drawing.cercle = cercle +drawing.etiquette = etiquette +drawing.fixecap = fixecap +drawing.fixex = fixex +drawing.fixexy = fixexy +drawing.fixey = fixey +drawing.fillpolygon=remplispolygone +drawing.fontjustify=ap alignementpolice +drawing.fpos = fpos fixeposition +drawing.longueuretiquette=le longueuretiquette +drawing.origine = origine +drawing.point = point +drawing.re = re recule +drawing.saveimage=sauveimage +drawing.setfontjustify=fap fixealignementpolice +drawing.td = td tournedroite +drawing.tg = tg tournegauche +drawingquality=qd qualitedessin +drawing.x=x +drawing.y=y +drawing.z=z +ec = ec ecris +ecoutetcp=ecoutetcp +ecrisligneflux = ecrisligneflux +efseq = efseq effacesequence +egal? = egal? +enleve = enleve +enr = enr enroule +entier? = entier? +envoietcp=envoietcp +et = et +executetcp=executetcp +faux = faux +fcc = fcc fixecouleurcrayon +fcfg = fcfg fixecouleurfondgraphique +fct = fct fixecouleurtexte +fen = fen fenetre +fermeflux = fermeflux +findseq = findseq fixeindexsequence +finflux? = finflux? +finstr = finstr fixeinstrument +fintemps? = fintemps? +fixenompolice = fnp fixenompolice +fixenompolicetexte = fnpt fixenompolicetexte +fixeseparation = fsep fixeseparation +fixestyle = fsty fixestyle +fpolice = fixetaillepolice ftp +fpt = fixetaillepolicetexte ftpt +frep = frep fixerepertoire +ftc = ftc fixetaillecrayon +ftortue = ftortue fixetortue +go = go gomme +grid?=grille? +gridcolor=couleurgrille +grille=grille +guiaction=guiaction +guibutton=guibouton +guidraw=guidessine +guimenu=guimenu +guiposition=guiposition +guiremove=guienleve +heure = heure +ic = ic inversecrayon +indseq = indseq indexsequence +instr = instr instrument +inverse = inverse +item = item +joue = joue +lc = lc levecrayon +lis = lis +liscar = liscar +liscarflux = liscarflux +lisligneflux = lisligneflux +lissouris = lissouris +liste = liste +liste? = liste? +listeflux = listeflux +loop.dountil=repetejusqua +loop.dowhile=repetetantque +md = md metsdernier +membre = membre +membre? = membre? +message = msg message +mot = mot +mot? = mot? +mp = mp metspremier +mt = mt montretortue +nettoie = nettoie +nombre? = nombre? +nompolice = np nompolice +nompolicetexte = npt nompolicetexte +non = non +ou = ou +ouvreflux = ouvreflux +penshape=fc formecrayon +penwidth=tc taillecrayon +ph = ph phrase +police = taillepolice tp +pos = pos +possouris = possouris +precede? = precede? +premier = premier prem +prim? = prim? primtive? +proc? = proc? procedure? +ptexte = taillepolicetexte tpt +rafraichis = rf rafraichis +ramene = ramene +remplace = remplace +remplis = remplis +rempliszone = rempliszone +rep = rep repertoire +resetall=init +ret = ret retourne +sauve = sauve +sauved = sauved +sd = sd saufdernier +separation = sep separation +seq = seq sequence +setaxiscolor=fca fixecouleuraxes +setdrawingquality=fqd fixequalitedessin +setgridcolor=fcg fixecouleurgrille +setpenshape=ffc fixeformecrayon +setscreensize=ftd fixetailledessin +setturtlesnumber=fmt fixemaxtortues +setzoom=fixezoom +si = si +sound.mp3play=jouemp3 +sound.mp3stop=stopmp3 +souris? = souris? +sp = sp saufpremier +stopanimation=stopanimation +stopaxis=stopaxes +stopgrille=stopgrille +style = sty style +taillefenetre=tf taillefenetre +tailleimage=tailledessin +tape = tape +tc =trouvecouleur +temps =temps +tortue = tortue +tortues = tortues +touche? = touche? +tuetortue = effacetortue +turtle.fforme = fforme fixeforme +turtle.forme = forme +turtlesnumber=maxtortues +unicode = unicode +var?=var? variable? +ve = ve videecran +vers = vers +vide? = vide? +visible? = visible? +vrai = vrai +vt = vt videtexte +workspace.chose = chose +workspace.content=contenu +workspace.def = def definis +workspace.donne = donne +workspace.donnelocale = donnelocale soit +workspace.ed=ed edite +workspace.edall=edtout editetout +workspace.efn = efp effaceprocedure +workspace.efns = effacetout +workspace.efv = efv effacevariable +workspace.erpl=eflp effacelisteproprietes +workspace.exec = exec execute +workspace.externalcommand=commandeexterne +workspace.gprop=rprop rendspropriete +workspace.imts =procedures +workspace.listevariables =variables +workspace.locale = locale +workspace.plist=lprop listepropriete +workspace.pprop=dprop donnepropriete +workspace.primitives=primitives +workspace.propertylists=listesproprietes +workspace.remprop=efprop effacepropriete +workspace.stoptrace=stoptrace +workspace.text=texte +workspace.trace = trace +xaxis?=axex? +xaxis=axex +yaxis?=axey? +yaxis=axey +zoom=zoom
\ No newline at end of file diff --git a/logo/src/primitives_gl_ES.properties b/logo/src/primitives_gl_ES.properties new file mode 100644 index 0000000..150b5e1 --- /dev/null +++ b/logo/src/primitives_gl_ES.properties @@ -0,0 +1,278 @@ +3d.downpitch=cabeceaabaixo baixanariz +3d.leftroll=abalaesquerda ae +3d.lineend=finli\u00f1a +3d.linestart=defineli\u00f1a comezali\u00f1a +3d.orientation=orientacion orientaci\u00f3n +3d.perspective=perspectiva +3d.pitch=cabeceo +3d.pointend=finpunto +3d.pointstart=definepunto comezapunto +3d.polyend=finpoligono +3d.polystart=definepoligono +3d.polyview=vista3d vistapoligono +3d.rightroll=abaladereita +3d.roll=abalo +3d.setorientation=ponorientacion ponorientaci\u00f3n +3d.setpitch=poncabeceo +3d.setroll=ponabalo +3d.setxyz=ponxyz +3d.setz=ponz +3d.textend=fintexto +3d.textstart=comezatexto definetexto +3d.uppitch=cabecearriba sobenariz +ajoute=engade +ajouteligneflux=engadeli\u00f1afluxo +animation=animacion animaci\u00f3n +arithmetic.absolue=absoluto abs +arithmetic.acos=acos arcoseno +arithmetic.arrondi=redondea +arithmetic.asin=asen arcoseno +arithmetic.atan=atan arcotanxente +arithmetic.cos=cos coseno +arithmetic.difference=diferenza +arithmetic.digits=decimais +arithmetic.div=div division divisi\u00f3n +arithmetic.exp=exp +arithmetic.hasard=azar +arithmetic.log=ln logneperiano +arithmetic.log10=log10 log +arithmetic.moins=menos +arithmetic.pi=pi +arithmetic.produit=produto +arithmetic.puissance=potencia +arithmetic.quotient=cociente +arithmetic.racine=rc raizcadrada +arithmetic.reste=resto +arithmetic.setdigits=pondecimais +arithmetic.sin=sen seno +arithmetic.somme=suma +arithmetic.tan=tan tanxente +arithmetic.tronque=truncar +attends=agarda +axis=eixos +axiscolor=coreixos +bc=bl baixalapis +bc?=bl? baixalapis? +bye=adeus +cap=rumbo +caractere=caracter car +cat=cat catalogo cat\u00e1logo +cc=cl corlapis +cf=corpapel +changedossier=cambiadirectorio cd +chattcp=chattcp +choix=elixe +ci=ci cargaimaxe +clos=mg modogaiola +color.blanc=branca +color.bleu=azul +color.bleufonce=azulescura +color.cyan=cyan +color.gris=gris +color.grisclair=grisclara +color.jaune=amarela +color.magenta=maxenta +color.marron=marron marr\u00f3n +color.noir=negra +color.orange=laranxa +color.rose=rosa +color.rouge=vermella +color.rougefonce=vermellaescura +color.vert=verde +color.vertfonce=verdeescura +color.violet=violeta +compte=conta +controls.compteur=contarepite contador +controls.foreach=paracada +controls.forever=parasempre +controls.ifelse=sesen\u00f3n sen\u00f3n +controls.repete=repite +controls.repetepour=repitepara +controls.stop=alto +controls.stoptout=detentodo det\u00e9ntodo +controls.tantque=mentres +couleurtexte=cortexto +ct=ot ocultatartaruga +date=data +de=pla ponlapis +debuttemps=crono cronometro cron\u00f3metro +dernier=ultimo \u00faltimo +distance=distancia +drawing.arc=arco +drawing.av=av avanza +drawing.cercle=circulo +drawing.etiquette=rotula +drawing.fixecap=ponr ponrumbo +drawing.fixex=ponx +drawing.fixexy=ponxy +drawing.fixey=pony +drawing.fpos=ponpos ponposicion ponposici\u00f3n +drawing.longueuretiquette=longoetiqueta le +drawing.origine=centro +drawing.point=punto +drawing.re=re retrocede +drawing.saveimage=gardaimaxe +drawing.td=xd xiradereita +drawing.tg=xe xiraesquerda +drawingquality=calidadedebuxo +ec=es escribe +ecoutetcp=escoitatcp +ecrisligneflux=escribeli\u00f1afluxo +efseq=bos borrasecuencia +egal?=iguais? +enleve=saca +enr=modovolta +entier?=enteiro? +envoietcp=enviatcp etcp +et=e +executetcp=executatcp +faux=falso +fcc=pcl poncorlapis +fcfg=poncp poncorpapel +fct=pct poncortexto +fen=modofiestra +fermeflux=cerrafluxo +findseq=pisec ponindicesecuencia +finflux?=finfluxo +finstr=pinstr poninstrumento +fintemps?=fincrono? fincronometro? fincron\u00f3metro? +fixenompolice=pnf ponnomefonte +fixenompolicetexte=pnft ponnomefontetexto +fixeseparation=ponseparacion ponsep ponseparaci\u00f3n +fixestyle=pest ponestilo +fpolice=pf ponfonte +fpt=pft ponfontetexto +frep=pondir pondirectorio +ftc=pongrosor +ftortue=ptartaruga pontartaruga +go=go goma +grid?=grella? +gridcolor=corgrella +grille=grella +guiaction=accionigu +guibutton=botonigu +guidraw=dibuxaigu +guimenu=menuigu +guiposition=posicionigu +guiremove=eliminaigu +heure=hora +ic=il invertelapis +indseq=indsec indicesecuencia +instr=instr instrumento +inverse=inverso +item=elemento +joue=tocamusica tocam\u00fasica +lc=sl subelapis +lis=leteclado lelista +liscar=lecar letecla +liscarflux=lecarfluxo +lisligneflux=leli\u00f1afluxo +lissouris=lerato +liste?=lista? +liste=lista +listeflux=listafluxos +md=pu ponultimo pon\u00faltimo +membre?=membro? +membre=membro +message=msx mensaxe +mot?=palabra? +mot=palabra +mp=pp ponprimeiro +mt=mt mostratartaruga +nettoie=limpa +nombre?=numero? n\u00famero? +nompolice=nomefonte nf +nompolicetexte=nft nomefontetexto +non=non +ou=ou +ouvreflux=abrefluxo +penshape=fl formalapis +penwidth=gl grosorlapis +ph=fr frase +police=fonte +pos=pos posicion posici\u00f3n +possouris=posrato +precede?=antes? anterior? +premier=pri primeiro +prim?=prim? primitiva? +proc?=proc? procedemento? +ptexte=ftexto fontetexto +rafraichis=refrescar +ramene=carga +remplace=substitue substit\u00fae +remplis=rechea reenche +rempliszone=reenchezona recheazona +rep=dir directorio +resetall=inicializa repontodo +ret=dev devolve +sauve=garda +sauved=gardatodo +sd=mu menosultimo menos\u00faltimo +separation=separacion separaci\u00f3n +seq=sec secuencia +setaxiscolor=poncoreixos pce +setdrawingquality=pcd poncalidadedebuxo +setgridcolor=pcc poncorgrella +setpenshape=pfl ponformalapis +setscreensize=ptp pontama\u00f1opantalla +setturtlesnumber=pmt ponmaximodetartarugas ponm\u00e1ximodetartarugas +setzoom=fixazoom +si=se +sound.mp3play=escoitarmp3 +sound.mp3stop=detenmp3 +souris?=rato? +sp=mp menosprimeiro +stopanimation=detenanimacion det\u00e9nanimaci\u00f3n +stopaxis=deteneixos det\u00e9neixos +stopgrille=detengrella +style=est estilo +taillefenetre=tama\u00f1ofiestra tv esquinasfiestras +tailleimage=tpant tama\u00f1opantalla +tape=tipea +tc=ec encontracor +temps=tempo +tortue=tartaruga +tortues=tartarugas +touche?=tecla? +tuetortue=eliminatartaruga +turtle.fforme=pforma ponforma +turtle.forme=forma +turtlesnumber=numerotartarugas n\u00famerotartarugas +unicode=unicode +var?=var? variable? +ve=bp borrapantalla +vers=caraa +vide?=baleiro? +visible?=visible? +vrai=certo +vt=bt borratexto +workspace.chose=obxecto cousa +workspace.content=contido +workspace.def=def define +workspace.donne=fai +workspace.donnelocale=failocal +workspace.ed=ed edita +workspace.edall=edtodo editatodo +workspace.efn=bo borra +workspace.efns=borratodo +workspace.efv=bv borravariable +workspace.erpl=blp bolistaprop +workspace.exec=executa +workspace.externalcommand=comandoexterno +workspace.gprop=lepropiedade +workspace.imts=imts listaprocs +workspace.listevariables=imvars listavars +workspace.locale=local +workspace.plist=listapropiedades +workspace.pprop=ponpropiedade +workspace.primitives=primitivas +workspace.propertylists=listaspropiedades +workspace.remprop=borrapropiedade +workspace.stoptrace=det detentrazado det\u00e9ntrazado det\u00e9ntrazado +workspace.text=texto +workspace.trace=trazado +xaxis?=eixox +xaxis=eixox +yaxis?=eixoy? +yaxis=eixoy +zoom=zoom
\ No newline at end of file diff --git a/logo/src/primitives_hu_HU.properties b/logo/src/primitives_hu_HU.properties new file mode 100644 index 0000000..0123abf --- /dev/null +++ b/logo/src/primitives_hu_HU.properties @@ -0,0 +1,288 @@ +3d.downpitch=leb\u00f3lint\u00e1s +3d.leftroll=balrad\u0151l\u00e9s +3d.lineend=v\u00e9gevonal +3d.linestart=kezdvonal +3d.orientation=ir\u00e1ny +3d.perspective=perspect\u00edva 3d +3d.pitch=b\u00f3lint\u00e1s +3d.pointend=v\u00e9gepont +3d.pointstart=kezdpont +3d.polyend=v\u00e9gesoksz\u00f6g +3d.polystart=kezdsoksz\u00f6g +3d.polyview=3dn\u00e9zet +3d.rightroll=jobbrad\u0151l\u00e9s +3d.roll=d\u0151l\u00e9s +3d.setorientation=ir\u00e1ny! +3d.setpitch=b\u00f3lint\u00e1s! +3d.setroll=d\u0151l\u00e9s! +3d.setxyz=helyzet! +3d.setz=zhelyzet! +3d.textend=v\u00e9gesz\u00f6veg +3d.textstart=kezdsz\u00f6veg +3d.uppitch=felb\u00f3lint\u00e1s +ajoute = felveszt\u00e9tel +ajouteligneflux = hozz\u00e1f\u0171zadatfolyam +animation = rajzfilm +arithmetic.absolue = absz +arithmetic.acos = acos +arithmetic.alea=v\u00e9letletlen +arithmetic.arrondi = kerek\u00edt +arithmetic.asin = asin +arithmetic.atan = atg +arithmetic.cos = cos coszinusz +arithmetic.difference = k\u00fcl\u00f6nbs\u00e9g +arithmetic.digits=sz\u00e1mjegyek +arithmetic.div = eh eg\u00e9szh\u00e1nyados +arithmetic.exp=exp hatv\u00e1ny +arithmetic.hasard = v\u00e9letlen +arithmetic.log=log logaritmus +arithmetic.log10 = log10 +aritmetic.modulo=mod modulus +arithmetic.moins = minusz +arithmetic.pi = pi +arithmetic.produit = szorzat +arithmetic.puissance = hatv\u00e1nyoz\u00e1s +arithmetic.quotient = h\u00e1nyados +arithmetic.racine = gy\u00f6k +arithmetic.reste = marad\u00e9k +arithmetic.setdigits=sz\u00e1mjegyek! +arithmetic.sin = sin szinusz +arithmetic.somme = \u00f6sszeg +arithmetic.tan = tg tangens +arithmetic.tronque = eg\u00e9szsz\u00e1m +attends = v\u00e1rj +axis=tengelyek +axiscolor= tengelysz\u00edn +bc = tl tollatle +bc? = tollatlent? +bye=szia +cap = ir\u00e1ny +caractere = karakter +cat = f\u00e1jlok +cc = tsz tollsz\u00edn +cf = rajzlapsz\u00edn +changedossier = mappav\u00e1lt\u00e1s +chattcp=besz\u00e9lget\u00e9stcp +choix = kiv\u00e1laszt +ci = bet\u00f6ltk\u00e9psor +clos = ker\u00edt\u00e9s +color.blanc = feh\u00e9r +color.bleu = k\u00e9k +color.bleufonce = s\u00f6t\u00e9tk\u00e9k +color.cyan = ci\u00e1nk\u00e9k +color.gris = sz\u00fcrke +color.grisclair = vil\u00e1gossz\u00fcrke +color.jaune = citroms\u00e1rga +color.magenta = s\u00f6t\u00e9tr\u00f3zsasz\u00edn +color.marron = barna +color.noir = fekete +color.orange = narancss\u00e1rga +color.rose = r\u00f3zsasz\u00edn +color.rouge = piros +color.rougefonce = s\u00f6t\u00e9tpiros +color.vert = z\u00f6ld +color.vertfonce = s\u00f6t\u00e9tz\u00f6ld +color.violet = lila +compte = esz elemsz\u00e1m +controls.compteur = h\u00e1nyadik +controls.foreach=mindegyikre +controls.forever=mind\u00f6r\u00f6kk\u00e9 +controls.ifelse=k\u00fcl\u00f6nben +controls.repete = ism ism\u00e9tl\u00e9s +controls.repetepour = ciklus +controls.stop = visszat\u00e9r +controls.stoptout = kiugr\u00e1s +controls.tantque = am\u00edg +couleurtexte= bet\u0171sz\u00edn +ct = l\u00e1thatatlan +date = d\u00e1tum +de = tollminta +debuttemps = visszasz\u00e1ml\u00e1l +dernier = utols\u00f3 +distance = t\u00e1vols\u00e1g +drawing.arc = k\u00f6r\u00edv +drawing.av = e el\u0151re +drawing.cercle = k\u00f6r +drawing.etiquette = c\u00edmke +drawing.fillpolygon=t\u00f6ltsoksz\u00f6g +drawing.fixecap =ir\u00e1ny! +drawing.fixex = x! xhely! +drawing.fixexy = xy! xyhely! +drawing.fixey = y! yhely! +drawing.fontjustify=sorkiz\u00e1r\u00e1s +drawing.fpos = hely! +drawing.longueuretiquette=c\u00edmkem\u00e9ret +drawing.origine = haza +drawing.point = pont +drawing.re = h h\u00e1tra +drawing.saveimage=mentk\u00e9psor +drawing.setfontjustify=sorkiz\u00e1r\u00e1s! +drawing.td = j jobbra +drawing.tg = b balra +drawing.x=x +drawing.y=y +drawing.z=z +drawingquality= rajzmin\u0151s\u00e9g +ec = ki\u00edr +ecoutetcp=adatfogad\u00e1stcp +ecrisligneflux = \u00edradatfolyam +efseq = t\u00f6r\u00f6lszekvencia +egal? = egyenl\u0151? +enleve = elmozd\u00edt +enr = k\u00f6rk\u00f6r\u00f6sen +entier? = eg\u00e9szsz\u00e1m? +envoietcp=adatk\u00fcld\u00e9stcp +et = \u00e9s +executetcp=adatv\u00e9grehajt\u00e1stcp +faux = hamis +fcc = tsz! tollsz\u00edn! +fcfg = rajzlapsz\u00edn! +fct = bet\u0171sz\u00edn! +fen = ablak +fermeflux = lez\u00e1radatfolyam +findseq = szekvenciapoz\u00edci\u00f3! +finflux? = adatfolyamv\u00e9g? +finstr = hangszer! +fintemps? = visszasz\u00e1ml\u00e1l\u00e1sletelt? +fixenompolice=bet\u0171k\u00e9szlet! +fixenompolicetexte = bet\u0171t\u00edpus! +fixeseparation = k\u00fcl\u00f6nv\u00e1laszt! +fixestyle= bet\u0171st\u00edlus! +fpolice = bet\u0171m\u00e9ret! +fpt= \u00edr\u00f3lapablak! +frep = tart\u00e1ll tartalomjegyz\u00e9ket\u00e1ll\u00edt +ftc = tv! tollvastags\u00e1g! +ftortue = tekn\u0151s! +go = trd tollrad\u00edr +grid?=n\u00e9gyzetr\u00e1cs? +gridcolor=n\u00e9gyzetr\u00e1cssz\u00edn +grille=n\u00e9gyzetr\u00e1cs +guiaction=guim\u0171vlet +guibutton=guigomb +guidraw=guikirak +guimenu=guimenu +guiposition=guihely +guiremove=guileszed +heure = id\u0151 +ic = tvt tollv\u00e1lt\u00f3 +indseq = szekvenciapoz\u00edci\u00f3 +instr = hangszer +inverse = ford\u00edt +item = elem +joue = hangsor +lc = tf tollatfel +lis = olvas +liscar = oj olvasjel +liscarflux = karakterolvasadatfolyam +lisligneflux = sorolvasadatfolyam +lissouris = eg\u00e9rgomb +liste = lista +liste? = lista? +listeflux = list\u00e1zadatfolyam +loop.dountil=ism\u00e9tl\u00e9s_am\u00edg +loop.dowhile=ism\u00e9tl\u00e9s_addig +md = utols\u00f3nak +membre = eleme +membre? = eleme? +message=\u00fczenet +mot = sz\u00f3 +mot? = sz\u00f3? +mp = els\u0151nek +mt = l\u00e1that\u00f3 +nettoie = takar\u00edt +nombre? = sz\u00e1m? +nompolice = bet\u0171k\u00e9szlet +nompolicetexte = bet\u0171t\u00edpus +non = nem +ou = vagy +ouvreflux = nyitadatfolyam +penshape=th tollhegy +penwidth=tv tollvastags\u00e1g +ph = m mondat +police = bet\u0171m\u00e9ret +pos = poz poz\u00edci\u00f3 +possouris = eg\u00e9rhely +precede? = el\u0151tt? +premier = els\u0151 +prim? = alapsz\u00f3? +proc? = elj? elj\u00e1r\u00e1s? +ptexte = bet\u0171n\u00e9gyzet +rafraichis = friss\u00edt +ramene = bet\u00f6lt +remplace = csere +remplis = t\u00f6lt +rempliszone = kit\u00f6lt +rep = tart tartalomjegyz\u00e9k +resetall=\u00fajrakezd +ret = er eredm\u00e9ny +sauve = ment +sauved = mentett +sd = un utols\u00f3n\u00e9lk\u00fcli +separation = k\u00fcl\u00f6nv\u00e1laszt +seq = szekvencia +setaxiscolor=tengelysz\u00edn! +setdrawingquality= rajzmin\u0151s\u00e9g! +setgridcolor=n\u00e9gyzetr\u00e1cssz\u00edn! +setpenshape=setps setpenshape +setscreensize=rajzlapm\u00e9ret! +setturtlesnumber=tekn\u0151smax! +setzoom=nagy\u00edt\u00e1s +si = ha +sound.mp3play=mp3lej\u00e1tsz\u00e1s +sound.mp3stop=mp3v\u00e9ge +souris? = eg\u00e9r? +sp = en els\u0151n\u00e9lk\u00fcli +stopanimation=megszak\u00edtrajzfilm +stopaxis=tengelyleszed +stopgrille=rejtn\u00e9gyzetr\u00e1cs +style = bet\u0171st\u00edlus +taillefenetre=rajzlaphelye +tailleimage=rajzalpm\u00e9ret +tape = \u00edr +tc = egyez\u0151sz\u00edn +temps = elteltid\u0151 +tortue = tekn\u0151s +tortues = tekn\u0151s\u00f6k +touche? = gny? gombnyom\u00e1s? +tuetortue = t\u00f6r\u00f6ltekn\u0151c +turtle.fforme = tekn\u0151salak +turtle.forme = alak +turtlesnumber=tekn\u0151smax +unicode = unicode +var?=v\u00e1ltoz\u00f3? +ve = tr t\u00f6r\u00f6lrajzlap +vers = ir\u00e1nysz\u00f6g +vide? = \u00fcres? +visible? = l\u00e1that\u00f3? +vrai = igaz +vt = t\u00ed t\u00f6r\u00f6l\u00edr\u00f3lap +workspace.chose = tartalom +workspace.content=tartalomlista +workspace.def = saj\u00e1tsz\u00f3 +workspace.donne = n\u00e9v +workspace.donnelocale = lok\u00e1lisn\u00e9v +workspace.ed=\u00e1t\u00edr +workspace.edall=\u00e1t\u00edrmind +workspace.efn = nevett\u00f6r\u00f6l +workspace.efns = mindentt\u00f6r\u00f6l +workspace.efv = v\u00e1ltoz\u00f3tt\u00f6r\u00f6l +workspace.erpl=sz\u00f3t\u00e1rlistat\u00f6rl\u00e9s +workspace.exec = v\u00e9grehajt +workspace.externalcommand=k\u00fcls\u0151parancs +workspace.gprop=veszsz\u00f3t\u00e1rb\u00f3l +workspace.imts = saj\u00e1tnevek +workspace.listevariables =v\u00e1ltoz\u00f3k +workspace.locale = lok\u00e1lis +workspace.plist=sz\u00f3t\u00e1rlista +workspace.pprop=teszsz\u00f3t\u00e1rba +workspace.primitives=alapszavak +workspace.propertylists=sz\u00f3t\u00e1raklist\u00e1ja +workspace.remprop=dobsz\u00f3t\u00e1rb\u00f3l +workspace.stoptrace=nyomk\u00f6vet\u00e9skikapcsol\u00e1s +workspace.text=sz\u00f3tartalom +workspace.trace = nyomk\u00f6vet\u00e9s +xaxis?=xtengely? +xaxis=xtengely +yaxis?=ytengely? +yaxis=ytengely +zoom=nagy\u00edt\u00e1s
\ No newline at end of file diff --git a/logo/src/primitives_it_IT.properties b/logo/src/primitives_it_IT.properties new file mode 100644 index 0000000..200d25e --- /dev/null +++ b/logo/src/primitives_it_IT.properties @@ -0,0 +1,293 @@ + + + + + +3d.downpitch=BG BeccheggiaGiu BeccheggiaGi\u00f9 +3d.leftroll=RSX RollioSinistra +3d.lineend=IL InizioLinea +3d.linestart=FL FineLinea +3d.orientation=Direzione +3d.perspective=Prospettiva 3D +3d.pitch=Beccheggio +3d.pointend=FP FinePunto +3d.pointstart=IP InizioPunto +3d.polyend=FP FinePoligono +3d.polystart=IP InizioPoligono +3d.polyview=VP3D VistaPoligono3D +3d.rightroll=RDX RollioDestra +3d.roll=Rollio +3d.setorientation=ImpOr ImpostaOrientamento +3d.setpitch=ImpBec ImpostaBeccheggio +3d.setroll=ImpRol ImpostaRollio +3d.setxyz=ImpXYZ ImpostaXYZ +3d.setz=ImpZ ImpostaZ +3d.textend=FT FineTesto +3d.textstart=IT InizioTesto +3d.uppitch=BS BeccheggiaSu BeccheggiaS\u00f9 +ajoute=AE Aggiungi AggiungiElemento +ajouteligneflux=AggiungiLineaNelFlusso +animation=Animazione +arithmetic.absolue=Ass Assoluto +arithmetic.acos=ACos ArcoCoseno +arithmetic.alea=Casuale01 +arithmetic.arrondi=Arrotonda +arithmetic.asin=ASen ArcoSeno +arithmetic.atan=ATan ArcoTangente +arithmetic.cos=Cos Coseno +arithmetic.difference=Diff Differenza +arithmetic.digits=Decimali +arithmetic.div=Dividi Div +arithmetic.exp=Exp +arithmetic.hasard=Casuale +arithmetic.log10=Log10 +arithmetic.log=Log +aritmetic.modulo=mod modulo +arithmetic.moins=Meno +arithmetic.pi=Pi +arithmetic.produit=Prodotto +arithmetic.puissance=Potenza +arithmetic.quotient=Quoziente +arithmetic.racine=RadQ RadiceQuadrata +arithmetic.reste=Resto +arithmetic.setdigits=ImpDec ImpostaDecimali +arithmetic.sin=Sen Seno +arithmetic.somme=Somma +arithmetic.tan=Tan Tangente +arithmetic.tronque=Int Intero +aritmetic.modulo=mod modulo +attends=Aspetta +axis=Asse +axiscolor=ColoreAsse +bc=PG PennaGiu PennaGi\u00f9 +bc?=PG? PennaGiu? PennaGi\u00f9? +bye=Bye Ciao +cap=Intestazione +caractere=Car Carattere +cat=File +cc=ColP ColorePenna +cf=ColS ColoreSfondo +changedossier=CCart CambiaCartella +chattcp=FChatTCP FinestraChatTCP +choix=Scegli +ci=CI CaricaImmagine +clos=Recinta +color.blanc=Bianco +color.bleu=Blu Bl\u00f9 +color.bleufonce=BluScuro Bl\u00f9Scuro +color.cyan=Ciano +color.gris=Grigio +color.grisclair=GrigioChiaro +color.jaune=Giallo +color.magenta=Magenta +color.marron=Marrone +color.noir=Nero +color.orange=Arancio +color.rose=Rosa +color.rouge=Rosso +color.rougefonce=RossoScuro +color.vert=Verde +color.vertfonce=VerdeScuro +color.violet=Violetto +compte=Conta +controls.compteur=ContaRipetizioni +controls.foreach=RipetiPerCiascuno +controls.forever=RipetiPerSempre +controls.ifelse=SeAl SeAltrimenti +controls.repete=Ripeti +controls.repetepour=RipetiPer +controls.stop=Ferma +controls.stoptout=FermaTutto +controls.tantque=Mentre +couleurtexte=CT ColoreTesto +ct=NT NascondiTartaruga +date=Data +de=PennaDisegno PD +debuttemps=Cronometro +dernier=Ultimo +distance=Distanza +drawing.arc=Arco +drawing.av=Av Avanti +drawing.cercle=Cerchio Circonferenza +drawing.etiquette=Etichetta +drawing.fillpolygon=RiempiPoligono +drawing.fixecap=ImpDir ImpostaDirezione +drawing.fixex=ImpX ImpostaX +drawing.fixexy=ImpXY ImpostaXY +drawing.fixey=ImpY ImpostaY +drawing.fontjustify=AllineamentoTesto +drawing.fpos=ImpPos ImpostaPosizione +drawing.longueuretiquette=LE LunghezzaEtichetta +drawing.origine=Origine +drawing.point=Punto +drawing.re=In Indietro +drawing.setfontjustify=ImpAllTesto ImpostaAllineamentoTesto +drawing.td=DX RuotaDestra +drawing.tg=SX RuotaSinistra +drawing.x=x +drawing.y=y +drawing.z=z +drawingquality=QD QualitaDisegno Qualit\u00e0Disegno +ec=St Stampa +ecoutetcp=ATCP AscoltaTCP +ecrisligneflux=ScriviLineaNelFlusso +efseq=CancSeq CancellaSequenza +egal?=Uguale? +enleve=Rimuovi +enr=Gira +entier?=Intero? +envoietcp=ITCP InviaTCP +et=e +executetcp=ETCP EseguiTCP +faux=falso +fcc=ImpCP ImpostaColorePenna +fcfg=ImpCS ImpostaColoreSfondo +fct=ImpCT ImpostaColoreTesto +fen=Finestra +fermeflux=ChiudiFlusso +findseq=ImpSeq ImpostaIndiceInSequenza +finflux?=FineFlusso? +finstr=ImpStr ImpostaStrumento +fintemps?=FineCronometro? +fixenompolice=ImpNFont ImpostaNomeFont +fixenompolicetexte=ImpNTesto ImpostaNomeTesto +fixeseparation=ImpSep ImpostaSeparazione +fixestyle=ImpSt ImpostaStile +fpolice=ImpCFont ImpostaCorpoFont +fpt=ImpDTesto ImpostaDimensioneTesto +frep=ImpCart ImpostaCartella +ftc=ImpostaSpessorePenna ImpSP +ftortue=ImpTar ImpostaTartaruga +go=CP CancellaPenna +grid?=Griglia? +gridcolor=ColoreGriglia +grille=Griglia +guiaction=AzioneGUI AGUI +guibutton=BottoneGUI BGUI +guidraw=DisegnaGUI DGUI +guimenu=MenuGUI MGUI +guiposition=PosizioneGUI PGUI +guiremove=RimuoviGUI RGUI +heure=Ora HMS +ic=InvPenna InvertiPenna +indseq=IndSeq IndiceSequenza +instr=Strumento +inverse=Inverso +item=Elemento +joue=Suona +lc=PS PennaSu PennaS\u00f9 +lis=Leggi +liscar=LeggiCar LeggiCarattere +liscarflux=LeggiCarattereDalFlusso +lisligneflux=LeggiLineaDalFlusso +lissouris=LeggiMouse +liste=Elenco +liste?=Elenco? +listeflux=ElencaFlussi +loop.dountil=RipetiFinoAChe +loop.dowhile=RipetiIntantoChe +md=FLista AggiungiElementoFineLista +membre=Membro +membre?=Membro? +message=msg Messaggio +mot=Parola +mot?=Parola? +mp=IElenco InserisciElementoInizioElenco +md=FElenco AggiungiElementoFineElenco +nettoie=Pulisci +nombre?=Numero? +nompolice=NF NomeFont +nompolicetexte=NT NomeTesto +non=non +ou=o +ouvreflux=ApriFlusso +penshape=FP FormaPenna +penwidth=SP SpessorePenna +ph=Frase +police=CorpoFont +pos=Pos Posizione +possouris=PosMouse PosizioneMouse +precede?=Prima? +premier=Primo +prim?=Primitiva? +proc?=Procedura? +ptexte=DT DimensioneTesto +rafraichis=Aggiorna Ridisegna +ramene=Carica +remplace=ImpostaElemento Sostituisci +remplis=Riempi +rempliszone=RiempiZona +rep=Cart Cartella +resetall=ResettaTutto InizializzaTutto +ret=OUT Output +sauve=Salva +sauved=Salvato +sd=EU EccettoUltimo +separation=Sep Separazione +seq=Seq Sequenza +setaxiscolor=ImpColAsse ImpostaColoreAsse +setdrawingquality=ImpQualitaDisegno ImpQualit\u00e0Disegno ImpQD +setgridcolor=ImpColGiglia ImpostaColoreGriglia +setpenshape=ImpFP ImpFormaPenna +setscreensize=ImpDimensioneSchermo ImpostaDimSchermo +setturtlesnumber=ImpNumMaxT ImpostaNumeroMassimoTartarughe +setzoom=ImpZoom ImpostaZoom +si=Se +sound.mp3play=Avviamp3 +sound.mp3stop=Fermamp3 +souris?=Mouse? +sp=EP EccettoPrimo +stopanimation=FermaAnimazione +stopaxis=CancAssi CancellaAssi +stopgrille=CancGriglia CancellaGriglia +style=St Stile +taillefenetre=DimensioneZona +tailleimage=DimensioneSchermo +tape=Scrivi +tc=CC CercaColore +temps=SecondiDaAvvio +tortue=Tartaruga +tortues=Tartarughe +touche?=Tasto? +tuetortue=CancT CancellaTartaruga +turtle.fforme=ImpFo ImpostaForma +turtle.forme=Forma +turtlesnumber=NumMaxT NumMaxTartarughe +unicode=UniCode +var?=Var? Variabile? +ve=PSc PulisciSchermo +vers=verso +vide?=Vuoto? +visible?=Visibile? +vrai=vero +vt=PT PulisciTesto +workspace.chose=ValoreVar +workspace.content=Contenuti +workspace.def=Def Definisci +workspace.donne=AssegnaVar +workspace.donnelocale=AssegnaVarLocale +workspace.ed=Modifica +workspace.edall=ModTutte ModificaTutte +workspace.efn=CancProc CancellaProcedura +workspace.efns=CancTutte CancellaTutte +workspace.efv=CancVar CancellaVariabile +workspace.erpl=CancEP CancellaElencoPropriet\u00e0 CancellaElencoProprieta +workspace.exec=Esegui Lancia +workspace.externalcommand=ComandoEsterno +workspace.gprop=Proprieta Propriet\u00e0 +workspace.imts=Procs Procedure +workspace.listevariables=Vars Variabili +workspace.locale=VarLocale +workspace.plist=ElencaProprieta ElencaPropriet\u00e0 +workspace.pprop=AggiungiPropriet\u00e0 AggiungiProprieta +workspace.primitives=Primitive +workspace.propertylists=ElencaProprieta ElencaPropriet\u00e0 +workspace.remprop=CancellaProprieta CancellaPropriet\u00e0 +workspace.stoptrace=FermaTraccia +workspace.text=Testo +workspace.trace=Traccia +xaxis=AsseX +xaxis?=AsseX? +yaxis=AsseY +yaxis?=AsseY? +zoom=Zoom
\ No newline at end of file diff --git a/logo/src/primitives_pt_BR.properties b/logo/src/primitives_pt_BR.properties new file mode 100644 index 0000000..b1b5ba1 --- /dev/null +++ b/logo/src/primitives_pt_BR.properties @@ -0,0 +1,288 @@ +3d.downpitch=baixenariz +3d.leftroll=roleparaesquerda rolepe +3d.lineend=terminelinha +3d.linestart=inicielinha +3d.orientation=orienta\u00e7\u00e3o +3d.perspective=perspectiva logo3d +3d.pitch=dire\u00e7\u00e3onariz +3d.pointend=termineponto +3d.pointstart=inicieponto +3d.polyend=terminepol\u00edgono +3d.polystart=iniciepol\u00edgono +3d.polyview=mostrepol\u00edgono visor3d +3d.rightroll=roleparadireita rolepd +3d.roll=dire\u00e7\u00e3orolagem +3d.setorientation=mudeorienta\u00e7\u00e3o +3d.setpitch=mudeDire\u00e7\u00e3oNariz +3d.setroll=mudedire\u00e7\u00e3orolagem +3d.setxyz=mudexyz +3d.setz=mudez +3d.textend=terminetexto +3d.textstart=inicietexto +3d.uppitch=levantenariz +ajoute = coloqueelemento colelem +ajouteligneflux = juntelfx +animation = animado +arithmetic.absolue = absoluto abs +arithmetic.acos = acos arccoseno +arithmetic.alea=aleat\u00f3rio +arithmetic.arrondi = arredonde +arithmetic.asin = asen arcseno +arithmetic.atan = atan +arithmetic.cos = cos coseno +arithmetic.difference = diferen\u00e7a +arithmetic.digits=precis\u00e3o +arithmetic.div = div +arithmetic.exp=exp +arithmetic.hasard = sorteie +arithmetic.log=ln +arithmetic.log10 = log10 +aritmetic.modulo=mod m\u00f3dulo +arithmetic.moins = menos +arithmetic.pi = pi +arithmetic.produit = produto +arithmetic.puissance = pot\u00eancia +arithmetic.quotient = quociente +arithmetic.racine = raizq +arithmetic.reste = resto +arithmetic.setdigits=mudeprecis\u00e3o +arithmetic.sin = sen seno +arithmetic.somme = soma +arithmetic.tan = tan tangente +arithmetic.tronque = inteiro +attends = espere +axis=eixo +axiscolor=cordoeixo +bc = ul usel\u00e1pis +bc? = ul? \u00e9usel\u00e1pis? +bye=adeus +cap = dire\u00e7\u00e3o d\u00e7 +caractere=caracter car +cat = marq mostrearquivos +cc = cdl cordol\u00e1pis +cf = cdf cordofundo +changedossier = mudedir +chattcp=chattcp +choix = escolhe +ci = carimg carregueimagem +clos = cercar +color.blanc = branco +color.bleu = azul +color.bleufonce = azulescuro +color.cyan = ciano +color.gris = cinza +color.grisclair = cinzaclaro +color.jaune = amarelo +color.magenta = magenta +color.marron = marrom +color.noir = preto +color.orange = laranja +color.rose = rosa +color.rouge = vermelho +color.rougefonce = vermelhoescuro +color.vert = verde +color.vertfonce = verdeescuro +color.violet = violeta +compte = conte +controls.compteur = contevezes cv +controls.foreach=paracada +controls.forever=parasempre +controls.ifelse=sesen\u00e3o sen\u00e3o +controls.repete = repita +controls.repetepour = para +controls.stop = pare +controls.stoptout = paretudo +controls.tantque = enquanto +couleurtexte= cdt cordotexto +ct = dt escondetat +date = data +de = lp l\u00e1pispinta +debuttemps = contador +dernier = ult \u00faltimo +distance = dist dist\u00e2ncia +drawing.arc = arco +drawing.av = pf parafrente +drawing.cercle = c\u00edrculo circ +drawing.etiquette = rotule +drawing.fillpolygon=preenchapol\u00edgono +drawing.fixecap = muded\u00e7 mudedire\u00e7\u00e3o +drawing.fixex = mudex +drawing.fixexy = mudexy +drawing.fixey = mudey +drawing.fontjustify=alinhefonte +drawing.fpos = mudepos +drawing.longueuretiquette=tamanhorotule tr +drawing.origine = centro +drawing.point = ponto +drawing.re = pt paratr\u00e1s +drawing.saveimage=guardeimagem +drawing.setfontjustify=mudealinhefonte +drawing.td = pd paradireita +drawing.tg = pe paraesquerda +drawingquality=qi qualidadedaimagem +drawing.x=x +drawing.y=y +drawing.z=z +ec = mo mostre +ecoutetcp=escutetcp +ecrisligneflux = escrevalinha eslfx +efseq=delseq deletesequ\u00eancia +egal? = saoiguais? s\u00e3oiguais? +enleve = apague +enr = comlimite +entier? = \u00e9inteiro? +envoietcp=envietcp +et = e +executetcp=executetcp +faux = falso +fcc = mudecl mudecordol\u00e1pis +fcfg = mudecf mudecordofundo +fct = mudect mudecordotexto +fen = semlimite +fermeflux = fechefluxo fechefx +findseq = mudeindseq mude\u00edndiceseq\u00fc\u00eancia +finflux? = fimarq? fimfluxo? +finstr = mudeinstr mudeinstrumento +fintemps? = fimcontador? +fixenompolice = mudenf mudenomefonte +fixenompolicetexte = mudenft mudenomefontetexto +fixeseparation = mudesepara\u00e7\u00e3o +fixestyle = mudeestilo +fpolice = mudef mudefonte +fpt = mudeft mudefontetexto +frep = mudedir mudediret\u00f3rio +ftc = mudeel mudeespessuradol\u00e1pis +ftortue = atat aten\u00e7\u00e3otat +go = ub useborracha +grid?=grade? +gridcolor=cordagrade +grille=grade +guiaction=igfaz +guibutton=igbot\u00e3o +guidraw=igdesenhe +guimenu=igmenu +guiposition=iglocal +guiremove=igapague +heure = tempo +ic = il invertel\u00e1pis +indseq=indseq \u00edndicesequ\u00eancia +instr = instr instrumento +inverse = inverte +item = elem elemento +joue = toque +lc = un usenada +lis = leia +liscar = leiacar +liscarflux = leiacaractere leiacarfx +lisligneflux = leialinha leialfx +lissouris = leiamouse +liste = lista +liste? = elista? \u00e9lista? +listeflux = listefluxo listefx +loop.dountil=fa\u00e7aat\u00e9 repitaat\u00e9 +loop.dowhile=fa\u00e7aenquanto +md = jf juntenofim +membre = membro +membre? = emembro? \u00e9membro? +message=msg mensagem +mot = pal palavra +mot? = epal? \u00e9palavra? +mp = ji juntenoin\u00edcio +mt = at mostretat +nettoie = limpe +nombre? = enum? \u00e9n\u00famero? +nompolice = nomefonte +nompolicetexte = nft nomefontetexto +non = n\u00e3o +ou = ou +ouvreflux = abrafluxo abrafx +penshape=pl pontadol\u00e1pis +penwidth=el espessuradol\u00e1pis +ph = sn senten\u00e7a +police = fonte +pos=pos +possouris = posmouse +precede? = eant? \u00e9anterior? +premier = pri primeiro +prim? = eprim? \u00e9primitiva? +proc? = eproc? \u00e9procedimento? +ptexte = ftexto fontetexto +rafraichis = veranimado +ramene = abra +remplace = mudeelemento mudeelem +remplis = pinte +rempliszone = pintezona +rep = dir diret\u00f3rio +resetall=novo +ret=sa\u00edda devolva +sauve = guarde +sauved = guardado +sd = su sem\u00faltimo +separation = separa\u00e7\u00e3o +seq=seq sequ\u00eancia +setaxiscolor=mudecordoeixo +setdrawingquality=mudeqi mudequalidadedaimagem +setgridcolor=mudecordagrade mudecdg +setpenshape= mudepl mudepontadol\u00e1pis +setscreensize=mudetamjan mudetamanhodajanela +setturtlesnumber=mudemaxtat mudem\u00e1ximodetartarugas +setzoom = mudezoom +si = se +sound.mp3play=toquemp3 +sound.mp3stop=paremp3 +souris? = mouse? rato? +sp = sp semprimeiro +stopanimation=pareanimado +stopaxis=semeixo +stopgrille=semgrade +style = estilo +taillefenetre=tamanhojanela tj +tailleimage=tamjan tamanhodajanela +tape = escreva esc +tc = cdp cordoponto +temps = tempodec tempodecorrido +tortue = tatativa +tortues = tartarugas +touche? = \u00e9tecla? +tuetortue = semtat semtartaruga +turtle.fforme = muderoupa +turtle.forme = roupa +turtlesnumber= maxtat m\u00e1ximodetartarugas +unicode = unicode +var?=evar? \u00e9vari\u00e1vel? +ve = ld limpedesenho +vers = d\u00e7para dire\u00e7\u00e3opara +vide? = evazio? \u00e9vazio? +visible? = vis\u00edvel? +vrai = verd +vt = lt limpetexto +workspace.chose=objeto +workspace.content=conte\u00fado +workspace.def = def defina +workspace.donne = atr atribua +workspace.donnelocale = atrlocal +workspace.ed=edite +workspace.edall=edtudo +workspace.efn = el elimine +workspace.efns = et eliminetudo +workspace.efv = mate +workspace.erpl=ellprop apaguelprop +workspace.exec = execute +workspace.externalcommand=comandoexterno +workspace.gprop=leiapropriedade +workspace.imts = imts +workspace.listevariables = listevar +workspace.locale = local +workspace.plist=listapropriedade +workspace.pprop=ponhapropriedade +workspace.primitives=primitivas +workspace.propertylists=ellprops apaguelprops +workspace.remprop=apaguepropriedade +workspace.stoptrace=parerastreie +workspace.text=texto +workspace.trace = rastreie +xaxis?=eixox? +xaxis=eixox +yaxis?=eixoy? +yaxis=eixoy +zoom=zoom
\ No newline at end of file diff --git a/logo/src/xlogo/AppSettings.java b/logo/src/xlogo/AppSettings.java new file mode 100644 index 0000000..60cc1e7 --- /dev/null +++ b/logo/src/xlogo/AppSettings.java @@ -0,0 +1,151 @@ +package xlogo;
+
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+
+import xlogo.storage.workspace.Language;
+import xlogo.storage.workspace.SyntaxHighlightConfig;
+
+/**
+ * This singleton class shall eliminate the accesses to Logo.messages.getString(),
+ * provide a unique way to access current settings and to stay updated through change events.
+ * @since 10th June 2014 - not yet consistently used throughout the application
+ * @author Marko
+ *
+ */
+public class AppSettings
+{
+ private static AppSettings instance;
+
+ public static AppSettings getInstance()
+ {
+ if (instance == null)
+ instance = new AppSettings();
+ return instance;
+ }
+
+ /* * * * * * *
+ * LANGUAGE
+ * * * * * * */
+
+ private Language language;
+
+ public Language getLanguage()
+ {
+ return language;
+ }
+
+ public void setLanguage(Language language)
+ {
+ if (language == this.language)
+ return;
+ this.language = language;
+ Logo.generateLanguage(language);
+ notifyLanguageChanged();
+ }
+
+ /**
+ * Translate the key into the current language.
+ * Shortcut for Logo.messages#getString()
+ * @param key
+ * @return
+ */
+ public String translate(String key)
+ {
+ return Logo.messages.getString(key);
+ }
+
+ private ArrayList<ActionListener> languageChangeListeners = new ArrayList<ActionListener>();
+
+ public void addLanguageChangeListener(ActionListener listener)
+ {
+ languageChangeListeners.add(listener);
+ }
+
+ public void removeLanguageChangeListener(ActionListener listener)
+ {
+ languageChangeListeners.remove(listener);
+ }
+
+ private void notifyLanguageChanged()
+ {
+ ActionEvent event = new ActionEvent(this, 0, "languageChange");
+ for (ActionListener listener : languageChangeListeners)
+ listener.actionPerformed(event);
+ }
+
+ /* * * * * * *
+ * FONT
+ * * * * * * */
+
+ private Font font;
+
+ public Font getFont()
+ {
+ return font;
+ }
+
+ public void setFont(Font font)
+ {
+ this.font = font;
+ notifyFontChanged();
+ }
+
+ private ArrayList<ActionListener> fontChangeListeners = new ArrayList<ActionListener>();
+
+ public void addFontChangeListener(ActionListener listener)
+ {
+ fontChangeListeners.add(listener);
+ }
+
+ public void removeFontChangeListener(ActionListener listener)
+ {
+ fontChangeListeners.remove(listener);
+ }
+
+ private void notifyFontChanged()
+ {
+ ActionEvent event = new ActionEvent(this, 0, "fontChange");
+ for (ActionListener listener : fontChangeListeners)
+ listener.actionPerformed(event);
+ }
+
+ /* * * * * * *
+ * SYNTAX HIGHLIGHTING STYLE
+ * * * * * * */
+
+ private SyntaxHighlightConfig syntaxHighlightingStyles;
+
+ public SyntaxHighlightConfig getSyntaxHighlightStyles()
+ {
+ return syntaxHighlightingStyles;
+ }
+
+ public void setSyntaxHighlightingStyles(SyntaxHighlightConfig syntaxHighlighStyles)
+ {
+ this.syntaxHighlightingStyles = syntaxHighlighStyles;
+ notifySyntaxHighlightStyleChanged();
+ }
+
+ private ArrayList<ActionListener> syntaxHighlightStyleChangeListeners = new ArrayList<ActionListener>();
+
+ public void addSyntaxHighlightStyleChangeListener(ActionListener listener)
+ {
+ syntaxHighlightStyleChangeListeners.add(listener);
+ }
+
+ public void removeSyntaxHighlightStyleChangeListener(ActionListener listener)
+ {
+ syntaxHighlightStyleChangeListeners.remove(listener);
+ }
+
+ private void notifySyntaxHighlightStyleChanged()
+ {
+ ActionEvent event = new ActionEvent(this, 0, "fontChange");
+ for (ActionListener listener : syntaxHighlightStyleChangeListeners)
+ listener.actionPerformed(event);
+ }
+
+}
diff --git a/logo/src/xlogo/Application.java b/logo/src/xlogo/Application.java new file mode 100644 index 0000000..9a60655 --- /dev/null +++ b/logo/src/xlogo/Application.java @@ -0,0 +1,1875 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * a lot of modifications, extensions, refactorings might been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +package xlogo; + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.*; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.plaf.metal.MetalLookAndFeel; + +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.Stack; + +import xlogo.interfaces.BasicFileContainer.FileContainerChangeListener; +import xlogo.interfaces.ErrorDetector.FileErrorCollector.ErrorListener; +import xlogo.interfaces.ProcedureMapper.ProcedureMapListener; +import xlogo.interfaces.X4SModeSwitcher.ModeChangeListener; +import xlogo.kernel.DrawPanel; +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +import xlogo.storage.user.UserConfig; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.utils.Utils; +import xlogo.utils.WriteImage; +import xlogo.gui.components.ProcedureSearch; +import xlogo.gui.components.TurtleComboBox; +import xlogo.gui.components.ProcedureSearch.ProcedureSearchRequestListener; +import xlogo.gui.components.fileslist.FilesList; +import xlogo.gui.*; +import xlogo.kernel.Affichage; +import xlogo.kernel.Kernel; +import xlogo.kernel.network.NetworkServer; +import xlogo.kernel.perspective.Viewer3D; +import xlogo.kernel.userspace.UserSpace; +import xlogo.kernel.userspace.procedures.Procedure; +import xlogo.messages.MessageKeys; +import xlogo.messages.async.AsyncMediumAdapter; +import xlogo.messages.async.AsyncMessage; +import xlogo.messages.async.AsyncMessenger; +import xlogo.messages.async.dialog.DialogMessenger; +import xlogo.messages.async.history.HistoryMessenger; + +/** + * @author Marko + * @author Lo�c Le Coq + */ +public class Application +{ + private static final int BG_COLOR = 0xB3BCEA; + public static final String appName = "XLogo4Schools"; + + private static Stack<String> pile_historique = new Stack<String>(); + private int index_historique = 0; + + private MenuListener menulistener; + + public boolean error = false; + boolean stop = false; + + public Affichage affichage = null; + private Sound_Player son = new Sound_Player(this); + private Touche touche = new Touche(); + private Popup jpop; + + // pref Box + /** + * To display 3D View + */ + private Viewer3D viewer3d = null; + + // Interpreter and drawer + private Kernel kernel; + + private UserSpace userSpace; + private UserConfig uc; + + /* + * My Layout + */ + + private JFrame mainFrame = new JFrame(); + private JPanel filesAndProcedures = new JPanel(); + private JPanel commandOrEditor; + private FilesList filesList; + private ProcedureSearch procedureSearch; + + // drawingOrEditor@Drawing + private JPanel commandCard = new JPanel(); + private ZoneCommande commandLine = new ZoneCommande(this); + private JLabel recordTimerLabel = new JLabel(); + private JButton stopButton = new JButton(); + private JButton menuButton = new JButton(); + public JSplitPane drawingAndHistory = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + + private JPanel drawingAndExtras = new JPanel(); + private HistoryPanel history = new HistoryPanel(this); + + public JScrollPane scrollArea; + private DrawPanel drawPanel; + private JPanel extrasPanel = new JPanel(); + private JSlider speedSlider = new JSlider(JSlider.VERTICAL); + + // drawingOrEditor@Editor + public Editor editeur = new Editor(this); + + // Extras Menu + private JPopupMenu extras = new JPopupMenu(); + + private static final String COMMAND_CARD_ID = "command_card"; + private static final String EDITOR_CARD_ID = "editor_card"; + + + + /** Builds the main frame */ + public Application() + { + uc = WSManager.getUserConfig(); + + userSpace = new UserSpace(); + kernel = new Kernel(this, userSpace); + initMessenger(); + kernel.initInterprete(); + + menulistener = new MenuListener(this); + jpop = new Popup(menulistener, commandLine); + + try + { + initGUI(); + } + catch (Exception e) + { + e.printStackTrace(); + } + setText(); + + initListeners(); + + showWelcomeMessage(); + } + + /** + * Hello Username + * You defined a, b, c, d, ... + */ + public void showWelcomeMessage() { + HistoryMessenger.getInstance().dispatchComment(Logo.messages.getString(MessageKeys.APP_HELLO) + " " + uc.getUserName() + "!\n"); + + StringBuilder sb = new StringBuilder(); + for (String procedureName : userSpace.getAllProcedureNames()) + { + sb.append(procedureName); + sb.append(", "); + } + if (sb.length() == 0) + return; + + sb.delete(sb.length() - 2, sb.length()); + + HistoryMessenger.getInstance().dispatchComment( + Logo.messages.getString("definir") + " " + + sb.toString() + ".\n"); + } + + public JFrame getFrame() + { + return mainFrame; + } + + private void initMessenger() + { + + DialogMessenger.getInstance().setMedium(new AsyncMediumAdapter<AsyncMessage<JFrame>, JFrame>(){ + public boolean isReady() + { + return getFrame().isDisplayable(); + } + public JFrame getMedium() + { + return getFrame(); + } + public void addMediumReadyListener(final AsyncMessenger messenger) + { + getFrame().addWindowStateListener(new WindowStateListener(){ + + @Override + public void windowStateChanged(WindowEvent e) + { + if (getFrame().isDisplayable()) + messenger.onMediumReady(); + } + }); + } + }); + + + } + + private void initGUI() + { + setTheme(); + initFrame(); + JPanel contentPane = (JPanel) mainFrame.getContentPane(); + JPanel toplevel = new JPanel(); + toplevel.setLayout(new BorderLayout()); + layoutFilesAndProcedures(); + toplevel.add(filesAndProcedures, BorderLayout.WEST); + commandOrEditor = new JPanel(new CardLayout()); + toplevel.add(commandOrEditor, BorderLayout.CENTER); + + commandOrEditor.add(commandCard, COMMAND_CARD_ID); + commandOrEditor.add(editeur.getComponent(), EDITOR_CARD_ID); + //commandOrEditor.setPreferredSize(new Dimension(d.width-200, d.height)); + showCommandCard(); + + scrollArea = new JScrollPane(); + DrawPanel.dessin=new BufferedImage(uc.getImageWidth(),uc.getImageHeight(),BufferedImage.TYPE_INT_RGB); + drawPanel = new DrawPanel(this); + + layoutCommandCard(); + layoutDrawingAndExtras(); + layoutDrawingArea(); + layoutExtras(); + initMenu(); + + contentPane.add(toplevel); + getFrame().setVisible(true); + initDrawingZone(); + } + + private void initFrame() + { + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + mainFrame.setSize(new Dimension(d.width, d.height * 9 / 10)); + mainFrame.setTitle("XLogo4Schools" + " - " + uc.getUserName()); + mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + mainFrame.setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("Icon_x4s.png"))); + mainFrame.addWindowListener(new WindowListener(){ + public void windowOpened(WindowEvent e){} + public void windowIconified(WindowEvent e){} + public void windowDeiconified(WindowEvent e){} + public void windowActivated(WindowEvent e){} + public void windowDeactivated(WindowEvent e){} + public void windowClosing(WindowEvent e) + { + closeWindow(); + } + public void windowClosed(WindowEvent e){} + }); + } + + /** + * @author Marko Zivkovic - new impl + */ + public void closeWindow() + { + WSManager storageManager = WSManager.getInstance(); + try + { + if (!uc.isVirtual()) + { + String openFile = userSpace.getOpenFileName(); + if (openFile != null) + { + userSpace.writeFileText(openFile, editeur.getText()); + userSpace.storeFile(openFile); + } + storageManager.getUserConfigInstance().store(); + } + System.exit(0); + } + catch (Exception e1) + { + String message = Logo.messages.getString(MessageKeys.US_COULD_NOT_STORE_RECENT_DATA) + "\n\n" + + e1.toString() + "\n\n" + + Logo.messages.getString("quitter?"); + + String[] choix = { Logo.messages.getString(MessageKeys.DIALOG_YES), Logo.messages.getString(MessageKeys.DIALOG_NO) }; + int retval = JOptionPane.showOptionDialog( + mainFrame, + message, + Logo.messages.getString("general.error.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.ERROR_MESSAGE, + null, choix, choix[0]); + + if (retval == JOptionPane.OK_OPTION) + System.exit(0); + } + } + + private void initDrawingZone() + { + // on centre la tortue + // Centering turtle + Dimension dim=scrollArea.getViewport().getViewRect().getSize(); + Point p=new Point(Math.abs( + uc.getImageWidth()/2-dim.width/2), + Math.abs(uc.getImageHeight()/2-dim.height/2)); + scrollArea.getViewport().setViewPosition(p); + + + MediaTracker tracker=new MediaTracker(getFrame()); + tracker.addImage(DrawPanel.dessin,0); + try{tracker.waitForID(0);} + catch(InterruptedException e){} + drawPanel.getGraphics().drawImage(DrawPanel.dessin,0,0,mainFrame); + scrollArea.validate(); + + setCommandLine(false); + genere_primitive(); + uc.setHeure_demarrage(Calendar.getInstance().getTimeInMillis()); + setCommandLine(true); + focus_Commande(); + resizeDrawingZone(); + } + + private void setTheme() + { + Font font = WSManager.getWorkspaceConfig().getFont(); + try + { + for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) + { + if ("Nimbus".equals(info.getName())) + { + UIManager.setLookAndFeel(info.getClassName()); + UIManager.put("defaultFont", font); + //UIManager.put("defaultFont", new Font(Font.SANS_SERIF, 0, 18)); + return; + } + } + + switch (uc.getLooknfeel()) + { + case JAVA: + //MetalLookAndFeel.setCurrentTheme(uc.getColorTheme().getTheme()); + UIManager.setLookAndFeel(new MetalLookAndFeel()); + break; + default: + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + + } + catch (Exception e) + { + try + { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch (Exception ignore){} + } + UIManager.put("defaultFont", font); + } + + private void layoutFilesAndProcedures() + { + + filesList = new FilesList(userSpace); + procedureSearch = new ProcedureSearch(userSpace); + filesAndProcedures = new JPanel(new GridBagLayout()); + + // Note : the following JPanel saved my day ... + // thanks to this The files list is finally position at the top :-) + JPanel layoutHelper = new JPanel(new BorderLayout()); + layoutHelper.add(filesList, BorderLayout.NORTH); + + JScrollPane scroller = new JScrollPane(layoutHelper); + scroller.getViewport().setBackground(new Color(BG_COLOR)); + layoutHelper.setBackground(new Color(BG_COLOR)); + + GridBagConstraints c = new GridBagConstraints(); + + c.fill = GridBagConstraints.HORIZONTAL; + c.weighty = 0; + c.gridx = 0; + c.gridy = 0; + c.anchor = GridBagConstraints.NORTHWEST; + filesAndProcedures.add(procedureSearch, c); + + c.gridx = 0; + c.gridy = 1; + + c.weighty = 1; + c.weightx = 1; + + c.fill = GridBagConstraints.BOTH; + + c.anchor = GridBagConstraints.NORTHWEST; + + filesAndProcedures.add(scroller, c); + + } + + private void layoutCommandCard() + { + + int preferredHeight = WSManager.getWorkspaceConfig().getFont().getSize() * 15 / 10; + + stopButton.setIcon(createImageIcon("stop.png", 20, 20)); + menuButton.setIcon(createImageIcon("menubtn.png", 20, 20)); + + stopButton.setMaximumSize(new Dimension(preferredHeight, preferredHeight)); + menuButton.setMaximumSize(new Dimension(preferredHeight, preferredHeight)); + commandCard.setBackground(Color.white); + Font clockFont = new Font(null, Font.BOLD, 20); + + recordTimerLabel.setOpaque(true); + recordTimerLabel.setBackground(Color.white); + recordTimerLabel.setFont(clockFont); + recordTimerLabel.setAlignmentY(JLabel.CENTER_ALIGNMENT); + + commandCard.add(recordTimerLabel); + commandCard.add(commandLine); + commandCard.add(drawingAndHistory); + commandLine.setAlignmentX(JFrame.CENTER_ALIGNMENT); + + drawingAndHistory.setTopComponent(drawingAndExtras); + drawingAndHistory.setBottomComponent(history); + drawingAndHistory.setResizeWeight(0.8); + + GroupLayout commandCardLayout = new GroupLayout(commandCard); + commandCard.setLayout(commandCardLayout); + commandLine.setAlignmentY(JComponent.CENTER_ALIGNMENT); + + commandCardLayout.setAutoCreateContainerGaps(false); + commandCardLayout.setAutoCreateGaps(false); + + commandCardLayout.setVerticalGroup( + commandCardLayout.createSequentialGroup() + .addGroup(commandCardLayout.createParallelGroup() + .addComponent(commandLine)// TODO GAP? + .addComponent(recordTimerLabel) + .addGap(2) + .addComponent(stopButton) + .addGap(2) + .addComponent(menuButton)) + .addComponent(drawingAndHistory)); + + commandCardLayout.setHorizontalGroup( + commandCardLayout.createParallelGroup() + .addGroup(commandCardLayout.createSequentialGroup() + .addComponent(commandLine) + .addComponent(recordTimerLabel) + .addComponent(stopButton) + .addComponent(menuButton)) + .addComponent(drawingAndHistory)); + } + + private void layoutDrawingAndExtras() + { + history.setMinimumSize(new Dimension(600, 40)); + drawingAndExtras.setBackground(new Color(BG_COLOR)); + + drawingAndExtras.add(scrollArea); + drawingAndExtras.add(extrasPanel); + + GroupLayout drawingAndExtrasLayout = new GroupLayout(drawingAndExtras); + drawingAndExtras.setLayout(drawingAndExtrasLayout); + + drawingAndExtrasLayout.setAutoCreateContainerGaps(false); + drawingAndExtrasLayout.setAutoCreateGaps(false); + + drawingAndExtrasLayout.setVerticalGroup( + drawingAndExtrasLayout.createParallelGroup() + .addComponent(scrollArea) + .addComponent(extrasPanel)); + + drawingAndExtrasLayout.setHorizontalGroup( + drawingAndExtrasLayout.createSequentialGroup() + .addComponent(scrollArea) + .addComponent(extrasPanel)); + } + + private void layoutDrawingArea() + { + drawPanel.setSize(new Dimension( + (int) (uc.getImageWidth() * DrawPanel.zoom), + (int) (uc.getImageHeight() * DrawPanel.zoom))); + scrollArea.getViewport().add(drawPanel); + scrollArea.getHorizontalScrollBar().setBlockIncrement(5); + scrollArea.getVerticalScrollBar().setBlockIncrement(5); + scrollArea.setPreferredSize(drawPanel.getPreferredSize()); + } + + private void layoutExtras() + { + extrasPanel.setBackground(new Color(BG_COLOR)); + extrasPanel.setLayout(new BoxLayout(extrasPanel, BoxLayout.Y_AXIS)); + speedSlider.setMaximumSize(new Dimension(20,200)); + speedSlider.setValue(speedSlider.getMaximum() - uc.getTurtleSpeed()); + + final TurtleComboBox turtleCombo = new TurtleComboBox(); + extrasPanel.add(speedSlider); + extrasPanel.add(turtleCombo); + turtleCombo.setBackground(new Color(BG_COLOR)); + + turtleCombo.getComboBox().setSelectedIndex(uc.getActiveTurtle()); + + + turtleCombo.getComboBox().addActionListener(new ActionListener(){ + + @Override + public void actionPerformed(ActionEvent e) + { + int i = turtleCombo.getComboBox().getSelectedIndex(); + System.out.println(i); + uc.setActiveTurtle(i); + getKernel().getActiveTurtle().setShape(uc.getActiveTurtle()); + getKernel().change_image_tortue("tortue" + i + ".png"); + } + }); + + } + + public void showCommandCard() + { + CardLayout cardLayout = (CardLayout) commandOrEditor.getLayout(); + cardLayout.show(commandOrEditor, COMMAND_CARD_ID); + } + + public void showEditorCard() + { + CardLayout cardLayout = (CardLayout) commandOrEditor.getLayout(); + cardLayout.show(commandOrEditor, EDITOR_CARD_ID); + } + + private JMenuItem startContestMenuItem; + private JMenuItem stopContestMenuItem; + private JMenuItem importMenuItem; + private JMenuItem exportMenuItem; + private JMenuItem saveImage; + + public void initMenu() + { + //Create the popup menu. + extras = new JPopupMenu(); + + if (!uc.isVirtual()) // Contest Mode not available in virtual mode + { + startContestMenuItem = new JMenuItem(Logo.messages.getString(MessageKeys.CONTEST_MODE_START)); + stopContestMenuItem = new JMenuItem(Logo.messages.getString(MessageKeys.CONTEST_MODE_STOP)); + extras.add(startContestMenuItem,0); + + startContestMenuItem.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + int nOfFiles = wc.getNOfContestFiles(); + int nOfBonusFiles = wc.getNOfContestBonusFiles(); + + String[] contestFileNames = new String[nOfFiles + nOfBonusFiles]; + + String nameBase = Logo.messages.getString("contest.mode.filename") + " "; + for (int i = 0; i < nOfFiles; i++) + contestFileNames[i] = nameBase + (i + 1); + + nameBase = Logo.messages.getString("contest.mode.bonus.filename") + " "; + + for (int i = 0; i < nOfBonusFiles; i++) + contestFileNames[nOfFiles + i] = nameBase + (i + 1); + try + { + userSpace.startRecordMode(contestFileNames); + } + catch (IOException e1) + { + DialogMessenger.getInstance().dispatchMessage(Logo.messages.getString("contest.error.title"), + Logo.messages.getString("contest.could.not.create") + "\n" + e.toString()); + return; + } + } + }); + stopContestMenuItem.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + userSpace.stopRecordMode(); + } + }); + } + + importMenuItem = new JMenuItem(Logo.messages.getString(MessageKeys.US_IMPORT)); + extras.add(importMenuItem); + importMenuItem.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + final JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.OPEN_DIALOG); + fc.setFileFilter(new FileFilter(){ + + @Override + public String getDescription() + { + return GlobalConfig.LOGO_FILE_EXTENSION; + } + + @Override + public boolean accept(File f) + { + return f.isDirectory() || f.getName().endsWith(GlobalConfig.LOGO_FILE_EXTENSION); + } + });; + + int returnVal = fc.showOpenDialog(getFrame()); + + if(returnVal == JFileChooser.APPROVE_OPTION) + { + File file = fc.getSelectedFile(); + try + { + userSpace.importFile(file); + } + catch (IOException e1) + { + DialogMessenger.getInstance().dispatchError(MessageKeys.GENERAL_ERROR_TITLE, e1.toString()); + } + } + + } + }); + + exportMenuItem = new JMenuItem(Logo.messages.getString(MessageKeys.US_EXPORT)); + extras.add(exportMenuItem); + exportMenuItem.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + + String fileName = (String) JOptionPane.showInputDialog(getFrame(), Logo.messages.getString(MessageKeys.US_EXPORT_MSG) + "\n", + Logo.messages.getString(MessageKeys.US_EXPORT), JOptionPane.PLAIN_MESSAGE, null, userSpace.getFileNames(), "ham"); + + //If a string was returned, say so. + if (fileName == null || fileName.length() == 0) + return; + + final JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.SAVE_DIALOG); + fc.setFileFilter(new FileFilter(){ + + @Override + public String getDescription() + { + return GlobalConfig.LOGO_FILE_EXTENSION; + } + + @Override + public boolean accept(File f) + { + return f.isDirectory() || f.getName().endsWith(GlobalConfig.LOGO_FILE_EXTENSION); + } + }); + ; + + int returnVal = fc.showOpenDialog(getFrame()); + + if (returnVal == JFileChooser.APPROVE_OPTION) + { + File file = fc.getSelectedFile(); + try + { + userSpace.exportFile(fileName, file); + } + catch (IOException e1) + { + DialogMessenger.getInstance().dispatchError(MessageKeys.GENERAL_ERROR_TITLE, + "Could not export file : \n " + e1.toString()); + } + } + } + }); + + saveImage = new JMenuItem(Logo.messages.getString(MessageKeys.US_SAVE_IMAGE)); + extras.add(saveImage); + saveImage.addActionListener(new ActionListener(){ + + @Override + public void actionPerformed(ActionEvent e) + { + WriteImage writeImage = new WriteImage(getFrame(), getDrawPanel() + .getSelectionImage()); + int value = writeImage.chooseFile(); + if (value == JFileChooser.APPROVE_OPTION) { + writeImage.start(); + } + } + }); + } + + private ImageIcon createImageIcon(String path, int width, int heigth) { + Image img = Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(path)); + return new ImageIcon(img.getScaledInstance(width, heigth, Image.SCALE_SMOOTH)); + } + + /* + * CHANGE LISTENERS + */ + + /** + * This glues together models and the GUI controllers. + */ + private void initListeners() + { + commandLine.addMouseListener(new MouseAdapter(){ + @Override + public void mousePressed(MouseEvent e) + { + maybeShowPopup(e); + } + @Override + public void mouseReleased(MouseEvent e) + { + maybeShowPopup(e); + } + + private void maybeShowPopup(MouseEvent e) + { + if (e.isPopupTrigger()) + { + jpop.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); + + commandLine.addKeyListener(touche); + + speedSlider.addChangeListener(new ChangeListener() + { + public void stateChanged(ChangeEvent e) + { + JSlider source = (JSlider) e.getSource(); + int value = source.getValue(); + uc.setTurtleSpeed(source.getMaximum() - value); + } + }); + + stopButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent arg0) + { + error=true; + if (NetworkServer.isActive){ + NetworkServer.stopServer(); + } + setCommandLine(true); + commandLine.requestFocus(); + } + }); + + menuButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + extras.show(menuButton, 0, 0); + } + }); + + userSpace.addProcedureMapListener(new ProcedureMapListener() + { + @Override + public void ownerRenamed(String oldName, String newName) + { + // ignore + } + + @Override + public void undefined(final String fileName, final String procedure) + { + if(SwingUtilities.isEventDispatchThread()) + { + onUndefined(fileName, procedure); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onUndefined(fileName, procedure); + } + }); + } + catch (InterruptedException e) + { + undefined(fileName, procedure); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onUndefined(String fileName, String procedure) + { + HistoryMessenger.getInstance().dispatchComment( + fileName + " : " + + Logo.messages.getString(MessageKeys.HIST_MSG_PROCEDURES_UNDEFINED) + " " + + procedure + ".\n"); + } + + @Override + public void undefined(final String fileName, final Collection<String> procedures) + { + if(SwingUtilities.isEventDispatchThread()) + { + onUndefined(fileName, procedures); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onUndefined(fileName, procedures); + } + }); + } + catch (InterruptedException e) + { + undefined(fileName, procedures); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onUndefined(String fileName, Collection<String> procedures) + { + StringBuilder sb = new StringBuilder(); + for (String procedureName : procedures) + { + sb.append(procedureName); + sb.append(", "); + } + sb.delete(sb.length() - 2, sb.length() - 1); + + HistoryMessenger.getInstance().dispatchComment( + fileName + " : " + + Logo.messages.getString(MessageKeys.HIST_MSG_PROCEDURES_UNDEFINED) + " " + + sb.toString() + ".\n"); + } + + @Override + public void defined(final String fileName, final String procedure) + { + if(SwingUtilities.isEventDispatchThread()) + { + onDefined(fileName, procedure); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onDefined(fileName, procedure); + } + }); + } + catch (InterruptedException e) + { + defined(fileName, procedure); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onDefined(String fileName, String procedure) + { + HistoryMessenger.getInstance().dispatchComment( + fileName + " : " + + Logo.messages.getString("definir") + " " + + procedure + ".\n"); + } + + @Override + public void defined(final String fileName, final Collection<String> procedures) + { + if(SwingUtilities.isEventDispatchThread()) + { + onDefined(fileName, procedures); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onDefined(fileName, procedures); + } + }); + } + catch (InterruptedException e) + { + defined(fileName, procedures); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onDefined(String fileName, Collection<String> procedures) + { + if (procedures.size() == 0) + return; + + StringBuilder sb = new StringBuilder(); + for (String procedureName : procedures) + { + sb.append(procedureName); + sb.append(", "); + } + sb.delete(sb.length() - 2, sb.length()); + + HistoryMessenger.getInstance().dispatchComment( + fileName + " : " + + Logo.messages.getString("definir") + " " + + sb.toString() + ".\n"); + } + }); + + userSpace.addFileListener(new FileContainerChangeListener() + { + public void fileOpened(final String fileName) + { + if(SwingUtilities.isEventDispatchThread()) + { + onFileOpened(fileName); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onFileOpened(fileName); + } + }); + } + catch (InterruptedException e) + { + fileOpened(fileName); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onFileOpened(String fileName) + { + showEditorCard(); + editeur.setText(userSpace.readFile(fileName)); + mainFrame.setTitle(appName + " - " + uc.getUserName() + " - " + fileName); + } + + public void fileClosed(final String fileName) + { + if(SwingUtilities.isEventDispatchThread()) + { + onFileClosed(fileName); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onFileClosed(fileName); + } + }); + } + catch (InterruptedException e) + { + fileClosed(fileName); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onFileClosed(String fileName) + { + try + { + if (userSpace.existsFile(fileName)) // It is possibly deleted, and the editor is therefore closed. + { + userSpace.writeFileText(fileName, editeur.getText()); + userSpace.storeFile(fileName); + } + } + catch (IOException e) + { + DialogMessenger.getInstance().dispatchError( + Logo.messages.getString("general.error.title"), + Logo.messages.getString("ws.automatic.save.failed")); + } + showCommandCard(); + commandLine.requestFocus(); + //commandLine.requestFocus(); + mainFrame.setTitle(appName + " - " + uc.getUserName()); + } + + @Override + public void fileAdded(String fileName) { } + + @Override + public void fileRemoved(String fileName) + { + if(SwingUtilities.isEventDispatchThread()) + { + showCommandCard(); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + showCommandCard(); + } + }); + } + catch (InterruptedException e) + { + fileRemoved(fileName); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + @Override + public void fileRenamed(String oldName, String newName) { } + + @Override + public void editRightsChanged(boolean editEnabled) { } + + }); + + userSpace.addErrorListener(new ErrorListener() + { + @Override + public void errorsDetected(final String fileName) + { + if(SwingUtilities.isEventDispatchThread()) + { + onErrorsDetected(fileName); + return; + } + + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onErrorsDetected(fileName); + } + }); + } + catch (InterruptedException e) + { + errorsDetected(fileName); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onErrorsDetected(String fileName) + { + HistoryMessenger.getInstance().dispatchError(fileName + " " + + Logo.messages.getString(MessageKeys.FILE_CONTAINS_ERRORS) + "\n"); + + for(String msg : userSpace.getErrorMessages(fileName)) + HistoryMessenger.getInstance().dispatchError(msg + "\n"); + } + + @Override + public void allErrorsCorrected(String fileName) + { + // ignore + } + }); + + userSpace.addModeChangedListener(new ModeChangeListener() + { + @Override + public void recordModeStopped() + { + if (SwingUtilities.isEventDispatchThread()) + { + onRecordModeStopped(); + return; + } + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onRecordModeStopped(); + } + }); + } + catch (InterruptedException e) + { + recordModeStopped(); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onRecordModeStopped() + { + extras.remove(stopContestMenuItem); + extras.add(startContestMenuItem, 0); + importMenuItem.setEnabled(true); + exportMenuItem.setEnabled(true); + recordTimer.stop(); + recordTimerLabel.setText(null); + } + + @Override + public void recordModeStarted() + { + if (SwingUtilities.isEventDispatchThread()) + { + onRecordModeStarted(); + return; + } + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onRecordModeStarted(); + } + }); + } + catch (InterruptedException e) + { + recordModeStarted(); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private Timer recordTimer; + + private void onRecordModeStarted() + { + extras.remove(startContestMenuItem); + extras.add(stopContestMenuItem, 0); + importMenuItem.setEnabled(false); + exportMenuItem.setEnabled(false); + recordTimer = new Timer(1000, new ActionListener(){ + private Date start = Calendar.getInstance().getTime(); + @Override + public void actionPerformed(ActionEvent e) + { + + Date now = Calendar.getInstance().getTime(); + + long diff = now.getTime() - start.getTime(); + + recordTimerLabel.setText(UserConfig.getMinSec(diff)); + } + }); + recordTimer.start(); + } + + @Override + public void networkModeStopped() + { + if (SwingUtilities.isEventDispatchThread()) + { + onNetworkModeStopped(); + return; + } + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onNetworkModeStopped(); + } + }); + } + catch (InterruptedException e) + { + networkModeStopped(); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onNetworkModeStopped() + { + filesList.setEnabled(true); + extras.setEnabled(true); + } + + @Override + public void networkModeStarted() + { + + if (SwingUtilities.isEventDispatchThread()) + { + onNetworkModeStarted(); + return; + } + try + { + SwingUtilities.invokeAndWait(new Runnable(){ + + @Override + public void run() + { + onNetworkModeStarted(); + } + }); + } + catch (InterruptedException e) + { + networkModeStarted(); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + } + + private void onNetworkModeStarted() + { + filesList.setEnabled(false); + extras.setEnabled(false); + } + }); + + procedureSearch.addSearchRequestListener(new ProcedureSearchRequestListener(){ + public void requestProcedureSearch(String procedureName) + { + displayProcedure(procedureName); + } + }); + } + + public void displayProcedure(String procedureName) + { + Procedure proc = userSpace.getExecutable(procedureName); + if (proc != null) + displayProcedure(proc); + else + { + HistoryMessenger.getInstance().dispatchError( + procedureName + " : " + + Logo.messages.getString(MessageKeys.EDITOR_DISPLAY_PROC_NOT_FOUND) + + "\n"); + } + } + + public void displayProcedure(Procedure proc) + { + String openFile = userSpace.getOpenFileName(); + + if (openFile != null) + { + try + { + userSpace.writeFileText(openFile, editeur.getText()); + userSpace.storeFile(openFile); + userSpace.closeFile(openFile); + } + catch (IOException e){} + } + + String fileName = proc.getOwnerName(); + if (userSpace.existsFile(fileName)) + { + userSpace.openFile(fileName); + editeur.displayProcedure(proc.getName()); + } + } + + // BELOW IS MOSTLY XLOGO LEGACY CODE + + /** + * Called by the constructor or when language has been modified + */ + public void setText() + { + stopButton.setToolTipText(Logo.messages.getString("interrompre_execution")); + + // Texte interne à utiliser pour JFileChooser et JColorChooser + UIManager.put("FileChooser.cancelButtonText", Logo.messages.getString("pref.cancel")); + UIManager.put("FileChooser.cancelButtonToolTipText", Logo.messages.getString("pref.cancel")); + UIManager.put("FileChooser.fileNameLabelText", Logo.messages.getString("nom_du_fichier")); + UIManager.put("FileChooser.upFolderToolTipText", Logo.messages.getString("dossier_parent")); + UIManager.put("FileChooser.lookInLabelText", Logo.messages.getString("rechercher_dans")); + + UIManager.put("FileChooser.newFolderToolTipText", Logo.messages.getString("nouveau_dossier")); + UIManager.put("FileChooser.homeFolderToolTipText", Logo.messages.getString("repertoire_accueil")); + UIManager.put("FileChooser.filesOfTypeLabelText", Logo.messages.getString("fichier_du_type")); + UIManager.put("FileChooser.helpButtonText", Logo.messages.getString("menu.help")); + + history.updateText(); + jpop.setText(); + } + + // Ce qu'il se passe en validant dans la zone de texte + /** + * When the user types "Enter" in the Command Line + * @author Lo�c Le Coq + */ + public void commande_actionPerformed() + { + // System.out.println("commandeTotal :"+Runtime.getRuntime().totalMemory()/1024/1024+" Free "+Runtime.getRuntime().freeMemory()/1024/1024); + // Si une parenthese était sélectionnée, on désactive la + // décoloration + commandLine.setActive(false); + // System.out.println(commande.getCaret().isVisible()); + if (stop) + stop = false; + String texte = commandLine.getText(); + if (!texte.equals("") && commandLine.isEditable()) + { + if (touche.tape) + { + touche.tape = false; + pile_historique.pop(); + } + if (pile_historique.size() > 49) + pile_historique.remove(0); + pile_historique.push(texte); // On rajoute ce texte à l'historique + index_historique = pile_historique.size(); // on réajuste l'index + // de + // l'historique + + HistoryMessenger.getInstance().dispatchMessage(texte + "\n"); + + // On enlève les éventuels commentaires + int a = texte.indexOf("#"); + + // LogoParser lp=new LogoParser(texte); + while (a != -1) + { + if (a == 0) + { + texte = ""; + break; + } + else if (!texte.substring(a - 1, a).equals("\\")) + { + texte = texte.substring(0, a); + break; + } + a = texte.indexOf("#", a + 1); + } + + if(userSpace.isRecordMode()) + recordCommandLine(texte); + + Thread.currentThread().setPriority(Thread.MIN_PRIORITY); + startInterpretation(Utils.decoupe(texte)); + + // On efface la ligne de commande + SwingUtilities.invokeLater(new Runnable(){ + public void run() + { + commandLine.setText(""); + } + }); + + } + } + + /** + * @author Marko Zivkovic + * @param text + */ + public void recordCommandLine(final String text) + { + new Thread(new Runnable(){ + + @Override + public void run() + { + PrintWriter out = null; + File logoFile = uc.getCommandLineContestFile(); + String line = UserConfig.getTimeStamp() + " : " + text; + try + { + out = new PrintWriter(new BufferedWriter(new FileWriter(logoFile, true))); + out.println(line); + }catch(Exception e) + { + DialogMessenger.getInstance().dispatchMessage( + Logo.messages.getString("contest.error.title"), + Logo.messages.getString("contest.could.not.store") + "\n" + e.toString()); + }finally + { + if(out != null) + out.close(); + } + } + }).run(); + } + + /** + * Launch the Thread Affichage with the instructions "st" + * + * @param st + * List of instructions + * @author Lo�c Le Coq + * @author Marko Zivkovic - renamed (it was affichage_Start) + */ + public void startInterpretation(StringBuffer st) + { + affichage = new Affichage(this, st); + affichage.start(); + } + + /** + * Get Method for Sound Player + * + * @return The Sound Player + */ + public Sound_Player getSon() + { + return son; + } + + /** + * Resize the dawing area + */ + public void resizeDrawingZone() + { + if (null != affichage) + { + affichage.setPause(true); + } + // resize the drawing image + SwingUtilities.invokeLater(new Runnable(){ + public void run() + { + DrawPanel.dessin = new BufferedImage(uc.getImageWidth(), uc.getImageHeight(), + BufferedImage.TYPE_INT_RGB); + // System.out.println("Total :"+Runtime.getRuntime().totalMemory()/1024+" max "+Runtime.getRuntime().maxMemory()/1024+" Free "+Runtime.getRuntime().freeMemory()/1024); + MediaTracker tracker = new MediaTracker(drawPanel); + tracker.addImage(DrawPanel.dessin, 0); + try + { + tracker.waitForID(0); + } + catch (InterruptedException e) + {} + // ardoise1.getGraphics().drawImage(Ardoise.dessin,0,0,ardoise1); + + drawPanel.setPreferredSize(new Dimension(uc.getImageWidth(), uc.getImageHeight())); + drawPanel.revalidate(); + kernel.initGraphics(); + // ardoise.repaint(); + //calculateMargin(); TODOD maybe return this + + Dimension d = scrollArea.getViewport().getViewRect().getSize(); + Point p = new Point( + Math.abs((uc.getImageWidth() - d.width) / 2), + Math.abs((uc.getImageHeight() - d.height) / 2)); + scrollArea.getViewport().setViewPosition(p); + if (null != affichage) + affichage.setPause(false); + } + + }); + + } + + /** + * Change Syntax Highlighting for the editor, the command line and the + * History zone + * + * @param c_comment + * Comment Color + * @param sty_comment + * Comment style + * @param c_primitive + * Primitive Color + * @param sty_primitive + * Primitive style + * @param c_parenthese + * Parenthesis Color + * @param sty_parenthese + * Parenthesis Style + * @param c_operande + * Operand Color + * @param sty_operande + * Operand style + */ + public void changeSyntaxHighlightingStyle(int c_comment, int sty_comment, int c_primitive, int sty_primitive, + int c_parenthese, int sty_parenthese, int c_operande, int sty_operande) + { + WorkspaceConfig uc = WSManager.getWorkspaceConfig(); + editeur.initStyles(uc.getCommentColor(), uc.getCommentStyle(), uc.getPrimitiveColor(), + uc.getPrimitiveStyle(), uc.getBraceColor(), uc.getBraceStyle(), + uc.getOperatorColor(), uc.getOperatorStyle()); + commandLine.initStyles(uc.getCommentColor(), uc.getCommentStyle(), uc.getPrimitiveColor(), + uc.getPrimitiveStyle(), uc.getBraceColor(), uc.getBraceStyle(), + uc.getOperatorColor(), uc.getOperatorStyle()); + history.getDsd().initStyles(uc.getCommentColor(), uc.getCommentStyle(), + uc.getPrimitiveColor(), uc.getPrimitiveStyle(), uc.getBraceColor(), + uc.getBraceStyle(), uc.getOperatorColor(), uc.getOperatorStyle()); + } + + /** + * Enable or disable Syntax Highlighting + */ + public void setColoration(boolean b) + { + history.setColoration(b); + commandLine.setColoration(b); + } + + /** + * Return the drawing area + * + * @return The drawing area + */ + public DrawPanel getDrawPanel() + { + return drawPanel; + } + + /** + * Set Focus on the command line + */ + public void focus_Commande() + { + commandLine.requestFocus(); + commandLine.getCaret().setVisible(true); + } + + /** + * Notice if the command line is editable. + * + * @return true if Command Line is editable, false otherwise + */ + public boolean commande_isEditable() + { + return commandLine.isEditable(); + } + + /** + * Set the text in the command Line + * + * @param txt + * The text to write + */ + public void setCommandText(String txt) + { + commandLine.setText(txt); + } + + /** + * Get History panel + * + * @return The HistoryPanel + */ + public HistoryPanel getHistoryPanel() + { + return history; + } + + /** + * Enable or disable the command line and the play button + */ + public void setCommandLine(boolean b) + { + if (b) + { + if (SwingUtilities.isEventDispatchThread()) + { + commandLine.setEditable(true); + commandLine.setBackground(Color.WHITE); + } + else + { + SwingUtilities.invokeLater(new Runnable(){ + public void run() + { + commandLine.setEditable(true); + // commande.requestFocus(); + commandLine.setBackground(Color.WHITE); + } + }); + } + } + else + { + commandLine.setEditable(false); + commandLine.setBackground(new Color(250, 232, 217)); + } + } + + /** + * This method copy the selected Text in the command line + */ + protected void copy() + { + commandLine.copy(); + } + + /** + * This methos cut the selected Text in the command line + */ + protected void cut() + { + commandLine.cut(); + } + + /** + * This methos paste the selected Text into the command line + */ + protected void paste() + { + commandLine.paste(); + } + + /** + * This methos selects all the Text in the command line + */ + protected void select_all() + { + commandLine.selectAll(); + } + + /** + * This method creates all primitives. + * In XLogo4Schools, this method does not initialize the startup files + * anymore, because we don't have startup files. + * + * @author Marko Zivkovic + */ + protected void genere_primitive() + { + kernel.initPrimitive(); + } + + /** + * Set the last key pressed to the key corresponding to integer i + * + * @param i + * The key code + */ + public void setCar(int i) + { + touche.setCar(i); + } + + /** + * Returns an int that corresponds to the last key pressed. + * + * @return the int representing the last key pressed + */ + public int getCar() + { + return touche.getCar(); + } + + /** + * This boolean indicates if the viewer3D is visible + * + * @return true or false + */ + public boolean viewer3DVisible() + { + if (null != viewer3d) + return viewer3d.isVisible(); + return false; + } + + /** + * Initialize the 3D Viewer + */ + public void initViewer3D() + { + if (null == viewer3d) + { + viewer3d = new Viewer3D(drawPanel.getWorld3D(), drawPanel.getBackgroundColor()); + } + + } + + public Viewer3D getViewer3D() + { + return viewer3d; + } + + /** + * Open the Viewer3D Frame + */ + public void viewerOpen() + { + if (null == viewer3d) + { + viewer3d = new Viewer3D(drawPanel.getWorld3D(), drawPanel.getBackgroundColor()); + } + else + { + viewer3d.setVisible(false); + } + viewer3d.insertBranch(); + viewer3d.setVisible(true); + viewer3d.requestFocus(); + } + + /** + * Returns the current kernel + * + * @return The Kernel Object associated to main frame + */ + public Kernel getKernel() + { + return kernel; + } + + /** + * + * @author loic This class is the Controller for the Command Line<br> + * It looks for key event, Upper and Lower Arrow for History<br> + * And all other Characters + */ + class Touche extends KeyAdapter + { + int car = -1; + + private boolean tape = false; + + public void setCar(int i) + { + car = i; + } + + public int getCar() + { + return car; + } + + public void keyPressed(KeyEvent e) + { + int ch = e.getKeyChar(); + int code = e.getKeyCode(); + if (commandLine.isEditable()) + { + if (code == KeyEvent.VK_UP) + { + if (index_historique > 0) + { + if (index_historique == pile_historique.size()) + { + tape = true; + pile_historique.push(commandLine.getText()); + } + index_historique--; + commandLine.setText(pile_historique.get(index_historique)); + } + else + index_historique = 0; + } + else if (code == KeyEvent.VK_DOWN) + { + if (index_historique < pile_historique.size() - 1) + { + index_historique++; + commandLine.setText(pile_historique.get(index_historique)); + } + else + index_historique = pile_historique.size() - 1; + } + } + else + { + if (ch != 65535) + car = ch; + else + car = -code; + } + } + } +} diff --git a/logo/src/xlogo/Logo.java b/logo/src/xlogo/Logo.java new file mode 100644 index 0000000..86406af --- /dev/null +++ b/logo/src/xlogo/Logo.java @@ -0,0 +1,183 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * a lot of modifications, extensions, refactorings have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +package xlogo; + +import javax.media.j3d.VirtualUniverse; +import javax.swing.UIManager; +import javax.swing.SwingUtilities; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ResourceBundle; + +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +import xlogo.storage.workspace.Language; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.gui.welcome.WelcomeScreen; +import xlogo.kernel.Primitive; +/** + * @author loic + * + *@author Marko - this class generates the language, + *displays the welcome screen for workspace and user selection, + *and then starts {@link Application} when the user space is entered. + */ +public class Logo { + /** + * This ResourceBundle contains all messages for XLogo (menu, errors...) + */ + public static ResourceBundle messages=null; + + public static String translationLanguage[]=new String[14]; + + /** + * Welcome screen is always displayed when the application is started. + * The user selected a workspace and a user to enter the application. + */ + private WelcomeScreen welcomeScreen=null; + + // private Language language; + + + /** + * The main methods + * @param args The file *.lgo to load on startup + */ + public static void main(String[] args) { + + try{ + // Display the java3d version + java.util.Map<String,String> map=VirtualUniverse.getProperties(); + System.out.println("Java3d :"+map.get("j3d.version")); + } + catch(Exception e){ + System.out.println("Java3d problem"); + e.printStackTrace(); + } + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch(Exception e) { + e.printStackTrace(); + } + + //Recuperer les fichiers de démarrage correspondant au double clic de souris + // ou au lancement en ligne de commande + + GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance(); + + for(int i=0;i<args.length;i++){ + gc.getPath().add(args[i]); + } + + gc.getPath().add(0,"#####"); + new Logo(); + } + + /**Builds Application with the valid Config*/ + public Logo() { + Language lang = WSManager.getInstance().getWorkspaceConfigInstance().getLanguage(); + generateLanguage(lang); + + showWelcomeScreen(); + } + + /** + * Display {@link xlogo.gui.welcome.WelcomeScreen} when starting the application. + * @author Marko Zivkovic + */ + private void showWelcomeScreen() { + + try{ + SwingUtilities.invokeAndWait(new Runnable(){ + public void run(){ + welcomeScreen=new WelcomeScreen(new ActionListener() { + public void actionPerformed(ActionEvent e) { + enterApplication(); + } + }); + } + }); + //UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel()); + } catch(Exception e){ + System.out.println("here " + e.toString()); //TODO error m + } + + } + + /** + * + */ + public void enterApplication(){ + WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance(); + + welcomeScreen.dispose(); + generateLanguage(wc.getLanguage()); + + // Initialize frame + SwingUtilities.invokeLater(new Runnable(){ + public void run(){ + new Application(); + } + }); + + } + + /** + * Sets the selected language for all messages + * @param id The integer that represents the language + */ + public static void generateLanguage(Language lang){ // fixe la langue utilisée pour les messages + messages=ResourceBundle.getBundle("langage",lang.getLocale()); + translationLanguage[0]=Logo.messages.getString("pref.general.french"); + translationLanguage[1]=Logo.messages.getString("pref.general.english"); + translationLanguage[2]=Logo.messages.getString("pref.general.arabic"); + translationLanguage[3]=Logo.messages.getString("pref.general.spanish"); + translationLanguage[4]=Logo.messages.getString("pref.general.portuguese"); + translationLanguage[5]=Logo.messages.getString("pref.general.esperanto"); + translationLanguage[6]=Logo.messages.getString("pref.general.german"); + translationLanguage[7]=Logo.messages.getString("pref.general.galician"); + translationLanguage[8]=Logo.messages.getString("pref.general.asturian"); + translationLanguage[9]=Logo.messages.getString("pref.general.greek"); + translationLanguage[10]=Logo.messages.getString("pref.general.italian"); + translationLanguage[11]=Logo.messages.getString("pref.general.catalan"); + translationLanguage[12]=Logo.messages.getString("pref.general.hungarian"); + translationLanguage[13]=Logo.messages.getString("pref.general.abz.german.english"); + + Primitive.buildPrimitiveTreemap(lang); + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/MemoryChecker.java b/logo/src/xlogo/MemoryChecker.java new file mode 100644 index 0000000..f35f73a --- /dev/null +++ b/logo/src/xlogo/MemoryChecker.java @@ -0,0 +1,163 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * a lot of modifications, extensions, refactorings have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + **/ +package xlogo; + +import xlogo.messages.async.dialog.DialogMessenger; +import xlogo.storage.global.GlobalConfig; + +/** + * This class is a thread that prevents from memory Overflow <br> + * Those problems could happen when a program loops indefinitely<br> + * Eg:<br> + * <br> + * <tt> + * To bad<br> + * fd 1 rt 1 <br> + * bad<br> + * this lines will explode memory<br> + * end <br> + * </tt> + * + * @author loic + * + * @author Marko Zivkovic - Extensive tests and provocation of the memory usage error message have shown + * that in XLogo4Schools, using a maximum 128MB heap, the memory threshold is never reached + * (Or very, very late in a gigantic recursion). + * + */ +public class MemoryChecker extends Thread +{ + /** + * The main frame + */ + private Application cadre; + /** + * This boolean indicates if the thread has to continue.<br> + * If false, the thread will stop. + */ + private boolean alive; + + /** + * Constructs the Memory Checker for the main Frame + * + * @param cadre + * the main Frame + */ + public MemoryChecker(Application cadre) + { + this.cadre = cadre; + } + + private static int maxSleepTime = 10000; + private static int minSleepTime = 500; + private static int sleepRange = maxSleepTime - minSleepTime; + + /** + * The Run Method for the Thread + */ + public void run() + { + /* + * Marko : I reduced the amount of calculations done in every iteration. + * Before it included 1 subtraction and 2 divisions and a fetch from GlobalConfig, + * now only 1 subtraction is used to determine consumed > consumptionThreshold + * and another long comparison was added to regulate frequency of memory checks. + */ + long consumptionThreshold = GlobalConfig.getMemoryThreshold(); + long listenThreshold = (long) (0.8 * consumptionThreshold); + + + /* + * I increased default sleeping time to about 10 seconds, because a check every 1 second is too much overhead for doing nothing useful. + * However, as soon as the listenThreshold is reached, the sleepTime will start to decrease. + * Only once the listenThreshold is reached, + * the MemoryChecker becomes important to prevent an OutOfMemoryError and start suggesting the garbage collector to work.) + */ + int sleepTime = maxSleepTime; + + alive = true; + + while (alive) + { + try + { + Thread.sleep(sleepTime); + } + catch (InterruptedException ignore) + {} + long free = Runtime.getRuntime().freeMemory(); + long total = Runtime.getRuntime().totalMemory(); + long consumed = (total - free); + + if (consumed >= listenThreshold) + { + sleepTime = (int) (maxSleepTime - consumed / total * sleepRange); + + /* + * Marko : + * In XLogo, when the error dialog was displayed, it usually kept displaying several times, disrupting any further use of the interpreter. + * The only out was to restart the application. This indicates that, although heavy memory usage was detected by this thread, + * the garbage collector did not yet start to free memory from dead objects. + * (Discussions about GC in the Internet indicate that the Java GC starts working as soon as a heap generation gets full. + * It is possible that the young generation is not full enough when 0.9*MaxMemory is reached, thus the message keeps appearing all the time, + * because memory is not sufficiently cleaned up.) + * Therefore, at least suggest the GC that it would be a good moment for garbage collection, and help recover. That's the best we can do. + */ + System.gc(); + } + else + sleepTime = maxSleepTime; + + if (consumed > consumptionThreshold) + { + cadre.error = true; + alive = false; + DialogMessenger.getInstance().dispatchError(Logo.messages.getString("erreur"), + Logo.messages.getString("depassement_memoire")); + } + } + } + + /** + * Causes the memory checker loop to break. + * @author Marko + */ + public void kill() + { + alive = false; + } + +} diff --git a/logo/src/xlogo/MenuListener.java b/logo/src/xlogo/MenuListener.java new file mode 100644 index 0000000..a40fd99 --- /dev/null +++ b/logo/src/xlogo/MenuListener.java @@ -0,0 +1,234 @@ +/** +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/* Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ + +package xlogo; +// TODO Use parts of this that might be useful, and then delete this file +import java.awt.*; +import java.io.*; + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.image.BufferedImage; +import java.awt.event.*; + +import javax.swing.*; + +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +import xlogo.storage.workspace.Language; +import xlogo.utils.WebPage; +import xlogo.utils.Utils; +import xlogo.gui.AImprimer; +import xlogo.gui.MyTextAreaDialog; +import xlogo.kernel.DrawPanel; + +/** + * This class is the Controller for the main frame.<br> + * All events are interpreted by this class + * + * @author loic + * + */ +public class MenuListener extends JDialog implements ActionListener { + private static final long serialVersionUID = 1L; + private double zoomfactor = 1.25; + protected static final String FILE_NEW = "new"; + protected static final String FILE_OPEN = "open"; + protected static final String FILE_SAVE_AS = "save_as"; + protected static final String FILE_SAVE = "save"; + protected static final String FILE_SAVE_IMAGE = "record_image"; + protected static final String FILE_COPY_IMAGE = "copy_image"; + protected static final String FILE_PRINT_IMAGE = "print_image"; + protected static final String FILE_SAVE_TEXT = "save_text"; + protected static final String FILE_QUIT = "quit"; + protected static final String EDIT_SELECT_ALL = "select_all"; + public static final String EDIT_COPY = "copy"; + public static final String EDIT_CUT = "cut"; + public static final String EDIT_PASTE = "paste"; + protected static final String TOOLS_PEN_COLOR = "pen_color"; + protected static final String TOOLS_SCREEN_COLOR = "screen_color"; + protected static final String TOOLS_TRANSLATOR = "translator"; + protected static final String TOOLS_OPTIONS = "preferences"; + protected static final String TOOLS_ERASER = "eraser"; + protected static final String HELP_LICENCE = "licence"; + protected static final String HELP_TRANSLATED_LICENCE = "translated_licence"; + protected static final String HELP_TRANSLATE_XLOGO = "translate_xlogo"; + protected static final String HELP_ABOUT = "about"; + public static final String PLAY = "play"; + public static final String ZOOMIN = "zoomin"; + public static final String ZOOMOUT = "zoomout"; + + private static final String WEB_SITE = "http://xlogo.tuxfamily.org"; + private static final String MAIL = "[email protected]"; + private Application cadre; + + /** + * Attached the controller MenuListener to the main Frame + * + * @param cadre + * main Frame + */ + public MenuListener(Application cadre) { + this.cadre = cadre; + } + + /** + * This method dispatches all events from the main Frame and executes the + * task corresponding to the incoming event. + */ + public void actionPerformed(ActionEvent e) { + Language lang = WSManager.getWorkspaceConfig().getLanguage(); + + String cmd = e.getActionCommand(); + if (MenuListener.EDIT_COPY.equals(cmd)) { // Copier + cadre.copy(); + } else if (MenuListener.EDIT_CUT.equals(cmd)) { // Couper + cadre.cut(); + } else if (MenuListener.EDIT_PASTE.equals(cmd)) { // Coller + cadre.paste(); + } else if (MenuListener.EDIT_SELECT_ALL.equals(cmd)) { // select all + cadre.select_all(); + } else if (MenuListener.FILE_COPY_IMAGE.equals(cmd)) { // Copier l'image + // au + // presse-papier + Thread copie = new CopyImage(); + copie.start(); + } else if (MenuListener.FILE_PRINT_IMAGE.equals(cmd)) { // imprimer + // l'image + AImprimer can = new AImprimer(cadre.getDrawPanel() + .getSelectionImage()); + Thread imprime = new Thread(can); + imprime.start(); + } else if (MenuListener.HELP_ABOUT.equals(cmd)) { // Boite de dialogue A + // propos + String message = Logo.messages.getString("message_a_propos1") + + GlobalConfig.getVersion() + "\n\n" + + Logo.messages.getString("message_a_propos2") + " " + + MenuListener.WEB_SITE + "\n\n" + + Logo.messages.getString("message_a_propos3") + "\n " + + MenuListener.MAIL; + MyTextAreaDialog jt = new MyTextAreaDialog(message); + ImageIcon icone = new ImageIcon( + Utils.class.getResource("icone.png")); + JOptionPane.showMessageDialog(null, jt, + Logo.messages.getString("menu.help.about"), + JOptionPane.INFORMATION_MESSAGE, (Icon) icone); + + } else if (MenuListener.ZOOMIN.equals(cmd)) { + cadre.getDrawPanel().zoom(zoomfactor * DrawPanel.zoom, true); + } else if (MenuListener.ZOOMOUT.equals(cmd)) { + cadre.getDrawPanel().zoom(1 / zoomfactor * DrawPanel.zoom, false); + } + else if (MenuListener.HELP_LICENCE.equals(cmd) | MenuListener.HELP_TRANSLATED_LICENCE.equals(cmd)) + { // Affichage + // de la + // licence + JFrame frame = new JFrame(Logo.messages.getString("menu.help.licence")); + frame.setIconImage(Toolkit.getDefaultToolkit().createImage(WebPage.class.getResource("icone.png"))); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + frame.setSize(500, 500); + WebPage editorPane = new WebPage(); + editorPane.setEditable(false); + String path = "gpl/gpl-"; + if (MenuListener.HELP_LICENCE.equals(cmd)) + path += "en"; + else + { + path += lang.getLanguageCode(); + } + path += ".html"; + java.net.URL helpURL = MenuListener.class.getResource(path); + if (helpURL != null) + { + try + { + editorPane.setPage(helpURL); + } + catch (IOException e1) + { + System.err.println("Attempted to read a bad URL: " + helpURL); + } + } + else + { + System.err.println("Couldn't find file: " + path); + } + + // Put the editor pane in a scroll pane. + JScrollPane editorScrollPane = new JScrollPane(editorPane); + editorScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + editorScrollPane.setPreferredSize(new Dimension(250, 145)); + editorScrollPane.setMinimumSize(new Dimension(10, 10)); + frame.getContentPane().add(editorScrollPane); + frame.setVisible(true); + } + + } + + /** + * This class is a thread that copy the Image selection into the clipboard + */ + class CopyImage extends Thread implements Transferable { + private BufferedImage image = null; + Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); + + CopyImage() { + image = cadre.getDrawPanel().getSelectionImage(); + } + + public void run() { + clip.setContents(this, null); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { DataFlavor.imageFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return DataFlavor.imageFlavor.equals(flavor); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + return image; + } + } + +} diff --git a/logo/src/xlogo/Popup.java b/logo/src/xlogo/Popup.java new file mode 100644 index 0000000..a2acc2d --- /dev/null +++ b/logo/src/xlogo/Popup.java @@ -0,0 +1,161 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */package xlogo; +import javax.swing.JMenuItem; +import javax.swing.text.JTextComponent; +import javax.swing.text.BadLocationException; +import javax.swing.JPopupMenu; + +import xlogo.storage.WSManager; +import xlogo.storage.workspace.Language; + +import java.awt.event.*; +/** + * This class represents the JPopupMenu when the user clicks with the right button on the command line.<br> + * It displays the action cut, copy, paste and:<br> + * In esperanto mode, the special characters for esperanto are added. + * @author loic + * + */ +public class Popup extends JPopupMenu implements ActionListener { + private static final long serialVersionUID = 1L; + /** + * This array contains all special characters for esperanto + */ + private String[] car=new String[12]; + /** + * Items for esperanto special characters + */ + private JMenuItem[] jpopcar=new JMenuItem[12]; + /** + * Item for copy action + */ + private JMenuItem jpopcopier = new JMenuItem(); + /** + * Item for paste action + */ + private JMenuItem jpopcoller = new JMenuItem(); + /** + * Item for cut action + */ + private JMenuItem jpopcouper = new JMenuItem(); + /** + * Separator between items + */ + private JPopupMenu.Separator separ=new JPopupMenu.Separator(); + /** + * The text Component for the Jpopup Menu + */ + private JTextComponent jt=null; + /** + * This Constructot attached the Jpopup to Text Component jt + * @param menulistener The Controller for action + * @param jt The Text Component + */ + public Popup(ActionListener menulistener,JTextComponent jt){ + this.jt=jt; + car[0]="\u0109"; + car[1]="\u011d"; + car[2]="\u0125"; + car[3]="\u0135"; + car[4]="\u015d"; + car[5]="\u016d"; + car[6]="\u0108"; + car[7]="\u011c"; + car[8]="\u0124"; + car[9]="\u0134"; + car[10]="\u015c"; + car[11]="\u016c"; + for(int i=0;i<car.length;i++) { + jpopcar[i]=new JMenuItem(car[i]); + jpopcar[i].addActionListener(this); + jpopcar[i].setActionCommand(car[i]); + } + add(jpopcouper); + add(jpopcopier); + add(jpopcoller); + jpopcouper.setActionCommand(MenuListener.EDIT_CUT); + jpopcouper.addActionListener(this); + jpopcoller.setActionCommand(MenuListener.EDIT_PASTE); + jpopcoller.addActionListener(this); + jpopcopier.setActionCommand(MenuListener.EDIT_COPY); + jpopcopier.addActionListener(this); + setText(); + } + /** + * Called by constructor and when the language is modified. + */ + void setText(){ + jpopcoller.setText(Logo.messages.getString("menu.edition.paste")); + jpopcouper.setText(Logo.messages.getString("menu.edition.cut")); + jpopcopier.setText(Logo.messages.getString("menu.edition.copy")); + // Si le langage choisie est l'esperanto, on rajoute les caractères accentués spéciaux au menu + if (WSManager.getWorkspaceConfig().getLanguage()==Language.LANGUAGE_ESPERANTO) { + add(separ); + for (int i=0;i<jpopcar.length;i++) { + add(jpopcar[i]); + } + } + else if(this.getComponentCount()>3){ + remove(separ); + for (int i=0;i<jpopcar.length;i++) remove(jpopcar[i]); + } + } + /** + * The action to dispatch when the user clicks on the popup menu + */ + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (cmd.equals(MenuListener.EDIT_COPY)) jt.copy(); + else if (cmd.equals(MenuListener.EDIT_CUT)) jt.cut(); + else if (cmd.equals(MenuListener.EDIT_PASTE)) jt.paste(); + else{ + for (int i=0;i<car.length;i++){ + if (car[i].equals(cmd)) { + int pos=jt.getCaretPosition(); + try{ + String debut=jt.getText(0,pos); + int longueur=jt.getText().length(); + String fin=""; + if (longueur>pos) fin=jt.getText(pos+1,longueur-pos); + jt.setText(debut+car[i]+fin); + jt.setCaretPosition(pos+1); + } + catch(BadLocationException e1){} + break; + } + } + } + } +} diff --git a/logo/src/xlogo/Sound_Player.java b/logo/src/xlogo/Sound_Player.java new file mode 100644 index 0000000..9940f23 --- /dev/null +++ b/logo/src/xlogo/Sound_Player.java @@ -0,0 +1,281 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ + +package xlogo; +import java.util.StringTokenizer; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Track; + +import xlogo.kernel.LogoError; + +/** + * This class is designed to play music in XLogo + * @author loic + * + */ +public class Sound_Player { + private Application cadre; + static final int[ ] offsets = { 0, 2, 4, 5, 7,9,11}; + private String[] notes={Logo.messages.getString("note.do"),Logo.messages.getString("note.re"),Logo.messages.getString("note.mi"),Logo.messages.getString("note.fa"),Logo.messages.getString("note.sol"),Logo.messages.getString("note.la"),Logo.messages.getString("note.si")}; + private Track track=null; + private int instrument=0; //instrument selectionne + private int ticks=0; // Temps écoulé depuis le début de la piste + private Synthesizer synthesizer; + private Sequencer sequencer; + private Sequence sequence; + /** + * Builds our Sound Player + * @param cadre The main Frame + */ + Sound_Player(Application cadre){ + this.cadre=cadre; + try{sequence = new Sequence(Sequence.PPQ, 16); + } + catch(InvalidMidiDataException e){} + } + /** + * Choose a specific instrument + * @param i The integer that represents this instrument + */ + public void setInstrument(int i){ + instrument=i; + } + /** + * Return the current instrument + * @return The integer that represents the current instrument + */ + public int getInstrument(){ + return instrument; + } + /** + * This methode parses the note sequence and write it into a MIDI Sequence + * @param li This List contains the sequence of note to play + * @throws LogoError If the sequence in't valid + */ + public void cree_sequence(String li) throws LogoError{ + // 16 ticks per quarter note. + try{ + + /* + * Cette méthode met les notes contenues dans li dans la piste Track + * Voici les notations utilisées: + * do-re-mi-fa-sol-la-si: Les notes do+ pour le dièse, do- pour le bémol + * :+,:++ etc Monte d'une octave, de deux octaves etc + * :-,:--, etc Descend d'une octave, de deux octaves etc + * 1 ou 0.5 ou 2 : Durée affectée à la série de notes + */ + if (null==track) track = sequence.createTrack( ); // Begin with a new track + // Set the instrument on channel 0 + ShortMessage sm = new ShortMessage( ); + sm.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument, 0); + + track.add(new MidiEvent(sm, 0)); + int notelength = 64; // valeur d'une noire + int velocity = 64; // default to middle volume + int basekey = 60; // 60 is middle C. Adjusted up and down by octave + int key=0; + StringTokenizer st=new StringTokenizer(li); + String element=""; + if (st.hasMoreTokens()) element=st.nextToken().toLowerCase(); + while (!element.equals("")){ + int i=isnotes(element); + if(i!=-1){ + key=basekey+offsets[isnotes(element)]; + if (st.hasMoreTokens()) element=st.nextToken().toLowerCase(); + else element=""; + if (element.equals("+")) { //dièse + key++; + if (st.hasMoreTokens()) element=st.nextToken().toLowerCase(); + else element=""; + } + else if (element.equals("-")) { //bémol + key--; + if (st.hasMoreTokens()) element=st.nextToken().toLowerCase(); + else element=""; + } + // System.out.println(ticks+" "+notelength+" "+velocity+" "+key); + addNote(ticks,notelength,key,velocity); + ticks+=notelength; + } + if (element.equals(":")){ + while (st.hasMoreTokens()){ + element=st.nextToken().toLowerCase(); + if (element.equals("+")) { + basekey+=12; //Une octave en plus + if (!st.hasMoreTokens()) element=""; + } + else if (element.equals("-")) { + basekey-=12; //Une octave en moins + if (!st.hasMoreTokens()) element=""; + } + else break; + } + } + else { + try{ + double longueur=Double.parseDouble(element); + notelength=(int)(longueur*64+0.5); + if (st.hasMoreTokens()) element=st.nextToken().toLowerCase(); + else element=""; + } + catch(NumberFormatException e){ + if (!element.equals("")&&isnotes(element)==-1&&!element.equals(":")) + throw new LogoError(Logo.messages.getString("probleme_sequence")); + } + } + } + } + catch(InvalidMidiDataException e2){} + } + /** + * If element is a note return the index for the notes in the array list "notes" + * @param element The String to test + * @return The index for this notes, -1 if it doesn't exist + */ + int isnotes(String element){ //teste si element est une note et renvoie alors son numéro sinon renvoie -1 + for (int i=0;i<notes.length;i++){ + if (notes[i].equals(element)) return i; + } + return -1; + } + + // These are some MIDI constants from the spec. They aren't defined + public static final int END_OF_TRACK = 47; +/** + * Play the Track + */ + public void joue(){ + if (null!=track){ + try{ + // Set up the Sequencer and Synthesizer objects + sequencer = MidiSystem.getSequencer( ); + sequencer.open( ); + synthesizer = MidiSystem.getSynthesizer( ); + synthesizer.open( ); + sequencer.getTransmitter( ).setReceiver(synthesizer.getReceiver( )); + // Specify the sequence to play, and the tempo to play it at + sequencer.setSequence(sequence); + sequencer.setTempoInBPM(240); + // Let us know when it is done playing + sequencer.addMetaEventListener(new MetaEventListener( ) { + public void meta(MetaMessage m) { + // A message of this type is automatically sent + // when we reach the end of the track + if (m.getType( ) == END_OF_TRACK) { + sequencer.close(); + synthesizer.close(); + } + } + }); + // And start playing now. + sequencer.start( ); + try{ + long temps=sequence.getTickLength(); + while (temps>0){ //On attends que la séquence soit jouée. + Thread.sleep(500); + temps-=32; + if (cadre.error) { //Marko: LogoError.lance && TODO lance was always false : check this + //On a appuyé sur le bouton stop + sequencer.close(); + synthesizer.close(); + break; + } + } + } + catch (InterruptedException e){} + } + catch(MidiUnavailableException e1){} + catch(InvalidMidiDataException e2){} + } + } + /** + * Delete the sequence in memory + */ + public void efface_sequence(){ + try{ + sequence=new Sequence(Sequence.PPQ,16); + track=null; + ticks=0; + } + catch(InvalidMidiDataException e){} + + + } + /** + * set tick index + * @param i + */ + public void setTicks(int i){ + ticks=i; + } + /** + * return tick index + * @return Tick index + */ + public int getTicks(){ + return ticks; + } + + /** + * A convenience method to add a note to the track on channel 0 + * @param startTick the starting tick + * @param tickLength the tick length + * @param key the note + * @param velocity the volume + * @throws InvalidMidiDataException + */ + + public void addNote(int startTick, + int tickLength, int key, int velocity) + throws InvalidMidiDataException + { + ShortMessage on = new ShortMessage( ); + on.setMessage(ShortMessage.NOTE_ON, 0, key, velocity); + ShortMessage off = new ShortMessage( ); + off.setMessage(ShortMessage.NOTE_OFF, 0, key, velocity); + track.add(new MidiEvent(on, startTick)); + track.add(new MidiEvent(off, startTick + tickLength)); + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/StyledDocument/DocumentLogo.java b/logo/src/xlogo/StyledDocument/DocumentLogo.java new file mode 100644 index 0000000..4fc0cc7 --- /dev/null +++ b/logo/src/xlogo/StyledDocument/DocumentLogo.java @@ -0,0 +1,390 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */package xlogo.StyledDocument; + +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultStyledDocument; + +import java.awt.*; + +import javax.swing.text.*; + +import xlogo.kernel.Primitive; +import xlogo.storage.WSManager; +import xlogo.storage.workspace.WorkspaceConfig; + +/** + * Title : XLogo Description : XLogo is an interpreter for the Logo programming + * language + * + * @author Loïc Le Coq + */ + +/* + * Cette classe permet de définir la coloration syntaxique dans l'éditeur + * Coloration des primitives Coloration des nombres, variables ou mot Coloration + * des commentaires Correspondance entre parenthèses ou crochets + */ +public class DocumentLogo extends DefaultStyledDocument { + private static final long serialVersionUID = 1L; + private DefaultStyledDocument doc; + private Element rootElement; + + private MutableAttributeSet parenthese; + private MutableAttributeSet normal; + private MutableAttributeSet keyword; + private MutableAttributeSet comment; + private MutableAttributeSet quote; + private boolean coloration_activee = WSManager.getWorkspaceConfig().isSyntaxHighlightingEnabled(); + private boolean colore_parenthese = false; + + public void setColoration(boolean b) { + coloration_activee = b; + } + + public DocumentLogo() { + WorkspaceConfig uc = WSManager.getWorkspaceConfig(); + + doc = this; + rootElement = doc.getDefaultRootElement(); + putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n"); + initStyles(uc.getCommentColor(), uc.getCommentStyle(), + uc.getPrimitiveColor(), uc.getPrimitiveStyle(), + uc.getBraceColor(), uc.getBraceStyle(), + uc.getOperatorColor(), uc.getOperatorStyle()); + } + + public void initStyles(int c_comment, int sty_comment, int c_primitive, + int sty_primitive, int c_parenthese, int sty_parenthese, + int c_operande, int sty_operande) { + Font font = WSManager.getWorkspaceConfig().getFont(); + + normal = new SimpleAttributeSet(); + StyleConstants.setFontFamily(normal, font.getFamily()); + StyleConstants.setForeground(normal, Color.black); + StyleConstants.setFontSize(normal, font.getSize()); + + comment = new SimpleAttributeSet(); + StyleConstants.setForeground(comment, new Color(c_comment)); + setBoldItalic(sty_comment, comment); + StyleConstants.setFontSize(comment, font.getSize()); + + keyword = new SimpleAttributeSet(); + StyleConstants.setForeground(keyword, new Color(c_primitive)); + setBoldItalic(sty_primitive, keyword); + StyleConstants.setFontSize(keyword, font.getSize()); + + quote = new SimpleAttributeSet(); + StyleConstants.setForeground(quote, new Color(c_operande)); + setBoldItalic(sty_operande, quote); + StyleConstants.setFontSize(quote, font.getSize()); + + parenthese = new SimpleAttributeSet(); + StyleConstants.setForeground(parenthese, new Color(c_parenthese)); + setBoldItalic(sty_parenthese, parenthese); + StyleConstants.setFontSize(parenthese, font.getSize()); + } + + void setBoldItalic(int id, MutableAttributeSet sty) { + switch (id) { + case 0: // aucun style + StyleConstants.setBold(sty, false); + StyleConstants.setItalic(sty, false); + StyleConstants.setUnderline(sty, false); + break; + case 1: // Gras + StyleConstants.setItalic(sty, false); + StyleConstants.setBold(sty, true); + StyleConstants.setUnderline(sty, false); + break; + case 2: // italique + StyleConstants.setBold(sty, false); + StyleConstants.setItalic(sty, true); + StyleConstants.setUnderline(sty, false); + break; + case 3: // Souligné + StyleConstants.setBold(sty, false); + StyleConstants.setItalic(sty, false); + StyleConstants.setUnderline(sty, true); + break; + } + + } + + /* + * Override to apply syntax highlighting after the document has been updated + */ + public void insertString(int offset, String str, AttributeSet a) + throws BadLocationException { + if (str.equals("\t")) + str = " "; + else if (str.equals("[")) { + if (offset > 0) { + String element = doc.getText(offset - 1, 1); + if (!element.equals(" ") && !element.equals("\\")) + str = " ["; + } + } else if (str.equals("(")) { + if (offset > 0) { + String element = doc.getText(offset - 1, 1); + if ("\\ *-+/&|><=(".indexOf(element) == -1) + str = " ("; + } + } + super.insertString(offset, str, a); + if (coloration_activee) + processChangedLines(offset, str.length()); + } + + /* + * Override to apply syntax highlighting after the document has been updated + */ + public void remove(int offset, int length) throws BadLocationException { + /* + * if (getText(offset+length-1,1).equals(" ")){ + * if(getLength()>offset+length) { String + * element=getText(offset+length,1); if (element.equals("[")) length--; + * } } + */ + super.remove(offset, length); + + if (coloration_activee) + processChangedLines(offset, 0); + } + + /* + * Determine how many lines have been changed, then apply highlighting to + * each line + */ + public void processChangedLines(int offset, int length) + throws BadLocationException { + String content = doc.getText(0, doc.getLength()); + + // The lines affected by the latest document update + + int startLine = rootElement.getElementIndex(offset); + int endLine = rootElement.getElementIndex(offset + length); + + // Do the actual highlighting + + for (int i = startLine; i <= endLine; i++) { + applyHighlighting(content, i); + } + } + + /* + * Parse the line to determine the appropriate highlighting + */ + private void applyHighlighting(String content, int line) + throws BadLocationException { + int startOffset = rootElement.getElement(line).getStartOffset(); + int endOffset = rootElement.getElement(line).getEndOffset() - 1; + int lineLength = endOffset - startOffset; + int contentLength = content.length(); + + if (endOffset > contentLength) + endOffset = contentLength - 1; + + // set normal attributes for the line + + doc.setCharacterAttributes(startOffset, lineLength, normal, true); + + // check for single line comment + // On enlève les éventuels commentaires + int index = content.indexOf(getSingleLineDelimiter(), startOffset); + while (index != -1) { + if (index == 0) { + break; + } else if (!content.substring(index - 1, index).equals("\\")) { + break; + } + index = content.indexOf(getSingleLineDelimiter(), index + 1); + } + + if ((index > -1) && (index < endOffset)) { + doc.setCharacterAttributes(index, endOffset - index + 1, comment, + false); + endOffset = index - 1; + } + + // check for tokens + colore(content, startOffset, endOffset); + } + + protected boolean isOperator(char character) { + String operands = "+-/*<=>&|"; + + if (operands.indexOf(character) != -1) + return true; + else + return false; + } + + /* + * Override for other languages + */ + protected boolean isKeyword(String token) { + token = token.toLowerCase(); + return Primitive.primitives.containsKey(token); + } + + protected String getSingleLineDelimiter() { + return "#"; + } + + public void Montre_Parenthese(int offset) { + doc.setCharacterAttributes(offset, 1, parenthese, false); + } + + public void setColore_Parenthese(boolean b) { + colore_parenthese = b; + } + + public void colore(String content, int startOffset, int endOffset) { + int debut = startOffset; + boolean nouveau_mot = true; + boolean backslash = false; + boolean mot = false; + boolean variable = false; + for (int i = startOffset; i < endOffset; i++) { + try { // Sometimes, Exception happens on next line + char c = content.charAt(i); + if (c == ' ' || c == '(' || c == ')' || c == '[' || c == ']') { + if (!backslash) { + String element = content.substring(debut, i); + if (mot) { + doc.setCharacterAttributes(debut, i - debut, quote, + false); + } else if (variable) { + doc.setCharacterAttributes(debut, i - debut, quote, + false); + } else if (isKeyword(element)) { + doc.setCharacterAttributes(debut, i - debut, + keyword, false); + } else + try { + Double.parseDouble(element); + doc.setCharacterAttributes(debut, i - debut, + quote, false); + } catch (NumberFormatException e) { + } + mot = false; + variable = false; + debut = i + 1; + nouveau_mot = true; + if (c != ' ') { + if (colore_parenthese) + doc.setCharacterAttributes(i, 1, parenthese, + false); + else { + doc.setCharacterAttributes(i, 1, normal, false); + // System.out.println(i+" normal "+StyleConstants.getFontFamily(normal)+" "+StyleConstants.isBold(normal)); + } + } + } + backslash = false; + } else if (nouveau_mot) { + if (c == '\"') { + mot = true; + backslash = false; + nouveau_mot = false; + } else if (c == ':') { + variable = true; + backslash = false; + nouveau_mot = false; + } else if (isOperator(c)) { + backslash = false; + mot = false; + variable = false; + nouveau_mot = true; + debut = i + 1; + doc.setCharacterAttributes(i, 1, keyword, false); + } else + nouveau_mot = false; + } else if (c == '\\') { + if (!backslash) { + backslash = true; + } else + backslash = false; + nouveau_mot = false; + } else if (isOperator(c)) { + if (!mot) { + String element = content.substring(debut, i); + if (variable) + doc.setCharacterAttributes(debut, i - debut, quote, + false); + else if (isKeyword(element)) + doc.setCharacterAttributes(debut, i - debut, + keyword, false); + else + try { + Double.parseDouble(element); + doc.setCharacterAttributes(debut, i - debut, + quote, false); + } catch (NumberFormatException e) { + } + backslash = false; + mot = false; + variable = false; + nouveau_mot = true; + debut = i + 1; + doc.setCharacterAttributes(i, 1, keyword, false); + } + } + } catch (StringIndexOutOfBoundsException e22) { + } + } + if (!nouveau_mot) { + String element = content.substring(debut, endOffset); + if (mot) { + doc.setCharacterAttributes(debut, endOffset - debut, quote, + false); + } else if (variable) { + doc.setCharacterAttributes(debut, endOffset - debut, quote, + false); + } else if (isKeyword(element)) { + doc.setCharacterAttributes(debut, endOffset - debut, keyword, + false); + } else + try { + Double.parseDouble(element); + doc.setCharacterAttributes(debut, endOffset - debut, quote, + false); + } catch (NumberFormatException e) { + } + } + + } + + public void insertStyleNormal(int offset, String str, AttributeSet a) { + try { + super.insertString(offset, str, a); + } catch (BadLocationException e) { + } + } +} diff --git a/logo/src/xlogo/StyledDocument/DocumentLogoCommande.java b/logo/src/xlogo/StyledDocument/DocumentLogoCommande.java new file mode 100644 index 0000000..f0a9efa --- /dev/null +++ b/logo/src/xlogo/StyledDocument/DocumentLogoCommande.java @@ -0,0 +1,62 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */package xlogo.StyledDocument; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import java.util.*; +import xlogo.Application; +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ + +public class DocumentLogoCommande extends DocumentLogo { + private static final long serialVersionUID = 1L; + private Application cadre; + public DocumentLogoCommande(Application cadre) { + super(); + this.cadre=cadre; + } + public void insertString(int offset, String str, AttributeSet a) throws BadLocationException + { + StringBuffer buffer=new StringBuffer(); + StringTokenizer st=new StringTokenizer(str,"\n"); + while(st.hasMoreTokens()){ + buffer.append(st.nextToken()); + } + if (str.equals("\n")){ + cadre.commande_actionPerformed(); + + } + else { + str=new String(buffer); + super.insertString(offset, str, a); + } + } +} diff --git a/logo/src/xlogo/StyledDocument/DocumentLogoHistorique.java b/logo/src/xlogo/StyledDocument/DocumentLogoHistorique.java new file mode 100644 index 0000000..7dc4e37 --- /dev/null +++ b/logo/src/xlogo/StyledDocument/DocumentLogoHistorique.java @@ -0,0 +1,170 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */package xlogo.StyledDocument; +import java.awt.Color; +import java.awt.Font; + +import javax.swing.text.*; + +import xlogo.gui.HistoryPanel; +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ + +public class DocumentLogoHistorique extends DocumentLogo { + private static final long serialVersionUID = 1L; + private Color couleur_texte = Color.BLUE; + private int taille_texte = 12; + private String style="normal"; + private MutableAttributeSet normal; + private MutableAttributeSet erreur; + private MutableAttributeSet commentaire; + private MutableAttributeSet perso; + private boolean tape=false; + public DocumentLogoHistorique() { + super(); + + Font font = WSManager.getWorkspaceConfig().getFont(); + + //Style normal + normal = new SimpleAttributeSet(); + StyleConstants.setFontSize(normal, font.getSize()); + StyleConstants.setFontFamily(normal, font.getName()); + + // Style pour l'écriture des erreurs + erreur = new SimpleAttributeSet(); + StyleConstants.setForeground(erreur, Color.RED); + StyleConstants.setFontSize(erreur, font.getSize()); + StyleConstants.setFontFamily(erreur, font.getName()); + + //Style pour les commentaires (Vous venez de définir ...) + commentaire = new SimpleAttributeSet(); + StyleConstants.setForeground(commentaire, Color.BLUE); + StyleConstants.setFontSize(commentaire, font.getSize()); + StyleConstants.setFontFamily(commentaire, font.getName()); + + // Style pour la primitive écris et la primitive tape + perso = new SimpleAttributeSet(); + StyleConstants.setForeground(perso, Color.BLACK); + StyleConstants.setFontFamily(perso, font.getName()); + + + } + public void setStyle(String sty){ + style=sty; + } + public Color getCouleurtexte() { + return couleur_texte; + } + + public int police() { + return taille_texte; + } + public void fixecouleur(Color color) { + couleur_texte = color; + StyleConstants.setForeground(perso, couleur_texte); + } + public void fixepolice(int taille) { + taille_texte = taille; + StyleConstants.setFontSize(perso, taille_texte); + } + public void fixenompolice(int id) { + StyleConstants.setFontFamily(perso, + GlobalConfig.fonts[HistoryPanel.fontPrint].getName()); + } + public void fixegras(boolean b){ + StyleConstants.setBold(perso,b); + } + public void fixeitalique(boolean b){ + StyleConstants.setItalic(perso,b); + } + public void fixesouligne(boolean b){ + StyleConstants.setUnderline(perso,b); + } + public void fixeexposant(boolean b){ + StyleConstants.setSuperscript(perso,b); + } + public void fixeindice(boolean b){ + StyleConstants.setSubscript(perso,b); + } + public void fixebarre(boolean b){ + StyleConstants.setStrikeThrough(perso,b); + } + public boolean estgras(){ + return StyleConstants.isBold(perso); + } + public boolean estitalique(){ + return StyleConstants.isItalic(perso); + } + public boolean estsouligne(){ + return StyleConstants.isUnderline(perso); + } + public boolean estexposant(){ + return StyleConstants.isSuperscript(perso); + } + public boolean estindice(){ + return StyleConstants.isSubscript(perso); + } + public boolean estbarre(){ + return StyleConstants.isStrikeThrough(perso); + } + public Font getFont(){ + return GlobalConfig.fonts[HistoryPanel.fontPrint].deriveFont(Font.BOLD,(float)taille_texte); + + } + public void change_police_interface(Font font, int taille) { + + String famille = font.getName(); + + StyleConstants.setFontSize(normal, taille); + StyleConstants.setFontFamily(normal, famille); + + StyleConstants.setFontSize(commentaire, taille); + StyleConstants.setFontFamily(commentaire, famille); + + StyleConstants.setFontSize(erreur, taille); + StyleConstants.setFontFamily(erreur, famille); + } + public void insertString(int offset, String str, AttributeSet a) throws BadLocationException + { + if (tape) { + tape=false; + super.insertStyleNormal(offset,str,a); + } + else super.insertString( offset, str, a); + if (style.equals("erreur")) this.setCharacterAttributes(offset,str.length(),erreur,true); + else if (style.equals("commentaire")) this.setCharacterAttributes(offset,str.length(),commentaire,true); + else if (style.equals("perso")) this.setCharacterAttributes(offset,str.length(),perso,true); + if (!str.endsWith("\n")) tape=true; + } + +}
\ No newline at end of file diff --git a/logo/src/xlogo/gpl/gpl-ar.html b/logo/src/xlogo/gpl/gpl-ar.html new file mode 100644 index 0000000..10ee645 --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-ar.html @@ -0,0 +1,376 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ar" + dir="rtl" lang="ar"> +<head> + <title>الرخصة المشاعة العامة لجنيو</title> + <link rev="made" href="mailto:[email protected]" /> + <meta http-equiv="Content-Type" + content="text/html; charset=UTF-8" /> + <meta name="author" content="Khaled Shagrouni" /> + <meta name="description" + content="الترجمة العربية للرخصة المشاعة العامة لجنيو" /> + <meta name="keywords" + content="رخصة، ترخيص، اتفاقية، استخدام، ملكية، برمجيات" /> + <meta content="Software Devolepment" + name="document-classification" /> + <link href="gpl.ar_fichiers/ni.css" type="text/css" + rel="stylesheet" /> +</head> +<body> +<table style="width: 801px; height: 92.38%;" border="0" + cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td style="height: 200px;" colspan="2" + valign="top"> <a + href="http://www.nidam.net/sd/index.html"><br /> + </a> + <table id="TABLE1" style="width: 100%;" + border="0" cellpadding="0" cellspacing="0"> + <tbody> + <tr bgcolor="#ffcc99"> + <td style="height: 2px;"> </td> + </tr> + <tr> + <td style="height: 4px;"> </td> + </tr> + <tr> + <td> </td> + </tr> + </tbody> + </table> + <table id="TABLE2" style="width: 100%; height: 93.03%;" + border="0" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td style="width: 20px;" colspan="1"> </td> + <td + style="width: 493px; background-color: rgb(255, 255, 255);" + colspan="1" valign="top"> + <p> <em>هذه ترجمة غير رسمية من الرخصة المشاعة +العامة ل جنيو إلى العربية. لم يتم إصدارها من قبل مؤسسة البرمجيات الحرة، +و لا تعبر قانونيا عن أحكام التوزيع للبرمجيات التي تستخدم الرخصة المشاعة +العامة لجنيو - فقط النصّ الإنكليزي الأصلي للرخصة المشاعة العامة لجنيو +تفعل هذا. إلا أننا نأمل أن هذه الترجمة سوف تعين متكلمي العربية على فهم +أفضل للرخصة المشاعة العامة لجنيو.</em> </p> + <div dir="ltr"> + <p class="PTitle"> <em>This is an +unofficial translation of the GNU General Public License into Arabic. +It was not published by the Free Software Foundation, and does not +legally state the distribution terms for software that uses the GNU +GPL--only the original English text of the GNU GPL does that. However, +we hope that this translation will help Arabic speakers understand the +GNU GPL better.</em><br /> + </p> + </div> + <img alt="" src="gpl.ar_fichiers/greydot.gif" + height="1" width="375" /><!-- Srart--> + <h3>جدول المحتويات </h3> + <ul> + <li> <a href="#SEC1" name="TOC1">الرخصة +المشاعة العامة ل ج ن يو</a> + <ul> + <li> <a href="#SEC2" name="TOC2">تمهيد</a> + </li> + <li> <a href="#SEC3" name="TOC3">أحكام +و شروط النسخ و التوزيع و التحوير</a> </li> + <li> <a href="#SEC4" name="TOC4">كيف +تطبق هذه الأحكام على برامجك الجديدة</a> </li> + </ul> + </li> + </ul> + <h3><a href="#TOC1" name="SEC1">الرخصة +المشاعة العامة ل ج ن يو</a> </h3> + <p> نسخة 2، يونيو 1991 </p> + <pre>حقوق النسخ محفوظة (C) 1989، 1991 مؤسسة البرمجيات الحرة المساهمة<br /> +51 شارع فرانكلين، الطابق الخامس، بوسطن، م أ 02110-1301،<br /> +الولايات المتحدة الأمريكية<br /> +لكل فرد الحق في نسخ و توزيع نُسخ حرفية لوثيقة الرخصة هذه،و لكن تغييرها<br /> +غبر مسموح به.</pre> + <h3><a href="#TOC2" name="SEC2">تمهيد</a> + </h3> + <p> الرُخص لمعظم البرمجيات مصممة لكي تنزع عنك حرية +تقاسمها و تغييرها. بالمقابل، فإن الرخصة المشاعة العامة ل ج ن يو أعدت +لضمان حريتك في تقاسم وتغيير البرمجيات الحرة - لتأكيد أن البرمجية حرة +ومجانية لكل مستخدميها. الرخصة المشاعة العامة تنطبق على معظم برمجيات +مؤسسة البرمجيات الحرة و على كل برنامج آخر التزم مؤلفوه باستخدامها. (بعض +برامج مؤسسة البرامج الحرة الأخرى محمية بالرخصة المشاعة العامة المخففة.) +يمكنك تطبيقها على برامجك أيضا. </p> + <p> عندما نتكلم عن البرمجيات الحرة، فنحن نشير إلى +الحرية وليس الثمن. رخصتنا المشاعة العامة قد صممت لتأكيد أن لديك الحرية +لتوزيع نسخ من البرمجيات الحرّة (و تطلب مقابلا لخدماتك إذا رغبت)، وأنك +قد استلمت التوليف المصدري أو انك تستطيع الحصول عليه إن أردت، أنه +بإمكانك تغيير البرمجية أو أن تستخدم أجزاء منها في برامج حرة جديدة؛ وأنك +تعلم أنه بإمكانك القيام بهذه الأمور. </p> + <p> من أجل حماية حقوقك، نحتاج لوضع قيود تمنع أي أحد +من حجبك هذه الحقوق أو أن يطلب منك التنازل عن الحقوق. هذه القيود تُترجم +إلى مسؤوليات محددة تقع عليك إذا ما قمت بتوزيع نسخ من البرمجية، أو إذا +قمت بتحويرها. </p> + <p> مثال ذلك، إذا قمت بتوزيع نسخ من برنامج كهذه، +مجانا كان أو بمقابل، يجب أن تعطى المستلمين كل الحقوق التي لديك. يجب +عليك التأكد من أنهم أيضا يستلمون أو بإمكانهم الحصول على التوليف +المصدري. و يجب أن تريهم هذه الأحكام حتى يعلموا حقوقهم. </p> + <p> نحن نحمي حقوقك على خطوتين: (1) إسباغ حق النشر +والطبع على البرمجية، و (2) منحك هذه الرخصة التي تعطيك إذنا قانونيا لنسخ +و توزيع و/أو تحوير البرمجية. </p> + <p> أيضا، ومن أجل حماية المؤلف وحمايتنا، نريد أن يكون +واضحا بأن كل شخص يدرك بأنه لا توجد ضمانة لهذه البرمجية الحرة. إذا تم +تحوير البرمجية من قبل شخص آخر ومرّرها، نريد من مستلميها أن يعلموا بأن +ما لديهم ليست الأصلية، وبذلك فإن أية مشاكل يسببها آخرون سوف لن تنعكس +على سمعة المؤلفين الأصليين. </p> + <p> أخيرا، أي برنامج مجاني مهدد دائما من قبل براءات +اختراع البرمجيات. نحن نرجو أن نتجنب خطورة أن معيدي توزيع البرامج الحرة +سيتحصلون شخصيا على رخص لبراءات اختراع، ينتج عنها جعل البرنامج ملكية +مقيدة. لمنع هذا، جعلنا الأمر واضحا بأن كل براءة اختراع يجب أن تُرخّص +للاستخدام الحر لكل شخص أو أن لا ترخص بتاتا. </p> + <p> تفصيل أحكام وشروط النسخ و التوزيع و التحوير كما +يلي: </p> + <h3><a href="#TOC3" name="SEC3">نصوص +و شروط النسخ و التوزيع و التحوير</a> </h3> + <p> <strong>0.</strong> هذه الرخصة تسري +على أي برنامج أو عمل آخر يحتوي على إشعار يضعه حامل حقوق الطبع قائلا فيه +بأنه بالإمكان توزيعه تحت أحكام الرخصة المشاعة العامة هذه. كلمة +"برنامج"، أدناه، تشير إلى برنامج أو عمل، و "عمل مبني على برنامج" يعني +إما البرنامج أو أي عمل مشتق منه ويكون تحت طائلة قانون حقوق الطبع: أي +أنه، عمل يحتوي على برنامج أو قسم منه، سواء كان حرفيا أو محوّرا و/أو +مترجما إلى لغة أخرى. (من هنا فصاعدا، الترجمة متضمنة وبدون حدود في +المصطلح "تحوير".) كل مرّخص له/لها يشار إليه بـ "أنت". </p> + <p> النشاطات الأخرى غير النسخ و التوزيع و التحوير لا +تغطيها هذه الرخصة؛ وخارج نطاقها. فعل تشغيل البرنامج غير مقيد، ومخرجات +البرنامج مغطّاة فقط إذا كانت محتوياتها تشكل عملا مبنيا على البرنامج +(مستقلا أو قد تم صنعه بتشغيل البرنامج). حقيقة هذا تعتمد على ما يقوم به +البرنامج. </p> + <p> <strong>1.</strong> أنت بإمكانك نسخ +و توزيع نسخا حرفية من التوليف الأصلي للبرنامج كما استلمته. في أي وسيط، +شرط أن تنشر بوضوح وعناية على كل نسخة بشكل ملائم إشعار حقوق الطبع +والتنصل من الضمان؛ وأن تبقيها سليمة كل الإشعارات التي تشير لهذه الرخصة +و تشير لانتفاء أي ضمان. و أن تُعطي أي مستلم آخر للبرنامج نسخة من هذه +الرخصة رفق البرنامج. </p> + <p> أنت بإمكانك أن تتقاضى أجرا مقابل الفعل المادي +لنقل النسخة، و أنت بإمكانك حسب اختيارك أن تُعطي تعهدا بالضمان مقابل +أجر. </p> + <p> <strong>2.</strong> أنت بإمكانك +تحوير نسختك أو نسخك من البرنامج أو أي جزء منه، فيكون عملا مبينا على +البرنامج، و تنسخ و توزع هذه التحويرات أو العمل تحت أحكام القسم 1 أعلاه، +بشرط أنك أيضا تلبي كل الشروط أدناه: </p> + <dl> + <dd> <strong>أ)</strong> يجب أن تجعل +من الملفات المحوّرة تحمل إشعارات صريحة تفيد بأنك قد غيّرت الملفات و +التاريخ لأي تغيير. </dd> + <dd> <strong>ب)</strong> يجب أن تجعل +من أي عمل تقوم بتوزيعه أو نشره، الذي بكامله أو في قسم منه يحوي أو مشتق +من البرنامج أو أي قسم منه، يكون مرخّصا ككل بدون مقابل لكل الأطراف +الثالثة تحت أحكام هذه الرخصة. </dd> + <dd> <strong>ج)</strong> إذا كان +البرنامج المحوّر يقرأ الأوامر عادة بصورة تفاعلية عند تشغيله، يجب أن +تجعله، عند بدئه التشغيل لمثل هذا الاستعمال التفاعلي و بأكثر الطرق +اعتيادية، كي يطبع أو يُظهر إشعار حقوق الطبع وإشعار أنه لا توجد ضمانة +(أو أخرى، تفيد بأنك تُعطي ضمانا) و أن المستخدمين يمكنهم إعادة توزيع +البرنامج تحت هذه الشروط، وأن ترشد المستخدم لكيفية الاطلاع على نسخة من +هذه الرخصة. (استثناء: إذا كان البرنامج ذاته تفاعليا و لكن لا يقوم عادة +بطبع إعلان كهذا، عملك المبني على البرنامج لا يتطلب طباعة إعلان.) </dd> + </dl> + <p> هذه المقتضيات تسري على العمل المحوّر ككل. إذا +وجدت أقسام بعينها من العمل ليست مشتقة من البرنامج، و يمكن منطقيا +اعتبارها مستقلة وعملا منفصل في ذاتها، فإن هذه الرخصة، و أحكامها، لا +تسري على تلك الأقسام عند توزيعك لها كأعمال منفصلة. لكن عند توزيعك لنفس +الأقسام كجزء من كل والتي تكون عملا مبنيا على البرنامج، فإن توزيع الكل +يجب أن يكون وفق أحكام هذه الرخصة، حيث السماح للمرخصين لهم الآخرين يمتد +لكامل المجمل، و بالتالي لكل جزء بعينه بغض النظر عن من كتبه. </p> + <p> بالتالي، ليس من نية هذا القسم إدعاء حقوق أو +منازعة حقوقك في عمل كُتِب بالكامل من قبلك؛ ولكن، النية هي في ممارسة +الحق في السيطرة على توزيع أعمال مشتقة أو مجمعة بالتأسيس على البرنامج. </p> + <p> بالإضافة، مجرّد الضمّ لعمل آخر ليس +مؤسسا على البرنامج مع البرنامج (أو مع عمل مؤسس على البرنامج) في حيز +التخزين أو التوزيع لا يدخل العمل الآخر في نطاق هذه الرخصة. </p> + <p> <strong>3.</strong> أنت بإمكانك نسخ +و توزيع البرنامج (أو عمل مؤسس عليه، تحت القسم 2) كتوليف كائني أو في +صيغة تنفيذية تحت أحكام الأقسام 1 و 2 أعلاه بشرط أنك أيضا تقوم بواحدة +مما يلي: </p> + <dl> + <dd> <strong>أ)</strong> إرفاقه بما +يناظره كاملا من توليف مصدري مقروء_بالآلة، و الذي يجب أن يُوزّع تحت +أحكام القسم 1 و 2 أعلاه في وسط مُستخدم عادة لتبادل البرمجيات؛ أو، </dd> + <dd> <strong>ب)</strong> إرفاقه مع عرض +مكتوب، صالح لثلاثة سنوات على الأقل، لإعطاء أي طرف ثالث، بمقابل لا يزيد +عن تكلفتك للأداء المادي لتوزيع المصدر، نسخة مقروءة_بالآلة كاملة من ما +يناظره من توليف مصدري، لتوزيعها تحت أحكام الأقسام 1 و 2 أعلاه في وسط +مُستخدم عادة لتبادل البرمجيات؛ أو، </dd> + <dd> <strong>ج)</strong> إرفاقه مع +المعلومات التي تسلّمتها كعرض من أجل توزيع ما يناظره من التوليف المصدري. +(هذا البديل مسموح به فقط للتوزيع غير التجاري و فقط إذا استلمت البرنامج +كتوليف كائني أو كصيغة تنفيذية مع العرض، طبقا للقسم الفرعي ب أعلاه.) </dd> + </dl> + <p> يقصد بالتوليف المصدري للعمل الشكل المفضل للعمل +لإجراء التحويرات فيه. بالنسبة للعمل التنفيذي، يُقصد بالتوليف المصدري +الكامل كل التوليف المصدري لكافة القوالب التي يحويها، إضافة لأية ملفات +مصاحبة لتعريف الواجهات، إضافة لنصوص التعليمات المستخدمة للتحكم في ترجمة +و تثبيت التنفيذيات. عموما، و كاستثناء خاص، التوليف المصدري الموزع لا +يحتاج أن يضمن أي شيء يكون عادة موزعا (في صيغة مصدرية أو ثنائية) مع +المكونات الرئيسية (مخرّج"محول"، نواة، و ما إلى ذلك) لنظام التشغيل الذي +يعمل التنفيذي فيه، ما لم تكن المكونات نفسها مرافقة للتنفيذي. </p> + <p> إذا كان توزيع التنفيذي أو التوليف الكائني +قد أتيح بتقديم مدخل للنسخ من مكان محدد، عندها فإن تقديم مدخل +مكافئ لنسخ التوليف المصدري من نفس المكان يتم احتسابه كتوزيع للتوليف +المصدري، حتى لو لم تشدّد أطراف ثالثة على نسخ المصدر مع التوليف الكائني. + </p> + <p> <strong>4.</strong> أنت لا يمكنك أن +تنسخ أو تحوّر أو ترخّص مفرعا أو توزع البرنامج إلا بالكيفية التي عُبر +عنها بجلاء تحت هذه الرخصة. أية محاولة أخرى لنسخ أو لتحوير أو لترخيص +مفرع أو لتوزيع البرنامج يُعد باطلا، و يُنهي آليا حقوقك تحت هذه الرخصة. +إلا أن الأطراف الذين استلموا نُسخا، أو حقوقا منك وفق هذه الرخصة سوف لن +تكون رخصهم منتهية طالما بقوا على التزام كامل. </p> + <p> <strong>5.</strong> أنت +لست مطالبا بالقبول بهذه الرخصة، ما دمت لم توقع عليها. ومع ذلك، لاشيء +آخر يضمن لك الإذن بتحوير أو توزيع البرنامج أو الأعمال المشتقة منه. + هذه الأفعال ممنوعة بالقانون إن لم تقبل بهذه الرخصة. لهذا، +بتحوير أو توزيع هذا البرنامج (أو أي عمل مؤسس على البرنامج)، فأنت تدل +على قبولك لهذه الرخصة بهذا الفعل، وبكل نصوصها و شروطها لنسخ أو توزيع أو +تحوير البرنامج أو الأعمال المؤسسة عليه. </p> + <p> <strong>6.</strong> كل مرّة تقوم +فيها بإعادة توزيع البرنامج (أو أي عمل مؤسس على البرنامج)، يتسلّم +المتلقون آليا رخصة من المرخّص الأصلي لنسخ أو توزيع أو تحوير البرنامج +خاضعة لهذه النصوص و الشروط. أنت لا يمكنك فرض قيود أخرى على ممارسة +المتلقين لحقوقهم المصانة هنا. أنت لست مسؤولا على إجبار أطراف ثالثة +بالالتزام بهذه الرخصة. </p> + <p> <strong>7.</strong> في حالة، كنتيجة +لحكم قضائي أو دعوى لخرق براءة اختراع أو لأي سبب آخر (ليس محصورا في +قضايا براءات الاختراع)، ظروف قد فُرضت عليك (سواء بحكم محكمة أو باتفاقية +أو بغيرها) من شأنها أن تعارض شروط هذه الرخصة، فإنها لا تعفيك من شروط +هذه الرخصة. إذا لم تستطع التوزيع بكيفية تلبي معا التزاماتك تحت هذه +الرخصة و أية التزامات أخرى ذات علاقة، عندها و نتيجة لذلك لا يمكنك توزيع +البرنامج مطلقا. مثال ذلك، إذا رخصة براءة الاختراع لن تسمح بإعادة توزيع +مجانية للبرنامج من قبل كل أولائك الذين استلموا نسخا بصورة مباشرة أو غير +مباشرة من خلالك، فإن الوسيلة الوحيدة لتلبيتك لها و لهذه الرخصة ستكون +بالتغاضي كليا عن توزيع البرنامج. </p> + <p> في حالة أن جزءا من هذا القسم لا يسري أو غير قابل +للفرض تحت ظرف معين، فإن باقي القسم سوف يسري و القسم ككل سوف يسري على +باقي الظروف. </p> + <p> ليس الغرض من هذا القسم دفعك لمخالفة أية براءة +اختراع أو دعاوى حقوق ملكية أخرى أو لمنازعة صلاحية أي من هذه دعاوى؛ هذا +القسم له غرض وحيد لحماية استقامة نظام توزيع البرمجيات الحرة، والتي نفذت +عبر ممارسات الترخيص المشاع. العديد من الناس قدموا إسهامات سخية لمدى +واسع من برمجيات وُزّعت عبر هذا النظام بالاعتماد على ثبات تطبيق هذا +النظام؛ إنه يرجع للمؤلف/المانح ليقرر ما إذا كان أو كانت راغب في توزيع +البرمجية عبر نظام آخر و أن المرخّص له لا يمكنه فرض/اذعان هذا الاختيار. </p> + <p> هذا القسم قُصد به جعله واضحا كلية ما يعتقد أنه +سيكون عواقب بقية هذه الرخصة. </p> + <p> <strong>8.</strong> إذا توزيع و/أو +استخدام البرنامج مقيد في بلدان معينة إما ببراءات اختراع أو بتداخلات ذات +حقوق تأليف، فإن حامل حقوق التأليف الأصلي الذي وضع البرنامج تحت هذه +الرخصة قد يضيف حدود توزيع جغرافية صريحة تستثني تلك البلدان، فيكون ذاك +التوزيع مسموحا فقط في أو عبر البلدان غير المستثناة. في مثل هذه الحالة، +هذه الرخصة تتضمن التقيبد كما لو أنها كتبت في متن هذه الرخصة. </p> + <p> <strong>9.</strong> مؤسسة البرمجيات +الحرة قد تنشر إصدارات معدّلة و/أو جديدة من الرخصة المشاعة العامة من وقت +لآخر. مثل هذه الإصدارات الجديدة ستكون شبيهة في روحها للإصدارة الحالية، +لكن قد تختلف في تفاصيل تتناول مسائل أو اهتمامات جديدة. </p> + <p> كلّ إصدارة تُعطى رقم إصدار مميّز. إذا حدّد +البرنامج رقم إصدارة لهذه الرخصة يتبعها و يتبع "أية إصدارة لاحقة"، يكون +لك الخيار بأن تتبع نصوص و شروط إما تلك الإصدارة أو أية إصدارة لاحقة +تُنشر من قبل مؤسسة البرمجيات الحرة. إذا البرنامج لم يحدد رقم إصدارة +لهذه الرخصة، يمكنك اختيار أية إصدارة تم نشرها من قبل مؤسسة البرمجيات +الحرة. </p> + <p> <strong>10.</strong> إذا أنت رغبت في +تضمين أجزاء من البرنامج في برامج حرة أخرى ذات شروط توزيع مختلفة، خاطب +المؤلف لالتماس الإذن. بالنسبة للبرامج التي ترجع حقوق تأليفها لمؤسسة +البرامج الحرة، كاتب مؤسسة البرامج الحرة؛ نحن أحيانا نضع استثناءات لهذه +الحالة. قرارنا سيكون محكوما بالغايتين الحفاظ على حالة الحرية لكل تفرعات +برامجنا الحرة و الدعوة لمشاركة و إعادة استخدام البرمجيات بصفة +عامة. </p> + <p> <strong>بدون ضمان</strong> </p> + <p> <strong>11.</strong> لأن البرنامج +مرخص بدون مقابل، لا يوجد ضمان على البرنامج، للمدى المسموح به من قبل +القانون الساري. باستثناء أن تكون حالات تبين ذلك كتابة فأن حاملي حقوق +التأليف و/أو الأطراف الأخرى يعرضون البرنامج "كما هو" بدون ضمان من أي +نوع، إما صراحة أو ضمنا، بما في ذلك، ولكن ليس محدودا به، الضمانات +المنطوية الخاصة بالصلاحية السوقية والموائمة لغاية معينة. المخاطرة +بأكملها فيما يخصّ جودة و أداء البرنامج تقع عليك. إذا أثبت البرنامج +قصورا، تتحمل أنت تكلفة كافة ما يلزم من صيانة أو إصلاح أو تقويم. </p> + <p> <strong>12.</strong> ليس تحت أي ظرف +ما لم يتطلبه قانون نافذ أو ما أتفق عليه كتابة سيكون أي مالك لحق +التأليف، أو أي طرف آخر قد حور و/أو أعاد توزيع البرنامج كما سُوغ أعلاه، +مسؤولا أمامك عن أضرار، بما في ذلك أضرار عامة أو خاصة أو عارضة +أو مستتبعة تنشأ عن استخدام أو عدم قدرة على استخدام البرنامج ( بما في +ذلك و لكن ليس محدودا به فقدان بيانات أو بيانات تم تسويتها بطريقة خاطئة + أو خسائر تتكبدها أنت أو أطراف ثالثة أو فشل البرنامج في أن +يعمل مع أي برامج أخرى)، حتى لو أن المالك أو أطراف ثالثة قد تم إعلامهم +باحتمال مثل هذه الأضرار. </p> + <h3>نهاية النصوص و الشروط </h3> + <h3><a href="#TOC4" name="SEC4">كيف +تطبق هذه الأحكام على برامجك الجديدة</a> </h3> + <p> إذا كنت تطوّر برنامجا جديدا، و تريد له أن يحظى +بأكبر استخدام ممكن له للعموم، فإن أفضل طريقة لتحقيق ذلك هي أن تجعله +برنامجا حرّا حيث يمكن لكل واحد أن يعيد توزيعه و يغيّره وفق هذه الأحكام. + </p> + <p> لتحقيق ذلك، قم بإرفاق الإشعارات التالية +بالبرنامج. من الأضمن إرفاقها مع بداية كل ملف مصدري بالطريقة الأكثر +فعالية لتبيان استبعاد الضمان؛ وكل ملف يجب أن يملك على الأقل سطر "حقوق +الطبع" و إشارة لأين يوجد كامل الإشهار. </p> + <pre><var>سطر واحد لتقديم إسم البرنامج و فكرة عن عمله.</var> +<br /> +حقوق الطبع (C) <var>السنة</var> <var>إسم المؤلف</var> +<br /> +هذا البرنامج هو يرمجية حرّة، بإمكانك إعادة توزيعه و/أو تحويره وفق أحكام<br /> +الرخصة المشاعة العامة لجنيو كما أصدرتها مؤسسة البرمجيات الحرة؛إما الإصدارة 2<br /> +من الرخصة، أو (حسب خيارك) أية إصدارة لاحقة. هذا البرنامج يوزع بأمل أن<br /> +يكون نافعا، لكن بدون أية ضمانة، بدون حتى ضمانة<br /> +ضمنية للصلاحية السوقية أو الملائمة لغرض معين. راجع الرخصة المشاعة العامة<br /> +لجنيو لمزيد من التفاصيل.<br /> +من المفترض أن تستلم نسخة من الرخصة المشاعة العامة لجنيو مع هذا البرنامج؛<br /> +إذا لا، كاتب مؤسسة البرمجيات الحرة، 51 شارع فرانكلين، الطابق الخامس،<br /> +بوسطن، م أ 02110-1301، الولايات المتحدة الأمريكية.</pre> + <p> أضف أيضا معلومات عن كيفية الاتصال بك عبر بريدك +الإلكتروني أو الورقي. </p> + <p> إذا كان البرنامج تفاعليا، إجعله يخرج إشعارا قصيرا +مثل هذا حين يبدأ بصورة تفاعلية: </p> + <pre>جينوموفيجن إصدارة 69، حقوق الطبع (C) السنة اسم المؤلف<br /> +جينوموفيجن يأتي قطعيا بلا ضمانة؛ للتفاصيل اطبع 'عرض ض'. هذه برمجية حرة،<br /> +أنت مرحب بك لإعادة توزيعه وفق شروط محددة؛ اطبع 'عرض ش' للتفاصيل.</pre> + <p> الأوامر الافتراضية <samp> 'عرض ض'</samp> +و <samp> 'عرض ش'</samp> يجب أن تظهر ما يتناسب من أجزاء من +الرخصة المشاعة العامة. بالطبع، الأوامر التي تستخدمها قد تسمى بشيء آخر +غير <samp> 'عرض ض'</samp> و <samp> 'عرض ش'</samp>؛ +يمكن أن تكون حتى نقرات فأرة أو بنود قائمة -- أيا كانت ما يناسب برنامجك. + </p> + <p> يجب عليك أيضا أن تجعل رب عملك (إذا كنت تعمل +كمبرمج) أو المدرسة، إذا وجدت، يوقعان "تنازلا عن حقوق الطبع" للبرنامج، +إذا دعت الضرورة. </p> + <p> ها هنا مثال؛ استبدل الأسماء: </p> + <pre>مؤسسة يويوداين المحدودة، بهذا تتنازل عن كل<br /> +مصالح حقوق الطبع في برنامج 'جينوموفيجن'<br /> +(الذي يصنع الاجتيازات عند المجمعات)<br /> +توقيع وع نون، 1 أبريل 1998<br /> +وع نون، رئيس النائب</pre> + <p> الرخصة المشاعة هذه لا تسمح بتضمين برنامجك في +البرامج الممتلكة. إذا كان برنامجك مكتبة إجرائية، قد تراه أكثر نفعا أن +تسمح بربط التطبيقات الممتلكة بالمكتبة. إذا كان هذا ما تريده، استخدم +الرخصة المشاعة العامة المخففة لجنيو بدلا عن هذه الرخصة </p> + <hr /> </td> + <td width="10"> </td> + <td colspan="1" valign="top"> <br /> + <br /> + <br /> + <br /> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + <tr> + <td style="height: 200px;" colspan="2" dir="rtl"> + <table style="width: 100%; height: 6.14%;" border="0" + cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td style="height: 10px;"> </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> +</table> +</body> +</html> diff --git a/logo/src/xlogo/gpl/gpl-de.html b/logo/src/xlogo/gpl/gpl-de.html new file mode 100644 index 0000000..20f33e2 --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-de.html @@ -0,0 +1,767 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <meta content="text/html; charset=ISO-8859-1" + http-equiv="content-type"> + <title>GNU General Public License</title> +</head> +<body> +<div class="main"> +<h1 class="dropshadow"> +<div>GNU General Public License +</div> +</h1> +<p><strong> +Deutsche Übersetzung der Version 2, Juni 1991 +</strong></p> +<p><em> +Den offiziellen englischen Originaltext finden Sie unter +<a href="gpl-en.html">http://www.gnu.org/licenses/gpl.html</a>. +</em></p> +<blockquote> + <p>Diese Übersetzung wurde ursprünglich +erstellt von Katja Lachmann +Übersetzungen im Auftrag der S.u.S.E. GmbH +– <tt>http://www.suse.de</tt>. Sie wurde +überarbeitet von Peter Gerwinski, G-N-U +GmbH – <tt>http://www.g-n-u.de</tt> +(31. Oktober 1996, +4. Juni 2000). </p> + <p>Diese Übersetzung wird mit der Absicht angeboten, +das Verständnis +der <em>GNU General Public License</em> (GNU GPL) zu +erleichtern. +Es handelt sich jedoch nicht um eine offizielle oder im +rechtlichen Sinne anerkannte Übersetzung. </p> + <p>Die <em>Free Software Foundation</em> (FSF) ist +nicht der +Herausgeber dieser Übersetzung, und sie hat diese +Übersetzung +auch nicht als rechtskräftigen Ersatz für die +Original-GNU-GPL +anerkannt. Da die Übersetzung nicht sorgfältig von +Anwälten +überprüft wurde, können die +Übersetzer nicht garantieren, daß die +Übersetzung die rechtlichen Aussagen der GNU GPL exakt +wiedergibt. Wenn Sie sichergehen wollen, daß von Ihnen +geplante +Aktivitäten im Sinne der GNU GPL gestattet sind, halten Sie +sich +bitte an die <a href="gpl-en.html">englischsprachige +Originalversion</a>. </p> + <p>Die Übersetzer und die <em>Free Software +Foundation</em> möchten +Sie darum bitten, diese Übersetzung nicht als offizielle +Lizenzbedingungen für von Ihnen geschriebene Programme zu +verwenden. Bitte benutzen Sie hierfür stattdessen die von der <em>Free +Software Foundation</em> herausgegebene <a href="gpl-en.html">englischsprachige +Originalversion</a>. </p> + <p><em>This is a translation of the GNU General Public +License into +German. This translation is distributed in the hope that it will +facilitate understanding, but it is not an official or legally +approved translation. </em></p> + <p><em>The Free Software Foundation is not the publisher +of this +translation and has not approved it as a legal substitute for the +authentic GNU General Public License. The translation has not +been reviewed carefully by lawyers, and therefore the translator +cannot be sure that it exactly represents the legal meaning of +the GNU General Public License. If you wish to be sure whether +your planned activities are permitted by the GNU General Public +License, please refer to the <a href="gpl-en.html">authentic +English version</a>. </em></p> + <p><em>The translators and the Free Software Foundation +strongly urge +you not to use this translation as the official distribution +terms for your programs; instead, please use the <a + href="gpl-en.html">authentic English version</a> +published by the Free Software Foundation. </em></p> +</blockquote> +<h1 align="center">GNU General Public License</h1> +<p align="center"><strong> +Deutsche Übersetzung der Version 2, Juni 1991 +</strong></p> +<p align="center"><strong> +Copyright © 1989, 1991 Free Software Foundation, Inc.<br> +51 Franklin St, Fifth Floor, Boston, MA 02110, USA +</strong></p> +<p> +Es ist jedermann gestattet, diese Lizenzurkunde zu +vervielfältigen +und unveränderte Kopien zu verbreiten; Änderungen +sind jedoch +nicht erlaubt. +</p> +<p><strong> +Diese Übersetzung ist kein rechtskräftiger Ersatz +für die +<a href="gpl-en.html">englischsprachige +Originalversion</a>! +</strong></p> +<h2>Vorwort</h2> +<p> +Die meisten Softwarelizenzen sind daraufhin entworfen worden, +Ihnen die Freiheit zu nehmen, die Software weiterzugeben und zu +verändern. Im Gegensatz dazu soll Ihnen die <em>GNU +General Public +License</em>, die Allgemeine Öffentliche GNU-Lizenz, +ebendiese +Freiheit garantieren. Sie soll sicherstellen, daß die +Software für +alle Benutzer frei ist. Diese Lizenz gilt für den +Großteil der von +der <em>Free Software Foundation</em> herausgegebenen +Software und +für alle anderen Programme, deren Autoren ihr Werk dieser +Lizenz +unterstellt haben. Auch Sie können diese Möglichkeit +der +Lizenzierung für Ihre Programme anwenden. (Ein anderer Teil +der +Software der <em>Free Software Foundation</em> unterliegt +stattdessen der <em>GNU Lesser General Public License</em>, +der +Kleineren Allgemeinen Öffentlichen GNU-Lizenz.) +</p> +<p> +Die Bezeichnung <em>„freie“ Software</em> +bezieht sich +auf Freiheit, nicht auf den Preis. Unsere Lizenzen sollen Ihnen +die Freiheit garantieren, Kopien freier Software zu verbreiten +(und etwas für diesen Service zu berechnen, wenn Sie +möchten), die +Möglichkeit, die Software im Quelltext zu erhalten oder den +Quelltext auf Wunsch zu bekommen. Die Lizenzen sollen garantieren, +daß Sie die Software ändern oder Teile davon in +neuen freien +Programmen verwenden dürfen – und daß Sie +wissen, daß Sie +dies alles tun dürfen. +</p> +<p> +Um Ihre Rechte zu schützen, müssen wir +Einschränkungen machen, die +es jedem verbieten, Ihnen diese Rechte zu verweigern oder Sie +aufzufordern, auf diese Rechte zu verzichten. Aus diesen +Einschränkungen folgen bestimmte Verantwortlichkeiten +für Sie, +wenn Sie Kopien der Software verbreiten oder sie verändern. +</p> +<p> +Beispielsweise müssen Sie den Empfängern alle Rechte +gewähren, die +Sie selbst haben, wenn Sie – kostenlos oder gegen Bezahlung +– Kopien eines solchen Programms verbreiten. Sie +müssen +sicherstellen, daß auch die Empfänger den Quelltext +erhalten +bzw. erhalten können. Und Sie müssen ihnen +diese Bedingungen +zeigen, damit sie ihre Rechte kennen. +</p> +<p> +Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen +die +Software unter ein Urheberrecht (Copyright), und (2) wir bieten +Ihnen diese Lizenz an, die Ihnen das Recht gibt, die Software zu +vervielfältigen, zu verbreiten und/oder zu verändern. +</p> +<p> +Um die Autoren und uns zu schützen, wollen wir +darüberhinaus +sicherstellen, daß jeder erfährt, daß +für diese freie Software +keinerlei Garantie besteht. Wenn die Software von jemand anderem +modifiziert und weitergegeben wird, möchten wir, daß +die Empfänger +wissen, daß sie nicht das Original erhalten haben, damit +irgendwelche von anderen verursachte Probleme nicht den Ruf des +ursprünglichen Autors schädigen. +</p> +<p> +Schließlich und endlich ist jedes freie Programm permanent +durch +Software-Patente bedroht. Wir möchten die Gefahr +ausschließen, daß +Distributoren eines freien Programms individuell Patente +lizensieren – mit dem Ergebnis, daß das Programm +proprietär +würde. Um dies zu verhindern, haben wir klargestellt, +daß jedes +Patent entweder für freie Benutzung durch jedermann lizenziert +werden muß oder überhaupt nicht lizenziert werden +darf. +</p> +<p> +Es folgen die genauen Bedingungen für die +Vervielfältigung, +Verbreitung und Bearbeitung: +</p> +<h2>Allgemeine Öffentliche GNU-Lizenz</h2> +<h2>Bedingungen für die Vervielfältigung, +Verbreitung und Bearbeitung</h2> +<p> +§0. Diese Lizenz gilt für jedes Programm und jedes +andere +Werk, in dem ein entsprechender Vermerk des Copyright-Inhabers +darauf hinweist, daß das Werk unter den Bestimmungen dieser +<em>General Public License</em> verbreitet werden darf. Im +folgenden wird jedes derartige Programm oder Werk als „das +Programm“ bezeichnet; die Formulierung „auf dem +Programm basierendes Werk“ bezeichnet das Programm sowie +jegliche Bearbeitung des Programms im urheberrechtlichen Sinne, +also ein Werk, welches das Programm, auch auszugsweise, sei es +unverändert oder verändert und/oder in eine andere +Sprache +übersetzt, enthält. (Im folgenden wird die +Übersetzung ohne +Einschränkung als „Bearbeitung“ +eingestuft.) Jeder +Lizenznehmer wird im folgenden als „Sie“ +angesprochen. +</p> +<p> +Andere Handlungen als Vervielfältigung, Verbreitung und +Bearbeitung werden von dieser Lizenz nicht berührt; sie fallen +nicht in ihren Anwendungsbereich. Der Vorgang der Ausführung +des +Programms wird nicht eingeschränkt, und die Ausgaben des +Programms +unterliegen dieser Lizenz nur, wenn der Inhalt ein auf dem +Programm basierendes Werk darstellt (unabhängig davon, +daß die +Ausgabe durch die Ausführung des Programmes erfolgte). Ob dies +zutrifft, hängt von den Funktionen des Programms ab. +</p> +<p> +§1. Sie dürfen auf beliebigen Medien +unveränderte Kopien des +Quelltextes des Programms, wie sie ihn erhalten haben, anfertigen +und verbreiten. Voraussetzung hierfür ist, daß Sie +mit jeder Kopie +einen entsprechenden Copyright-Vermerk sowie einen +Haftungsausschluß veröffentlichen, alle Vermerke, +die sich auf +diese Lizenz und das Fehlen einer Garantie beziehen, +unverändert +lassen und desweiteren allen anderen Empfängern des Programms +zusammen mit dem Programm eine Kopie dieser Lizenz zukommen +lassen. +</p> +<p> +Sie dürfen für den eigentlichen Kopiervorgang eine +Gebühr +verlangen. Wenn Sie es wünschen, dürfen Sie auch +gegen Entgelt +eine Garantie für das Programm anbieten. +</p> +<p> +§2. Sie dürfen Ihre Kopie(n) des Programms oder eines +Teils +davon verändern, wodurch ein auf dem Programm basierendes Werk +entsteht; Sie dürfen derartige Bearbeitungen unter den +Bestimmungen von Paragraph 1 vervielfältigen und verbreiten, +vorausgesetzt, daß zusätzlich alle im folgenden +genannten +Bedingungen erfüllt werden: +</p> +<ol type="lower-alpha"> + <li> + <p>Sie müssen die veränderten Dateien mit +einem auffälligen Vermerk +versehen, der auf die von Ihnen vorgenommene Modifizierung und +das Datum jeder Änderung hinweist. </p> + </li> + <li> + <p>Sie müssen dafür sorgen, daß +jede von Ihnen verbreitete oder +veröffentlichte Arbeit, die ganz oder teilweise von dem +Programm +oder Teilen davon abgeleitet ist, Dritten gegenüber als Ganzes +unter den Bedingungen dieser Lizenz ohne Lizenzgebühren zur +Verfügung gestellt wird. </p> + </li> + <li> + <p>Wenn das veränderte Programm normalerweise bei +der Ausführung +interaktiv Kommandos einliest, müssen Sie dafür +sorgen, daß es, +wenn es auf dem üblichsten Wege für solche +interaktive Nutzung +gestartet wird, eine Meldung ausgibt oder ausdruckt, die einen +geeigneten Copyright-Vermerk enthält sowie einen Hinweis, +daß es +keine Gewährleistung gibt (oder anderenfalls, daß +Sie Garantie +leisten), und daß die Benutzer das Programm unter diesen +Bedingungen weiter verbreiten dürfen. Auch muß der +Benutzer +darauf hingewiesen werden, wie er eine Kopie dieser Lizenz +ansehen kann. (Ausnahme: Wenn das Programm selbst interaktiv +arbeitet, aber normalerweise keine derartige Meldung ausgibt, +muß +Ihr auf dem Programm basierendes Werk auch keine solche Meldung +ausgeben). </p> + </li> +</ol> +<p> +Diese Anforderungen gelten für das bearbeitete Werk als +Ganzes. +Wenn identifizierbare Teile des Werkes nicht von dem Programm +abgeleitet sind und vernünftigerweise als unabhängige +und +eigenständige Werke für sich selbst zu betrachten +sind, dann +gelten diese Lizenz und ihre Bedingungen nicht für die +betroffenen +Teile, wenn Sie diese als eigenständige Werke weitergeben. +Wenn +Sie jedoch dieselben Abschnitte als Teil eines Ganzen weitergeben, +das ein auf dem Programm basierendes Werk darstellt, dann muß +die +Weitergabe des Ganzen nach den Bedingungen dieser Lizenz erfolgen, +deren Bedingungen für weitere Lizenznehmer somit auf das +gesamte +Ganze ausgedehnt werden – und somit auf jeden einzelnen +Teil, unabhängig vom jeweiligen Autor. +</p> +<p> +Somit ist es nicht die Absicht dieses Abschnittes, Rechte für +Werke in Anspruch zu nehmen oder Ihnen die Rechte für Werke +streitig zu machen, die komplett von Ihnen geschrieben wurden; +vielmehr ist es die Absicht, die Rechte zur Kontrolle der +Verbreitung von Werken, die auf dem Programm basieren oder unter +seiner auszugsweisen Verwendung zusammengestellt worden sind, +auszuüben. +</p> +<p> +Ferner bringt auch das einfache Zusammenlegen eines anderen +Werkes, das nicht auf dem Programm basiert, mit dem Programm oder +einem auf dem Programm basierenden Werk auf ein- und demselben +Speicher- oder Vertriebsmedium dieses andere Werk nicht in den +Anwendungsbereich dieser Lizenz. +</p> +<p> +§3. Sie dürfen das Programm (oder ein darauf +basierendes Werk +gemäß Paragraph 2) als Objectcode oder in +ausführbarer Form unter +den Bedingungen der Paragraphen 1 und 2 kopieren und weitergeben +– vorausgesetzt, daß Sie außerdem eine +der folgenden +Leistungen erbringen: +</p> +<ol type="lower-alpha"> + <li> + <p>Liefern Sie das Programm zusammen mit dem +vollständigen +zugehörigen maschinenlesbaren Quelltext auf einem für +den +Datenaustausch üblichen Medium aus, wobei die Verteilung unter +den Bedingungen der Paragraphen 1 und 2 erfolgen muß. Oder: </p> + </li> + <li> + <p>Liefern Sie das Programm zusammen mit einem mindestens +drei Jahre +lang gültigen schriftlichen Angebot aus, jedem Dritten eine +vollständige maschinenlesbare Kopie des Quelltextes zur +Verfügung +zu stellen – zu nicht höheren Kosten als denen, die +durch +den physikalischen Kopiervorgang anfallen –, wobei der +Quelltext unter den Bedingungen der Paragraphen 1 und 2 auf einem +für den Datenaustausch üblichen Medium weitergegeben +wird. Oder: </p> + </li> + <li> + <p>Liefern Sie das Programm zusammen mit dem schriftlichen +Angebot +der Zurverfügungstellung des Quelltextes aus, das Sie selbst +erhalten haben. (Diese Alternative ist nur für +nicht-kommerzielle +Verbreitung zulässig und nur, wenn Sie das Programm als +Objectcode oder in ausführbarer Form mit einem entsprechenden +Angebot gemäß Absatz b erhalten haben.) </p> + </li> +</ol> +<p> +Unter dem Quelltext eines Werkes wird diejenige Form des Werkes +verstanden, die für Bearbeitungen vorzugsweise verwendet wird. +Für +ein ausführbares Programm bedeutet „der komplette +Quelltext“: Der Quelltext aller im Programm enthaltenen +Module einschließlich aller zugehörigen +Modulschnittstellen-Definitionsdateien sowie der zur Compilation +und Installation verwendeten Skripte. Als besondere Ausnahme +jedoch braucht der verteilte Quelltext nichts von dem zu +enthalten, was üblicherweise (entweder als Quelltext oder in +binärer Form) zusammen mit den Hauptkomponenten des +Betriebssystems (Kernel, Compiler usw.) geliefert wird, unter dem +das Programm läuft – es sei denn, diese Komponente +selbst +gehört zum ausführbaren Programm. +</p> +<p> +Wenn die Verbreitung eines ausführbaren Programms oder von +Objectcode dadurch erfolgt, daß der Kopierzugriff auf eine +dafür +vorgesehene Stelle gewährt wird, so gilt die +Gewährung eines +gleichwertigen Zugriffs auf den Quelltext als Verbreitung des +Quelltextes, auch wenn Dritte nicht dazu gezwungen sind, den +Quelltext zusammen mit dem Objectcode zu kopieren. +</p> +<p> +§4. Sie dürfen das Programm nicht +vervielfältigen, verändern, +weiter lizenzieren oder verbreiten, sofern es nicht durch diese +Lizenz ausdrücklich gestattet ist. Jeder anderweitige Versuch +der +Vervielfältigung, Modifizierung, Weiterlizenzierung und +Verbreitung ist nichtig und beendet automatisch Ihre Rechte unter +dieser Lizenz. Jedoch werden die Lizenzen Dritter, die von Ihnen +Kopien oder Rechte unter dieser Lizenz erhalten haben, nicht +beendet, solange diese die Lizenz voll anerkennen und befolgen. +</p> +<p> +§5. Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da +Sie sie nicht unterzeichnet haben. Jedoch gibt Ihnen nichts +anderes die Erlaubnis, das Programm oder von ihm abgeleitete Werke +zu verändern oder zu verbreiten. Diese Handlungen sind +gesetzlich +verboten, wenn Sie diese Lizenz nicht anerkennen. Indem Sie das +Programm (oder ein darauf basierendes Werk) verändern oder +verbreiten, erklären Sie Ihr Einverständnis mit +dieser Lizenz und +mit allen ihren Bedingungen bezüglich der +Vervielfältigung, +Verbreitung und Veränderung des Programms oder eines darauf +basierenden Werks. +</p> +<p> +§6. Jedesmal, wenn Sie das Programm (oder ein auf dem +Programm basierendes Werk) weitergeben, erhält der +Empfänger +automatisch vom ursprünglichen Lizenzgeber die Lizenz, das +Programm entsprechend den hier festgelegten Bestimmungen zu +vervielfältigen, zu verbreiten und zu verändern. Sie +dürfen keine +weiteren Einschränkungen der Durchsetzung der hierin +zugestandenen +Rechte des Empfängers vornehmen. Sie sind nicht dafür +verantwortlich, die Einhaltung dieser Lizenz durch Dritte +durchzusetzen. +</p> +<p> +§7. Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs +einer Patentverletzung oder aus einem anderen Grunde (nicht auf +Patentfragen begrenzt) Bedingungen (durch Gerichtsbeschluß, +Vergleich oder anderweitig) auferlegt werden, die den Bedingungen +dieser Lizenz widersprechen, so befreien Sie diese Umstände +nicht +von den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht +möglich +ist, das Programm unter gleichzeitiger Beachtung der Bedingungen +in dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu +verbreiten, dann dürfen Sie als Folge das Programm +überhaupt nicht +verbreiten. Wenn zum Beispiel ein Patent nicht die +gebührenfreie +Weiterverbreitung des Programms durch diejenigen erlaubt, die das +Programm direkt oder indirekt von Ihnen erhalten haben, dann +besteht der einzige Weg, sowohl das Patentrecht als auch diese +Lizenz zu befolgen, darin, ganz auf die Verbreitung des Programms +zu verzichten. +</p> +<p> +Sollte sich ein Teil dieses Paragraphen als ungültig oder +unter +bestimmten Umständen nicht durchsetzbar erweisen, so soll +dieser +Paragraph seinem Sinne nach angewandt werden; im übrigen soll +dieser Paragraph als Ganzes gelten. +</p> +<p> +Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen, +irgendwelche Patente oder andere Eigentumsansprüche zu +verletzen +oder die Gültigkeit solcher Ansprüche zu bestreiten; +dieser +Paragraph hat einzig den Zweck, die Integrität des +Verbreitungssystems der freien Software zu schützen, das durch +die +Praxis öffentlicher Lizenzen verwirklicht wird. Viele Leute +haben +großzügige Beiträge zu dem großen +Angebot der mit diesem System +verbreiteten Software im Vertrauen auf die konsistente Anwendung +dieses Systems geleistet; es liegt am Autor/Geber, zu entscheiden, +ob er die Software mittels irgendeines anderen Systems verbreiten +will; ein Lizenznehmer hat auf diese Entscheidung keinen +Einfluß. +</p> +<p> +Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als +Konsequenz aus dem Rest dieser Lizenz betrachtet wird. +</p> +<p> +§8. Wenn die Verbreitung und/oder die Benutzung des Programms +in bestimmten Staaten entweder durch Patente oder durch +urheberrechtlich geschützte Schnittstellen +eingeschränkt ist, kann +der Urheberrechtsinhaber, der das Programm unter diese Lizenz +gestellt hat, eine explizite geographische Begrenzung der +Verbreitung angeben, in der diese Staaten ausgeschlossen werden, +so daß die Verbreitung nur innerhalb und zwischen den Staaten +erlaubt ist, die nicht ausgeschlossen sind. In einem solchen Fall +beinhaltet diese Lizenz die Beschränkung, als wäre +sie in diesem +Text niedergeschrieben. +</p> +<p> +§9. Die <em>Free Software Foundation</em> kann +von Zeit zu +Zeit überarbeitete und/oder neue Versionen der <em>General +Public +License</em> veröffentlichen. Solche neuen Versionen +werden vom +Grundprinzip her der gegenwärtigen entsprechen, +können aber im +Detail abweichen, um neuen Problemen und Anforderungen gerecht zu +werden. +</p> +<p> +Jede Version dieser Lizenz hat eine eindeutige Versionsnummer. +Wenn in einem Programm angegeben wird, daß es dieser Lizenz +in +einer bestimmten Versionsnummer oder „jeder späteren +Version“ <em>(“any later version”)</em> +unterliegt, so haben Sie die Wahl, entweder den Bestimmungen der +genannten Version zu folgen oder denen jeder beliebigen +späteren +Version, die von der <em>Free Software Foundation</em> +veröffentlicht wurde. Wenn das Programm keine Versionsnummer +angibt, können Sie eine beliebige Version wählen, die +je von der +<em>Free Software Foundation</em> veröffentlicht +wurde. +</p> +<p> +§10. Wenn Sie den Wunsch haben, Teile des Programms in +anderen freien Programmen zu verwenden, deren Bedingungen für +die +Verbreitung anders sind, schreiben Sie an den Autor, um ihn um die +Erlaubnis zu bitten. Für Software, die unter dem Copyright der +<em>Free Software Foundation</em> steht, schreiben Sie an +die +<em>Free Software Foundation</em>; wir machen zu diesem +Zweck +gelegentlich Ausnahmen. Unsere Entscheidung wird von den beiden +Zielen geleitet werden, zum einen den freien Status aller von +unserer freien Software abgeleiteten Werke zu erhalten und zum +anderen das gemeinschaftliche Nutzen und Wiederverwenden von +Software im allgemeinen zu fördern. +</p> +<h3>Keine Gewährleistung</h3> +<p><strong> +§11. Da das Programm ohne jegliche Kosten lizenziert wird, +besteht keinerlei Gewährleistung für das Programm, +soweit dies +gesetzlich zulässig ist. Sofern nicht anderweitig schriftlich +bestätigt, stellen die Copyright-Inhaber und/oder Dritte das +Programm so zur Verfügung, „wie es ist“, +ohne +irgendeine Gewährleistung, weder ausdrücklich noch +implizit, +einschließlich – aber nicht begrenzt auf +– Marktreife +oder Verwendbarkeit für einen bestimmten Zweck. Das volle +Risiko +bezüglich Qualität und Leistungsfähigkeit +des Programms liegt bei +Ihnen. Sollte sich das Programm als fehlerhaft herausstellen, +liegen die Kosten für notwendigen Service, Reparatur oder +Korrektur bei Ihnen. +</strong></p> +<p><strong> +§12. In keinem Fall, außer wenn durch geltendes +Recht +gefordert oder schriftlich zugesichert, ist irgendein +Copyright-Inhaber oder irgendein Dritter, der das Programm wie +oben erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber +für +irgendwelche Schäden haftbar, einschließlich +jeglicher allgemeiner +oder spezieller Schäden, Schäden durch Seiteneffekte +(Nebenwirkungen) oder Folgeschäden, die aus der Benutzung des +Programms oder der Unbenutzbarkeit des Programms folgen +(einschließlich – aber nicht beschränkt +auf – +Datenverluste, fehlerhafte Verarbeitung von Daten, Verluste, die +von Ihnen oder anderen getragen werden müssen, oder dem +Unvermögen +des Programms, mit irgendeinem anderen Programm +zusammenzuarbeiten), selbst wenn ein Copyright-Inhaber oder +Dritter über die Möglichkeit solcher Schäden +unterrichtet worden +war. +</strong></p> +<h2>Ende der Bedingungen</h2> +<h2> +Wie Sie diese Bedingungen auf Ihre eigenen, neuen Programme +anwenden können +</h2> +<p> +Wenn Sie ein neues Programm entwickeln und wollen, daß es vom +größtmöglichen Nutzen für die +Allgemeinheit ist, dann erreichen +Sie das am besten, indem Sie es zu freier Software machen, die +jeder unter diesen Bestimmungen weiterverbreiten und verändern +kann. +</p> +<p> +Um dies zu erreichen, fügen Sie die folgenden Vermerke zu +Ihrem +Programm hinzu. Am sichersten ist es, sie an den Anfang einer +jeden Quelldatei zu stellen, um den +Gewährleistungsausschluß +möglichst deutlich darzustellen; zumindest aber sollte jede +Datei +eine Copyright-Zeile besitzen sowie einen kurzen Hinweis darauf, +wo die vollständigen Vermerke zu finden sind. +</p> +<blockquote> + <p><tt>[<i>eine Zeile mit dem Programmnamen und +einer kurzen Beschreibung</i>]<br> +Copyright (C) [<i>Jahr</i>] [<i>Name +des Autors</i>] </tt></p> + <p><tt>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. </tt></p> + <p><tt>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. </tt></p> + <p><tt>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 St, Fifth Floor, Boston, MA 02110, +USA </tt></p> +</blockquote> +<p> +Auf Deutsch: +</p> +<blockquote> + <p><tt>[<i>eine Zeile mit dem Programmnamen und +einer kurzen Beschreibung</i>]<br> +Copyright (C) [<i>Jahr</i>] [<i>Name +des Autors</i>] </tt></p> + <p><tt>Dieses Programm ist freie Software. Sie +können es unter den +Bedingungen der GNU General Public License, wie von der Free +Software Foundation veröffentlicht, weitergeben und/oder +modifizieren, entweder gemäß Version 2 der Lizenz +oder (nach +Ihrer Option) jeder späteren Version. </tt></p> + <p><tt>Die Veröffentlichung dieses Programms +erfolgt in der Hoffnung, +daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE +GARANTIE, +sogar ohne die implizite Garantie der MARKTREIFE oder der +VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie +in +der GNU General Public License. </tt></p> + <p><tt>Sie sollten ein Exemplar der GNU General Public +License zusammen +mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an +die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +Boston, MA 02110, USA. </tt></p> +</blockquote> +<p> +Fügen Sie auch einen kurzen Hinweis hinzu, wie Sie +elektronisch +und per Brief erreichbar sind. +</p> +<p> +Wenn Ihr Programm interaktiv ist, sorgen Sie dafür, +daß es nach +dem Start einen kurzen Vermerk ausgibt: +</p> +<blockquote> + <p><tt>version 69, Copyright (C) +[<i>Jahr</i>] [<i>Name des Autors</i>]<br> +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. </tt></p> +</blockquote> +<p> +Auf Deutsch: +</p> +<blockquote> + <p><tt>Version 69, Copyright (C) +[<i>Jahr</i>] [<i>Name des Autors</i>] +Für Gnomovision besteht KEINERLEI GARANTIE; geben Sie "show +w" für Details ein. Gnonovision ist freie Software, die Sie +unter bestimmten Bedingungen weitergeben dürfen; geben Sie +"show c" für Details ein. </tt></p> +</blockquote> +<p> +Die hypothetischen Kommandos „<code>show w</code>“ +und +„<code>show c</code>“ sollten die +entsprechenden Teile +der GNU-GPL anzeigen. Natürlich können die von Ihnen +verwendeten +Kommandos anders heißen als „<code>show w</code>“ +und +„<code>show c</code>“; es +könnten auch Mausklicks oder +Menüpunkte sein – was immer am besten in Ihr +Programm paßt. +</p> +<p> +Soweit vorhanden, sollten Sie auch Ihren Arbeitgeber (wenn Sie als +Programmierer arbeiten) oder Ihre Schule einen Copyright-Verzicht +für das Programm unterschreiben lassen. Hier ein Beispiel. Die +Namen müssen Sie natürlich ändern. +</p> +<blockquote> + <p><tt>Yoyodyne, Inc., hereby disclaims all copyright +interest in the +program ‘Gnomovision’ (which makes passes at +compilers) written by James Hacker. </tt></p> + <p><tt>[<i>Unterschrift von Ty Coon</i>], 1 +April 1989<br> +Ty Coon, President of Vice </tt></p> +</blockquote> +<p> +Auf Deutsch: +</p> +<blockquote> + <p><tt>Die Yoyodyne GmbH erhebt keinen urheberrechtlichen +Anspruch auf +das von James Hacker geschriebene Programm +"Gnomovision" (einem Schrittmacher für Compiler). </tt></p> + <p><tt>[<i>Unterschrift von Ty Coon</i>], 1. +April 1989<br> +Ty Coon, Vizepräsident </tt></p> +</blockquote> +<p> +Diese <em>General Public License</em> gestattet nicht die +Einbindung des Programms in proprietäre Programme. Ist Ihr +Programm eine Funktionsbibliothek, so kann es sinnvoller sein, das +Binden proprietärer Programme mit dieser Bibliothek zu +gestatten. +Wenn Sie dies tun wollen, sollten Sie die +GNU Lesser General Public License anstelle dieser Lizenz verwenden. +</p> +</div> +</body> +</html> diff --git a/logo/src/xlogo/gpl/gpl-el.html b/logo/src/xlogo/gpl/gpl-el.html new file mode 100644 index 0000000..1855643 --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-el.html @@ -0,0 +1,175 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.4 (Linux)"> + <META NAME="CREATED" CONTENT="0;0"> + <META NAME="CHANGED" CONTENT="0;0"> + <STYLE TYPE="text/css"> + <!-- + @page { size: 21cm 29.7cm; margin: 2cm } + P { margin-bottom: 0.21cm } + PRE { font-family: "Times New Roman" } + --> + </STYLE> +</HEAD> +<BODY LANG="fr-FR" DIR="LTR"> +<PRE>Αυτή είναι μια ανεπίσημη μετάφραση της Γενικής ’δειας Δημόσιας Χρήσης +GNU (GNU GPL) στα ελληνικά. Δεν εκδόθηκε από το Ίδρυμα Ελεύθερου +Λογισμικού (Free Software Foundation) και δεν διατυπώνει νομικά τους όρους +διανομής λογισμικού που υπάγεται στη Γενική ’δεια Δημόσιας Χρήσης +GNU-αυτό γίνεται μόνο από την επίσημη αγγλική έκδοση της ’δειας (GNU GPL). +Ωστόσο, ελπίζουμε ότι η μετάφραση αυτή θα βοηθήσει όσους μιλούν την +ελληνική να κατανοήσουν καλύτερα την ’δεια GNU GPL. + +This is an unofficial translation of the GNU General Public License into greek. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GNU GPL-only the original English text of the GNU GPL does that. However, we hope that this translation will help greek speakers understand the GNU GPL better. + + + ΓΕΝΙΚΗ ΑΔΕΙΑ ΔΗΜΟΣΙΑΣ ΧΡΗΣΗΣ GNU + + Έκδοση 2, Ιούνιος 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Επιτρέπεται σε όλους η αντιγραφή και διανομή αυτούσιων αντιγράφων + αυτού του εγγράφου άδειας χρήσης, χωρίς ωστόσο να επιτρέπεται η αλλοίωσή του. + + Εισαγωγή + + Οι άδειες χρήσης των περισσότερων προγραμμάτων συντάσσονται για να περιορίσουν την ελευθερία σας να τα μοιράζεστε με άλλους και να τα επεξεργάζεστε. Εν αντιθέσει, η Γενική ’δεια Δημόσιας Χρήσης GNU έχει σκοπό να εγγυηθεί την ελευθερία σας να χρησιμοποιείτε από κοινού με άλλους και να τροποποιείτε προγράμματα που διατίθενται ελεύθερα -- δηλαδή να εγγυηθεί ότι το πρόγραμμα είναι ελεύθερο για όλους τους χρήστες. Αυτή η Γενική ’δεια Δημόσιας Χρήσης ισχύει για τα περισσότερα προγράμματα του Ιδρύματος Ελεύθερου Λογισμικού (Free Software Foundation), καθώς και για κάθε άλλο πρόγραμμα οι δημιουργοί του οποίου συμμορφώνονται με την άδεια αυτή. (Ορισμένα άλλα προγράμματα του Ιδρύματος Ελεύθερου Λογισμικού καλύπτονται από τη Γενική ’δεια Δημόσιας Χρήσης Βιβλιοθήκης GNU.) Την άδεια αυτή μπορείτε να την εφαρμόσετε και στα δικά σας προγράμματα. + + Μιλώντας για ελεύθερο λογισμικό, αναφερόμαστε στην ελευθερία χρήσης του, όχι +στο κόστος του. Οι Γενικές ’δειες Δημόσιας Χρήσης τις οποίες συντάσσουμε έχουν σκοπό να κατοχυρώσουν την ελευθερία σας να διανέμετε αντίγραφα ελεύθερου λογισμικού (και να χρεώνετε, εάν το επιθυμείτε, την παροχή αυτής της υπηρεσίας), να σας εξασφαλίσουν το δικαίωμα να λαμβάνετε τον πηγαίο κώδικα, εάν τον χρειάζεστε, καθώς και να τροποποιείτε το πρόγραμμα ή να χρησιμοποιείτε τμήματά του σε καινούργια ελεύθερα προγράμματα -- και να διασφαλίσουν ότι είστε ενήμεροι για τα παραπάνω δικαιώματά σας. + + Για την προστασία των δικαιωμάτων σας, επιβάλλεται να προβούμε σε περιορισμούς +οι οποίοι θα εμποδίζουν σε κάποιον να αμφισβητήσει τα δικαιώματά σας ή να σας ζητήσει να παραιτηθείτε από αυτά. Αυτοί οι περιορισμοί ερμηνεύονται ως συγκεκριμένες ευθύνες για εσάς εάν διανέμετε αντίγραφα κάποιου ελεύθερου λογισμικού ή εάν το τροποποιείτε. + + Για παράδειγμα, εάν διανέμετε αντίγραφα ενός τέτοιου προγράμματος, είτε δωρεάν +είτε με χρέωση, πρέπει να εκχωρήσετε στους παραλήπτες όλα τα δικαιώματα που έχετε και εσείς. Πρέπει να εγγυηθείτε ότι και εκείνοι επίσης λαμβάνουν, ή μπορούν να λάβουν, τον πηγαίο κώδικα. Πρέπει επίσης να τους επιδείξετε τους όρους αυτής της άδειας χρήσης, ώστε να είναι ενήμεροι για τα δικαιώματά τους. + + Προστατεύουμε τα δικαιώματά σας με δύο τρόπους: (1) προστατεύοντας το λογισμικό και (2) προσφέροντάς σας αυτήν την άδεια, με την οποία αποκτάτε νόμιμο δικαίωμα αντιγραφής, διανομής ή/και τροποποίησης του λογισμικού. + + Επιπλέον, για την προστασία των δημιουργών και τη δική μας, θέλουμε να καταστήσουμε βέβαιο ότι όλοι κατανοούν την απουσία εγγύησης για αυτό το ελεύθερο λογισμικό. Εάν το λογισμικό τροποποιηθεί από κάποιον τρίτο και στη συνέχεια διανεμηθεί, θέλουμε να γνωρίζουν οι παραλήπτες ότι το λογισμικό που απέκτησαν δεν είναι το πρωτότυπο, έτσι ώστε οποιοδήποτε πρόβλημα προκληθεί από τρίτους να μην βαρύνει το όνομα του δημιουργού. + + Τέλος, κάθε ελεύθερο λογισμικό απειλείται συνεχώς από τις κατοχυρώσεις ευρεσιτεχνίας λογισμικού. Θέλουμε να αποφύγουμε τον κίνδυνο να αποκτήσουν οι αναδιανομείς ελεύθερου λογισμικού τίτλους ευρεσιτεχνίας, καθιστώντας έτσι το λογισμικό προσωπική τους ιδιοκτησία. Για να αποκλείσουμε αυτό το ενδεχόμενο, έχουμε ξεκαθαρίσει ότι οποιαδήποτε ευρεσιτεχνία θα πρέπει να παρέχει άδεια ελεύθερης χρήσης από όλους, διαφορετικά να μην παρέχει καμιά απολύτως άδεια. + + Ακολουθούν οι ακριβείς όροι και συνθήκες αντιγραφής, διανομής και τροποποίησης. + + ΓΕΝΙΚΗ ΑΔΕΙΑ ΔΗΜΟΣΙΑΣ ΧΡΗΣΗΣ GNU + ΟΡΟΙ ΚΑΙ ΣΥΝΘΗΚΕΣ ΑΝΤΙΓΡΑΦΗΣ, ΔΙΑΝΟΜΗΣ ΚΑΙ ΤΡΟΠΟΠΟΙΗΣΗΣ + + 0. Η ’δεια αυτή ισχύει για κάθε πρόγραμμα ή άλλο έργο που περιέχει +σημείωμα από τον κάτοχο πνευματικών δικαιωμάτων, στο οποίο αναφέρεται ότι η διανομή του προγράμματος είναι δυνατή υπό τους όρους αυτής της Γενικής ’δειας Δημόσιας Χρήσης. Ο όρος "Πρόγραμμα", παρακάτω, αναφέρεται σε οποιοδήποτε τέτοιο πρόγραμμα ή έργο, ενώ ο όρος "έργο βασισμένο στο Πρόγραμμα" σημαίνει είτε το Πρόγραμμα είτε κάθε άλλο παραγόμενο έργο που υπάγεται στο νόμο περί πνευματικής ιδιοκτησίας: με λίγα λόγια, ένα έργο που περιέχει ακέραιο το Πρόγραμμα ή ένα μέρος του, είτε αυτούσιο είτε με τροποποιήσεις ή/και μεταφρασμένο σε άλλη γλώσσα. (Από αυτό το σημείο, η μετάφραση θα περιλαμβάνεται χωρίς περιορισμούς στον όρο "τροποποίηση".) Κάθε κάτοχος της άδειας χρήσης θα αναφέρεται στο εξής ως "εσείς/εσάς". + +’λλες δραστηριότητες πέραν της αντιγραφής, της διανομής και της τροποποίησης δεν καλύπτονται από αυτήν την ’δεια - είναι εκτός των πλαισίων της. Δεν υπάρχει περιορισμός στην ενέργεια εκτέλεσης ενός προγράμματος, ενώ το προϊόν της χρήσης του Προγράμματος καλύπτεται μόνο εφόσον το περιεχόμενό του συνιστά έργο βασισμένο στο Πρόγραμμα (ανεξάρτητα από το εάν δημιουργήθηκε με την εκτέλεση του Προγράμματος). Το κατά πόσο συμβαίνει αυτό εξαρτάται από το είδος του Προγράμματος. + + 1. Επιτρέπεται η αντιγραφή και διανομή αυτούσιων αντιγράφων του πηγαίου κώδικα του Προγράμματος όπως ακριβώς το έχετε λάβει, σε οποιοδήποτε αποθηκευτικό μέσο, με την προϋπόθεση ότι: θα δημοσιεύσετε εμφανώς και καταλλήλως, σε κάθε αντίγραφο, ένα σημείωμα πνευματικής ιδιοκτησίας και ένα σημείωμα αποποίησης ευθυνών εγγύησης - ότι θα συμπεριλάβετε ακέραια όλα τα σημειώματα που αναφέρονται στην ’δεια αυτή και στην απουσία οποιασδήποτε εγγύησης - και, τέλος, ότι θα εκχωρήσετε σε κάθε άλλον παραλήπτη του Προγράμματος ένα αντίγραφο αυτής της ’δειας μαζί με το Πρόγραμμα. + +Έχετε δικαίωμα να επιβάλετε χρέωση για τη φυσική ενέργεια της μεταφοράς ενός αντιγράφου, καθώς και να παράσχετε, κατά την κρίση σας, προστασία εγγύησης με χρέωση. + + 2. Επιτρέπεται η τροποποίηση του αντιγράφου ή των αντιγράφων του Προγράμματος ολόκληρου ή μέρους του, η οποία συνιστά συνεπώς δημιουργία ενός έργου βασισμένου στο Πρόγραμμα, και η διανομή αυτών των τροποποιήσεων ή έργων υπό τους όρους της Ενότητας 1 ως ανωτέρω, με την προϋπόθεση ότι και εσείς πληροίτε όλες τις παρακάτω προϋποθέσεις: + + α) Πρέπει να φροντίζετε ώστε τα τροποποιημένα αρχεία να παρέχουν εμφανή σημειώματα στα οποία να δηλώνεται η τροποποίηση των αρχείων και η ημερομηνία τροποποίησης. + + β) Πρέπει να φροντίζετε ώστε για κάθε έργο το οποίο διανέμετε ή δημοσιεύετε, και το οποίο περιέχει ή παράγεται από ολόκληρο ή μέρος του Προγράμματος, να παρέχεται άδεια χρήσης του, χωρίς χρέωση, σε όλα τα τρίτα μέρη, σύμφωνα με τους όρους αυτής της ’δειας. + + γ) Εάν το τροποποιημένο πρόγραμμα διαβάζει εντολές αλληλεπιδραστικά, κατά την τυπική εκτέλεσή του, πρέπει να φροντίζετε ώστε, κατά την έναρξη τυπικής εκτέλεσής του για αυτήν την αλληλεπιδραστική χρήση, να εκτυπώνεται ή να εμφανίζεται στην οθόνη μια ανακοίνωση, η οποία θα περιλαμβάνει το απαραίτητο σημείωμα πνευματικής ιδιοκτησίας και ένα σημείωμα στο οποίο θα αναφέρεται ότι δεν υπάρχει καμιά εγγύηση (ή, αντίθετα, ότι παρέχετε εγγύηση) και ότι οι χρήστες έχουν τη δυνατότητα να αναδιανέμουν το πρόγραμμα σύμφωνα με τις προϋποθέσεις αυτές, καθώς και οδηγίες προς το χρήστη για τον τρόπο προβολής ενός αντιγράφου αυτής της ’δειας. (Εξαίρεση: εάν το ίδιο το Πρόγραμμα είναι αλληλεπιδραστικό αλλά κανονικά δεν εκτυπώνει αυτήν την ανακοίνωση, δεν απαιτείται από το έργο που δημιουργήσατε βασισμένοι στο Πρόγραμμα να εκτυπώνει ανακοίνωση.) + +Οι απαιτήσεις αυτές ισχύουν για ολόκληρο το τροποποιημένο έργο. Εάν συγκεκριμένες ενότητες του έργου αυτού δεν παράγονται από το Πρόγραμμα, και μπορούν να θεωρηθούν με ασφάλεια από μόνες τους ως ανεξάρτητα και ξεχωριστά έργα, τότε αυτή η ’δεια και οι όροι της δεν ισχύουν για τις ενότητες αυτές, κατά τη διανομή τους ως ξεχωριστά έργα. Αλλά όταν διανέμετε τις ίδιες ενότητες ως τμήματα ενός ευρύτερου έργου το οποίο βασίζεται στο Πρόγραμμα, η διανομή του συνόλου πρέπει να υπόκειται στους όρους της ’δειας, σύμφωνα με την οποία τα δικαιώματα των άλλων χρηστών εκτείνονται σε ολόκληρο το έργο, επομένως και σε καθένα χωριστό τμήμα του, ανεξάρτητα από το ποιος είναι ο δημιουργός του. + +Επομένως, πρόθεση αυτής της ενότητας δεν είναι να εγείρει δικαιώματα ή να αμφισβητήσει τα δικά σας δικαιώματα σε μια εργασία που δημιουργήσατε εξ ολοκλήρου οι ίδιοι - η πρόθεση, περισσότερο, είναι να ασκήσει το δικαίωμα ελέγχου της διανομής των παραγόμενων ή των συλλογικών έργων που βασίζονται στο Πρόγραμμα. + +Επιπλέον, η απλή προσθήκη ενός άλλου έργου, που δεν βασίζεται στο Πρόγραμμα, μαζί με το Πρόγραμμα (ή με ένα έργο που βασίζεται στο Πρόγραμμα) σε τόμο ενός μέσου αποθήκευσης ή διανομής, δεν υπάγει το άλλο έργο στα πλαίσια αυτής της ’δειας. + + 3. Επιτρέπεται η αντιγραφή και διανομή του Προγράμματος (ή ενός έργου βασισμένο σε αυτό, σύμφωνα με την Ενότητα 2) σε μορφή αντικειμενικού κώδικα ή εκτελέσιμη μορφή, σύμφωνα με τους όρους των Ενοτήτων 1 και 2 ως ανωτέρω, με την προϋπόθεση ότι πραγματοποιείτε και μια από τις ακόλουθες ενέργειες: + + α) Το συνοδεύετε με τον αντίστοιχο, πλήρη πηγαίο κώδικα, ο οποίος είναι αναγνώσιμος από το σύστημα και ο οποίος πρέπει να διανέμεται σύμφωνα με τους όρους των Ενοτήτων 1 και 2 παραπάνω, σε ένα συνηθισμένο μέσο μεταφοράς λογισμικού - ή, + β) Το συνοδεύετε με γραπτή προσφορά, ισχύουσα τουλάχιστον για τρία χρόνια και με χρέωση όχι μεγαλύτερη από το κόστος της φυσικής διανομής κώδικα, παράδοσης σε τρίτους του πλήρους, αναγνώσιμου από το σύστημα αντιγράφου του αντίστοιχου πηγαίου κώδικα, ο οποίος θα διανεμηθεί υπό τους όρους των Ενοτήτων 1 και 2 ως ανωτέρω, σε συνηθισμένο μέσο μεταφοράς λογισμικού - ή, + + γ) Το συνοδεύετε με τις πληροφορίες που λάβατε όσον αφορά την προσφορά διανομής του αντίστοιχου πηγαίου κώδικα. (Η εναλλακτική αυτή επιλογή επιτρέπεται μόνο για μη εμπορική διανομή και μόνο εφόσον λάβατε το πρόγραμμα σε αντικειμενικό κώδικα ή εκτελέσιμη μορφή με αυτήν την προσφορά, σύμφωνα με την Υποενότητα [β] παραπάνω.) + +Ο πηγαίος κώδικας για ένα έργο συνιστά την προτιμώμενη μορφή του έργου για πραγματοποίηση τροποποιήσεων σε αυτό. Για ένα εκτελέσιμο έργο, πλήρης πηγαίος κώδικας σημαίνει όλον τον πηγαίο κώδικα για όλες τις λειτουργικές μονάδες που περιλαμβάνει, συν οποιαδήποτε σχετικά αρχεία ορισμού διασύνδεσης, συν τις δέσμες ενεργειών που χρησιμοποιούνται για τον έλεγχο της μεταγλώττισης και εγκατάστασης του εκτελέσιμου αρχείου. Ωστόσο, ως ειδική εξαίρεση, ο πηγαίος κώδικας που διανέμεται δεν χρειάζεται να περιλαμβάνει οτιδήποτε διανέμεται κανονικά (είτε ως κώδικας, είτε σε δυαδική μορφή) μαζί με τα μεγαλύτερα στοιχεία (μεταγλωττιστές, πυρήνας κ.ο.κ.) του λειτουργικού συστήματος στο οποίο εκτελείται το εκτελέσιμο αρχείο, εκτός εάν το ίδιο το στοιχείο συνοδεύει το εκτελέσιμο. + +Εάν η διανομή του εκτελέσιμου ή του αντικειμενικού κώδικα πραγματοποιείται με +παραχώρηση πρόσβασης για αντιγραφή από καθορισμένη τοποθεσία, τότε η παραχώρηση +ισοδύναμης πρόσβασης για αντιγραφή του πηγαίου κώδικα από την ίδια τοποθεσία λογίζεται ως διανομή του πηγαίου κώδικα - αν και τα τρίτα μέλη δεν +υποχρεούνται να αντιγράψουν τον πηγαίο κώδικα μαζί με τον αντικειμενικό. + + 4. Δεν επιτρέπεται η αντιγραφή, τροποποίηση, παραχώρηση άδειας περαιτέρω εκμετάλλευσης ή διανομή του Προγράμματος εκτός εάν προβλέπεται ρητά στην παρούσα ’δεια. Διαφορετικά, κάθε απόπειρα για αντιγραφή, τροποποίηση, παραχώρηση άδειας εκμετάλλευσης ή διανομή του Προγράμματος είναι άκυρη και αυτομάτως καταργεί τα δικαιώματα που σας παραχωρεί η παρούσα ’δεια. +Ωστόσο, οι άδειες χρήσης των μελών που έχουν λάβει αντίγραφα ή δικαιώματα από εσάς, μέσω της παρούσας ’δειας, δεν θα ακυρωθούν, εφόσον τα μέλη αυτά +παραμένουν πλήρως συμμορφωμένα με τους όρους της ’δειας. + + 5. Δεν απαιτείται από εσάς να δεχθείτε την παρούσα ’δεια, εφόσον δεν την έχετε υπογράψει. Ωστόσο, τίποτε άλλο δεν σας δίνει το δικαίωμα να τροποποιήσετε ή να διανείμετε το Πρόγραμμα ή τα παραγόμενα από αυτό έργα. Οι ενέργειες αυτές απαγορεύονται από το νόμο, εάν δεν αποδεχθείτε την παρούσα ’δεια. Συνεπώς, με το να τροποποιήσετε ή να διανείμετε το Πρόγραμμα (ή οποιοδήποτε έργο που βασίζεται στο Πρόγραμμα), δηλώνετε ότι αποδέχεστε την παρούσα ’δεια, καθώς και όλους τους όρους και συνθήκες που προβλέπει η ’δεια για την αντιγραφή, διανομή ή τροποποίηση του Προγράμματος ή έργων που βασίζονται σε αυτό. + + 6. Κάθε φορά που αναδιανέμετε το Πρόγραμμα (ή ένα έργο βασισμένο στο Πρόγραμμα), ο αποδέκτης αυτόματα παραλαμβάνει την αρχική άδεια αντιγραφής, διανομής ή τροποποίησης του Προγράμματος σύμφωνα με τους όρους και τις συνθήκες αυτές. Δεν επιτρέπεται να επιβάλλετε περαιτέρω περιορισμούς στην άσκηση των δικαιωμάτων του αποδέκτη τα οποία προβλέπονται εδώ. Δεν είστε υπεύθυνοι για το εάν τρίτα μέλη επιβάλλουν συμμόρφωση σε αυτήν τη ’δεια. + + 7. Εάν, ως συνέπεια δικαστικής απόφασης ή κατηγορίας για παράβαση νόμου περί πνευματικής ιδιοκτησίας ή για οποιονδήποτε άλλο λόγο (μη περιοριζόμενο σε θέματα ευρεσιτεχνίας), σας επιβληθούν όροι (είτε μέσω δικαστικής απόφασης, συμφωνίας ή μέσω άλλου τρόπου) οι οποίοι αντιβαίνουν τους όρους της παρούσας ’δειας, οι όροι εκείνοι δεν σας απαλλάσσουν από τους όρους της παρούσας. Εάν δεν είναι δυνατή η αναδιανομή με τρόπο ώστε να ικανοποιεί συγχρόνως τις υποχρεώσεις σας σύμφωνα με την παρούσα ’δεια και οποιεσδήποτε άλλες υποχρεώσεις απορρέουν από αυτή, τότε, ως συνέπεια, δεν επιτρέπεται να αναδιανέμετε το Πρόγραμμα με κανένα τρόπο. Για παράδειγμα, εάν μια άδεια ευρεσιτεχνίας δεν επιτρέπει τη χωρίς δικαιώματα εκμετάλλευσης αναδιανομή του Προγράμματος από όλους όσους λαμβάνουν αντίγραφα άμεσα ή έμμεσα από εσάς, τότε ο μόνος τρόπος με τον οποίο θα μπορούσατε να ικανοποιήσετε την άδεια εκείνη και την παρούσα ’δεια θα ήταν να αποφύγετε εντελώς την αναδιανομή του Προγράμματος. + +Εάν οποιοδήποτε τμήμα αυτής της ενότητας καταστεί άκυρο ή μη δυνάμενο να επιβληθεί σε κάποια συγκεκριμένη περίπτωση, το υπόλοιπο τμήμα της ενότητας αυτής εφαρμόζεται και η ενότητα ως σύνολο εφαρμόζεται υπό οποιεσδήποτε συγκυρίες. + +Δεν ανήκει στους σκοπούς της ενότητας αυτής να σας παρακινήσει να παραβιάσετε +την ευρεσιτεχνία ή άλλες αξιώσεις πνευματικής ιδιοκτησίας ή να αμφισβητήσετε τον κύρος οποιωνδήποτε τέτοιων αξιώσεων. Μοναδικός σκοπός αυτής της ενότητας είναι να προστατέψει την ακεραιότητα του συστήματος διανομής ελεύθερου λογισμικού, η οποία υλοποιείται μέσω της πρακτικής των αδειών δημόσιας χρήσης. Πολλοί άνθρωποι έχουν συνεισφέρει γενναιόδωρα στην ευρεία έκταση του λογισμικού που διανέμεται μέσω αυτού του συστήματος, εμπιστευόμενοι την συνεπή εφαρμογή αυτού του συστήματος. Είναι στην ευχέρεια του δημιουργού/δωρητή να αποφασίσει εάν προτίθεται να διανείμει λογισμικό μέσω οποιουδήποτε άλλου συστήματος, και μια άδεια δεν είναι δυνατό να επιβάλει αυτήν την επιλογή. + +Η ενότητα αυτή έχει ως σκοπό να καταστήσει σαφές ό,τι συνεπάγεται το υπόλοιπο τμήμα της παρούσας ’δειας. + + 8. Εάν η διανομή ή/και η χρήση του Προγράμματος εμποδίζεται σε ορισμένες χώρες, είτε μέσω κατοχυρωμένης ευρεσιτεχνίας είτε μέσω διασυνδέσεων που προστατεύονται από πνευματικά δικαιώματα, επιτρέπεται στον κάτοχο του αρχικού πνευματικού δικαιώματος, ο οποίος θέτει το Πρόγραμμα υπό τους όρους της παρούσας ’δειας, να προσθέσει έναν ρητό γεωγραφικό περιορισμό στη διανομή, εξαιρώντας εκείνες τις χώρες, έτσι ώστε η διανομή να επιτρέπεται μόνο για τις χώρες οι οποίες δεν εξαιρούνται. Σε τέτοια περίπτωση, η παρούσα ’δεια ενσωματώνει τον περιορισμό σαν να ήταν διατυπωμένος στο σώμα της παρούσας ’δειας. + + 9. Το Ίδρυμα Ελεύθερου Λογισμικού (Free Software Foundation) έχει τη δυνατότητα περιστασιακά να δημοσιεύει αναθεωρημένες ή/και νέες εκδόσεις της Γενικής ’δειας Δημόσιας Χρήσης. Αυτές οι νέες εκδόσεις θα είναι συναφείς στο πνεύμα με την παρούσα έκδοση, όμως ενδέχεται να διαφέρουν στις λεπτομέρειες, +καθώς αναφέρονται σε νέα προβλήματα και ζητήματα. + +Σε κάθε έκδοση δίνεται ένας διακριτικός αριθμός έκδοσης. Εάν στο Πρόγραμμα +καθορίζεται ένας αριθμός έκδοσης της παρούσας ’δειας, η οποία ισχύει σε αυτό, καθώς και "οποιασδήποτε μεταγενέστερης έκδοσης", μπορείτε να επιλέξετε ανάμεσα στο να ακολουθήσετε τους όρους και τις συνθήκες είτε εκείνης της έκδοσης είτε οποιασδήποτε άλλης έκδοσης που δημοσιεύεται από το Ίδρυμα Ελεύθερου Λογισμικού (Free Software Foundation). Εάν στο Πρόγραμμα δεν καθορίζεται αριθμός έκδοσης +της παρούσας ’δειας, μπορείτε να επιλέξετε οποιαδήποτε έκδοση η οποία έχει δημοσιευθεί από το Ίδρυμα Ελεύθερου Λογισμικού. + + 10. Εάν επιθυμείτε να ενσωματώσετε μέρη του Προγράμματος σε άλλα ελεύθερα +προγράμματα, των οποίων οι όροι διανομής είναι διαφορετικοί, επικοινωνήστε με το δημιουργό του Προγράμματος για να ζητήσετε την έγκρισή του. Για λογισμικό του οποίου η πνευματική ιδιοκτησία ανήκει στο Ίδρυμα Ελεύθερου Λογισμικού (Free Software Foundation), επικοινωνήστε μαζί μας στο Ίδρυμα Ελεύθερου Λογισμικού (σε ορισμένες περιπτώσεις προβαίνουμε σε εξαιρέσεις). Η απόφασή μας θα ληφθεί βάσει του διττού στόχου μας να διατηρήσουμε την ελευθερία όλων των προϊόντων που παράγονται από το ελεύθερο λογισμικό μας, καθώς και να προωθήσουμε γενικότερα την κοινή χρήση και τη δυνατότητα επαναχρησιμοποίησης του λογισμικού. + + ΚΑΜΙΑ ΕΓΓΥΗΣΗ + + 11. ΕΠΕΙΔΗ Η ΑΔΕΙΑ ΧΡΗΣΗΣ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΠΑΡΕΧΕΤΑΙ ΧΩΡΙΣ ΧΡΕΩΣΗ, ΔΕΝ ΥΠΑΡΧΕΙ ΕΓΓΥΗΣΗ ΓΙΑ ΤΟ ΠΡΟΓΡΑΜΜΑ, ΣΤΟ ΒΑΘΜΟ ΠΟΥ ΕΠΙΤΡΕΠΕΙ Η ΙΣΧΥΟΥΣΑ ΝΟΜΟΘΕΣΙΑ. ΕΦΟΣΟΝ ΔΕΝ ΥΠΑΡΧΕΙ ΔΙΑΦΟΡΕΤΙΚΗ ΕΓΓΡΑΦΗ ΔΗΛΩΣΗ, ΟΙ ΚΑΤΟΧΟΙ ΠΝΕΥΜΑΤΙΚΩΝ ΔΙΚΑΙΩΜΑΤΩΝ Ή/ΚΑΙ ΑΛΛΕΣ ΠΛΕΥΡΕΣ ΠΑΡΕΧΟΥΝ ΤΟ ΠΡΟΓΡΑΜΜΑ "ΩΣ ΕΧΕΙ" ΧΩΡΙΣ ΚΑΝΕΝΟΣ ΕΙΔΟΥΣ ΕΓΓΥΗΣΕΙΣ, ΕΙΤΕ ΡΗΤΕΣ ΕΙΤΕ ΕΜΜΕΣΕΣ, ΣΤΙΣ ΟΠΟΙΕΣ ΣΥΜΠΕΡΙΛΑΜΒΑΝΟΝΤΑΙ, ΕΝΔΕΙΚΤΙΚΑ, ΟΙ ΕΜΜΕΣΕΣ ΕΓΓΥΗΣΕΙΣ ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ΚΑΙ ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ. ΟΠΟΙΟΣΔΗΠΟΤΕ ΚΙΝΔΥΝΟΣ ΑΠΟ ΤΗΝ ΠΟΙΟΤΗΤΑ ΚΑΙ ΤΗΝ ΑΠΟΔΟΣΗ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΑΝΗΚΕΙ ΕΞ ΟΛΟΚΛΗΡΟΥ ΕΣΑΣ. ΕΑΝ ΤΟ ΠΡΟΓΡΑΜΜΑ ΑΠΟΔΕΙΧΘΕΙ ΕΛΑΤΤΩΜΑΤΙΚΟ, ΤΟ ΚΟΣΤΟΣ ΟΛΩΝ ΤΩΝ ΕΡΓΑΣΙΩΝ ΕΠΙΣΚΕΥΗΣ Ή ΔΙΟΡΘΩΣΗΣ ΒΑΡΥΝΕΙ ΕΣΑΣ. + + 12. ΣΕ ΚΑΜΙΑ ΠΕΡΙΠΤΩΣΗ, ΕΚΤΟΣ ΕΑΝ ΑΠΑΙΤΕΙΤΑΙ ΑΠΟ ΤΗΝ ΙΣΧΥΟΥΣΑ ΝΟΜΟΘΕΣΙΑ Ή ΕΧΕΙ ΣΥΜΦΩΝΗΘΕΙ ΓΡΑΠΤΩΣ, Ο ΚΑΤΟΧΟΣ ΤΩΝ ΠΝΕΥΜΑΤΙΚΩΝ ΔΙΚΑΙΩΜΑΤΩΝ, Ή ΟΠΟΙΟΔΗΠΟΤΕ ΑΛΛΟ ΜΕΛΟΣ ΤΟ ΟΠΟΙΟ ΜΠΟΡΕΙ ΝΑ ΤΡΟΠΟΠΟΙΗΣΕΙ Ή/ΚΑΙ ΝΑ ΑΝΑΔΙΑΝΕΙΜΕΙ ΤΟ ΠΡΟΓΡΑΜΜΑ ΟΠΩΣ ΠΡΟΒΛΕΠΕΤΑΙ ΠΑΡΑΠΑΝΩ, ΔΕΝ ΦΕΡΕΤΑΙ ΩΣ ΥΠΕΥΘΥΝΟΣ ΑΠΕΝΑΝΤΙ ΣΑΣ ΓΙΑ ΖΗΜΙΕΣ, ΣΥΜΠΕΡΙΛΑΜΒΑΝΟΜΕΝΩΝ ΟΛΩΝ ΤΩΝ ΓΕΝΙΚΩΝ, ΕΙΔΙΚΩΝ, ΣΥΜΠΤΩΜΑΤΙΚΩΝ Ή ΣΥΝΕΠΑΚΟΛΟΥΘΩΝ ΖΗΜΙΩΝ ΠΟΥ ΕΝΔΕΧΕΤΑΙ ΝΑ ΠΡΟΚΥΨΟΥΝ ΛΟΓΩ ΤΗΣ ΧΡΗΣΗΣ Ή ΤΗΣ ΑΔΥΝΑΜΙΑΣ ΧΡΗΣΗΣ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ (ΣΥΜΠΕΡΙΛΑΜΒΑΝΟΜΕΝΩΝ, ΕΝΔΕΙΚΤΙΚΑ, ΤΗΣ ΑΠΩΛΕΙΑΣ ΔΕΔΟΜΕΝΩΝ Ή ΤΗΣ ΑΛΛΟΙΩΣΗΣ ΤΗΣ ΑΚΡΙΒΕΙΑΣ ΤΟΥΣ, Ή ΑΠΩΛΕΙΑΣ ΠΟΥ ΕΠΗΛΘΕ ΑΠΟ ΕΣΑΣ Ή ΑΠΟ ΤΡΙΤΑ ΜΕΛΗ, Ή ΑΔΥΝΑΜΙΑΣ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΝΑ ΛΕΙΤΟΥΡΓΗΣΕΙ ΜΕ ΑΛΛΑ ΠΡΟΓΡΑΜΜΑΤΑ), ΕΣΤΩ ΚΑΙ ΑΝ Ο ΚΑΤΟΧΟΣ ΑΥΤΟΣ Ή ΤΟ ΑΛΛΟ ΜΕΛΟΣ ΕΧΕΙ ΕΝΗΜΕΡΩΘΕΙ ΓΙΑ ΤΟ ΕΝΔΕΧΟΜΕΝΟ ΤΕΤΟΙΩΝ ΖΗΜΙΩΝ. + + + ΤΕΛΟΣ ΤΩΝ ΟΡΩΝ ΚΑΙ ΤΩΝ ΣΥΝΘΗΚΩΝ + + + Τρόπος εφαρμογής των όρων στα νέα Προγράμματα + + Εάν αναπτύσσετε ένα νέο πρόγραμμα και θέλετε να έχει τη μεγαλύτερη δυνατή +χρήση από το κοινό, ο καλύτερος τρόπος να επιτύχετε αυτό είναι να το χαρακτηρίσετε ελεύθερο λογισμικό, το οποίο όλοι θα μπορούν να αναδιανέμουν και να τροποποιούν υπό τους όρους αυτούς. + Για να γίνει αυτό, συνάψτε το ακόλουθο σημείωμα στο πρόγραμμα. Είναι πιο ασφαλές να το συνάψετε στην αρχή κάθε αρχείου πηγαίου κώδικα, ώστε να φέρεται πιο αποτελεσματικά η εξαίρεση της εγγύησης - και κάθε αρχείο θα πρέπει να διαθέτει τουλάχιστον τη γραμμή "πνευματικής ιδιοκτησίας" και έναν δείκτη για το που βρίσκεται το πλήρες σημείωμα. + + <μια γραμμή που παρέχει το όνομα του προγράμματος και μια σύντομη περιγραφή της λειτουργίας του.> + Copyright (C) <έτος> <όνομα δημιουργού> + + Το πρόγραμμα αυτό είναι ελεύθερο λογισμικό. Επιτρέπεται η αναδιανομή ή/και τροποποίησή του υπό τους όρους της Γενικής ’δειας Δημόσιας Χρήσης GNU (GNU General Public License), όπως αυτή δημοσιεύεται από το Ίδρυμα Ελεύθερου Λογισμικού (Free Software Foundation) - είτε της έκδοσης 2 της ’δειας, είτε (κατ' επιλογήν) οποιασδήποτε μεταγενέστερης έκδοσης. + + Το πρόγραμμα αυτό διανέμεται με την ελπίδα ότι θα αποδειχθεί χρήσιμο, παρόλα αυτά ΧΩΡΙΣ ΚΑΜΙΑ ΕΓΓΥΗΣΗ - χωρίς ακόμη και την έμμεση εγγύηση ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ή ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ. Για περισσότερες λεπτομέρειες ανατρέξτε στη Γενική ’δεια Δημόσιας Χρήσης GNU (GNU General Public License). + + Θα πρέπει να έχετε λάβει ένα αντίγραφο της Γενικής ’δειας Δημόσιας Χρήσης GNU (GNU General Public License) μαζί με αυτό το πρόγραμμα. Εάν όχι, επικοινωνήστε γραπτώς με το Ίδρυμα Ελεύθερου Λογισμικού (Free Software Foundation), Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Επίσης, προσθέστε πληροφορίες για τον τρόπο με τον οποίο μπορεί κάποιος να επικοινωνήσει μαζί σας μέσω ηλεκτρονικού ή παραδοσιακού ταχυδρομείου. + +Εάν το πρόγραμμα είναι αλληλεπιδραστικό, φροντίστε ώστε κατά την εκκίνησή του σε αλληλεπιδραστική λειτουργία να εμφανίζει ένα σύντομο σημείωμα όπως το παρακάτω: + + <Όνομα_προγράμματος> έκδοση <αριθμός_έκδοσης>, Copyright (C) <έτος> <όνομα_δημιουργού> + Το <όνομα_προγράμματος> διανέμεται ΧΩΡΙΣ ΚΑΜΙΑ ΕΓΓΥΗΣΗ. Για λεπτομέρειες πληκτρολογήστε `show w'. + Το λογισμικό αυτό είναι ελεύθερο, και η αναδιανομή του είναι ευπρόσδεκτη υπό συγκεκριμένους όρους. Πληκτρολογήστε `show c' για λεπτομέρειες. + +Οι υποθετικές εντολές `show w' και `show c' θα πρέπει να προβάλλουν τις αντίστοιχες ενότητες της Γενικής ’δειας Δημόσιας Χρήσης. Ασφαλώς οι εντολές που χρησιμοποιείτε δεν είναι απαραίτητο να ονομάζονται `show w' και `show c'. Μπορούν να είναι ακόμη και σύνδεσμοι που ενεργοποιούνται με πάτημα του ποντικιού ή στοιχεία μενού--οτιδήποτε ταιριάζει με το πρόγραμμά σας. + +Εάν κρίνετε απαραίτητο, θα πρέπει επίσης να ζητήσετε από τον εργοδότη σας (εάν εργάζεστε ως προγραμματιστής) ή τη σχολή σας, εάν υπάρχουν, να υπογράψουν μια "δήλωση αποκήρυξης πνευματικών δικαιωμάτων" (copyright disclaimer) για το πρόγραμμα. +Μπορείτε να ακολουθήσετε το παρακάτω δείγμα, συμπληρώνοντας τα ονόματα: + + Η <επωνυμία_εταιρίας/σχολής> αποκηρύσσει οποιοδήποτε δικαίωμα πνευματικής ιδιοκτησίας επί του προγράμματος <όνομα_προγράμματος>', το οποίο αποτελεί δημιουργία του <όνομα_δημιουργού>. + + <υπογραφή_εκπροσώπου_εταιρίας/σχολής>, <ημερομηνία, έτος> + + +Η παρούσα Γενική ’δεια Δημόσιας Χρήσης δεν επιτρέπει την ενσωμάτωση του προγράμματός σας σε ιδιόκτητα προγράμματα. Εάν το πρόγραμμά σας αποτελεί βιβλιοθήκη υπορουτίνας, θα είναι ενδεχομένως χρησιμότερο να επιτρέπετε σύνδεση ιδιόκτητων εφαρμογών με τη βιβλιοθήκη. Εάν όντως αυτό επιθυμείτε, χρησιμοποιήστε τη Γενική ’δεια Δημόσιας Χρήσης Βιβλιοθήκης GNU (GNU Library General Public License) αντί της παρούσας ’δειας. +</PRE> +</BODY> +</HTML>
\ No newline at end of file diff --git a/logo/src/xlogo/gpl/gpl-en.html b/logo/src/xlogo/gpl/gpl-en.html new file mode 100644 index 0000000..f404388 --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-en.html @@ -0,0 +1,499 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + + <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> + <title></title> + + +</head> + + +<body> + +<h3>Table of Contents</h3> + +<ul> + + <li><a name="TOC1" href="#SEC1">GNU GENERAL +PUBLIC LICENSE</a></li> + + <li> + <ul> + + <li><a name="TOC2" href="#SEC2">Preamble</a></li> + + <li><a name="TOC3" href="#SEC3">TERMS AND +CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></li> + + <li><a name="TOC4" href="#SEC4">How to +Apply These Terms to Your New Programs</a></li> + + </ul> + + </li> + +</ul> + +<hr> +<h3><a name="SEC1" href="#TOC1">GNU GENERAL +PUBLIC LICENSE</a></h3> + +<p> +Version 2, June 1991 +</p> + +<pre>Copyright (C) 1989, 1991 Free Software Foundation, Inc. <br>51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA<br><br>Everyone is permitted to copy and distribute verbatim copies<br>of this license document, but changing it is not allowed.<br></pre> + +<h3><a name="SEC2" href="#TOC2">Preamble</a></h3> + +<p> 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. +</p> + +<p> 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. +</p> + +<p> 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. +</p> + +<p> 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. +</p> + +<p> 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. +</p> + +<p> 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. +</p> + +<p> 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. +</p> + +<p> The precise terms and conditions for copying, distribution +and +modification follow. +</p> + +<h3><a name="SEC3" href="#TOC3">TERMS AND +CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></h3> + +<p> +<strong>0.</strong> 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". +</p> + +<p> +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. +</p> + +<p> +<strong>1.</strong> 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. +</p> + +<p> +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. +</p> + +<p> +<strong>2.</strong> 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: +</p> + +<dl> + + <dt></dt> + + <dd> <strong>a)</strong> You must cause the +modified files to carry prominent notices stating that you changed the +files and the date of any change. </dd> + + <dt></dt> + + <dd> <strong>b)</strong> 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. </dd> + + <dt></dt> + + <dd> <strong>c)</strong> 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.) </dd> + +</dl> + +<p> +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. +</p> + +<p> +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. +</p> + +<p> +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. +</p> + +<p> +<strong>3.</strong> 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: +</p> + +<!-- we use this doubled UL to get the sub-sections indented, --> +<!-- while making the bullets as unobvious as possible. --> +<dl> + + <dt></dt> + + <dd> <strong>a)</strong> 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, </dd> + + <dt></dt> + + <dd> <strong>b)</strong> 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, </dd> + + <dt></dt> + + <dd> <strong>c)</strong> 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.) + </dd> + +</dl> + +<p> +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. +</p> + +<p> +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. +</p> + +<p> +<strong>4.</strong> 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. +</p> + +<p> +<strong>5.</strong> 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. +</p> + +<p> +<strong>6.</strong> 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. +</p> + +<p> +<strong>7.</strong> 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. +</p> + +<p> +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. +</p> + +<p> +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. +</p> + +<p> +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. +</p> + +<p> +<strong>8.</strong> 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. +</p> + +<p> +<strong>9.</strong> 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. +</p> + +<p> +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. +</p> + +<p> +<strong>10.</strong> 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. +</p> + +<p><strong>NO WARRANTY</strong></p> + +<p> +<strong>11.</strong> 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. +</p> + +<p> +<strong>12.</strong> 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. +</p> + +<h3>END OF TERMS AND CONDITIONS</h3> + +<h3><a name="SEC4" href="#TOC4">How to +Apply These Terms to Your New Programs</a></h3> + +<p> 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. +</p> + +<p> 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. +</p> + +<pre><var>one line to give the program's name and an idea of what it does.</var><br>Copyright (C) <var>yyyy</var> <var>name of author</var><br><br>This program is free software; you can redistribute it and/or<br>modify it under the terms of the GNU General Public License<br>as published by the Free Software Foundation; either version 2<br>of the License, or (at your option) any later version.<br><br>This program is distributed in the hope that it will be useful,<br>but WITHOUT ANY WARRANTY; without even the implied warranty of<br>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>GNU General Public License for more details.<br><br>You should have received a copy of the GNU General Public License<br>along with this program; if not, write to the Free Software<br>Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.<br></pre> + +<p> +Also add information on how to contact you by electronic and paper +mail. +</p> + +<p> +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: +</p> + +<pre>Gnomovision version 69, Copyright (C) <var>year</var> <var>name of author</var><br>Gnomovision comes with ABSOLUTELY NO WARRANTY; for details<br>type `show w'. This is free software, and you are welcome<br>to redistribute it under certain conditions; type `show c' <br>for details.<br></pre> + +<p> +The hypothetical commands <samp>`show w'</samp> and <samp>`show +c'</samp> should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than <samp>`show +w'</samp> and +<samp>`show c'</samp>; they could even be mouse-clicks or +menu items--whatever +suits your program. +</p> + +<p> +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: +</p> + +<pre>Yoyodyne, Inc., hereby disclaims all copyright<br>interest in the program `Gnomovision'<br>(which makes passes at compilers) written <br>by James Hacker.<br><br><var>signature of Ty Coon</var>, 1 April 1989<br>Ty Coon, President of Vice<br></pre> + +<p> +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. +</p> + +</body> +</html> diff --git a/logo/src/xlogo/gpl/gpl-eo.html b/logo/src/xlogo/gpl/gpl-eo.html new file mode 100644 index 0000000..86f91db --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-eo.html @@ -0,0 +1,714 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + + <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> + <title>GNU General Public Licence</title> + + +</head> + + +<body> + +<pre><b><br> Note about this translation of Avizo pri ĉi tiu traduko de la<br> GNU General Public License GNUa Ĝenerala Publika Permesilo<br></b><br>This is an unofficial translation Ĉi tiu esperantigo de la «GNUa<br>of the GNU General Public License Ĝenerala publika permesilo» ne estas<br>into Esperanto. It was not oficiala. Ĝin ne publikigis «Free<br>published by the Free Software Software Foundation» kaj ĝi ne estas<br>Foundation, and does not legally jura dokumento determinanta<br>state the distribution terms for kondiĉojn por distribuado de<br>software that uses the GNU General programaro laŭ la «GNUa Ĝenerala<br>Public License – only the Publika Permesilo» – nur la<br>original English text of the GNU originala anglalingva teksto validas<br>GPL does that. However, we hope por tio. Tamen espereble la traduko<br>that this translation will help helpos la Esperanto-parolantojn pli<br>Esperanto speakers understand the bone kompreni la enhavon de la «GNUa<br>GNU General Public License better. Ĝenerala publika permesilo».<br><br>You can find the official text of La oficialan tekston de la GNUa<br>the GNU General Public License at Ĝenerala Publika Permesilo vidu ĉe<br> <a target="_blank" href="gpl-en.html">http://www.gnu.org/copyleft/gpl.html</a><br>Translated by Sergei B. Pokrovsky. Elangligis Sergio Pokrovskij.<br></pre> + +<h1> GNU General Public License / GNUa Ĝenerala Publika Permesilo +</h1> + +<h2> Esperantigo de la versio 2 (Junio 1991) +</h2> + +<blockquote> Copyright © 1989, 1991, Free Software +Foundation Inc. <br> + +59 Temple Place, Suite 330, Boston, MA 02111-1307 <br> + +Usono + <p> Ĉiu rajtas reprodukti kaj disvastigi neŝanĝitajn kopiojn de +ĉi tiu Permesilo; sed ŝanĝi ĝin oni ne rajtas. </p> + +</blockquote> + +<h2> Antaŭparolo +</h2> + +<p> +La pliparto de la permesiloj pri uzo de programo celas limigi vian +liberon ĝin kunhavigi kaj modifi. Male, la GNUa Ĝenerala Publika +Permesilo celas garantii vian liberon kunhavigi kaj modifi liberan +programaron – certigi ke la programaro estu libera por ĉiuj +uzantoj. Ĉi +tiu Ĝenerala Publika Permesilo validas por pliparto da programaro de +Free +Software Foundation (la Fondaĵo de Libera Programaro) kaj por multaj +aliaj programoj kies aŭtoroj volas ĝin uzi. (Por alia parto de la +programaro de Free Software Foundation validas, anstataŭe, +«GNU Library +General Public License», la <a name="re-lgpl" href="#lgpl">GNUa +Ĝenerala Publika Permesilo Biblioteka [1]</a>.) +Ankaŭ vi povas apliki ĝin al viaj programoj. +</p> + +<p> +Kiam ni parolas pri liberaj programoj, ja temas pri libero, ne pri +prezo. +Niaj Ĝeneralaj Publikaj Permesiloj estas faritaj por disponigi al vi la +liberon +</p> + +<ul> + + <li> <a name="re-distribui" href="#distribui">distribui +[2]</a> ekzemplerojn de liberaj programverkoj (kaj postuli pagon +por ili, se vi volas);</li> + + <li> ricevi la fontotekstojn aŭ povi preni ilin, se vi deziras;</li> + + <li> modifi la programojn aŭ uzi pecojn el ili en novaj liberaj +programoj;</li> + + <li> kaj scii ke vi rajtas fari tiojn.</li> + +</ul> + +<p> +Por protekti viajn rajtojn ni devas enkonduki limigojn kiuj malebligu +al +iu ajn rifuzi al vi tiujn rajtojn aŭ proponi al vi cedi ilin. Tiuj +limigoj esprimiĝas en certaj devigoj por vi, se vi distribuas +ekzemplerojn de programo aŭ se vi modifas ilin. +</p> + +<p> +Ekzemple, se vi distribuas ekzemplerojn de tia programo, ĉu senpage aŭ +kontraŭ pago, vi devas pludoni al la ricevantoj ĉiujn rajtojn je ĝi, +kiujn vi havas. Vi devas certigi ke ankaŭ la novaj posedantoj ricevu aŭ +povu havigi al si la fontotekstojn. Kaj vi devas informi ilin pri la +kondiĉoj, por ke ili sciu siajn rajtojn. +</p> + +<p> +Ni protektas viajn rajtojn en du paŝoj: +</p> + +<ol> + + <li> {ni} rezervas {al ni} la <a href="#copy" name="re-copy">aŭtorrajton [3]</a> je la programoj, kaj</li> + + <li> ni disponigas al vi ĉi tiun Permesilon, kiu donas al vi +juran eblon <a href="#prod" name="re-prod">reprodukti [4]</a>, distribui kaj/aŭ +modifi la programojn.</li> + +</ol> + +<p> +Krome, por protekti la aŭtorojn kaj nin mem, ni sciigas al ĉiuj ke +estas +nenia garantio pri la libera programaro. Personoj akirintaj programon +modifitan per tria partio sciu, ke ili ricevis ne la originalon, kaj +tial +la problemoj kaŭzitaj de triapartiaj ŝanĝoj ne kompromitu la reputacion +la originala aŭtoro. +</p> + +<p> +Fine, ĉiun liberan programon konstante minacas +<a href="#pat" name="re-pat">programa patento [5]</a>. +Ni malvolas ke perantoj de libera programo individue akiru patenton je +ĝi, per tio fakte farante la programon +<a href="#propr" name="re-propr">proprieta [6]</a>. Por malebligi tion +ni klarigis, ke patento estu koncesiita al ĉies ajn libera uzo +– aŭ tute +ne estu koncesiita. +</p> + +<p> +Nun sekvas la precizaj kondiĉoj pri reproduktado, distribuado kaj +modifado. +</p> + +<h2> La kondiĉoj pri reproduktado, distribuado kaj modifado +<br> + +laŭ la GNUa Ĝenerala Publika Permesilo +</h2> + +<p> +§0. Ĉi tiu Permesilo validas por ajna programo aŭ alia verko +entenanta +averton enmetitan de la posedanto de la aŭtorrajto, dirantan ke ĝi +estas +distribuebla laŭ la kondiĉoj de ĉi tiu Ĝenerala Publika Permesilo. +Ĉi-sube «Programo» indikas ĉian tian programon aŭ +verkon, kaj «verko +bazita sur la Programo» estas aŭ la Programo mem, aŭ ia ajn +derivita +verko laŭ la difino de la leĝo pri la aŭtorrajto +<a href="#deriv" name="re-deriv">[7]</a>: t.e. verko entenata +la Programon aŭ ties pecon, ĉu modifitan aŭ ne, kaj/aŭ tradukitan en +alian lingvon. (Ĉi tie kaj sube la termino <dfn>modifo</dfn> +kovras, senrezerve, +tradukojn laŭ la plej ĝenerala senco.) Ĉi-sube <dfn>vi</dfn> +indikas +koncesiulon de la Permesilo. +</p> + +<p> +Ĉi tiu Permesilo ne koncernas realigon de la ceteraj rajtoj, aliaj ol +reproduktado, distribuado kaj modifado. Rulado de la Programo ne estas +limigita, kaj ties eligaĵo estas koncernata nur se ĝia enhavo +konstituas +verkon bazitan sur la Programo (alie ol pro la fakto ke ĝi estas +rezulto +de rulo de la Programo). Ĉu tio validas aŭ ne, dependas de la funkcio +de +la Programo. +</p> + +<p> +§1. Vi rajtas senŝanĝe reprodukti kaj distribui ekzemplerojn +de la +fontoteksto de la Programo tia kia vi ĝin ricevis, sur ajna +datumportilo, +kondiĉe ke +</p> + +<ul> + + <li> ĉiu ekzemplero havu klare videblan kaj taŭgan avizon pri +la aŭtorrajto (copyright notice) kaj malgarantiilon (disclaimer of +warranty);</li> + + <li> ĉiuj avizoj pri ĉi tiu Permesilo kaj malgarantiiloj restas +netuŝitaj;</li> + + <li> kun la ekzemplero de la Programo la akiranto ricevu kopion +de ĉi tiu Permesilo.</li> + +</ul> + +<p> +Vi rajtas fakturi la fizikan agon por liverado de ekzemplero de la +Programo, kaj laŭvole vi rajtas oferti pagajn servojn garantiajn. +</p> + +<p> +§2. Vi rajtas modifi vian ekzemplerojn aŭ viajn ekzemplerojn +de la +Programo, aŭ ajnan ties pecon, tiel kreante verkon bazitan sur la +Programo. Vi rajtas reprodukti kaj distribui ekzemplerojn de tia verko +laŭ la reguloj de §1, se vi ankaŭ plenumas ĉiujn sekvajn +kondiĉojn: +</p> + +<ol type="a"> + + <li>la de vi modifitaj dosieroj enhavu bone videblan avizon ke +vi ŝanĝis ilin, kaj la datojn de ĉiuj ŝanĝoj;</li> + + <li>distribuante aŭ publikigante ajnan verkon kiu tute aŭ parte +entenas la Programon aŭ estas bazita sur la Programo aŭ ties parto, vi +devas koncesii la rajtojn uzi tiun verkon al ĉiu tria partio laŭ la +kondiĉoj de ĉi tiu Permesilo, sen ajna koncesia pago, kaj la verko estu +koncesiata kiel unu tuto;</li> + + <li>se dum la normala uzmaniero de la modifita programo ĝi +dialoge legas komandojn, vi devas zorgi ke ĝi, lanĉite en la plej +kutima maniero por dialoga uzo, eligu anoncon kiu entenu: + <ul> + + <li> avizon pri la aŭtorrajto;</li> + + <li> malgarantiilon (aŭ male, informon ke vi provizas +garantion);</li> + + <li> permeson al la uzantoj plu distribui la Programon sub +ĉi tiuj kondiĉoj, kaj indikon kiel la uzanto povas vidi kopion de ĉi +tiu Permesilo.</li> + + </ul> + +(Escepto: se la Programo mem estas dialoga sed normale ne eligas tian +anoncon, tiam ankaŭ por via derivita verko tia anonco ne estas deviga.)</li> + +</ol> + +<p> +Tiuj postuloj rilatas al la modifita verko konsiderata kiel unu tuto. +Se +apartigeblaj komponantoj de la verko ne estas derivitaj el la Programo, +kaj sencas uzi ilin kiel sendependajn kaj apartajn verkojn, tiam ĉi tiu +Permesilo ne koncernas tiujn komponantojn en la okazoj kiam vi +distribuas +ilin kiel apartajn verkojn. Sed kiam vi distribuas tiujn samajn +komponantojn kiel parton de tuto estanta verko bazita sur la Programo, +tiam la distribuado de tiu tuto obeu la regulojn de ĉi tiu Permesilo, +kaj +la rajtoj akirataj de la pluaj koncesiuloj surbaze de ĉi tiu Permesilo +etendiĝas ĝis la plena tuto, inklude ĉiujn ties partojn, sendepende +tion, +kiu aŭtoris ilin. +</p> + +<p> +Do, la motivo de ĉi tiu §2 ne estas akiri aŭ kontesti viajn la +rajtojn je +verko kiun vi aŭtoras; la celo estas realigi la rajton determini la +manieron distribui la derivitajn aŭ kolektivajn verkojn bazitajn sur la +Programo. +</p> + +<p> +Simpla kunesto de alia verko, ne bazita sur la Programo, apud la +Programo +(aŭ apud verko bazita sur la Programo) sur unu sama datumportilo memora +aŭ distribua ne etendas la kondiĉojn de ĉi tiu Permesilo sur tiun alian +verkon. +</p> + +<p> +§3. Vi rajtas reprodukti kaj distribui ekzemplerojn de la +Programo (aŭ de +verko bazita sur la Programo, laŭ §2) en celkodo aŭ en formo +de +plenumebla programo laŭ la reguloj de §§1 kaj 2 +ĉi-supre, kondiĉe ke vi +ankaŭ plenumas iun el la sekvaj postuloj: +</p> + +<ol type="a"> + + <li>la ekzempleron akompanu la responda kompleta fontoteksto en +komputile legebla formo, distribuenda laŭ la reguloj de +§§1 kaj 2 ĉi-supre, sur datumportilo kutime uzata por +interŝanĝi programaron; aŭ</li> + + <li>la ekzempleron akompanu skribita oferto, valida por almenaŭ +3 jaroj, disponigi al ajna tria partio, kontraŭ pago ne pli granda ol +via kosto de fizika transmeto, ekzempleron de kompleta responda +komputile legebla fontoteksto distribuenda laŭ la reguloj de +§§1 kaj 2 ĉi-supre, sur datumportilo kutime uzata por +interŝanĝi programaron; aŭ</li> + + <li>la ekzempleron akompanu la de vi ricevita informo pri +distribuado de la responda fontoteksto. (Tiu opcio validas nur okaze de +nekomerca distribuado kaj nur se vi ricevis la programon en celkodo aŭ +en formo de plenumebla programo, akompanitan de tia oferto laŭ +§3.b de ĉi tiu Permesilo.)</li> + +</ol> + +<p> +La fontoteksto de verko estas tiu ĝia formo, kiu plej oportunas por +modifado. La kompleta fontoteksto de plenumebla verko estas ĉiuj +fontotekstoj de ĉiuj komponantaj moduloj, plus ĉiuj dosieroj difinantaj +interfacojn, plus la skriptoj uzataj por regi tradukadon kaj instaladon +de la plenumebla programo. Tamen, per speciala escepto, en la +distribuata fontoteksto povas foresti ĉio normale kundistribuata (ĉu en +formo de fontoteksto aŭ kiel plenumebla programo) por la bazaj +komponantoj (programlingva tradukilo, operaciuma kerno ktp) de la +operaciumo per kiu ruliĝas la plenumebla programo – krom se +tia +komponanto mem apartenas al la plenumebla programo. +</p> + +<p> +Se distribuado de la verko en formo de plenumebla programo aŭ celkodo +okazas per atingebligo por kopiado el difinita loko, tiam disponigo de +egala atingeblo por kopii fontotekston el la sama loko plenumas la +postulon pri liverado de la fontoteksto, eĉ malgraŭ ke la tria partio +ne +estas devigata kopii la fontotekston kun la celkodo. +</p> + +<p> +§4. Vi ne rajtas reprodukti, modifi, subkoncesii aŭ distribui +la +Programon alie ol laŭ la malimplicaj reguloj de ĉi tiu Permesilo. Ĉia +provo alimaniere reprodukti, modifi, subkoncesii aŭ distribui la +Programon estas nevalida kaj aŭtomate estingas ĉiujn viajn rajtojn +donitajn per ĉi tiu Permesilo. Tamen la rajtoj de la partioj ricevintaj +de vi ekzemplerojn de la Programo aŭ rajtojn laŭ ĉi tiu Permesilo plu +validas, dum ili mem observas la kondiĉojn de la Permesilo. +</p> + +<p> +§5. Ne estas postulate ke vi akceptu ĉi tiun Permesilon, ĉar +vi ĝin ne +subskribis. Tamen nenio alia rajtigas vin modifi aŭ distribui la +Programon aŭ verkojn el ĝi derivitajn. Tiajn agojn malpermesas la leĝo, +krom se vi akceptas la Permesilon. Tial, se vi modifas aŭ distribuas +ekzemplerojn de la Programo (aŭ de verko bazita sur la Programo), vi +per +tio indikas vian akcepton de la rajtigo per la Permesilo fari tion, kaj +la akcepton de ĉiuj ĝiaj kondiĉoj kaj reguloj pri reprodukto, +distribuado +kaj modifado de la Programo aŭ de verkoj sur ĝi bazitaj. +</p> + +<p> +§6. Ĉiufoje kiam vi pludistribuas la Programon (aŭ verkon +bazitan sur la +Programo), la ricevanto aŭtomate ricevas permeson reprodukti, distribui +aŭ modifi la Programon laŭ la kondiĉoj kaj reguloj de ĉi tiu Permesilo. +Vi ne rajtas aldoni iajn ajn kromajn limigojn je la rajtoj de la +ricevanto provizitaj per ĉi tiu Permesilo. Vi ne responsas pri obeigo +de +triaj partioj al ĉi tiu Permesilo. +</p> + +<p> +§7. Se, sekve de juĝa decido, aŭ de plendo pri rompo de +patenta rajto, aŭ +pro alia kaŭzo (ne nepre ligita al la patenta juro), vi trafas sub +devigon (ĉu per juĝa decido, kontrakto aŭ alie), kiu kontraŭas al la +kondiĉoj de ĉi tiu Permesilo, tio ne rajtigas vin malobei la kondiĉojn +de +ĉi tiu Permesilo. Se vi ne povas distribui plenumante kaj la kondiĉojn +de ĉi tiu Permesilo, kaj viajn aliajn koncernajn devigojn, tiam vi +neniel +povas ĝin distribui. Ekzemple, se patenta permesilo malebligas al la +subkoncesiuloj, akirintaj ekzemplerojn de la Programo rekte de vi aŭ +per +tria partio, ĝin senhonorarie pludistribui, tiam vi nur povas rezigni +pri +distribuado de la Programo. +</p> + +<p> +Se iu postulo de ĉi tiu paragrafo iĝas nevalida aŭ neplenumebla ĉe +estiĝo +de iuj specialaj cirkonstancoj, aplikiĝu la resto de ĉi tiu paragrafo +sen +tiu postulo. Ĉi tiu paragrafo aplikiĝas plene +<a href="#cxeso" name="re-cxeso">{post la ĉeso de tia +cirkonstanco aŭ} [8]</a> se malestas tiaj cirkonstancoj. +</p> + +<p> +Ne estas celo de ĉi tiu §7 instigi vin rompi patentojn aŭ +aliajn +pretendojn je proprieto aŭ kontesti validon de tiaj pretendoj; la sola +celo estas protekti la integron de la sistemo de distribuado de libera +programaro, sistemo funkcianta per publikaj permesiloj. Multaj homoj +malavare kontribuis al la kreo de riĉa gamo da programaro distribuata +per +tiu sistemo, fidante je ĝia konsekvenca aplikado; la rajto elekti la +sistemon de distribuado de programverko apartenas al la aŭtoro / +donanto, +kaj ne koncesiulo ĝin altrudu. +</p> + +<p> +La intenco de ĉi tiu §7 estas klare prezenti, kiajn +konsekvencojn celas +estigi la ceteraj partoj de ĉi tiu Permesilo. +</p> + +<p> +§8. Se distribuadon kaj/aŭ uzadon de la Programo en iuj landoj +limigas +patentoj aŭ interfacoj kovritaj per aŭtorrajto, la praposedanto de la +aŭtorrajto, metanta la Programon sub la kondiĉojn de ĉi tiu Permesilo, +rajtas malimplice limigi la teritorion de distribuado de la Programo, +ekskludante tiajn landojn, tiel ke la distribuado estu permesita nur en +aŭ inter la landoj ne tuŝitaj per tia limigo. En tia okazo la koncerna +limigo estu rigardata kiel unu el la kondiĉoj de ĉi tiu Permesilo. +</p> + +<p> +§9. Laŭbezone «Free Software Foundation» +rajtas publikigi reviziitajn +kaj/aŭ novajn versiojn de la Ĝenerala Publika Permesilo. Tiaj versioj +konservos la bazajn principojn de ĉi tiu versio, sed povas diferenci en +detaloj, responde al novaj problemoj aŭ situacioj. +</p> + +<p> +Ĉiu versio ricevas sian propran numeron. Se la Programo indikas, ke ĝi +estas submetita al ĉi tiu Permesilo en ties difinita versinumero +«aŭ ajna +posta versio» («any later version»), tiam +vi rajtas, laŭplaĉe, sekvi aŭ +la kondiĉojn kaj regulojn de la indikita versio, aŭ tiujn de ajna pli +malfrua versio publikigita de «Free Software +Foundation». Se la Programo +ne indikas versinumeron, vi rajtas elekti iun ajn version iam ajn +publikigitan de «Free Software Foundation». +</p> + +<p> +§10. Se vi volas uzi partojn de la Programo en aliaj +programoj, kies +distribuaj kondiĉoj diferencas, skribe petu permeson de la aŭtoro. Por +programaro kies aŭtorrajton tenas «Free Software +Foundation», petu +permeson de «Free Software Foundation»; iam ĝi +faras esceptojn pri tio. +La decidojn de «Free Software Foundation» motivas +du celoj: konservi la +liberon de ĉiu verko derivita el nia libera programaro, kaj – +ĝenerale +– helpi kunhavigon kaj reuzon de programaro. +</p> + +<h2> Malgarantiilo +</h2> + +<p> +§11. <em>Ĉar la Programo estas koncesiata senpage, al +ĝi aplikiĝas nenia +garantio, kiom tion permesas la koncerna leĝo. Krom se alio estas +malimplice indikita en skriba formo, la tenantoj de la aŭtorrajto +kaj/aŭ +aliaj partioj disponigas la Programon «tia, kia ĝi +estas» («as is») sen +ia ajn garantio, nek esprimita nek implica, interalie sen la implica +garantio pri surmerkatigeblo, aŭ taŭgeco por konkreta uzo. La tuta +risko +koncerne la kvaliton kaj funkcikapablon de la programo estas via. Se la +programo montriĝos difekta, vi portos la kostojn de ĉiuj necesaj +servoj, +riparo aŭ korekto.</em> +</p> + +<p> +§12. <em>Neniokaze, krom se alion postulas aplikebla +leĝo aŭ skribita +interkonsento, neniu tenanto de la aŭtorrajto aŭ alia partio rajtigita +modifi kaj/aŭ pludistribui la Programon laŭ la ĉi-supraj permesoj, ne +responsos al vi pro la damaĝoj, inklude ĝeneralajn, specialajn, +akcidentajn aŭ malrektajn, rezultantaj el uzo aŭ maleblo uzi la +Programon (interalie, perdon aŭ difekton de datumoj, aŭ perdojn +suferitajn de vi aŭ de triaj partioj, aŭ nekapablo de la Programo +kunlabori kun iuj ajn aliaj programoj) – eĉ se tiaj tenanto +aŭ alia +partio estis avertitaj pri la eblo de tiaj damaĝoj.</em> +</p> + +<h3> Fino de la reguloj kaj kondiĉoj +</h3> + +<h2> Aldono:<br> + +Kiel apliki tiujn regulojn al viaj novaj programoj +</h2> + +<p> +Se vi verkas novan programon kaj volas fari ĝin kiel eble plej uzebla +por +la socio, la plej bona maniero atingi tion estas fari ĝin libera, kaj +tiam ĉiu povos ĝin pludistribui kaj modifi laŭ la kondiĉoj de ĉi tiu +Permesilo. +</p> + +<p> +Tiucele, aldonu al la programo la sekvajn avizojn. Plej sekure estas +meti ilin komence de ĉiu fonta dosiero, por plej klare averti pri +malesto +de garantioj; kaj ĉiu dosiero enhavu almenaŭ la linion kun la +aŭtorrajta +signo kaj referencon al la plena teksto de la avizo: +</p> + +<pre><unu linio kun la nomo de la programo kaj resumo de ĝia funkcio><br>Copyright © <jaro> <nomo la la aŭtoro><br><br>This program is free software; you Ĉi tiu verko estas libera programo;<br>can redistribute it and/or modify vi povas ĝin pludistribui kaj/aŭ<br>it under the terms of the GNU modifi je la kondiĉoj de la GNUa<br>General Public License as published Ĝenerala Publika Permesilo, eldonita<br>by the Free Software Foundation; de «Free Software Foundation», laŭ<br>either version 2 of the License, or la versio 2 de tiu Permesilo aŭ, se<br>(at your option) any later version. vi preferas, ajna posta versio.<br><br>This program is distributed in the Ni distribuas ĉi tiun programon<br>hope that it will be useful, but esperante ke ĝi estos utila, tamen<br>WITHOUT ANY WARRANTY; without even SEN IA AJN GARANTIO, i.a. sen la<br>the implied warranty of implica garantio pri SURMERKATIGEBLO<br>MERCHANTABILITY or FITNESS FOR A aŭ TAŬGECO POR IU KONKRETA CELO.<br>PARTICULAR PURPOSE. See the GNU Pliajn detalojn vidu en la GNUa<br>General Public License for more Ĝenerala Publika Permesilo.<br>details.<br><br>You should have received a copy of Ekzemplero de la GNUa Ĝenerala<br>the GNU General Public License Publika Permesilo devas esti<br>along with this program; if not, liverita al vi kun ĉi tiu programo;<br>write to the se vi ĝin ne ricevis, turnu vin al<br><br> Free SoftwareFoundation, Inc.,<br> 59 Temple Place, Suite 330,<br> Boston, MA 02111-1307<br> USA<br></pre> + +<p> +Krome, indiku kiel eblas vin kontakti per la reta aŭ papera poŝto. +</p> + +<p> +Se la programo estas dialoga, zorgu ke ĝi eligu mallongan avizon, kiel +la +ĉi-suba ekzemplo, ĉe startigo en la interaga reĝimo: +</p> + +<pre> Gnomovido, versio 69. Aŭtorrajto © <jaro> <aŭtornomo><br> Gnomovido estas distribuata SEN IA AJN GARANTIO;<br> por vidigi detalojn tajpu «show w».<br> Tio estas libera programo, kaj bonvenas ĝia distribuado laŭ certaj<br> kondiĉoj; por vidigi detalojn tajpu «show c».<br></pre> + +<p> +La proponitaj komandoj «show w» kaj «show +c» devus surekranigi la +koncernajn partojn de la Ĝenerala Publika Permesilo. Kompreneble, ili +povas havi aliajn nomojn; ili eĉ povas esti musklakoj aŭ menueroj +– io +ajn konvena al via programo. +</p> + +<p> +Se necesas, vi devas ankaŭ ricevi de via dunganto (se vi estas dungita +programisto) aŭ eventuale de reprezentanto de via +<a href="#dungo" name="re-dungo">lernejo [9]</a> skriban +malpretendon je la aŭtorrajto. Vi povas uzi ĉi-suban modelon, konvene +ŝanĝinte la nomojn: +</p> + +<blockquote> La firmao «ABCĈ» per ĉi tio +rezignas pri ĉiaj proprietaj rajtoj je la programo +«Gnomovido» (faranta pasaĵojn por tradukiloj) +verkita de Pro Gramisto. + <p> <subskribo de Mag Nato>, la 1an de aprilo 3001<br> + +Mag Nato, Prezidanto </p> + +</blockquote> + +<p> +Ĉi tiu Ĝenerala Publika Permesilo malebligas inkludigi vian programon +en +proprietan programaron. Se via programo estas biblioteko da +subprogramoj, +vi eble juĝos pli utila permesi bindi proprietajn aplikaĵojn kun la +biblioteko. Se vi volas tion, anstataŭ ĉi tiun Permesilon uzu la GNUan +Ĝeneralan Publikan Permesilon Bibliotekan. +</p> + +<h2> Notoj de la tradukinto +</h2> + +<p> +<a name="lgpl" href="#re-lgpl">[1]</a> +Lastatempe FSF preferas +nomi tiun permesilon ne «biblioteka» sed +«malplia» aŭ «reduktita» +(GNU Lesser General Public License); ĉe tio la angla siglo restas la +sama (LGPL). +</p> + +<p> +<a href="#re-distribui" name="distribui">[2] Distribui</a> programon: +disponigi atingon al ekzemplero de programo en +ajna formo por <a href="#prod" name="re-prod">reproduktado [4]</a>, +interalie per la Reto, vendo, ludono, pruntedono ktp. +</p> + +<p> +<a href="#re-copy" name="copy">[3]</a> Anglalingve temas pri +«copyright», kaj «kopirajto» ja +ekzistas en +Esperanto; tamen la termino «aŭtorrajto» ŝajnas iom +preferata. – La +angla teksto estas iom malklara: kiu iĝas la tenanto de la aŭtorrajto, +ĉu +nepre FSF aŭ eventuale iu alia, ekz-e la aŭtoro mem? La gramatiko de ĉi +tiu loko pensigas ke temas pri transdono de la aŭtorrajto al FSF; sed +en +la postaj rekomendoj ni vidas modelan ekzemplon +</p> + +<blockquote> Gnomovido, versio 69. Aŭtorrajto © +<jaro> <aŭtornomo> +</blockquote> + +<p> +Aŭ eble «ni» estas ne FSF sed +«oni»? +</p> + +<p> +<a href="#re-prod" name="prod">[4]</a> La originalo ĉiam parolas pri +«copying», tamen en la aŭtorrajta juro +la jura termino estas «reprodukti»: Reproduktado de +programo estas farado +de unu aŭ pli ol unu ekzempleroj de la programo sur ajna datumportilo, +inklude registradon de la programo en komputilan memoron. +</p> + +<p> +<a href="#re-pat" name="pat">[5]</a> La Usona juro ebligas patenti +certajn programojn (Software Patents). +</p> + +<p> +<a href="#re-propr" name="propr">[6]</a> Proprieta rajto je programo estas +la ekskluziva rajto plenumi kaj/aŭ permesi plenumi la sekvajn agojn: +</p> + +<ul> + + <li> publikigi programon;</li> + + <li> reprodukti programon, plene aŭ parte, en ajna formo;</li> + + <li> distribui la programon;</li> + + <li> modifi la programon (inklude tradukon en aliajn lingvojn);</li> + + <li> kaj aliajn agojn menciitajn en la koncerna leĝo.</li> + +</ul> + +<p> +<a href="#re-deriv" name="deriv">[7]</a> «derivative work under +copyright law», termino de la Usona leĝo. +</p> + +<p> +<a href="#re-cxeso" name="cxeso">[8]</a> La teksto intervinkula +en la originalo malestas, sed estus +memtrudiĝanta en la responda teksto rusa (kaj enestas en la rusa +traduko). +</p> + +<p> +<a href="#re-dungo" name="dungo">[9]</a> Postulo de Usona leĝo. Sed +ekz-e en Ruslando nur la dunganto povas +aŭtomate ricevi la aŭtorrajton je via verko, kaj nur je verko ofice +komisiita al vi (krom se la dunga kontrakto antaŭvidis alion). +</p> + +<h2> Tradukproblemoj +</h2> + +<p> +Ĉi tio estas mia unua teksto jura, kaj super ĉio la originalo estas en +fremda lingvo. Pri la senco de kelkaj lokoj mi havas dubojn. +</p> + +<dl> + + <dt>En §11</dt> + + <dd>The entire risk as to the quality and PERFORMANCE of the +program is with you.<br> + +La tuta risko koncerne la kvaliton kaj FUNKCIKAPABLON de la programo +estas via. <br> + +{Normale PERFORMANCE signifus «rendimento», sed la +kunteksto ŝajnas +postuli funkcikapablon, kiel en la traduko germana +(Leistungsfähigkeit); +cetere mi atendus ĝin unualoke, kaj nur poste zorgus pri kvalito.} </dd> + + <dt>En §12</dt> + + <dd>including any GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +damages<br> + +damaĝoj, inklude ĜENERALAJN, SPECIALAJN, AKCIDENTAJN aŭ MALREKTAJN <br> + +{Mi tradukis «laŭvorte», sen bone kompreni kio +estas tiuj «specialaj +damaĝoj» ktp; la rusa traduko ĉi tie parolas pri +«ĝeneralaj (ĉu sumaj?), +realaj, antaŭvideblaj kaj malrektaj damaĝoj»; la germana +traduko, pri +«allgemeiner oder spezieller Schäden, +Schäden durch Seiteneffekte +(Nebenwirkungen) oder Folgeschäden»; la ceteraj +tradukoj, same papage +kiel mi.} </dd> + + <dt>(garantio pri) surmerkatigeblo </dt> + + <dd>tiel mi tradukis «merchantability». +En la germana traduko, «Marktreife»; ruse, +proksimume, «var/ec/o, +var/esto, var/statuso»; france +«commercialisation». </dd> + +</dl> + +</body> +</html> diff --git a/logo/src/xlogo/gpl/gpl-es.html b/logo/src/xlogo/gpl/gpl-es.html new file mode 100644 index 0000000..f78887a --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-es.html @@ -0,0 +1,773 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + + <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> + <title>Licencia Pública General</title> + + +</head> + + +<body> + +<h3><font face="Verdana" size="2">Licencia +Pública General</font></h3> + +<p> +<font face="Verdana" size="2">Versión 2, +Junio de 1991<br> + +Traducción al Español : Diciembre de 2001 por<br> + +José María Saráchaga Fischer: +jmsarachaga at garaitia dot com +</font></p> + +<p> +<font face="Verdana" size="2"><b>Contribuciones:</b><br> + +13-Dic-2002 Fabián Rodríguez +www.fabianrodriguez.com +</font></p> + +<p> +<font face="Verdana" size="1"> > <a href="#preambulo">preámbulo</a><br> + +> <a href="#terminos">términos +y condiciones</a><br> + +> <a href="#aplicacion">cómo +aplicar esta licencia</a></font></p> + +<font face="Verdana" size="1"><font size="3"> +</font></font> +<hr><font face="Verdana" size="1"><font size="3"><tt>This is an unofficial +translation of the GNU General Public License into spanish. It was not +published by the Free Software Foundation, and does not legally state +the distribution terms for software that uses the GNU GPL--only the +original English text of the GNU GPL does that. However, we hope that +this translation will help spanish speakers understand the GNU GPL +better.<br> + +</tt></font></font> +<hr width="60%"><font face="Verdana" size="1"><font size="3"><tt>Esta es una traducción +NO oficial de la "GNU General Public License" al español. No +fué +publicada por la "FSF Free Software Foundation", y no respalda +legalmente los términos de distribución del +software que utiliza la +"GNU GPL", sólo el texto original en inglés lo +hace. Sin embargo +esperamos que esta traducción ayude a las personas de habla +hispana a +entender mejor la "GPL".<br> + +</tt></font></font> +<hr> +<p><font face="Verdana" size="1"><font face="Verdana" size="2"> +Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br> + +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Toda +persona tiene permiso de copiar y distribuir copias fieles de este +documento de licencia, pero no se permite hacer modificaciones. +</font></font></p> + +<p><font face="Verdana" size="1"><font face="Verdana" size="2"><br> + +<br> + +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><a name="preambulo"></a><font size="3"><b>PREAMBULO</b></font> +</font></font></p> + +<hr> +<font face="Verdana" size="1"><font face="Verdana" size="2">Los +contratos de licencia de la mayor parte del software están +diseñados +para quitarle su libertad de compartir y modificar dicho software. En +contraste, la "GNU General Public License" pretende garantizar su +libertad de compartir y modificar el software "libre", esto es para +asegurar que el software es libre para todos sus usuarios. Esta +licencia pública general se aplica a la mayoría +del software de la "FSF +Free Software Foundation" (Fundación para el Software Libre) +y a +cualquier otro programa de software cuyos autores así lo +establecen. +Algunos otros programas de software de la Free Software Foundation +están cubiertos por la "LGPL Library General Public License" +(Licencia +Pública General para Librerías), la cual puede +aplicar a sus programas +también. +</font></font> +<p><font face="Verdana" size="1"><font face="Verdana" size="2">Cuando +hablamos de software libre, nos referimos a libertad, no precio. +Nuestras licencias "General Public Licenses" están +diseñadas para +asegurar que: +</font></font></p> + +<ol> + + <font face="Verdana" size="1"><font face="Verdana" size="2"> <li> usted tiene la +libertad de distribuir copias del software libre (y cobrar por ese +sencillo servicio si así lo desea) </li> + + <li> recibir el código fuente (o tener la +posibilidad de obtenerlo si así lo desea) </li> + + <li> que usted puede modificar el software o utilizar partes de +el en nuevos programas de software libre </li> + + <li> que usted esté enterado de que tiene la +posibilidad de hacer todas estas cosas. </li> + + </font></font> +</ol> + +<font face="Verdana" size="1"><font face="Verdana" size="2">Para +proteger sus derechos, necesitamos hacer restricciones que prohiban a +cualquiera denegarle estos derechos o a pedirle que renuncie a ellos. +Estas restricciones se traducen en algunas responsabilidades para usted +si distribuye copias del software, o si lo modifica. +</font></font> +<p><font face="Verdana" size="1"><font face="Verdana" size="2">Por +ejemplo, si usted distribuye copias de un programa, ya sea +gratuitamente o por algun importe, usted debe dar al que recibe el +software todos los derechos que usted tiene sobre el mismo. Debe +asegurarse también que reciban el código fuente o +bién que puedan +obtenerlo si lo desean. Y por último debe mostrarle a esa +persona estos +términos para que conozca los derechos de que goza. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Nosotros +protegemos sus derechos en 2 pasos: (1) protegiendo los derechos de +autor del software y (2) ofreciendole este contrato de licencia que le +otorga permiso legal para copiar, distribuir y modificar el software. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Además, +para la protección de los autores de software y la nuestra, +queremos +asegurarnos de que toda persona entienda que no existe ninguna +garantía +del software libre. Si el software es modificado por alguien y lo +distribuye, queremos que quienes lo reciban sepan que la copia que +obtuvieron no es la original, por lo que cualquier problema provocado +por quien realizó la modificación no +afectará la reputación del autor +original. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Finalmente, +cualquier programa de software libre es constantemente amenazado por +las patentes de software. Deseamos evadir el peligro de que los +re-distribuidores de un programa de software libre obtenga +individualmente los derechos de patente con el fin de volver dicho +programa propietario. Para prevenir esto, hemos dejado en claro que +cualquier patente deberá ser licenciada para el uso libre de +toda +persona o que no esté licenciada del todo. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">A +continuación se describen con precisión los +términos y condiciones para copiar, distribuir y modificar +el +software. +</font></font></p> + +<p><font face="Verdana" size="1"><font face="Verdana" size="2"><br> + +<br> + +</font></font></p> + +<p> +</p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><a name="terminos"></a><font size="3"><b>TERMINOS Y CONDICIONES PARA COPIA, +MODIFICACION Y DISTRIBUCION</b></font> +</font></font></p> + +<hr> +<p><font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>0.</b></font> +Esta licencia aplica a cualquier programa o trabajo que contenga una +nota puesta por el propietario de los derechos del trabajo +estableciendo que su trabajo puede ser distribuido bajo los +términos de +esta "GPL General Public License". El "Programa", utilizado en lo +subsecuente, se refiere a cualquier programa o trabajo original, y el +"trabajo basado en el Programa" significa ya sea el Programa o +cualquier trabajo derivado del mismo bajo la ley de derechos de autor: +es decir, un trabajo que contenga el Programa o alguna +porción de el, +ya sea íntegra o con modificaciones y/o traducciones a otros +idiomas. +De aquí en adelante "traducción" +estará incluida (pero no limitada a) +en el término "modificación", y la persona a la +que se aplique esta +licencia será llamado "usted". +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Otras +actividades que no sean copia, distribución o +modificación no están +cubiertas en esta licencia y están fuera de su alcance. El +acto de +ejecutar el programa no está restringido, y la salida de +información +del programa está cubierta sólo si su contenido +constituye un trabajo +basado en el Programa (es independiente de si fue resultado de ejecutar +el programa). Si esto es cierto o no depende de la función +del +programa. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>1.</b></font> +Usted puede copiar y distribuir copias fieles del código +fuente del +programa tal como lo recibió, en cualquier medio, siempre +que +proporcione de manera conciente y apropiada una nota de derechos de +autor y una declaración de no garantía, +además de mantener intactas +todas las notas que se refieran a esta licencia y a la ausencia de +garantía, y que le proporcione a las demás +personas que reciban el +programa una copia de esta licencia junto con el Programa. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Usted puede +aplicar un cargo por el acto físico de transferir una copia, +y ofrecer +protección de garantía por una cuota, lo cual no +compromete a que el +autor original del Programa responda por tal efecto. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>2.</b></font> +Usted puede modificar su copia del Programa o de cualquier parte de el, +formando así un trabajo basado en el Programa, y copiar y +distribuir +tales modificaciones o bién trabajar bajo los +términos de la sección 1 +arriba descrita, siempre que cumpla con las siguientes condiciones: +</font></font></p> + +<p> +</p> + +<ol type="A"> + + <font face="Verdana" size="1"><font face="Verdana" size="2"> <li> Usted debe +incluir en los archivos modificados notas declarando que +modificó dichos archivos y la fecha de los cambios. </li> + + <li>Usted debe notificar que ese trabajo que distribuye +contiene totalmente +o en partes al Programa, y que debe ser licenciado como un conjunto sin +cargo alguno a cualquier otra persona que reciba sus modificaciones +bajo los términos de esta Licencia. </li> + + <li> Si el programa modificado lee normalmente comandos +interactivamente cuando es ejecutado, usted debe presentar un aviso, +cuando el programa inicie su ejecución en ese modo +interactivo de la +forma más ordinaria, que contenga una noticia de derechos de +autor y un +aviso de que no existe garantía alguna (o que sí +existe si es que usted +la proporciona) y que los usuarios pueden redistribuir el programa bajo +esas condiciones, e informando al usuario como puede ver una copia de +esta Licencia. (Excepción: si el programa en sí +es interactivo pero +normalmente no muestra notas, su trabajo basado en el Programa no tiene +la obligación de mostrar tales notas) </li> + + </font></font> +</ol> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Estos +requerimientos aplican al trabajo modificado como un todo. Si existen +secciones identificables de tal trabajo que no son derivadas del +Programa original, y pueden ser razonablemente consideradas trabajos +separados e independientes como tal, entonces esta Licencia y sus +términos no aplican a dichas secciones cuando usted las +distribuye como +trabajos separados. Pero cuando usted distribuye las mismas secciones +como parte de un todo que es un trabajo basado en el Programa, la +distribución del conjunto debe ser bajo los +términos de esta Licencia, +cuyos permisos para otras personas que obtengan el software se +extienden para todo el software, así como para cada parte de +el, +independientemente de quién lo escribió. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">No es la +intención de esta sección de reclamar derechos o +pelear sus derechos +sobre trabajos hechos enteramente por usted, en lugar de eso, la +intención es ejercer el derecho de controlar la +distribución de los +trabajos derivados o colectivos basados en el Programa. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Adicionalmente, +el simple agregado de otro trabajo NO basado en el Programa al Programa +en cuestión (o a un trabajo basado en el Programa) en +algún medio de +almacenamiento no pone el otro trabajo bajo el alcance de esta +Licencia. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>3.</b></font> +Usted puede copiar y distribuir el Programa (o un trabajo basado en +él, +bajo la Sección 2) en código objeto o en forma de +ejecutable najo los +términos de las secciones 1 y 2 arriba descritas siempre que +cumpla los +siguientes requisitos: +</font></font></p> + +<ol type="A"> + + <font face="Verdana" size="1"><font face="Verdana" size="2"> <li>Acompañarlo +con el correspondiente código fuente legible por la +máquina, que debe ser distribuído bajo los +términos de las secciones 1 +y 2 y en un medio comunmente utilizado para el intercambio de software, +o </li> + + <li> Acompañarlo con una oferta escrita, +válida por al menos 3 +años y para cualquier persona, por un cargo no mayor al +costo que +conlleve la distribución física del +código fuente correspondiente en un +medio comunmente utilizado para el intercambio de software, o </li> + + <li> Acompañarlo con la información que +usted recibió sobre la +oferta de distribución del código fuente +correspondiente. (Esta +alternativa está permitida sólo para +distribución no-comercial y sólo +si usted recibió el Programa en código objeto o +en forma de ejecutable +con tal oferta de acuerdo a la subsección b anterior) </li> + + </font></font> +</ol> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">El código +fuente de un trabajo significa la forma preferida de hacer +modificaciones al mismo. Para un trabajo ejecutable, un +código fuente +completo significa todo el código fuente de todos los +módulos que +contiene, mas cualquier archivo de definición de interfases, +mas los +programas utilizados para controlas la compilación y la +instalación del +ejecutable. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Sinembargo, como +excepción especial, no se requiere que el código +fuente distribuído incluya cualquier cosa que no sea +normalmente +distribuída con las componentes mayores (compilador, kernel, +etc.) +del sistema operativo en el cual el ejecutable corre, a menos de que +una componente en particular acompañe al ejecutable. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Si la +distribución del ejecutable o del código objeto +se hace ofreciendo +acceso a copiar desde un lugar designado, entonces el ofrecer acceso +equivalente para copiar el código fuente desde el mismo +lugar se +considera distribución del código fuente, aunque +las demás personas no +copien el código fuente junto con el código +objeto. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>4.</b></font> +Usted no puede copiar, modificar, sub-licenciar ni distribuir el +Programa a menos que sea expresamente bajo esta Licencia, de otra forma +cualquier intento de copiar, modificar, sub-licenciar o distribuir el +programa es nulo, y automáticamente causará la +pérdida de sus derechos +bajo esta Licencia. Sin embargo, cualquier persona que haya recibido +copias o derechos de usted bajo esta Licencia no verán +terminadas sus +Licencias ni sus derechos perdidos mientras ellas continúen +cumpliendo +los términos de esta Licencia. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>5.</b></font> +Usted no está obligado a aceptar esta Licencia, dado que no +la ha +firmado. Sin embargo, nada le otorga el permiso de modificar o +distribuir el Programa ni sus trabajos derivados. Estas acciones +están +prohibidas por la ley si usted no acepta esta Licencia. Sin embargo, +modificando o distribuyendo el Programa (o cualquier trabajo basado en +el Programa) indica su aceptación de esta Licencia y de +todos sus +términos y condiciones para copiar, distribuir o modificar +el Programa +y/o trabajos basados en el. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>6.</b></font> +Cada vez que usted redistribuye el Programa (o cualquier trabajo basado +en el Programa), la persona que lo recibe automáticamente +recibe una +licencia del autor original para copiar, distribuir o modificar el +Programa sujeto a estos términos y condiciones. Usted no +puede imponer +ninguna restricción adicional a las personas que reciban el +Programa +sobre los derechos que en esta Licencia se les otorga. Usted no es +responsable de forzar a terceras personas en el cumplimiento de esta +Licencia. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>7.</b></font> +Si como consecuencia de un veredicto de un juzgado o por el alegato de +infringir una patente o por cualquier otra razón (no +limitado solo a +cuestiones de patentes) se imponen condiciones sobre usted que +contradigan los términos y condiciones de esta Licencia, +éstas no le +excusan de los términos y condiciones aquí +descritos. Si usted no puede +distribuir el producto cumpliendo totalmente con las obligaciones +concernientes a la resolución oficial y al mismo tiempo con +las +obligaciones que se describen en este contrato de Licencia, entonces no +podrá distribuir más este producto. Por ejemplo, +si una licencia de +patente no permitirá la distribución del Programa +de forma libre de +regalías (sin pago de regalías) por parte de +quienes lo reciban directa +o indirectamente, entonces la única forma de cumplir con +ambas +obligaciones es renunciar a la distribución del mismo. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Si +cualquier parte de esta sección resulta inválida, +inaplicable o no +obligatoria bajo cualquier circunstancia en particular, la tendencia de +esta es a aplicarse, y la sección completa se +aplicará bajo otras +circunstancias. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">La +intención de esta sección no es la de inducirlo a +infringir ninguna ley +de patentes, ni tampoco infringir algún reclamo de derechos, +ni +discutir la validez de tales reclamos; esta sección tiene el +único +propósito de proteger la integridad del sistema de +distribución del +software libre, que está implementado por +prácticas de licencia +pública. Mucha gente ha hecho generosas contribuciones a la +amplia gama +de software distribuido bajo este sistema favoreciendo así +la constante +aplicación de este sistema de distribución; es +decisión del +autor/donador si su Programa será distribuído +utilizando este u otro +sistema de distribución, y la persona que recibe el software +no puede +obligarlo a hacer ninguna elección en particular. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Esta sección +pretende dejar muy en claro lo que se cree que será una +consecuencia del resto de esta Licencia. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>8.</b></font> +Si la distribución y/o el uso del Programa se restringe a +algunos +países ya sea por patentes, interfases protegidas por +derechos de +autor, el propietario original de los derechos de autor que ubica su +Programa bajo esta Licencia puede agregar una restricción +geográfica de +distribución explícita excluyendo los +países que aplique, dando como +resultado que su distribución sólo se permita en +los países no +excluídos. En tal caso, esta Licencia incorpora la +limitación como si +hubiera sido escrita en el cuerpo de esta misma Licencia. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>9.</b></font> +La "FSF Free Software Foundation" puede publicar versiones nuevas o +revisadas de la "GPL General Public License" de uno a otro momento. +Estas nuevas versiones mantendrán el espíritu de +la presente versión, +pero pueden diferir en la inclusión de nuevos problemas o en +la manera +de tocar los problemas o aspectos ya presentes. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Cada +versión tendrá un número de +versión que la distinga. Si el Programa +especifica un número de versión para esta +Licencia que aplique a él y +"cualquier versión subsecuente", usted tiene la +opción de seguir los +términos y condiciones de dicha versión o de +cualquiera de las +posteriores versiones publicadas por la "FSF". Si el programa no +especifica una versión en especial de esta Licencia, usted +puede elegir +entre cualquiera de las versiones que han sido publicadas por la "FSF". +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>10.</b></font> +Si usted desea incorporar partes del Programa en otros Programas de +software libre cuyas condiciones de distribución sean +distintas, deberá +escribir al autor solicitando su autorización. Para +programas de +software protegidas por la "FSF Free Software Foundation", +deberá +escribir a la "FSF" solicitando autorización, en ocasiones +hacemos +excepciones. Nuestra decisión será guiada por dos +metas principales: +</font></font></p> + +<ul> + + <font face="Verdana" size="1"><font face="Verdana" size="2"> <li> mantener el +estado de libertad de todos los derivados de nuestro software libre </li> + + <li> promover el uso comunitario y compartido del software en +general </li> + + </font></font> +</ul> + +<p><font face="Verdana" size="1"><font face="Verdana" size="2"><br> + +<br> + +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="3"><b>NO +EXISTE GARANTIA ALGUNA</b></font> +</font></font></p> + +<hr> +<p><font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>11.</b></font> +DEBIDO A QUE EL PROGRAMA SE OTORGA LIBRE DE CARGOS Y REGALIAS, NO +EXISTE NINGUNA GARANTIA PARA EL MISMO HASTA DONDE LO PERMITA LA LEY +APLICABLE. A EXCEPCION DE QUE SE INDIQUE OTRA COSA, LOS PROPIETARIOS DE +LOS DERECHOS DE AUTOR PROPORCIONAN EL PROGRAMA "COMO ES" SIN NINGUNA +GARANTIA DE NINGUN TIPO, YA SEA EXPLICITA O IMPLICITA, INCLUYENDO, PERO +NO LIMITADA A, LAS GARANTIAS QUE IMPLICA EL MERCADEO Y EJERCICIO DE UN +PROPOSITO EN PARTICULAR. CUALQUIER RIESGO DEBIDO A LA CALIDAD Y +DESEMPEÑO DEL PROGRAMA ES TOMADO COMPLETAMENTE POR USTED. SI +EL +SOFTWARE MUESTRA ALGUN DEFECTO, USTED CUBRIRA LOS COSTOS DE CUALQUIER +SERVICIO, REPARACION O CORRECCION DE SUS EQUIPOS Y/O SOFTWARE QUE +REQUIERA. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="4"><b>12.</b></font> +EN NINGUN CASO NI BAJO NINGUNA CIRCUNSTANCIA EXCEPTO BAJO SOLICITUD DE +LA LEY O DE COMUN ACUERDO POR ESCRITO, NINGUN PROPIETARIO DE LOS +DERECHOS DE AUTOR NI TERCERAS PERSONAS QUE PUDIERAN MODIFICAR Y/O +REDISTRIBUIR EL PROGRAMA COMO SE PERMITE ARRIBA, SERAN RESPONSABLES DE +LOS DAÑOS CORRESPONDIENTES AL USO O IMPOSIBILIDAD DE USAR EL +PROGRAMA, +SIN IMPORTAR SI SON DAÑOS GENERALES, ESPECIALES, +INCIDENTALES O +CONSEQUENTES CORRESPONDIENTES AL USO O IMPOSIBILIDAD DE USAR EL +PROGRAMA (INCLUYENDO PERO NO LIMITADO A LA PERDIDA DE INFORMACION O +DETERIORO DE LA MISMA AFECTANDOLO A USTED, A TERCERAS PERSONAS QUE SEA +POR FALLAS EN LA OPERACION DEL PROGRAMA O SU INTERACCION CON OTROS +PROGRAMAS) INCLUSIVE SI TAL PROPIETARIO U OTRAS PERSONAS HAYAN SIDO +NOTIFICADAS DE TALES FALLAS Y DE LA POSIBILIDAD DE TALES +DAÑOS. +</font></font></p> + +<p> +</p> + +<hr> +<font face="Verdana" size="1"><font face="Verdana" size="2"><font size="3"><b>FIN +DE TERMINOS Y CONDICIONES</b></font> +</font></font> +<p><font face="Verdana" size="1"><font face="Verdana" size="2"><br> + +<br> + +<br> + +<br> + +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2"><a name="aplicacion"></a><font size="3"><b>Cómo aplicar estos +términos a sus nuevos programas?</b></font> +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Si usted +desarrolla un nuevo Programa y desea que sea lo más +público posible, el +mejor modo de hacerlo es haciendolo Software Libre donde toda persona +lo puede redistribui y cambiar bajo estos términos. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Para hacer +esto, agregue las siguientes notas al programa. Es más +seguro +agregarlas al inicio de cada archivo del código fuente para +notificar +de manera más efectiva la ausencia de garantía; y +cada archivo debe de +contener al menos la línea de "Copyright" o derechos de +autor y una +referencia de donde se puede encontrar la nota completa. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">ejemplo: +</font></font></p> + +<p> +</p> + +<dir> +<pre><font face="Verdana" size="1"><font face="Verdana" size="2"><font size="3"><i>esta línea que contenga el nombre del programa y una idea de lo que hace.<br>Copyright (C) AÑO nombre del autor<br><br>Este programa es Software Libre; usted puede redistribuirlo<br>y/o modificarlo bajo los términos de la "GNU General Public<br>License" como lo publica la "FSF Free Software Foundation",<br>o (a su elección) de cualquier versión posterior.<br><br>Este programa es distribuido con la esperanza de que le será<br>útil, pero SIN NINGUNA GARANTIA; incluso sin la garantía<br>implícita por el MERCADEO o EJERCICIO DE ALGUN PROPOSITO en<br>particular. Vea la "GNU General Public License" para más<br>detalles.<br><br>Usted debe haber recibido una copia de la "GNU General Public<br>License" junto con este programa, si no, escriba a la "FSF<br>Free Software Foundation, Inc.", 59 Temple Place - Suite 330,<br>Boston, MA 02111-1307, USA.<br></i></font></font></font></pre> + +</dir> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Adicionalmente agregue +información de cómo contactarle por correo +electrónico y convencional. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Si el programa es +interactivo, ponga en la salida del programa una nota corta al iniciar +el modo interactivo: +</font></font></p> + +<p> +</p> + +<dir> +<pre><font face="Verdana" size="1"><font face="Verdana" size="2"><font size="3"><i>Gnomovision version 69, Copyright (C) AÑO nombre del autor<br>Gnomovision no tiene NINGUNA GARANTIA, para más detalles<br>escriba 'show w'. Este es Software Libre, y usted está<br>permitido para redistribuirlo bajo ciertas condiciones;<br>escriba 'show c' para más detalles.<br></i></font></font></font></pre> + +</dir> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Estos +supuestos comandos 'show w' y 'show c' deberán mostrar las +partes +apropiadas de la "GPL General Public License". Por supuesto, los +comandos que utilice pueden ser distintos, pueden ser incluso "clicks" +del ratón, opciones de menús etc, lo +más apropiado para su programa. +</font></font></p> + +<p> +<font face="Verdana" size="1"><font face="Verdana" size="2">Usted +debería hacer que su jefe de proyecto (si trabaja como +programador) o +su escuela, si aplica, firme una "declaración de derechos de +autor" +para el programa, si se necesita. Aquí hay un ejemplo, +modifique los +nombres: +</font></font></p> + +<p> +</p> + +<dir> +<pre><font face="Verdana" size="1"><font face="Verdana" size="2"><font size="3"><i>Yoyodyne, Inc., aquí vienen las declaraciones de derechos de autor<br>interés en el programa 'Gnomovision'<br>(lo que make pasa al compilador)<br>escrito por James Hacker.<br><br>firma de Ty Coon, 1 de Abril 1989<br>Ty Coon, Presidente<br></i></font></font></font></pre> + +</dir> + +<font face="Verdana" size="1"><font face="Verdana" size="2">Esta +Licencia Pública General no permite incorporar su programa +en programas +propietarios. Si su programa es una librería de subrutinas, +puede ser +más útil permitir que se ligue en tiempo de +compilación o ejecución a +aplicaciones propietarias. Si esto es lo que quiere hacer, use la +licencia Pública General para Librerías en lugar +de esta licencia. +</font></font> +</body> +</html> diff --git a/logo/src/xlogo/gpl/gpl-fr.html b/logo/src/xlogo/gpl/gpl-fr.html new file mode 100644 index 0000000..33cef97 --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-fr.html @@ -0,0 +1,580 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> + <title>Licence</title> +</head> +<body> +<em> +<p> + Ceci est une traduction non officielle de la GNU General Public + License en français. Elle n'a pas été publiée par la Free + Software Foundation, et ne détermine pas les termes de + distribution pour les logiciels qui utilisent la GNU GPL, seul + le texte anglais original de la GNU GPL déterminent ces + termes. Cependant, nous espérons que cette traduction aidera les + francophones à mieux comprendre la GNU GPL. + + </p> + + </em> + + +<h2>Licence Publique Générale GNU</h2> + + +<p>Les licences de la plupart des logiciels sont + conçues pour vous enlever toute liberté de les partager et de les + modifier. </p> + + +<p>A contrario, la Licence Publique Générale est destinée à garantir + votre liberté de partager et de modifier les logiciels libres, + et à assurer que ces logiciels soient libres pour tous leurs + utilisateurs. </p> + + +<p>La présente Licence Publique Générale s'applique à la + plupart des logiciels de la Free Software Foundation, ainsi + qu'à tout autre programme pour lequel ses auteurs s'engagent à + l'utiliser.</p> + + +<p>(Certains autres logiciels de la Free Software Foundation + sont couverts par la GNU Lesser General Public License à la place.)</p> + + +<p>Vous pouvez aussi l'appliquer aux programmes qui sont les vôtres.</p> + + +<p>Quand nous parlons de logiciels libres, nous parlons de + liberté, non de prix.</p> + + +<p>Nos licences publiques générales sont conçues pour vous donner + l'assurance d'être libres de distribuer des copies des + logiciels libres (et de facturer ce service, si vous le + souhaitez), de recevoir le code source ou de pouvoir + l'obtenir si vous le souhaitez, de pouvoir modifier les + logiciels ou en utiliser des éléments dans de nouveaux + programmes libres et de savoir que vous pouvez le + faire. </p> + + +<p>Pour protéger vos droits, il nous est nécessaire d'imposer + des limitations qui interdisent à quiconque de vous refuser + ces droits ou de vous demander d'y renoncer.</p> + + +<p>Certaines responsabilités vous incombent en raison de ces + limitations si vous distribuez des copies de ces logiciels, ou + si vous les modifiez.</p> + + +<p>Par exemple, si vous distribuez des copies d'un tel + programme, à titre gratuit ou contre une rémunération, vous devez + accorder aux destinataires tous les droits dont vous disposez. + </p> + + +<p>Vous devez vous assurer qu'eux aussi reçoivent ou puissent + disposer du code source.</p> + + +<p>Et vous devez leur montrer les présentes conditions afin + qu'ils aient connaissance de leurs droits.</p> + + +<p>Nous protégeons vos droits en deux étapes : (1) nous sommes + titulaires des droits d'auteur du logiciel, et + (2) nous vous délivrons cette licence, qui vous donne + l'autorisation légale de copier, distribuer et/ou modifier + le logiciel.</p> + + +<p>En outre, pour la protection de chaque auteur ainsi que la nôtre, + nous voulons nous assurer que chacun comprenne que ce logiciel libre ne fait l'objet + d'aucune garantie.</p> + + +<p>Si le logiciel est modifié par quelqu'un d'autre puis + transmis à des tiers, nous voulons que les destinataires + soient mis au courant que ce qu'ils ont reçu n'est pas le logiciel d'origine, de sorte + que tout problème introduit par d'autres ne puisse entacher + la réputation de + l'auteur originel.</p> + + +<p>En définitive, un programme libre restera à la merci des + brevets de logiciels.</p> + + +<p>Nous souhaitons éviter le risque que les redistributeurs + d'un programme libre fassent des demandes individuelles de + licence de brevet, ceci ayant pour effet de rendre le programme + propriétaire. + </p> + + +<p>Pour éviter cela, nous établissons clairement que toute licence de brevet + doit être concédée de façon à ce que l'usage en soit libre pour tous + ou bien qu'aucune licence ne soit concédée.</p> + + +<p>Les termes exacts et les conditions de copie, distribution et + modification sont les suivants:</p> + + +<h2>Conditions de copie, distribution + et modification de la Licence Publique Générale GNU.</h2> + + +<p>0. La présente Licence s'applique à tout programme + ou tout autre ouvrage contenant un avis, apposé par le titulaire des + droits d'auteur, stipulant qu'il peut être distribué au titre + des conditions de la présente Licence Publique + Générale.</p> + + +<p>Ci-après, le "Programme" désigne l'un quelconque de ces + programmes ou ouvrages, et un "ouvrage fondé sur le Programme" + désigne soit le Programme, soit un ouvrage qui en dérive au + titre des lois sur le droit d'auteur : en d'autres termes, + un ouvrage contenant le Programme ou une partie de + ce dernier, soit à l'identique, soit avec des modifications et/ou + traduit dans un autre langage.</p> + + +<p>(Ci-après, le terme "modification" implique, sans s'y réduire, le terme traduction)</p> + + +<p>Chaque concessionaire sera désigné par "vous".</p> + + +<p>Les activités autres que la copie, la distribution et + la modification ne sont pas couvertes par la présente Licence + ; elles sont hors de son champ d'application.</p> + + +<p>L'opération consistant à exécuter le Programme n'est soumise à aucune limitation + et les sorties du programme ne sont couvertes que si leur + contenu constitue un ouvrage fondé sur le Programme + (indépendamment du fait qu'il ait été réalisé par l'exécution + du Programme).</p> + + +<p>La validité de ce qui précède dépend de ce que fait le + Programme.</p> + + +<p>1. Vous pouvez copier et distribuer des copies à + l'identique du code source du Programme tel que vous l'avez + reçu, sur n'importe quel support, du moment que vous apposiez + sur chaque copie, de manière ad hoc et parfaitement + visible, l'avis de droit d'auteur adéquat et + une exonération de garantie ; que vous gardiez intacts tous les + avis faisant référence à la présente Licence et à l'absence de + toute garantie ; et que vous fournissiez à tout destinataire du + Programme autre que vous-même un exemplaire de la présente + Licence en même temps que le Programme.</p> + + +<p>Vous pouvez faire payer l'acte physique de + transmission d'une copie, et vous pouvez, à votre discrétion, + proposer une garantie contre rémunération.</p> + + +<p>2. Vous pouvez modifier votre copie ou des copies du Programme + ou n'importe quelle partie de celui-ci, créant ainsi un ouvrage + fondé sur le Programme, et copier et distribuer de telles modifications ou ouvrage selon les + termes de l'Article 1 ci-dessus, à condition de vous conformer également + à chacune des obligations suivantes :</p> + + +<p>a) Vous devez munir les fichiers modifiés d'avis bien visibles + stipulants que vous avez modifié ces + fichiers, ainsi que la date de chaque modification ;</p> + + +<p>b) Vous devez prendre les dispositions nécessaires pour que + tout ouvrage + que vous distribuez ou publiez, et qui, en totalité ou en partie, + contient ou est fondé sur le Programme - ou une partie + quelconque de ce dernier - soit concédé comme un tout, + à titre gratuit, à n'importe quel tiers, au titre des conditions + de la présente Licence.</p> + + +<p>c) Si le programme modifié lit habituellement des instructions + de façon interactive lorsqu'on l'exécute, vous devez, + quand il commence son exécution pour ladite + utilisation interactive de la manière la plus usuelle, faire + en sorte qu'il imprime ou affiche une annonce + comprenant un avis de droit d'auteur ad hoc, et un avis + stipulant qu'il n'y a pas de garantie (ou bien indiquant que + c'est vous qui fournissez la garantie), et que + les utilisateurs peuvent redistribuer le programme en respectant + les présentes obligations, et expliquant à l'utilisateur comment + voir une copie de la présente Licence.</p> + + +<p>(Exception : si le Programme est lui-même interactif + mais n'imprime pas habituellement une telle annonce, votre + ouvrage fondé sur le Programme n'est pas obligé + d'imprimer une annonce).</p> + + +<p>Ces obligations s'appliquent à l'ouvrage modifié + pris comme un tout. + </p> + + +<p>Si des éléments identifiables + de cet ouvrage ne sont pas fondés sur le Programme et peuvent + raisonnablement être considérés comme des ouvrages indépendants + distincts en eux mêmes, alors la présente Licence et + ses conditions ne + s'appliquent pas à ces éléments lorsque vous les distribuez + en tant qu'ouvrages distincts.</p> + + +<p> + Mais lorsque vous distribuez ces mêmes éléments comme partie + d'un tout, lequel constitue un ouvrage fondé sur le Programme, + la distribution de ce tout doit être soumise aux conditions de + la présente Licence, et les autorisations qu'elle octroie aux + autres concessionnaires s'étendent à l'ensemble de l'ouvrage et + par conséquent à chaque et toute partie indifférement de qui + l'a écrite. + </p> + + +<p>Par conséquent, l'objet du présent article n'est pas de revendiquer des droits + ou de contester vos droits sur un ouvrage entièrement écrit par + vous; son objet est plutôt d'exercer le droit de contrôler + la distribution d'ouvrages dérivés ou d'ouvrages collectifs fondés + sur le Programme. + </p> + + +<p> + De plus, la simple proximité du Programme avec un autre + ouvrage qui n'est pas fondé sur le Programme (ou un ouvrage + fondé sur le Programme) sur une partition d'un espace de + stockage ou un support de distribution ne place pas cet autre + ouvrage dans le champ d'application de la présente Licence. + </p> + + +<p>3. Vous pouvez copier et distribuer le Programme (ou un + ouvrage fondé sur lui, selon l'Article 2) sous forme de code + objet ou d'exécutable, selon les termes des Articles 1 et 2 + ci-dessus, à condition que vous accomplissiez l'un des points + suivants :</p> + + +<p>a) L'accompagner de l'intégralité du code source correspondant, + sous une forme lisible par un ordinateur, lequel doit être distribué + au titre + des termes des Articles 1 et 2 ci-dessus, sur un support + habituellement utilisé pour l'échange de logiciels; ou,</p> + + +<p>b) L'accompagner d'une proposition écrite, valable pendant + au moins trois ans, de fournir à tout tiers, à un tarif qui + ne soit pas supérieur à ce que vous coûte l'acte physique de + réaliser une distribution source, une copie intégrale du code + source correspondant sous une forme lisible par un + ordinateur, qui sera distribuée au titre des termes des + Articles 1 et 2 ci-dessus, sur un support habituellement + utilisé pour l'échange de logiciels; ou, + </p> + + +<p>c) L'accompagner des informations reçues par vous concernant +la proposition de distribution du code source correspondant. (Cette +solution n'est autorisée que dans le cas d'une distribution non +commerciale et seulement si vous avez reçu le programme sous +forme de code objet ou d'exécutable accompagné d'une +telle proposition - en conformité avec le sous-Article b +ci-dessus.) </p> + + +<p>Le code source d'un ouvrage désigne la forme favorite pour + travailler à des modifications de cet ouvrage. Pour un + ouvrage exécutable, le code source intégral désigne la + totalité du code source de la totalité des modules qu'il + contient, ainsi que les éventuels fichiers de définition des + interfaces qui y sont associés, ainsi que les scripts utilisés + pour contrôler la compilation et l'installation de + l'exécutable. Cependant, par exception spéciale, le code + source distribué n'est pas censé inclure quoi que ce soit de + normalement distribué (que ce soit sous forme source ou + binaire) avec les composants principaux (compilateur, noyau, + et autre) du système d'exploitation sur lequel l'exécutable + tourne, à moins que ce composant lui-même n'accompagne + l'exécutable. + </p> + + +<p> + Si distribuer un exécutable ou un code objet consiste à + offrir un accès permettant leur copie depuis un + endroit particulier, alors l'offre d'un accès équivalent pour + copier le code source depuis le même endroit compte comme une + distribution du code source - même si les tiers ne sont pas + contraints de copier le source en même temps que le code + objet. + </p> + + +<p>4. Vous ne pouvez copier, modifier, concéder en sous-licence, ou distribuer + le Programme, sauf tel qu'expressément prévu par la présente Licence. + Toute tentative de copier, modifier, concéder en sous-licence, ou + distribuer le Programme d'une autre manière est réputée non valable, et met + immédiatement fin à vos droits au titre de la présente Licence. + Toutefois, les tiers ayant reçu de vous des copies, ou des droits, + au titre de la présente Licence ne verront pas leurs autorisations résiliées + aussi longtemps que ledits tiers se conforment pleinement à elle. + </p> + + +<p>5. Vous n'êtes pas obligé d'accepter la présente Licence étant donné que vous ne + l'avez pas signée. Cependant, rien d'autre + ne vous accorde l'autorisation de modifier ou + distribuer le Programme ou les ouvrages fondés sur lui. Ces actions sont + interdites par la loi si vous n'acceptez pas la présente Licence. + En conséquence, en modifiant ou + distribuant le Programme (ou un ouvrage quelconque fondé sur + le Programme), vous signifiez votre acceptation de la présente Licence en le faisant, + et de toutes ses conditions concernant la copie, la + distribution ou la modification du Programme ou d'ouvrages fondés + sur lui.</p> + + +<p> + 6. Chaque fois que vous redistribuez le Programme (ou n'importe quel + ouvrage fondé sur le Programme), une licence est automatiquement + concédée au destinataire par le concédant originel de la licence, + l'autorisant à + copier, distribuer ou modifier le Programme, sous réserve + des présentes conditions. Vous ne pouvez imposer + une quelconque limitation supplémentaire à l'exercice des + droits octroyés au titre des présentes par le destinataire. Vous + n'avez pas la responsabilité d'imposer le respect de + la présente Licence à des tiers. </p> + + +<p> +7. Si, conséquement à une décision de justice ou l'allégation d'une +transgression de brevet ou pour toute autre raison (non limitée à un +probleme de brevet), des obligations vous sont imposées (que ce soit +par jugement, conciliation ou autre) qui contredisent les conditions de +la présente Licence, elles ne vous excusent pas des conditions de la +présente Licence. Si vous ne pouvez distribuer de manière à satisfaire +simultanément vos obligations au titre de la présente Licence et toute +autre obligation pertinente, alors il en découle que vous ne pouvez pas +du tout distribuer le Programme. Par exemple, si une licence de brevet +ne permettait pas une redistribution sans redevance du Programme par +tous ceux qui reçoivent une copie directement ou indirectement par +votre intermédiaire, alors la seule façon pour vous de satisfaire à la +fois à la licence du brevet et à la présente Licence serait de vous +abstenir totalement de toute distribution du Programme. </p> + + +<p>Si une partie quelconque de cet article est tenue pour + nulle ou inopposable dans une circonstance particulière + quelconque, l'intention est que le reste de l'article + s'applique. La totalité de la section s'appliquera dans toutes les + autres circonstances.</p> + + +<p>Cet article n'a pas pour but de vous induire à transgresser un + quelconque brevet ou d'autres revendications à un droit de propriété ou + à contester la validité de la moindre de ces revendications ; cet article a pour + seul objectif de protéger l'intégrité du système de distribution + du logiciel libre, qui est mis en oeuvre par la pratique des licenses + publiques. De nombreuses personnes ont fait de généreuses contributions + au large spectre de logiciels distribués par ce système en se fiant à + l'application cohérente de ce système ; il appartient à chaque auteur/donateur + de décider si il ou elle veut distribuer du logiciel par l'intermédiaire + d'un quelconque autre système et un concessionaire ne peut imposer ce + choix. + </p> + + +<p>Cet article a pour but de rendre totalement limpide ce que l'on pense + être une conséquence du reste de la présente Licence.</p> + + +<p>8. Si la distribution et/ou l'utilisation du Programme est limitée + dans certains pays que ce soit par des brevets ou par des interfaces soumises + au droit d'auteur, le titulaire originel des droits d'auteur + qui décide de couvrir le Programme par la présente Licence peut ajouter + une limitation géographique de distribution explicite qui exclue ces pays afin + que la distribution soit permise seulement dans ou entre les pays qui ne sont + pas ainsi exclus. Dans ce cas, la présente Licence incorpore la limitation + comme si elle était écrite dans le corps de la présente Licence. + </p> + + +<p>9. La Free Software Foundation peut, de temps à autre, publier des + versions révisées et/ou nouvelles de la Licence Publique Générale. De telles + nouvelles versions seront similaires à la présente version dans l'esprit + mais pourront différer dans le détail pour prendre en compte + de nouvelles problématiques ou inquiétudes. + </p> + + +<p>Chaque version possède un numéro de version la distinguant. Si le Programme + précise le numéro de version de la présente Licence qui s'y applique + et "une version ultérieure quelconque", vous avez le choix + de suivre les + conditions de + la présente version ou de toute autre version ultérieure publiée par la + Free Software Foundation. Si le Programme ne spécifie aucun numéro de + version de la présente Licence, vous pouvez choisir une version quelconque + publiée par la Free Software Foundation à quelque moment que ce soit.</p> + + +<p>10. Si vous souhaitez incorporer des parties du Programme + dans d'autres programmes libres dont les conditions de + distribution sont différentes, écrivez à l'auteur pour lui en demander + l'autorisation. Pour les logiciels dont la Free Software Foundation est + titulaire des droits d'auteur, écrivez à la Free Software Foundation ; + nous faisons parfois des exceptions dans ce sens. Notre décision sera guidée + par le double objectif de préserver le statut libre de tous les dérivés de nos + logiciels libres et de promouvoir le partage et la réutilisation des logiciels + en général. + </p> + + +<h2>ABSENCE DE GARANTIE</h2> + + +<p>11. COMME LA LICENCE DU PROGRAMME EST CONCEDEE A TITRE GRATUIT, + AUCUNE GARANTIE NE S'APPLIQUE AU PROGRAMME, DANS LES LIMITES + AUTORISEES PAR LA LOI APPLICABLE. SAUF MENTION CONTRAIRE ECRITE, + LES TITULAIRES DU DROIT D'AUTEUR ET/OU LES AUTRES PARTIES FOURNISSENT + LE PROGRAMME "EN L'ETAT", SANS AUCUNE GARANTIE DE + QUELQUE NATURE QUE CE SOIT, EXPRESSE OU IMPLICITE, Y COMPRIS, MAIS + SANS Y ETRE LIMITE, LES GARANTIES IMPLICITES DE COMMERCIABILITE ET + DE LA CONFORMITE A UNE UTILISATION PARTICULIERE. VOUS + ASSUMEZ LA TOTALITE DES RISQUES LIES A LA QUALITE ET AUX PERFORMANCES DU PROGRAMME. + SI LE PROGRAMME SE REVELAIT DEFECTUEUX, LE COUT DE L'ENTRETIEN, + DES REPARATIONS OU DES CORRECTIONS NECESSAIRES + VOUS INCOMBENT INTEGRALEMENT.</p> + + +<p>12. +EN AUCUN CAS, SAUF LORSQUE LA LOI APPLICABLE OU UNE CONVENTION ECRITE +L'EXIGE, UN TITULAIRE DE DROIT D'AUTEUR QUEL QU'IL SOIT, OU TOUTE +PARTIE QUI POURRAIT MODIFIER ET/OU REDISTRIBUER LE PROGRAMME COMME +PERMIS CI-DESSUS, NE POURRAIT ETRE TENU POUR RESPONSABLE A VOTRE EGARD +DES DOMMAGES, INCLUANT LES DOMMAGES GENERIQUES, SPECIFIQUES, +SECONDAIRES OU CONSECUTIFS, RESULTANT DE L'UTILISATION OU DE +L'INCAPACITE D'UTILISER LE PROGRAMME (Y COMPRIS, MAIS SANS Y ETRE +LIMITE, LA PERTE DE DONNEES, OU LE FAIT QUE DES DONNEES SOIENT RENDUES +IMPRECISES, OU LES PERTES EPROUVEES PAR VOUS OU PAR DES TIERS, OU LE +FAIT QUE LE PROGRAMME ECHOUE A INTEROPERER AVEC UN AUTRE PROGRAMME QUEL +QU'IL SOIT) MEME SI LE DIT TITULAIRE DU DROIT D'AUTEUR OU LE PARTIE +CONCERNEE A ETE AVERTI DE L'EVENTUALITE DE TELS DOMMAGES. +</p> + + +<h2>FIN DES CONDITIONS</h2> + + +<h2>Comment appliquer ces conditions à vos nouveaux programmes</h2> + + +<p> +Si vous développez un nouveau programme, et si vous voulez qu'il soit +de la plus grande utilité possible pour le public, le meilleur moyen +d'y parvenir est d'en faire un logiciel libre que chacun peut +redistribuer et modifier au titre des présentes conditions.</p> + + +<p>Pour ce faire, munissez le programme des avis qui suivent. + Le plus sûr est de les ajouter au début de chaque fichier source + pour véhiculer le plus efficacement possible l'absence + de toute garantie ; chaque fichier devrait aussi contenir au moins + la ligne "copyright" et une indication de l'endroit où se trouve l'avis + complet. + </p> + + +<p> [Une ligne donnant le nom du programme et une courte idée de ce qu'il fait.] + + Copyright (C) [année] [nom de l'auteur] + + Ce programme est un logiciel libre ; vous pouvez le + redistribuer et/ou le modifier au titre des clauses de la + Licence Publique Générale GNU, telle que publiée par la Free + Software Foundation ; soit la version 2 de la Licence, ou (à + votre discrétion) une version ultérieure quelconque. + + Ce programme est distribué dans l'espoir qu'il sera utile, + mais SANS AUCUNE GARANTIE ; sans même une garantie implicite de + COMMERCIABILITE ou DE CONFORMITE A UNE UTILISATION + PARTICULIERE. Voir la Licence Publique + Générale GNU pour plus de détails. + + Vous devriez avoir reçu un exemplaire de la Licence Publique + Générale GNU avec ce programme ; si ce n'est pas le cas, + écrivez à la Free Software Foundation Inc., 51 Franklin + Street, Fifth Floor, Boston, MA 02110-1301, USA.</p> + + +<p>Ajoutez aussi des informations sur la manière de vous contacter + par courrier électronique et courrier postal.</p> + + +<p>Si le programme est interactif, faites en sorte qu'il + affiche un court avis tel que celui-ci lorsqu'il démarre en + mode interactif : + </p> + + +<p>Gnomovision version 69, Copyright (C) année nom de l'auteur + Gnomovision n'est accompagné d'ABSOLUMENT AUCUNE GARANTIE ; pour plus de + détails tapez "show w". Ceci est un logiciel libre et vous êtes + invité à le redistribuer en respectant certaines obligations ; pour plus + de détails tapez "show c".</p> + + +<p>Les instructions hypothétiques "show w" et "show c" sont supposées montrer + les parties ad hoc de la Licence Publique Générale. Bien + entendu, les instructions que vous utilisez peuvent porter d'autres + noms que "show w" et "show c" ; elles peuvent même être des + clics de souris ou des éléments d'un menu ou tout ce qui convient à + votre programme.</p> + + +<p>Vous devriez aussi obtenir de votre employeur (si vous + travaillez en tant que développeur) ou de votre école, si c'est + le cas, qu'il (ou elle) signe une "renonciation aux droits + d'auteur" concernant le programme, si nécessaire. Voici un + exemple (changez les noms) : + </p> + + +<p>Yoyodyne, Inc., déclare par la présente renoncer à toute prétention + sur les droits d'auteur du programme "Gnomovision" (qui fait des + avances aux compilateurs) écrit par James Hacker. + + [signature de Ty Coon], 1er avril 1989 + + Ty Coon, Président du Vice</p> + + +<p>La présente Licence Publique Générale n'autorise pas l'incorporation de votre + programme dans des programmes + propriétaires. Si votre programme est une bibliothèque de + sous-programmes, vous pouvez considérer plus utile + d'autoriser l'édition de liens d'applications propriétaires avec + la bibliothèque. Si c'est ce que vous voulez faire, utilisez la + GNU Lesser General Public License au lieu de la présente Licence. + </p> +</body> +</html> diff --git a/logo/src/xlogo/gpl/gpl-gl.html b/logo/src/xlogo/gpl/gpl-gl.html new file mode 100644 index 0000000..e49d21b --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-gl.html @@ -0,0 +1,140 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.3 (Linux)"> + <META NAME="CREATED" CONTENT="0;0"> + <META NAME="CHANGED" CONTENT="0;0"> + <STYLE TYPE="text/css"> + <!-- + @page { size: 21cm 29.7cm; margin: 2cm } + P { margin-bottom: 0.21cm } + --> + </STYLE> +</HEAD> +<BODY LANG="fr-FR" DIR="LTR"> +<PRE>This is an unofficial translation of the GNU General Public License into galician. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GNU GPL—only the original English text of the GNU GPL does that. However, we hope that this translation will help galician speakers understand the GNU GPL better. + +Esta é unha tradución non oficial da Licenza Pública Xeral GNU ao galego. Esta licenza non foi publicada pola Free Software Foundation e non establece legalmente os termos de distribución para software que utiliza a Free Software Foundation, só a licenza orixinal en inglés GNU GPL os establece. No entanto, esperamos que esta tradución axude aos galegos a entender mellor a GNU GPL. + +LICENZA PÚBLICA XERAL DE GNU +Versión 2 (xuño de 1991) + +Copyright © 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Permítese a copia e distribución de copias textuais desta licenza, sempre que non se introduza ningunha modificación. + +Preámbulo + +A maioría das licenzas de software están concibidas para privar o usuario da súa liberdade de compartir e modificar ese software. Pola contra, a licenza pública xeral de GNU busca garantir a súa liberdade para compartir e modificar software libre, para se asegurar de que o software é libre para todos os seus usuarios. Esta licenza pública xeral é de aplicación á maioría do software da Free Software Foundation, así como a calquera outro programa cuxos autores se comprometan a utilizala (hai outro software da Free Software Foundation que se rexe, no seu lugar, pola licenza pública xeral reducida de GNU). Tamén pode aplicala aos seus propios programas. + +Cando se fala de software libre fálase de liberdade, non de prezo. As nosas licenzas públicas xerais están deseñadas co obxectivo de asegurar a súa liberdade para distribuír copias de software libre (e cobrar por este servizo, se así o desexa), que recibe o código fonte ou pode recibilo se así o desexa, que ten a posibilidade de modificar o software ou empregar partes del en novos programas libres e que, ademais, é consciente de que pode facer todo isto. + +Para protexer os seus dereitos, cómpre introducir certas restricións que impidan que calquera outro lle poida negar estes dereitos ou pedirlle que renuncie a eles. Estas restricións implican determinadas responsabilidades para vostede, no caso de distribuír copias do software ou modificalo. + +Por exemplo, se distribúe copias dun programa libre, sexa gratis ou non, tenlle que ceder aos receptores todos os dereitos que ten vostede. Terase que asegurar de que eses receptores tamén reciben ou poden recibir o código fonte e terá que mostrarlles os termos desta licenza para informalos dos seus dereitos. + +Dous son os pasos para protexer os seus dereitos: (1) pór o software baixo copyright e (2) ofrecerlle esta licenza, que o autoriza legalmente para copiar, distribuír e/ou modificar o software. + +Ademais, como medida de protección para todos os autores e para nós mesmos, é importante deixarlles claro a todas as partes que non existe garantía para este software libre. No caso de que calquera usuario modifique o software e logo o distribúa a un terceiro, os receptores deben saber que o que se lles entrega non é o software orixinal, de xeito que calquera problema introducido pola outra parte non afecte a reputación dos autores orixinais. + +Por último, calquera programa libre está constantemente ameazado polas patentes de software. A nosa intención é evitar o perigo de que os redistribuidores dun programa libre obteñan licenzas de patente pola súa conta, convertendo así o seu programa en software rexistrado. Para evitar que isto suceda, deixamos ben claro que calquera patente debe de garantir a cesión da licenza a calquera usuario posible, de maneira que todo o mundo poida usar o programa libremente ou, en caso contrario, non debe de garantir licenza ningunha a ninguén. + +A seguir detállanse os termos e condicións exactos para a copia, distribución e modificación. + +LICENZA PÚBLICA XERAL DE GNU +TERMOS E CONDICIÓNS PARA A COPIA, DISTRIBUCIÓN E MODIFICACIÓN + +0. Esta licenza é aplicable a calquera programa ou produto doutro tipo no que figure un aviso inserido polo titular do copyright que especifique que se pode distribuír baixo os termos desta licenza pública xeral. De aquí en adiante, o termo "Programa" referirase a calquera programa ou produto deste tipo, mentres que o termo "produto baseado no Programa" referirase tanto ao programa coma a calquera produto derivado consonte a lei de propiedade intelectual, é dicir, calquera produto que conteña o programa ou unha parte del, sexa textual ou con modificacións e/ou traducida a outra lingua. (De aquí en adiante, a tradución inclúese sen límite ningún no termo "modificación".) As licenzas están redactadas na forma de cortesía "vostede". + +Calquera actividade distinta da copia, distribución e modificación non está cuberta por esta licenza, senón que queda fóra do seu ámbito de aplicación. Non se restrinxe a acción de executar o Programa, e os resultados tirados do Programa só están cubertos se o seu contido constitúe un produto baseado no Programa (sen importar se foi realizado mediante a execución do Programa). Que isto sexa certo ou non dependerá do que faga o Programa. + +1. Pode copiar e distribuír copias textuais do código fonte do Programa tal e como o recibe, en calquera medio, sempre que inclúa en cada copia, de forma axeitada e suficientemente visible, as indicacións necesarias relativas á propiedade intelectual e á renuncia á concesión de garantía, que manteña intactos todos os avisos referentes a esta licenza e á ausencia de toda garantía e que lles entregue a todos os demais receptores do Programa unha copia desta licenza xunto co Programa. + +Pode cobrar unha taxa polo acto físico de transferir unha copia e, se vostede quixer, pode tamén ofrecer unha determinada garantía a cambio do pagamento dunha taxa. + +2. Pode modificar a súa copia ou copias do Programa, ou calquera parte del, e obter así un produto baseado no Programa, así como copiar e distribuír as devanditas modificacións ou produto de acordo cos termos do apartado 1 anterior, sempre que cumpra tamén con todas as condicións seguintes: + + a) Debe facer que calquera ficheiro modificado inclúa indicacións ben visibles nas que se especifique que o correspondente ficheiro foi modificado, así como a data de calquera modificación. + b) Debe facer que calquera produto distribuído ou publicado por vostede, que en todo ou en parte conteña ou derive do Programa ou de calquera parte do Programa, obteña unha licenza no seu conxunto sen que isto repercuta en ningún gasto para calquera terceira parte de acordo cos termos desta licenza. + c) Se o programa modificado adoita ler comandos de forma interactiva ao executalo, debe facer que, cando se execute para tal uso interactivo na forma máis habitual, mostre ou exhiba un aviso no que se inclúan as oportunas informacións relativas á propiedade intelectual do programa e á ausencia de toda garantía (ou, se for o caso, ao feito de que é vostede quen proporciona a garantía), a indicación de que os usuarios poden redistribuír o programa consonte estas condicións e a información necesaria para que o usuario saiba como acceder a unha copia desta licenza. (Excepción: se o Programa en si mesmo é interactivo pero non adoita mostrar avisos deste tipo, non é necesario que o seu produto baseado no Programa exhiba ningún aviso.) + +Estes requisitos aplícanse ao produto modificado no seu conxunto. Se o produto contén seccións facilmente identificables non derivadas do Programa, que razoablemente se poidan considerar como produtos separados e independentes por si mesmos, esta licenza e mais os seus termos non serán aplicables ás devanditas seccións cando se distribúan como produtos separados. Pero se esas mesmas seccións se distribúen como parte dun todo consistente nun produto baseado no Programa, a distribución do todo deberá de se acoller aos termos desta licenza, cuxas disposicións, aplicables a todos os demais titulares da licenza, abranguen o conxunto completo e, en consecuencia, todas e cada unha das partes do conxunto independentemente de quen as escribise. + +Así, o obxectivo deste apartado non é reclamar dereitos ou rebater os seus dereitos sobre calquera produto escrito por vostede na súa totalidade; máis ben ao contrario, o seu obxectivo é exercer o dereito de controlar a distribución de produtos derivados ou colectivos baseados no Programa. +Ademais, a simple agregación ao Programa (ou a un produto baseado no Programa) doutro produto non baseado no Programa nun volume dun medio de distribución ou almacenamento non implica a inclusión do outro produto no ámbito de aplicación desta licenza. + +3. Pode copiar e distribuír o Programa (ou un produto baseado nel, segundo os termos do apartado 2) en código obxecto ou forma executable de acordo co establecido nos apartados 1 e 2 anteriores, sempre que cumpra tamén con un dos seguintes requisitos: + + a) Acompañalo do correspondente código fonte completo nun formato lexible por máquina, que se ha de distribuír de acordo co estipulado nos apartados 1 e 2 anteriores nun soporte tipicamente utilizado para o intercambio de software. + b) Acompañalo dunha oferta por escrito, cunha validez mínima de tres anos, na que se entregue a calquera terceiro interesado, por un custo nunca superior aos gastos nos que vostede poida incorrer pola execución física da distribución do código fonte, unha copia completa en formato lexible por máquina do código fonte correspondente, que se ha de distribuír de acordo co estipulado nos apartados 1 e 2 anteriores nun soporte tipicamente utilizado para o intercambio de software. + c) Acompañalo da información que recibiu vostede verbo da oferta de distribuír o código fonte correspondente. (Esta opción só está permitida para a distribución non-comercial, e unicamente no caso de que vostede recibise o programa en código obxecto ou forma executable cunha oferta como a que se acaba de explicar, de acordo co subapartado b anterior.) + +Enténdese por código fonte dun traballo o seu formato máis idóneo á hora de realizar modificacións nel. No caso dun traballo executable, enténdese por código fonte completo todo o código fonte para todos os módulos que inclúe, ademais de todos os ficheiros de definición de interfaces asociados e os scripts utilizados para controlar a compilación e a instalación do executable. Porén, como caso excepcional, o código fonte distribuído non precisa incluír nada que se distribúa normalmente (xa sexa de forma binaria ou fonte) cos compoñentes principais (compilador, núcleo etc.) do sistema operativo en que se executa o executable, agás que ese propio compoñente acompañe o executable. + +Se a distribución do código obxecto ou executable se realiza concedendo acceso de copia desde un lugar determinado, entón a concesión de acceso equivalente para copiar o código fonte do mesmo lugar considérase como distribución do código fonte, aínda que ningún terceiro estea obrigado a copiar o código fonte xunto co obxecto. + +4. Non lle está permitido copiar, modificar, emitir unha sublicenza nin distribuír o Programa agás nos termos especificamente estipulados nesta licenza. Calquera outro intento de copiar, modificar, emitir unha sublicenza ou distribuír o Programa será considerado nulo, e implicará a cancelación automática dos dereitos que lle concede esta licenza. No entanto, as partes ás que vostede concedera copias ou dereitos consonte os termos desta licenza non verán resoltas as súas respectivas licenzas, sempre que cumpran plenamente con todo o que nelas se estipula. + +5. Dado que aínda non a asinou, non está obrigado a aceptar os termos desta licenza. Porén, ela é o único que o autoriza a modificar ou distribuír o Programa ou calquera outro produto derivado del. Estas accións están prohibidas por lei mentres non acepte esta licenza. Xa que logo, mediante a modificación ou distribución do Programa (ou de calquera produto baseado no Programa) vostede expresa a súa aceptación desta licenza para a realización das devanditas accións, así como de todos os termos e condicións estipulados nela para a copia, distribución ou modificación do Programa ou de calquera produto baseado nel. + +6. Cada vez que redistribúa o Programa (ou calquera produto baseado no Programa), o receptor recibirá automaticamente unha licenza por parte do emisor da licenza orixinal que lle permitirá copiar, distribuír ou modificar o Programa consonte estes termos e condicións. Vostede non poderá impor ningunha outra restrición sobre o exercicio dos dereitos nela estipulados por parte do receptor. Vostede non é responsable á hora de esixirlle a un terceiro o cumprimento dos termos estipulados nesta licenza. + +7. Se, como consecuencia dun proceso xudicial ou dunha acusación por violación de patentes, ou por calquera outra causa (sen restrinxirse aos temas de patentes), resultase a imposición de calquera condición sobre vostede (xa sexa por orde xudicial, por acordo ou por calquera outra causa) que contradiga as condicións desta licenza, iso non o escusa do cumprimento das condicións desta licenza. De non lle ser posible distribuír o Programa respectando as obrigas contraídas baixo esta licenza e, asemade, calquera outra obriga pertinente, entón terá que deixar de distribuílo en ningún modo. Por exemplo, no caso de existir unha licenza de patente que non permitise a redistribución do Programa exenta de dereitos de autor por parte de todos aqueles que recibisen copias de maneira directa ou indirecta de vostede, o único xeito de cumprir cos termos da devandita licenza de patente e mais desta licenza ao mesmo tempo sería evitando por completo a distribución do Programa. + +No caso de que calquera sección deste apartado se considerase non válida ou non executable baixo calquera circunstancia concreta será de aplicación o resto do apartado e, en calquera outras circunstancias, aplicarase o apartado no seu conxunto. + +O obxectivo deste apartado non é inducilo a infrinxir ningunha reivindicación de patente nin de calquera outro dereito de propiedade intelectual, así como tampouco impugnar a validez deste tipo de reivindicacións. O único que pretende este apartado é protexer a integridade do sistema de distribución do software libre, levado á práctica mediante o desenvolvemento de licenzas públicas. + +Moitas persoas contribuíron xenerosamente ao desenvolvemento do amplo abano de software distribuído a través deste sistema, coa confianza de que se aplicará consistentemente. Só o autor/doador pode decidir se está disposto a distribuír o seu software mediante calquera outro sistema; o titular dunha licenza non pode impor este tipo de elección. + +Este apartado pretende deixar ben claro o que considera que é consecuencia do resto desta licenza. + +8. No caso de que nalgúns países se restrinxa a distribución e/ou o uso do Programa pola execución dalgunha patente ou interface protexida por copyright, o titular orixinal do copyright que somete o Programa aos termos desta licenza poderá engadir unha limitación explícita á distribución xeográfica que exclúa aqueles países, de xeito que só se permita a distribución nos ou entre os países non suxeitos á devandita exclusión. Se este for o caso, a licenza incorporaría a limitación citada nos mesmos termos que se fose redactada como parte do corpo desta licenza. + +9. A Free Software Foundation poderá publicar versións revisadas e/ou novas desta licenza pública xeral no momento en que o estime oportuno. As novas versións manterán o mesmo espírito ca a actual, se ben poden diferir nalgúns detalles do contido co obxectivo de facer fronte a novos problemas ou preocupacións. + +Cada versión leva un número identificativo diferente. Se o Programa especifica que lle é aplicable unha versión específica desta licenza e "calquera versión posterior", vostede poderá escoller entre cinguirse aos termos e condicións ben da primeira versión ou ben de calquera versión posterior publicada pola Free Software Foundation. Se o Programa non especifica ningún número de versión desta licenza, vostede terá a opción de escoller calquera versión de entre todas as publicadas pola Free Software Foundation. + +10. Se desexa incluír partes do Programa noutros programas libres cunhas condicións de distribución distintas, deberá de se dirixir ao autor por escrito para lle pedir a súa autorización. No caso do software co copyright da Free Software Foundation, diríxase por escrito á Free Software Foundation, que en ocasións fai excepcións nestes casos. A decisión que tomemos basearase nos nosos dous obxectivos de preservar o estatus libre de calquera produto derivado do noso software libre e de promover o compartimento e a reutilización do software en xeral. + +AUSENCIA DE GARANTÍA + +11. DADO QUE SE TRATA DUN PROGRAMA ACOMPAÑADO DUNHA LICENZA GRATUÍTA, DENTRO DOS LÍMITES PERMITIDOS POLA LEXISLACIÓN APLICABLE CONSIDÉRASE UN PROGRAMA EXENTO DE TODA GARANTÍA. AGÁS QUE SE ESPECIFIQUE O CONTRARIO POR ESCRITO, OS TITULARES DO COPYRIGHT E/OU OUTRAS PARTES CEDEN O PROGRAMA "TAL CAL" SEN NINGÚN TIPO DE GARANTÍA, NIN EXPLÍCITA NIN IMPLÍCITA, INCLUÍDAS, AÍNDA QUE SEN EXCLUSIVIDADE, AS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDADE E IDONEIDADE PARA UN DETERMINADO FIN. A TOTALIDADE DOS RISCOS ASOCIADOS Á CALIDADE E AO RENDEMENTO DO PROGRAMA RECAE SOBRE VOSTEDE. SE O PROGRAMA RESULTASE DEFECTUOSO, VOSTEDE TERÁ QUE ASUMIR OS CUSTOS DE CALQUERA REPARACIÓN, ARRANXO OU EMENDA. + +12. EN NINGÚN CASO, AGÁS QUE ASÍ O ESIXA A LEXISLACIÓN APLICABLE OU QUE EXISTA UN ACORDO POR ESCRITO ENTRE AS PARTES, SE LLE ESIXIRÁ RESPONSABILIDADE AO TITULAR DO COPYRIGHT, OU A CALQUERA OUTRA PARTE AUTORIZADA PARA MODIFICAR E/OU REDISTRIBUÍR O PROGRAMA CONSONTE OS TERMOS DESCRITOS ANTERIORMENTE, POLOS DANOS E PERDAS OCASIONADOS, INCLUÍDOS OS DANOS XERAIS, ESPECIAIS, INCIDENTAIS OU DE IMPORTANCIA DE CALQUERA TIPO QUE POIDAN DERIVAR DO USO OU DA INCAPACIDADE DE USO DO PROGRAMA (O QUE INCLÚE, AÍNDA QUE SEN RESTRICIÓN, BEN A PERDA DE DATOS, OU BEN A INTERPRETACIÓN IMPRECISA DE DATOS, OU BEN AS PERDAS OCASIONADAS A VOSTEDE OU A UN TERCEIRO, OU BEN A IMPOSIBILIDADE DE EXECUTAR O PROGRAMA CON CALQUERA OUTRO PROGRAMA), MESMO SE O DEVANDITO TITULAR OU A OUTRA PARTE FOSEN ADVERTIDOS DA POSIBILIDADE DE QUE SE PRODUCISEN OS DANOS DESCRITOS ANTERIORMENTE. + + +FIN DOS TERMOS E CONDICIÓNS + + +Como aplicar os termos desta licenza aos seus novos programas + +Se vostede desenvolve un programa novo e quere que sexa da maior utilidade posible para o público, o mellor xeito de facelo é convertelo en software libre, de xeito que todo o mundo poida redistribuílo e modificalo segundo os termos desta licenza. + +Para iso, ten que acompañar o programa dos avisos que se especifican a seguir. O mellor é inserilos ao comezo de cada ficheiro fonte para transmitir do xeito máis eficaz e seguro posible a información sobre a exclusión de garantía. Ademais, cada ficheiro debería ter polo menos a liña do "copyright" e unha referencia ou indicación que remita ao lugar onde se pode ler o aviso completo. + +<unha liña na que se indiquen o nome do programa e unha breve descrición do que fai.> +Copyright © <ano> <nome do autor> + +Este é un programa de software libre e, xa que logo, vostede pode redistribuílo e/ou modificalo consonte os termos establecidos na licenza pública xeral de GNU segundo a súa publicación pola Free Software Foundation. Pode escoller a versión 2 da licenza ou, se prefire, calquera outra versión posterior. + +Este programa distribúese coa esperanza de que resulte útil, se ben NON TEN NINGUNHA GARANTÍA, nin sequera a garantía implícita de COMERCIABILIDADE ou IDONEIDADE PARA UN DETERMINADO FIN. Para obter información máis detallada pode consultar a licenza pública xeral de GNU. + +Dáse por sentado que recibiu unha copia da licenza pública xeral de GNU xunto con este programa. Se non for así, pode solicitarlla por escrito á Free Software Foundation, Inc. no enderezo seguinte: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +No seu escrito debe incluír o seu correo postal e electrónico. + +De se tratar dun programa interactivo, terá que asegurarse de que ao arrancar en modo interactivo amose un breve aviso do estilo do seguinte: + +Gnomovision versión 69, Copyright © ano nome do autor Gnomovision non ofrece GARANTÍA DE NINGÚN TIPO. Para máis información introduza 'amosar g'. Este é un programa de software libre, de xeito que pode redistribuílo tranquilamente sempre que cumpra determinadas condicións. Para máis información introduza 'amosar c'. + +Os comandos hipotéticos 'amosar g' e 'amosar c' deberían levalo aos respectivos parágrafos correspondentes da licenza pública xeral. Por suposto, os comandos utilizados por vostede poden ser distintos a 'amosar g' e 'amosar c'; mesmo poden ser ligazóns nas que premer ou elementos do menú, segundo o que resulte máis axeitado para o seu programa. +En caso necesario, tamén deberá pedirlle á súa empresa (se traballa como programador) ou ao seu centro de ensino, se for o caso, que asine unha carta de renuncia a todos os dereitos de propiedade intelectual que puideran estar asociados ao programa. Velaquí un exemplo (só cómpre modificar os nomes): + +Yoyodyne, Inc. renuncia a calquera dereito de propiedade intelectual sobre o programa 'Gnomovision' (que realiza pasadas nos compiladores), desenvolvido por James Hacker. +<sinatura de Xan Perillán>, 1 de abril de 1989 +Xan Perillán, Presidente de XXX + +Consonte os termos desta licenza pública xeral non lle está permitido incluír o seu programa noutros programas con dereitos rexistrados. No caso de que o seu programa sexa unha biblioteca de subrutinas, poida que lle resulte máis útil permitir que se establezan ligazóns entre aplicacións rexistradas e a biblioteca. Se é isto o que lle interesa facer, utilice a licenza pública xeral reducida de GNU no canto desta.</PRE> +</BODY> +</HTML>
\ No newline at end of file diff --git a/logo/src/xlogo/gpl/gpl-hu.html b/logo/src/xlogo/gpl/gpl-hu.html new file mode 100644 index 0000000..5f3e023 --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-hu.html @@ -0,0 +1,428 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.4 (Linux)"> + <META NAME="AUTHOR" CONTENT="Loïc"> + <META NAME="CREATED" CONTENT="20090422;15283600"> + <META NAME="CHANGEDBY" CONTENT="Loïc"> + <META NAME="CHANGED" CONTENT="20090422;15292500"> + <STYLE TYPE="text/css"> + <!-- + @page { size: 21cm 29.7cm; margin: 2cm } + P { margin-bottom: 0.21cm } + H1 { margin-bottom: 0.21cm } + H1.western { font-family: "Times New Roman", serif } + H1.cjk { font-family: "DejaVu Sans" } + H1.ctl { font-family: "DejaVu Sans" } + H2 { margin-bottom: 0.21cm } + --> + </STYLE> +</HEAD> +<BODY LANG="fr-FR" DIR="LTR"> +<P><STRONG>This is an unofficial translation of the GNU General +Public License into Hungarian. It was not published by the Free +Software Foundation, and does not legally state the distribution +terms for software that uses the GNU GPL—only the original English +text of the GNU GPL does that. However, we hope that this translation +will help Hungarian speakers understand the GNU GPL better.</STRONG></P> +<DIV ID="content" DIR="LTR"> + <P><STRONG>Ez a GNU General Public License nem hivatalos magyar + fordítása. A fordítást nem a Free Software Foundation adta ki, + és jogi értelemben nem határozza meg a GNU GPL-t felhasználó + szoftverek terjesztési feltételeit – e tekintetben csak a GNU + GPL angol nyelvű verziója irányadó. Mindazonáltal reméljük, + hogy ez a fordítás segít a GNU GPL jobb megértésében.</STRONG></P> + <H1 CLASS="western">GNU General Public License (GPL) + </H1> + <P>Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple + Place, Suite 330, Boston, MA 02111-1307, USA + </P> + <P>Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass + Ave, Cambridge, MA 02139, USA + </P> + <H2>Előszó + </H2> + <P>A legtöbb szoftver licencei azzal a szándékkal készültek, + hogy minél kevesebb lehetőséget adjanak a szoftver + megváltoztatására és terjesztésére. Ezzel szemben a GNU GPL + célja, hogy garantálja a szabad szoftver másolásának és + terjesztésének szabadságát, ezáltal biztosítva a szoftver + szabad felhasználhatóságát minden felhasználó számára. A GPL + szabályai vonatkoznak a Free Software Foundation legtöbb + szoftverére, illetve minden olyan programra, melynek szerzője úgy + dönt, hogy ezt használja a szerzői jog megjelölésekor. (A Free + Software Foundation egyes szoftvereire a GNU LGPL érvényes.) Bárki + használhatja a programjaiban a GPL-t a szerzői jogi megjegyzésnél. + </P> + <P>A szabad szoftver megjelölés nem jelenti azt, hogy a + szoftvernek nem lehet ára. A GPL licencek célja, hogy garantálja + a szabad szoftver másolatainak szabad terjesztését (és e + szolgáltatásért akár díj felszámítását), a forráskód + elérhetőségét, hogy bárki szabadon módosíthassa a szoftvert, + vagy felhasználhassa a részeit új szabad programokban; és hogy + mások megismerhessék ezt a lehetőséget. + </P> + <P>A szerző jogainak védelmében korlátozásokat kell hozni, + amelyek megtiltják, hogy bárki megtagadhassa ezeket a jogokat + másoktól, vagy ezekről való lemondásra kényszerítsen bárki + mást. Ezek a megszorítások bizonyos felelősségeket jelentenek + azok számára, akik a szoftver másolatait terjesztik vagy + módosítják. + </P> + <P>Ha valaki például ilyen program másolatait terjeszti, akár + ingyen vagy bizonyos összeg fejében, a szoftverre vonatkozó + minden jogot tovább kell adnia a fogadó feleknek. Biztosítani + kell továbbá, hogy megkapják vagy legalábbis megkaphassák a + forráskódot is. És persze ezeket a licencfeltételeket is el kell + juttatni, hogy tisztában legyenek a jogaikkal. + </P> + <P>A jogok védelme két lépésből áll: + </P> + <P STYLE="margin-left: 1.06cm">(1) a szoftver szerzői jogainak + védelméből és + </P> + <P STYLE="margin-left: 1.06cm">(2) a jelen licenc biztosításából, + amely jogalapot biztosít a szoftver másolására, terjesztésére + és/vagy módosítására. + </P> + <P>Az egyes szerzők és a magunk védelmében biztosítani akarjuk, + hogy mindenki megértse: a jelen szabad szoftverre nincs jótállás. + Ha a szoftvert módosították és továbbadták, akkor mindenkinek, + aki a módosított változatot kapja, tudnia kell, hogy az nem az + eredeti, így a mások által okozott hibáknak nem lehet hatása az + eredeti szerző hírnevére. + </P> + <P>Végül, a szabad szoftver létét állandóan fenyegetik a + szoftverszabadalmak. El szeretnénk kerülni annak veszélyét, hogy + a szabad program terjesztői szabadalmat jegyezhessenek be rá, + ezáltal saját szellemi tulajdont képezővé tegyék a programot. + Ennek megelőzéséhez tisztázni kívánjuk: szabadalom szabad + szoftverrel kapcsolatban csak mindenki általi szabad használatra + jegyezhető be, vagy egyáltalán nem jegyezhető be. + </P> + <P>A másolásra, terjesztésre, módosításra vonatkozó pontos + szabályok és feltételek: + </P> + <H2>A MÁSOLÁSRA, TERJESZTÉSRE ÉS MÓDOSÍTÁSRA VONATKOZÓ + FELTÉTELEK ÉS KIKÖTÉSEK + </H2> + <P><B>0.</B> Ez a licenc minden olyan programra vagy munkára + vonatkozik, amelynek a szerzői jogi megjegyzésében a jog + tulajdonosa a következő szöveget helyezte el: a GPL-ben foglaltak + alapján terjeszthető. Az alábbiakban a Program kifejezés bármely + ilyen programra vagy munkára vonatkozik, a Programon alapuló munka + pedig magát a programot vagy egy szerzői joggal védett munkát + jelenti: vagyis olyan munkát, amely tartalmazza a programot vagy + annak egy részletét, módosítottan vagy módosítatlanul és/vagy + más nyelvre fordítva. (Az alábbiakban a fordítás minden egyéb + megkötés nélkül beletartozik a módosítás fogalmába.) Minden + engedélyezés címzettje Ön. + </P> + <P>A jelen licenc a másoláson, terjesztésen és módosításon + kívül más tevékenységre nem vonatkozik, azok a hatályán kívül + esnek. A Program futtatása nincs korlátozva, illetve a Program + kimenetére is csak abban az esetben vonatkozik ez a szabályozás, + ha az tartalmazza a Programon alapuló munka egy részletét + (függetlenül attól, hogy ez a Program futtatásával jött-e + létre). Ez tehát a Program működésétől függ. + </P> + <P><B>1.</B> A Program forráskódja módosítás nélkül másolható + és bármely adathordozón terjeszthető, feltéve, hogy minden + egyes példányon pontosan szerepel a megfelelő szerzői jogi + megjegyzés, illetve a garanciavállalás elutasítása; + érintetlenül kell hagyni minden erre a szabályozásra és a + garancia teljes hiányára utaló szöveget és a jelen + licencdokumentumot is el kell juttatni mindazokhoz, akik a Programot + kapják. + </P> + <P>Felszámítható díj a másolat fizikai továbbítása fejében, + illetve ellenszolgáltatás fejében a Programhoz garanciális + támogatás is biztosítható. + </P> + <P><B>2.</B> A Program vagy annak egy része módosítható, így a + Programon alapuló munka jön létre. A módosítás ezután az 1. + szakaszban adott feltételek szerint tovább terjeszthető, ha az + alábbi feltételek is teljesülnek: + </P> + <DL> + <DD STYLE="margin-bottom: 0.5cm">a) A módosított fájlokat el + kell látni olyan megjegyzéssel, amely feltünteti a módosítást + végző nevét és a módosítások dátumát. + </DD><DD STYLE="margin-bottom: 0.5cm"> + b) Minden olyan munkát, amely részben vagy egészben tartalmazza + a Programot vagy a Programon alapul, olyan szabályokkal kell + kiadni vagy terjeszteni, hogy annak használati joga harmadik + személy részére licencdíjmentesen hozzáférhető legyen, a + jelen dokumentumban található feltételeknek megfelelően. + </DD><DD STYLE="margin-bottom: 0.5cm"> + c) Ha a módosított Program interaktívan olvassa a parancsokat + futás közben, akkor úgy kell elkészíteni, hogy a megszokott + módon történő indításkor megjelenítsen egy üzenetet a + megfelelő szerzői jogi megjegyzéssel és a garancia hiányára + utaló közléssel (vagy éppen azzal az információval, hogy + miként juthat valaki garanciához), illetve azzal az + információval, hogy bárki terjesztheti a Programot a jelen + feltételeknek megfelelően, és arra is utalást kell tenni, hogy + a felhasználó miként tekintheti meg a licenc egy példányát. + (Kivétel: ha a Program interaktív ugyan, de nem jelenít meg + hasonló üzenetet, akkor a Programon alapuló munkának sem kell + ezt tennie.) + </DD></DL> + <P> + Ezek a feltételek a módosított munkára, mint egészre + vonatkoznak. Ha a munka azonosítható részei nem a Programon + alapulnak és független munkákként elkülönülten azonosíthatók, + akkor ez a szabályozás nem vonatkozik ezekre a részekre, ha azok + külön munkaként kerülnek terjesztésre. Viszont, ha ugyanez a + rész az egész részeként kerül terjesztésre, amely a Programon + alapuló munka, akkor az egész terjesztése csak a jelen dokumentum + alapján lehetséges, amely ebben az esetben a jogokat minden egyes + felhasználó számára kiterjeszti az egészre tekintet nélkül + arra, hogy melyik részt ki írta. + </P> + <P>E szövegrésznek tehát nem az a célja, hogy mások jogait + elvegye vagy korlátozza a kizárólag saját maga által írt + munkákra; a cél az, hogy a jogok gyakorlása szabályozva legyen a + Programon alapuló illetve a gyűjteményes munkák terjesztése + esetében. + </P> + <P>Ezenkívül más munkáknak, amelyek nem a Programon alapulnak, a + Programmal (vagy a Programon alapuló munkával) közös + adathordozón vagy adattárolón szerepeltetése nem jelenti a jelen + szabályok érvényességét azokra is. + </P> + <P><B>3.</B> A Program (vagy a Programon alapuló munka a 2. + szakasznak megfelelően) másolható és terjeszthető tárgykódú + vagy végrehajtható kódú formájában az 1. és 2. szakaszban + foglaltak szerint, amennyiben az alábbi feltételek is teljesülnek: + </P> + <DL> + <DD STYLE="margin-bottom: 0.5cm">a) a teljes, gép által + értelmezhető forráskód kíséri az anyagot, amelynek + terjesztése az 1. és 2. szakaszban foglaltak szerint történik, + jellemzően szoftverterjesztésre használt adathordozón; vagy, + </DD><DD STYLE="margin-bottom: 0.5cm"> + b) legalább három évre szólóan írásban vállalja, hogy + bármely külső személynek rendelkezésre áll a teljes gép + által értelmezhető forráskód, a fizikai továbbítást fedező + összegnél nem nagyobb díjért az 1. és 2. szakaszban foglaltak + szerint szoftverterjesztésre használt adathordozón; vagy, + </DD><DD STYLE="margin-bottom: 0.5cm"> + c) a megfelelő forráskód terjesztésére vonatkozóan megkapott + tájékoztatás kíséri az anyagot. (Ez az alternatíva csak nem + kereskedelmi terjesztés esetén alkalmazható abban az esetben, ha + a terjesztő a Programhoz a tárgykódú vagy forráskódú + formájában jutott hozzá az ajánlattal együtt a fenti b. + cikkelynek megfelelően.) + </DD></DL> + <P> + Egy munka forráskódja a munkának azt a formáját jelenti, + amelyben a módosításokat elsődlegesen végezni szokás. Egy + végrehajtható program esetében a teljes forráskód a + tartalmazott összes modul forráskódját jelenti, továbbá a + kapcsolódó felületdefiníciós fájlokat és a fordítást + vezérlő parancsfájlokat. Egy speciális kivételként a + forráskódnak nem kell tartalmaznia normál esetben a végrehajtható + kód futtatására szolgáló operációs rendszer főbb részeiként + (kernel, fordítóprogram stb.) terjesztett részeit (forrás vagy + bináris formában), kivéve, ha a komponens maga a végrehajtható + állományt kíséri. + </P> + <P>Ha a végrehajtható program vagy tárgykód terjesztése a + forráskód hozzáférését egy megadott helyen biztosító írásban + vállalja, akkor ez egyenértékű a forráskód terjesztésével, + bár másoknak nem kell a forrást lemásolniuk a tárgykóddal + együtt. + </P> + <P><B>4.</B> A Programot csak a jelen Licencben leírtaknak + megfelelően szabad lemásolni, terjeszteni, módosítani és + allicencbe adni. Az egyéb módon történő másolás, módosítás, + terjesztés és allicencbe adás érvénytelen, és azonnal + érvényteleníti a dokumentumban megadott jogosultságokat. + Mindazonáltal azok, akik a Licencet megszegőtől kaptak + példányokat vagy jogokat, tovább gyakorolhatják a Licenc által + meghatározott jogaikat mindaddig, amíg teljesen megfelelnek a + Licenc feltételeinek. + </P> + <P><B>5.</B> Önnek nem kötelező elfogadnia ezt a szabályozást, + hiszen nem írta alá. Ezen kívül viszont semmi más nem ad + jogokat a Program terjesztésére és módosítására. Ezeket a + cselekedeteket a törvény bünteti, ha nem a jelen szerzői jogi + szabályozás keretei között történnek. Mindezek miatt a Program + (vagy a Programon alapuló munka) terjesztése vagy módosítása a + jelen dokumentum szabályainak, és azon belül a Program vagy a + munka módosítására, másolására vagy terjesztésére vonatkozó + összes feltételének elfogadását jelenti. + </P> + <P><B>6.</B> Minden alkalommal, amikor a Program (vagy az azon + alapuló munka) továbbadása történik, a Programot megkapó + személy automatikusan hozzájut az eredeti licenctulajdonostól + származó licenchez, amely a jelen szabályok szerint biztosítja a + jogot a Program másolására, terjesztésére és módosítására. + Nem lehet semmilyen módon tovább korlátozni a fogadó félnek az + itt megadott jogait. A Program továbbadója nem felelős harmadik + személyekkel betartatni a jelen szabályokat. + </P> + <P><B>7.</B> Ha bírósági határozat, szabadalomsértés vélelme, + vagy egyéb (nem kizárólag szabadalmakkal kapcsolatos) okból + olyan feltételeknek kell megfelelnie (akár bírósági határozat, + akár megállapodás, akár bármi más eredményeképp), amelyek + ellentétesek a jelen feltételekkel, az nem menti fel a terjesztőt + a jelen feltételek figyelembevétele alól. Ha a terjesztés nem + lehetséges a jelen Licenc és az egyéb feltételek + kötelezettségeinek együttes betartásával, akkor tilos a Program + terjesztése. Ha például egy szabadalmi szerződés nem engedi meg + egy program jogdíj nélküli továbbterjesztését azok számára, + akik közvetve vagy közvetlenül megkapják, akkor az egyetlen + módja, hogy eleget tegyen valaki mindkét feltételnek az, hogy + eláll a Program terjesztésétől. + </P> + <P>Ha ennek a szakasznak bármely része érvénytelen, vagy nem + érvényesíthető valamely körülmény folytán, akkor a szakasz + maradék részét kell alkalmazni, egyéb esetekben pedig a szakasz + egésze alkalmazandó. + </P> + <P>Ennek a szakasznak nem az a célja, hogy a szabadalmak vagy egyéb + hasonló jogok megsértésére ösztönözzön bárkit is; mindössze + meg szeretné védeni a szabad szoftver terjesztési rendszerének + egységét, amelyet a szabad közreadást szabályozó + feltételrendszerek teremtenek meg. Sok ember nagymértékben járult + hozzá az e rendszer keretében terjesztett, különféle + szoftverekhez, és számít a rendszer következetes alkalmazására; + azt a szerző/adományozó dönti el, hogy a szoftverét más + rendszer szerint is közzé kívánja-e tenni, és a licencet kapók + ezt nem befolyásolhatják. + </P> + <P>E szakasz célja, hogy pontosan tisztázza azt, ami elgondolásunk + szerint a jelen licenc többi részének a következménye. + </P> + <P><B>8.</B> Ha a Program terjesztése és/vagy használata egyes + országokban nem lehetséges akár szabadalmak, akár szerzői + jogokkal védett felületek miatt, akkor a Program szerzői jogainak + eredeti tulajdonosa, aki a Programot ezen szabályozás alapján + adja közre, egy explicit földrajzi megkötést adhat a + terjesztésre, és egyes országokat kizárhat. Ebben az esetben úgy + tekintendő, hogy a jelen licenc ezt a megkötést is tartalmazza, + ugyanúgy mintha csak a fő szövegében lenne leírva. + </P> + <P><B>9.</B> A Free Software Foundation időről időre kiadja a + General Public License dokumentum felülvizsgált és/vagy újabb + változatait. Ezek az újabb dokumentumok az előzőek szellemében + készülnek, de részletekben különbözhetnek, hogy új + problémákat vagy aggályokat is kezeljenek. + </P> + <P>A dokumentum minden változata egy megkülönböztető + verziószámmal ellátva jelenik meg. Ha a Program szerzői jogi + megjegyzésében egy bizonyos vagy annál újabb verzió van + megjelölve, akkor lehetőség van akár a megjelölt, vagy a Free + Software Foundation által kiadott későbbi verzióban leírt + feltételek követésére. Ha nincs ilyen megjelölt verzió, akkor + lehetőség van a Free Software Foundation által valaha kibocsátott + bármelyik dokumentum alkalmazására. + </P> + <P><B>10.</B> A Programot más szabad szoftverbe, amelynek szerzői + jogi szabályozása különbözik, csak akkor építheti be, ha a + szerzőtől erre engedélyt szerzett. Abban az esetben, ha a program + szerzői jogainak tulajdonosa a Free Software Foundation, akkor a + Free Software Foundation címére kell írni; néha kivételt + teszünk. A döntés a következő két cél szem előtt tartásával + fog történni: megmaradjon a szabad szoftveren alapuló munkák + szabad állapota, valamint segítse elő a szoftver + újrafelhasználását és megosztását. + </P> + <H2>GARANCIAVÁLLALÁS HIÁNYA + </H2> + <P><B>11.</B> MIVEL A JELEN PROGRAM HASZNÁLATI JOGA DÍJMENTES, AZ + ALKALMAZHATÓ JOGSZABÁLYOK ÁLTAL BIZTOSÍTOTT MAXIMÁLIS MÉRTÉKBEN + VISSZAUTASÍTJUK A PROGRAMHOZ A GARANCIA BIZTOSÍTÁSÁT. AMENNYIBEN + A SZERZŐI JOGOK TULAJDONOSAI ÍRÁSBAN MÁSKÉNT NEM NYILATKOZNAK, + A PROGRAM A "JELEN ÁLLAPOTÁBAN" KERÜL KIADÁSRA, + MINDENFÉLE GARANCIAVÁLLALÁS NÉLKÜL, LEGYEN AZ KIFEJEZETT VAGY + BELEÉRTETT, BELEÉRTVE, DE NEM KIZÁRÓLAGOSAN A FORGALOMBA + HOZHATÓSÁGRA VAGY ALKALMAZHATÓSÁGRA VONATKOZÓ GARANCIÁKAT. A + PROGRAM MINŐSÉGÉBŐL ÉS MŰKÖDÉSÉBŐL FAKADÓ ÖSSZES + KOCKÁZAT A FELHASZNÁLÓT TERHELI. HA A PROGRAM HIBÁSAN MŰKÖDIK, + A FELHASZNÁLÓNAK MAGÁNAK KELL VÁLLALNIA A JAVÍTÁSHOZ SZÜKSÉGES + MINDEN KÖLTSÉGET. + </P> + <P><B>12.</B> AMENNYIBEN A HATÁLYOS JOGSZABÁLYOK VAGY A SZERZŐI + JOGOK TULAJDONOSAI ÍRÁSOS MEGÁLLAPODÁSBAN MÁSKÉNT NEM + RENDELKEZNEK, SEM A PROGRAM SZERZŐJE, SEM MÁSOK, AKIK MÓDOSÍTOTTÁK + ÉS/VAGY TERJESZTETTÉK A PROGRAMOT A FENTIEKNEK MEGFELELŐEN, NEM + TEHETŐK FELELŐSSÉ A KÁROKÉRT, BELEÉRTVE MINDEN VÉLETLEN, VAGY + KÖVETKEZMÉNYES KÁRT, AMELY A PROGRAM HASZNÁLATÁBÓL VAGY A + HASZNÁLAT MEGAKADÁLYOZÁSÁBÓL SZÁRMAZIK (BELEÉRTVE, DE NEM + KIZÁRÓLAGOSAN AZ ADATVESZTÉST ÉS A HELYTELEN ADATFELDOLGOZÁST, + VALAMINT A MÁS PROGRAMOKKAL VALÓ HIBÁS EGYÜTTMŰKÖDÉST), MÉG + AKKOR SEM, HA EZEN FELEK TUDATÁBAN VOLTAK, HOGY ILYEN KÁROK + KELETKEZHETNEK. + </P> + <P><B>FELTÉTELEK ÉS SZABÁLYOK VÉGE</B> + </P> + <H2>Hogyan alkalmazhatók ezek a szabályok egy új programra? + </H2> + <P>Ha valaki egy új programot készít és szeretné, hogy az bárki + számára a lehető leginkább hasznos legyen, akkor a legjobb + módszer, hogy azt szabad szoftverré teszi, megengedve mindenkinek + a szabad másolást és módosítást a jelen feltételeknek + megfelelően. + </P> + <P>Ehhez a következő megjegyzést kell csatolni a programhoz. A + legbiztosabb ezt minden egyes forrásfájl elejére beírni, így + közölve leghatásosabban a garancia visszautasítását; ezenkívül + minden fájl kell, hogy tartalmazzon egy copyright sort és egy + mutatót arra a helyre, ahol a teljes szöveg található. + </P> + <PRE> <I>Egy sor, amely megadja a program nevét és funkcióját</I> + Copyright (C) év; szerző neve; + + Ez a program szabad szoftver; terjeszthető illetve módosítható a + Free Software Foundation által kiadott GNU General Public License + dokumentumában leírtak; akár a licenc 2-es, akár (tetszőleges) későbbi + változata szerint. + Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz, + de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA + VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve. + További részleteket a GNU General Public License tartalmaz. + A felhasználónak a programmal együtt meg kell kapnia a GNU General + Public License egy példányát; ha mégsem kapta meg, akkor + ezt a Free Software Foundationnak küldött levélben jelezze + (cím: Free Software Foundation Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307, USA.)</PRE><P> + A programhoz csatolni kell azt is, hogy miként lehet kapcsolatba + lépni a szerzővel, elektronikus vagy hagyományos levél + küldésével. + </P> + <P>Ha a program interaktív, a következőhöz hasonló üzenettel + lehet ezt megtenni a program indulásakor:</P> + <PRE> Gnomovision version 69, Copyright (C) <I>év, a szerző neve</I>. + A Gnomovision programhoz SEMMILYEN GARANCIA NEM JÁR; részletekért + írja be a 'show w' parancsot. Ez egy szabad szoftver, bizonyos + feltételek mellett terjeszthető, illetve módosítható; részletekért + írja be a 'show c' parancsot.</PRE><P> + A show w és show c képzeletbeli parancsok, és a GPL megfelelő + részeit kell megjeleníteniük. Természetesen a valódi parancsok + a show w és show c parancstól különbözhetnek; lehetnek akár + egérkattintások vagy menüpontok is, ami a programnak megfelel. + </P> + <P>Ha szükséges, meg kell szerezni a munkáltatótól (ha a szerző + programozóként dolgozik) vagy az iskolától a program szerzői + jogairól való lemondás igazolását. Erre itt egy példa; + változtassa meg a neveket: + </P> + <PRE> A Fiktív Bt. ezennel lemond minden szerzői jogi érdekeltségéről + a „Gnomovision” programmal (amelyet több fázisban fordítanak le + a fordítóprogramok) kapcsolatban, amelyet H. Ekker János írt. + + Aláírás: Tira Mihály, 1989. április 1. Tira Mihály ügyvezető</PRE><P STYLE="margin-bottom: 0cm"> + A GNU General Public License nem engedi meg, hogy a program része + legyen szellemi tulajdont képező programoknak. Ha a program egy + szubrutinkönyvtár, akkor megfontolhatja, hogy nem célszerűbb-e + megengedni, hogy szellemi tulajdont képező alkalmazásokkal is + összefűzhető legyen a programkönyvtár. Ha ezt szeretné, akkor + a GPL helyett a GNU LGPL-t kell használni.</P> +</DIV> +</BODY> +</HTML>
\ No newline at end of file diff --git a/logo/src/xlogo/gpl/gpl-pt.html b/logo/src/xlogo/gpl/gpl-pt.html new file mode 100644 index 0000000..5edb32d --- /dev/null +++ b/logo/src/xlogo/gpl/gpl-pt.html @@ -0,0 +1,10 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> + <title>GNU General Public Licence</title> +</head> +<body> +<pre> LICENÇA PÚBLICA GERAL GNU<br> Versão 2, junho de 1991<br><br> This is an unofficial translation of the GNU General Public License<br> into Brazilian Portuguese. It was not published by the Free Software<br> Foundation, and does not legally state the distribution terms for<br> software that uses the GNU GPL -- only the original English text of<br> the GNU GPL does that. However, we hope that this translation will<br> help Brazilian Portuguese speakers understand the GNU GPL better.<br><br> Esta é uma tradução não-oficial da Licença Pública Geral GNU ("GPL<br> GNU") para o português do Brasil. Ela não foi publicada pela Free<br>Software Foundation, e legalmente não afirma os termos de distribuição<br> de software que utiliza a GPL GNU -- apenas o texto original da GPL<br> GNU, em inglês, faz isso. Contudo, esperamos que esta tradução ajude<br> aos que utilizam o português do Brasil a entender melhor a GPL GNU.<br><br> Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,<br> Cambridge, MA 02139, USA<br><br>A qualquer pessoa é permitido copiar e distribuir cópias desse<br>documento de licença, desde que sem qualquer alteração.<br><br> Introdução<br><br> As licenças de muitos software são desenvolvidas para restringir sua<br>liberdade de compartilhá-lo e mudá-lo. Contrária a isso, a Licença<br>Pública Geral GNU pretende garantir sua liberdade de compartilhar e<br>alterar software livres -- garantindo que o software será livre e<br>gratuito para os seus usuários. Esta Licença Pública Geral aplica-se à<br>maioria dos software da Free Software Foundation e a qualquer outro<br>programa cujo autor decida aplicá-la. (Alguns outros software da FSF<br>são cobertos pela Licença Pública Geral de Bibliotecas, no entanto.)<br>Você pode aplicá-la também aos seus programas.<br><br> Quando nos referimos a software livre, estamos nos referindo a<br>liberdade e não a preço. Nossa Licença Pública Geral foi desenvolvida<br>para garantir que você tenha a liberdade de distribuir cópias de<br>software livre (e cobrar por isso, se quiser); que você receba o<br>código-fonte ou tenha acesso a ele, se quiser; que você possa mudar o<br>software ou utilizar partes dele em novos programas livres e<br>gratuitos; e que você saiba que pode fazer tudo isso.<br><br> Para proteger seus direitos, precisamos fazer restrições que impeçam<br>a qualquer um negar estes direitos ou solicitar que você deles<br>abdique. Estas restrições traduzem-se em certas responsabilidades para<br>você, se você for distribuir cópias do software ou modificá-lo.<br><br> Por exemplo, se você distribuir cópias de um programa, gratuitamente<br>ou por alguma quantia, você tem que fornecer aos recebedores todos os<br>direitos que você possui. Você tem que garantir que eles também<br>recebam ou possam obter o código-fonte. E você tem que mostrar-lhes<br>estes termos para que eles possam conhecer seus direitos.<br><br> Nós protegemos seus direitos em dois passos: (1) com copyright do<br>software e (2) com a oferta desta licença, que lhe dá permissão legal<br>para copiar, distribuir e/ou modificar o software.<br><br> Além disso, tanto para a proteção do autor quanto a nossa,<br>gostaríamos de certificar-nos que todos entendam que não há qualquer<br>garantia nestes software livres. Se o software é modificado por alguém<br>mais e passado adiante, queremos que seus recebedores saibam que o que<br>eles obtiveram não é original, de forma que qualquer problema<br>introduzido por terceiros não interfira na reputação do autor<br>original.<br><br> Finalmente, qualquer programa é ameaçado constantemente por patentes<br>de software. Queremos evitar o perigo de que distribuidores de<br>software livre obtenham patentes individuais, o que tem o efeito de<br>tornar o programa proprietário. Para prevenir isso, deixamos claro que<br>qualquer patente tem que ser licenciada para uso livre e gratuito por<br>qualquer pessoa, ou então que nem necessite ser licenciada.<br><br> Os termos e condições precisas para cópia, distribuição e<br>modificação se encontram abaixo:<br><br> LICENÇA PÚBLICA GERAL GNU<br> TERMOS E CONDIÇÕES PARA CÓPIA, DISTRIBUIÇÃO E MODIFICAÇÃO<br><br> 0. Esta licença se aplica a qualquer programa ou outro trabalho que<br>contenha um aviso colocado pelo detentor dos direitos autorais<br>informando que aquele pode ser distribuído sob as condições desta<br>Licença Pública Geral. O "Programa" abaixo refere-se a qualquer<br>programa ou trabalho, e "trabalho baseado no Programa" significa tanto<br>o Programa em si como quaisquer trabalhos derivados, de acordo com a<br>lei de direitos autorais: isto quer dizer um trabalho que contenha o<br>Programa ou parte dele, tanto originalmente ou com modificações, e/ou<br>tradução para outros idiomas. (Doravante o processo de tradução está<br>incluído sem limites no termo "modificação".) Cada licenciado é<br>mencionado como "você".<br><br>Atividades outras que a cópia, a distribuição e modificação não estão<br>cobertas por esta Licença; elas estão fora de seu escopo. O ato de<br>executar o Programa não é restringido e o resultado do Programa é<br>coberto apenas se seu conteúdo contenha trabalhos baseados no Programa<br>(independentemente de terem sido gerados pela execução do<br>Programa). Se isso é verdadeiro depende do que o programa faz.<br><br> 1. Você pode copiar e distribuir cópias fiéis do código-fonte do<br>Programa da mesma forma que você o recebeu, usando qualquer meio,<br>deste que você conspícua e apropriadamente publique em cada cópia um<br>aviso de direitos autorais e uma declaração de inexistência de<br>garantias; mantenha intactas todos os avisos que se referem a esta<br>Licença e à ausência total de garantias; e forneça a outros<br>recebedores do Programa uma cópia desta Licença, junto com o Programa.<br><br>Você pode cobrar pelo ato físico de transferir uma cópia e pode,<br>opcionalmente, oferecer garantia em troca de pagamento.<br><br> 2. Você pode modificar sua cópia ou cópias do Programa, ou qualquer<br>parte dele, assim gerando um trabalho baseado no Programa, e copiar e<br>distribuir essas modificações ou trabalhos sob os termos da seção 1<br>acima, desde que você também se enquadre em todas estas condições:<br><br> a) Você tem que fazer com que os arquivos modificados levem avisos<br> proeminentes afirmando que você alterou os arquivos, incluindo a<br> data de qualquer alteração.<br><br> b) Você tem que fazer com que quaisquer trabalhos que você<br> distribua ou publique, e que integralmente ou em partes contenham<br> ou sejam derivados do Programa ou de suas partes, sejam<br> licenciados, integralmente e sem custo algum para quaisquer<br> terceiros, sob os termos desta Licença.<br><br> c) Se qualquer programa modificado normalmente lê comandos<br> interativamente quando executados, você tem que fazer com que,<br> quando iniciado tal uso interativo da forma mais simples, seja<br> impresso ou mostrado um anúncio de que não há qualquer garantia<br> (ou então que você fornece a garantia) e que os usuários podem<br> redistribuir o programa sob estas condições, ainda informando os<br> usuários como consultar uma cópia desta Licença. (Exceção: se o<br> Programa em si é interativo mas normalmente não imprime estes<br> tipos de anúncios, seu trabalho baseado no Programa não precisa<br> imprimir um anúncio.)<br><br>Estas exigências aplicam-se ao trabalho modificado como um todo. Se<br>seções identificáveis de tal trabalho não são derivadas do Programa, e<br>podem ser razoavelmente consideradas trabalhos independentes e<br>separados por si só, então esta Licença, e seus termos, não se aplicam<br>a estas seções quando você distribui-las como trabalhos em<br>separado. Mas quando você distribuir as mesmas seções como parte de um<br>todo que é trabalho baseado no Programa, a distribuição como um todo<br>tem que se enquadrar nos termos desta Licença, cujas permissões para<br>outros licenciados se estendem ao todo, portanto também para cada e<br>toda parte independente de quem a escreveu.<br><br>Desta forma, esta seção não tem a intenção de reclamar direitos os<br>contestar seus direitos sobre o trabalho escrito completamente por<br>você; ao invés disso, a intenção é a de exercitar o direito de<br>controlar a distribuição de trabalhos, derivados ou coletivos,<br>baseados no Programa.<br><br>Adicionalmente, a mera adição ao Programa de outro trabalho não<br>baseado no Programa (ou de trabalho baseado no Programa) em um volume<br>de armazenamento ou meio de distribuição não faz o outro trabalho<br>parte do escopo desta Licença.<br><br> 3. Você pode copiar e distribuir o Programa (ou trabalho baseado<br>nele, conforme descrito na Seção 2) em código-objeto ou em forma<br>executável sob os termos das Seções 1 e 2 acima, desde que você<br>faça um dos seguintes:<br><br> a) O acompanhe com o código-fonte completo e em forma acessível<br> por máquinas, que tem que ser distribuído sob os termos das Seções<br> 1 e 2 acima e em meio normalmente utilizado para o intercâmbio de<br> software; ou,<br><br> b) O acompanhe com uma oferta escrita, válida por pelo menos três<br> anos, de fornecer a qualquer um, com um custo não superior ao<br> custo de distribuição física do material, uma cópia do<br> código-fonte completo e em forma acessível por máquinas, que tem<br> que ser distribuído sob os termos das Seções 1 e 2 acima e em meio<br> normalmente utilizado para o intercâmbio de software; ou,<br><br> c) O acompanhe com a informação que você recebeu em relação à<br> oferta de distribuição do código-fonte correspondente. (Esta<br> alternativa é permitida somente em distribuição não comerciais, e<br> apenas se você recebeu o programa em forma de código-objeto ou<br> executável, com oferta de acordo com a Subseção b acima.)<br><br>O código-fonte de um trabalho corresponde à forma de trabalho<br>preferida para se fazer modificações. Para um trabalho em forma<br>executável, o código-fonte completo significa todo o código-fonte de<br>todos os módulos que ele contém, mais quaisquer arquivos de definição<br>de "interface", mais os "scripts" utilizados para se controlar a<br>compilação e a instalação do executável. Contudo, como exceção<br>especial, o código-fonte distribuído não precisa incluir qualquer<br>componente normalmente distribuído (tanto em forma original quanto<br>binária) com os maiores componentes (o compilador, o "kernel" etc.) do<br>sistema operacional sob o qual o executável funciona, a menos que o<br>componente em si acompanhe o executável.<br><br>Se a distribuição do executável ou código-objeto é feita através da<br>oferta de acesso a cópias de algum lugar, então ofertar o acesso<br>equivalente a cópia, do mesmo lugar, do código-fonte equivale à<br>distribuição do código-fonte, mesmo que terceiros não sejam compelidos<br>a copiar o código-fonte com o código-objeto.<br><br> 4. Você não pode copiar, modificar, sub-licenciar ou distribuir o<br>Programa, exceto de acordo com as condições expressas nesta<br>Licença. Qualquer outra tentativa de cópia, modificação,<br>sub-licenciamento ou distribuição do Programa não é valida, e<br>cancelará automaticamente os direitos que lhe foram fornecidos por<br>esta Licença. No entanto, terceiros que de você receberam cópias ou<br>direitos, fornecidos sob os termos desta Licença, não terão suas<br>licenças terminadas, desde que permaneçam em total concordância com<br>ela.<br><br> 5. Você não é obrigado a aceitar esta Licença já que não a<br>assinou. No entanto, nada mais o dará permissão para modificar ou<br>distribuir o Programa ou trabalhos derivados deste. Estas ações são<br>proibidas por lei, caso você não aceite esta Licença. Desta forma, ao<br>modificar ou distribuir o Programa (ou qualquer trabalho derivado do<br>Programa), você estará indicando sua total aceitação desta Licença<br>para fazê-los, e todos os seus termos e condições para copiar,<br>distribuir ou modificar o Programa, ou trabalhos baseados nele.<br><br> 6. Cada vez que você redistribuir o Programa (ou qualquer trabalho<br>baseado nele), os recebedores adquirirão automaticamente do<br>licenciador original uma licença para copiar, distribuir ou modificar<br>o Programa, sujeitos a estes termos e condições. Você não poderá impor<br>aos recebedores qualquer outra restrição ao exercício dos direitos<br>então adquiridos. Você não é responsável em garantir a concordância de<br>terceiros a esta Licença.<br><br> 7. Se, em conseqüência de decisões judiciais ou alegações de<br>infringimento de patentes ou quaisquer outras razões (não limitadas a<br>assuntos relacionados a patentes), condições forem impostas a você<br>(por ordem judicial, acordos ou outras formas) e que contradigam as<br>condições desta Licença, elas não o livram das condições desta<br>Licença. Se você não puder distribuir de forma a satisfazer<br>simultaneamente suas obrigações para com esta Licença e para com as<br>outras obrigações pertinentes, então como conseqüência você não poderá<br>distribuir o Programa. Por exemplo, se uma licença de patente não<br>permitirá a redistribuição, livre de "royalties", do Programa, por<br>todos aqueles que receberem cópias direta ou indiretamente de você,<br>então a única forma de você satisfazer a ela e a esta Licença seria a<br>de desistir completamente de distribuir o Programa.<br><br>Se qualquer parte desta seção for considerada inválida ou não<br>aplicável em qualquer circunstância particular, o restante da seção se<br>aplica, e a seção como um todo se aplica em outras circunstâncias.<br><br>O propósito desta seção não é o de induzi-lo a infringir quaisquer<br>patentes ou reivindicação de direitos de propriedade outros, ou a<br>contestar a validade de quaisquer dessas reivindicações; esta seção<br>tem como único propósito proteger a integridade dos sistemas de<br>distribuição de software livres, o que é implementado pela prática de<br>licenças públicas. Várias pessoas têm contribuído generosamente e em<br>grande escala para os software distribuídos usando este sistema, na<br>certeza de que sua aplicação é feita de forma consistente; fica a<br>critério do autor/doador decidir se ele ou ela está disposto a<br>distribuir software utilizando outro sistema, e um licenciado não pode<br>impor qualquer escolha.<br><br>Esta seção destina-se a tornar bastante claro o que se acredita ser<br>conseqüência do restante desta Licença.<br><br> 8. Se a distribuição e/ou uso do Programa são restringidos em certos<br>países por patentes ou direitos autorais, o detentor dos direitos<br>autorais original, e que colocou o Programa sob esta Licença, pode<br>incluir uma limitação geográfica de distribuição, excluindo aqueles<br>países de forma a tornar a distribuição permitida apenas naqueles ou<br>entre aqueles países então não excluídos. Nestes casos, esta Licença<br>incorpora a limitação como se a mesma constasse escrita nesta Licença.<br><br> 9. A Free Software Foundation pode publicar versões revisadas e/ou<br>novas da Licença Pública Geral de tempos em tempos. Estas novas<br>versões serão similares em espírito à versão atual, mas podem diferir<br>em detalhes que resolvem novos problemas ou situações.<br><br>A cada versão é dada um número distinto. Se o Programa especifica um<br>número de versão específico desta Licença que se aplica a ele e a<br>"qualquer nova versão", você tem a opção de aceitar os termos e<br>condições daquela versão ou de qualquer outra versão publicada pela<br>Free Software Foundation. Se o programa não especifica um número de<br>versão desta Licença, você pode escolher qualquer versão já publicada<br>pela Free Software Foundation.<br><br> 10. Se você pretende incorporar partes do Programa em outros<br>programas livres cujas condições de distribuição são diferentes,<br>escreva ao autor e solicite permissão. Para o software que a Free<br>Software Foundation detém direitos autorais, escreva à Free Software<br>Foundation; às vezes nós permitimos exceções a este caso. Nossa<br>decisão será guiada pelos dois objetivos de preservar a condição de<br>liberdade de todas as derivações do nosso software livre, e de<br>promover o compartilhamento e reutilização de software em aspectos<br>gerais.<br><br> AUSÊNCIA DE GARANTIAS<br><br> 11. UMA VEZ QUE O PROGRAMA É LICENCIADO SEM ÔNUS, NÃO HÁ QUALQUER<br>GARANTIA PARA O PROGRAMA, NA EXTENSÃO PERMITIDA PELAS LEIS<br>APLICÁVEIS. EXCETO QUANDO EXPRESSADO DE FORMA ESCRITA, OS DETENTORES<br>DOS DIREITOS AUTORAIS E/OU TERCEIROS DISPONIBILIZAM O PROGRAMA "NO<br>ESTADO", SEM QUALQUER TIPO DE GARANTIAS, EXPRESSAS OU IMPLÍCITAS,<br>INCLUINDO, MAS NÃO LIMITADO A, AS GARANTIAS IMPLÍCITAS DE<br>COMERCIALIZAÇÃO E AS DE ADEQUAÇÃO A QUALQUER PROPÓSITO. O RISCO TOTAL<br>COM A QUALIDADE E DESEMPENHO DO PROGRAMA É SEU. SE O PROGRAMA SE<br>MOSTRAR DEFEITUOSO, VOCÊ ASSUME OS CUSTOS DE TODAS AS MANUTENÇÕES,<br>REPAROS E CORREÇÕES.<br><br> 12. EM NENHUMA OCASIÃO, A MENOS QUE EXIGIDO PELAS LEIS APLICÁVEIS OU<br>ACORDO ESCRITO, OS DETENTORES DOS DIREITOS AUTORAIS, OU QUALQUER OUTRA<br>PARTE QUE POSSA MODIFICAR E/OU REDISTRIBUIR O PROGRAMA CONFORME<br>PERMITIDO ACIMA, SERÃO RESPONSABILIZADOS POR VOCÊ POR DANOS, INCLUINDO<br>QUALQUER DANO EM GERAL, ESPECIAL, ACIDENTAL OU CONSEQÜENTE,<br>RESULTANTES DO USO OU INCAPACIDADE DE USO DO PROGRAMA (INCLUINDO, MAS<br>NÃO LIMITADO A, A PERDA DE DADOS OU DADOS TORNADOS INCORRETOS, OU<br>PERDAS SOFRIDAS POR VOCÊ OU POR OUTRAS PARTES, OU FALHAS DO PROGRAMA<br>AO OPERAR COM QUALQUER OUTRO PROGRAMA), MESMO QUE TAL DETENTOR OU<br>PARTE TENHAM SIDO AVISADOS DA POSSIBILIDADE DE TAIS DANOS.<br><br> FIM DOS TERMOS E CONDIÇÕES<br><br> Como Aplicar Estes Termos aos Seus Novos Programas<br><br> Se você desenvolver um novo programa, e quer que ele seja utilizado<br>amplamente pelo público, a melhor forma de alcançar este objetivo é<br>torná-lo software livre que qualquer um pode redistribuir e alterar,<br>sob estes termos.<br><br> Para isso, anexe os seguintes avisos ao programa. É mais seguro<br>anexá-los logo no início de cada arquivo-fonte para reforçarem mais<br>efetivamente a inexistência de garantias; e cada arquivo deve possuir<br>pelo menos a linha de "copyright" e uma indicação de onde o texto<br>completo se encontra.<br><br> <uma linha que forneça o nome do programa e uma idéia do que ele faz.><br> Copyright (C) <ano> <nome do autor><br> <br> Este programa é software livre; você pode redistribuí-lo e/ou<br> modificá-lo sob os termos da Licença Pública Geral GNU, conforme<br> publicada pela Free Software Foundation; tanto a versão 2 da<br> Licença como (a seu critério) qualquer versão mais nova.<br><br> Este programa é distribuído na expectativa de ser útil, mas SEM<br> QUALQUER GARANTIA; sem mesmo a garantia implícita de<br> COMERCIALIZAÇÃO ou de ADEQUAÇÃO A QUALQUER PROPÓSITO EM<br> PARTICULAR. Consulte a Licença Pública Geral GNU para obter mais<br> detalhes.<br> <br> Você deve ter recebido uma cópia da Licença Pública Geral GNU<br> junto com este programa; se não, escreva para a Free Software<br> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA<br> 02111-1307, USA.<br><br>Inclua também informações sobre como contactá-lo eletronicamente e por<br>carta.<br><br>Se o programa é interativo, faça-o mostrar um aviso breve como este,<br>ao iniciar um modo interativo:<br><br> Gnomovision versão 69, Copyright (C) ano nome do autor<br> O Gnomovision não possui QUALQUER GARANTIA; para obter mais<br> detalhes digite `show w'. Ele é software livre e você está<br> convidado a redistribui-lo sob certas condições; digite `show c'<br> para obter detalhes.<br><br>Os comandos hipotéticos `show w' e `show c' devem mostrar as partes<br>apropriadas da Licença Pública Geral. Claro, os comandos que você usar<br>podem ser ativados de outra forma que `show w' e `show c'; eles podem<br>até ser cliques do mouse ou itens de um menu -- o que melhor se<br>adequar ao programa.<br><br>Você também deve obter do seu empregador (se você trabalha como<br>programador) ou escola, se houver, uma "declaração de ausência de<br>direitos autorais" sobre o programa, se necessário. Aqui está um<br>exemplo; altere os nomes:<br><br> Yoyodyne, Inc., aqui declara a ausência de quaisquer direitos<br> autorais sobre o programa `Gnomovision' (que executa interpretações<br> em compiladores) escrito por James Hacker.<br><br> <assinatura de Ty Coon>, 1o. de abril de 1989<br> Ty Con, Vice-presidente<br><br>Esta Licença Pública Geral não permite incorporar seu programa em<br>programas proprietários. Se seu programa é uma biblioteca de<br>sub-rotinas, você deve considerar mais útil permitir ligar aplicações<br>proprietárias com a biblioteca. Se isto é o que você deseja, use a<br>Licença Pública Geral de Bibliotecas GNU, ao invés desta Licença.<br></pre> +</body> +</html> diff --git a/logo/src/xlogo/gpl/x4s_info.html b/logo/src/xlogo/gpl/x4s_info.html new file mode 100644 index 0000000..ff7458e --- /dev/null +++ b/logo/src/xlogo/gpl/x4s_info.html @@ -0,0 +1,42 @@ +<html>
+ <head>
+ <title>HTML Online Editor Sample</title>
+ </head>
+ <body>
+ <h2>
+ XLogo4Schools</h2>
+ <p>
+ XLogo4Schools is a modified, extended and reengineered version of Loïc Le Coq's XLogo. It is the result of a six month Bachelor's thesis conducted by Marko Živković at ETHZ, D-INFK department from March 2013 until September 2013.</p>
+ <p>
+ I want to thank <a href="http://www.ite.ethz.ch/people/host/jhromkov">Prof. Juraj Hromkovič</a> for giving me the opportunity to dive into the world of Logo and for letting me do the reengineering of XLogo for my Bachelor's Thesis. Very special thanks go to <a href="http://www.ite.ethz.ch/people/fachdidaktik/serafing/curriculum">Giovanni Serafini</a> who acted as an excellent adviser and mentor during this project. I also want to thank <a href="http://www.inf.ethz.ch/personal/gebauerh/">Dr. Heidi Gebauer</a>, <a href="http://www.ite.ethz.ch/people/postdocs/ivanak">Dr. Ivana Kosirova</a>, <a href="http://www.ite.ethz.ch/people/researchassistants/lkeller">Lucia Keller</a>, and <a href="http://www.ite.ethz.ch/people/researchassistants/steffenb">Björn Steffen</a> from Prof. Hromkovič's chair for their intensive contributions during the requirements analysis phase. I enjoyed the many talks and discussions and appreciated every new idea from you. And finally I want to thank the other Logo tutors, Lukas Häfliger, Samuel Bryner, Alexander Viand, Petra Hromkovičova, Stefan Dietiker, and Christine Zeller, who contributed in numerous inspiring talks during the many Logo projects.</p>
+ <h3>
+ What was reengineered?</h3>
+ <p>
+ The new main features introduced are</p>
+ <ul>
+ <li>
+ <strong>Multiple active files</strong>. That implies an ambiguity check among several files. The internal workspace had to be changed completely.</li>
+ <li>
+ <strong>Automatic saving</strong> to the file system</li>
+ <li>
+ <strong>Backup system</strong> - the teacher's specify how many old version of the pupil's files should be kept in a backup folder</li>
+ <li>
+ <strong>Competition/record mode</strong> - a predefined number of files, one for each exercise is created, each having a clock. The children's inputs are recorded in a file for later analysis</li>
+ <li>
+ More accurate error messages when parsing the procedure's signatures.</li>
+ <li>
+ A simple workspace management system. Workspaces consist of multiple projects or users. Certain settings apply to the whole workspace, others are per user or project.</li>
+ </ul>
+ <p>
+ What was changed?</p>
+ <ul>
+ <li>
+ The <strong>user interface</strong> has completely changed. I reduced the complexity of customizability to the minimum. Very necessary settings can be defined by the teachers, but not by the children. There is a simple password mechanism to hide these settings. The main window now includes everything that is needed. A command line, the drawing area, the history panel, and the list of files to the left. There is also a procedue search, that lets one more easily find the desired procedures amongst the files. The editor is now integrated in the same window. When a file is opened, the editor is shown instead of the drawing area and the command line. All the options menus and preferences have been removed. The turtle speed and the turtle icon can be changed in the main window directly. I removed these border-images that were used by XLogo, instead providing a larger view onto the drawing area.</li>
+ <li>
+ The core of the application, the interpreter and drawing engine are left almost untouched. Things that I had to alter a lot have become replaced by loosely coupled components that can work independently of each other. The communication between different parts of the application is now event driven instead of static variables and similar anti-patterns.</li>
+ <li>
+ The Graphics are much smoother due to another rendering configuration.</li>
+ <li>
+ Measured on a Sierpinski Triangle of depth 9, XLogo4Schools is around 25% faster than XLogo (16s vs. 21s on my machine). It is even faster, when many procedures are added to the workspace. XLogo uses a stack to manage its procedures and it uses O(N) string comparisons to find a procedure. Interestingly, the hash operations push and pop are not really used. XLogo4Schools uses a HashMap that usually works in O(1).</li>
+ </ul></body>
+</html>
\ No newline at end of file diff --git a/logo/src/xlogo/gui/AImprimer.java b/logo/src/xlogo/gui/AImprimer.java new file mode 100644 index 0000000..7f20ecb --- /dev/null +++ b/logo/src/xlogo/gui/AImprimer.java @@ -0,0 +1,90 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +package xlogo.gui; + +import java.awt.print.*; +import javax.swing.*; + +import java.awt.Image; +import java.awt.Graphics; + +public class AImprimer extends JPanel implements Printable, Runnable { + private static final long serialVersionUID = 1L; + private Image image; + + public AImprimer(Image image) { + this.image = image; + } + + public void run() { + Thread.currentThread().setPriority(Thread.MAX_PRIORITY); + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(this); + if (job.printDialog()) { + try { + job.print(); + } catch (PrinterException ex) { + System.out.println(ex.getMessage()); + } + } + } + + public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { + double largeur = image.getWidth(this); + double hauteur = image.getHeight(this); + double facteur = pf.getImageableWidth() / largeur; // largeur + // imprimable sur la + // feuille + double facteur2 = pf.getImageableHeight() / hauteur; // hauteur + // imprimable + // sur la + // feuille + + if (facteur < 1 | facteur2 < 1) { + facteur = Math.min(facteur, facteur2); + image = image.getScaledInstance((int) (largeur * facteur), + (int) (hauteur * facteur), Image.SCALE_SMOOTH); + } + largeur = image.getWidth(this); // permet d'attendre que l'image soit + // bien créée + hauteur = image.getHeight(this); + if (pi < 1) { + g.drawImage(this.image, (int) pf.getImageableX(), (int) pf + .getImageableY(), this); + return (Printable.PAGE_EXISTS); + } else + return Printable.NO_SUCH_PAGE; + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/gui/Editor.java b/logo/src/xlogo/gui/Editor.java new file mode 100644 index 0000000..6da4cd8 --- /dev/null +++ b/logo/src/xlogo/gui/Editor.java @@ -0,0 +1,396 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyListener; + +import javax.swing.GroupLayout; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import xlogo.storage.WSManager; +import xlogo.storage.user.UserConfig; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.utils.Utils; +import xlogo.Application; +import xlogo.kernel.userspace.UserSpace; +import xlogo.messages.MessageKeys; +import xlogo.messages.async.dialog.DialogMessenger; +import xlogo.Logo; + +/** + * Title : XLogo Description : XLogo is an interpreter for the Logo programming + * language + * <p> + * <p> + * Changes made in July 2013 by Marko Zivkovic: All the procedure analyzing is + * moved to class 'Workspace' which was then renamed to {@link UserSpace}. + * Reason: This is a GUI component and it should not do much model manipulation + * things. As often in XLogo this was an issue of weak separation of concerns, + * leading to bad modifiability, extensibility, changeability, and + * maintainability. Better have the Workspace deal with all the workspace + * management. For the editor, it's enough to edit text, do syntax highlighting, + * and provide the input text to some other specialized class. + * + * @author Loïc Le Coq, Marko Zivkovic + * + */ + +/* + * The main class for the Editor windows + */ +public class Editor implements ActionListener +{ + private JPanel mainPanel = new JPanel(); + private JPanel menu = new JPanel(); + private JButton chercher, undo, redo; + private JScrollPane scroll; + private EditorTextZone textZone; + // private ZoneEdition zonedition; + + private Application app; + private ReplaceFrame sf; + UserConfig uc; + + private KeyListener logoTextAnalyzerTrigger; + //private ArrayList<ProcedureErrorMessage> errors = new ArrayList<ProcedureErrorMessage>(); + + + public Editor(Application app) + { + super(); + mainPanel.setOpaque(true); + this.app = app; + uc = WSManager.getUserConfig(); + + try + { + initGui(); + } + catch (Exception e) + { + DialogMessenger.getInstance().dispatchError( + Logo.messages.getString(MessageKeys.GENERAL_ERROR_TITLE), + Logo.messages.getString(MessageKeys.ERROR_WHILE_CREATING_EDITOR)); + } + + } + + public String getText() + { + return textZone.getText(); + } + + public JComponent getComponent() + { + return mainPanel; + } + + /** + * Set the text of this component and displays it. <br> + * If the Editor was already open, it will store the old file and then + * display the new file. + * + * @param file + */ + public void setText(String text) + { + textZone.clearText(); + setEditorStyledText(text); + textZone.requestFocus(); + } + + /** + * @author Marko Zivkovic + */ + public void displayProcedure(String procedureName) + { + String to = Logo.messages.getString("pour"); + if (!textZone.find(to + " " + procedureName, false)) + textZone.find(to + " " + procedureName, true); + + } + + private void initGui() throws Exception + { + WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + + // Init All other components + scroll = new JScrollPane(); + if (wc.isSyntaxHighlightingEnabled()) + { + textZone = new EditorTextPane(this); + textZone.getTextComponent().addKeyListener(logoTextAnalyzerTrigger); + } + else + textZone = new EditorTextArea(this); + + sf = new ReplaceFrame(app.getFrame(), textZone); + + scroll.setPreferredSize(new Dimension(500, 500)); + scroll.getViewport().add(textZone.getTextComponent(), null); + sf = new ReplaceFrame(app.getFrame(), textZone); + + applyLayout(); + initToolbar(); + } + + private void applyLayout() + { + GroupLayout groupLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(groupLayout); + + groupLayout.setAutoCreateContainerGaps(true); + groupLayout.setAutoCreateGaps(true); + + groupLayout.setVerticalGroup( + groupLayout.createSequentialGroup() + .addComponent(menu) + .addComponent(scroll)); + + groupLayout.setHorizontalGroup( + groupLayout.createParallelGroup() + .addComponent(menu) + .addComponent(scroll)); + + FlowLayout flowLayout = new FlowLayout(); + menu.setLayout(flowLayout); + mainPanel.add(menu); + mainPanel.add(scroll); + } + + /* + * Below everything is inherited from XLogo, except for minor changes due to refactoring + */ + + + private void initToolbar() + { + menu.setMaximumSize(new Dimension(Integer.MAX_VALUE, 40)); + + chercher = getIconButton("chercher.png","find"); + undo = getIconButton("undo.png","editor.undo"); + redo = getIconButton("redo.png","editor.redo"); + + undo.setEnabled(false); + redo.setEnabled(false); + + menu.add(chercher); + menu.add(undo); + menu.add(redo); + + } + + private JButton getIconButton(String iconName, String description) + { + JButton btn = new JButton(); + if (iconName != null) + btn.setIcon(Utils.dimensionne_image(iconName, mainPanel)); + + btn.setToolTipText(Logo.messages.getString(description)); + btn.setActionCommand(Logo.messages.getString(description)); + btn.addActionListener(this); + return btn; + } + + public void actionPerformed(ActionEvent e) + { + String cmd = e.getActionCommand(); + if (cmd.equals(Logo.messages.getString("find"))) + { + if (!sf.isVisible()) + { + sf.setSize(350, 350); + sf.setVisible(true); + } + } + // Undo Action + else if (cmd.equals(Logo.messages.getString("editor.undo"))) + { + textZone.getUndoManager().undo(); + updateUndoRedoButtons(); + } + // Redo Action + else if (cmd.equals(Logo.messages.getString("editor.redo"))) + { + textZone.getUndoManager().redo(); + updateUndoRedoButtons(); + } + } + + // Change Syntax Highlighting for the editor + public void initStyles(int c_comment, int sty_comment, int c_primitive, int sty_primitive, int c_parenthese, + int sty_parenthese, int c_operande, int sty_operande) + { + WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + + if (textZone.supportHighlighting()) + { + ((EditorTextPane) textZone).getDsd().initStyles(wc.getCommentColor(), wc.getCommentStyle(), + wc.getPrimitiveColor(), wc.getPrimitiveStyle(), wc.getBraceColor(), + wc.getBraceStyle(), wc.getOperatorColor(), wc.getOperatorStyle()); + } + } + + // Enable or disable Syntax Highlighting + /* + * public void setColoration(boolean b){ if (textZone.supportHighlighting()) + * ((EditorTextPane)textZone).getDsd().setColoration(b); } + */ + public void setEditorFont(Font f) + { + textZone.setFont(f); + } + + /** + * Erase all text + */ + public void clearText() + { + textZone.clearText(); + } + + /** + * Convert the textZone from a JTextArea to a JTextPane To allow Syntax + * Highlighting + */ + public void toTextPane() + { + textZone.getTextComponent().removeKeyListener(logoTextAnalyzerTrigger); + scroll.getViewport().removeAll();// .remove(textZone.getTextComponent()); + String s = textZone.getText(); + textZone = new EditorTextPane(this); + sf = new ReplaceFrame(app.getFrame(), textZone); + textZone.ecris(s); + textZone.getTextComponent().addKeyListener(logoTextAnalyzerTrigger); + scroll.getViewport().add(textZone.getTextComponent()); + scroll.revalidate(); + } + + /** + * Convert the textZone from a JTextPane to a JTextArea Cause could be that: + * - Syntax Highlighting is disabled - Large text to display in the editor + */ + public void toTextArea() + { + /* + * Marko : for large text or disabled highlighting, we also don't want error messages to be produced while typing. + * + */ + textZone.getTextComponent().removeKeyListener(logoTextAnalyzerTrigger); + String s = textZone.getText(); + scroll.getViewport().removeAll();// .remove(textZone.getTextComponent()); + textZone = new EditorTextArea(this); + sf = new ReplaceFrame(app.getFrame(), textZone); + textZone.ecris(s); + scroll.getViewport().add(textZone.getTextComponent()); + scroll.revalidate(); + } + + /** + * Inserts the text at the current caret position. + * + * @param txt + */ + public void setEditorStyledText(String txt) + { + if (txt.length() < 100000) + { + textZone.ecris(txt); + } + else + { + if (textZone instanceof EditorTextPane) + { + WSManager.getWorkspaceConfig().setSyntaxHighlightingEnabled(false); + toTextArea(); + textZone.ecris(txt); + } + else + textZone.ecris(txt); + } + } + + /** + * append a procedure to the end of the document. + * + * @param program + * @author Marko Zivkovic + */ + public void append(String procedure) + { + if (procedure.length() < 100000) + { + textZone.append(procedure); + } + else + { + if (textZone instanceof EditorTextPane) + { + WSManager.getWorkspaceConfig().setSyntaxHighlightingEnabled(false); + toTextArea(); + textZone.append(procedure); + } + else + textZone.append(procedure); + } + } + + public void focus_textZone() + { + textZone.requestFocus(); + } + + public void discardAllEdits() + { + textZone.getUndoManager().discardAllEdits(); + updateUndoRedoButtons(); + } + + protected void updateUndoRedoButtons() + { + if (textZone.getUndoManager().canRedo()) + redo.setEnabled(true); + else + redo.setEnabled(false); + if (textZone.getUndoManager().canUndo()) + undo.setEnabled(true); + else + undo.setEnabled(false); + } + + +} diff --git a/logo/src/xlogo/gui/EditorTextArea.java b/logo/src/xlogo/gui/EditorTextArea.java new file mode 100644 index 0000000..387b30f --- /dev/null +++ b/logo/src/xlogo/gui/EditorTextArea.java @@ -0,0 +1,58 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.JTextArea; + +public class EditorTextArea extends EditorTextZone { + EditorTextArea(Editor editor){ + super(editor); + jtc=new JTextArea(); + initGui(); + } + public void setActive(boolean b){} + + protected void ecris(String s){ + int deb=jtc.getCaretPosition(); + ((JTextArea)jtc).insert(s,deb); + jtc.setCaretPosition(deb+s.length()); + } + + /** + * Added 21.6.2013 + * <p> this method is used to append a program to the end of the editor. + * It is used for the Logo command "define". + * @author Marko Zivkovic + */ + @Override + protected void append(String program) { + int deb= jtc.getText().length(); + ((JTextArea)jtc).insert(program,deb); + } +} diff --git a/logo/src/xlogo/gui/EditorTextPane.java b/logo/src/xlogo/gui/EditorTextPane.java new file mode 100644 index 0000000..fd069fe --- /dev/null +++ b/logo/src/xlogo/gui/EditorTextPane.java @@ -0,0 +1,83 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.text.BadLocationException; +import xlogo.StyledDocument.DocumentLogo; + + +public class EditorTextPane extends EditorTextZone{ + private DocumentLogo dsd; + EditorTextPane(Editor editor){ + super(editor); + dsd=new DocumentLogo(); + jtc=new ZoneEdition(this); + initGui(); + initHighlight(); + } + protected void initHighlight(){ + jtc.setDocument(dsd); + dsd.addUndoableEditListener(new MyUndoableEditListener()); + } + protected DocumentLogo getDsd(){ + return dsd; + } + protected void ecris(String mot){ + try{ + int deb=jtc.getCaretPosition(); + dsd.insertString(deb,mot,null); + jtc.setCaretPosition(deb+mot.length()); + } + catch(BadLocationException e){} + } + /** + * Added 21.6.2013 + * <p> this method is used to append a program to the end of the editor. + * It is used for the Logo command "define". + * @author Marko Zivkovic + */ + @Override + protected void append(String program) { + try{ + int deb= dsd.getLength(); + dsd.insertString(deb,program,null); + } + catch(BadLocationException e){} + + } + + public void setActive(boolean b){ + ((ZoneEdition)jtc).setActive(b); + } + + protected boolean supportHighlighting(){ + return true; + } + +} diff --git a/logo/src/xlogo/gui/EditorTextZone.java b/logo/src/xlogo/gui/EditorTextZone.java new file mode 100644 index 0000000..b14749b --- /dev/null +++ b/logo/src/xlogo/gui/EditorTextZone.java @@ -0,0 +1,303 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import java.awt.Font; +import java.awt.Graphics; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.util.Stack; +import java.util.StringTokenizer; +import javax.swing.event.UndoableEditEvent; +import javax.swing.event.UndoableEditListener; +import javax.swing.text.AbstractDocument; +import javax.swing.text.JTextComponent; +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultHighlighter; +import javax.swing.undo.UndoManager; +import javax.swing.undo.UndoableEdit; +import xlogo.Popup; +/** + * + * @author loic + * This class is the generic component to display the text in the editor + * If there are too many characters, it is a JTextArea <br> + * Else it's a JtextPane that allows Syntax Highlighting + */ +public abstract class EditorTextZone implements Searchable, Printable { + private Editor editor; + private StringBuffer text; + protected JTextComponent jtc; + private Popup jpop; + + private boolean highlightWasSet = false; + + // When printing the text area, this stack stores each page + private Stack<String> pages=null; + // To remember undoable edits + private UndoManager undoManager; + private int startOffset,endOffset; + /** + * Default constructor for this generic constructor + * + * @param editor The parent editor + */ + EditorTextZone(Editor editor){ + this.editor=editor; + + } + protected void initGui(){ + // Adds the JPopup Menu + jpop=new Popup(editor,jtc); + MouseListener popupListener = new PopupListener(); + jtc.addMouseListener(popupListener); + + jtc.addMouseListener(new MouseListener(){ + + @Override + public void mouseReleased(MouseEvent e) { } + + @Override + public void mousePressed(MouseEvent e) + { + } + + @Override + public void mouseExited(MouseEvent e) { } + + @Override + public void mouseEntered(MouseEvent e) { } + + @Override + public void mouseClicked(MouseEvent e) { + if (highlightWasSet) + { + removeHighlight(); + highlightWasSet = false; + } + } + }); + undoManager=new UndoManager(); + } + /** + * Erase all text + */ + protected void clearText(){ + jtc.setText(""); + } + + public boolean find(String searchText,boolean forward){ + try + { + int index; + String element = searchText.toLowerCase(); + text = new StringBuffer(jtc.getText().toLowerCase()); + // Find forward + if (forward) + index = text.indexOf(element, jtc.getCaretPosition()); + else + index = text.lastIndexOf(element, jtc.getCaretPosition()); + if (index == -1) + { + startOffset = 0; + endOffset = 0; + return false; + } + else + { + jtc.getHighlighter().removeAllHighlights(); + startOffset = index; + endOffset = index + element.length(); + jtc.getHighlighter().addHighlight(startOffset, endOffset, DefaultHighlighter.DefaultPainter); + if (forward) + jtc.setCaretPosition(index + element.length()); + else if (index > 1) + jtc.setCaretPosition(index - 1); + + highlightWasSet = true; + return true; + } + } + catch(NullPointerException e){} // If the combo is empty + catch(BadLocationException e){} + return false; + } + public void replace(String element, boolean forward){ + text.delete(startOffset, endOffset); + try{ + text.insert(startOffset,element ); + + } + catch(NullPointerException err){} + jtc.setText(text.toString()); + if (forward) jtc.setCaretPosition(endOffset); + else if (startOffset>1) jtc.setCaretPosition(startOffset-1); + + } + public void replaceAll(String element, String substitute){ + + try { + String string=jtc.getText().toString(); + string=string.replaceAll(element, substitute); + jtc.setText(string); + } + catch(NullPointerException e2){} + + } + public void removeHighlight(){ + jtc.getHighlighter().removeAllHighlights(); + } + + class MyUndoableEditListener implements UndoableEditListener{ + public void undoableEditHappened(UndoableEditEvent e){ + UndoableEdit edit = e.getEdit(); + // Include this method to ignore syntax changes + if (edit instanceof AbstractDocument.DefaultDocumentEvent && + ((AbstractDocument.DefaultDocumentEvent)edit).getType() == + AbstractDocument.DefaultDocumentEvent.EventType.CHANGE) { + return; + } + // Remember the edit + undoManager.addEdit(edit); +// System.out.println(e.getEdit().getPresentationName()); + editor.updateUndoRedoButtons(); + } +} + protected UndoManager getUndoManager(){ + return undoManager; + } + protected String getText(){ + return jtc.getText(); + } + public void requestFocus(){ + jtc.requestFocus(); + } + protected JTextComponent getTextComponent(){ + return jtc; + } + protected boolean supportHighlighting(){ + return false; + } + + protected void setFont(Font f){ + jtc.setFont(f); + } + protected Font getFont(){ + return jtc.getFont(); + } + // To print the text Area + + public int print(Graphics g,PageFormat pf, int pi) throws PrinterException{ + if(pi<pages.size()){ + jtc.setText(pages.get(pi)); + g.translate((int)pf.getImageableX(),(int)pf.getImageableY()); + jtc.paint(g); + return(Printable.PAGE_EXISTS); + } + else return Printable.NO_SUCH_PAGE; + } + protected void actionPrint(){ + Font font=jtc.getFont(); + String txt=jtc.getText(); + jtc.setFont(new Font(font.getFontName(),Font.PLAIN,10)); + jtc.setText(txt); + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(this,job.defaultPage()); + double h_imp=job.defaultPage().getImageableHeight(); + java.awt.FontMetrics fm = jtc.getFontMetrics(jtc.getFont()); + pages=new Stack<String>(); + StringTokenizer st = new StringTokenizer(txt, "\n"); + String page=""; + // System.out.println("hauteur "+fm.getHeight()+" "+h_imp); + int compteur=0; + while (st.hasMoreTokens()) { + String element = st.nextToken(); + compteur+=fm.getHeight(); + if (compteur>h_imp) { + pages.push(page); + page = element; + compteur=fm.getHeight(); + } + else page+= element+"\n"; + } + if (!page.equals("")) pages.push(page); + if (job.printDialog()) { + try { + job.print(); + } + catch (PrinterException ex) { + System.out.println(ex.getMessage()); + } + } + font=jtc.getFont(); + jtc.setFont(new Font(font.getFontName(),Font.PLAIN,12)); + jtc.setText(txt); + } + // Edit Actions + protected void copy(){ + jtc.copy(); + } + protected void cut(){ + jtc.cut(); + } + protected void paste(){ + jtc.paste(); + } + + // setText Method for Text Zone + protected void setText(String s){ + jtc.setText(s); + } + protected abstract void ecris(String s); + + protected abstract void append(String s); + + abstract void setActive(boolean b); + class PopupListener extends MouseAdapter { + + public void mousePressed(MouseEvent e) { + maybeShowPopup(e); + } + + public void mouseReleased(MouseEvent e) { + maybeShowPopup(e); + } + + private void maybeShowPopup(MouseEvent e) { + if (e.isPopupTrigger()) { + jpop.show(e.getComponent(), e.getX(), e.getY()); + } + } + } +} diff --git a/logo/src/xlogo/gui/HistoryPanel.java b/logo/src/xlogo/gui/HistoryPanel.java new file mode 100644 index 0000000..d1c17ba --- /dev/null +++ b/logo/src/xlogo/gui/HistoryPanel.java @@ -0,0 +1,416 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.*; + +import java.awt.*; +import java.awt.event.*; + +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; +import javax.swing.text.rtf.RTFEditorKit; +import javax.swing.text.*; + +import java.io.*; + +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +import xlogo.storage.user.UserConfig; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.utils.Utils; +import xlogo.utils.ExtensionFichier; +import xlogo.StyledDocument.DocumentLogoHistorique; +import xlogo.Application; +import xlogo.kernel.DrawPanel; +import xlogo.kernel.LogoError; +import xlogo.messages.async.AsyncMediumAdapter; +import xlogo.messages.async.AsyncMessage; +import xlogo.messages.async.AsyncMessenger; +import xlogo.messages.async.history.HistoryMessenger; +import xlogo.messages.async.history.HistoryWriter; +import xlogo.Logo; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +public class HistoryPanel extends JPanel implements HistoryWriter +{ + + private static final long serialVersionUID = 1L; + // numéro identifiant la police de + // l'historique avec "ecris" + public static int fontPrint = GlobalConfig.police_id(WSManager.getWorkspaceConfig().getFont()); // TODO + // how + // to + // remove + // fontPrint? + // Error@static? + private ImageIcon ianimation = Utils.dimensionne_image("animation.png", this); + private JLabel label_animation = new JLabel(ianimation); + private MouseAdapter mouseAdapt; + private Color couleur_texte = Color.BLUE; + private int taille_texte = 12; + private JPanel jPanel1 = new JPanel(); + private JScrollPane jScrollPane1 = new JScrollPane(); + private Historique historique = new Historique(); + private DocumentLogoHistorique dsd; + private BorderLayout borderLayout1 = new BorderLayout(); + private Application cadre; + + public HistoryPanel() + { + } + + public HistoryPanel(Application cadre) { + historique.setFont(WSManager.getWorkspaceConfig().getFont()); + this.cadre=cadre; + try { + jbInit(); + } + catch(Exception e) { + e.printStackTrace(); + } + dsd=new DocumentLogoHistorique(); + historique.setDocument(dsd); + + /* + * Added by Marko Zivkovic to decouple HistoryPanel from the rest of the old XLogo classes + */ + HistoryMessenger.getInstance().setMedium(new AsyncMediumAdapter<AsyncMessage<HistoryWriter>, HistoryWriter>(){ + + public boolean isReady() + { + return getThis().historique.isDisplayable(); + } + + public HistoryWriter getMedium() + { + return getThis(); + } + + public void addMediumReadyListener(final AsyncMessenger messenger) + { + historique.addAncestorListener(new AncestorListener(){ + public void ancestorRemoved(AncestorEvent event) + { + maybeMediumReadyEvent(); + } + public void ancestorMoved(AncestorEvent event) + { + maybeMediumReadyEvent(); + } + public void ancestorAdded(AncestorEvent event) + { + maybeMediumReadyEvent(); + } + + private void maybeMediumReadyEvent() + { + if (isDisplayable()) + messenger.onMediumReady(); + } + + }); + } + }); + } + + private HistoryPanel getThis() + { + return this; + } + + public Color getCouleurtexte() + { + return couleur_texte; + } + + public int police() + { + return taille_texte; + } + + public void vide_texte() + { + historique.setText(""); + } + + /** + * Made private by Marko Zivkovic. + * This functionality is now publicly available through the implementation of {@link HistoryWriter#writeMessage(String, String)} + * @param sty + * @param texte + */ + private void ecris(String sty, String texte) + { + try + { + int longueur = historique.getDocument().getLength(); + if (texte.length() > 32000) + throw new LogoError( Logo.messages.getString("chaine_trop_longue")); + if (longueur + texte.length() < 65000) + { + try + { + dsd.setStyle(sty); + dsd.insertString(dsd.getLength(), texte, null); + historique.setCaretPosition(dsd.getLength()); + } + catch (BadLocationException e) + {} + } + else + { + vide_texte(); + } + } + catch (LogoError e2) + {} + } + + private void jbInit() throws Exception + { + + this.setLayout(borderLayout1); + this.setMinimumSize(new Dimension(4, 4)); + this.setPreferredSize(new Dimension(600, 40)); + historique.setForeground(Color.black); + historique.setEditable(false); + this.add(jPanel1, BorderLayout.EAST); + label_animation.setToolTipText(Logo.messages.getString("animation_active")); + this.add(jScrollPane1, BorderLayout.CENTER); + jScrollPane1.getViewport().add(historique, null); + } + + public void active_animation() + { + add(label_animation, BorderLayout.WEST); + DrawPanel.classicMode = DrawPanel.MODE_ANIMATION; + mouseAdapt = new MouseAdapter(){ + public void mouseClicked(MouseEvent e) + { + stop_animation(); + cadre.getDrawPanel().repaint(); + } + }; + label_animation.addMouseListener(mouseAdapt); + validate(); + } + + public void stop_animation() + { + DrawPanel.classicMode = DrawPanel.MODE_CLASSIC; + remove(label_animation); + label_animation.removeMouseListener(mouseAdapt); + validate(); + } + + // Change Syntax Highlighting for the editor + public void initStyles(int c_comment, int sty_comment, int c_primitive, int sty_primitive, int c_parenthese, + int sty_parenthese, int c_operande, int sty_operande) + { + WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + dsd.initStyles(wc.getCommentColor(), wc.getCommentStyle(), wc.getPrimitiveColor(), wc.getPrimitiveStyle(), + wc.getBraceColor(), wc.getBraceStyle(), wc.getOperatorColor(), wc.getOperatorStyle()); + } + + // Enable or disable Syntax Highlighting + public void setColoration(boolean b) + { + dsd.setColoration(b); + } + + public void changeFont(Font f) + { + historique.setFont(f); + } + + public void updateText() + { + historique.setText(); + } + + public DocumentLogoHistorique getDsd() + { + return dsd; + } + + public StyledDocument sd_Historique() + { + return historique.getStyledDocument(); + } + + class Historique extends JTextPane implements ActionListener + { + private static final long serialVersionUID = 1L; + private JPopupMenu popup = new JPopupMenu(); + private JMenuItem jpopcopier = new JMenuItem(); + private JMenuItem jpopselect = new JMenuItem(); + private JMenuItem jpopsave = new JMenuItem(); + + Historique() + { + // this.setBackground(new Color(255,255,220)); + popup.add(jpopcopier); + popup.add(jpopselect); + popup.add(jpopsave); + jpopselect.addActionListener(this); + jpopcopier.addActionListener(this); + jpopsave.addActionListener(this); + setText(); + MouseListener popupListener = new MouseAdapter(){ + public void mouseClicked(MouseEvent e) + { + if (e.getButton() == 1) + { + int i = getCaretPosition(); + int borneinf = borne(i, -1); + int bornesup = borne(i, 1); + if (borneinf == 0) + borneinf = borneinf - 1; + select(borneinf + 1, bornesup - 2); + cadre.setCommandText(getSelectedText()); + // historique.setCaretPosition(historique.getDocument().getLength()); + cadre.focus_Commande(); + } + } + + public void mouseReleased(MouseEvent e) + { + maybeShowPopup(e); + cadre.focus_Commande(); + } + + public void mousePressed(MouseEvent e) + { + maybeShowPopup(e); + } + + private void maybeShowPopup(MouseEvent e) + { + if (e.isPopupTrigger()) + { + popup.show(e.getComponent(), e.getX(), e.getY()); + } + } + }; + addMouseListener(popupListener); + } + + int borne(int i, int increment) + { + boolean continuer = true; + while (continuer && i != 0) + { + select(i - 1, i); + String t = historique.getSelectedText(); + if (t.equals("\n")) + { + continuer = false; + } + i = i + increment; + } + return (i); + } + + void setText() + { + jpopselect.setText(Logo.messages.getString("menu.edition.selectall")); + jpopcopier.setText(Logo.messages.getString("menu.edition.copy")); + jpopsave.setText(Logo.messages.getString("menu.file.textzone.rtf")); + jpopselect.setActionCommand(Logo.messages.getString("menu.edition.selectall")); + jpopcopier.setActionCommand(Logo.messages.getString("menu.edition.copy")); + jpopsave.setActionCommand(Logo.messages.getString("menu.file.textzone.rtf")); + } + + public void actionPerformed(ActionEvent e) + { + UserConfig uc = WSManager.getUserConfig(); + WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance(); + String cmd = e.getActionCommand(); + if (Logo.messages.getString("menu.edition.copy").equals(cmd)) + { // Copier + copy(); + } + else if (Logo.messages.getString("menu.edition.selectall").equals(cmd)) + { // Selectionner tout + requestFocus(); + selectAll(); + cadre.focus_Commande(); + } + else if (cmd.equals(Logo.messages.getString("menu.file.textzone.rtf"))) + { + RTFEditorKit myRTFEditorKit = new RTFEditorKit(); + StyledDocument myStyledDocument = getStyledDocument(); + try + { + JFileChooser jf = new JFileChooser(Utils.SortieTexte(uc.getDefaultFolder())); + String[] ext = { ".rtf" }; + jf.addChoosableFileFilter(new ExtensionFichier(Logo.messages.getString("fichiers_rtf"), ext)); + Utils.recursivelySetFonts(jf, wc.getFont()); + int retval = jf.showDialog(cadre.getFrame(), Logo.messages.getString("menu.file.save")); + if (retval == JFileChooser.APPROVE_OPTION) + { + String path = jf.getSelectedFile().getPath(); + String path2 = path.toLowerCase(); // on garde la casse + // du path pour les + // systèmes + // d'exploitation + // faisant la + // différence + if (!path2.endsWith(".rtf")) + path += ".rtf"; + FileOutputStream myFileOutputStream = new FileOutputStream(path); + myRTFEditorKit.write(myFileOutputStream, myStyledDocument, 0, myStyledDocument.getLength() - 1); + myFileOutputStream.close(); + + } + } + catch (FileNotFoundException e1) + {} + catch (IOException e2) + {} + catch (BadLocationException e3) + {} + catch (NullPointerException e4) + {} + } + } + } + + public void writeMessage(String messageType, String message) + { + ecris(messageType, message); + } +} diff --git a/logo/src/xlogo/gui/Lis.java b/logo/src/xlogo/gui/Lis.java new file mode 100644 index 0000000..bd6c3ff --- /dev/null +++ b/logo/src/xlogo/gui/Lis.java @@ -0,0 +1,78 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +// Frame for the primitive "read" + + +import javax.swing.JFrame; +import javax.swing.JTextField; +import java.awt.HeadlessException; +import javax.swing.JButton; +import java.awt.event.*; +import java.awt.*; +import xlogo.utils.Utils; +import xlogo.Logo; +public class Lis extends JFrame implements ActionListener{ + private static final long serialVersionUID = 1L; + private JTextField texte=new JTextField(); + private JButton ok=new JButton(Logo.messages.getString("pref.ok")); + public Lis() throws HeadlessException { + } + public Lis(String titre,int longueur){ + setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("icone.png"))); + getContentPane().setLayout(new BorderLayout()); + this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + getContentPane().add(ok,BorderLayout.EAST); + getContentPane().add(texte,BorderLayout.CENTER); + texte.setPreferredSize(new Dimension(longueur,50)); + ok.setPreferredSize(new Dimension(75,50)); + texte.addActionListener(this); + ok.addActionListener(this); + pack(); + setTitle(titre); + Dimension d=Toolkit.getDefaultToolkit().getScreenSize().getSize(); + int x=(int)(d.getWidth()/2-longueur/2); + int y=(int)(d.getHeight()/2-25); + setLocation(x,y); + setVisible(true); + texte.requestFocus(); + } + public void actionPerformed(ActionEvent e){ + setVisible(false); + } + public String getText(){ + return texte.getText(); + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/gui/MyTextAreaDialog.java b/logo/src/xlogo/gui/MyTextAreaDialog.java new file mode 100644 index 0000000..fb689ce --- /dev/null +++ b/logo/src/xlogo/gui/MyTextAreaDialog.java @@ -0,0 +1,59 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import java.awt.Color; + +import javax.swing.JTextArea; + +import xlogo.StyledDocument.DocumentLogoHistorique; +import xlogo.storage.WSManager; +/** + * This class creates the common yellow JTextArea for all dialog box. + * @author loic + * + */ +public class MyTextAreaDialog extends JTextArea { + + private static final long serialVersionUID = 1L; + public MyTextAreaDialog(String message){ + setText(message); + setEditable(false); + setBackground(new Color(255,255,177)); + setFont(WSManager.getWorkspaceConfig().getFont()); + } + + public MyTextAreaDialog(String message, DocumentLogoHistorique dsd){ + setFont(dsd.getFont()); + setText(message); + setEditable(false); + setBackground(new Color(255,255,177)); + setFont(WSManager.getWorkspaceConfig().getFont()); + } +} diff --git a/logo/src/xlogo/gui/MyToolBar.java b/logo/src/xlogo/gui/MyToolBar.java new file mode 100644 index 0000000..bb7afa3 --- /dev/null +++ b/logo/src/xlogo/gui/MyToolBar.java @@ -0,0 +1,126 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JToolBar; +import xlogo.MenuListener; +import xlogo.utils.Utils; + +public class MyToolBar extends JToolBar { + private static final long serialVersionUID = 1L; + private MenuListener menulistener; + private ImageIcon izoomin=Utils.dimensionne_image("zoomin.png",this); + private ImageIcon izoomout=Utils.dimensionne_image("zoomout.png",this); + private ImageIcon icopier=Utils.dimensionne_image("editcopy.png",this); + private ImageIcon icoller=Utils.dimensionne_image("editpaste.png",this); + private ImageIcon icouper=Utils.dimensionne_image("editcut.png",this); + private ImageIcon iplay=Utils.dimensionne_image("play.png",this); + //private ImageIcon iturtleProp=new ImageIcon(Utils.dimensionne_image("turtleProp.png", this)); + private JButton zoomin=new JButton(izoomin); + private JButton zoomout=new JButton(izoomout); + private JButton copier=new JButton(icopier); + private JButton coller=new JButton(icoller); + private JButton couper=new JButton(icouper); + private JButton play=new JButton(iplay); + //private JButton turtleProp=new JButton(iturtleProp); + + + public MyToolBar(MenuListener menulistener){ + super(JToolBar.VERTICAL); + this.menulistener=menulistener; + initGui(); + } + + private void initGui(){ + zoomin.addActionListener(menulistener); + zoomin.setActionCommand(MenuListener.ZOOMIN); + zoomout.addActionListener(menulistener); + zoomout.setActionCommand(MenuListener.ZOOMOUT); + copier.addActionListener(menulistener); + copier.setActionCommand(MenuListener.EDIT_COPY); + couper.addActionListener(menulistener); + couper.setActionCommand(MenuListener.EDIT_CUT); + coller.addActionListener(menulistener); + coller.setActionCommand(MenuListener.EDIT_PASTE); + play.addActionListener(menulistener); + play.setActionCommand(MenuListener.PLAY); +/* slider= new JSlider(JSlider.VERTICAL); + slider.setValue(slider.getMaximum()-Config.turtleSpeed); + //Create the label table + Hashtable labelTable = new Hashtable(); + labelTable.put( new Integer( 0 ), new JLabel("Slow") ); + labelTable.put( new Integer( 100 ), new JLabel("Fast") ); + slider.setLabelTable( labelTable ); + slider.setPaintLabels(true); + /* slider.setMajorTickSpacing(10); + slider.setMinorTickSpacing(5); + slider.setPaintTicks(true); + + slider.setSnapToTicks(true); + slider.addChangeListener(new ChangeListener(){ + public void stateChanged(ChangeEvent e) { + JSlider source = (JSlider)e.getSource(); + int value=source.getValue(); + Config.turtleSpeed=source.getMaximum()-value; + } + }); + int width=Toolkit.getDefaultToolkit().getScreenSize().width; + width=32*width/1024; + slider.setMinimumSize(new java.awt.Dimension(width,200)); + slider.setMaximumSize(new java.awt.Dimension(width,200)); + */ + add(zoomin); + addSeparator(); + add(zoomout); + addSeparator(); + add(couper); + addSeparator(); + add(copier); + addSeparator(); + add(coller); + addSeparator(); + add(play); + addSeparator(); +// add(slider); + } + public void enabledPlay(boolean b){ + play.setEnabled(b); + } + /** + * Enables or disables the zoom buttons + * @param b The boolean + */ + public void setZoomEnabled(boolean b){ + zoomin.setEnabled(b); + zoomout.setEnabled(b); +// repaint(); + } +} diff --git a/logo/src/xlogo/gui/ReplaceFrame.java b/logo/src/xlogo/gui/ReplaceFrame.java new file mode 100644 index 0000000..f51229f --- /dev/null +++ b/logo/src/xlogo/gui/ReplaceFrame.java @@ -0,0 +1,265 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.JDialog; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JRadioButton; +import javax.swing.JPanel; +import javax.swing.BoxLayout; + +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JLabel; +import javax.swing.ButtonGroup; +import javax.swing.BorderFactory; +import javax.swing.border.TitledBorder; +import javax.swing.text.Highlighter; + +import java.awt.event.*; + +import javax.swing.JFrame; + +import xlogo.Logo; +import xlogo.storage.WSManager; +public class ReplaceFrame extends JDialog implements ActionListener{ + private static final long serialVersionUID = 1L; + private final String FIND="find"; + private final String REPLACE="replace"; + private final String REPLACEALL="replaceall"; + private final String FIND_REPLACE="find_replace"; + + private JButton find,replace,findReplace,replaceAll; + private JRadioButton backward, forward; + private JPanel buttonPanel; + private JComboBox comboFind,comboReplace; + private ButtonGroup bg; + private JLabel labelFind, labelReplace,labelResult; + private Searchable jtc; + Highlighter.HighlightPainter cyanPainter; + + public ReplaceFrame(JFrame jf,Searchable jtc){ + super(jf); + this.jtc=jtc; + initGui(); + } + + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (cmd.equals(FIND)){ + find(); + + } + else if (cmd.equals(REPLACE)){ + replace(); + } + else if (cmd.equals(FIND_REPLACE)){ + replace(); + find(); + } + else if (cmd.equals(REPLACEALL)){ + replaceAll(); + } + + } + private void replaceAll(){ + String substitute=""; + try { + substitute=comboReplace.getSelectedItem().toString(); + addCombo(substitute,comboReplace); + } + catch(NullPointerException e2){} + String element=comboFind.getSelectedItem().toString(); + addCombo(element,comboFind); + jtc.replaceAll(element, substitute); + replace.setEnabled(false); + findReplace.setEnabled(false); + + } + private void replace(){ + String element=comboReplace.getSelectedItem().toString(); + addCombo(element,comboReplace); + jtc.replace(element,forward.isSelected()); + replace.setEnabled(false); + findReplace.setEnabled(false); + } + private void find(){ + String element=comboFind.getSelectedItem().toString(); + // Add the element to the combobox + addCombo(element,comboFind); + boolean b=jtc.find(element,forward.isSelected()); + if (b) { + replace.setEnabled(true); + findReplace.setEnabled(true); + // Found + labelResult.setText(""); + } + else { + replace.setEnabled(false); + findReplace.setEnabled(false); + // Not found + labelResult.setText(Logo.messages.getString("string_not_found")); + } + } + protected void processWindowEvent(WindowEvent e){ + super.processWindowEvent(e); + if (e.getID()==WindowEvent.WINDOW_CLOSING){ + jtc.removeHighlight(); + } + } + private void addCombo(String element,JComboBox combo){ + boolean b=false; + for (int i=0;i<combo.getItemCount();i++){ + if (combo.getItemAt(i).equals(element)) { + b=true; + break; + } + } + if (!b){ + combo.insertItemAt(element, 0); + int n=combo.getItemCount(); + if (n>10){ + combo.removeItemAt(n-1); + } + } + } + private void setFont(){ + Font font = WSManager.getWorkspaceConfig().getFont(); + find.setFont(font); + replace.setFont(font); + findReplace.setFont(font); + replaceAll.setFont(font); + backward.setFont(font); + forward.setFont(font); + comboFind.setFont(font); + comboReplace.setFont(font); + labelFind.setFont(font); + labelReplace.setFont(font); + labelResult.setFont(font); + + + } + protected void setText(){ + setFont(); + backward=new JRadioButton(Logo.messages.getString("backward")); + forward=new JRadioButton(Logo.messages.getString("forward")); + TitledBorder tb=BorderFactory.createTitledBorder(Logo.messages.getString("direction")); + tb.setTitleFont(WSManager.getWorkspaceConfig().getFont()); + buttonPanel.setBorder(tb); + find=new JButton(Logo.messages.getString("find")); + replace=new JButton(Logo.messages.getString("replace")); + findReplace=new JButton(Logo.messages.getString("find_replace")); + replaceAll=new JButton(Logo.messages.getString("replaceall")); + labelFind=new JLabel(Logo.messages.getString("find")+" :"); + labelReplace=new JLabel(Logo.messages.getString("replacewith")); + setTitle(Logo.messages.getString("find_replace")); + } + private void initGui(){ + + setTitle(Logo.messages.getString("find_replace")); + // Init the RadioButton for the direction search + backward=new JRadioButton(Logo.messages.getString("backward")); + forward=new JRadioButton(Logo.messages.getString("forward")); + forward.setSelected(true); + bg=new ButtonGroup(); + bg.add(forward); + bg.add(backward); + buttonPanel=new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.Y_AXIS)); + buttonPanel.add(forward); + buttonPanel.add(backward); + TitledBorder tb=BorderFactory.createTitledBorder(Logo.messages.getString("direction")); + tb.setTitleFont(WSManager.getWorkspaceConfig().getFont()); + buttonPanel.setBorder(tb); + // Init Buttons + find=new JButton(Logo.messages.getString("find")); + replace=new JButton(Logo.messages.getString("replace")); + findReplace=new JButton(Logo.messages.getString("find_replace")); + replaceAll=new JButton(Logo.messages.getString("replaceall")); + findReplace.setEnabled(false); + replace.setEnabled(false); + find.addActionListener(this); + findReplace.addActionListener(this); + replaceAll.addActionListener(this); + replace.addActionListener(this); + find.setActionCommand(FIND); + replace.setActionCommand(REPLACE); + findReplace.setActionCommand(FIND_REPLACE); + replaceAll.setActionCommand(REPLACEALL); + + // Init JLabel and JCombobox + labelFind=new JLabel(Logo.messages.getString("find")+" :"); + labelReplace=new JLabel(Logo.messages.getString("replacewith")); + labelResult=new JLabel(); + + comboFind=new JComboBox(); + comboReplace=new JComboBox(); + comboFind.setEditable(true); + comboReplace.setEditable(true); + setFont(); + getContentPane().setLayout(new GridBagLayout()); + + // Draw all + + getContentPane().add(labelFind, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(comboFind, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(labelReplace, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(comboReplace, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(buttonPanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(labelResult, new GridBagConstraints(1, 2, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(find, new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(replace, new GridBagConstraints(1, 3, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(findReplace, new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(replaceAll, new GridBagConstraints(1, 4, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + } +} diff --git a/logo/src/xlogo/gui/SearchFrame.java b/logo/src/xlogo/gui/SearchFrame.java new file mode 100644 index 0000000..2a177e8 --- /dev/null +++ b/logo/src/xlogo/gui/SearchFrame.java @@ -0,0 +1,189 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.JDialog; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JRadioButton; +import javax.swing.JPanel; +import javax.swing.BoxLayout; + +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JLabel; +import javax.swing.ButtonGroup; +import javax.swing.BorderFactory; +import javax.swing.border.TitledBorder; +import javax.swing.text.Highlighter; + +import java.awt.event.*; + +import javax.swing.JFrame; + +import xlogo.Logo; +import xlogo.storage.WSManager; +public class SearchFrame extends JDialog implements ActionListener{ + private static final long serialVersionUID = 1L; + private final String FIND="find"; + + private JButton find; + private JRadioButton backward, forward; + private JPanel buttonPanel; + private JComboBox comboFind; + private ButtonGroup bg; + private JLabel labelFind,labelResult; + private Searchable jtc; + Highlighter.HighlightPainter cyanPainter; + + public SearchFrame(JFrame jf,Searchable jtc){ + super(jf); + this.jtc=jtc; + initGui(); + } + + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (cmd.equals(FIND)){ + find(); + + } + } + private void find(){ + String element=comboFind.getSelectedItem().toString(); + // Add the element to the combobox + addCombo(element,comboFind); + boolean b=jtc.find(element,forward.isSelected()); + if (b) { + // Found + labelResult.setText(""); + } + else { + // Not found + labelResult.setText(Logo.messages.getString("string_not_found")); + } + } + protected void processWindowEvent(WindowEvent e){ + super.processWindowEvent(e); + if (e.getID()==WindowEvent.WINDOW_CLOSING){ + jtc.removeHighlight(); + } + } + private void addCombo(String element,JComboBox combo){ + boolean b=false; + for (int i=0;i<combo.getItemCount();i++){ + if (combo.getItemAt(i).equals(element)) { + b=true; + break; + } + } + if (!b){ + combo.insertItemAt(element, 0); + int n=combo.getItemCount(); + if (n>10){ + combo.removeItemAt(n-1); + } + } + } + protected void setText(){ + Font font = WSManager.getWorkspaceConfig().getFont(); + backward.setFont(font); + forward.setFont(font); + find.setFont(font); + labelFind.setFont(font); + setFont(font); + backward=new JRadioButton(Logo.messages.getString("backward")); + forward=new JRadioButton(Logo.messages.getString("forward")); + TitledBorder tb=BorderFactory.createTitledBorder(Logo.messages.getString("direction")); + tb.setTitleFont(font); + buttonPanel.setBorder(tb); + find=new JButton(Logo.messages.getString("find")); + labelFind=new JLabel(Logo.messages.getString("find")+" :"); + setTitle(Logo.messages.getString("find_replace")); + } + private void initGui(){ + Font font = WSManager.getWorkspaceConfig().getFont(); + + setTitle(Logo.messages.getString("find_replace")); + // Init the RadioButton for the direction search + backward=new JRadioButton(Logo.messages.getString("backward")); + forward=new JRadioButton(Logo.messages.getString("forward")); + forward.setSelected(true); + bg=new ButtonGroup(); + bg.add(forward); + bg.add(backward); + buttonPanel=new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.Y_AXIS)); + buttonPanel.add(forward); + buttonPanel.add(backward); + TitledBorder tb=BorderFactory.createTitledBorder(Logo.messages.getString("direction")); + tb.setTitleFont(font); + buttonPanel.setBorder(tb); + + // Init Buttons + find=new JButton(Logo.messages.getString("find")); + find.addActionListener(this); + find.setActionCommand(FIND); + + // Init JLabel and JCombobox + labelFind=new JLabel(Logo.messages.getString("find")+" :"); + labelResult=new JLabel(); + + comboFind=new JComboBox(); + comboFind.setEditable(true); + + backward.setFont(font); + forward.setFont(font); + find.setFont(font); + labelFind.setFont(font); + setFont(font); + + getContentPane().setLayout(new GridBagLayout()); + // Draw all + + getContentPane().add(labelFind, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(comboFind, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(buttonPanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(labelResult, new GridBagConstraints(0, 3, 2, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( + 10, 10, 10, 10), 0, 0)); + getContentPane().add(find, new GridBagConstraints(1, 2, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( + 10, 10, 10, 10), 0, 0)); + } +} diff --git a/logo/src/xlogo/gui/Searchable.java b/logo/src/xlogo/gui/Searchable.java new file mode 100644 index 0000000..2244de8 --- /dev/null +++ b/logo/src/xlogo/gui/Searchable.java @@ -0,0 +1,36 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +public interface Searchable { + boolean find(String element, boolean forward); + void replace(String element,boolean forward); + void replaceAll(String element,String substitute); + void removeHighlight(); +} diff --git a/logo/src/xlogo/gui/Traduc.java b/logo/src/xlogo/gui/Traduc.java new file mode 100644 index 0000000..1c36acc --- /dev/null +++ b/logo/src/xlogo/gui/Traduc.java @@ -0,0 +1,216 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; +import javax.swing.*; + +import java.awt.*; +import java.awt.event.*; +import java.util.StringTokenizer; +import java.util.Enumeration; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.TreeMap; + +import xlogo.storage.WSManager; +import xlogo.storage.workspace.Language; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.utils.Utils; +import xlogo.Logo; +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ + +/** Frame For translating Logo Code from a language to another + * * */ + +public class Traduc extends JFrame implements ActionListener { + private static final long serialVersionUID = 1L; + private JLabel traduire_de=new JLabel(Logo.messages.getString("traduire_de")+" "); + private JLabel vers=new JLabel(" "+Logo.messages.getString("vers")+" "); + + private JComboBox combo_origine=new JComboBox(Logo.translationLanguage); + private JComboBox combo_destination=new JComboBox(Logo.translationLanguage); + private JScrollPane js_source=new JScrollPane(); + private JScrollPane js_destination=new JScrollPane(); + private JTextArea origine=new JTextArea(); + private JTextArea destination=new JTextArea(); + private JPanel p_nord_origine =new JPanel(); + private JPanel p_nord_destination =new JPanel(); + private JPanel p_ouest =new JPanel(); + private JPanel p_est=new JPanel(); + private JPanel p_edition_origine=new JPanel(); + private JPanel p_edition_destination=new JPanel(); + private JButton traduire=new JButton(Logo.messages.getString("traduire")); + private ImageIcon icopier=Utils.dimensionne_image("editcopy.png",this); + private ImageIcon icoller=Utils.dimensionne_image("editpaste.png",this); + private ImageIcon icouper=Utils.dimensionne_image("editcut.png",this); + private JButton copier_origine=new JButton(icopier); + private JButton coller_origine=new JButton(icoller); + private JButton couper_origine=new JButton(icouper); + private JButton copier_destination=new JButton(icopier); + private JButton coller_destination=new JButton(icoller); + private JButton couper_destination=new JButton(icouper); + + private ResourceBundle primitives_origine=null; + private ResourceBundle primitives_destination=null; + private TreeMap<String,String> tre=new TreeMap<String,String>(); + + public Traduc(){ + WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + Font font = wc.getFont(); + Language lang = wc.getLanguage(); + + setTitle(Logo.messages.getString("menu.tools.translate")); + setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("icone.png"))); + setFont(font); + traduire.setFont(font); + vers.setFont(font); + traduire_de.setFont(font); + getContentPane().setLayout(new BorderLayout()); + combo_origine.setSelectedIndex(lang.getValue()); + combo_destination.setSelectedIndex(lang.getValue()); + + p_nord_origine.add(traduire_de); + p_nord_origine.add(combo_origine); + p_nord_destination.add(vers); + p_nord_destination.add(combo_destination); + + p_edition_origine.add(copier_origine); + p_edition_origine.add(couper_origine); + p_edition_origine.add(coller_origine); + + p_ouest.setLayout(new BorderLayout()); + p_ouest.add(js_source,BorderLayout.CENTER); + p_ouest.add(p_edition_origine,BorderLayout.SOUTH); + p_ouest.add(p_nord_origine,BorderLayout.NORTH); + + getContentPane().add(p_ouest,BorderLayout.WEST); + + p_edition_destination.add(copier_destination); + p_edition_destination.add(couper_destination); + p_edition_destination.add(coller_destination); + + p_est.setLayout(new BorderLayout()); + p_est.add(js_destination,BorderLayout.CENTER); + p_est.add(p_edition_destination,BorderLayout.SOUTH); + p_est.add(p_nord_destination,BorderLayout.NORTH); + + getContentPane().add(p_est,BorderLayout.EAST); + getContentPane().add(traduire,BorderLayout.CENTER); + + js_source.getViewport().add(origine); + js_destination.getViewport().add(destination); + js_source.setPreferredSize(new Dimension(300,300)); + js_destination.setPreferredSize(new Dimension(300,300)); + + traduire.addActionListener(this); + copier_destination.addActionListener(this); + couper_destination.addActionListener(this); + coller_destination.addActionListener(this); + copier_origine.addActionListener(this); + couper_origine.addActionListener(this); + coller_origine.addActionListener(this); + copier_origine.setActionCommand("copier_origine"); + couper_origine.setActionCommand("couper_origine"); + coller_origine.setActionCommand("coller_origine"); + coller_destination.setActionCommand("coller_destination"); + copier_destination.setActionCommand("copier_destination"); + couper_destination.setActionCommand("couper_destination"); + + pack(); + setVisible(true); + } + + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (Logo.messages.getString("traduire").equals(cmd)){ + String texte=origine.getText(); + texte=texte.replaceAll("\\t", " "); + primitives_origine=genere_langue(combo_origine); + primitives_destination=genere_langue(combo_destination); + Enumeration<String> en=primitives_origine.getKeys(); + while (en.hasMoreElements()){ + String element=en.nextElement().toString(); + String primitives=primitives_origine.getString(element); + String primitives2=primitives_destination.getString(element); + StringTokenizer st=new StringTokenizer(primitives); + StringTokenizer st2=new StringTokenizer(primitives2); + int compteur=st.countTokens(); + for (int i=0;i<compteur;i++){ + while (st2.hasMoreTokens()) element=st2.nextToken(); + tre.put(st.nextToken(),element); + } + } + // ajout des mots clés pour et fin + int id=combo_origine.getSelectedIndex(); + Locale locale=Language.getLanguage(id).getLocale(); + ResourceBundle res1=ResourceBundle.getBundle("langage",locale); + id=combo_destination.getSelectedIndex(); + locale=Language.getLanguage(id).getLocale(); + ResourceBundle res2=ResourceBundle.getBundle("langage",locale); + tre.put(res1.getString("pour"),res2.getString("pour")); + tre.put(res1.getString("fin"),res2.getString("fin")); + StringTokenizer st=new StringTokenizer(texte," */+-\n|&()[]",true); + String traduc=""; + while (st.hasMoreTokens()){ + String element=st.nextToken().toLowerCase(); + if (tre.containsKey(element)) traduc+=tre.get(element); + else traduc+=element; + } + destination.setText(traduc); + } + else if ("copier_origine".equals(cmd)) { + origine.copy(); + } + else if ("couper_origine".equals(cmd)) { + origine.cut(); + } + else if ("coller_origine".equals(cmd)) { + origine.paste(); + } + else if ("copier_destination".equals(cmd)) { + destination.copy(); + } + else if ("couper_destination".equals(cmd)) { + destination.cut(); + } + else if ("coller_destination".equals(cmd)) { + destination.paste(); + } + } + private ResourceBundle genere_langue(JComboBox jc){ // fixe la langue utilisée pour les messages + Locale locale=null; + int id=jc.getSelectedIndex(); + locale=Language.getLanguage(id).getLocale(); + return ResourceBundle.getBundle("primitives",locale); + } +} diff --git a/logo/src/xlogo/gui/ZoneCommande.java b/logo/src/xlogo/gui/ZoneCommande.java new file mode 100644 index 0000000..0bc5f76 --- /dev/null +++ b/logo/src/xlogo/gui/ZoneCommande.java @@ -0,0 +1,271 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.event.*; +import javax.swing.text.BadLocationException; + +import java.awt.Color; + +import xlogo.StyledDocument.DocumentLogoCommande; +import xlogo.storage.WSManager; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.Application; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +public class ZoneCommande extends JTextPane implements CaretListener +{ + private static final long serialVersionUID = 1L; + private DocumentLogoCommande dlc; + // Si la correspondance entre parenthese ou crochets est activée + private boolean active = false; + // Dernière position allumée + private int[] position = new int[2]; + + public ZoneCommande(Application cadre) + { + dlc = new DocumentLogoCommande(cadre); + this.setBackground(Color.WHITE); + setDocument(dlc); + addCaretListener(this); + } + + class verif_parenthese implements Runnable + { + int pos; + + verif_parenthese(int pos) + { + this.pos = pos; + } + + public void run() + { + if (active) + { + active = false; + int debut = position[0]; + int fin = position[0]; + if (debut != -1) + { + if (debut > 0) + debut--; + if (fin < dlc.getLength()) + fin++; + try + { + String content = dlc.getText(0, dlc.getLength()); + // System.out.println(debut+" "+fin); + dlc.colore(content, debut, fin); + } + catch (BadLocationException e) + {} + } + debut = position[1]; + fin = position[1]; + if (debut != -1) + { + if (debut > 0) + debut--; + if (fin < dlc.getLength()) + debut++; + if (fin < dlc.getLength()) + fin++; + try + { + String content = dlc.getText(0, dlc.getLength()); + // System.out.println(debut+" "+fin); + dlc.colore(content, debut, fin); + } + catch (BadLocationException e) + {} + } + } + int length = dlc.getLength(); + try + { + String content = dlc.getText(pos, length - pos); + int id = -1; + if (length > pos) + { + id = "[]()".indexOf(content.substring(0, 1)); + } + if (id > -1 && !TesteBackslash(dlc.getText(0, pos), pos)) + { + active = true; + switch (id) + { + case 0: + chercheApres(content, pos, "[", "]"); + break; + case 1: + content = getText(0, pos); + chercheAvant(content, pos, "[", "]"); + break; + case 2: + chercheApres(content, pos, "(", ")"); + break; + case 3: + content = getText(0, pos); + chercheAvant(content, pos, "(", ")"); + break; + } + } + } + catch (BadLocationException e1) + {} + + } + } + + public void caretUpdate(CaretEvent e) + { + int pos = e.getDot(); + if (WSManager.getWorkspaceConfig().isSyntaxHighlightingEnabled()) + SwingUtilities.invokeLater(new verif_parenthese(pos)); + } + + // Teste si le caractère précédent est un backslash + private boolean TesteBackslash(String content, int pos) + { + String caractere = ""; + if (pos > 0) + caractere = content.substring(pos - 1, pos); + // System.out.println(caractere); + if (caractere.equals("\\")) + return true; + return false; + } + + void chercheApres(String content, int pos, String ouv, String fer) + { + boolean continuer = true; + int of_ouvrant; + int of_fermant = 0; + int from_index_ouvrant = 1; + int from_index_fermant = 1; + while (continuer) + { + of_ouvrant = content.indexOf(ouv, from_index_ouvrant); + while (of_ouvrant != -1 && TesteBackslash(content, of_ouvrant)) + of_ouvrant = content.indexOf(ouv, of_ouvrant + 1); + of_fermant = content.indexOf(fer, from_index_fermant); + while (of_fermant != -1 && TesteBackslash(content, of_fermant)) + { + of_fermant = content.indexOf(fer, of_fermant + 1); + // System.out.println(of_fermant); + } + if (of_fermant == -1) + break; + if (of_ouvrant != -1 && of_ouvrant < of_fermant) + { + from_index_ouvrant = of_ouvrant + 1; + from_index_fermant = of_fermant + 1; + } + else + continuer = false; + ; + } + if (of_fermant != -1) + { + dlc.Montre_Parenthese(of_fermant + pos); + position[1] = of_fermant + pos; + } + else + position[1] = -1; + dlc.Montre_Parenthese(pos); + position[0] = pos; + } + + void chercheAvant(String content, int pos, String ouv, String fer) + { + boolean continuer = true; + int of_fermant = 0; + int of_ouvrant = 0; + int from_index_ouvrant = pos; + int from_index_fermant = pos; + while (continuer) + { + of_ouvrant = content.lastIndexOf(ouv, from_index_ouvrant); + while (of_ouvrant != -1 && TesteBackslash(content, of_ouvrant)) + of_ouvrant = content.lastIndexOf(ouv, of_ouvrant - 1); + of_fermant = content.lastIndexOf(fer, from_index_fermant); + while (of_fermant != -1 && TesteBackslash(content, of_fermant)) + of_fermant = content.lastIndexOf(fer, of_fermant - 1); + if (of_ouvrant == -1) + break; + if (of_ouvrant < of_fermant) + { + from_index_ouvrant = of_ouvrant - 1; + from_index_fermant = of_fermant - 1; + } + else + continuer = false; + ; + } + if (of_ouvrant != -1) + { + dlc.Montre_Parenthese(of_ouvrant); + position[0] = of_ouvrant; + } + else + position[0] = -1; + dlc.Montre_Parenthese(pos); + position[1] = pos; + } + + // Change Syntax Highlighting for the command line + public void initStyles(int c_comment, int sty_comment, int c_primitive, int sty_primitive, int c_parenthese, + int sty_parenthese, int c_operande, int sty_operande) + { + WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + dlc.initStyles(wc.getCommentColor(), wc.getCommentStyle(), wc.getPrimitiveColor(), wc.getPrimitiveStyle(), + wc.getBraceColor(), wc.getBraceStyle(), wc.getOperatorColor(), wc.getOperatorStyle()); + } + + // Enable or disable Syntax Highlighting + public void setColoration(boolean b) + { + dlc.setColoration(b); + } + + public void setActive(boolean b) + { + active = b; + } + +} diff --git a/logo/src/xlogo/gui/ZoneEdition.java b/logo/src/xlogo/gui/ZoneEdition.java new file mode 100644 index 0000000..afbda11 --- /dev/null +++ b/logo/src/xlogo/gui/ZoneEdition.java @@ -0,0 +1,196 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui; + +import javax.swing.event.*; +import javax.swing.JTextPane; +import javax.swing.text.BadLocationException; +import javax.swing.SwingUtilities; + +import xlogo.StyledDocument.DocumentLogo; +import xlogo.storage.WSManager; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +class ZoneEdition extends JTextPane implements CaretListener{ + private static final long serialVersionUID = 1L; + private DocumentLogo dsd=null; + // Si la correspondance entre parenthese ou crochets est activée + private boolean active=false; + // Dernière position allumée + private int[] position=new int[2]; + + +// public DocumentLogo getDsd(){ +// return dsd; +// } + public void setActive(boolean b){ + active=b; + } + ZoneEdition(EditorTextPane etp){ + dsd=etp.getDsd(); + addCaretListener(this); +} + +// Teste si le caractère précédent est un backslash +private boolean TesteBackslash(String content,int pos){ + String caractere=""; + if (pos>0) caractere=content.substring(pos-1,pos); + //System.out.println(caractere); + if (caractere.equals("\\")) return true; + return false; +} + +class verif_parenthese implements Runnable{ + int pos; + verif_parenthese(int pos){ + this.pos=pos; + } + public void run(){ + if (active){ + active=false; + int debut=position[0]; + int fin=position[0]; + if (debut!=-1){ + if (debut>0) debut--; + if (fin<dsd.getLength()) fin++; + try{ + String content=dsd.getText(0,dsd.getLength()); + dsd.colore(content,debut,fin); + } + catch(BadLocationException e){} + } + debut=position[1]; + fin=position[1]; + if (debut!=-1){ + if (debut>0) debut--; + if (fin<dsd.getLength()) debut++; + if (fin<dsd.getLength()) fin++; + try{ + String content=dsd.getText(0,dsd.getLength()); + dsd.colore(content,debut,fin); + } + catch(BadLocationException e){} + } + } + int length=dsd.getLength(); + try{ + String content=dsd.getText(pos,length-pos); + int id=-1; + if (length>pos) { + id="[]()".indexOf(content.substring(0,1)); + } + if (id>-1&&!TesteBackslash(dsd.getText(0,pos),pos)){ + active=true; + switch(id){ + case 0: + chercheApres(content,pos,"[","]"); + break; + case 1: + content=getText(0,pos); + chercheAvant(content,pos,"[","]"); + break; + case 2: + chercheApres(content,pos,"(",")"); + break; + case 3: + content=getText(0,pos); + chercheAvant(content,pos,"(",")"); + break; + } + } + } + catch(BadLocationException e1){} + + } +} +public void caretUpdate(CaretEvent e){ + int pos=e.getDot(); + if (WSManager.getWorkspaceConfig().isSyntaxHighlightingEnabled()) SwingUtilities.invokeLater(new verif_parenthese(pos)); +} + void chercheApres(String content,int pos,String ouv,String fer){ + boolean continuer=true; + int of_ouvrant; + int of_fermant=0; + int from_index_ouvrant=1; + int from_index_fermant=1; + while(continuer){ + of_ouvrant=content.indexOf(ouv,from_index_ouvrant); + while (of_ouvrant!=-1&&TesteBackslash(content,of_ouvrant)) of_ouvrant=content.indexOf(ouv,of_ouvrant+1); + of_fermant=content.indexOf(fer,from_index_fermant); + while (of_fermant!=-1&&TesteBackslash(content,of_fermant)) of_fermant=content.indexOf(fer,of_fermant+1); + if (of_fermant==-1) break; + if (of_ouvrant!=-1 && of_ouvrant<of_fermant) { + from_index_ouvrant=of_ouvrant+1; + from_index_fermant=of_fermant+1; + } + else continuer=false;; + } + if (of_fermant!=-1) { + dsd.Montre_Parenthese(of_fermant+pos); + position[1]=of_fermant+pos; + } + else position[1]=-1; + dsd.Montre_Parenthese(pos); + position[0]=pos; + } + void chercheAvant(String content,int pos,String ouv,String fer){ + boolean continuer=true; + int of_fermant=0; + int of_ouvrant=0; + int from_index_ouvrant=pos; + int from_index_fermant=pos; + while(continuer){ + of_ouvrant=content.lastIndexOf(ouv,from_index_ouvrant); + while (of_ouvrant!=-1&&TesteBackslash(content,of_ouvrant)) of_ouvrant=content.lastIndexOf(ouv,of_ouvrant-1); + of_fermant=content.lastIndexOf(fer,from_index_fermant); + while (of_fermant!=-1&&TesteBackslash(content,of_fermant)) of_fermant=content.lastIndexOf(fer,of_fermant-1); + if (of_ouvrant==-1) break; + if (of_ouvrant<of_fermant) { + from_index_ouvrant=of_ouvrant-1; + from_index_fermant=of_fermant-1; + } + else continuer=false;; + } + if (of_ouvrant!=-1) { + dsd.Montre_Parenthese(of_ouvrant); + position[0]=of_ouvrant; + } + else position[0]=-1; + dsd.Montre_Parenthese(pos); + position[1]=pos; + + + } + +}
\ No newline at end of file diff --git a/logo/src/xlogo/gui/components/ColorStyleSelectionPanel.java b/logo/src/xlogo/gui/components/ColorStyleSelectionPanel.java new file mode 100644 index 0000000..0e161a2 --- /dev/null +++ b/logo/src/xlogo/gui/components/ColorStyleSelectionPanel.java @@ -0,0 +1,232 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * a lot of modifications, extensions, refactorings have been applied by Marko Zivkovic + */ + +package xlogo.gui.components; + +import javax.swing.*; + +import java.awt.event.*; +import java.awt.*; +import java.util.ArrayList; + +import xlogo.kernel.DrawPanel; +import xlogo.Logo; + +/** + * Title : XLogo Description : XLogo is an interpreter for the Logo programming + * language + * + * @author Loïc Le Coq, Marko refactored + */ +public class ColorStyleSelectionPanel { + + private JPanel component = new JPanel(); + + public JPanel getComponent() + { + return component; + } + + private Integer[] intArray = new Integer[17]; + private JButton bchoisir = new JButton( + Logo.messages.getString("pref.highlight.other")); + private JComboBox combo_couleur; + private String[] msg = { + Logo.messages.getString("style.none"), + Logo.messages.getString("style.bold"), + Logo.messages.getString("style.italic"), + Logo.messages.getString("style.underline") }; + private JComboBox style = new JComboBox(msg); + private JLabel titre = new JLabel(); + private Color couleur_perso = Color.WHITE; + private GridBagLayout gb = new GridBagLayout(); + + public ColorStyleSelectionPanel(int rgb, int sty, String title) { + //WorkspaceConfig wc = WSManager.getWorkspaceConfig(); + //Font font = wc.getFont(); + + component.setLayout(gb); + + for (int i = 0; i < 17; i++) { + intArray[i] = new Integer(i); + } + // Create the combo box. + //titre.setFont(font); + titre.setText(title + ":"); + + combo_couleur = new JComboBox(intArray); + ComboBoxRenderer renderer = new ComboBoxRenderer(); + combo_couleur.setRenderer(renderer); + setColorAndStyle(rgb, sty); + combo_couleur.setActionCommand("combo"); + combo_couleur.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + notifyActionListeners(e); + } + }); + //bchoisir.setFont(font); + //style.setFont(font); + bchoisir.setActionCommand("bouton"); + bchoisir.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Color color = selectColor(); + if (null != color) { + couleur_perso = color; + combo_couleur.setSelectedIndex(7); + combo_couleur.repaint(); + } + notifyActionListeners(e); + } + }); + + style.setActionCommand("style"); + style.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + notifyActionListeners(e); + } + }); + //int hauteur = font.getSize() + 5; + // jt.setPreferredSize(new Dimension(240,hauteur)); + + // Lay out the demo. + component.add(combo_couleur, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 5, 5, 5), 0, 0)); + component.add(bchoisir, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(5, 5, 5, 5), 0, 0)); + component.add(style, new GridBagConstraints(2, 1, 1, 1, 1.0, 1.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 5, 5, 5), 0, 0)); + component.add(titre, new GridBagConstraints(0, 0, 3, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.VERTICAL, + new Insets(5, 5, 0, 5), 0, 0)); + + component.setBorder(BorderFactory.createLineBorder(Color.BLUE)); + //component.setPreferredSize(new Dimension(300, hauteur * 2 + 20)); + } + + public void setTitle(String title) + { + titre.setText(title); + } + + public void setColorAndStyle(int rgb, int sty) { + style.setSelectedIndex(sty); + int index = -1; + for (int i = 0; i < 17; i++) { + if (DrawPanel.defaultColors[i].getRGB() == rgb) { + index = i; + } + } + if (index == -1) { + couleur_perso = new Color(rgb); + index = 7; + } + combo_couleur.setSelectedIndex(index); + } + + private Color selectColor(){ + return JColorChooser.showDialog(component, "", + DrawPanel.defaultColors[combo_couleur.getSelectedIndex()]); + } + + private class ComboBoxRenderer extends JPanel implements ListCellRenderer { + private static final long serialVersionUID = 1L; + int id = 0; + + public ComboBoxRenderer() { + setOpaque(true); + setPreferredSize(new Dimension(50, 20)); + } + + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + // Get the selected index. (The index param isn't + // always valid, so just use the value.) + int selectedIndex = ((Integer) value).intValue(); + this.id = selectedIndex; + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + // Set the icon and text. If icon was null, say so. + + setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + return this; + } + + public void paint(Graphics g) { + super.paint(g); + if (id != 7) + g.setColor(DrawPanel.defaultColors[id]); + else + g.setColor(couleur_perso); + g.fillRect(5, 2, 40, 15); + } + } + + public int color() { + int id = combo_couleur.getSelectedIndex(); + if (id != 7) + return DrawPanel.defaultColors[id].getRGB(); + return couleur_perso.getRGB(); + } + + public int style() { + int id = style.getSelectedIndex(); + return id; + } + + public void setEnabled(boolean b) { + component.setEnabled(b); + combo_couleur.setEnabled(b); + style.setEnabled(b); + bchoisir.setEnabled(b); + } + + + private ArrayList<ActionListener> actionListeners = new ArrayList<ActionListener>(); + + public void addStyleChangeListener(ActionListener listener) + { + actionListeners.add(listener); + } + + private void notifyActionListeners(ActionEvent e) + { + for (ActionListener listener : actionListeners) + listener.actionPerformed(e); + } +} diff --git a/logo/src/xlogo/gui/components/ProcedureSearch.java b/logo/src/xlogo/gui/components/ProcedureSearch.java new file mode 100644 index 0000000..4c01acc --- /dev/null +++ b/logo/src/xlogo/gui/components/ProcedureSearch.java @@ -0,0 +1,309 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components;
+
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import xlogo.interfaces.ProcedureMapper;
+import xlogo.interfaces.ProcedureMapper.ProcedureMapListener;
+import xlogo.utils.Utils;
+
+public class ProcedureSearch extends JPanel
+{
+ private static final long serialVersionUID = 2275479142269992452L;
+
+ private ProcedureMapper procedureMapper = null;
+
+ private JComboBox procedureSelection = new JComboBox();
+ private JButton procedureSearchButton = new JButton();
+
+ public ProcedureSearch(ProcedureMapper procedureMapper)
+ {
+ this.procedureMapper = procedureMapper;
+ setExecutables(procedureMapper.getAllProcedureNames());
+ initComponents();
+ //applyColorTheme();
+ initListeners();
+ }
+
+ private void initListeners()
+ {
+ procedureMapper.addProcedureMapListener(new ProcedureMapListener(){
+
+ @Override
+ public void ownerRenamed(String oldName, String newName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ ownerRenamed(oldName, newName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void defined(String fileName, Collection<String> procedures)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ defined(fileName, procedures);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void defined(String fileName, String procedure)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ defined(fileName, procedure);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void undefined(String fileName, Collection<String> procedures)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ undefined(fileName, procedures);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void undefined(String fileName, String procedure)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ setExecutables(procedureMapper.getAllProcedureNames());
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ undefined(fileName, procedure);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ procedureSearchButton.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent arg0)
+ {
+ String selected = (String) procedureSelection.getSelectedItem();
+ if (selected == null || selected.length() == 0)
+ return;
+ notifySearchListeners(selected);
+ }
+ });
+
+ procedureSelection.getEditor().addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ String selected = (String) procedureSelection.getSelectedItem();
+ if (selected == null || selected.length() == 0)
+ return;
+ notifySearchListeners(selected);
+ }
+ });
+ }
+
+ private void setExecutables(Collection<String> procedures)
+ {
+ String[] sorted = new String[procedures.size()];
+ sorted = procedures.toArray(sorted);
+ Arrays.sort(sorted);
+
+ procedureSelection.setModel(new DefaultComboBoxModel(sorted));
+ }
+
+ private void initComponents()
+ {
+ procedureSelection.setEditable(true);
+
+ Image img = Toolkit.getDefaultToolkit().getImage(Utils.class.getResource("chercher.png"));
+ procedureSearchButton.setIcon(new ImageIcon(img.getScaledInstance(20, 20, Image.SCALE_SMOOTH)));
+
+ setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ add(procedureSelection, c);
+
+ c.gridx = 1;
+ c.weightx = 0;
+ add(procedureSearchButton, c);
+ }
+
+ public JComponent getComponent()
+ {
+ return this;
+ }
+
+ @Override
+ public void setFont(Font font)
+ {
+ super.setFont(font);
+ if (procedureSelection != null) // Apparently this became called before object construction...
+ procedureSelection.setFont(font);
+ }
+
+ /*
+ * PROCEDURE SEARCH REQUEST LISTENER
+ */
+
+ public interface ProcedureSearchRequestListener
+ {
+ public void requestProcedureSearch(String procedureName);
+ }
+
+ private ArrayList<ProcedureSearchRequestListener> searchListeners = new ArrayList<ProcedureSearchRequestListener>();
+
+ public void addSearchRequestListener(ProcedureSearchRequestListener listener)
+ {
+ searchListeners.add(listener);
+ }
+
+ public void removeSearchRequestListener(ProcedureSearchRequestListener listener)
+ {
+ searchListeners.remove(listener);
+ }
+
+ private void notifySearchListeners(String procedureName)
+ {
+ for (ProcedureSearchRequestListener listener : searchListeners)
+ listener.requestProcedureSearch(procedureName);
+ }
+}
diff --git a/logo/src/xlogo/gui/components/TurtleComboBox.java b/logo/src/xlogo/gui/components/TurtleComboBox.java new file mode 100644 index 0000000..952ed7e --- /dev/null +++ b/logo/src/xlogo/gui/components/TurtleComboBox.java @@ -0,0 +1,169 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were adapted by Marko Zivkovic
+ *
+ * The original authors:
+ *
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Oracle or the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package xlogo.gui.components;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+import xlogo.utils.Utils;
+
+public class TurtleComboBox extends JPanel
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6921667779684536164L;
+ ImageIcon[] images;
+ String[] petStrings = { "preview0", "preview1", "preview2", "preview3", "preview4", "preview5", "preview6" };
+
+ JComboBox petList;
+ /*
+ * Despite its use of EmptyBorder, this panel makes a fine content
+ * pane because the empty border just increases the panel's size
+ * and is "painted" on top of the panel's normal background. In
+ * other words, the JPanel fills its entire background if it's
+ * opaque (which it is by default); adding a border doesn't change
+ * that.
+ */
+ public TurtleComboBox()
+ {
+ super(new BorderLayout());
+
+ //Load the pet images and create an array of indexes.
+ images = new ImageIcon[petStrings.length];
+ Integer[] intArray = new Integer[petStrings.length];
+ for (int i = 0; i < petStrings.length; i++)
+ {
+ intArray[i] = new Integer(i);
+ images[i] = createImageIcon(petStrings[i] + ".png");
+ if (images[i] != null)
+ {
+ images[i].setDescription(petStrings[i]);
+ }
+ }
+
+ //Create the combo box.
+ petList = new JComboBox(intArray);
+ ComboBoxRenderer renderer = new ComboBoxRenderer();
+ renderer.setPreferredSize(new Dimension(50, 50));
+ petList.setRenderer(renderer);
+ petList.setMaximumRowCount(7);
+
+ //Lay out the demo.
+ add(petList, BorderLayout.PAGE_START);
+ setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ }
+
+ public JComboBox getComboBox()
+ {
+ return petList;
+ }
+
+ /** Returns an ImageIcon, or null if the path was invalid. */
+ protected static ImageIcon createImageIcon(String path)
+ {
+ try{
+ return new ImageIcon(Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(path)));
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ class ComboBoxRenderer extends JLabel implements ListCellRenderer
+ {
+
+ private static final long serialVersionUID = -2208613325470559104L;
+
+ public ComboBoxRenderer()
+ {
+ setOpaque(true);
+ setHorizontalAlignment(CENTER);
+ setVerticalAlignment(CENTER);
+ }
+
+ /*
+ * This method finds the image and text corresponding
+ * to the selected value and returns the label, set up
+ * to display the text and image.
+ */
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+ boolean cellHasFocus)
+ {
+ //Get the selected index. (The index param isn't
+ //always valid, so just use the value.)
+ int selectedIndex = ((Integer) value).intValue();
+
+ if (isSelected)
+ {
+ setBackground(list.getSelectionBackground());
+ setForeground(list.getSelectionForeground());
+ }
+ else
+ {
+ setBackground(list.getBackground());
+ setForeground(list.getForeground());
+ }
+
+ //Set the icon and text. If icon was null, say so.
+ ImageIcon icon = images[selectedIndex];
+ setIcon(icon);
+
+ return this;
+ }
+ }
+}
diff --git a/logo/src/xlogo/gui/components/X4SComponent.java b/logo/src/xlogo/gui/components/X4SComponent.java new file mode 100644 index 0000000..f28341d --- /dev/null +++ b/logo/src/xlogo/gui/components/X4SComponent.java @@ -0,0 +1,81 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components;
+
+import java.io.File;
+
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+
+/**
+ * Base Class for well structured GUI components.
+ * includes commonly used features for displaying popups and retrieving user input per dialogs.
+ * @author Marko
+ *
+ */
+public abstract class X4SComponent extends X4SGui{
+
+ public X4SComponent() {
+ super();
+ }
+
+ public abstract JComponent getComponent();
+
+ protected String getUserText(String message, String title)
+ {
+ return (String) JOptionPane.showInputDialog(
+ getComponent(),
+ message,
+ title,
+ JOptionPane.PLAIN_MESSAGE,
+ null,
+ null,
+ null);
+ }
+
+ protected boolean getUserYesOrNo(String message, String title)
+ {
+ int ans = JOptionPane.showConfirmDialog(getComponent(), message, title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+
+ return ans == JOptionPane.YES_OPTION;
+ }
+
+ protected File getUserSelectedDirectory()
+ {
+ final JFileChooser fc = new JFileChooser();
+ fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ int returnVal = fc.showOpenDialog(getComponent());
+
+ if(returnVal == JFileChooser.APPROVE_OPTION)
+ return fc.getSelectedFile();
+ else
+ return null;
+ }
+
+}
diff --git a/logo/src/xlogo/gui/components/X4SFrame.java b/logo/src/xlogo/gui/components/X4SFrame.java new file mode 100644 index 0000000..92296bb --- /dev/null +++ b/logo/src/xlogo/gui/components/X4SFrame.java @@ -0,0 +1,40 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components;
+
+import javax.swing.JFrame;
+
+public abstract class X4SFrame extends X4SGui{
+
+ public X4SFrame() {
+ super();
+ }
+
+ public abstract JFrame getFrame();
+
+}
diff --git a/logo/src/xlogo/gui/components/X4SGui.java b/logo/src/xlogo/gui/components/X4SGui.java new file mode 100644 index 0000000..c0dbc81 --- /dev/null +++ b/logo/src/xlogo/gui/components/X4SGui.java @@ -0,0 +1,112 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import xlogo.AppSettings;
+
+/**
+ * Automatically calls all convenience features in the following order:
+ * <li> initComponent() </li>
+ * <li> layoutComponent() </li>
+ * <li> setText() </li>
+ * <li> initEventListeners() </li>
+ * <li> startListernForLanguageChangeEvents() </li>
+ * <p> Additionally, setText is called when language is changed by the user.
+ * If you do not need to update the language, just {@link X4SGui#stopListenForLanguageChangeEvents()}
+ * @since June 10th 2014
+ * @author Marko
+ */
+public abstract class X4SGui {
+
+ public X4SGui() {
+ initComponent();
+ layoutComponent();
+ setText();
+ initEventListeners();
+ startListenForLanguageChangeEvents();
+ }
+ /**
+ * Subclassses should make sure the component is completely initialized and ready to be used.
+ * Called before setText() and layotComponent()
+ */
+ protected abstract void initComponent();
+
+ protected abstract void layoutComponent();
+
+ protected abstract void initEventListeners();
+
+ public void stopEventListeners()
+ {
+ stopListenForLanguageChangeEvents();
+ }
+
+ private ActionListener languageChangeListener;
+
+ /**
+ * Note: registers only once, even if called more than once.
+ */
+ public void startListenForLanguageChangeEvents()
+ {
+ if (languageChangeListener != null)
+ return;
+ languageChangeListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ setText();
+ }
+ };
+ AppSettings.getInstance().addLanguageChangeListener(languageChangeListener);
+ }
+
+ public void stopListenForLanguageChangeEvents()
+ {
+ if (languageChangeListener == null)
+ return;
+ AppSettings.getInstance().removeLanguageChangeListener(languageChangeListener);
+ languageChangeListener = null;
+ }
+
+ /**
+ * Called whenever language is changed or the component is initialized.
+ */
+ protected void setText() { }
+
+ /**
+ * Shortcut to LanguageManager.getInstance().translate(key)
+ * @param key
+ * @return
+ */
+ protected String translate(String key)
+ {
+ return AppSettings.getInstance().translate(key);
+ }
+
+}
diff --git a/logo/src/xlogo/gui/components/fileslist/11_alerts_and_states_error.png b/logo/src/xlogo/gui/components/fileslist/11_alerts_and_states_error.png Binary files differnew file mode 100644 index 0000000..097c3bc --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/11_alerts_and_states_error.png diff --git a/logo/src/xlogo/gui/components/fileslist/1_navigation_accept.png b/logo/src/xlogo/gui/components/fileslist/1_navigation_accept.png Binary files differnew file mode 100644 index 0000000..cf5fab3 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/1_navigation_accept.png diff --git a/logo/src/xlogo/gui/components/fileslist/5_content_discard.png b/logo/src/xlogo/gui/components/fileslist/5_content_discard.png Binary files differnew file mode 100644 index 0000000..cedb108 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/5_content_discard.png diff --git a/logo/src/xlogo/gui/components/fileslist/5_content_edit.png b/logo/src/xlogo/gui/components/fileslist/5_content_edit.png Binary files differnew file mode 100644 index 0000000..f09b2e4 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/5_content_edit.png diff --git a/logo/src/xlogo/gui/components/fileslist/5_content_remove.png b/logo/src/xlogo/gui/components/fileslist/5_content_remove.png Binary files differnew file mode 100644 index 0000000..9f4c3d6 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/5_content_remove.png diff --git a/logo/src/xlogo/gui/components/fileslist/FilesList.java b/logo/src/xlogo/gui/components/fileslist/FilesList.java new file mode 100644 index 0000000..eaef2b9 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/FilesList.java @@ -0,0 +1,665 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components.fileslist;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+import xlogo.Logo;
+import xlogo.interfaces.BasicFileContainer;
+import xlogo.interfaces.BasicFileContainer.FileContainerChangeListener;
+import xlogo.interfaces.BroadcasterErrorFileContainer;
+import xlogo.interfaces.ErrorDetector.FileErrorCollector.ErrorListener;
+import xlogo.interfaces.MessageBroadcaster.MessageListener;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.gui.components.fileslist.IFilesListItem.ItemRequestHandler;
+
+public class FilesList extends JPanel
+{
+ private static final long serialVersionUID = -3330227288228959914L;
+
+ BroadcasterErrorFileContainer model;
+ FileContainerChangeListener fileContainerModelListener;
+ ErrorListener errorListener;
+ MessageListener messageListener;
+
+ // Handlers
+ private ActionListener addFileRequestHandler;
+ private ItemRequestHandler fileItemRequestHandler;
+
+ // GUI Components
+ /**
+ * The class of file items to use
+ */
+ private Class<? extends IFilesListItem> listItemClass = FilesListItem.class;
+
+ //private JScrollPane scroller;
+ private JButton addFileButton;
+ private Map<String, IFilesListItem> listItems = new HashMap<String, IFilesListItem>();
+
+ private boolean editEnabled = true;
+
+ /*
+ * Init & Model
+ */
+
+ public FilesList(BroadcasterErrorFileContainer fileContainerModel)
+ {
+
+ initComponents();
+ initFileItemListeners();
+ initErrorListener();
+ initFileContainerListener();
+ intitMessageListener();
+ setModel(fileContainerModel);
+ addFileButton.addActionListener(addFileRequestHandler);
+ }
+
+ private void intitMessageListener()
+ {
+ messageListener = new MessageListener(){
+
+ @Override
+ public void messageEvent(final String fileName, final String message)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onMessageEvent(fileName, message);
+ return;
+ }
+
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onMessageEvent(fileName, message);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ messageEvent(fileName, message);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onMessageEvent(String fileName, String message)
+ {
+ IFilesListItem item = listItems.get(fileName);
+ if (item == null)
+ return;
+
+ item.setMessage(message);
+ }
+ };
+ }
+
+ private void initComponents()
+ {
+ this.setOpaque(false);
+
+ Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource("new_content.png"));
+ addFileButton = new JButton(new ImageIcon(img.getScaledInstance(20, 20, Image.SCALE_SMOOTH)));
+ addFileButton.setOpaque(true);
+
+ setLayout(new GridBagLayout());
+ }
+
+ GridBagConstraints getLayoutConstraints()
+ {
+ GridBagConstraints c = new GridBagConstraints();
+
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.NORTHWEST;
+ c.gridx = 0;
+ c.gridy = GridBagConstraints.RELATIVE;
+ c.weightx = 1;
+ return c;
+ }
+
+ private void initFileContainerListener()
+ {
+ fileContainerModelListener = new FileContainerChangeListener(){
+
+ @Override
+ public void fileAdded(final String fileName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onFileAdded(fileName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onFileAdded(fileName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ fileAdded(fileName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onFileAdded(String fileName)
+ {
+ // On initialization, the files list is fetched using set model
+ // and the events are received, causing a duplication of items in the list.
+ if (listItems.containsKey(fileName))
+ return;
+
+ IFilesListItem item = null;
+ try
+ {
+ item = listItemClass.newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ e.printStackTrace();
+ return;
+ }
+ catch (IllegalAccessException e)
+ {
+ e.printStackTrace();
+ return;
+ }
+ item.setRequestHandler(fileItemRequestHandler);
+ item.setFileName(fileName);
+ item.setEditEnabled(model.isFilesListEditable());
+ item.setError(model.hasErrors(fileName));
+ GridBagConstraints c = getLayoutConstraints();
+ add(item.getComponent(), c);
+ listItems.put(fileName, item);
+ revalidate();
+ }
+
+ @Override
+ public void fileRemoved(final String fileName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onFileRemoved(fileName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onFileRemoved(fileName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ fileRemoved(fileName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onFileRemoved(String fileName)
+ {
+ IFilesListItem item = listItems.get(fileName);
+ remove(item.getComponent());
+ listItems.remove(fileName);
+ revalidate();
+ validate();
+ }
+
+ @Override
+ public void fileRenamed(final String oldName, final String newName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onFileRenamed(oldName, newName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onFileRenamed(oldName, newName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ fileRenamed(oldName, newName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onFileRenamed(String oldName, String newName)
+ {
+ IFilesListItem item = listItems.get(oldName);
+ item.setFileName(newName);
+ item.setSelected(true);
+ listItems.remove(oldName);
+ listItems.put(newName, item);
+ item.getComponent().revalidate();
+ }
+
+ /**
+ * This implementation allows multiple files open, if the model decides so.
+ * The Model is responsible to close a specific file before opening another.
+ */
+ @Override
+ public void fileOpened(final String fileName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onFileOpened(fileName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onFileOpened(fileName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ fileOpened(fileName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onFileOpened(String fileName)
+ {
+ IFilesListItem item = listItems.get(fileName);
+ item.setSelected(true);
+ revalidate();
+ }
+
+ @Override
+ public void fileClosed(final String fileName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onFileClosed(fileName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onFileClosed(fileName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ fileClosed(fileName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onFileClosed(String fileName)
+ {
+ IFilesListItem item = listItems.get(fileName);
+ item.setSelected(false);
+ item.getComponent().revalidate();
+ }
+
+ @Override
+ public void editRightsChanged(final boolean enabled)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onEditRightsChanged(enabled);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onEditRightsChanged(enabled);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ editRightsChanged(enabled);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onEditRightsChanged(boolean enabled)
+ {
+ editEnabled = enabled;
+ if (addFileButton != null)
+ addFileButton.setVisible(editEnabled);
+ for (IFilesListItem item : listItems.values())
+ {
+ item.setEditEnabled(editEnabled);
+ }
+ revalidate();
+ }
+
+ };
+ }
+
+ private void initErrorListener()
+ {
+ errorListener = new ErrorListener(){
+
+ @Override
+ public void errorsDetected(final String fileName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onErrorsDetected(fileName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onErrorsDetected(fileName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ errorsDetected(fileName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onErrorsDetected(String fileName)
+ {
+ IFilesListItem item = listItems.get(fileName);
+ if (item == null)
+ return;
+ item.setError(true);
+ item.getComponent().revalidate();
+ }
+
+ @Override
+ public void allErrorsCorrected(final String fileName)
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ onAllErrorsCorrected(fileName);
+ return;
+ }
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ onAllErrorsCorrected(fileName);
+ }
+ });
+ }
+ catch (InterruptedException e)
+ {
+ allErrorsCorrected(fileName);
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void onAllErrorsCorrected(String fileName)
+ {
+ IFilesListItem item = listItems.get(fileName);
+ item.setError(false);
+ item.getComponent().revalidate();
+ }
+ };
+ }
+
+ public void setModel(BroadcasterErrorFileContainer fileContainerModel)
+ {
+ if (this.model != null)
+ {
+ this.model.removeFileListener(fileContainerModelListener);
+ this.model.removeErrorListener(errorListener);
+ this.model.removeBroadcastListener(messageListener);
+ }
+
+ this.model = fileContainerModel;
+
+ if (this.model != null)
+ {
+ this.model.addFileListener(fileContainerModelListener);
+ this.model.addErrorListener(errorListener);
+ this.model.addBroadcastListener(messageListener);
+ }
+
+ initItemsList();
+ }
+
+ /**
+ * Empties the filesList and listItems and then refills them according to the model
+ */
+ private void initItemsList()
+ {
+ listItems.clear();
+ //filesList.removeAll();
+ removeAll();
+ if (model == null)
+ return;
+
+ GridBagConstraints c = getLayoutConstraints();
+
+ c.anchor = GridBagConstraints.NORTHWEST;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridy = 0;
+ c.weighty = 0;
+ c.weightx = 1;
+ add(addFileButton, c);
+ addFileButton.setVisible(editEnabled);
+
+ for (String fileName : model.getFileNames())
+ fileContainerModelListener.fileAdded(fileName);
+ revalidate();
+ }
+
+ public JComponent getComponent()
+ {
+ return this;
+ }
+
+ public BasicFileContainer getModel()
+ {
+ return model;
+ }
+
+ /*
+ * GETTERS & SETTERS
+ */
+
+ public JScrollPane getScrollPane()
+ {
+ return null;
+ }
+
+ public JButton getAddFileButton()
+ {
+ return addFileButton;
+ }
+
+ protected Map<String, IFilesListItem> getListItems()
+ {
+ return listItems;
+ }
+
+ /**
+ * @param newButton if null, no add button is shown. If this effect is only temporarily wished, use {@link #setEditFilesListEnabled(boolean)}
+ */
+ public void setAddFileButton(JButton newButton)
+ {
+ if (addFileButton != null)
+ {
+ addFileButton.removeActionListener(addFileRequestHandler);
+ //filesList.remove(addFileButton);
+ remove(addFileButton);
+ }
+ if (newButton != null)
+ {
+ newButton.addActionListener(addFileRequestHandler);
+ newButton.setVisible(model.isFilesListEditable());
+ add(newButton);
+ }
+ addFileButton = newButton;
+ revalidate();
+ }
+
+ public void setListItemClass(Class<? extends IFilesListItem> itemClass) throws InstantiationException,
+ IllegalAccessException
+ {
+ if (itemClass == null)
+ throw new IllegalArgumentException("List item class must not be null.");
+
+ this.listItemClass = itemClass;
+
+ initItemsList();
+ }
+
+ // ITEM LISTENERS
+
+ private void initFileItemListeners()
+ {
+ fileItemRequestHandler = new ItemRequestHandler(){
+ @Override
+ public void renameRequest(String oldName, String newName)
+ {
+ model.renameFile(oldName, newName);
+ }
+
+ @Override
+ public void deleteRequest(String fileName)
+ {
+ model.closeFile(fileName);
+ model.removeFile(fileName);
+ }
+
+ @Override
+ public void openRequest(String fileName)
+ {
+ model.openFile(fileName);
+ }
+
+ @Override
+ public void closeRequest(String fileName)
+ {
+ model.closeFile(fileName);
+ }
+ };
+
+ addFileRequestHandler = new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent event)
+ {
+ String name = model.makeUniqueFileName(Logo.messages.getString("new.file")); // TODO remove dependency
+ try
+ {
+ model.createFile(name);
+ }
+ catch (Exception e)
+ {
+ DialogMessenger.getInstance().dispatchError(Logo.messages.getString("ws.error.title"), // TODO remove dependency
+ Logo.messages.getString("ws.error.could.not.create.logo.file") + "\n" + e.toString());
+ }
+ }
+ };
+ }
+
+}
diff --git a/logo/src/xlogo/gui/components/fileslist/FilesListItem.java b/logo/src/xlogo/gui/components/fileslist/FilesListItem.java new file mode 100644 index 0000000..33c3934 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/FilesListItem.java @@ -0,0 +1,542 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components.fileslist;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.UIManager;
+
+/**
+ * This list item was programmed to provide general methods for a files list.
+ *
+ * However, the component styles could try to follow the current look and feel.
+ * At the moment, style and colors are hard-coded.
+ *
+ * @author Marko Zivkovic
+ */
+public class FilesListItem extends JPanel implements IFilesListItem
+{
+ private static final long serialVersionUID = 3061129268414679076L;
+
+ /*
+ * These are just estimations that are used for getMinimumSize
+ */
+ //private static int MINIMUM_BUTTON_SIZE = 15; // This scales the button icons
+
+ /*
+ * Item State and properties
+ */
+
+ private boolean isEditEnabled = true;
+
+ /**
+ * This is intentionally not included in the State enum (it would double the amount of states),
+ * because it affects only one property
+ */
+ private State state = State.UNSELECTED;
+
+ /**
+ * This enum denotes the different states that FilesListItem can have.
+ * It further provides all necessary state transitions and the state-dependent sizes.
+ * <p>
+ * Note that only properties are modeled here that affect more than one component's properties,
+ * or properties that depend on more than one variable.
+ * @author Marko
+ *
+ */
+ private enum State
+ {
+ UNSELECTED, SELECTED, EDITING,
+ // E prefix <=> File has error
+ E_UNSELECTED, E_SELECTED, E_EDITING;
+
+ /*
+ * State transitions
+ */
+
+ public State selected()
+ {
+ switch(this)
+ {
+ case E_EDITING:
+ case E_SELECTED:
+ case E_UNSELECTED:
+ return State.E_SELECTED;
+ default:
+ return State.SELECTED;
+ }
+ }
+
+ public State unselected()
+ {
+ switch(this)
+ {
+ case E_EDITING:
+ case E_SELECTED:
+ case E_UNSELECTED:
+ return State.E_UNSELECTED;
+ default:
+ return State.UNSELECTED;
+ }
+ }
+
+ public State editing()
+ {
+ switch(this)
+ {
+ case E_EDITING:
+ case E_SELECTED:
+ case E_UNSELECTED:
+ return State.E_EDITING;
+ default:
+ return State.EDITING;
+ }
+ }
+
+ public State withError()
+ {
+ switch(this)
+ {
+ case EDITING:
+ case E_EDITING:
+ return State.E_EDITING;
+ case SELECTED:
+ case E_SELECTED:
+ return State.E_SELECTED;
+ default:
+ return State.E_UNSELECTED;
+ }
+ }
+
+ public State withoutError()
+ {
+ switch(this)
+ {
+ case EDITING:
+ case E_EDITING:
+ return State.EDITING;
+ case SELECTED:
+ case E_SELECTED:
+ return State.SELECTED;
+ default:
+ return State.UNSELECTED;
+ }
+ }
+
+ /*
+ * State dependent component properties
+ */
+
+ public Color getBackgroundColor()
+ {
+ switch(this)
+ {
+ case E_SELECTED:
+ case E_EDITING:
+ return new Color(0xFF6666);
+ case E_UNSELECTED:
+ return new Color(0xFFCCCC);
+ case SELECTED:
+ case EDITING:
+ return new Color(0xDBEBFF);
+ case UNSELECTED:
+ default:
+ return new Color(0xA8CFFF);
+
+ }
+ }
+
+ public Color getBorderColor()
+ {
+ switch(this)
+ {
+ case E_SELECTED:
+ case E_EDITING:
+ return new Color(0xFF4242);
+ case E_UNSELECTED:
+ return new Color(0xFFE0E0);
+ case UNSELECTED:
+ return new Color(0x5BA4FE);
+ default:
+ return new Color(0xEAF4FF);
+
+ }
+ }
+
+ public int getBorderThickness()
+ {
+ switch(this)
+ {
+ case UNSELECTED:
+ case E_UNSELECTED:
+ return 1;
+ default:
+ return 2;
+ }
+ }
+
+ public boolean isSelected()
+ {
+ switch(this)
+ {
+ case E_SELECTED:
+ case SELECTED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isEditing()
+ {
+ switch(this)
+ {
+ case E_EDITING:
+ case EDITING:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean hasError()
+ {
+ switch(this)
+ {
+ case E_UNSELECTED:
+ case E_SELECTED:
+ case E_EDITING:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ }
+
+ /*
+ * Request handler
+ *
+ * Note : this component does not change its state alone.
+ * It only asks the handler to handle some user requests.
+ * It is up to the handler to change the state of this component, based on the result of the request.
+ */
+
+ ItemRequestHandler handler;
+
+ /*
+ * Components
+ */
+
+ private JButton openButton = new JButton();
+ private JButton closeButton = new JButton();
+ private JButton editButton = new JButton();
+ private JButton removeButton = new JButton();
+ private JButton confirmButton = new JButton();
+ private JLabel errorIcon = new JLabel();
+ private JTextField textField = new JTextField();
+ private JLabel messageLabel = new JLabel();
+
+ /*
+ * Constructor & Layout
+ */
+
+ public FilesListItem()
+ {
+
+ closeButton.setIcon(createImageIcon("close_icon2.png", 20, 20));
+ editButton.setIcon(createImageIcon("5_content_edit.png", 20, 20));
+ removeButton.setIcon(createImageIcon("5_content_discard.png", 20, 20));
+ confirmButton.setIcon(createImageIcon("1_navigation_accept.png", 20, 20));
+ errorIcon.setIcon(createImageIcon("11_alerts_and_states_error.png", 20, 20));
+
+ initComponents();
+ initLayout();
+ validate();
+ initComponentListener();
+ }
+
+ public FilesListItem(String fileName, ItemRequestHandler handler)
+ {
+ setFileName(fileName);
+ setRequestHandler(handler);
+ initComponents();
+ initLayout();
+ validate();
+ initComponentListener();
+ }
+
+ private void initLayout()
+ {
+ try
+ {
+ // Apparently, these properties were not set automatically
+ Font font = (Font) UIManager.get("defaultFont");
+ openButton.setFont(font);
+ closeButton.setFont(font);
+ messageLabel.setFont(font);
+ textField.setFont(font);
+ }catch(ClassCastException ignore) {}
+
+ this.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30));
+ this.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+
+ c.fill = GridBagConstraints.BOTH;
+ c.gridx = 0;
+ add(errorIcon, c);
+ add(removeButton, c);
+
+ c.weightx=1; // This is the only one which should extend
+ c.gridx = 1;
+ add(openButton, c);
+ add(closeButton, c);
+ add(textField, c);
+
+ c.weightx=0;
+ c.gridx = 2;
+ add(messageLabel, c);
+
+ c.gridx = 3;
+ add(editButton, c);
+ add(confirmButton, c);
+ }
+
+ private void initComponents()
+ {
+ // The background of this JPanel will be visible below.
+ // => state dependent background color must only be set once
+ openButton.setOpaque(false);
+ closeButton.setOpaque(false);
+ editButton.setOpaque(false);
+ removeButton.setOpaque(false);
+ confirmButton.setOpaque(false);
+ errorIcon.setOpaque(false);
+ messageLabel.setOpaque(false);
+ }
+
+ private void initComponentListener()
+ {
+ openButton.addActionListener(new ActionListener(){
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (handler != null)
+ handler.openRequest(openButton.getText());
+ }
+ });
+
+ closeButton.addActionListener(new ActionListener(){
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (handler != null)
+ handler.closeRequest(openButton.getText());
+ }
+ });
+
+ editButton.addActionListener(new ActionListener(){
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ state = state.editing();
+ validate();
+ }
+ });
+
+ removeButton.addActionListener(new ActionListener(){
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (handler != null)
+ handler.deleteRequest(openButton.getText());
+ }
+ });
+
+ confirmButton.addActionListener(new ActionListener(){
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ String oldName = openButton.getText();
+ String newName = textField.getText();
+
+ if (handler != null && !oldName.equals(newName))
+ handler.renameRequest(oldName, newName);
+ else
+ {
+ state = state.selected();
+ validate();
+ }
+ }
+ });
+
+ textField.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ String oldName = openButton.getText();
+ String newName = textField.getText();
+
+ if (handler != null && !oldName.equals(newName))
+ handler.renameRequest(oldName, newName);
+ else
+ {
+ state = state.selected();
+ validate();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void validate()
+ {
+ super.validate();
+ // First the properties of components are set before super.validate()
+ // Otherwise the changes are not validated, are they?
+ boolean isSelected = state.isSelected();
+ boolean isEditing = state.isEditing();
+ boolean hasError = state.hasError();
+
+ openButton.setVisible(!isSelected && !isEditing);
+ closeButton.setVisible(isSelected);
+ editButton.setVisible(isSelected && isEditEnabled);
+
+ confirmButton.setVisible(isEditing);
+ textField.setVisible(isEditing);
+ removeButton.setVisible(isEditing);
+
+ errorIcon.setVisible(hasError && !isEditing);
+
+ Color backgroundColor = state.getBackgroundColor();
+ setBackground(backgroundColor);
+
+ this.setBorder(BorderFactory.createLineBorder(state.getBorderColor(), state.getBorderThickness()) );
+
+ }
+
+ /*
+ * IFilesListItem
+ */
+
+ @Override
+ public JComponent getComponent()
+ {
+ return this;
+ }
+
+ @Override
+ public void setRequestHandler(ItemRequestHandler handler)
+ {
+ this.handler = handler;
+ validate();
+ }
+
+ @Override
+ public void setFileName(String fileName)
+ {
+ this.openButton.setText(fileName);
+ this.closeButton.setText(fileName);
+ this.textField.setText(fileName);
+ validate();
+ }
+
+ @Override
+ public void setSelected(boolean isSelected)
+ {
+ state = isSelected ? state.selected() : state.unselected();
+ invalidate();
+ validate();
+ }
+
+
+ @Override
+ public void setEditing(boolean isEditing)
+ {
+ state = isEditing ? state.editing() : state.selected();
+ validate();
+ }
+
+ /**
+ * This is used to display the clock per file item in XLogo4Schools
+ * Generally, this can be any message.
+ * @param msg : if null, the message will be hidden, otherwise it is displayed
+ */
+ @Override
+ public void setMessage(String msg)
+ {
+ messageLabel.setVisible(msg != null);
+ messageLabel.setText(msg);
+ validate();
+ }
+
+
+ public String getMessage()
+ {
+ return messageLabel.getText();
+ }
+
+
+ @Override
+ public void setError(boolean hasError)
+ {
+ state = hasError ? state.withError() : state.withoutError();
+ validate();
+ }
+
+
+ public void setEditEnabled(boolean enabled)
+ {
+ isEditEnabled = enabled;
+ validate();
+ }
+
+ /*
+ * Helper
+ */
+ private ImageIcon createImageIcon(String path, int width, int heigth) {
+ Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(path));
+ return new ImageIcon(img.getScaledInstance(width, heigth, Image.SCALE_SMOOTH));
+ }
+}
diff --git a/logo/src/xlogo/gui/components/fileslist/IFilesListItem.java b/logo/src/xlogo/gui/components/fileslist/IFilesListItem.java new file mode 100644 index 0000000..684ec96 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/IFilesListItem.java @@ -0,0 +1,60 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.components.fileslist;
+
+import javax.swing.JComponent;
+
+public interface IFilesListItem
+{
+ public JComponent getComponent();
+
+ public void setSelected(boolean isSelected);
+
+ public void setEditing(boolean isSelected);
+
+ public void setMessage(String msg);
+
+ public void setError(boolean hasError);
+
+ public void setFileName(String string);
+
+ public void setRequestHandler(ItemRequestHandler handler);
+
+ public void setEditEnabled(boolean enabled);
+
+ public interface ItemRequestHandler
+ {
+ public void openRequest(String fileName);
+
+ public void closeRequest(String fileName);
+
+ public void renameRequest(String oldName, String newName);
+
+ public void deleteRequest(String fileName);
+ }
+}
diff --git a/logo/src/xlogo/gui/components/fileslist/close_icon2.png b/logo/src/xlogo/gui/components/fileslist/close_icon2.png Binary files differnew file mode 100644 index 0000000..8892697 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/close_icon2.png diff --git a/logo/src/xlogo/gui/components/fileslist/new_content.png b/logo/src/xlogo/gui/components/fileslist/new_content.png Binary files differnew file mode 100644 index 0000000..884c9d2 --- /dev/null +++ b/logo/src/xlogo/gui/components/fileslist/new_content.png diff --git a/logo/src/xlogo/gui/preferences/AbstractPanelColor.java b/logo/src/xlogo/gui/preferences/AbstractPanelColor.java new file mode 100644 index 0000000..e580526 --- /dev/null +++ b/logo/src/xlogo/gui/preferences/AbstractPanelColor.java @@ -0,0 +1,143 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.gui.preferences; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JComboBox; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +import xlogo.Logo; +import xlogo.kernel.DrawPanel; +import xlogo.storage.WSManager; + +public abstract class AbstractPanelColor extends JPanel implements ActionListener{ + private static final long serialVersionUID = 1L; +// private ImageIcon[] images=new ImageIcon[17]; + private Integer[] intArray=new Integer[17]; + private JButton bchoisir=new JButton(Logo.messages.getString("pref.highlight.other")); + protected JComboBox combo_couleur; + private Color couleur_perso=Color.WHITE; + public AbstractPanelColor(Color c) { + setBackground(Color.blue); + for(int i=0;i<17;i++){ + intArray[i]=new Integer(i); + } + combo_couleur = new JComboBox(intArray); + ComboBoxRenderer renderer= new ComboBoxRenderer(); + combo_couleur.setRenderer(renderer); + setColorAndStyle(c); + combo_couleur.setActionCommand("combo"); + combo_couleur.addActionListener(this); + bchoisir.setFont(WSManager.getWorkspaceConfig().getFont()); + bchoisir.setActionCommand("bouton"); + bchoisir.addActionListener(this); + add(combo_couleur); + add(bchoisir); + } + public void setEnabled(boolean b){ + super.setEnabled(b); + combo_couleur.setEnabled(b); + bchoisir.setEnabled(b); + + } + void setColorAndStyle(Color rgb){ + int index=-1; + for(int i=0;i<17;i++){ + if (DrawPanel.defaultColors[i].equals(rgb)){ + index=i; + } + } + if (index==-1){couleur_perso=rgb;index=7;} + combo_couleur.setSelectedIndex(index); + } + abstract public void actionPerformed(ActionEvent e); + + private class ComboBoxRenderer extends JPanel + implements ListCellRenderer { + private static final long serialVersionUID = 1L; + int id=0; + public ComboBoxRenderer() { + setOpaque(true); + setPreferredSize(new Dimension(50,20)); + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { +//Get the selected index. (The index param isn't +//always valid, so just use the value.) + int selectedIndex = ((Integer)value).intValue(); + this.id=selectedIndex; + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + //Set the icon and text. If icon was null, say so. + + setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); + return this; + } + public void paint(Graphics g){ + super.paint(g); + if (id!=7) g.setColor(DrawPanel.defaultColors[id]); + else g.setColor(couleur_perso); + g.fillRect(5,2,40,15); + } + } + public Color getValue(){ + int id=combo_couleur.getSelectedIndex(); + if (id!=7) return DrawPanel.defaultColors[id]; + return couleur_perso; + } + protected void actionButton(){ + Color color=JColorChooser.showDialog(this,"",DrawPanel.defaultColors[combo_couleur.getSelectedIndex()]); + if (null!=color){ + couleur_perso=color; + combo_couleur.setSelectedIndex(7); + combo_couleur.repaint(); + } + } +} diff --git a/logo/src/xlogo/gui/preferences/PanelColor.java b/logo/src/xlogo/gui/preferences/PanelColor.java new file mode 100644 index 0000000..2fbfe18 --- /dev/null +++ b/logo/src/xlogo/gui/preferences/PanelColor.java @@ -0,0 +1,45 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq + */ + +package xlogo.gui.preferences; + +import java.awt.Color; +import java.awt.event.ActionEvent; + +public class PanelColor extends AbstractPanelColor{ + + private static final long serialVersionUID = 1L; + public PanelColor(Color c){ + super(c); + } + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (cmd.equals("bouton")){ + actionButton(); + } + } +} diff --git a/logo/src/xlogo/gui/translation/BottomPanel.java b/logo/src/xlogo/gui/translation/BottomPanel.java new file mode 100644 index 0000000..bcd98e3 --- /dev/null +++ b/logo/src/xlogo/gui/translation/BottomPanel.java @@ -0,0 +1,89 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings migh have been applied by Marko Zivkovic + */ + +package xlogo.gui.translation; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import java.awt.BorderLayout; +import xlogo.Logo; +import xlogo.utils.Utils; +public class BottomPanel extends JPanel { + private static final long serialVersionUID = 1L; + private TranslateXLogo tx; + private JTabbedPane jt; + private MyTable messageTable; + private MyTable primTable; + private String id; + private String action; + private JButton searchButton; + private ImageIcon ichercher=Utils.dimensionne_image("chercher.png",this); + + protected BottomPanel(TranslateXLogo tx,String action, String id){ + this.tx=tx; + this.action=action; + this.id=id; + initGui(); + } + private void initGui(){ + setLayout(new BorderLayout()); + jt= new JTabbedPane(); + messageTable=new MyTable(tx,action,id,"langage"); + primTable=new MyTable(tx,action,id,"primitives"); + jt.add(primTable,Logo.messages.getString("primitives")); + jt.add(messageTable,Logo.messages.getString("messages")); + javax.swing.JScrollPane scroll=new javax.swing.JScrollPane(jt); + + add(scroll,BorderLayout.CENTER); + searchButton=new JButton(ichercher); + searchButton.setToolTipText(Logo.messages.getString("find")); + searchButton.addActionListener(tx); + searchButton.setActionCommand(TranslateXLogo.SEARCH); + searchButton.setSize(new java.awt.Dimension(100,50)); + add(searchButton,BorderLayout.EAST); + } + protected String getPrimValue(int a, int b){ + return primTable.getValue(a, b); + } + protected String getMessageValue(int a, int b){ + String st=messageTable.getValue(a, b); + return st; + } + protected MyTable getMessageTable(){ + return this.messageTable; + } + protected MyTable getPrimTable(){ + return this.primTable; + } + protected MyTable getVisibleTable(){ + if (jt.getSelectedIndex()==0) return primTable; + return messageTable; + } +} diff --git a/logo/src/xlogo/gui/translation/FirstPanel.java b/logo/src/xlogo/gui/translation/FirstPanel.java new file mode 100644 index 0000000..1fc0309 --- /dev/null +++ b/logo/src/xlogo/gui/translation/FirstPanel.java @@ -0,0 +1,237 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings migh have been applied by Marko Zivkovic + */ + +package xlogo.gui.translation; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ButtonGroup; +import javax.swing.JRadioButton; +import javax.swing.JButton; +import javax.swing.ListCellRenderer; +import javax.swing.JComboBox; + +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Insets; +import java.awt.MediaTracker; +import java.awt.Toolkit; + +import xlogo.Logo; +import xlogo.storage.WSManager; +import xlogo.utils.Utils; + +import java.awt.event.*; +public class FirstPanel extends JPanel implements ActionListener{ + private static final long serialVersionUID = 1L; + private Integer[] intArray; + + + private JRadioButton consultButton; + private JRadioButton modifyButton; + private JRadioButton completeButton; + private JRadioButton createButton; + private JButton validButton; + private ButtonGroup group=new ButtonGroup(); + private JLabel label; + private JComboBox comboLangModify; + private JComboBox comboLangComplete; +// private JTextField textLang; + private TranslateXLogo tx; + protected FirstPanel(TranslateXLogo tx){ + this.tx=tx; + int n=Logo.translationLanguage.length; + intArray=new Integer[n]; + for(int i=0;i<n;i++){ + intArray[i]=new Integer(i); + } + initGui(); + } + protected String getAction(){ + if (modifyButton.isSelected()) return TranslateXLogo.MODIFY; + else if (completeButton.isSelected()) return TranslateXLogo.COMPLETE; + else if (consultButton.isSelected()) return TranslateXLogo.CONSULT; + else if (createButton.isSelected()) return TranslateXLogo.CREATE; + return null; + } + protected String getLang(){ + if (modifyButton.isSelected()) return String.valueOf(comboLangModify.getSelectedIndex()); + return String.valueOf(comboLangComplete.getSelectedIndex()); + } +/* protected String getNewLang(){ + return textLang.getText(); + }*/ + private void initGui(){ + + setLayout(new GridBagLayout()); + + // textLang=new JTextField(); + label=new JLabel(Logo.messages.getString("translatewant")); + createButton=new JRadioButton(Logo.messages.getString("translatecreate")); + modifyButton=new JRadioButton(Logo.messages.getString("translatemodify")); + completeButton=new JRadioButton(Logo.messages.getString("translatecomplete")); + consultButton=new JRadioButton(Logo.messages.getString("translateconsult")); + createButton.setActionCommand(TranslateXLogo.CREATE); + modifyButton.setActionCommand(TranslateXLogo.MODIFY); + consultButton.setActionCommand(TranslateXLogo.CONSULT); + completeButton.setActionCommand(TranslateXLogo.COMPLETE); + createButton.addActionListener(this); + completeButton.addActionListener(this); + modifyButton.addActionListener(this); + consultButton.addActionListener(this); + comboLangModify=new JComboBox(intArray); + comboLangModify.setRenderer(new Contenu()); + comboLangComplete=new JComboBox(intArray); + comboLangComplete.setRenderer(new Contenu()); + validButton=new JButton(Logo.messages.getString("pref.ok")); + validButton.setActionCommand(TranslateXLogo.OK); + validButton.addActionListener(tx); + setSize(new java.awt.Dimension(600,120)); + validButton.setSize(new java.awt.Dimension(100,50)); + // textLang.setSize(new java.awt.Dimension(100,20)); + + group.add(createButton); + group.add(modifyButton); + group.add(completeButton); + group.add(consultButton); + + add(label, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets( + 0,0,0,0), 0, 0)); + add(createButton, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets( + 0,0,0,0), 0, 0)); + //add(textLang, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, + // GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( + // 0,0,0,0), 0, 0)); + add(modifyButton, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets( + 0,0,0,0), 0, 0)); + add(comboLangModify, new GridBagConstraints(1, 2, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( + 0,0,0,0), 0, 0)); + add(completeButton, new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets( + 0,0,0,0), 0, 0)); + add(comboLangComplete, new GridBagConstraints(1, 3, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( + 0,0,0,0), 0, 0)); + add(consultButton, new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets( + 0,0,0,0), 0, 0)); + add(validButton, new GridBagConstraints(2, 5, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( + 0,0,0,0), 0, 0)); + comboLangComplete.setVisible(false); + comboLangModify.setVisible(false); + // textLang.setVisible(false); + + + + } + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (cmd.equals(TranslateXLogo.MODIFY)){ + comboLangComplete.setVisible(false); + comboLangModify.setVisible(true); + // textLang.setVisible(false); + } + else if (cmd.equals(TranslateXLogo.CREATE)){ + comboLangComplete.setVisible(false); + comboLangModify.setVisible(false); + //textLang.setVisible(true); + //textLang.validate(); + } + else if (cmd.equals(TranslateXLogo.COMPLETE)){ + comboLangComplete.setVisible(true); + comboLangModify.setVisible(false); + //textLang.setVisible(false); + } + else if (cmd.equals(TranslateXLogo.CONSULT)){ + comboLangComplete.setVisible(false); + comboLangModify.setVisible(false); + //textLang.setVisible(false); + } + } + + + + class Contenu extends JLabel implements ListCellRenderer{ + private static final long serialVersionUID = 1L; + private ImageIcon[] drapeau; + + Contenu(){ + drapeau=new ImageIcon[Logo.translationLanguage.length]; + cree_icone(); + } + void cree_icone(){ + for (int i=0;i<drapeau.length;i++){ + Image image=null; + image= Toolkit.getDefaultToolkit().getImage(Utils.class.getResource("drapeau"+i+".png")); + MediaTracker tracker=new MediaTracker(this); + tracker.addImage(image,0); + try{tracker.waitForID(0);} + catch(InterruptedException e1){} + int largeur=image.getWidth(this); + int hauteur=image.getHeight(this); + double facteur = (double) WSManager.getWorkspaceConfig().getFont().getSize()/(double)hauteur; + image=image.getScaledInstance((int)(facteur*largeur),(int)(facteur*hauteur),Image.SCALE_SMOOTH); + tracker=new MediaTracker(this); + tracker.addImage(image,0); + try{tracker.waitForID(0);} + catch(InterruptedException e1){} + drapeau[i]=new ImageIcon(); + drapeau[i].setImage(image); +// drapeau[i]=new ImageIcon(image); + } + + } + public Component getListCellRendererComponent(JList list, Object value,int + index, boolean isSelected,boolean cellHasFocus){ + setOpaque(true); + int selectedIndex = ((Integer)value).intValue(); + setText(Logo.translationLanguage[selectedIndex]); + setIcon(drapeau[selectedIndex]); + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); } + else{ + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + setBorder(BorderFactory.createEmptyBorder(5,0,5,5)); +// setEnabled(list.isEnabled()); + return(this); + } + } + +} diff --git a/logo/src/xlogo/gui/translation/MyTable.java b/logo/src/xlogo/gui/translation/MyTable.java new file mode 100644 index 0000000..9976a09 --- /dev/null +++ b/logo/src/xlogo/gui/translation/MyTable.java @@ -0,0 +1,375 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings migh have been applied by Marko Zivkovic + */ + +package xlogo.gui.translation; +import java.util.Locale; +import java.util.ResourceBundle; +import java.awt.Component; +import java.util.Vector; +import java.util.Enumeration; +import java.util.Collections; + +import javax.swing.ListSelectionModel; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.AbstractCellEditor; +import javax.swing.table.TableCellEditor; +import javax.swing.JTextArea; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.event.*; +import javax.swing.JScrollPane; + +import java.awt.event.*; + +import xlogo.gui.Searchable; +import xlogo.storage.workspace.Language; +import xlogo.Logo; +public class MyTable extends JPanel implements Searchable{ + private static final long serialVersionUID = 1L; + private JTable table; + private JScrollPane scrollPane; + private TranslateXLogo tx; + private String id; + private String action; + private String bundle; + private Vector<String> keys; + protected MyTable(TranslateXLogo tx, String action, String id,String bundle){ + this.tx=tx; + this.action=action; + this.id=id; + this.bundle=bundle; + initGui(); + } + + public void setColumnSize(){ + for (int i = 0 ; i < table.getColumnCount() ; i++) + { + table.getColumnModel().getColumn(i).setPreferredWidth(200); + } + } + protected String getValue(int a, int b){ + return table.getValueAt(a, b).toString(); + } + private void initGui(){ + setLayout(new java.awt.BorderLayout()); + table=new JTable(new MyModel(bundle,action,id)); + + MultiLineCellEditor editor = new MultiLineCellEditor(table); + table.setDefaultEditor(String.class,editor); + + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + scrollPane = new JScrollPane(table); + //table.setFillsViewportHeight(true); + // Only one selection is possible + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + // You can only select Cell + table.setCellSelectionEnabled (true); + setColumnSize(); + add(scrollPane,java.awt.BorderLayout.CENTER); + + } + protected Vector<String> getKeys(){ + return keys; + } + class MultiLineCellEditor extends AbstractCellEditor implements TableCellEditor { + private static final long serialVersionUID = 1L; + MyTextArea textArea; + JTable table; + + public MultiLineCellEditor(JTable ta) { + super(); + table = ta; + // this component relies on having this renderer for the String class + MultiLineCellRenderer renderer = new MultiLineCellRenderer(); + table.setDefaultRenderer(String.class,renderer); +// JOptionPane.showMessageDialog(null,"jui ds l'editor","h",JOptionPane.INFORMATION_MESSAGE); + textArea = new MyTextArea(); + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + for(int i=0;i<table.getRowCount();i++) updateRow(i); + } + + /** This method determines the height in pixel of a cell given the text it contains */ + private int cellHeight(int row,int col) { + if (row == table.getEditingRow() && col == table.getEditingColumn()) + return textArea.getPreferredSize().height; + else + return table.getDefaultRenderer(String.class).getTableCellRendererComponent(table, + table.getModel().getValueAt(row,col),false,false,row,col).getPreferredSize().height; + } + + void cellGrewEvent(int row,int column) { + updateRow(row); + } + + void cellShrankEvent(int row,int column) { + updateRow(row); + } + + void updateRow(int row) { + int maxHeight = 0; + for(int j=0;j<table.getColumnCount();j++) { + int ch; + if ((ch = cellHeight(row,j)) > maxHeight) { + maxHeight = ch; + } + } + table.setRowHeight(row,maxHeight); + } + + public Object getCellEditorValue() { + return textArea.getText(); + } + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, + int row, int column) { + textArea.setText(table.getValueAt(row,column).toString()); + textArea.rowEditing = row; + textArea.columnEditing = column; + textArea.lastPreferredHeight = textArea.getPreferredSize().height; + + return textArea; + + } + + class MyTextArea extends JTextArea implements KeyListener { + private static final long serialVersionUID = 1L; + int lastPreferredHeight = 0; + int rowEditing; + int columnEditing; + + MyTextArea() { + addKeyListener(this); + // This is a fix to Bug Id 4256006 + addAncestorListener( new AncestorListener(){ + public void ancestorAdded(AncestorEvent e){ + requestFocus(); + } + public void ancestorMoved(AncestorEvent e){} + public void ancestorRemoved(AncestorEvent e){} + }); + } + + public void keyPressed(KeyEvent e) {} + public void keyReleased(KeyEvent e) {} + public void keyTyped(KeyEvent e) { + if (getPreferredSize().getHeight() > lastPreferredHeight) { + lastPreferredHeight = getPreferredSize().height; + cellGrewEvent(rowEditing,columnEditing); + // this will trigger the addition of extra lines upon the cell growing and + // prevent all the text being lost when the cell grows to the point of requiring + // scrollbars + table.setValueAt(getText(),rowEditing,columnEditing); + } + else if (getPreferredSize().getHeight() < lastPreferredHeight) { + lastPreferredHeight = getPreferredSize().height; + cellShrankEvent(rowEditing,columnEditing); + } + else if (table.getValueAt(rowEditing,columnEditing).equals("")) + table.setValueAt(getText(),rowEditing,columnEditing); + + } + } + } + + class MyModel extends AbstractTableModel { + private static final long serialVersionUID = 1L; + private String[] columnNames; + private String[][] rowData; + String action; + String id; + + MyModel(String bundle,String action, String id){ + this.action=action; + this.id=id; + + if (action.equals(TranslateXLogo.CREATE)){ + // Initilaize all Column Names + String[] tmp=Logo.translationLanguage; + columnNames=new String[tmp.length+1]; + columnNames[0]=id; + for (int i=1;i<columnNames.length;i++){ + columnNames[i]=tmp[i-1]; + } + } + else columnNames=Logo.translationLanguage; + buildRowData(bundle, action,id); + } + public String getColumnName(int col) { + return columnNames[col].toString(); + } + public int getRowCount() { return rowData.length; } + public int getColumnCount() { return columnNames.length; } + public Object getValueAt(int row, int col) { + return rowData[row][col]; + } + public boolean isCellEditable(int row, int col) + { + if (action.equals(TranslateXLogo.CONSULT)) return false; + else if (action.equals(TranslateXLogo.CREATE)) { + if (col==0) return true; + else return false; + } + else if (action.equals(TranslateXLogo.MODIFY)) { + if (col==Integer.parseInt(id)) return true; + else return false; + } + else if (action.equals(TranslateXLogo.COMPLETE)) { + if (col==Integer.parseInt(id)) { + + if (rowData[row][col].equals("")) return true; + else return false; + } + else return false; + } + return true; } + public void setValueAt(Object value, int row, int col) { + rowData[row][col] = value.toString(); + fireTableCellUpdated(row, col); + } + public Class<? extends Object> getColumnClass(int c) { + return getValueAt(0, c).getClass(); + + } + + private void buildRowData(String bundle,String action, String id){ + ResourceBundle[] rb=new ResourceBundle[getColumnCount()]; + // initialize all ResourceBundle + for(int i=0;i<getColumnCount();i++){ + Locale locale = Language.getLanguage(i).getLocale(); + // In CREATE Mode, when i=getColumnCount(), the last locale is null + if (null==locale) break; + rb[i] = ResourceBundle.getBundle(bundle, locale); + } + keys=new Vector<String>(); + Enumeration<String> en=rb[0].getKeys(); + while(en.hasMoreElements()){ + String value=en.nextElement(); + keys.add(value); + } + Collections.sort(keys); + rowData=new String[keys.size()][getColumnCount()]; + int row=0; + for (int j=0;j<keys.size();j++) { + String key=keys.get(j).toString(); + + for(int i=0;i<getColumnCount();i++){ + if (action.equals(TranslateXLogo.CREATE)){ + if (i==0) rowData[row][0]=""; + else rowData[row][i]=rb[i-1].getString(key); + } + else { + String element=rb[i].getString(key); + if (element.equals("")) { + rowData[row][i]=""; + } + else rowData[row][i]=element; + } + } + row++; + } + } + } + class MultiLineCellRenderer extends JTextArea implements TableCellRenderer { + private static final long serialVersionUID = 1L; + public MultiLineCellRenderer() { + setEditable(false); + setLineWrap(true); + setWrapStyleWord(true); + } + + public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected, boolean hasFocus, int row, int column) { + + if (value instanceof String) { + if (value.toString().equals("")) setBackground(new java.awt.Color(255,200,200)); + else setBackground(java.awt.Color.WHITE); + setText((String)value); + if (isSelected) setBackground(java.awt.Color.LIGHT_GRAY); + // set the table's row height, if necessary + //updateRowHeight(row,getPreferredSize().height); + } + else + setText(""); + return this; + } + } + int selectedRow=0; + int selectedColumn=0; + public boolean find(String element,boolean forward){ + int row=table.getSelectedRow(); + int col=table.getSelectedColumn(); + if (row!=-1) { + if (row==table.getRowCount()-1) { + selectedRow=0; + if (col==table.getColumnCount()-1) selectedColumn=0; + else selectedColumn=col+1; + } + else selectedRow=row+1; + } + int start=selectedRow; + for (int c=selectedColumn;c<table.getColumnCount();c++){ + for(int r=start;r<table.getRowCount();r++){ + String value=table.getValueAt(r, c).toString(); + int index=value.indexOf(element); + if (index!=-1) { + table.clearSelection(); + if (r==table.getRowCount()-1){ + selectedRow=0; + if (c==table.getColumnCount()-1) selectedColumn=0; + else selectedColumn=c+1; + } + else { + selectedRow=r+1; + selectedColumn=c; + } + boolean b=table.editCellAt(r, c); + if (!b) { + table.changeSelection(r, c,false,false); + } +// System.out.println(selectedRow+" "+selectedColumn); + return true; + } + } + start=0; + } + selectedColumn=0; + selectedRow=0; + table.changeSelection(0, 0,false,false); + return false; + } + public void replace(String element, boolean forward){ + + } + public void replaceAll(String element, String substitute){ + + } + public void removeHighlight(){ + tx.resetSearchFrame(); + } + +} diff --git a/logo/src/xlogo/gui/translation/TopPanel.java b/logo/src/xlogo/gui/translation/TopPanel.java new file mode 100644 index 0000000..239398b --- /dev/null +++ b/logo/src/xlogo/gui/translation/TopPanel.java @@ -0,0 +1,63 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings migh have been applied by Marko Zivkovic + */ + +package xlogo.gui.translation; +import java.awt.FlowLayout; +import java.awt.Dimension; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JButton; +import xlogo.Logo; +public class TopPanel extends JPanel { + private static final long serialVersionUID = 1L; + private TranslateXLogo tx; + private JTextArea area; + private JButton sendButton; + protected TopPanel(TranslateXLogo tx){ + this.tx=tx; + initGui(); + } + private void initGui(){ + setLayout(new FlowLayout()); + area=new JTextArea(Logo.messages.getString("translatemessage")); + area.setWrapStyleWord(true); + area.setLineWrap(true); + sendButton=new JButton(Logo.messages.getString("pref.ok")); + + + area.setEditable(false); + sendButton.addActionListener(tx); + sendButton.setActionCommand(TranslateXLogo.SEND); + + + area.setSize(new Dimension(400,100)); + sendButton.setSize(new Dimension(50,30)); + add(area); + add(sendButton); + } +} diff --git a/logo/src/xlogo/gui/translation/TranslateXLogo.java b/logo/src/xlogo/gui/translation/TranslateXLogo.java new file mode 100644 index 0000000..9be2d37 --- /dev/null +++ b/logo/src/xlogo/gui/translation/TranslateXLogo.java @@ -0,0 +1,178 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings migh have been applied by Marko Zivkovic + */ + +package xlogo.gui.translation; + +import javax.swing.JFrame; +import javax.swing.JFileChooser; + +import java.awt.BorderLayout; +import java.awt.Toolkit; +import java.awt.event.*; +import java.io.IOException; +import java.util.Locale; +import java.util.ResourceBundle; + +import xlogo.Logo; +import xlogo.messages.async.dialog.DialogMessenger; +import xlogo.storage.WSManager; +import xlogo.storage.workspace.Language; +import xlogo.utils.Utils; +import xlogo.gui.SearchFrame; +/** + * Modifications made by Marko: <br> + * IO error is displayed through DialogMessenger (singleton) instead of {@link Application#ecris()}. Result: This class is completely decoupled from the Application class. + * @author lo�c Le Coq, slightly modified by Marko Zivkovic + */ +public class TranslateXLogo extends JFrame implements ActionListener { + private static final long serialVersionUID = 1L; + private String id=""; + private String action; + + protected static final String OK="ok"; + protected static final String SEND="send"; + protected static final String SEARCH="search"; + + protected static final String CONSULT="0"; + protected static final String MODIFY="1"; + protected static final String CREATE="2"; + protected static final String COMPLETE="3"; + + private FirstPanel first; + private TopPanel top; + private BottomPanel bottom; + + private SearchFrame sf=null; + public TranslateXLogo(){ + initGui(); + } + private void initGui(){ + setIconImage(Toolkit.getDefaultToolkit().createImage( + Utils.class.getResource("icone.png"))); + setTitle(Logo.messages.getString("menu.help.translatexlogo")); + first=new FirstPanel(this); + getContentPane().add(first); + setVisible(true); + } + public void actionPerformed(ActionEvent e){ + String cmd=e.getActionCommand(); + if (cmd.equals(TranslateXLogo.OK)){ + action=first.getAction(); + + if (null==action) return; + else if (action.equals(TranslateXLogo.MODIFY)) id=first.getLang(); + else if (action.equals(TranslateXLogo.COMPLETE)) id=first.getLang(); + //else if (action.equals(TranslateXLogo.CREATE)) id=first.getNewLang(); + remove(first); + bottom=new BottomPanel(this,action,id); + getContentPane().setLayout(new BorderLayout()); + if (!action.equals(TranslateXLogo.CONSULT)){ + top=new TopPanel(this); + getContentPane().add(top,BorderLayout.NORTH); + + } + + getContentPane().add(bottom,BorderLayout.CENTER); + this.getContentPane().validate(); + } + else if (cmd.equals(TranslateXLogo.SEND)){ + String path=""; + JFileChooser jf=new JFileChooser(Utils.SortieTexte(WSManager.getUserConfig().getDefaultFolder())); + int retval=jf.showDialog(this,Logo.messages + .getString("menu.file.save")); + if (retval==JFileChooser.APPROVE_OPTION){ + path=jf.getSelectedFile().getPath(); + StringBuffer sb=new StringBuffer(); + try { + Locale locale=null; + if (action.equals(TranslateXLogo.CREATE)){ + locale = Language.getLanguage(0).getLocale(); + } + else if (!action.equals(TranslateXLogo.CONSULT)){ + locale = Language.getLanguage(Integer.parseInt(id)).getLocale(); + } + java.util.Vector<String> v=bottom.getPrimTable().getKeys(); + ResourceBundle rb = ResourceBundle.getBundle("primitives", locale); + for (int i=0;i<v.size();i++) { + String key=v.get(i); + if (action.equals(TranslateXLogo.CREATE)){ + writeLine(sb,key,bottom.getPrimValue(i,0)); + } + else if (!action.equals(TranslateXLogo.CONSULT)){ + String element=bottom.getPrimValue(i, Integer.parseInt(id)); + // System.out.println(element+" clé "+key); + if (!rb.getString(key).equals(element)) writeLine(sb,key,element); + } + } + sb.append("\n---------------------------------------\n"); + v=bottom.getMessageTable().getKeys(); + rb = ResourceBundle.getBundle("langage", locale); + for(int i=0;i<v.size();i++){ + String key=v.get(i); + if (action.equals(TranslateXLogo.CREATE)){ + writeLine(sb,key,bottom.getMessageValue(i,0).replaceAll("\\n","\\\\n")); + } + else if (!action.equals(TranslateXLogo.CONSULT)){ + String element=bottom.getMessageValue(i, Integer.parseInt(id)); + if (!rb.getString(key).equals(element)) writeLine(sb,key,element.replaceAll("\\n","\\\\n")); + } + } + Utils.writeLogoFile(path,sb.toString()); + } + catch(NullPointerException e3){System.out.println("annulation");} //Si l'utilisateur annule + catch(IOException e2){ + DialogMessenger.getInstance().dispatchError("general.error.title", Logo.messages.getString("error.ioecriture")); + } + } + } + else if (cmd.equals(TranslateXLogo.SEARCH)){ + if (null==sf) { + sf=new SearchFrame(this,bottom.getVisibleTable()); + sf.setSize(350, 350); + sf.setVisible(true); + } + } + } + protected void resetSearchFrame(){ + sf=null; + } + private void writeLine(StringBuffer sb,String key, String value){ + sb.append(key); + sb.append("="); + sb.append(value); + sb.append("\n"); + + } + protected void processWindowEvent(WindowEvent e){ + super.processWindowEvent(e); + if (e.getID()==WindowEvent.WINDOW_CLOSING){ + //app.close_TranslateXLogo(); TODO Application does not need this. Maybe in settings @ welcome + } + + } +} diff --git a/logo/src/xlogo/gui/welcome/WelcomeScreen.java b/logo/src/xlogo/gui/welcome/WelcomeScreen.java new file mode 100644 index 0000000..f6e068c --- /dev/null +++ b/logo/src/xlogo/gui/welcome/WelcomeScreen.java @@ -0,0 +1,518 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were entirely written by Marko Zivkovic + */ + +package xlogo.gui.welcome; +import java.awt.event.*; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.JTextComponent; + +import java.awt.*; +import java.io.IOException; + +import xlogo.messages.MessageKeys; +import xlogo.messages.async.AsyncMediumAdapter; +import xlogo.messages.async.AsyncMessage; +import xlogo.messages.async.AsyncMessenger; +import xlogo.messages.async.dialog.DialogMessenger; +import xlogo.storage.Storable; +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +import xlogo.storage.workspace.WorkspaceConfig; +import xlogo.utils.Utils; +import xlogo.utils.WebPage; +import xlogo.Application; +import xlogo.Logo; + +/** + * This was initially called {@code Selection_Langue} and it was only displayed when the Application was opened for the very first time. + * Now this has become {@code WelcomeScreen}, as it was enhanced with more options than just language selection: + * <li> User Account Selection / Creation </li> + * <li> Storage Location (master password required) </li> + * @author Marko + */ +public class WelcomeScreen extends JFrame { + private static final long serialVersionUID = 1L; + + private JLabel label; + + private JLabel workspace = new JLabel("Workspace"); + private JLabel username = new JLabel("User"); + + private JComboBox workspaceSelection = new JComboBox(); + private JComboBox userSelection = new JComboBox(); + + private JButton openWorkspaceSettingsBtn = new JButton("Settings"); + private JButton enterButton = new JButton("Enter"); + + private JButton infoButton = new JButton(); + private JButton gplButton = new JButton(); + + private JPanel panel = new JPanel(); + private GroupLayout groupLayout; + + private ActionListener listener; + + /** + * + * @param listener to be informed when the user is ready to enter the application + */ + public WelcomeScreen(ActionListener listener){ + this.listener = listener; + // Window + super.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("Icon_x4s.png"))); + setTitle("XLogo4Schools"); + + // The XLogo4Schools logo + //ImageIcon logo = Utils.dimensionne_image("Logo_xlogo4schools.png", this); + + infoButton.setIcon(createImageIcon("info_icon.png", "Info", 40, 40)); + gplButton.setIcon(createImageIcon("gnu_gpl.png", "GPL", 40, 40)); + label = new JLabel(createImageIcon("Logo_xlogo4schools.png", "XLogo4Schools", 250, 40)); + + // Select workspace combo box + initWorkspaceListModel(); + workspaceSelection.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + String workspace = (String) workspaceSelection.getSelectedItem(); + enterWorkspace(workspace); + } + }); + // Open workspace settings button + openWorkspaceSettingsBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + showWorkspaceSettings(); + } + }); + + // Select user combo box + populateUserList(); + final JTextComponent tc = (JTextComponent) userSelection.getEditor().getEditorComponent(); + tc.getDocument().addDocumentListener(new DocumentListener() { + public void removeUpdate(DocumentEvent arg0) { enableOrDisableEnter(); } + public void insertUpdate(DocumentEvent arg0) { enableOrDisableEnter(); } + public void changedUpdate(DocumentEvent arg0) { enableOrDisableEnter(); } + private void enableOrDisableEnter() + { + String username = tc.getText(); + enterButton.setEnabled(username != null && username.length() != 0); + } + }); + + userSelection.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String username = (String) userSelection.getSelectedItem(); + enterButton.setEnabled(username != null && username.length() != 0); + } + }); + + // Enter user space button + enterButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + enterApplication(); + } + }); + + gplButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + showGPL(); + } + }); + + infoButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + showInfo(); + } + }); + + // Add all + initLayout(); + getContentPane().add(panel); + setText(); + pack(); + setVisible(true); + //MessageManager.getInstance().setParent(this); + setMessageManagerParent(); + } + + private void initWorkspaceListModel() + { + WSManager wsManager = WSManager.getInstance(); + try + { + String lastUsedWorkspace = wsManager.getGlobalConfigInstance().getLastUsedWorkspace(); + wsManager.enterWorkspace(lastUsedWorkspace); + populateWorkspaceList(); + } + catch (IOException e) + { + DialogMessenger + .getInstance() + .dispatchMessage( + "I'm sorry, something very bad happened", + "Please report this error message. You could try to delete the file X4S_GlobalConfig from your home directory, " + + "and restart XLogo4Schools. You will have to import your Workspaces again.\n\n" + + e.toString()); + } + } + + private void populateWorkspaceList() + { + GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance(); + String[] workspaces = gc.getAllWorkspaces(); + workspaceSelection.setModel(new DefaultComboBoxModel(workspaces)); + workspaceSelection.setSelectedItem(gc.getLastUsedWorkspace()); + } + + private void populateUserList() + { + WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance(); + String[] users = wc.getUserList(); + userSelection.setModel(new DefaultComboBoxModel(users)); + String lastUser = wc.getLastActiveUser(); + userSelection.setSelectedItem(lastUser); + enterButton.setEnabled(lastUser != null && lastUser.length() > 0); + userSelection.setEditable(wc.isUserCreationAllowed()); + } + + protected void enterWorkspace(String workspaceName) { + try { + WSManager.getInstance().enterWorkspace(workspaceName); + populateUserList(); + } catch (IOException e) { + DialogMessenger.getInstance().dispatchMessage( + Logo.messages.getString("ws.error.title"), + Logo.messages.getString("ws.settings.could.not.enter.wp") + "\n\n" + e.toString()); + } + } + + private void initLayout() + { + setResizable(false); + infoButton.setBorder(null); + gplButton.setBorder(null); + + infoButton.setOpaque(false); + gplButton.setOpaque(false); + + panel.add(workspace); + panel.add(username); + panel.add(workspaceSelection); + panel.add(userSelection); + panel.add(openWorkspaceSettingsBtn); + panel.add(enterButton); + panel.add(infoButton); + panel.add(gplButton); + + workspaceSelection.setMinimumSize(new Dimension(200, 25)); + userSelection.setMinimumSize(new Dimension(200, 25)); + workspaceSelection.setMaximumSize(new Dimension(200, 25)); + userSelection.setMaximumSize(new Dimension(200, 25)); + + groupLayout = new GroupLayout(panel); + panel.setLayout(groupLayout); + + groupLayout.setAutoCreateGaps(true); + groupLayout.setAutoCreateContainerGaps(true); + + groupLayout.setVerticalGroup( + groupLayout.createSequentialGroup() + .addGroup(groupLayout.createParallelGroup() + .addComponent(gplButton) + .addComponent(infoButton) + .addComponent(label)) + .addGroup(groupLayout.createParallelGroup() + .addComponent(workspace) + .addComponent(workspaceSelection) + .addComponent(openWorkspaceSettingsBtn)) + .addGroup(groupLayout.createParallelGroup() + .addComponent(username) + .addComponent(userSelection) + .addComponent(enterButton)) + ); + + groupLayout.setHorizontalGroup( + groupLayout.createParallelGroup() + .addGroup( + groupLayout.createSequentialGroup() + .addComponent(label) + .addComponent(gplButton) + .addComponent(infoButton)) + .addGroup( + groupLayout.createSequentialGroup() + .addGroup(groupLayout.createParallelGroup() + .addComponent(workspace) + .addComponent(username)) + .addGroup(groupLayout.createParallelGroup() + .addComponent(workspaceSelection) + .addComponent(userSelection)) + .addGroup(groupLayout.createParallelGroup() + .addComponent(openWorkspaceSettingsBtn) + .addComponent(enterButton)) + ) + ); + } + + /** + * Display {@link xlogo.gui.welcome.WelcomeScreen} when starting the application. + */ + private void showWorkspaceSettings() + { + + Runnable runnable = new Runnable() { + public void run() { + String authentification = null; + GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance(); + if (gc.isPasswordRequired()) + { + authentification = showPasswordPopup(); + if (authentification == null) + return; // user cancelled the process + + if(!gc.authenticate(new String(authentification))) + { + // Could not authenticate => cancel + DialogMessenger.getInstance().dispatchMessage( + Logo.messages.getString("i.am.sorry"), + Logo.messages.getString("welcome.wrong.pw")); + return; + } + } + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + setMessageManagerParent(); + setText(); + populateWorkspaceList(); + populateUserList(); + setEnabled(true); + } + }; + + setEnabled(false); + new WorkspaceSettings(listener, authentification); + } + }; + + new Thread(runnable).start(); + } + + private void setMessageManagerParent() + { + DialogMessenger.getInstance().setMedium(new AsyncMediumAdapter<AsyncMessage<JFrame>, JFrame>(){ + public boolean isReady() + { + return getThis().isDisplayable(); + } + public JFrame getMedium() + { + return getThis(); + } + public void addMediumReadyListener(final AsyncMessenger messenger) + { + getThis().addWindowStateListener(new WindowStateListener(){ + + @Override + public void windowStateChanged(WindowEvent e) + { + if (getThis().isDisplayable()) + messenger.onMediumReady(); + } + }); + } + }); + } + + private JFrame getThis() + { + return this; + } + + + protected String showPasswordPopup() { + JPasswordField passwordField = new JPasswordField(); + int option = JOptionPane.showConfirmDialog(this, passwordField, Logo.messages.getString("welcome.enter.pw"), + JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); + + if (option == JOptionPane.OK_OPTION) { + return new String(passwordField.getPassword()); + } + return null; + } + + public void enterApplication() + { + System.gc(); + String username = (String) userSelection.getSelectedItem(); + + if ((username == null) || (username.length() == 0)) + return; // this should not happen since the enter button is disabled + + if(!Storable.checkLegalName(username)) + { + DialogMessenger.getInstance().dispatchError( + Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE), + Logo.messages.getString(MessageKeys.ILLEGAL_NAME)); + return; + } + + + WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance(); + if (!wc.existsUserLogically(username)) + wc.createUser(username); + + try { + WSManager.getInstance().enterUserSpace(username); + } catch (IOException e) { + DialogMessenger.getInstance().dispatchMessage( + Logo.messages.getString("ws.error.title"), + Logo.messages.getString("welcome.could.not.enter.user") + e.toString()); + return; + } + System.gc(); + listener.actionPerformed(new ActionEvent(this, 0, null)); + } + + @Override + public void dispose() + { + try { + WSManager.getInstance().getGlobalConfigInstance().store(); + } catch (IOException e) { + DialogMessenger.getInstance().dispatchMessage( + Logo.messages.getString("ws.error.title"), + Logo.messages.getString("storage.could.not.store.gc")); + } + + System.gc(); + super.dispose(); + } + + public void setText() + { + workspace.setText(Logo.messages.getString("welcome.workspace")); + username.setText(Logo.messages.getString("welcome.username")); + openWorkspaceSettingsBtn.setText(Logo.messages.getString("welcome.settings")); + enterButton.setText(Logo.messages.getString("welcome.enter")); + setTitle(Logo.messages.getString("welcome.title")); + pack(); + } + + /** + * Like in XLogo, almost unmodified. + * It is displayed in the language of the currently selected workspace. + */ + private void showGPL() + { + JFrame frame = new JFrame(Logo.messages.getString("menu.help.licence")); + frame.setIconImage(Toolkit.getDefaultToolkit().createImage(WebPage.class.getResource("Logo_xlogo4schools.png"))); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + frame.setSize(500, 500); + WebPage editorPane = new WebPage(); + editorPane.setEditable(false); + + String langCode = WSManager.getWorkspaceConfig().getLanguage().getLanguageCode(); + + String path = "gpl/gpl-" + langCode + ".html"; + + java.net.URL helpURL = Application.class.getResource(path); + if (helpURL != null) + { + try + { + editorPane.setPage(helpURL); + } + catch (IOException e1) + { + System.err.println("Attempted to read a bad URL: " + helpURL); + } + } + else + { + System.err.println("Couldn't find file: " + path); + } + + // Put the editor pane in a scroll pane. + JScrollPane editorScrollPane = new JScrollPane(editorPane); + editorScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + editorScrollPane.setPreferredSize(new Dimension(250, 145)); + editorScrollPane.setMinimumSize(new Dimension(10, 10)); + frame.getContentPane().add(editorScrollPane); + frame.setVisible(true); + } + + private void showInfo() + { + JFrame frame = new JFrame(Logo.messages.getString("menu.help.licence")); + frame.setIconImage(Toolkit.getDefaultToolkit().createImage(WebPage.class.getResource("Icon_x4s.png"))); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + frame.setSize(500, 500); + WebPage editorPane = new WebPage(); + editorPane.setEditable(false); + + String path = "gpl/x4s_info.html"; + + java.net.URL helpURL = Application.class.getResource(path); + if (helpURL != null) + { + try + { + editorPane.setPage(helpURL); + } + catch (IOException e1) + { + System.err.println("Attempted to read a bad URL: " + helpURL); + } + } + else + { + System.err.println("Couldn't find file: " + path); + } + + // Put the editor pane in a scroll pane. + JScrollPane editorScrollPane = new JScrollPane(editorPane); + editorScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + editorScrollPane.setPreferredSize(new Dimension(250, 145)); + editorScrollPane.setMinimumSize(new Dimension(10, 10)); + frame.getContentPane().add(editorScrollPane); + frame.setVisible(true); + } + + /* + * Helper + */ + + private ImageIcon createImageIcon(String path, String description, int width, int heigth) { + Image img = Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(path)); + return new ImageIcon(img.getScaledInstance(width, heigth, Image.SCALE_SMOOTH)); + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/gui/welcome/WorkspaceSettings.java b/logo/src/xlogo/gui/welcome/WorkspaceSettings.java new file mode 100644 index 0000000..9634325 --- /dev/null +++ b/logo/src/xlogo/gui/welcome/WorkspaceSettings.java @@ -0,0 +1,183 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome;
+
+import java.awt.Toolkit;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowStateListener;
+import java.io.IOException;
+
+import javax.swing.JFrame;
+import javax.swing.JTabbedPane;
+
+import xlogo.gui.components.X4SFrame;
+import xlogo.gui.welcome.settings.tabs.SyntaxHighlightingTab;
+import xlogo.gui.welcome.settings.tabs.ContestTab;
+import xlogo.gui.welcome.settings.tabs.GlobalTab;
+import xlogo.gui.welcome.settings.tabs.WorkspaceTab;
+import xlogo.messages.async.AsyncMediumAdapter;
+import xlogo.messages.async.AsyncMessage;
+import xlogo.messages.async.AsyncMessenger;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.WSManager;
+import xlogo.utils.Utils;
+
+public class WorkspaceSettings extends X4SFrame {
+
+ private JFrame frame;
+
+ // TABS
+ JTabbedPane tabs;
+ GlobalTab globalTab;
+ WorkspaceTab workspaceTab;
+ SyntaxHighlightingTab appearanceTab;
+ ContestTab contestTab;
+
+ /**
+ * Used to communicate with the frame which opened this one.
+ */
+ private ActionListener listener;
+
+ public WorkspaceSettings(ActionListener listener, String authentification)
+ {
+ super();
+ this.listener = listener;
+ globalTab.authenticate(authentification);
+ frame.setVisible(true);
+ }
+
+ @Override
+ public JFrame getFrame() {
+ return frame;
+ }
+
+ @Override
+ protected void initComponent() {
+ frame = new JFrame(){
+ private static final long serialVersionUID = 7057009528231153055L;
+
+ @Override
+ public void dispose()
+ {
+ try {
+ WSManager.getInstance().getGlobalConfigInstance().store();
+ WSManager.getInstance().getWorkspaceConfigInstance().store();
+ } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("storage.could.not.store.gc"));
+ }
+
+ listener.actionPerformed(null);
+ super.dispose();
+ System.gc();
+ }
+ };
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("Icon_x4s.png"))); // TODO need new icon?
+
+ tabs = new JTabbedPane();
+ globalTab = new GlobalTab();
+ workspaceTab = new WorkspaceTab();
+ appearanceTab = new SyntaxHighlightingTab();
+ contestTab = new ContestTab();
+
+ setMessageManagerParent();
+ }
+
+ @Override
+ protected void layoutComponent() {
+ frame.setResizable(false);
+
+ tabs.addTab("Global", null, globalTab.getComponent(), "Global Settings");
+ tabs.addTab("Workspace", null, workspaceTab.getComponent(), "Workspace Settings");
+ tabs.addTab("Appearance", null, appearanceTab.getComponent(), "Workspace Appearance");
+ tabs.addTab("Contest", null, contestTab.getComponent(), "Contest Settings");
+
+ frame.getContentPane().add(tabs);
+ }
+
+ @Override
+ protected void setText()
+ {
+ frame.setTitle(translate("ws.settings.title"));
+ tabs.setTitleAt(0, translate("ws.settings.global"));
+ tabs.setToolTipTextAt(0, translate("ws.settings.global.settings"));
+ tabs.setTitleAt(1, translate("ws.settings.workspace"));
+ tabs.setToolTipTextAt(1, translate("ws.settings.global.settings"));
+ tabs.setTitleAt(2, translate("ws.settings.syntax")); // TODO make translation
+ tabs.setToolTipTextAt(2, translate("ws.settings.global.settings"));
+ tabs.setTitleAt(3, translate("ws.settings.contest"));
+ tabs.setToolTipTextAt(3, translate("ws.settings.global.settings"));
+ frame.pack();
+ }
+
+ @Override
+ protected void initEventListeners()
+ {
+
+ }
+
+ @Override
+ public void stopEventListeners()
+ {
+ stopListenForLanguageChangeEvents();
+ globalTab.stopEventListeners();
+ workspaceTab.stopEventListeners();
+ appearanceTab.stopEventListeners();
+ contestTab.stopEventListeners();
+ }
+
+ private void setMessageManagerParent()
+ {
+ DialogMessenger.getInstance().setMedium(new AsyncMediumAdapter<AsyncMessage<JFrame>, JFrame>(){
+ public boolean isReady()
+ {
+ return frame.isDisplayable();
+ }
+ public JFrame getMedium()
+ {
+ return frame;
+ }
+ public void addMediumReadyListener(final AsyncMessenger messenger)
+ {
+ frame.addWindowStateListener(new WindowStateListener(){
+
+ @Override
+ public void windowStateChanged(WindowEvent e)
+ {
+ if (frame.isDisplayable())
+ messenger.onMediumReady();
+ }
+ });
+ }
+ });
+ }
+
+}
diff --git a/logo/src/xlogo/gui/welcome/settings/tabs/AbstractWorkspacePanel.java b/logo/src/xlogo/gui/welcome/settings/tabs/AbstractWorkspacePanel.java new file mode 100644 index 0000000..a226e64 --- /dev/null +++ b/logo/src/xlogo/gui/welcome/settings/tabs/AbstractWorkspacePanel.java @@ -0,0 +1,269 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome.settings.tabs;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+
+import xlogo.AppSettings;
+import xlogo.gui.components.X4SComponent;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.WSManager;
+import xlogo.storage.global.GlobalConfig;
+import xlogo.storage.workspace.WorkspaceConfig;
+
+public abstract class AbstractWorkspacePanel extends X4SComponent{
+
+ private ActionListener enterWorkspaceListener;
+ private ActionListener workspaceListChangeListener;
+
+ protected abstract JComboBox getWorkspaceSelection();
+
+ @Override
+ protected void initEventListeners()
+ {
+ getWorkspaceSelection().addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ String wsName = (String) getWorkspaceSelection().getSelectedItem();
+ enterWorkspace(wsName);
+ }
+ }).run();
+ }
+ });
+
+ final GlobalConfig gc = WSManager.getGlobalConfig();
+
+ gc.addWorkspaceListChangeListener(workspaceListChangeListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ populateWorkspaceList();
+ }
+ });
+
+ gc.addEnterWorkspaceListener(enterWorkspaceListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ getWorkspaceSelection().setSelectedItem(gc.getLastUsedWorkspace());
+ }
+ });
+ }
+
+ @Override
+ public void stopEventListeners()
+ {
+ super.stopEventListeners();
+ GlobalConfig gc = WSManager.getGlobalConfig();
+ gc.removeEnterWorkspaceListener(enterWorkspaceListener);
+ gc.removeWorkspaceListChangeListener(workspaceListChangeListener);
+
+ }
+ protected abstract void setValues();
+
+ protected abstract void enableComponents();
+
+ protected abstract void disableComponents();
+
+ protected void populateWorkspaceList() {
+ GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance();
+ String[] workspaces = gc.getAllWorkspaces();
+ getWorkspaceSelection().setModel(new DefaultComboBoxModel(workspaces));
+ String lastUsed = gc.getLastUsedWorkspace();
+ enterWorkspace(lastUsed);
+ getWorkspaceSelection().setSelectedItem(lastUsed);
+ }
+
+ protected void deleteWorkspace() {
+ WSManager wsManager = WSManager.getInstance();
+ GlobalConfig gc = wsManager.getGlobalConfigInstance();
+
+ String wsName = (String) getWorkspaceSelection().getSelectedItem();
+ String wsLocation = gc.getWorkspaceDirectory(wsName).toString();
+ String message =
+ translate("ws.settings.want.delete.dir.1")
+ + wsLocation
+ + translate("ws.settings.want.delete.dir.2");
+
+ boolean ans = getUserYesOrNo(message, translate("ws.settings.delete.from.fs"));
+
+ try {
+ wsManager.enterWorkspace(WorkspaceConfig.VIRTUAL_WORKSPACE);
+ } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("ws.settings.could.not.enter.virtual.ws") + e.toString());
+ }
+ wsManager.deleteWorkspace(wsName, ans);
+
+ populateWorkspaceList();
+ }
+
+ protected void importWorkspace() {
+ File dir = getUserSelectedDirectory();
+ if (dir == null)
+ return;
+
+ WSManager wsManager = WSManager.getInstance();
+ if (!WSManager.isWorkspaceDirectory(dir))
+ {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("i.am.sorry"),
+ dir.toString() + translate("ws.settings.not.legal.ws.dir"));
+ return;
+ }
+ String newName = dir.getName();
+
+ if (dir.equals(WSManager.getGlobalConfig().getWorkspaceDirectory(newName)))
+ {
+ DialogMessenger.getInstance().dispatchMessage("The workspace was already in the list.");
+ return;
+ }
+
+ File newDir = new File(dir.toString());
+
+ if (WSManager.getGlobalConfig().existsWorkspace(newName) || !Storable.checkLegalName(newName))
+ {
+ do
+ {
+ String msg = WSManager.getGlobalConfig().existsWorkspace(newName) ?
+ "The workspace name " + newName + " already exists. Please choose a new name"
+ : newDir.exists() ? newDir.toString() + " already exists. Please choose a new name."
+ : "The chosen name contains illegal characters.";
+
+ newName = getUserText(msg, "Name Conflict");
+ if (newName == null)
+ return;
+
+ newDir = new File(dir.getParent() + File.separator + newName);
+ }
+ while(WSManager.getGlobalConfig().existsWorkspace(newName)
+ || !Storable.checkLegalName(newName)
+ || newDir.exists());
+ }
+
+ if(!newDir.equals(dir))
+ dir.renameTo(newDir);
+
+ wsManager.importWorkspace(newDir, newName);
+ populateWorkspaceList();
+ }
+
+ protected void enterWorkspace(String wsName) {
+ try {
+ // enter workspace
+ WSManager.getInstance().enterWorkspace(wsName);
+ WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance();
+ if (wc == null)
+ {
+ disableComponents();
+ return;
+ }
+ if (wc.isVirtual())
+ disableComponents();
+ else
+ enableComponents();
+ setValues();
+ AppSettings.getInstance().setLanguage(wc.getLanguage());
+ } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("ws.settings.could.not.enter.wp") + e.toString());
+ disableComponents();
+ }
+
+ }
+
+ protected void addWorkspace() {
+ WorkspaceCreationPanel wscPanel = new WorkspaceCreationPanel();
+
+ int option = JOptionPane.showConfirmDialog(
+ getComponent(),
+ wscPanel.getComponent(),
+ translate("ws.settings.create.new.wp"),
+ JOptionPane.OK_CANCEL_OPTION,
+ JOptionPane.PLAIN_MESSAGE);
+
+ if (option != JOptionPane.OK_OPTION)
+ return;
+
+ String wsName = wscPanel.wsNameField.getText();
+ String location = wscPanel.locationField.getText();
+ File dir = new File(location);
+
+ GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance();
+
+ // Make sure that the specified workspace name is non-empty and that it does not exist already
+ if (wsName.length() == 0){
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("i.am.sorry"),
+ translate("ws.settings.wp.name.non.empty"));
+ return;
+ }
+ if (gc.existsWorkspace(wsName)){
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("i.am.sorry"),
+ translate("ws.settings.wp.exists.already"));
+ return;
+ }
+
+ // Make sure dir is an existing directory
+ if(!dir.exists()){
+ if (!dir.mkdirs()){
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("ws.settings.could.not.create.directory"));
+ return;
+ }
+ }else if (!dir.isDirectory()){
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("ws.settings.need.dir.not.file"));
+ return;
+ }
+ // dir exists & wsName doesn't exist yet => fine to create WS now
+ try {
+ WSManager.getInstance().createWorkspace(dir, wsName);
+ populateWorkspaceList();
+ } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("ws.settings.could.not.create.ws"));
+ return;
+ }
+
+ }
+
+}
diff --git a/logo/src/xlogo/gui/welcome/settings/tabs/ContestTab.java b/logo/src/xlogo/gui/welcome/settings/tabs/ContestTab.java new file mode 100644 index 0000000..e2dfa0a --- /dev/null +++ b/logo/src/xlogo/gui/welcome/settings/tabs/ContestTab.java @@ -0,0 +1,197 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome.settings.tabs;
+
+import java.awt.Dimension;
+
+import javax.swing.GroupLayout;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import xlogo.storage.WSManager;
+import xlogo.storage.workspace.WorkspaceConfig;
+
+public class ContestTab extends AbstractWorkspacePanel {
+
+ JPanel component;
+ JLabel workspaceLabel;
+ JComboBox workspaceSelection;
+ JLabel nOfFilesLabel;
+ JSpinner nOfFileSpinner;
+ JLabel nOfBonusFilesLabel;
+ JSpinner nOfBonusFileSpinner;
+
+ public JComponent getComponent()
+ {
+ return component;
+ }
+
+ @Override
+ protected JComboBox getWorkspaceSelection() {
+ return workspaceSelection;
+ }
+
+ @Override
+ protected void initComponent()
+ {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ component = new JPanel();
+
+ workspaceLabel = new JLabel();
+ workspaceSelection = new JComboBox();
+
+ nOfFilesLabel = new JLabel();
+ nOfFileSpinner = new JSpinner(new SpinnerNumberModel(wc.getNOfContestFiles(), 0, 100, 1));
+ JComponent editor = new JSpinner.NumberEditor(nOfFileSpinner);
+ nOfFileSpinner.setEditor(editor);
+
+ nOfBonusFilesLabel = new JLabel();
+ nOfBonusFileSpinner = new JSpinner(new SpinnerNumberModel(wc.getNOfContestBonusFiles(), 0, 100, 1));
+ JComponent editor2 = new JSpinner.NumberEditor(nOfBonusFileSpinner);
+ nOfBonusFileSpinner.setEditor(editor2);
+
+ populateWorkspaceList();
+ }
+
+ @Override
+ protected void layoutComponent()
+ {
+ workspaceSelection.setMinimumSize(new Dimension(150,25));
+ workspaceSelection.setMaximumSize(new Dimension(150,25));
+
+ nOfFileSpinner.setMinimumSize(new Dimension(25,25));
+ nOfFileSpinner.setMaximumSize(new Dimension(50,25));
+
+ nOfBonusFileSpinner.setMinimumSize(new Dimension(25,25));
+ nOfBonusFileSpinner.setMaximumSize(new Dimension(50,25));
+
+ component.add(workspaceLabel);
+ component.add(workspaceSelection);
+ component.add(nOfFilesLabel);
+ component.add(nOfFileSpinner);
+ component.add(nOfBonusFilesLabel);
+ component.add(nOfBonusFileSpinner);
+
+ GroupLayout groupLayout = new GroupLayout(component);
+ component.setLayout(groupLayout);
+
+ groupLayout.setAutoCreateGaps(true);
+ groupLayout.setAutoCreateContainerGaps(true);
+
+ groupLayout.setVerticalGroup(
+ groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceLabel)
+ .addComponent(workspaceSelection)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(nOfFilesLabel)
+ .addComponent(nOfFileSpinner)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(nOfBonusFilesLabel)
+ .addComponent(nOfBonusFileSpinner)
+ )
+ );
+
+ groupLayout.setHorizontalGroup(
+ groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceLabel)
+ .addComponent(nOfFilesLabel)
+ .addComponent(nOfBonusFilesLabel)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceSelection)
+ .addComponent(nOfFileSpinner)
+ .addComponent(nOfBonusFileSpinner)
+ )
+ );
+ }
+
+ @Override
+ protected void setText()
+ {
+ workspaceLabel.setText(translate("ws.settings.workspace"));
+ nOfFilesLabel.setText(translate("contest.number.of.files"));
+ nOfBonusFilesLabel.setText(translate("contest.number.of.bonus.files"));
+ }
+
+ @Override
+ protected void initEventListeners()
+ {
+ super.initEventListeners();
+
+ nOfFileSpinner.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent arg0) {
+ WSManager.getWorkspaceConfig().setNOfContestFiles((Integer) nOfFileSpinner.getValue());
+ }
+ });
+
+ nOfBonusFileSpinner.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ WSManager.getWorkspaceConfig().setNOfContestBonusFiles((Integer) nOfBonusFileSpinner.getValue());
+ }
+ });
+ }
+
+ @Override
+ public void stopEventListeners()
+ {
+ super.stopEventListeners();
+
+ }
+
+ @Override
+ protected void setValues() {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ nOfFileSpinner.setValue(wc.getNOfContestFiles());
+ nOfBonusFileSpinner.setValue(wc.getNOfContestBonusFiles());
+ }
+
+ @Override
+ protected void enableComponents() {
+ nOfFileSpinner.setEnabled(true);
+ nOfBonusFileSpinner.setEnabled(true);
+ }
+
+ @Override
+ protected void disableComponents() {
+ nOfFileSpinner.setEnabled(false);
+ nOfBonusFileSpinner.setEnabled(false);
+ }
+
+}
diff --git a/logo/src/xlogo/gui/welcome/settings/tabs/GlobalTab.java b/logo/src/xlogo/gui/welcome/settings/tabs/GlobalTab.java new file mode 100644 index 0000000..ecaef9c --- /dev/null +++ b/logo/src/xlogo/gui/welcome/settings/tabs/GlobalTab.java @@ -0,0 +1,230 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome.settings.tabs;
+
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.IOException;
+
+import javax.swing.GroupLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+
+import xlogo.gui.components.X4SComponent;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.WSManager;
+import xlogo.storage.global.GlobalConfig;
+/**
+ * @since June 10th 2014
+ * @author Marko
+ */
+public class GlobalTab extends X4SComponent {
+
+ private JPanel component;
+
+ private JCheckBox askPasswordCb;
+ private JLabel passwordLabel;
+ private JLabel retypeLabel;
+ private JPasswordField passwordField;
+ private JPasswordField retypeField;
+ private JButton save1;
+
+ private String authentification;
+
+ public GlobalTab() {
+ super();
+ }
+
+ public void authenticate(String authentification)
+ {
+ this.authentification = authentification;
+
+ boolean hasPw = authentification != null;
+ askPasswordCb.setSelected(hasPw);
+ showOrHidePw(hasPw);
+ passwordField.setText(authentification);
+ retypeField.setText(authentification);
+ }
+
+ public JComponent getComponent()
+ {
+ return component;
+ }
+
+ @Override
+ protected void initComponent()
+ {
+ component = new JPanel();
+
+ askPasswordCb = new JCheckBox("Protect these settings with a password.");
+ passwordLabel = new JLabel("Password");
+ retypeLabel = new JLabel("Retype Password");
+ passwordField = new JPasswordField();
+ retypeField = new JPasswordField();
+ save1 = new JButton("Save Password");
+ }
+
+ @Override
+ protected void layoutComponent()
+ {
+ passwordField.setMinimumSize(new Dimension(200, 25));
+ retypeField.setMinimumSize(new Dimension(200, 25));
+ passwordField.setMaximumSize(new Dimension(200, 25));
+ retypeField.setMaximumSize(new Dimension(200, 25));
+
+ component.add(askPasswordCb);
+ component.add(passwordLabel);
+ component.add(passwordField);
+ component.add(retypeLabel);
+ component.add(retypeField);
+ component.add(save1);
+
+ GroupLayout groupLayout = new GroupLayout(component);
+ component.setLayout(groupLayout);
+
+ groupLayout.setAutoCreateGaps(true);
+ groupLayout.setAutoCreateContainerGaps(true);
+
+ groupLayout.setVerticalGroup(
+ groupLayout.createSequentialGroup()
+ .addComponent(askPasswordCb)
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(passwordLabel)
+ .addComponent(passwordField))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(retypeLabel)
+ .addComponent(retypeField))
+ .addComponent(save1)
+ );
+
+ groupLayout.setHorizontalGroup(
+ groupLayout.createParallelGroup()
+ .addComponent(askPasswordCb)
+ .addGroup(groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(passwordLabel)
+ .addComponent(retypeLabel)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(passwordField)
+ .addComponent(retypeField)
+ )
+ )
+ .addComponent(save1)
+ );
+ }
+
+ @Override
+ protected void initEventListeners()
+ {
+ askPasswordCb.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ boolean selected = e.getStateChange() == ItemEvent.SELECTED;
+ showOrHidePw(selected);
+ passwordField.setText(null);
+ retypeField.setText(null);
+ if (!selected)
+ WSManager.getInstance().getGlobalConfigInstance().setNewPassword(authentification, null);
+ }
+ });
+
+ save1.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ try {
+ savePassword();
+ } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("ws.error.title"),
+ translate("ws.settings.cannot.store.pw") + e.toString());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void stopEventListeners()
+ {
+ super.stopEventListeners();
+
+ }
+
+ private void showOrHidePw(boolean show)
+ {
+ askPasswordCb.setSelected(show);
+ passwordLabel.setVisible(show);
+ passwordField.setVisible(show);
+ retypeLabel.setVisible(show);
+ retypeField.setVisible(show);
+ save1.setVisible(show);
+ }
+
+ private void savePassword() throws IOException
+ {
+ GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance();
+
+ if (askPasswordCb.isSelected())
+ {
+ String pw1 = new String(passwordField.getPassword());
+ String pw2 = new String(retypeField.getPassword());
+ if (pw1.equals(pw2))
+ {
+ gc.setNewPassword(authentification, pw1);
+ authentification = pw1;
+ gc.store();
+ }
+ else
+ {
+ DialogMessenger.getInstance().dispatchMessage(
+ translate("i.am.sorry"),
+ translate("ws.settings.pw.must.be.equal"));
+ }
+ }else // checkbox not selected
+ {
+ gc.setNewPassword(authentification, null);
+ authentification = null;
+ gc.store();
+ }
+ }
+
+ @Override
+ protected void setText()
+ {
+ askPasswordCb.setText(translate("ws.settings.require_password"));
+ passwordLabel.setText(translate("ws.settings.password"));
+ retypeLabel.setText(translate("ws.settings.retype.password"));
+ save1.setText(translate("ws.settings.save.password"));
+ }
+
+}
diff --git a/logo/src/xlogo/gui/welcome/settings/tabs/SyntaxHighlightingTab.java b/logo/src/xlogo/gui/welcome/settings/tabs/SyntaxHighlightingTab.java new file mode 100644 index 0000000..c5926f3 --- /dev/null +++ b/logo/src/xlogo/gui/welcome/settings/tabs/SyntaxHighlightingTab.java @@ -0,0 +1,288 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome.settings.tabs;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.GroupLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextPane;
+
+import xlogo.AppSettings;
+import xlogo.StyledDocument.DocumentLogo;
+import xlogo.gui.components.ColorStyleSelectionPanel;
+import xlogo.storage.WSManager;
+import xlogo.storage.workspace.SyntaxHighlightConfig;
+import xlogo.storage.workspace.WorkspaceConfig;
+
+public class SyntaxHighlightingTab extends AbstractWorkspacePanel{
+ private JPanel component;
+
+ private JLabel workspaceLabel;
+ private JComboBox workspaceSelection;
+ private ColorStyleSelectionPanel commentStyleSelection;
+ private ColorStyleSelectionPanel braceStyleSelection;
+ private ColorStyleSelectionPanel primitiveStyleSelection;
+ private ColorStyleSelectionPanel operandStyleSelection;
+ private JCheckBox activateHighlightingCheckBox;
+ private JLabel activateHighlightingLabel;
+ private JButton restoreDefaultsButton;
+ private DocumentLogo previewLogoDocument;
+ private JTextPane previewTextPane;
+
+ private ActionListener syntaxHighlightChangeListener;
+
+ public SyntaxHighlightingTab() {
+ super();
+ }
+
+ public JComponent getComponent()
+ {
+ return component;
+ }
+
+ protected void initComponent()
+ {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ //Font font = wc.getFont();
+ component = new JPanel();
+ workspaceLabel = new JLabel();
+ workspaceSelection = new JComboBox();
+ commentStyleSelection=new ColorStyleSelectionPanel(wc.getCommentColor(), wc.getCommentStyle(), translate("pref.highlight.comment"));
+ braceStyleSelection=new ColorStyleSelectionPanel(wc.getBraceColor(), wc.getBraceStyle(), translate("pref.highlight.parenthesis"));
+ primitiveStyleSelection=new ColorStyleSelectionPanel(wc.getPrimitiveColor(), wc.getPrimitiveStyle(), translate("pref.highlight.primitive"));
+ operandStyleSelection=new ColorStyleSelectionPanel(wc.getOperatorColor(), wc.getOperatorStyle(), translate("pref.highlight.operand"));
+
+ previewTextPane=new JTextPane();
+ activateHighlightingCheckBox = new JCheckBox();
+ activateHighlightingLabel=new JLabel();
+ restoreDefaultsButton=new JButton();
+
+ //activateHighlightingLabel.setFont(font);
+ //restoreDefaultsButton.setFont(font);
+ previewTextPane.setOpaque(true);
+ previewTextPane.setBackground(Color.white);
+ previewLogoDocument=new DocumentLogo();
+ previewTextPane.setDocument(previewLogoDocument);
+ previewLogoDocument.setColore_Parenthese(true);
+
+ populateWorkspaceList();
+ setValues();
+ }
+
+ protected void layoutComponent()
+ {
+ component.add(workspaceLabel);
+ component.add(workspaceSelection);
+ component.add(activateHighlightingCheckBox);
+ component.add(activateHighlightingLabel);
+ component.add(commentStyleSelection.getComponent());
+ component.add(primitiveStyleSelection.getComponent());
+ component.add(operandStyleSelection.getComponent());
+ component.add(braceStyleSelection.getComponent());
+ component.add(previewTextPane);
+ component.add(restoreDefaultsButton);
+
+ GroupLayout groupLayout = new GroupLayout(component);
+ component.setLayout(groupLayout);
+
+ groupLayout.setAutoCreateGaps(true);
+ groupLayout.setAutoCreateContainerGaps(true);
+
+ groupLayout.setVerticalGroup(
+ groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceLabel)
+ .addComponent(workspaceSelection))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(activateHighlightingLabel)
+ .addComponent(activateHighlightingCheckBox))
+ .addComponent(commentStyleSelection.getComponent())
+ .addComponent(primitiveStyleSelection.getComponent())
+ .addComponent(operandStyleSelection.getComponent())
+ .addComponent(braceStyleSelection.getComponent())
+ .addComponent(previewTextPane)
+ .addComponent(restoreDefaultsButton)
+ );
+ groupLayout.setHorizontalGroup(
+ groupLayout.createParallelGroup()
+ .addGroup(groupLayout.createSequentialGroup()
+ .addComponent(workspaceLabel)
+ .addComponent(workspaceSelection))
+ .addGroup(groupLayout.createSequentialGroup()
+ .addComponent(activateHighlightingLabel)
+ .addComponent(activateHighlightingCheckBox))
+ .addComponent(commentStyleSelection.getComponent())
+ .addComponent(primitiveStyleSelection.getComponent())
+ .addComponent(operandStyleSelection.getComponent())
+ .addComponent(braceStyleSelection.getComponent())
+ .addComponent(previewTextPane)
+ .addComponent(restoreDefaultsButton)
+ );
+ }
+
+ protected void setText()
+ {
+ workspaceLabel.setText(translate("ws.settings.workspace"));
+ previewTextPane.setText(translate("pref.highlight.example"));
+ commentStyleSelection.setTitle(translate("pref.highlight.comment"));
+ braceStyleSelection.setTitle(translate("pref.highlight.parenthesis"));
+ primitiveStyleSelection.setTitle(translate("pref.highlight.primitive"));
+ operandStyleSelection.setTitle(translate("pref.highlight.operand"));
+ activateHighlightingLabel.setText(translate("pref.highlight.enabled"));
+ restoreDefaultsButton.setText(translate("pref.highlight.init"));
+ previewTextPane.setText(translate("pref.highlight.example"));
+ }
+
+ @Override
+ protected void initEventListeners()
+ {
+ super.initEventListeners();
+ activateHighlightingCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ WSManager.getWorkspaceConfig().setSyntaxHighlightingEnabled(activateHighlightingCheckBox.isSelected());
+ }
+ });
+ restoreDefaultsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ SyntaxHighlightConfig syntaxStyles = new SyntaxHighlightConfig();
+ WSManager.getWorkspaceConfig().setSyntaxHighlightConfig(syntaxStyles);
+ setValues();
+ }
+ });
+ AppSettings.getInstance().addSyntaxHighlightStyleChangeListener(
+ syntaxHighlightChangeListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateSyntaxHighlightingPreview();
+ }
+ });
+
+ operandStyleSelection.addStyleChangeListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ wc.setOperandColor(operandStyleSelection.color());
+ wc.setOperandStyle(operandStyleSelection.style());
+ }
+ });
+
+ braceStyleSelection.addStyleChangeListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ wc.setBraceColor(braceStyleSelection.color());
+ wc.setBraceStyle(braceStyleSelection.style());
+ }
+ });
+
+ primitiveStyleSelection.addStyleChangeListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ wc.setPrimitiveColor(primitiveStyleSelection.color());
+ wc.setPrimitiveStyle(primitiveStyleSelection.style());
+ }
+ });
+
+ commentStyleSelection.addStyleChangeListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ wc.setCommentColor(commentStyleSelection.color());
+ wc.setCommentStyle(commentStyleSelection.style());
+ }
+ });
+ }
+
+ @Override
+ public void stopEventListeners()
+ {
+ super.stopEventListeners();
+ AppSettings.getInstance().removeSyntaxHighlightStyleChangeListener(syntaxHighlightChangeListener);
+
+ }
+
+ @Override
+ protected JComboBox getWorkspaceSelection() {
+ return workspaceSelection;
+ }
+
+ @Override
+ protected void setValues() {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ commentStyleSelection.setColorAndStyle(wc.getCommentColor(), wc.getCommentStyle());
+ braceStyleSelection.setColorAndStyle(wc.getBraceColor(), wc.getBraceStyle());
+ primitiveStyleSelection.setColorAndStyle(wc.getPrimitiveColor(), wc.getPrimitiveStyle());
+ operandStyleSelection.setColorAndStyle(wc.getOperatorColor(), wc.getOperatorStyle());
+
+ updateSyntaxHighlightingPreview();
+ }
+
+ protected void updateSyntaxHighlightingPreview()
+ {
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+
+ boolean isHighlightingEnabled = wc.isSyntaxHighlightingEnabled();
+ activateHighlightingCheckBox.setSelected(isHighlightingEnabled);
+ commentStyleSelection.setEnabled(isHighlightingEnabled);
+ primitiveStyleSelection.setEnabled(isHighlightingEnabled);
+ braceStyleSelection.setEnabled(isHighlightingEnabled);
+ operandStyleSelection.setEnabled(isHighlightingEnabled);
+ restoreDefaultsButton.setEnabled(isHighlightingEnabled);
+ previewLogoDocument.setColoration(isHighlightingEnabled);
+
+ previewLogoDocument.initStyles(
+ wc.getCommentColor(), wc.getCommentStyle(),
+ wc.getPrimitiveColor(), wc.getPrimitiveStyle(),
+ wc.getBraceColor(), wc.getBraceStyle(),
+ wc.getOperatorColor(), wc.getOperatorStyle());
+
+ previewTextPane.setText(translate("pref.highlight.example"));
+ }
+
+ @Override
+ protected void enableComponents() {
+
+ }
+
+ @Override
+ protected void disableComponents() {
+
+ }
+
+}
diff --git a/logo/src/xlogo/gui/welcome/settings/tabs/WorkspaceCreationPanel.java b/logo/src/xlogo/gui/welcome/settings/tabs/WorkspaceCreationPanel.java new file mode 100644 index 0000000..06f8ad6 --- /dev/null +++ b/logo/src/xlogo/gui/welcome/settings/tabs/WorkspaceCreationPanel.java @@ -0,0 +1,144 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome.settings.tabs;
+
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+import javax.swing.GroupLayout;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import xlogo.gui.components.X4SComponent;
+import xlogo.storage.WSManager;
+
+class WorkspaceCreationPanel extends X4SComponent
+{
+
+ private JPanel component;
+
+ public JLabel wsNameLabel;
+ public JLabel locationLabel;
+ public JTextField wsNameField;
+ public JTextField locationField;
+ public JButton openFilechooserBtn;
+
+ public JComponent getComponent()
+ {
+ return component;
+ }
+
+ @Override
+ protected void initComponent() {
+ component = new JPanel();
+
+ wsNameLabel = new JLabel("Workspace Name");
+ locationLabel = new JLabel("Location");
+ wsNameField = new JTextField();
+ locationField = new JTextField();
+ openFilechooserBtn = new JButton("Browse");
+
+ locationField.setText(WSManager.getInstance().getGlobalConfigInstance().getLocation().toString());
+ locationField.setEditable(false);
+ }
+
+ @Override
+ protected void layoutComponent() {
+ component.add(wsNameLabel);
+ component.add(locationLabel);
+ component.add(wsNameField);
+ component.add(locationField);
+ component.add(openFilechooserBtn);
+
+ locationField.setMinimumSize(new Dimension(250,15));
+
+ GroupLayout groupLayout = new GroupLayout(component);
+ component.setLayout(groupLayout);
+
+ groupLayout.setAutoCreateContainerGaps(true);
+ groupLayout.setAutoCreateGaps(true);
+
+ groupLayout.setVerticalGroup(groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(wsNameLabel)
+ .addComponent(wsNameField)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(locationLabel)
+ .addComponent(locationField)
+ .addComponent(openFilechooserBtn)
+ )
+ );
+
+ groupLayout.setHorizontalGroup(groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(wsNameLabel)
+ .addComponent(locationLabel)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(wsNameField)
+ .addGroup(groupLayout.createSequentialGroup()
+ .addComponent(locationField)
+ .addComponent(openFilechooserBtn))
+ )
+ );
+
+ }
+
+ @Override
+ protected void initEventListeners()
+ {
+ openFilechooserBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ File location = getUserSelectedDirectory();
+ if (location != null)
+ locationField.setText(location.toString());
+ }
+ });
+ }
+
+ @Override
+ public void stopEventListeners()
+ {
+ super.stopEventListeners();
+
+ }
+
+ @Override
+ protected void setText()
+ {
+ wsNameLabel.setText(translate("ws.creation.panel.name"));
+ locationLabel.setText(translate("ws.creation.panel.location"));
+ openFilechooserBtn.setText(translate("ws.creation.panel.browse"));
+ }
+}
\ No newline at end of file diff --git a/logo/src/xlogo/gui/welcome/settings/tabs/WorkspaceTab.java b/logo/src/xlogo/gui/welcome/settings/tabs/WorkspaceTab.java new file mode 100644 index 0000000..3b0e8a4 --- /dev/null +++ b/logo/src/xlogo/gui/welcome/settings/tabs/WorkspaceTab.java @@ -0,0 +1,537 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.gui.welcome.settings.tabs;
+
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.GroupLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import xlogo.Logo;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.WSManager;
+import xlogo.storage.global.GlobalConfig;
+import xlogo.storage.workspace.Language;
+import xlogo.storage.workspace.NumberOfBackups;
+import xlogo.storage.workspace.WorkspaceConfig;
+
+public class WorkspaceTab extends AbstractWorkspacePanel{
+
+ JPanel component;
+
+ JLabel workspaceLabel;
+ JLabel wsLocationLabel;
+ JLabel wsLanguageLabel;
+ JLabel wsBackupLabel;
+ JLabel userLabel;
+
+ JButton addWorkspaceBtn;
+ JButton addUserBtn;
+
+ JButton removeWorkspaceBtn;
+ JButton removeUserBtn;
+
+ JButton importWorkspaceBtn;
+ JButton importUserBtn;
+
+ JComboBox workspaceSelection;
+ JComboBox userSelection;
+ JLabel wsLocation;
+ JFileChooser wsLocationChooser;
+ JComboBox languageSelection;
+ JComboBox nOfBackupsSelecteion;
+ JCheckBox userCreatable;
+
+ public WorkspaceTab() {
+ super();
+ }
+
+ @Override
+ public JComponent getComponent()
+ {
+ return component;
+ }
+
+ @Override
+ protected JComboBox getWorkspaceSelection() {
+ return workspaceSelection;
+ }
+
+ protected void initComponent()
+ {
+ component = new JPanel();
+
+ workspaceLabel = new JLabel("Workspace: ");
+ wsLocationLabel = new JLabel("Location: ");
+ wsLanguageLabel = new JLabel("Language: ");
+ wsBackupLabel = new JLabel("Number of Backups: ");
+ userLabel = new JLabel("User: ");
+
+ addWorkspaceBtn = new JButton("Add");
+ addUserBtn = new JButton("Add");
+
+ removeWorkspaceBtn = new JButton("Remove");
+ removeUserBtn = new JButton("Remove");
+
+ importWorkspaceBtn = new JButton("Import");
+ importUserBtn = new JButton("Import");
+
+ workspaceSelection = new JComboBox();
+ userSelection = new JComboBox();
+ wsLocation = new JLabel();
+ wsLocationChooser = new JFileChooser();
+ languageSelection = new JComboBox(Language.values());
+ nOfBackupsSelecteion = new JComboBox(NumberOfBackups.values());
+ userCreatable = new JCheckBox("Allow the users to create new user accounts?");
+
+ populateWorkspaceList();
+ setValues();
+ }
+
+ protected void layoutComponent()
+ {
+ workspaceSelection.setMinimumSize(new Dimension(150,25));
+ workspaceSelection.setMaximumSize(new Dimension(150,25));
+ userSelection.setMinimumSize(new Dimension(150,25));
+ userSelection.setMaximumSize(new Dimension(150,25));
+ languageSelection.setMinimumSize(new Dimension(150,25));
+ languageSelection.setMaximumSize(new Dimension(150,25));
+ nOfBackupsSelecteion.setMinimumSize(new Dimension(75,25));
+ nOfBackupsSelecteion.setMaximumSize(new Dimension(75,25));
+
+ component.add(workspaceLabel);
+ component.add(wsLocationLabel);
+ component.add(wsLanguageLabel);
+ component.add(wsBackupLabel);
+ component.add(userLabel);
+
+ component.add(addWorkspaceBtn);
+ component.add(addUserBtn);
+ component.add(removeWorkspaceBtn);
+ component.add(removeUserBtn);
+ component.add(importWorkspaceBtn);
+ component.add(importUserBtn);
+
+ component.add(workspaceSelection);
+ component.add(userSelection);
+ component.add(wsLocation);
+ component.add(languageSelection);
+ component.add(nOfBackupsSelecteion);
+
+ GroupLayout groupLayout = new GroupLayout(component);
+ component.setLayout(groupLayout);
+
+ groupLayout.setAutoCreateGaps(true);
+ groupLayout.setAutoCreateContainerGaps(true);
+
+ groupLayout.setVerticalGroup(
+ groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceLabel)
+ .addComponent(workspaceSelection)
+ .addComponent(addWorkspaceBtn)
+ .addComponent(removeWorkspaceBtn)
+ .addComponent(importWorkspaceBtn))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(wsLocationLabel)
+ .addComponent(wsLocation))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(userLabel)
+ .addComponent(userSelection)
+ .addComponent(addUserBtn)
+ .addComponent(removeUserBtn)
+ .addComponent(importUserBtn))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(wsLanguageLabel)
+ .addComponent(languageSelection))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(wsBackupLabel)
+ .addComponent(nOfBackupsSelecteion))
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(userCreatable))
+ );
+
+ groupLayout.setHorizontalGroup(
+ groupLayout.createParallelGroup()
+ .addGroup(groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceLabel)
+ .addComponent(userLabel)
+ .addComponent(wsLocationLabel)
+ .addComponent(wsLanguageLabel)
+ .addComponent(wsBackupLabel)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addGroup(groupLayout.createSequentialGroup()
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(workspaceSelection)
+ .addComponent(userSelection)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(addWorkspaceBtn)
+ .addComponent(addUserBtn)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(removeWorkspaceBtn)
+ .addComponent(removeUserBtn)
+ )
+ .addGroup(groupLayout.createParallelGroup()
+ .addComponent(importWorkspaceBtn)
+ .addComponent(importUserBtn)
+ )
+ )
+ .addComponent(wsLocation)
+ .addComponent(languageSelection)
+ .addComponent(nOfBackupsSelecteion)
+ )
+ )
+ .addComponent(userCreatable)
+ );
+ }
+
+ @Override
+ protected void initEventListeners()
+ {
+ /*
+ * WORKSPACE [SELECT in super class]; ADD; REMOVE; IMPORT
+ */
+ super.initEventListeners();
+
+ addWorkspaceBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ addWorkspace();
+ }
+ }).run();
+ }
+ });
+
+ removeWorkspaceBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ deleteWorkspace();
+ }
+ }).run();
+ }
+ });
+
+ importWorkspaceBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ importWorkspace();
+ }
+ }).run();
+ }
+ });
+
+ /*
+ * USER ADD; REMOVE; IMPORT
+ */
+
+ addUserBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ addUser();
+ }
+ }).run();
+ }
+ });
+
+ removeUserBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ removeUser();
+ }
+ }).run();
+ }
+ });
+
+ importUserBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ importUser();
+ }
+ }).run();
+ }
+ });
+
+ /*
+ * LANGUAGE
+ */
+
+ languageSelection.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ new Thread(new Runnable() {
+ public void run() {
+ Language lang = (Language) languageSelection.getSelectedItem();
+ changeLanguage(lang);
+ }
+ }).run();
+ }
+ });
+
+ /*
+ * BACKUP VERSIONS
+ */
+
+ nOfBackupsSelecteion.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ NumberOfBackups n = (NumberOfBackups) nOfBackupsSelecteion.getSelectedItem();
+ WSManager.getInstance().getWorkspaceConfigInstance().setNumberOfBackups(n);
+ }
+ });
+
+ /*
+ * USER CREATION
+ */
+
+ userCreatable.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent arg0) {
+ boolean isAllowed = userCreatable.isSelected();
+ WSManager.getInstance().getWorkspaceConfigInstance().setAllowUserCreation(isAllowed);
+ }
+ });
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * WORKSPACE : ADD, REMOVE, IMPORT
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * On creation or when a workspace is set, the input elements must be set according to the current workspace properties.
+ */
+ protected void setValues()
+ {
+ WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance();
+ GlobalConfig gc = WSManager.getInstance().getGlobalConfigInstance();
+
+ // location text
+ if (wc == null)
+ {
+ String wsName = (String) workspaceSelection.getSelectedItem();
+ wsLocation.setText(gc.getWorkspaceDirectory(wsName).toString());
+ wsLocationLabel.setText(Logo.messages.getString("ws.settings.damaged"));
+ disableComponents();
+ return;
+ }else if(wc.isVirtual())
+ wsLocation.setText(Logo.messages.getString("ws.settings.virtual.ws.not.stored"));
+ else
+ wsLocation.setText(wc.getLocation().toString());
+
+ // user list
+ populateUserList();
+
+ // Language
+ languageSelection.setSelectedItem(wc.getLanguage());
+ changeLanguage(wc.getLanguage());
+
+ // Backups
+ nOfBackupsSelecteion.setSelectedItem(wc.getNumberOfBackups());
+
+ // User Creation
+ userCreatable.setSelected(wc.isUserCreationAllowed());
+ }
+
+ /**
+ * Disable controls that depend on the workspace and that cannot be used with a virtual workspace
+ * or a workspace that could not be loaded
+ */
+ protected void disableComponents()
+ {
+ WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance();
+ removeWorkspaceBtn.setEnabled(wc == null);
+ userSelection.setEnabled(false);
+ addUserBtn.setEnabled(false);
+ removeUserBtn.setEnabled(false);
+ importUserBtn.setEnabled(false);
+ nOfBackupsSelecteion.setEnabled(false);
+ userCreatable.setEnabled(false);
+ }
+
+ @Override
+ /**
+ * Enable if Workspace is successfully entered and if it is not virtual.
+ */
+ protected void enableComponents()
+ {
+ removeWorkspaceBtn.setEnabled(true);
+ userSelection.setEnabled(true);
+ addUserBtn.setEnabled(true);
+ removeUserBtn.setEnabled(true);
+ importUserBtn.setEnabled(true);
+ nOfBackupsSelecteion.setEnabled(true);
+ userCreatable.setEnabled(true);
+ }
+
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * USER : ADD, REMOVE, IMPORT
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+ private void populateUserList()
+ {
+ WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance();
+ String[] users = wc.getUserList();
+ userSelection.setModel(new DefaultComboBoxModel(users));
+ String lastUser = wc.getLastActiveUser();
+ userSelection.setSelectedItem(lastUser);
+ }
+
+ private void addUser()
+ {
+ String username = getUserText(Logo.messages.getString("ws.settings.enter.user.name"), Logo.messages.getString("ws.settings.create.new.user"));
+
+ if ((username == null) || (username.length() == 0))
+ return;
+
+ if (WSManager.getInstance().getWorkspaceConfigInstance().existsUserLogically(username))
+ {
+ DialogMessenger.getInstance().dispatchMessage(
+ Logo.messages.getString("ws.error.title"),
+ Logo.messages.getString("ws.settings.user.exists.already"));
+ return;
+ }
+
+ WSManager.getInstance().createUser(username);
+ populateUserList();
+ }
+
+ private void removeUser()
+ {
+ WSManager wsManager = WSManager.getInstance();
+ WorkspaceConfig wc = wsManager.getWorkspaceConfigInstance();
+
+ String username = (String) userSelection.getSelectedItem();
+ if (username == null)
+ return;
+ String userDirectory = wc.getUserDirectroy(username).toString();
+ String message =
+ Logo.messages.getString("ws.settings.want.delete.dir.1")
+ + userDirectory
+ + Logo.messages.getString("ws.settings.want.delete.dir.1");
+
+ boolean ans = getUserYesOrNo(message, Logo.messages.getString("ws.settings.remove.user"));
+
+ WSManager.getInstance().deleteUser(username, ans);
+
+ populateUserList();
+ }
+
+ private void importUser()
+ {
+ File dir = getUserSelectedDirectory();
+ if (dir == null)
+ return;
+
+ if (!WSManager.isUserDirectory(dir))
+ {
+ DialogMessenger.getInstance().dispatchMessage(
+ Logo.messages.getString("i.am.sorry"),
+ dir.toString() + Logo.messages.getString("ws.settings.not.legal.user.dir"));
+ return;
+ }
+
+ String newName = dir.getName();
+ WorkspaceConfig wc = WSManager.getWorkspaceConfig();
+ if (dir.equals(wc.getUserDirectroy(newName)))
+ {
+ DialogMessenger.getInstance().dispatchMessage("This user was already in the list.");
+ return;
+ }
+
+ while (wc.existsUserLogically(newName) || !Storable.checkLegalName(newName))
+ {
+ String msg = wc.existsUserLogically(newName) ?
+ "The user name " + newName + " already exists. Please choose a new name."
+ : "The chosen name contains illegal characters. Please choose a new name.";
+
+ newName = getUserText(msg, "Name Conflict");
+ if (newName == null)
+ return;
+ }
+
+ try {
+ WSManager.getInstance().importUser(dir, newName);
+ } catch (Exception e) {
+ DialogMessenger.getInstance().dispatchMessage(
+ Logo.messages.getString("ws.error.title"),
+ Logo.messages.getString("ws.settings.could.not.import.user") + e.toString());
+ }
+ populateUserList();
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * START : LANGUAGE
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ private void changeLanguage(Language lang) {
+ WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance();
+
+ if (wc.getLanguage() != lang)
+ {
+ wc.setLanguage(lang);
+ }
+ }
+
+ protected void setText()
+ {
+ workspaceLabel.setText(Logo.messages.getString("ws.settings.workspace"));
+ wsLocationLabel.setText(Logo.messages.getString("ws.settings.location"));
+ wsLanguageLabel.setText(Logo.messages.getString("ws.settings.language"));
+ wsBackupLabel.setText(Logo.messages.getString("ws.settings.backups"));
+ userLabel.setText(Logo.messages.getString("ws.settings.user"));
+ addWorkspaceBtn.setText(Logo.messages.getString("ws.settings.add"));
+ addUserBtn.setText(Logo.messages.getString("ws.settings.add"));
+ removeWorkspaceBtn.setText(Logo.messages.getString("ws.settings.remove"));
+ removeUserBtn.setText(Logo.messages.getString("ws.settings.remove"));
+ importWorkspaceBtn.setText(Logo.messages.getString("ws.settings.import"));
+ importUserBtn.setText(Logo.messages.getString("ws.settings.import"));
+ userCreatable.setText(Logo.messages.getString("ws.settings.enable.user.account.creation"));
+ }
+}
diff --git a/logo/src/xlogo/interfaces/BasicFileContainer.java b/logo/src/xlogo/interfaces/BasicFileContainer.java new file mode 100644 index 0000000..5e12d22 --- /dev/null +++ b/logo/src/xlogo/interfaces/BasicFileContainer.java @@ -0,0 +1,129 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.interfaces;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface BasicFileContainer
+{
+ public String[] getFileNames();
+
+ public String readFile(String name); // Content
+
+ public String getLastEditedFileName();
+
+ public void createFile(String fileName) throws IOException;
+
+ public String makeUniqueFileName(String base);
+
+ public boolean existsFile(String name);
+
+ public void writeFileText(String fileName, String content) throws IOException;
+
+ public void storeFile(String fileName) throws IOException;
+
+ public void importFile(File filePath) throws IOException;
+
+ public void exportFile(String fileName, File dest) throws IOException;
+
+ public void exportFile(String fileName, File location, String targetName) throws IOException;
+
+ public void renameFile(String oldName, String newName);
+
+ public void removeFile(String fileName);
+
+ public void eraseAll();
+
+ public void openFile(String fileName);
+
+ public void closeFile(String fileName);
+
+ public String getOpenFileName();
+
+ public boolean isFilesListEditable();
+
+ //public boolean hasErrors(String fileName);
+
+ public void addFileListener(FileContainerChangeListener listener);
+
+ public void removeFileListener(FileContainerChangeListener listener);
+
+ public interface FileContainerChangeListener
+ {
+ /**
+ * After the file has been opened
+ * @param file name
+ */
+ public void fileOpened(String file);
+
+ /**
+ * After the file has been closed
+ * @param file name
+ */
+ public void fileClosed(String file);
+
+ /**
+ * After the file has been added
+ * @param file name
+ */
+ public void fileAdded(String file);
+
+ /**
+ * After the file has been removed
+ * @param file name
+ */
+ public void fileRemoved(String file);
+
+ /**
+ * After a file has been renamed
+ * @param oldName
+ * @param newName
+ */
+ public void fileRenamed(String oldName, String newName);
+
+ /**
+ * Applies to the whole container.
+ * @param editEnabled
+ */
+ public void editRightsChanged(boolean editEnabled);
+
+ /**
+ * After a file is updated,
+ * or after a context switch.
+ * @param fileName
+ */
+ //public void errorsDetected(String fileName);
+
+ /**
+ * Only fired if errors existed before a file was updated.
+ * @param fileName
+ */
+ //public void errorsCorrected(String fileName);
+ }
+}
diff --git a/logo/src/xlogo/interfaces/BroadcasterErrorFileContainer.java b/logo/src/xlogo/interfaces/BroadcasterErrorFileContainer.java new file mode 100644 index 0000000..ceb4bcb --- /dev/null +++ b/logo/src/xlogo/interfaces/BroadcasterErrorFileContainer.java @@ -0,0 +1,40 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.interfaces;
+
+import xlogo.interfaces.ErrorDetector.FileErrorCollector;
+
+/**
+ * Used only for files list component...
+ * @author Marko
+ *
+ */
+public interface BroadcasterErrorFileContainer extends BasicFileContainer, MessageBroadcaster, FileErrorCollector
+{
+
+}
diff --git a/logo/src/xlogo/interfaces/ErrorDetector.java b/logo/src/xlogo/interfaces/ErrorDetector.java new file mode 100644 index 0000000..01b59dc --- /dev/null +++ b/logo/src/xlogo/interfaces/ErrorDetector.java @@ -0,0 +1,104 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.interfaces;
+
+import java.util.Collection;
+import java.util.Map;
+
+import xlogo.kernel.userspace.ProcedureErrorMessage;
+import xlogo.kernel.userspace.procedures.Procedure;
+
+public interface ErrorDetector
+{
+ public boolean hasErrors();
+
+ public Collection<ProcedureErrorMessage> getAllErrors();
+
+ public interface FileErrorCollector extends ErrorDetector
+ {
+ public boolean hasErrors(String fileName);
+
+ public Collection<String> getAllErroneousFiles();
+
+ public void addErrorListener(ErrorListener listener);
+
+ public void removeErrorListener(ErrorListener listener);
+
+ public interface ErrorListener
+ {
+ /**
+ * This event is fired as soon as one or more errors are detected in a file
+ * @param fileName
+ */
+ public void errorsDetected(String fileName);
+
+ /**
+ * This event is fired as soon as all errors are removed from a document
+ * @param fileName
+ */
+ public void allErrorsCorrected(String fileName);
+ }
+ }
+
+ public interface AmbiguityDetector extends ErrorDetector
+ {
+ /**
+ * @return Files whose procedures conflict with procedures of other files.
+ */
+ public Collection<String> getAllConflictingFiles();
+
+ /**
+ * @param fileName
+ * @return whether the specified file conflicts with some other file
+ */
+ boolean hasAmbiguousProcedures(String fileName);
+
+ /**
+ * @param name
+ * @return whether the specified procedure name is defined in more than one file.
+ */
+ public boolean isProcedureAmbiguous(String procedureName);
+
+
+ void addAmbiguityListener(AmbiguityListener listener);
+
+ void removeAmbiguityListener(AmbiguityListener listener);
+
+
+ public interface AmbiguityListener
+ {
+ public void ambiguityDetected(String procedureName, Map<String, Procedure> fileToProcedure);
+
+ /**
+ * @param procedureName
+ * @param fileName When a single file has lost ambiguity for that specific procedure (might still have other ambiguities)
+ */
+ public void ambiguityResolved(String procedureName, String fileName);
+ }
+ }
+}
diff --git a/logo/src/xlogo/interfaces/MessageBroadcaster.java b/logo/src/xlogo/interfaces/MessageBroadcaster.java new file mode 100644 index 0000000..8021a36 --- /dev/null +++ b/logo/src/xlogo/interfaces/MessageBroadcaster.java @@ -0,0 +1,39 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.interfaces;
+
+public interface MessageBroadcaster
+{
+ public void addBroadcastListener(MessageListener listener);
+ public void removeBroadcastListener(MessageListener listener);
+
+ public interface MessageListener
+ {
+ public void messageEvent(String source, String message);
+ }
+}
diff --git a/logo/src/xlogo/interfaces/ProcedureMapper.java b/logo/src/xlogo/interfaces/ProcedureMapper.java new file mode 100644 index 0000000..32e73bb --- /dev/null +++ b/logo/src/xlogo/interfaces/ProcedureMapper.java @@ -0,0 +1,54 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.interfaces;
+
+import java.util.Collection;
+
+public interface ProcedureMapper
+{
+ public Collection<String> getAllProcedureNames();
+
+ public Collection<String> getAllProcedureNames(String fileName);
+
+ public String getProcedureOwner(String procedureName);
+
+ public void addProcedureMapListener(ProcedureMapListener listener);
+
+ public void removeProcedureMapListener(ProcedureMapListener listener);
+
+ public interface ProcedureMapListener
+ {
+ public void ownerRenamed(String oldName, String newName);
+
+ public void defined(String fileName, Collection<String> procedures);
+ public void defined(String fileName, String procedure);
+
+ public void undefined(String fileName, Collection<String> procedures);
+ public void undefined(String fileName, String procedure);
+ }
+}
diff --git a/logo/src/xlogo/interfaces/X4SModeSwitcher.java b/logo/src/xlogo/interfaces/X4SModeSwitcher.java new file mode 100644 index 0000000..4ddc248 --- /dev/null +++ b/logo/src/xlogo/interfaces/X4SModeSwitcher.java @@ -0,0 +1,82 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.interfaces;
+
+import java.io.IOException;
+
+/**
+ * X4S USER SPACE MODES<br>
+ * 1. User Mode : [lowest priority] (default, a.k.a. root context) cannot be killed, only 1 <br>
+ * 2. Contest Mode : [medium priority] only 0..1 can exist. If this is killed, all current network contexts are killed too.<br>
+ * 3. Network Mode : [highest priority] 0..n can exist, stacked on each other, 1 active at a time.
+ * <p>
+ * General Policy: <br>
+ * 1. Only one context is active at a time. <br>
+ * 2. Priority = if there exists a context which has higher priority, then this context's symbol tables and properties are active. <br>
+ * 3. If there exist multiple contexts of the same priority, then the last created is active. <br>
+ *
+ * @author Marko Zivkovic
+ */
+public interface X4SModeSwitcher
+{
+ public String getSerializedContext();
+
+ public boolean isNetworkMode();
+
+ public boolean isRecordMode();
+
+ public boolean isUserMode();
+
+
+ public void pushNetworkMode(String serializedContext) throws IllegalArgumentException;
+
+ public void popNetworkMode();
+
+
+ public void startRecordMode(String[] fileNames) throws IllegalArgumentException, IllegalStateException, IOException;
+
+ public void stopRecordMode();
+
+
+ public void addModeChangedListener(ModeChangeListener listener);
+
+ public void removeModeChangedListener(ModeChangeListener listener);
+
+
+ public interface ModeChangeListener
+ {
+ public void recordModeStarted();
+
+ public void recordModeStopped();
+
+ public void networkModeStarted();
+
+ public void networkModeStopped();
+ }
+
+}
diff --git a/logo/src/xlogo/kernel/Affichage.java b/logo/src/xlogo/kernel/Affichage.java new file mode 100644 index 0000000..7da2120 --- /dev/null +++ b/logo/src/xlogo/kernel/Affichage.java @@ -0,0 +1,207 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo Description : XLogo is an interpreter for the Logo programming + * language + * + * @author Loïc Le Coq + */ +package xlogo.kernel; + +import java.util.Stack; +import java.util.HashMap; +import java.awt.event.*; + +import javax.swing.SwingUtilities; + +import xlogo.Application; +import xlogo.messages.async.history.HistoryMessenger; +import xlogo.utils.Utils; +import xlogo.MemoryChecker; +import xlogo.Logo; + +// Ce thread gère l'animation de la tortue pendant l'exécution +/** + * This Thread is responsible of the turtle animation. + * This animation has to be executed in a separated thread, else it will block + * the event dispatcher thread + */ +public class Affichage extends Thread +{ + public static boolean execution_lancee = false; + private boolean pause = false; + private Application cadre; + private StringBuffer instruction; + private Souris souris = new Souris(); + private MemoryChecker memoryChecker = null; + + public Affichage() + { + } + + public Affichage(Application cadre, StringBuffer instruction) + { + this.cadre = cadre; + this.instruction = instruction; + } + + class Souris extends MouseAdapter + { // Si on déplace les Scrollbar pendant + // le dessin + public Souris() + { + } // Ceci permet d'interrompre momentanément l'exécution + + public void mousePressed(MouseEvent e) + { + pause = true; + } + + public void mouseReleased(MouseEvent e) + { + pause = false; + } + } + + public void run() + { + // currentThread().setPriority(Thread.MIN_PRIORITY); + SwingUtilities.invokeLater(new Runnable(){ + public void run() + { + cadre.setCommandLine(false);// la ligne de commandes + // n'est plus active + } + }); + execution_lancee = true; + cadre.getDrawPanel().active_souris(); // On active les événements souris + // sur + // la zone de dessin + cadre.scrollArea.getVerticalScrollBar().addMouseListener(souris); + cadre.scrollArea.getHorizontalScrollBar().addMouseListener(souris); + try + { + cadre.setCar(-1); + cadre.error = false; + Interprete.operande = Interprete.operateur = Interprete.drapeau_ouvrante = false; + cadre.getKernel().getInstructionBuffer().clear(); + Interprete.calcul = new Stack<String>(); + Interprete.nom = new Stack<String>(); + Interprete.locale = new HashMap<String, String>(); + Interprete.en_cours = new Stack<String>(); + memoryChecker = new MemoryChecker(cadre); + memoryChecker.start(); + boolean b = true; + while (b) + { + String st = cadre.getKernel().execute(instruction); + if (!st.equals("")) + throw new LogoError(Logo.messages.getString("error.whattodo") + " " + st + " ?"); + if (Interprete.actionInstruction.length() == 0) + b = false; + else + { + instruction = Interprete.actionInstruction; + Interprete.actionInstruction = new StringBuffer(); + } + } + } + catch (LogoError e) + { + // if (st.equals("siwhile")) st=Logo.messages.getString("tantque"); + while (!Interprete.en_cours.isEmpty() && Interprete.en_cours.peek().equals("(")) + Interprete.en_cours.pop(); + if (!cadre.error & !Interprete.en_cours.isEmpty()) + { + HistoryMessenger.getInstance().dispatchError( + Logo.messages.getString("dans") + " " + Interprete.en_cours.pop() + ", " + + Logo.messages.getString("line") + " " + getLineNumber() + ":\n"); + } + if (!cadre.error) + HistoryMessenger.getInstance().dispatchError(Utils.SortieTexte(e.getMessage()) + "\n"); + abortExecution(); + } + cadre.setCommandLine(true); + if (!cadre.viewer3DVisible()) + cadre.focus_Commande(); + execution_lancee = false; + memoryChecker.kill(); + cadre.error = false; + cadre.scrollArea.getVerticalScrollBar().removeMouseListener(souris); + cadre.scrollArea.getHorizontalScrollBar().removeMouseListener(souris); + } + + private void abortExecution() + { + cadre.focus_Commande(); + cadre.error = true; + Interprete.calcul = new Stack<String>(); + cadre.getKernel().getInstructionBuffer().clear(); + Primitive.stackLoop = new Stack<LoopProperties>(); + } + + private int getLineNumber() + { + String string = Interprete.lineNumber; + // System.out.println("bb"+string+"bb"); + if (string.equals("")) + string = cadre.getKernel().getInstructionBuffer().toString(); + // System.out.println("cc"+string+"cc"); + int id = string.indexOf("\\l"); + if (id != -1) + { + String lineNumber = ""; + int i = id + 2; + char c = string.charAt(i); + while (c != ' ') + { + lineNumber += c; + i++; + c = string.charAt(i); + } + // System.out.println(lineNumber); + return Integer.parseInt(lineNumber); + } + return 1; + } + + protected boolean isOnPause() + { + return pause; + } + + /** + * @param b + * @uml.property name="pause" + */ + public void setPause(boolean b) + { + pause = b; + } +} diff --git a/logo/src/xlogo/kernel/DrawPanel.java b/logo/src/xlogo/kernel/DrawPanel.java new file mode 100644 index 0000000..269a0c0 --- /dev/null +++ b/logo/src/xlogo/kernel/DrawPanel.java @@ -0,0 +1,2917 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Point; + +import javax.swing.JViewport; + +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Transparency; + +import javax.vecmath.Color3f; + +import java.awt.FontMetrics; +import java.awt.Stroke; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.QuadCurve2D; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextLayout; +import java.awt.Dimension; +import java.awt.geom.PathIterator; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.CropImageFilter; +import java.awt.image.ReplicateScaleFilter; +import java.awt.image.FilteredImageSource; + +import com.sun.j3d.utils.geometry.Text2D; + +import javax.swing.ImageIcon; +import javax.swing.SwingUtilities; + +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; + +import javax.swing.JPanel; +import javax.imageio.ImageIO; +import javax.media.j3d.*; +import javax.vecmath.Vector3d; +import javax.vecmath.Matrix3d; +import javax.vecmath.Point3d; + +import java.util.Stack; +import java.util.Set; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.Vector; +import java.awt.event.*; + +import xlogo.Application; +import xlogo.storage.WSManager; +import xlogo.storage.user.DrawQuality; +import xlogo.storage.user.PenShape; +import xlogo.storage.user.UserConfig; +import xlogo.utils.Utils; +import xlogo.Logo; +import xlogo.kernel.grammar.LogoNumber; +import xlogo.kernel.grammar.LogoType; +import xlogo.kernel.grammar.LogoTypeNull; +import xlogo.kernel.gui.*; +import xlogo.kernel.perspective.*; +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ + public class DrawPanel extends JPanel implements MouseMotionListener,MouseListener { + public static final LogoTypeNull nullType=new LogoTypeNull(); + private static final long serialVersionUID = 1L; + public Turtle tortue; + public Turtle[] tortues; + + /** + * When a turtle is active on screen, its number is added to this stack + * @uml.property name="tortues_visibles" + * @uml.associationEnd multiplicity="(0 -1)" elementType="java.lang.String" + */ + public Stack<String> tortues_visibles; + + /** + * this int indicates the window mode, default 0 + */ + protected static int WINDOW_MODE = 0; + /** + * WINDOW MODE: 0 <br> + * Turtles can go out the drawing area + */ + protected static final int WINDOW_CLASSIC=0; + /** + * WRAP MODE: 1 <br> + * Turtles can go out the drawing area and reappear on the other side + */ + protected static final int WINDOW_WRAP=1; + /** + * CLOSE MODE: 2 <br> + * Turtles can't go out the drawing area + */ + protected static final int WINDOW_CLOSE=2; + /** + * Perspective MODE <br> + * The screen is a projection of the 3D universe + */ + protected static final int WINDOW_3D=3; + + /** Boolean for animation mode */ + public static boolean classicMode=true; // true si classique false si animation + /** Animation mode: */ + public final static boolean MODE_ANIMATION=false; + /** Classic mode */ + public final static boolean MODE_CLASSIC=true; + + /** + * default predefined colors + */ + public static final Color[] defaultColors={Color.BLACK,Color.RED,Color.GREEN,Color.YELLOW,Color.BLUE, + Color.MAGENTA,Color.CYAN,Color.WHITE,Color.GRAY,Color.LIGHT_GRAY,new Color(128,0,0),new Color(0,128,0), + new Color(0,0,128),new Color(255,128,0),Color.PINK,new Color(128,0,255),new Color(153,102,0)}; + + + /** + * The id for the drawing font (with primitive label) + * @uml.property name="police_etiquette" + */ + protected int police_etiquette; + /** + * The default drawing area color + * @uml.property name="couleurfond" + */ + private Color couleurfond = Color.white; + private Shape shape=null; + private Line2D line; + private Rectangle2D rec; + private Application cadre; + /** This Image is used for Buffering the drawing*/ + public static BufferedImage dessin; + /** + * Graphics of the BufferedImage dessin + * @uml.property name="g" + */ + private Graphics2D g; + /** The scale for the zoom*/ + public static double zoom=1; + + + /** + * All Gui Objects on the drawing area are stored in the GuiMap gm + * @uml.property name="gm" + * @uml.associationEnd multiplicity="(1 1)" + */ + private GuiMap gm; + /** + * The Stroke for the triangle turtle + * @uml.property name="crayon_triangle" + */ + private BasicStroke crayon_triangle = new BasicStroke(1); + /** + * Tools for 3D Mode + * @uml.property name="w3d" + * @uml.associationEnd + */ + private World3D w3d=null; + /** + * Boolean that indicates if the interpreter is recording polygon in 3D Mode + */ + protected static int record3D=0; + protected final static int record3D_NONE=0; + protected final static int record3D_POLYGON=1; + protected final static int record3D_LINE=2; + protected final static int record3D_POINT=3; + protected final static int record3D_TEXT=4; + + /** + * Boolean that indicates if the interpreter is recording polygon in 2D Mode + */ + private static int record2D=0; + private final static int record2D_NONE=0; + private final static int record2D_POLYGON=1; + private Vector<Point2D.Double> stackTriangle; + + + protected static Element3D poly; + + private double[] coords; + private double oldx; + private double oldy; + private double x1; + private double y1; + private double x2; + private double y2; + // Were used for clipping + // private double nx,ny,vx,vy,factor,length; + // private GeneralPath gp; + // private Arc2D clipArc; + private Arc2D arc; + /** + * Button number when user click on the drawing area + * @uml.property name="bouton_souris" + */ + private int bouton_souris=0; // Numéro du bouton de souris appuyé sur la zone de dessin + /** + * Last coords for last mouse event + * @uml.property name="possouris" + */ + private String possouris="[ 0 0 ] "; // Coordonnées du point du dernier événement souris + + /** + * Notify if a mouse event has occured + * @uml.property name="lissouris" + */ + private boolean lissouris=false; //Indique si un événement souris est intervenu depuis le debut du programme + /** + * The rectangular selection zone + * @uml.property name="selection" + */ + private Rectangle selection; + /** + * Color for the rectangular selection + * @uml.property name="colorSelection" + */ + private Color colorSelection; + /** + * The First clicked point when the rectangular selection is created + * @uml.property name="origine" + */ + Point origine; + public DrawPanel(Application cadre){ + this.gm= cadre.getKernel().getWorkspace().getGuiMap(); + setLayout(null); + this.setPreferredSize(new Dimension( + (int)(WSManager.getUserConfig().getImageWidth()*zoom), + (int)(WSManager.getUserConfig().getImageHeight()*zoom))); + this.cadre=cadre; + addMouseListener(this); + addMouseMotionListener(this); + initGraphics(); + } + /** + * This method is used to draw for primitive "forward" + * @param arg LogoType which represents the number of steps to move + */ + protected LogoType av(LogoType number){ + if (number.isException()) return number; + LogoNumber ln=(LogoNumber)number; + return av(ln.getValue()); + + } + /** + * This method is used to draw for primitive "backward" + * @param arg LogoType which represents the number of steps to move + */ + protected LogoType re(LogoType number){ + if (number.isException()) return number; + LogoNumber ln=(LogoNumber)number; + return av(-ln.getValue()); + + } + /** + * This method is used to draw for primitive "right" + * @param arg LogoType which represents the number of steps to rotate + */ + protected LogoType td(LogoType number){ + if (number.isException()) return number; + LogoNumber ln=(LogoNumber)number; + return td(ln.getValue()); + + } /** + * This method is used to draw for primitive "left" + * @param arg LogoType which represents the number of steps to rotate + */ + protected LogoType tg(LogoType number){ + if (number.isException()) return number; + LogoNumber ln=(LogoNumber)number; + return td(-ln.getValue()); + + } + + /** + * This method is used to draw for primitive "forward" and "backward" + * @param arg Number of steps + */ + protected LogoType av(double arg) { + // Graphics2D g=(Graphics2D)dessin.getGraphics(); + + oldx = tortue.corX; + oldy = tortue.corY; + if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_CLASSIC) { //mode fenetre + montrecacheTortue(false); + + tortue.corX = tortue.corX + arg + * Math.cos(tortue.angle); + tortue.corY = tortue.corY - arg + * Math.sin(tortue.angle); + if (tortue.isPenDown()) { + g.setStroke(tortue.stroke); // TODO Marko : fix penerase problem. TODO also for other ops, circle etc + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + if (null==line) line=new Line2D.Double(); + /* if (null==gp) gp=new GeneralPath(); + else gp.reset();*/ + if (oldx < tortue.corX){ + x1=oldx;y1=oldy;x2=tortue.corX;y2=tortue.corY; + } + if (oldx>tortue.corX){ + x2=oldx;y2=oldy;x1=tortue.corX;y1=tortue.corY; + } + else if (oldx==tortue.corX){ + if (oldy<tortue.corY){ + x2=oldx;y2=oldy;x1=tortue.corX;y1=tortue.corY; + } + else{ + x1=oldx;y1=oldy;x2=tortue.corX;y2=tortue.corY; + } + } + + line.setLine(x1,y1,x2,y2); + + /* + // perpendicular vector + nx=y1-y2; + ny=x2-x1; + length=Math.sqrt(nx*nx+ny*ny); + if (length!=0){ + factor=(1+tortue.getPenWidth())/length; + vx=x2-x1; + vy=y2-y1; + gp.moveTo((float)(x1-vx*factor-nx*factor), + (float)(y1-vy*factor-ny*factor)); + gp.lineTo((float)(x1-vx*factor+nx*factor), + (float)(y1-vy*factor+ny*factor)); + gp.lineTo((float)(x2+vx*factor+nx*factor), + (float)(y2+vy*factor+ny*factor)); + gp.lineTo((float)(x2+vx*factor-nx*factor), + (float)(y2+vy*factor-ny*factor)); + gp.lineTo((float)(x1-vx*factor-nx*factor), + (float)(y1-vy*factor-ny*factor)); + } + else{ + float width=tortue.getPenWidth()+0.5f; + gp.moveTo((float)(x1-width), + (float)(y1-width)); + gp.lineTo((float)(x1+width), + (float)(y1-width)); + gp.lineTo((float)(x1+width), + (float)(y1+width)); + gp.lineTo((float)(x1-width), + (float)(y1+width)); + gp.lineTo((float)(x1-width), + (float)(y1-width)); + } + shape=gp;*/ + tryRecord2DMode(tortue.corX,tortue.corY); + g.draw(line); + //if (!tortue.isVisible()) + clip(); + // g.dispose(); + } + montrecacheTortue(true); + } else if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_WRAP) { //mode enroule + trace_enroule(arg, oldx, oldy); + } else if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_CLOSE) { //mode clos + try { + trace_ferme(oldx, oldy, arg); + } catch (LogoError e) { + } + } + else if (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_3D){ + montrecacheTortue(false); + tortue.X=tortue.X+arg*tortue.getRotationMatrix()[0][1]; + tortue.Y=tortue.Y+arg*tortue.getRotationMatrix()[1][1]; + tortue.Z=tortue.Z+arg*tortue.getRotationMatrix()[2][1]; + + double tmp[]=new double[3]; + tmp[0]=tortue.X; + tmp[1]=tortue.Y; + tmp[2]=tortue.Z; + + tmp=this.toScreenCoord(tmp,true); + tortue.corX = tmp[0]; + tortue.corY = tmp[1]; + + + if (tortue.isPenDown()) { + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + if (null==line) line=new Line2D.Double(); + + if (oldx < tortue.corX){ + x1=oldx;y1=oldy;x2=tortue.corX;y2=tortue.corY; + } + if (oldx>tortue.corX){ + x2=oldx;y2=oldy;x1=tortue.corX;y1=tortue.corY; + } + else if (oldx==tortue.corX){ + if (oldy<tortue.corY){ + x2=oldx;y2=oldy;x1=tortue.corX;y1=tortue.corY; + } + else{ + x1=oldx;y1=oldy;x2=tortue.corX;y2=tortue.corY; + } + } + + line.setLine(x1,y1,x2,y2); + + g.draw(line); + clip(); + } + montrecacheTortue(true); + } + return DrawPanel.nullType; + } + + /** + * This method is used for drawing with primitive "right" or "left" + * @param arg The angle to rotate + */ + protected LogoType td(double arg) { +// System.out.println(tortue.angle); + if (tortue.isVisible()) + montrecacheTortue(false); + if (!enabled3D()){ + tortue.heading = ((tortue.heading + arg) % 360 + 360) % 360; + tortue.angle = Math.toRadians(90 - tortue.heading); + } + else{ + tortue.setRotationMatrix(w3d.multiply(tortue.getRotationMatrix(),w3d.rotationZ(-arg))); + double[] tmp=w3d.rotationToEuler(tortue.getRotationMatrix()); + tortue.heading=tmp[2]; + tortue.roll=tmp[1]; + tortue.pitch=tmp[0]; + } + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande = false; + + return DrawPanel.nullType; + } + /** + * This method is used for drawing with primitive "rightroll" or "leftroll" + * @param arg + */ + protected void rightroll(double arg) { +// System.out.println(tortue.angle); + if (tortue.isVisible()) + montrecacheTortue(false); + if (enabled3D()){ + tortue.setRotationMatrix(w3d.multiply(tortue.getRotationMatrix(),w3d.rotationY(-arg))); + double[] tmp=w3d.rotationToEuler(tortue.getRotationMatrix()); + tortue.heading=tmp[2]; + tortue.roll=tmp[1]; + tortue.pitch=tmp[0]; + } + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande = false; + } + /** + * This method is used for drawing with primitive "uppitch" or "downpitch" + * @param arg + */ + protected void uppitch(double arg) { +// System.out.println(tortue.angle); + if (tortue.isVisible()) + montrecacheTortue(false); + if (enabled3D()){ + tortue.setRotationMatrix(w3d.multiply(tortue.getRotationMatrix(),w3d.rotationX(arg))); + double[] tmp=w3d.rotationToEuler(tortue.getRotationMatrix()); + tortue.heading=tmp[2]; + tortue.roll=tmp[1]; + tortue.pitch=tmp[0]; + } + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande = false; + } + /** + * This method set the turtle's Roll + * @param arg The new roll + */ + protected void setRoll(double arg){ + if (tortue.isVisible()) + montrecacheTortue(false); + tortue.roll=arg; + tortue.setRotationMatrix(w3d.EulerToRotation(-tortue.roll, tortue.pitch, -tortue.heading)); + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande=false; + } + /** + * This method set the turtle's heading + * @param arg The new heading + */ + protected void setHeading(double arg){ + if (tortue.isVisible()) + montrecacheTortue(false); + tortue.heading=arg; + tortue.setRotationMatrix(w3d.EulerToRotation(-tortue.roll, tortue.pitch, -tortue.heading)); + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande=false; + } + /** + * This method set the turtle's pitch + * @param arg The new pitch + */ + protected void setPitch(double arg){ + if (tortue.isVisible()) + montrecacheTortue(false); + tortue.pitch=arg; + tortue.setRotationMatrix(w3d.EulerToRotation(-tortue.roll, tortue.pitch, -tortue.heading)); + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande=false; + } + /** + * + * This method set the turtle's orientation + * @param arg The new orientation + * @throws LogoError If the list doesn't contain three numbers + */ + protected void setOrientation(String arg) throws LogoError{ + initCoords(); + if (tortue.isVisible()) + montrecacheTortue(false); + extractCoords(arg,Utils.primitiveName("3d.setorientation")); + tortue.roll = coords[0]; + tortue.pitch = coords[1]; + tortue.heading = coords[2]; + tortue.setRotationMatrix(w3d.EulerToRotation(-tortue.roll, tortue.pitch, -tortue.heading)); + if (tortue.isVisible()) + montrecacheTortue(true); + Interprete.operande=false; + } + /** + * Primitive "origine" + */ + protected void origine(){ // primitive origine + try { + if (!enabled3D()) + fpos("0 0"); + else fpos("0 0 0"); + } catch (LogoError e) { + } + if (tortue.isVisible()) + montrecacheTortue(false); + tortue.heading = 0; + tortue.angle = Math.PI / 2; + tortue.roll=0; + tortue.pitch=0; + if (enabled3D()) + tortue.setRotationMatrix(w3d.EulerToRotation(-tortue.roll, tortue.pitch, -tortue.heading)); + if (tortue.isVisible()) + montrecacheTortue(true); + } + + + /** + * Primitive distance + * @param liste The coords + * @param nom + * @return The distance from the turtle position to this point + * @throws LogoError If bad format list + */ + protected double distance(String liste) throws LogoError { + + initCoords(); + extractCoords(liste,Utils.primitiveName("distance")); + double distance; + if (!enabled3D()){ + coords=this.toScreenCoord(coords,false); + distance = Math.sqrt(Math.pow(tortue.corX - coords[0], 2) + + Math.pow(tortue.corY - coords[1], 2)); + } + else distance= Math.sqrt(Math.pow(tortue.X - coords[0], 2) + + Math.pow(tortue.Y - coords[1], 2)+Math.pow(tortue.Z - coords[2], 2)); + return distance; + } + protected double[] vers3D(String liste) throws LogoError{ + double[] tmp=new double [3]; + initCoords(); + extractCoords(liste,Utils.primitiveName("vers")); + tmp[0]=coords[0]-tortue.X; + tmp[1]=coords[1]-tortue.Y; + tmp[2]=coords[2]-tortue.Z; + double length=Math.sqrt(Math.pow(tmp[0],2)+Math.pow(tmp[1],2)+Math.pow(tmp[2],2)); + if (length==0) return tmp; + tmp[0]=tmp[0]/length; + tmp[1]=tmp[1]/length; + tmp[2]=tmp[2]/length; + double heading=Math.acos(tmp[1]); + double f=Math.sin(heading); + double tr_x=-tmp[0]/f; + double tr_y=-tmp[2]/f; + double roll=Math.atan2(tr_y, tr_x); + tmp[0]=-Math.toDegrees(roll); + tmp[1]=0; + tmp[2]=-Math.toDegrees(heading); + for (int i=0;i<3;i++){ + if (tmp[i]<0) tmp[i]+=360; + } + return tmp; + } + + /** + * Primitive towards in 2D MODE + * @param liste the coordinate for the point + * @return the rotation angle + * @throws LogoError if Bad format List + */ + protected double vers2D(String liste) throws LogoError{ + initCoords(); + extractCoords(liste,Utils.primitiveName("vers")); + double angle; + coords=this.toScreenCoord(coords, false); + if (tortue.corY == coords[1]) { + if (coords[0] > tortue.corX) + angle = 90; + else if (coords[0] == tortue.corX) + angle = 0; + else + angle = 270; + } + else if (tortue.corX == coords[0]) { + if (tortue.corY > coords[1]) + angle = 0; + else + angle = 180; + } + else { + angle = Math.toDegrees(Math.atan(Math + .abs(coords[0] - tortue.corX) + / Math.abs(tortue.corY - coords[1]))); + // System.out.println(coords[0] - tortue.corX+" "+Math.abs(tortue.corY - coords[1])+" "+angle); + if (coords[0] > tortue.corX && coords[1] > tortue.corY) + angle = 180 - angle; // 2eme quadrant + else if (coords[0] < tortue.corX && coords[1] > tortue.corY) + angle = 180 + angle; // 3eme quadrant + else if (coords[0] < tortue.corX && coords[1] < tortue.corY) + angle = 360 - angle; // 4eme quadrant + } + return angle; + } + /** + * Draw with the primitive "setposition" in 2D mode or 3D + * @param liste The list with the coordinates to move + * @throws LogoError If the coordinates are invalid + */ + protected void fpos(String liste) throws LogoError { + initCoords(); + oldx = tortue.corX; + oldy = tortue.corY; + extractCoords(liste,Utils.primitiveName("drawing.fpos")); + montrecacheTortue(false); + if (enabled3D()) { + tortue.X = coords[0]; + tortue.Y = coords[1]; + tortue.Z = coords[2]; + } + coords=toScreenCoord(coords,true); + + tortue.corX=coords[0]; + tortue.corY=coords[1]; + if (tortue.isPenDown()) { + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + if (null==line) line=new Line2D.Double(); + if (oldx < tortue.corX){ + x1=oldx;y1=oldy;x2=tortue.corX;y2=tortue.corY; + } + if (oldx>tortue.corX){ + x2=oldx;y2=oldy;x1=tortue.corX;y1=tortue.corY; + } + else if (oldx==tortue.corX){ + if (oldy<tortue.corY){ + x2=oldx;y2=oldy;x1=tortue.corX;y1=tortue.corY; + } + else{ + x1=oldx;y1=oldy;x2=tortue.corX;y2=tortue.corY; + } + } + line.setLine(x1,y1,x2,y2); + tryRecord2DMode(tortue.corX,tortue.corY); + g.draw(line); + clip(); + } + montrecacheTortue(true); + } + public void drawEllipseArc(double xAxis,double yAxis, double angleRotation,double xCenter,double yCenter, double angleStart, double angleExtent){ + montrecacheTortue(false); + arc=new Arc2D.Double(-xAxis,-yAxis,2*xAxis,2*yAxis,angleStart,angleExtent,Arc2D.Double.OPEN); + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + double tmpx=WSManager.getUserConfig().getImageWidth()/2+xCenter; + double tmpy=WSManager.getUserConfig().getImageHeight()/2-yCenter; + g.translate(tmpx, tmpy); + g.rotate(-angleRotation); + g.draw(arc); + g.rotate(angleRotation); + g.translate(-tmpx, -tmpy); + /* if (null==clipArc) clipArc=new Arc2D.Double(); + clipArc.setArcByCenter(tortue.corX,tortue.corY, + rayon+2+tortue.getPenWidth(),0,360, Arc2D.OPEN);*/ + clip(); + montrecacheTortue(true); // on efface la tortue si elle st visible + } + /** + * This method draw an arc on the drawing area + * @param rayon The radius + * @param pangle Starting angle + * @param fangle End angle + * @throws LogoError + */ + protected void arc(double rayon, double pangle, double fangle) throws LogoError { + // Put fangle and pangle between 0 and 360 + fangle = ((90 - fangle) % 360); + pangle = ((90 - pangle) % 360); + if (fangle<0) fangle+=360; + if (pangle<0) pangle+=360; + // Calculate angle extend + double angle=pangle-fangle; + if (angle<0) angle+=360; + montrecacheTortue(false); + if (null==arc) arc=new Arc2D.Double(); + if (!enabled3D()){ + if (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_WRAP) centers=new Vector<Point2D.Double>(); + arc2D(tortue.corX,tortue.corY,rayon,fangle,angle); + + /* if (null==gp) gp=new GeneralPath(); + else gp.reset(); + gp.moveTo((float)(tortue.corX-rayon-tortue.getPenWidth()), + (float)(tortue.corY-rayon-tortue.getPenWidth()); + gp.lineTo((float)(tortue.corX-rayon-tortue.getPenWidth()), + (float)(tortue.corY-rayon-tortue.getPenWidth())); + gp.lineTo((float)(tortue.corX-rayon-tortue.getPenWidth()), + (float)(tortue.corY-rayon-tortue.getPenWidth())); + gp.lineTo((float)(tortue.corX-rayon-tortue.getPenWidth()), + (float)(tortue.corY-rayon-tortue.getPenWidth())); + gp.lineTo((float)(tortue.corX-rayon-tortue.getPenWidth()), + (float)(tortue.corY-rayon-tortue.getPenWidth()));*/ +/* if (null==rec) rec=new Rectangle2D.Double(); + rec.setRect(tortue.corX-rayon-tortue.getPenWidth(), + tortue.corY-rayon-tortue.getPenWidth(), + 2*(rayon+tortue.getPenWidth()),2*(rayon+tortue.getPenWidth()));*/ + clip(); + + } + else{ + arcCircle3D(rayon,fangle,angle); + } + montrecacheTortue(true); + } + private void arc2D(double x, double y, double radius,double fangle, double angle){ + arc.setArcByCenter(x,y,radius, + fangle,angle, Arc2D.OPEN); + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + g.draw(arc); + clip(); + + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + if (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_WRAP){ + if (x+radius>w&& x<=w){ + pt=new Point2D.Double(-w+x,y); + if (! centers.contains(pt)) { + centers.add(pt); + arc2D(-w+x,y,radius,fangle,angle); + } + } + if (x-radius<0&& x>=0){ + pt=new Point2D.Double(w+x,y); + if (! centers.contains(pt)) { + centers.add(pt); + arc2D(w+x,y,radius,fangle,angle); + } + } + if (y-radius<0&& y>=0){ + pt=new Point2D.Double(x,h+y); + if (! centers.contains(pt)) { + centers.add(pt); + arc2D(x,h+y,radius,fangle,angle); + } + } + if (y+radius>h&&y<=h){ + pt=new Point2D.Double(x,-h+y); + if (! centers.contains(pt)) { + centers.add(pt); + arc2D(x,-h+y,radius,fangle,angle); + } + } + } + } + + + private void arcCircle3D(double radius,double angleStart,double angleExtent) throws LogoError{ + if (null==arc) arc=new Arc2D.Double(); + arc.setArcByCenter(0,0,radius, + angleStart,angleExtent, Arc2D.OPEN); + Shape s=transformShape(arc); + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + g.draw(s); + if (DrawPanel.record3D==DrawPanel.record3D_LINE||DrawPanel.record3D==DrawPanel.record3D_POLYGON){ + recordArcCircle3D(radius,angleStart,angleExtent); + } + } + + + /** + * + * returns the color for the pixel "ob" + * @param liste: The list containing the coordinates of the pixel + * @return Color of this pixel + * @throws LogoError If the list doesn't contain coordinates + */ + protected Color guessColorPoint(String liste) throws LogoError { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + initCoords(); + extractCoords(liste,Utils.primitiveName("tc")); + coords=toScreenCoord(coords,false); + int couleur = -1; + int x=(int)coords[0]; + int y=(int)coords[1]; + if (0 < x && x < w && 0 < y && y < h) { + couleur = DrawPanel.dessin.getRGB(x, y); + } + return new Color(couleur); + } + /** + * This method draw a circle from the turtle position on the drawing area + * @param radius The radius of the circle + * @throws LogoError + */ + protected void circle(double radius) throws LogoError { + montrecacheTortue(false); + if (null==arc) arc=new Arc2D.Double(); + if (!enabled3D()){ + if (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_WRAP) centers=new Vector<Point2D.Double>(); + circle2D(tortue.corX,tortue.corY,radius); + /* if (null==clipArc) clipArc=new Arc2D.Double(); + clipArc.setArcByCenter(tortue.corX,tortue.corY, + rayon+2+tortue.getPenWidth(),0,360, Arc2D.OPEN);*/ + } + else{ + circle3D(radius); + } + montrecacheTortue(true); // on efface la tortue si elle st visible + } + /** + * This method draws a circle in 2D mode in WRAP mode, makes recursion to draw all circle part on the screen + * @param x x circle center + * @param y y circle center + * @param circle radius + * @uml.property name="pt" + */ + private Point2D.Double pt; + /** + * @uml.property name="centers" + */ + private Vector <Point2D.Double> centers; + private void circle2D(double x,double y, double radius){ + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + arc.setArcByCenter(x,y,radius, + 0,360, Arc2D.OPEN); + + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + g.draw(arc); + clip(); + if (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_WRAP){ + if (x+radius>w&& x<=w){ + pt=new Point2D.Double(-w+x,y); + if (! centers.contains(pt)) { + centers.add(pt); + circle2D(-w+x,y,radius); + } + } + if (x-radius<0&& x>=0){ + pt=new Point2D.Double(w+x,y); + if (! centers.contains(pt)) { + centers.add(pt); + circle2D(w+x,y,radius); + } + } + if (y-radius<0&& y>=0){ + pt=new Point2D.Double(x,h+y); + if (! centers.contains(pt)) { + centers.add(pt); + circle2D(x,h+y,radius); + } + } + if (y+radius>h&&y<=h){ + pt=new Point2D.Double(x,-h+y); + if (! centers.contains(pt)) { + centers.add(pt); + circle2D(x,-h+y,radius); + } + } + } + } + + /** + * used for drawing with primitive "dot" + * @param liste The list with the dot coordinates + * @throws LogoError If the list is invalid coordinates + */ + protected void point(String liste) throws LogoError { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + initCoords(); + extractCoords(liste,Utils.primitiveName("drawing.point")); + coords=toScreenCoord(coords,true); +// System.out.println(coords[0]+" "+coords[1]+" "+h+" "+w); + if (coords[0]>0 && coords[1]>0 && coords[0]<w && coords[1] < h) { + if (tortue.isPenReverse()) { + g.setColor(couleurfond); + g.setXORMode(tortue.couleurcrayon); + + } else { + g.setColor(tortue.couleurcrayon); + g.setPaintMode(); + } + if (rec==null) rec=new Rectangle2D.Double(); + // High quality + if (uc.getQuality()==DrawQuality.HIGH){ + double width=tortue.getPenWidth(); + rec.setRect(coords[0]-width+0.5,coords[1]-width+0.5, + 2*width,2*width); + } + // Normal or Low Quality + else{ + // penWidth is 2k or 2k+1?? + int intWidth=(int)(2*tortue.getPenWidth()+0.5); + if (intWidth%2==1){ + double width=tortue.getPenWidth()-0.5; +// System.out.println(coords[0]+" "+coords[1]); + rec.setRect(coords[0]-width,coords[1]-width, + 2*width+1,2*width+1); + } + else { + double width=tortue.getPenWidth(); + rec.setRect(coords[0]-width,coords[1]-width, + 2*width,2*width); + } + } + if (uc.getPenShape()==PenShape.SQUARE){ // MAKE ENUM + g.fill(rec); + } + else if (uc.getPenShape()==PenShape.OVAL){ + if (null==arc) arc=new Arc2D.Double(); + arc.setArcByCenter(coords[0],coords[1],0,0,360,Arc2D.OPEN); + g.draw(arc); + } + clip(); + } + } + + + + /** + * @throws LogoError + * + */ + private void circle3D(double radius) throws LogoError{ + + // In camera world, + // the circle is the intersection of + // - a plane with the following equation: ax+by+cz+d=0 <-> f(x,y,z)=0 + // - and a sphere with the following equation: (x-tx)^2+(y-ty)^2+(z-tz)^2=R^2 <-> g(x,y,z)=0 + // I found the cone equation resolving f(x/lambda,y/lambda,z/lambda)=0=g(x/lambda,y/lambda,z/lambda) + + double[] v=new double[3]; + for(int i=0;i<3;i++){ + v[i]=tortue.getRotationMatrix()[i][2]; + } + v[0]+=w3d.xCamera; + v[1]+=w3d.yCamera; + v[2]+=w3d.zCamera; + w3d.toCameraWorld(v); + // Now v contains coordinates of a normal vector to the plane in camera world coordinates + double a=v[0]; + double b=v[1]; + double c=v[2]; + + // We convert the turtle coordinates + v[0]=tortue.X; + v[1]=tortue.Y; + v[2]=tortue.Z; + w3d.toCameraWorld(v); + + double x=v[0]; + double y=v[1]; + double z=v[2]; + // We calculate the number d for the plane equation + double d=-a*x-b*y-c*z; + + // We have to work with Bigdecimal because of precision problems + + BigDecimal[] big=new BigDecimal[6]; + BigDecimal bx=new BigDecimal(x); + BigDecimal by=new BigDecimal(y); + BigDecimal bz=new BigDecimal(z); + BigDecimal ba=new BigDecimal(a); + BigDecimal bb=new BigDecimal(b); + BigDecimal bc=new BigDecimal(c); + BigDecimal bd=new BigDecimal(d); + BigDecimal deux=new BigDecimal("2"); + BigDecimal screenDistance=new BigDecimal(w3d.screenDistance); + BigDecimal bradius=new BigDecimal(String.valueOf(radius)); + + // Now we calculate the coefficient for the conic ax^2+bxy+cy^2+dx+ey+f=0 + // Saved in an array + + // lambda=(x*x+y*y+z*z-radius*radius); + BigDecimal lambda=bx.pow(2).add(by.pow(2)).add(bz.pow(2)).subtract(bradius.pow(2)); + + // x^2 coeff + // d*d+2*d*x*a+a*a*lambda; + big[0]=bd.pow(2).add(bd.multiply(bx).multiply(ba).multiply(deux)).add(ba.pow(2).multiply(lambda)); + // xy coeff + // 2*d*x*b+2*d*y*a+2*a*b*lambda; + big[1]=deux.multiply(bd).multiply(bx).multiply(bb).add(deux.multiply(bd).multiply(by).multiply(ba)).add(deux.multiply(ba).multiply(bb).multiply(lambda)); + // y^2 coeff + // d*d+2*d*y*b+b*b*lambda; + big[2]=bd.pow(2).add(bd.multiply(by).multiply(bb).multiply(deux)).add(bb.pow(2).multiply(lambda)); + // x coeff + // 2*w3d.screenDistance*(d*x*c+d*z*a+lambda*a*c); + big[3]=deux.multiply(screenDistance).multiply(bd.multiply(bx).multiply(bc).add(bd.multiply(bz).multiply(ba)).add(lambda.multiply(ba).multiply(bc))); + // y coeff + // 2*w3d.screenDistance*(d*y*c+d*z*b+lambda*b*c); + big[4]=deux.multiply(screenDistance).multiply(bd.multiply(by).multiply(bc).add(bd.multiply(bz).multiply(bb)).add(lambda.multiply(bb).multiply(bc))); + // Numbers + // Math.pow(w3d.screenDistance,2)*(d*d+2*d*z*c+lambda*c*c); + big[5]=screenDistance.pow(2).multiply(bd.pow(2).add(deux.multiply(bd).multiply(bz).multiply(bc)).add(lambda.multiply(bc.pow(2)))); + new Conic(this,big); + if (DrawPanel.record3D==DrawPanel.record3D_LINE||DrawPanel.record3D==DrawPanel.record3D_POLYGON){ + recordArcCircle3D(radius,0,360); + } + } + /** + * This method records this circle in the polygon's List + * @param radius The circle's radius + * @param angleStart The starting Angle + * @param angleExtent The angle for the sector + * @throws LogoError + */ + public void recordArcCircle3D(double radius,double angleStart,double angleExtent) throws LogoError{ + double[][] d=tortue.getRotationMatrix(); + Matrix3d m=new Matrix3d(d[0][0],d[0][1],d[0][2],d[1][0],d[1][1],d[1][2],d[2][0],d[2][1],d[2][2]); + // Vector X + Point3d v1=new Point3d(radius/1000,0,0); + Transform3D t=new Transform3D(m,new Vector3d(),1); + t.transform(v1); + // Vector Y + Point3d v2=new Point3d(0,radius/1000,0); + t.transform(v2); + + // Turtle position + Point3d pos=new Point3d(tortue.X/1000,tortue.Y/1000,tortue.Z/1000); + int indexMax=(int)angleExtent; + if (indexMax!=angleExtent) indexMax+=2; + else indexMax+=1; + if (null!=DrawPanel.poly&&DrawPanel.poly.getVertexCount()>1) + DrawPanel.poly.addToScene(); + if (DrawPanel.record3D==DrawPanel.record3D_POLYGON) { + DrawPanel.poly=new ElementPolygon(cadre.getViewer3D()); + DrawPanel.poly.addVertex(pos, tortue.couleurcrayon); + } + else { + DrawPanel.poly=new ElementLine(cadre.getViewer3D(), cadre.getKernel().getActiveTurtle().getPenWidth()); + } + + for(int i=0;i<indexMax-1;i++){ + Point3d tmp1=new Point3d(v1); + tmp1.scale(Math.cos(Math.toRadians(angleStart+i))); + Point3d tmp2=new Point3d(v2); + tmp2.scale(Math.sin(Math.toRadians(angleStart+i))); + tmp1.add(tmp2); + tmp1.add(pos); + DrawPanel.poly.addVertex(tmp1, tortue.couleurcrayon); + } + Point3d tmp1=new Point3d(v1); + tmp1.scale(Math.cos(Math.toRadians(angleStart+angleExtent))); + Point3d tmp2=new Point3d(v2); + tmp2.scale(Math.sin(Math.toRadians(angleStart+angleExtent))); + tmp1.add(tmp2); + tmp1.add(pos); + DrawPanel.poly.addVertex(tmp1, tortue.couleurcrayon); + } + +/** + * Load an image and draw it on the drawing area + * @param image The image to draw + */ + protected void chargeimage(BufferedImage image) { + if (tortue.isVisible()) + montrecacheTortue(false); + g.setPaintMode(); + g.translate(tortue.corX, tortue.corY); + g.rotate(-tortue.angle); + g.drawImage(image, null, 0,0); + g.rotate(tortue.angle); + g.translate(-tortue.corX, -tortue.corY); + + clip(); +// repaint(); +/* if (null==rec) rec=new Rectangle2D.Double(); + rec.setRect(tortue.corX,tortue.corY, + image.getWidth(),image.getHeight());*/ + if (tortue.isVisible()) + montrecacheTortue(true); + } + /** + * To guess the length before going out the drawing area in WRAP mode + * @param mini The minimum distance before leaving + * @param maxi The maximum distance before leaving + * @param oldx The X turtle location + * @param oldy The Y turtle location + * @return the number of steps (Recursive dichotomy) + */ + private double trouve_longueur(double mini, double maxi, double oldx, double oldy) { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + // renvoie la longueur dont on peut encore avancer + if (Math.abs(maxi - mini) < 0.5){ + return (mini);} + else { + double milieu = (mini + maxi) / 2; + double nx = oldx + milieu * Math.cos(tortue.angle); + double ny = oldy - milieu * Math.sin(tortue.angle); + if (nx < 0 || nx > w|| ny < 0 || ny > h) + return trouve_longueur(mini, milieu, oldx, oldy); + else + return trouve_longueur(milieu, maxi, oldx, oldy); + } + } +/** + * This method is used for drawing with primitive forward, backward in WRAP MODE + * @param arg the length to forward + * @param oldx X position + * @param oldy Y position + */ + private void trace_enroule(double arg, double oldx, double oldy) { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + boolean re = false; + if (arg < 0) { + re = true; + } + double diagonale=Math.sqrt(Math.pow(w,2)+Math.pow(h,2))+1; + double longueur; + if (re) + longueur = trouve_longueur(0, -diagonale, oldx, oldy); + else + longueur = trouve_longueur(0, diagonale, oldx, oldy); +// System.out.println(diagonale+" "+oldx+" "+oldy); + while (Math.abs(longueur) < Math.abs(arg)) { + // System.out.println(Math.abs(longueur)+" "+Math.abs(arg)); + arg -= longueur; + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_CLASSIC; + av(longueur); + //System.out.println(Math.abs(longueur)+" "+Math.abs(arg)); + if (cadre.error) + break; //permet d'interrompre avec le bouton stop + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_WRAP; + if (uc.getTurtleSpeed() != 0) { + try { + Thread.sleep(uc.getTurtleSpeed() * 5); + } catch (InterruptedException e) { + } + } + if (tortue.isVisible()) + this.montrecacheTortue(false); + if (re) tortue.heading=(tortue.heading+180)%360; + if (tortue.corX > w-1 + && (tortue.heading < 180 && tortue.heading != 0)) { + tortue.corX = 0; + if (tortue.corY > h-1 + && (tortue.heading > 90 && tortue.heading < 270)) + tortue.corY = 0; + else if (tortue.corY < 1 + && (tortue.heading < 90 || tortue.heading > 270)) + tortue.corY = h; + } else if (tortue.corX < 1 && tortue.heading > 180) { + tortue.corX = w; + if (tortue.corY > h-1 + && (tortue.heading > 90 && tortue.heading < 270)) + tortue.corY = 0; + else if (tortue.corY < 1 + && (tortue.heading < 90 || tortue.heading > 270)) + tortue.corY = h; + } else if (tortue.corY > h-1) + tortue.corY = 0; + else if (tortue.corY < 1) + tortue.corY = h; + if (re) tortue.heading=(tortue.heading+180)%360; + if (tortue.isVisible()) + this.montrecacheTortue(true); + if (re) + longueur = trouve_longueur(0, -diagonale, tortue.corX, + tortue.corY); + else + longueur = trouve_longueur(0, diagonale, tortue.corX, + tortue.corY); + } + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_CLASSIC; + if (!cadre.error) + av(arg); + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_WRAP; + } +/** + * This method is used for drawing with primitive forward, backward in CLOSE MODE + * @param oldx X position + * @param oldy Y position + * @param arg The length to forward + * @throws LogoError + */ + private void trace_ferme(double oldx, double oldy, double arg) throws LogoError { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + boolean re = false; + double longueur; + double diagonale=Math.sqrt(Math.pow(w,2)+Math.pow(h,2))+1; + if (arg < 0) + re = true; + if (re) + longueur = trouve_longueur(0, -diagonale, oldx, oldy); + else + longueur = trouve_longueur(0, diagonale, oldx, oldy); + if (Math.abs(longueur) < Math.abs(arg)) + throw new LogoError(Logo.messages + .getString("erreur_sortie1") + + "\n" + + Logo.messages.getString("erreur_sortie2") + + Math.abs((int) (longueur))); + else { + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_CLASSIC; + av(arg); + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_CLOSE; + } + } + /** + * This method extract coords from a list <br> + * X is stored in coords(0], Y stored in coords[1], Z Stored in coords[2] + * @param liste The list + * @param prim The calling primitive + * @throws LogoError If List isn't a list coordinate + */ + + private void extractCoords(String liste,String prim)throws LogoError{ + StringTokenizer st = new StringTokenizer(liste); + try { + for(int i=0;i<coords.length;i++){ + coords[i]=1; + if (!st.hasMoreTokens()) + throw new LogoError(prim + + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + String element = st.nextToken(); + if (element.equals("-")) { + if (st.hasMoreTokens()) + element = st.nextToken(); + coords[i] = -1; + } + coords[i] = coords[i] * Double.parseDouble(element); + } + + } catch (NumberFormatException e) { + throw new LogoError(prim + + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + } + if (st.hasMoreTokens()) + throw new LogoError(prim + + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + } + /** + * This method sets the drawing area to perspective mode + */ + + protected void perspective(){ + UserConfig uc = WSManager.getUserConfig(); + if (!enabled3D()) { + uc.setDrawXAxis(false); + uc.setDrawYAxis(false); + uc.setDrawGrid(false); + change_image_tortue(cadre,"tortue0.png"); + montrecacheTortue(false); + DrawPanel.WINDOW_MODE=DrawPanel.WINDOW_3D; + w3d=new World3D(); + montrecacheTortue(true); + } + } + /** + * This method sets the drawing area to Wrap, Close or Window mode + * @param id The window Mode + */ + protected void setWindowMode(int id){ + if (DrawPanel.WINDOW_MODE!=id) { + montrecacheTortue(false); + DrawPanel.WINDOW_MODE=id; + w3d=null; + montrecacheTortue(true); + } + } + + + /** + * This method converts the coordinates contained in "coords" towards the coords on the drawing area + */ + double[] toScreenCoord(double[] coord,boolean drawPoly){ + // If Mode perspective is active + if (enabled3D()){ + // w3d.toScreenCoord(coord); + // camera world + // If we have to record the polygon coordinates + if (DrawPanel.record3D!=DrawPanel.record3D_NONE&&DrawPanel.record3D!=DrawPanel.record3D_TEXT&&drawPoly){ + + DrawPanel.poly.addVertex(new Point3d(coord[0]/1000,coord[1]/1000,coord[2]/1000),tortue.couleurcrayon); + } + + w3d.toCameraWorld(coord); + + // Convert to screen Coordinates + w3d.cameraToScreen(coord); + } + // Mode2D + else { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + coord[0]=w/2+coord[0]; + coord[1]=h/2-coord[1]; + } + return coord; + } + + + + /** + * This method creates an instance of coord with the valid size:<br> + * size 2 for 2D coordinates<br> + * size 3 for 3D coordinates + */ + + private void initCoords(){ + + if (null==coords) coords=new double[2]; + if (enabled3D()){ + if (coords.length!=3) coords=new double[3]; + } + else { + if (coords.length!=2) coords=new double[2]; + } + } + public boolean enabled3D(){ + return (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_3D); + } + + /** + * For hideturtle and showturtle + */ + protected void ct_mt() { + if (null == tortue.tort) { + g.setXORMode(couleurfond); + g.setColor(tortue.couleurcrayon); + tortue.drawTriangle(); + BasicStroke crayon_actuel = (BasicStroke) g.getStroke(); + if (crayon_actuel.getLineWidth() == 1) + g.draw(tortue.triangle); + else { + g.setStroke(crayon_triangle); + g.draw(tortue.triangle); + g.setStroke(crayon_actuel); + } + } else { + g.setXORMode(couleurfond); + double angle = Math.PI / 2 - tortue.angle; + float x = (float) (tortue.corX * Math.cos(angle) + tortue.corY + * Math.sin(angle)); + float y = (float) (-tortue.corX * Math.sin(angle) + tortue.corY + * Math.cos(angle)); + g.rotate(angle); + g.drawImage(tortue.tort, (int) x - tortue.largeur / 2, + (int) y - tortue.hauteur / 2, this); + g.rotate(-angle); + } +/* if (null==rec) rec=new Rectangle2D.Double(); + rec.setRect(tortue.corX - tortue.gabarit, + tortue.corY - tortue.gabarit, + tortue.gabarit * 2, + tortue.gabarit * 2); + */ + clip(); + +/* clip((int) (tortue.corX - tortue.gabarit), + (int) (tortue.corY - tortue.gabarit), + tortue.gabarit * 2, tortue.gabarit * 2);*/ + } + /** + * When the turtle has to be redrawn, this method erase the turtle on the drawing screen + * + */ + protected void montrecacheTortue(boolean b) { + g.setColor(couleurfond); + for (int i = 0; i < tortues_visibles.size(); i++) { + int id = Integer.parseInt(tortues_visibles.get(i)); + // Turtle triangle + if (null == tortues[id].tort) { + g.setXORMode(couleurfond); + g.setColor(tortues[id].couleurmodedessin); + tortues[id].drawTriangle(); + BasicStroke crayon_actuel = (BasicStroke) g.getStroke(); + if (crayon_actuel.getLineWidth() == 1) + g.draw(tortues[id].triangle); + else { + g.setStroke(crayon_triangle); + g.draw(tortues[id].triangle); + g.setStroke(crayon_actuel); + } + } else { + // Image turtle + g.setXORMode(couleurfond); + double angle = Math.PI / 2 - tortues[id].angle; + float x = (float) (tortues[id].corX * Math.cos(angle) + tortues[id].corY + * Math.sin(angle)); + float y = (float) (-tortues[id].corX * Math.sin(angle) + tortues[id].corY + * Math.cos(angle)); + g.rotate(angle); + g.drawImage(tortues[id].tort, (int) x + - tortues[id].largeur / 2, (int) y + - tortues[id].hauteur / 2, this); + g.rotate(-angle); + } + /*if (null==rec) rec=new Rectangle2D.Double(); + rec.setRect(tortues[id].corX - tortues[id].gabarit, + tortues[id].corY - tortues[id].gabarit, + tortues[id].gabarit * 2, + tortues[id].gabarit * 2); + shape=rec;*/ + if (b) clip(); + } + } + + + +/* private void montrecacheTortue() { + // Graphics2D g=(Graphics2D)dessin.getGraphics(); + g.setColor(couleurfond); + for (int i = 0; i < tortues_visibles.size(); i++) { + int id = Integer.parseInt(String.valueOf(tortues_visibles + .get(i))); + + if (null == tortues[id].tort) { + g.setXORMode(couleurfond); + g.setColor(tortues[id].couleurmodedessin); + tortues[id].coord(); + BasicStroke crayon_actuel = (BasicStroke) g.getStroke(); + if (crayon_actuel.getLineWidth() == 1) + g.draw(tortues[id].triangle); + else { + g.setStroke(crayon_triangle); + g.draw(tortues[id].triangle); + g.setStroke(crayon_actuel); + } + } else { + g.setXORMode(couleurfond); + double angle = Math.PI / 2 - tortues[id].angle; + float x = (float) (tortues[id].corX * Math.cos(angle) + tortues[id].corY + * Math.sin(angle)); + float y = (float) (-tortues[id].corX * Math.sin(angle) + tortues[id].corY + * Math.cos(angle)); + g.rotate(angle); + g.drawImage(tortues[id].tort, (int) x + - tortues[id].largeur / 2, (int) y + - tortues[id].hauteur / 2, cadre.getArdoise()); + g.rotate(-angle); + } + /* if (null==rec) rec=new Rectangle2D.Double(); + rec.setRect(tortues[id].corX - tortues[id].gabarit, + tortues[id].corY - tortues[id].gabarit, + tortues[id].gabarit * 2, + tortues[id].gabarit * 2); + + clip(); + // g.dispose(); + } + } +*/ + /** + * Primitive clearscreen + */ + protected void videecran() { + // Delete all Gui Component + Set<String> set=gm.keySet(); + Iterator<String> it=set.iterator(); + while(it.hasNext()){ + String element=it.next(); + gui=gm.get(element).getGuiObject(); + it.remove(); + if (SwingUtilities.isEventDispatchThread()){ + remove(gui); + validate(); + } + else { + try{ + SwingUtilities.invokeAndWait(new Runnable(){ + public void run(){ + remove(gui); + validate(); + } + }); + } + catch(Exception e){} + } + } + + + // Delete List Polygon in 3D mode +// DrawPanel.listPoly=new Vector<Shape3D>(); +// DrawPanel.listText=new Vector<TransformGroup>(); + // Erase the 3d viewer if visible + if (null!=cadre.getViewer3D()) { + cadre.getViewer3D().clearScreen(); + System.gc(); + } + + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + g.setPaintMode(); + couleurfond=uc.getScreencolor(); + g.setColor(uc.getScreencolor()); + g.fillRect(0, 0, w,h); + stopRecord2DPolygon(); + + // Draw Grid + g.setStroke(new BasicStroke(1)); + drawGrid(); + drawXAxis(); + drawYAxis(); + // Init Turtles + if (null == tortues[0]) + tortues[0] = new Turtle(cadre); + // The active turtle will be the turtle 0 + tortue = tortues[0]; + tortue.id = 0; + // We delete all other turtles + for (int i = 1; i < tortues.length; i++) { + tortues[i] = null; + } + tortues_visibles.removeAllElements(); + tortues_visibles.push("0"); + g.setColor(tortue.couleurcrayon); + clip(); + tortue.init(); + tortue.setVisible(true); + g.setStroke(new BasicStroke(1)); + montrecacheTortue(true); + // Update the selection frame + updateColorSelection(); + + } + /** + * Primitive wash + */ + protected void nettoie() { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + stopRecord2DPolygon(); + g.setPaintMode(); + g.setColor(couleurfond); + g.fillRect(0, 0, w,h); + + drawGrid(); + /* Réinitialiser les tortues + if (null == tortues[0]) + tortues[0] = new Tortue(cadre); + tortue = tortues[0]; //la tortue active sera à présent la + // numéro 0 + tortue.id = 0; + for (int i = 1; i < tortues.length; i++) { //On élimine les + // autres tortues + tortues[i] = null; + } + tortues_visibles.removeAllElements(); + tortues_visibles.push("0");*/ + g.setColor(tortue.couleurcrayon); + clip(); + + if (tortue.isVisible()) + montrecacheTortue(true); + else + tortues_visibles=new Stack<String>(); + } + /** + * Used for primitive fillzone + * @param x + * @param y + * @param increment + * @param couleur_frontiere + * @return + */ + + private int bornes_remplis_zone(int x, int y, int increment, int couleur_frontiere) { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); +// System.out.println(x+" "+y); + while (!meme_couleur(DrawPanel.dessin.getRGB(x, y) ,couleur_frontiere)) { + DrawPanel.dessin.setRGB(x, y, couleur_frontiere); + x = x + increment; + if (!(x > 0 && x < w-1)) + break; + } + return x - increment; + } + /** + * Are the two color equals? + * @param col1 The first color + * @param col2 The second color + * @return true or false + */ + private boolean meme_couleur(int col1,int col2){ +/* if (Config.quality==Logo.QUALITY_HIGH){ + int rouge1 = (col1 >> 16) & 0xFF; + int vert1 = (col1 >> 8) & 0xFF; + int bleu1 = col1 & 0xFF; + int rouge2 = (col2 >> 16) & 0xFF; + int vert2 = (col2 >> 8) & 0xFF; + int bleu2 = col2 & 0xFF; + int tolerance=120; + int diff_rouge=rouge1-rouge2; + int diff_bleu=bleu1-bleu2; + int diff_vert=vert1-vert2; + boolean rouge;boolean vert; boolean bleu; + if (rouge1>rouge2){ + if (rouge1-rouge2< 128 -rouge2/2) rouge=true; + else rouge=false; + } + else{ + if (rouge2-rouge1<rouge2/2) rouge=true; + else rouge=false; + } + if (vert1>vert2){ + if (vert1-vert2< 128 -vert2/2) vert=true; + else vert=false; + } + else{ + if (vert2-vert1<vert2/2) vert=true; + else vert=false; + } + if (bleu1>bleu2){ + if (bleu1-bleu2< 128 -bleu2/2) bleu=true; + else bleu=false; + } + else{ + if (bleu2-bleu1<bleu2/2) bleu=true; + else bleu=false; + } + + return rouge&&bleu&| +// if (Math.abs(rouge1-rouge2)<tolerance&&Math.abs(vert1-vert2)<tolerance&&Math.abs(bleu1-bleu2)<tolerance&&Math.abs(rouge1+bleu1+vert1-rouge2-bleu2-vert2)<450) +// return true; + // else return false; + } + else{*/ + return (col1==col2); + //} + } + /** + * Primitive fillzone + */ + protected void rempliszone() { + montrecacheTortue(false); + int x = (int) (tortue.corX + 0.5); + int y = (int) (tortue.corY + 0.5); + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + if (x > 0 & x < w & y > 0 & y < h) { + int couleur_origine = DrawPanel.dessin.getRGB(x, y); + int couleur_frontiere = tortue.couleurcrayon.getRGB(); + // System.out.println(couleur_origine+" " +couleur_frontiere); + Stack<Point> pile_germes = new Stack<Point>(); + boolean couleurs_differentes = !meme_couleur(couleur_origine,couleur_frontiere); + if (couleurs_differentes) + pile_germes.push(new Point(x, y)); + while (!pile_germes.isEmpty()) { + + Point p = pile_germes.pop(); + int xgerme = p.x; + int ygerme = p.y; + int xmax = bornes_remplis_zone(xgerme, ygerme, 1, + couleur_frontiere); + int xmin=0; + if (xgerme>0) xmin = bornes_remplis_zone(xgerme - 1, ygerme, -1, + couleur_frontiere); + boolean ligne_dessus = false; + boolean ligne_dessous = false; + for (int i = xmin; i < xmax + 1; i++) { + //on recherche les germes au dessus et au dessous + if (ygerme > 0 + && meme_couleur(DrawPanel.dessin.getRGB(i, ygerme - 1) ,couleur_frontiere)) { + if (ligne_dessus) + pile_germes.push(new Point(i - 1, ygerme - 1)); + ligne_dessus = false; + } else { + ligne_dessus = true; + if (i == xmax && ygerme > 0) + pile_germes.push(new Point(xmax, ygerme - 1)); + } + if (ygerme < h-1 + && meme_couleur(DrawPanel.dessin.getRGB(i, ygerme + 1),couleur_frontiere)) { + if (ligne_dessous) + pile_germes.push(new Point(i - 1, ygerme + 1)); + ligne_dessous = false; + } else { + ligne_dessous = true; + if (i == xmax && ygerme < h-1) + pile_germes.push(new Point(xmax, ygerme + 1)); + } + } + } + clip(); + montrecacheTortue(true); + } + } + /** + * Used for primitive "fill" + * @param x + * @param y + * @param increment + * @param couleur_crayon + * @param couleur_origine + * @return + */ + private int bornes_remplis(int x, int y, int increment, int couleur_crayon, + int couleur_origine) { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + while (DrawPanel.dessin.getRGB(x, y) == couleur_origine) { + DrawPanel.dessin.setRGB(x, y, couleur_crayon); + x = x + increment; + if (!(x > 0 && x < w-1)) + break; + } + return x - increment; + } + /** + * Primitive "fill" + */ + protected void remplis() { + montrecacheTortue(false); + int x = (int) (tortue.corX + 0.5); + int y = (int) (tortue.corY + 0.5); + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + if (x > 0 & x < w & y > 0 & y < h) { + int couleur_origine = DrawPanel.dessin.getRGB(x, y); + int couleur_crayon = tortue.couleurcrayon.getRGB(); + if (x > 0 & x < w & y > 0 & y < h) { + Stack<Point> pile_germes = new Stack<Point>(); + boolean couleurs_differentes = !(couleur_origine == couleur_crayon); + if (couleurs_differentes) + pile_germes.push(new Point(x, y)); + while (!pile_germes.isEmpty()) { + Point p = pile_germes.pop(); + int xgerme = p.x; + int ygerme = p.y; + // System.out.println(xgerme+" "+ygerme); + int xmax = bornes_remplis(xgerme, ygerme, 1, couleur_crayon, + couleur_origine); + int xmin=0; + if (xgerme>0) xmin = bornes_remplis(xgerme - 1, ygerme, -1, + couleur_crayon, couleur_origine); + // System.out.println("xmax "+xmax+"xmin "+xmin); + boolean ligne_dessus = false; + boolean ligne_dessous = false; + for (int i = xmin; i < xmax + 1; i++) { + //on recherche les germes au dessus et au dessous + if (ygerme > 0 + && DrawPanel.dessin.getRGB(i, ygerme - 1) != couleur_origine) { + if (ligne_dessus) + pile_germes.push(new Point(i - 1, ygerme - 1)); + ligne_dessus = false; + } else { + ligne_dessus = true; + if (i == xmax && ygerme > 0) + pile_germes.push(new Point(xmax, ygerme - 1)); + } + if (ygerme < h-1 + && DrawPanel.dessin.getRGB(i, ygerme + 1) != couleur_origine) { + if (ligne_dessous) + pile_germes.push(new Point(i - 1, ygerme + 1)); + ligne_dessous = false; + } else { + ligne_dessous = true; + if (i == xmax && ygerme < h-1) + pile_germes.push(new Point(xmax, ygerme + 1)); + } + } + } + clip(); + montrecacheTortue(true); + } + } + } + /** + * Primitive "label" + * @param mot The word to write on the drawing area + */ + protected void etiquette(String mot) { + // Graphics2D g = (Graphics2D) Ardoise.dessin.getGraphics(); + montrecacheTortue(false); + if (!enabled3D()){ + double angle = Math.PI / 2 - tortue.angle; + if(DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_WRAP) centers=new Vector<Point2D.Double>(); + etiquette2D(tortue.corX,tortue.corY,angle,mot); +/* g.rotate(angle); + g.setPaintMode(); + g.setColor(tortue.couleurcrayon); + float x = (float) (tortue.corX * Math.cos(angle) + tortue.corY + * Math.sin(angle)); + float y = (float) (-tortue.corX * Math.sin(angle) + tortue.corY + * Math.cos(angle)); + g.setFont(Panel_Font.fontes[police_etiquette] + .deriveFont((float) tortue.police)); + g.drawString(mot, x, y); + g.rotate(-angle);*/ + } + else{ + FontRenderContext frc=g.getFontRenderContext(); + GlyphVector gv=g.getFont().createGlyphVector(frc, mot); + Shape outline=gv.getOutline(0, 0); + Shape s=transformShape(outline); + g.setPaintMode(); + g.setColor(tortue.couleurcrayon); + g.fill(s); + if (record3D==DrawPanel.record3D_TEXT){ + Text2D text=new Text2D( + mot,new Color3f(tortue.couleurcrayon), UserConfig.fontes[police_etiquette].getName(), + tortue.police,Font.PLAIN); + + text.setRectangleScaleFactor(0.001f); + Appearance appear=text.getAppearance(); + PolygonAttributes pa=new PolygonAttributes(); + pa.setCullFace(PolygonAttributes.CULL_NONE); + pa.setBackFaceNormalFlip(true); + appear.setPolygonAttributes(pa); + text.setAppearance(appear); +// if (null==DrawPanel.listText) DrawPanel.listText=new Vector<TransformGroup>(); + TransformGroup tg=new TransformGroup(); + double[][] d=tortue.getRotationMatrix(); + Matrix3d m=new Matrix3d(d[0][0],d[0][1],d[0][2],d[1][0],d[1][1],d[1][2],d[2][0],d[2][1],d[2][2]); + Transform3D t=new Transform3D(m,new Vector3d(tortue.X/1000,tortue.Y/1000,tortue.Z/1000),1); + tg.setTransform(t); + tg.addChild(text); + cadre.getViewer3D().add2DText(tg); +// DrawPanel.listText.add(tg); + } + + + } + montrecacheTortue(true); + if (classicMode) repaint(); + } + private void etiquette2D(double x,double y, double angle, String word){ + if (word.length()==0) return; + + g.setPaintMode(); + g.setColor(tortue.couleurcrayon); + Font f= UserConfig.fontes[police_etiquette] + .deriveFont((float) tortue.police); + g.setFont(f); + g.translate(x, y); + g.rotate(angle); + FontRenderContext frc = g.getFontRenderContext(); + TextLayout layout = new TextLayout(word, f, frc); + Rectangle2D bounds = layout.getBounds(); + float height=(float)bounds.getHeight(); + float width=(float)bounds.getWidth(); + float x1=0,y1=0; + switch(tortue.getLabelHorizontalAlignment()){ + case Turtle.LABEL_HORIZONTAL_ALIGNMENT_LEFT: + x1=0; + break; + case Turtle.LABEL_HORIZONTAL_ALIGNMENT_CENTER: + x1=-width/2; + break; + case Turtle.LABEL_HORIZONTAL_ALIGNMENT_RIGHT: + x1=-width; + break; + } + switch(tortue.getLabelVerticalAlignment()){ + case Turtle.LABEL_VERTICAL_ALIGNMENT_BOTTOM: + y1=0; + break; + case Turtle.LABEL_VERTICAL_ALIGNMENT_CENTER: + y1=height/2; + break; + case Turtle.LABEL_VERTICAL_ALIGNMENT_TOP: + y1=height; + break; + } + layout.draw(g, x1, y1); + g.drawString(word, x1, y1); + g.rotate(-angle); + g.translate(-x, -y); + if (DrawPanel.WINDOW_MODE==DrawPanel.WINDOW_WRAP){ + Rectangle2D.Double rec=new Rectangle2D.Double(0,0,width,height); + AffineTransform at=new AffineTransform(); + at.translate(x, y); + at.rotate(angle); + Rectangle2D bound =at.createTransformedShape(rec).getBounds2D(); + double right= bound.getX()+bound.getWidth()-x; + double left= x-bound.getX(); + double up=y-bound.getY(); + double down=bound.getY()+bound.getHeight()-y; + + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + if (x+right>w&& x<=w){ + pt=new Point2D.Double(-w+x,y); + if (! centers.contains(pt)) { + centers.add(pt); + etiquette2D(-w+x,y,angle,word); + } + } + if (x-left<0&& x>=0){ + pt=new Point2D.Double(w+x,y); + if (! centers.contains(pt)) { + centers.add(pt); + etiquette2D(w+x,y,angle,word); + } + } + if (y-up<0&& y>=0){ + pt=new Point2D.Double(x,h+y); + if (! centers.contains(pt)) { + centers.add(pt); + etiquette2D(x,h+y,angle,word); + } + } + if (y+down>h&&y<=h){ + pt=new Point2D.Double(x,-h+y); + if (! centers.contains(pt)) { + centers.add(pt); + etiquette2D(x,-h+y,angle,word); + } + } + } + } + + /** + * This method transform a plane 2D shape in the shape corresponding to the turtle plane + * @param s the first shape + * @return the new shape after transformation + */ + private Shape transformShape(Shape s){ + PathIterator it=s.getPathIterator(null); + double[] d=new double[6]; + double[][] coor=new double[3][1]; + GeneralPath gp=new GeneralPath(); + double[] end=new double[3]; + double[] ctl1=new double[3]; + double[] ctl2=new double[3]; + boolean b=false; + while(!it.isDone()){ + it.next(); + int id=0; + if (!it.isDone()) id=it.currentSegment(d); + else break; + coor[0][0]=d[0]; + coor[1][0]=-d[1]; + coor[2][0]=0; + coor=w3d.multiply(tortue.getRotationMatrix(), coor); + + end[0]=coor[0][0]+tortue.X; + end[1]=coor[1][0]+tortue.Y; + end[2]=coor[2][0]+tortue.Z; + w3d.toScreenCoord(end); + + if (id==PathIterator.SEG_MOVETO) + gp.moveTo((float)end[0], (float)end[1]); + else if (id==PathIterator.SEG_LINETO) + { + if (!b) { + b=true; + gp.moveTo((float)end[0], (float)end[1]); + } + else gp.lineTo((float)end[0], (float)end[1]); + } + else if (id==PathIterator.SEG_CLOSE){ + gp.closePath(); + } + else { + if (!b) { + b=true; + Point2D p=null; + if (s instanceof Arc2D.Double) + p=((Arc2D.Double)s).getStartPoint(); + else if (s instanceof GeneralPath) + p=((GeneralPath)s).getCurrentPoint(); + coor[0][0]=p.getX(); + coor[1][0]=-p.getY(); + coor[2][0]=0; + coor=w3d.multiply(tortue.getRotationMatrix(), coor); + ctl1[0]=coor[0][0]+tortue.X; + ctl1[1]=coor[1][0]+tortue.Y; + ctl1[2]=coor[2][0]+tortue.Z; + w3d.toScreenCoord(ctl1); + gp.moveTo((float)ctl1[0], (float)ctl1[1]); + } + coor[0][0]=d[2]; + coor[1][0]=-d[3]; + coor[2][0]=0; + coor=w3d.multiply(tortue.getRotationMatrix(), coor); + ctl1[0]=coor[0][0]+tortue.X; + ctl1[1]=coor[1][0]+tortue.Y; + ctl1[2]=coor[2][0]+tortue.Z; + w3d.toScreenCoord(ctl1); + if(id==PathIterator.SEG_QUADTO){ + QuadCurve2D qc=new QuadCurve2D.Double(gp.getCurrentPoint().getX(),gp.getCurrentPoint().getY() + ,end[0], end[1],ctl1[0], ctl1[1]); + gp.append(qc, true);} + else if (id==PathIterator.SEG_CUBICTO){ + coor[0][0]=d[4]; + coor[1][0]=-d[5]; + coor[2][0]=0; + coor=w3d.multiply(tortue.getRotationMatrix(), coor); + + ctl2[0]=coor[0][0]+tortue.X; + ctl2[1]=coor[1][0]+tortue.Y; + ctl2[2]=coor[2][0]+tortue.Z; + + w3d.toScreenCoord(ctl2); + CubicCurve2D qc=new CubicCurve2D.Double(gp.getCurrentPoint().getX(),gp.getCurrentPoint().getY() + ,end[0], end[1],ctl1[0], ctl1[1],ctl2[0], ctl2[1]); + gp.append(qc, true); + } + } + } + return gp; + } + public World3D getWorld3D(){ + return w3d; + } + /** + * primitive setscreencolor + * @param color The Color of the nackground screen + */ + protected void fcfg(Color color) { + couleurfond=color; + updateColorSelection(); + if (enabled3D()){ + if (cadre.getViewer3D()!=null){ + cadre.getViewer3D().updateBackGround(couleurfond); + } + } + nettoie(); + } + /** + * Primitive setpencolor + * @param color The pen Color + */ + protected void fcc(Color color) { + if (tortue.isVisible()&&null==tortue.tort) montrecacheTortue(false); + tortue.couleurcrayon = color; + tortue.couleurmodedessin = color; + if (tortue.isVisible()&&null==tortue.tort) montrecacheTortue(true); + } + + /** + * Primitive "guiposition" + * @param id The id for the gui Object + * @param liste The Coordinates list + * @param name The translated name for the primitive "guiposition" + * @throws LogoError If coordinates list is invalid + */ + protected void guiposition(String id, String liste,String name) throws LogoError{ + if (guiExist(id)){ + initCoords(); + extractCoords(liste,name); + coords=toScreenCoord(coords,false); + gm.get(id).setLocation((int)coords[0],(int)coords[1]); + } + } + /** + * Draw the Gui object refered with "id" + * @param id The Gui Object Id + * @throws LogoError If this object doesn't exist + */ + protected void guiDraw(String id) throws LogoError{ + if (guiExist(id)){ + GuiComponent gc=gm.get(id); + add(gc.getGuiObject()); + validate(); + repaint(); + // updateGuiComponents(); + } + } + /** + * @uml.property name="gui" + * @uml.associationEnd + */ + private javax.swing.JComponent gui; + /** + * This method erases a Gui on the drawing area + * @param id The Gui Object id + * @throws LogoError + */ + + protected void guiRemove(String id) throws LogoError{ + if (guiExist(id)){ + gui=gm.get(id).getGuiObject(); + gm.remove(id); + if (SwingUtilities.isEventDispatchThread()){ + remove(gui); + validate(); + } + else { + try{ + SwingUtilities.invokeAndWait(new Runnable(){ + public void run(){ + remove(gui); + validate(); + } + }); + } + catch(Exception e){} + } + repaint(); + } + } + private StringBuffer extractList(String list) throws LogoError{ + StringBuffer sb=new StringBuffer(); + int compteur=0; + int i=0; + while(list.length()!=0){ + char c=list.charAt(i); + if (c=='[') compteur++; + else if (c==']') { + if (compteur==0) return sb; + else compteur--; + } + sb.append(c); + i++; + } + throw new LogoError("[ "+list+" "+Logo.messages.getString("pas_liste")); + } + + protected void guiAction(String id, String liste) throws LogoError{ + if (guiExist(id)){ + GuiComponent gc=gm.get(id); + // If gc is a JButton + if (gc.isButton()){ + ((GuiButton)gc).setAction(Utils.decoupe(liste)); + if (!gc.hasAction()){ + ((javax.swing.JButton)gc.getGuiObject()).addActionListener(gc); + gc.hasAction=true; + } + } + // gc is a JcomboBox + else if (gc.isMenu()){ + liste=liste.trim(); + int i=0; + while(liste.length()!=0){ + if (liste.charAt(0)=='['){ + liste=liste.substring(1).trim(); + StringBuffer sb=extractList(liste); + liste=liste.substring(sb.length()+1).trim(); + ((GuiMenu)gc).setAction(sb, i); + i++; + } + else throw new LogoError(liste.charAt(0)+" "+Logo.messages.getString("pas_liste")); + } + GuiMenu gm=(GuiMenu)gc; + if (!gm.hasAction){ + gm.hasAction=true; + ((javax.swing.JComboBox)gc.getGuiObject()).addActionListener(gm); + } + } + } + } + private boolean guiExist(String id) throws LogoError{ + if (gm.containsKey(id.toLowerCase())) return true; + else throw new LogoError(Logo.messages.getString("no_gui")+" "+id); + } +// boolean access=false; + private void clip(){ + if (classicMode){ + + //access=true; +// refresh(); + + repaint(); + /* if (SwingUtilities.isEventDispatchThread()){ + repaint(); + } + else { + try { + + SwingUtilities.invokeLater(new Runnable(){ + public void run(){ + repaint(); + } + }); + } + catch(Exception e2){} + }*/ + } + /*Rectangle rec1=cadre.jScrollPane1.getViewport().getViewRect(); + boolean inter=sh.intersects(rec1); + if (inter){ + if (classicMode){ + repaint(); + } + }*/ + } + public void setQuality(DrawQuality q){ + /* + * Marko Zivkovic + * I improved all the qualities for one level. I introduced a super high quality that is assigned to "high" + * and dropped the low quality, which is now the old normal/default quality + */ + + if (q==DrawQuality.HIGH){ + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE); + } + else if(q==DrawQuality.LOW){ + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_DEFAULT); + g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_DEFAULT); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); + } + else { //normal + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } + } + public void change_image_tortue(Application cadre, String chemin) { + if (tortue.isVisible()) + montrecacheTortue(false); + if (chemin.equals("tortue0.png")) { + tortue.tort = null; + tortue.largeur = 26; + tortue.hauteur = 26; + } else { + //ON teste tout d'abord si le chemin est valide + if (null == Utils.class.getResource(chemin)) + chemin = "tortue1.png"; + tortue.tort = Toolkit.getDefaultToolkit().getImage( + Utils.class.getResource(chemin)); + MediaTracker tracker = new MediaTracker(cadre.getFrame()); + tracker.addImage(tortue.tort, 0); + try { + tracker.waitForID(0); + } catch (InterruptedException e1) { + } + double largeur_ecran = Toolkit.getDefaultToolkit().getScreenSize() + .getWidth(); + // On fait attention à la résolution de l'utilisateur + double facteur = largeur_ecran / 1024.0; + + if ((int) (facteur + 0.001) != 1) { + tortue.largeur = tortue.tort.getWidth(cadre.getFrame()); + tortue.hauteur = tortue.tort.getHeight(cadre.getFrame()); + tortue.tort = tortue.tort.getScaledInstance( + (int) (facteur * tortue.largeur), + (int) (facteur * tortue.hauteur), + Image.SCALE_SMOOTH); + tracker = new MediaTracker(cadre.getFrame()); + tracker.addImage(tortue.tort, 0); + try { + tracker.waitForID(0); + } catch (InterruptedException e1) { + } + } + tortue.largeur = tortue.tort.getWidth(cadre.getFrame()); + tortue.hauteur = tortue.tort.getHeight(cadre.getFrame()); + } + tortue.gabarit = Math.max(tortue.hauteur, + tortue.largeur); + if (tortue.isVisible()) + montrecacheTortue(true); + + } + // animation + protected void setAnimation(boolean predic){ + if (predic==classicMode){ + if (predic) { + cadre.getHistoryPanel().active_animation(); + } + else { + cadre.getHistoryPanel().stop_animation(); + repaint(); + } + } + } + + protected void setGraphicsFont(Font f){ + g.setFont(f); + } + protected Font getGraphicsFont(){ + return g.getFont(); + } + protected void setStroke(Stroke st){ + g.setStroke(st); + } + public Color getBackgroundColor(){ + return couleurfond; + } + protected void setBackgroundColor(Color c){ + couleurfond=c; + } + protected void updateColorSelection(){ + float r=(255-couleurfond.getRed())/255; + float v=(255-couleurfond.getGreen())/255; + float b=(255-couleurfond.getBlue())/255; + colorSelection=new Color(r,v,b,0.2f); + } + public void setNumberOfTurtles(int max){ + WSManager.getUserConfig().setMaxTurtles(max); + Turtle[] tampon = tortues.clone(); + tortues = new Turtle[max]; + int borne_sup=Math.min(tampon.length,tortues.length); + for(int i=0;i<borne_sup;i++){ + tortues[i]=tampon[i]; + } + for(int i=tortues_visibles.size()-1;i>-1;i--){ + int integer=Integer.parseInt(tortues_visibles.get(i)); + if (integer>=max){ + tortues_visibles.remove(i); + } + } + } + protected void initGraphics(){ + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + police_etiquette=UserConfig.police_id(WSManager.getWorkspaceConfig().getFont()); + // init all turtles + tortues = new Turtle[uc.getMaxTurtles()]; + tortues_visibles=new Stack<String>(); + tortue=new Turtle(cadre); + tortues[0] = tortue; + tortue.id = 0; + tortues_visibles.push("0"); + for (int i = 1; i < tortues.length; i++) { + // All other turtles are null + tortues[i] = null; + } + g=(Graphics2D)dessin.getGraphics(); + couleurfond=uc.getScreencolor(); + setQuality(uc.getQuality()); + g.setColor(uc.getScreencolor()); + g.fillRect(0,0,w,h); + g.setColor(uc.getScreencolor()); + if (!enabled3D()){ + drawGrid(); + drawXAxis(); + drawYAxis(); + } + MediaTracker tracker; + if (0==uc.getActiveTurtle()) { + g.setXORMode(couleurfond); + tortue.drawTriangle(); + g.setColor(tortue.couleurcrayon); + g.draw(tortue.triangle); + } + else { + g.setXORMode(couleurfond); + tracker=new MediaTracker(cadre.getFrame()); + tracker.addImage(tortue.tort,0); + try{tracker.waitForID(0);} + catch(InterruptedException e){} + if (tracker.checkID(0)) g.drawImage(tortue.tort, w/2 - tortue.largeur / 2, + h/2 - tortue.hauteur/2, this); + } + updateColorSelection(); + } + + private void resizeAllGuiComponents(double d){ + // Resize all GuiComponent + Set<String> set=gm.keySet(); + Iterator<String> it=set.iterator(); + while (it.hasNext()){ + String element=it.next(); + GuiComponent gui=gm.get(element); + gui.getGuiObject().setSize((int)(gui.getOriginalWidth()*d), + (int)(gui.getOriginalHeight()*d) ); + Font f=gui.getGuiObject().getFont(); + gui.getGuiObject().setFont(f.deriveFont((float)(WSManager.getWorkspaceConfig().getFont().getSize()*d))); + double x=gui.getLocation().x/zoom; + double y=gui.getLocation().y/zoom; + gui.setLocation((int)(x*d),(int)(y*d)); + + } + + } + + + /** + * Make a zoom on the drawing area + * @param d The absolute factor + */ + public void zoom(double d, boolean zoomIn){ + // Disable zoom buttons + //cadre.setZoomEnabled(false); // TODO REMOVE ZOOM COMPLETELY? + + javax.swing.JViewport jv=cadre.scrollArea.getViewport(); + Point p=jv.getViewPosition(); + Rectangle r=jv.getVisibleRect(); + + + // If a selection rectangle is displaying on the drawing area + // And If zoomout has been pressed + // Zooming on the rectangular selection + if (null!=selection&&cadre.commande_isEditable()&&zoomIn){ + int originalWidth=jv.getWidth(); + double width=selection.getWidth(); + d=zoom*originalWidth/width; + p=selection.getLocation(); + r.width=selection.width; + // adjust height in the same ratio as width + r.height=r.height*(int)width/originalWidth; + // erase selection + selection=null; + } + // Resize all Gui Components on the drawing area + resizeAllGuiComponents(d); + + double oldZoom=zoom; + zoom=d; + + /* + * ------------------------------------- + * | | + * | ------------------------- | + * | | | | + * | | | | + * | | x-- dx----- | --> CenterView Point of the rectangle + * | | | | | + * | | dy | | + * | ------------------------- | + * ------------------------------------- + * */ + + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + double dx=Math.min(r.width,w*oldZoom)/2; + double dy=Math.min(r.height,h*oldZoom)/2; + Point centerView=new Point((int)(p.x+dx),(int)(p.y+dy)); + + // Dynamically modify the drawing Area size + setPreferredSize(new java.awt.Dimension( + (int)(w*zoom) + ,(int)(h*zoom))); + + SwingUtilities.invokeLater(new PositionJViewport(jv, + new Point((int)(centerView.x/oldZoom*zoom-dx), + (int)(centerView.y/oldZoom*zoom-dy)))); + + } + private Color getTransparencyColor(int color,int trans){ + Color c=new Color(color); + return new Color(c.getRed(),c.getGreen(),c.getBlue(),trans); + } + /** + * Draw the horizontal axis + */ + private void drawXAxis(){ + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + if (uc.isDrawXAxis()){ + g.setColor(getTransparencyColor(uc.getAxisColor(),128)); + g.drawLine(0,h/2,w,h/2); + for (int i=w/2%uc.getXAxis();i<w;i=i+uc.getXAxis()){ + g.drawLine(i, h/2-2, i, h/2+2); + g.setFont(new Font("Dialog",Font.PLAIN,10)); + String tick=String.valueOf(i-w/2); + FontMetrics fm=g.getFontMetrics(); + int back=fm.stringWidth(String.valueOf(tick))/2; + // if the both axes are drawn, the zero has to translated + // So we don't draw the zero + if (i!=w/2||!uc.isDrawYAxis()) g.drawString(tick, i-back, h/2+20); + } + } + } + /** + * Draw the vertical axis + */ + private void drawYAxis(){ + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + if (uc.isDrawYAxis()){ + g.setColor(getTransparencyColor(uc.getAxisColor(),128)); + g.drawLine(w/2,0,w/2,h); + for (int i=h/2%uc.getYAxis();i<h;i=i+uc.getYAxis()){ + g.drawLine( w/2-2, i, w/2+2,i); + g.setFont(new Font("Dialog",Font.PLAIN,10)); + String tick=String.valueOf(h/2-i); + // If both axes are drawn, zero is translated + if (i==h/2&&uc.isDrawXAxis()) g.drawString("0", w/2+10, i-5); + else g.drawString(tick, w/2+10, i+5); + } + } + } + private void drawGrid(){ + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + if (uc.isDrawGrid()){ + g.setStroke(new BasicStroke(1)); + g.setColor(getTransparencyColor(uc.getGridColor(),100)); + for (int i=w/2%uc.getXGrid();i<w;i=i+uc.getXGrid()) + g.drawLine(i, 0, i, h); + + for (int i=h/2%uc.getYGrid();i<h;i=i+uc.getYGrid()) + g.drawLine(0,i, w, i); + } + } + // In animation mode, we have to wait for the drawing to be finished before modifying graphics. + // Thread must be synchronized. + protected synchronized void refresh(){ + repaint(); + try{ + wait(); + } + catch(InterruptedException e){} + + } + + protected synchronized void paintComponent(Graphics graph){ + super.paintComponent(graph); + Graphics2D g2d=(Graphics2D)graph; + if (null==shape){ + g2d.setClip(cadre.scrollArea.getViewport().getViewRect()); + } + else { + g2d.setClip(shape); + shape=null; + } + g2d.scale(DrawPanel.zoom,DrawPanel.zoom); + g2d.drawImage(dessin,0,0,this); + g2d.scale(1/DrawPanel.zoom,1/DrawPanel.zoom); + if (!Affichage.execution_lancee&&null!=selection&&cadre.commande_isEditable()){ + g2d.setColor(colorSelection); + g2d.fillRect(selection.x, selection.y, selection.width, selection.height); + } + notify(); + } + public void active_souris(){ + lissouris=false; + } + public boolean get_lissouris(){ + return lissouris; + } + public int get_bouton_souris(){ + lissouris=false; + return bouton_souris; + } + public String get_possouris(){ + lissouris=false; + return possouris; + } + public void mousePressed(MouseEvent e){ + if (!Affichage.execution_lancee) { + selection=new Rectangle(); + origine=new Point(e.getPoint()); + selection.setSize(0, 0); + } + } + public void mouseReleased(MouseEvent e){} + public void mouseClicked(MouseEvent ev){ + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + if (!Affichage.execution_lancee){ + selection=null; + origine=null; + repaint(); + } + else{ + lissouris=true; + bouton_souris=ev.getButton(); + Point point=ev.getPoint(); + possouris="[ "+(point.x-w/2)+" "+(h/2-point.y)+" ] "; + } + } + + public void mouseExited(MouseEvent e){ + } + public void mouseEntered(MouseEvent e){ + } + // Select an export area + public void mouseDragged(MouseEvent e){ + if (!Affichage.execution_lancee&&null!=selection){ + // First, we test if we need to move the scrollbars + Point pos=e.getPoint(); + javax.swing.JViewport jv=cadre.scrollArea.getViewport(); + Point viewPosition=jv.getViewPosition(); + Rectangle r=jv.getVisibleRect(); + r.setLocation(viewPosition); + // Is the point visible on screen? + boolean b=r.contains(pos); + + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + // Move the scroolPane if necessary + if (!b){ + int x,y; + if (pos.x<viewPosition.x) x=Math.max(0,pos.x); + else if (pos.x>viewPosition.x+r.width) x=Math.min(pos.x-r.width,(int)(w*zoom-r.width)); + else x=viewPosition.x; + if (pos.y<viewPosition.y) y=Math.max(0,pos.y); + else if (pos.y>viewPosition.y+r.height) y=Math.min(pos.y-r.height,(int)(h*zoom-r.height)); + else y=viewPosition.y; + jv.setViewPosition(new Point(x,y)); + } + + // Then , drawing the selection area + + selection.setFrameFromDiagonal(origine, e.getPoint()); + repaint(); + } + } + + public void mouseMoved(MouseEvent ev) { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + + lissouris = true; + bouton_souris = 0; + Point point = ev.getPoint(); + possouris = "[ " + (point.x - w / 2) + " " + (h / 2 - point.y) + " ] "; + } + + protected void addToGuiMap(GuiComponent gc) throws xlogo.kernel.LogoError { + gm.put(gc); + } + + // This method modifies all Shape for any turtle on screen + protected void updateAllTurtleShape() { + for (int i = 0; i < tortues.length; i++) { + if (null != tortues[i]) { + tortues[i].fixe_taille_crayon(2 * tortues[i].getPenWidth()); + } + } + } + /** + * Saves the a part of the drawing area as an image + * @param name The image name + * @param coords The upper left corner and the right bottom corner + */ + protected void saveImage(String name, int[] coords){ + BufferedImage buffer=getImagePart(coords); + String lowerName=name.toLowerCase(); + String format="png"; + if (lowerName.endsWith(".jpg")||lowerName.endsWith(".jpeg")) { + format="jpg"; + } + else if (!lowerName.endsWith(".png")) { + name=name+".png"; + } + name=WSManager.getUserConfig().getDefaultFolder()+File.separator+name; + try{ + File f=new File(name); + ImageIO.write(buffer, format, f); + } + catch(IOException e){} + + } + /** + * Return a part of the drawing area as an image + * @return + */ + private BufferedImage getImagePart(int[] coords){ + Image pic=DrawPanel.dessin; + if (zoom!=1){ + pic=createImage(new FilteredImageSource(pic.getSource(), + new ReplicateScaleFilter((int)(dessin.getWidth()*zoom),(int)(dessin.getHeight()*zoom)))); + } + pic=createImage(new FilteredImageSource(pic.getSource(), + new CropImageFilter(coords[0],coords[1],coords[2],coords[3]))); + return toBufferedImage(pic); + } + + + public BufferedImage getSelectionImage(){ + Image pic=DrawPanel.dessin; + if (zoom!=1){ + pic=createImage(new FilteredImageSource(pic.getSource(), + new ReplicateScaleFilter((int)(dessin.getWidth()*zoom),(int)(dessin.getHeight()*zoom)))); + } + if (null!=selection){ + int x=(int)(selection.getBounds().getX()); + int y=(int)(selection.getBounds().getY()); + int width=(int)(selection.getBounds().getWidth()); + int height=(int)(selection.getBounds().getHeight()); + pic=createImage(new FilteredImageSource(pic.getSource(), + new CropImageFilter(x,y,width,height))); + } + return toBufferedImage(pic); + } +// This method returns a buffered image with the contents of an image + private BufferedImage toBufferedImage(Image image) { + if (image instanceof BufferedImage) + return (BufferedImage)image; + + // This code ensures that all the pixels in the image are loaded + image = new ImageIcon(image).getImage(); + + + // Create a buffered image with a format that's compatible with the screen + BufferedImage bimage = null; + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + try { + // Determine the type of transparency of the new buffered image + int transparency = Transparency.OPAQUE; + + // Create the buffered image + GraphicsDevice gs = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gs.getDefaultConfiguration(); + bimage = gc.createCompatibleImage( + image.getWidth(null), image.getHeight(null), transparency); + } catch (HeadlessException e) { + // The system does not have a screen + } + + if (bimage == null) { + // Create a buffered image using the default color model + int type = BufferedImage.TYPE_INT_RGB; + bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); + } + + // Copy image to buffered image + Graphics g = bimage.createGraphics(); + + // Paint the image onto the buffered image + g.drawImage(image, 0, 0, null); + g.dispose(); + + return bimage; + } + class PositionJViewport implements Runnable{ + JViewport jv; + Point p; + PositionJViewport(JViewport jv, Point p){ + this.jv=jv; + this.p=p; + } + public void run(){ + revalidate(); + //cadre.calculateMargin(); // TODO here is a zoom bug TODO maybe return this + // I have to add those two lines because of a bug I don't understand + // zoom 8 zoom 1 zoom 8 + // Sometimes after the method revalidate(), the left upper corner position + // wasn't correct + cadre.scrollArea.invalidate(); + cadre.scrollArea.validate(); + // End Bug + + jv.setViewPosition(p); + repaint(); + + //cadre.setZoomEnabled(true); + } + } + private void tryRecord2DMode(double a, double b){ + if (DrawPanel.record2D==DrawPanel.record2D_POLYGON){ + // FillPolygon mode + if (stackTriangle.size()==3){ + stackTriangle.remove(0); + stackTriangle.add(new Point2D.Double(a,b)); + } + else{ + stackTriangle.add(new Point2D.Double(a,b)); + } + if (stackTriangle.size()==3){ + GeneralPath gp=new GeneralPath(); + Line2D.Double ld=new Line2D.Double(stackTriangle.get(0),stackTriangle.get(1)); + gp.append(ld,false); + ld=new Line2D.Double(stackTriangle.get(1),stackTriangle.get(2)); + gp.append(ld,true); + ld=new Line2D.Double(stackTriangle.get(2),stackTriangle.get(0)); + gp.append(ld,true); + g.fill(gp); + } + } + + } + protected void startRecord2DPolygon(){ + DrawPanel.record2D=DrawPanel.record2D_POLYGON; + stackTriangle=new Vector<Point2D.Double>(); + stackTriangle.add(new Point2D.Double(tortue.corX,tortue.corY)); + } + protected void stopRecord2DPolygon(){ + DrawPanel.record2D=DrawPanel.record2D_NONE; + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/kernel/InstructionBuffer.java b/logo/src/xlogo/kernel/InstructionBuffer.java new file mode 100644 index 0000000..befe0d9 --- /dev/null +++ b/logo/src/xlogo/kernel/InstructionBuffer.java @@ -0,0 +1,206 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +public class InstructionBuffer { + /** + * This integer represents the max Characters in the StringBuffer + */ + + private final static int MAX_CHARACTERS=15000; + /** + * The main StringBuffer containing instruction + */ + private StringBuffer mainBuffer; + /** + * If the main StringBuffer is very large, Xlogo could become very slow. If main StringBuffer should contain more than MAX_CHARACTERS, those characters are saved in this StringBuffer + */ + private StringBuffer stock; + + InstructionBuffer(){ + clear(); + } + InstructionBuffer(String s){ + mainBuffer=new StringBuffer(s); + stock=new StringBuffer(); + } + /** + * Inserts some instructions at the beginning of the StringBuffer mainBuffer + * @param sb: The code to insert + */ + void insertCode(StringBuffer sb){ + if (sb.length()>InstructionBuffer.MAX_CHARACTERS) { + // insert current mainBuffer to stock + if (mainBuffer.length()!=0) stock.insert(0,mainBuffer); + // Copy MAX_CHARACTERS into mainBuffer + mainBuffer=new StringBuffer(sb.substring(0, InstructionBuffer.MAX_CHARACTERS)); + // All remaining characters into stock + stock.insert(0,sb.substring(InstructionBuffer.MAX_CHARACTERS)); + } + else { + mainBuffer.insert(0, sb); + } + + } + /** + * returns the total length of the two Buffer + */ + protected int getLength(){ + return mainBuffer.length()+stock.length(); + } + /** + * Inserts the String s at the beginning of the mainBuffer + * @param s + */ + protected void insert(String s){ + mainBuffer.insert(0, s); + } + /** + * Search for the String s , first in mainBuffer and then in stock + * if it isn't found in any buffer returns -1 + * @param s: The String to search + */ + protected int indexOf(String s){ + int index=mainBuffer.indexOf(s); + if (index==-1){ + index=stock.indexOf(s); + if (index==-1) return -1; + else return index+mainBuffer.length(); + } + return index; + + } + /** + * Search for the String s , first in mainBuffer and then in stock + * if not found in any buffer returns -1 + * @param s: The String to search + */ + protected int indexOf(String s, int fromIndex){ + int index=-1; + if (fromIndex<mainBuffer.length()) index=mainBuffer.indexOf(s,fromIndex); + if (index==-1){ + int from=0; + if (fromIndex>=mainBuffer.length()) from=fromIndex-mainBuffer.length(); + index=stock.indexOf(s,from); + if (index==-1) return -1; + else return index+mainBuffer.length(); + } + return index; + + } + + + /** + * Delete all code from offset start to offset end + * @param start Start offset + * @param end End offset + */ + protected void delete(int start, int end){ + if (end<=mainBuffer.length()) mainBuffer.delete(start, end); + else { + stock.delete(0, end-mainBuffer.length()); + mainBuffer=new StringBuffer(); + transferStock(); + } + if (mainBuffer.length()==0){ + // if there are instruction in stock yet + if (stock.length()!=0) transferStock(); + } + + } + /** + * Transfers MAX_CHARCATERS from the buffer stock to mainBuffer + */ + + private void transferStock(){ + if (stock.length()>InstructionBuffer.MAX_CHARACTERS){ + mainBuffer.append(stock.substring(0, InstructionBuffer.MAX_CHARACTERS)); + stock.delete(0, InstructionBuffer.MAX_CHARACTERS); + } + else { + mainBuffer.append(stock); + stock=new StringBuffer(); + } + } + /** + * Returns next Word + * @return a String which represents the next word + */ + protected String getNextWord() { + StringBuffer mot = new StringBuffer(); + char caractere; + for (int i = 0; i < mainBuffer.length(); i++) { + caractere = mainBuffer.charAt(i); + if (caractere == ' ') { + return mot.toString(); + } else + mot.append(caractere); + if (i==mainBuffer.length()-1&& stock.length()!=0){ + transferStock(); + } + } + // System.out.println("mot: "+mot); + return mot.toString(); + } + /** + * Deletes the String mot from the mainBuffer instructions + * @param mot The string to delete + */ + protected void deleteFirstWord(String mot) { + if (mainBuffer.length() > mot.length()) + mainBuffer = mainBuffer.delete(0, mot.length() + 1); + else + mainBuffer = new StringBuffer(); + if (mainBuffer.length()==0){ + // if there are instruction in stock yet + if (stock.length()!=0) transferStock(); + } + } + /** + * Return Character at the chosen index. this methos search first in mainBuffer and then in stock + * @param index The chosen index + * @return A character + */ + protected char charAt(int index){ + if (index<mainBuffer.length()) return mainBuffer.charAt(index); + return stock.charAt(index-mainBuffer.length()); + + } + /** + * Clear the both buffers + */ + public void clear(){ + mainBuffer=new StringBuffer(); + stock=new StringBuffer(); + } + public String toString(){ + return mainBuffer.toString()+stock.toString(); +// return "MainBuffer:"+mainBuffer.toString()+":stock:"+stock.toString(); + } +} diff --git a/logo/src/xlogo/kernel/Interprete.java b/logo/src/xlogo/kernel/Interprete.java new file mode 100644 index 0000000..291674f --- /dev/null +++ b/logo/src/xlogo/kernel/Interprete.java @@ -0,0 +1,981 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq */ +package xlogo.kernel; + +import java.util.Stack; +import java.util.HashMap; + +import xlogo.Application; +import xlogo.Logo; +import xlogo.kernel.userspace.UserSpace; +import xlogo.kernel.userspace.procedures.Procedure; + +public class Interprete +{ + + private LaunchPrimitive lanceprim; + + private Application app; + + private Kernel kernel; + + private UserSpace wp; + protected static boolean renvoi_instruction = false; + public static Stack<String> calcul = new Stack<String>(); + protected static Stack<HashMap<String, String>> stockvariable = new Stack<HashMap<String, String>>(); + protected static boolean stop = false; + protected static Stack<String> nom = new Stack<String>(); + // procédures attendant + // parmamètres à recevoir + public static Stack<String> en_cours = new Stack<String>(); + // actuellement en cours + // d'exécution + /** + * This buffer contains all instructions to execute + * + * @uml.property name="instructionBuffer" + * @uml.associationEnd multiplicity="(1 1)" + */ + private InstructionBuffer instructionBuffer = new InstructionBuffer(); + + public static StringBuffer actionInstruction = new StringBuffer(); + + protected static HashMap<String, String> locale = new HashMap<String, String>(); + // noms des variables + // locales + + protected static boolean operande = false; + protected static boolean operateur = false; + protected static boolean drapeau_ouvrante = false; + protected static boolean drapeau_fermante = false; + public static String lineNumber = ""; + + // private TreeParser tp; + /* + * public Interprete(Application cadre){ this.cadre=cadre; + * lanceprim=new LaunchPrimitive(cadre); cadre.error=false; } + */ + public Interprete(Application app) + { + this.kernel = app.getKernel(); + this.app = app; + wp = kernel.getWorkspace(); + lanceprim = new LaunchPrimitive(app, wp); + app.error = false; + } + + String execute(StringBuffer instructions) throws LogoError + { + if (!instructions.equals("")) + { + instructionBuffer.insertCode(instructions); + } + + // Object obca1,obca2,oban; + while (instructionBuffer.getLength() != 0) + { + if (app.error) // TODO && LogoError.lance : before, lance was always false, thus this branch was never taken. check this. + throw new LogoError(Logo.messages.getString("stop")); + while (app.affichage.isOnPause()) + { // Si l'on touche aux scrollbars + try + { + wait(); + } + catch (Exception e) + {} + } + // System.out.println("en_cours d'execution "+"\n"+ + // en_cours+"\n\n"); + // System.out.println("nom "+nom); + // System.out.println("calcul \n"+calcul+"\n\n"); + // System.out.println("nom "+nom.toString()+" locale "+locale+ " + // "+valeur+" stockvariable "+stockvariable); + // System.out.println("operande "+calcul+" "+operande+"debut"+instructionBuffer); + + // Is this line really interesting?? + if (instructionBuffer.getLength() == 0) + break; + // System.out.print("debut\n"+instructionBuffer+"\nfin\n------------------\n"); + String element = instructionBuffer.getNextWord(); + // System.out.println(app.affichage.getPause()+element); + + // System.out.println("/"+instructionBuffer+"/"); + + /* + * if (element=="") + * break; + *//* *********************************************** + * // si c'est une primitive ou une procedure ******* + * *********************************************** + */ + String element_minuscule = element.toLowerCase(); + /* + * Marko Zivkovic: In XLogo4Schools, a procedure is identified by its name, not by its position in a stack. + * Now, i denotes only Logo primitives. If element_minuscule is a procedure, then i will be set to -2, + * s.t. the interpreter can assume as before that it denotes something other than primitive. + * If i >= 0, then the interpreter will work just as before, using i. + */ + boolean isProcedure = wp.isExecutable(element_minuscule); + int i; + + if (Primitive.primitives.containsKey(element_minuscule) || isProcedure) + { + + // identifiant de la primitive + if (!isProcedure) + { + i = Integer.valueOf(Primitive.primitives.get(element_minuscule)).intValue() + % Primitive.PRIMITIVE_NUMBER; + } + else + { + //i = -i - 2; + i = -2; // Marko Zivkovic : i now denotes something else than a primitive : if i < -1 => isProcedure + } + // if (!calcul.empty()&&nom.isEmpty()) + // throw new + // monException(cadre,Logo.messages.getString("que_faire")+" + // "+calcul.pop() +" gdfdsf"); + // exécuter la procédure ou la primitive. + Stack<String> param = new Stack<String>(); + if (isInfixedOperator(i)) + { // Si c'est un opérateur infixé + deleteLineNumber(); + operateur = true; + operande = false; + /* + * if (drapeau_ouvrante) { drapeau_ouvrante=false; + * if (i!=32&&i!=33) throw new myException(element+" + * "+Logo.messages.getString("ne_peut_etre")); else + * param.push("0"); } + */ + // else + if (calcul.isEmpty()) + { // Si le + ou le - représente le + // signe négatif ou positif + if (i != 32 && i != 33) + throw new LogoError(element + " " + Logo.messages.getString("error.ne_peut_etre")); // d'un + // nombre + if (nom.isEmpty()) + param.push("0"); + else + { + String st = nom.peek(); + if (!testoperateur(st)) + param.push("0"); + else if ("*/".indexOf(st) > -1) + { // Si le signe - + // ou + suit un + // * ou / + instructionBuffer.deleteFirstWord(element); + if (st.equals("*")) + instructionBuffer.insert("* "); + else + instructionBuffer.insert("/ "); + if (i == 32) + return ("1"); // Si c'est un plus + else + return ("-1"); // Si c'est un moins + } + else + param.push("0"); + } + } + else if (nom.isEmpty()) + { + param.push(calcul.pop()); + } + else + { + String st = nom.peek(); + if (testoperateur(st)) + { + // System.out.println("st "+st+" element "+element+" + // "+prioriteinf(st,element)); + if (prioriteinf(st, element)) + { + param.push(calcul.pop()); + } + else + return (calcul.pop()); + } + else + param.push(calcul.pop()); + } + }// END: INFIX OPERATOR + else if (operande && i != 204) + { + checkParenthesis(); + operande = false; + break; + } // Si ce n'est pas l'opérateur de fin de parenthèse, on sort + + /* + * Example: + * To test | Formatted Form: + * fd 5 | fd 5 \l1 rt \l2 + * rt | --> The \l2 can't be removed before be + * end | sure the rt has noproblem + */ + if (!element.equals("\n")) + deleteLineNumber(); + instructionBuffer.deleteFirstWord(element); + + // Case with parenthensis + // eg (sum 3 4 5) + // eg (myProcedure 2 3 4 5) + if (drapeau_ouvrante) + { + drapeau_ouvrante = false; + int constantNumber = -1; + if (!hasGeneralForm(element_minuscule, i)) + { + if (!isProcedure) + constantNumber = kernel.primitive.parametres[i]; + else + constantNumber = wp.getExecutable(element_minuscule).nbparametre; + } + // Looking for all arguments (Number undefined) + nom.push(element); + int j = 0; + while (true) + { + /* + * This line fixed the bug for primitive or procedure + * without arguments + * eg: pr (pi+2) + */ + if (constantNumber == 0) + break; + try + { + operande = operateur = drapeau_ouvrante = false; + if (instructionBuffer.getNextWord().equals(")")) + { + if (constantNumber != -1) + { + // If the primitive or the procedure doesn't + // accept optional parameters + if (j > constantNumber) + { + throw new LogoError(Logo.messages.getString("too_much_arguments")); + } + else if (j < constantNumber) + throw new LogoError(Logo.messages.getString("pas_assez_de") + " " + nom.peek()); + } + break; + } + String a = execute(new StringBuffer()); + + param.push(a); + } + catch (LogoError e) + { + throw e; + } + j++; + } + // If It's a procedure + + if (isProcedure) + { + if (wp.isProcedureAmbiguous(element_minuscule)) + throw new LogoError(Logo.messages.getString("error.call.ambiguous.procedure.name")); + + Procedure proc = wp.getExecutable(element_minuscule); + + if (j > proc.nbparametre + proc.optVariables.size()) + throw new LogoError(Logo.messages.getString("too_much_arguments")); + else if (j < proc.nbparametre) + throw new LogoError(Logo.messages.getString("pas_assez_de") + " " + nom.peek()); + // Searching for optional arguments that are not defined + + if (j < proc.optVariables.size() + proc.nbparametre) + { + j = j - proc.nbparametre; + for (int c = j; c < proc.optVariables.size(); c++) + { + try + { + operande = operateur = drapeau_ouvrante = false; + String a = execute(proc.optVariablesExp.get(c)); + param.push(a); + } + catch (LogoError e) + { + throw e; + } + } + } + } + + } + // classic case: predefined number of arguments + else + { + drapeau_ouvrante = false; + // How many arguments for the procedure or the primitive + int nbparametre = 0; + // For primitive + if (!isProcedure) + nbparametre = kernel.primitive.parametres[i]; + // For procedure + else + nbparametre = wp.getExecutable(element_minuscule).nbparametre; + // Looking for each arguments + int j = 0; + nom.push(element); + while (j < nbparametre) + { + try + { + operande = operateur = drapeau_ouvrante = false; + + String a = execute(new StringBuffer()); + param.push(a); + j++; + } + catch (LogoError e) + { + throw e; + } + } + // System.out.println(instructionBuffer.toString()); + // System.out.println(nom+"arguments"+param); + // Looking for Optional arguments in case of procedure + if (isProcedure) + { + Procedure proc = wp.getExecutable(element_minuscule); + nbparametre = proc.optVariables.size(); + for (j = 0; j < nbparametre; j++) + { + try + { + operande = operateur = drapeau_ouvrante = false; + String a = execute(proc.optVariablesExp.get(j)); + param.push(a); + } + catch (LogoError e) + { + throw e; + } + } + } + } + + // ////////////////////////////////////////////////////////////////////////////////////////// + // System.out.println(nom+" "+"debut "+instruction+" + // fin\n"+param.toString()); + // System.out.println(nom); + nom.pop(); + if (!app.error) + lanceprim.execute(i, element_minuscule, param); + if (app.error) + break; + if (drapeau_fermante && !calcul.empty()) + { + drapeau_fermante = false; + operande = false; + return calcul.pop(); + } + + // Tester si la procédure rend quelque chose lorsqu'attendu + + if (!operande) + { + // dans le cas des primitives exec ou si + if (renvoi_instruction) + { + renvoi_instruction = false; + } + else + { + if (!nom.isEmpty() && !app.error && !nom.peek().equals("\n")) + { + if (!element.equals("\n")) + { + // If it's the end of a loop + // repeat 2 [fd 90 rt] + if (element.equals("\\")) + { + // The loop had been executed, we have to + // remove + // the loop instruction + int offset = instructionBuffer.indexOf(" \\ "); + instructionBuffer.delete(0, offset + 1); + + throw new LogoError(Logo.messages.getString("pas_assez_de") + " " + nom.peek()); + } + // (av 100) ---> OK + // av av 20 ----> Bad + if (!nom.peek().equals("(")) + throw new LogoError(element + " " + Logo.messages.getString("ne_renvoie_pas") + " " + + nom.peek()); + + } + } + } + } + else + { + // The primitive returns a word or a list. + // There's no primitive or procedure waiting for it. + if (!nom.isEmpty() && nom.peek().equals("\n")) + throw new LogoError(Logo.messages.getString("error.whattodo") + " " + calcul.peek() + " ?"); + } + } + + /* ******************************** + * / IF element IS A VARIABLE + * ******************************** + */ + else if (element.substring(0, 1).equals(":") && element.length() > 1) + { + // System.out.println(operande); + if (operande) + { + checkParenthesis(); + operande = false; + break; + } + else + deleteLineNumber(); + String value; + String variableName = element_minuscule.substring(1, element_minuscule.length()); + // If the variable isn't local + if (!locale.containsKey(variableName)) + { + // check it's a global variable + if (!wp.getGlobals().getVariables().contains(variableName)) // TODO + // CHECK + throw new LogoError(variableName + " " + Logo.messages.getString("error.novalue")); + else + value = wp.getGlobals().getValue(variableName).toString(); // TODO + // CHECK + } + // If the variable is local + else + { + value = locale.get(variableName); + } + + if (null == value) + throw new LogoError(variableName + " " + Logo.messages.getString("error.novalue")); + calcul.push(value); + operande = true; + operateur = false; + drapeau_ouvrante = false; + instructionBuffer.deleteFirstWord(element); + } + else + { + /* ***************************** + * IF element IS A NUMBER ****** + * ************************** + */ + try + { + Double.parseDouble(element); + boolean deleteEndZero = false; + if (element.endsWith(".0")) + { + deleteEndZero = true; + element = element.substring(0, element.length() - 2); + } + /* + * boolean addStartZero=false; + * if (element.startsWith(".") || element.equals("")){ + * element = "0" + element; + * addStartZero=true; + * } + */ + calcul.push(element); + if (operande) + { + checkParenthesis(); + calcul.pop(); + operande = false; + break; + } + else + deleteLineNumber(); + operande = true; + operateur = false; + drapeau_ouvrante = false; + // if (addStartZero) + // instructionBuffer.deleteFirstWord(element.substring(1)); + if (deleteEndZero) + instructionBuffer.deleteFirstWord(element + ".0"); + else + instructionBuffer.deleteFirstWord(element); + + } + catch (NumberFormatException e) + { + /* ********************************* + * IF element IS A SQUARE BRACKET [ + * OPEN + * ********************************** + */ + if (element.equals("[")) + { + + // Utilité de cette ligne? + // if (!calcul.isEmpty()&&operateur==false) break; + if (operande) + { + checkParenthesis(); + break; + } + else + deleteLineNumber(); + operande = true; + operateur = false; + drapeau_ouvrante = false; + instructionBuffer.deleteFirstWord(element); + String a = chercheListe(); + calcul.push(a); + } + /* *************************** + * IF element IS A PARENTHESIS + * OPEN + * *********************** + */ + else if (element.equals("(")) + { + if (operande) + { + checkParenthesis(); + break; + } + else + deleteLineNumber(); + drapeau_ouvrante = true; + + Interprete.en_cours.push("("); + int pos = chercheParenthese(); + if (pos == -1) + { + try + { + throw new LogoError(Logo.messages.getString("parenthese_fermante")); + } + catch (LogoError e1) + {} + } + instructionBuffer.deleteFirstWord(element); + // System.out.println("&&"+instruction); + Interprete.nom.push("("); + } + /* ********************************** + * IF element IS A WORD + * ************************** + */ + else if (element.substring(0, 1).equals("\"")) + { + try + { + String el = element.substring(1); + Double.parseDouble(el); + calcul.push(el); + } + catch (NumberFormatException e1) + { + calcul.push(element); + } + if (operande) + { + checkParenthesis(); + calcul.pop(); + operande = false; + break; + } + else + deleteLineNumber(); + operande = true; + operateur = false; + drapeau_ouvrante = false; + instructionBuffer.deleteFirstWord(element); + } + // Si c'est le mot pour + else if (element_minuscule.equals(Logo.messages.getString("pour"))) + { + instructionBuffer.deleteFirstWord(element); + if (instructionBuffer.getLength() != 0) + { + element = instructionBuffer.getNextWord(); + element_minuscule = element.toLowerCase(); + } + else + throw new LogoError(Logo.messages.getString("pas_assez_de") + " " + "\"" + + Logo.messages.getString("pour") + "\""); + if (Primitive.primitives.containsKey(element_minuscule) || wp.isExecutable(element_minuscule)) // TODO + // check + throw new LogoError(element + " " + Logo.messages.getString("existe_deja")); + else + { + String definition = Logo.messages.getString("pour") + " " + element + " "; + instructionBuffer.deleteFirstWord(element); + while (instructionBuffer.getLength() != 0) + { + element = instructionBuffer.getNextWord().toLowerCase(); + if (null == element) + break; + if (!element.substring(0, 1).equals(":") || element.length() == 1) + throw new LogoError(element + " " + Logo.messages.getString("pas_argument")); + definition += element + " "; + instructionBuffer.deleteFirstWord(element); + } + if (app.editeur.getComponent().isVisible()) + throw new LogoError(Logo.messages.getString("ferme_editeur")); + else + { + app.editeur.getComponent().setVisible(true); + app.editeur.setEditorStyledText(definition + "\n\n" + Logo.messages.getString("fin")); + } + } + } + else if (element.startsWith("\\l")) + { + if (operande) + { + break; + } + instructionBuffer.deleteFirstWord(element); + lineNumber = element + " "; + element = instructionBuffer.getNextWord(); + + } + else + { + deleteLineNumber(); + throw new LogoError(Logo.messages.getString("je_ne_sais_pas") + " " + element); + } + } + } + // System.out.println("instruction "+instruction+" calcul "+calcul); + } + /* ****************************** + * **** END OF THE MAIN LOOP + * ***************************** + */ + // S'il n'y a rien à retourner. + if (calcul.isEmpty()) + { + if (!nom.isEmpty()) + {// &&!nom.peek().equals("\n")) { + while ((!nom.isEmpty()) && nom.peek().equals("\n")) + nom.pop(); + if (!nom.isEmpty()) { throw new LogoError(Logo.messages.getString("pas_assez_de") + " " + nom.peek()); } + } + } + // Sinon on retourne la valeur contenue dans la pile de calcul. + if (!calcul.isEmpty()) + { + // S'il y a une procédure de lancer + // Ex: pour t -- 6 -- fin . Puis, av t. + if ((!nom.isEmpty()) && nom.peek().equals("\n")) + { + String up = ""; + int id = 0; + while (!nom.isEmpty() && nom.peek().equals("\n")) + { + nom.pop(); + id++; + } + if (!nom.isEmpty()) + { + up = nom.peek().toString(); + try + { + throw new LogoError(en_cours.get(en_cours.size() - id) + " " + + Logo.messages.getString("ne_renvoie_pas") + " " + up); + } + catch (LogoError e) + {} + } + else + { + try + { + throw new LogoError(Logo.messages.getString("error.whattodo") + " " + calcul.peek() + " ?"); + } + catch (LogoError e) + {} + } + /* + * } + * if (!nom.isEmpty() && nom.peek().equals("\n")) { + * up = en_cours.get(en_cours.size() - 2).toString(); + * try { + * throw new myException( en_cours.peek() + " " + * + Logo.messages.getString("ne_renvoie_pas") + * + " " + up); + * } catch (myException e) { + * } + * } else if (!nom.isEmpty()) { + * up = nom.peek().toString(); + * try { + * throw new myException( en_cours.peek() + " " + * + Logo.messages.getString("ne_renvoie_pas") + * + " " + up); + * } catch (myException e) { + * } + * } else { + * try { + * throw new myException( Logo.messages + * .getString("que_faire") + * + " " + calcul.peek() + " ?"); + * } catch (myException e) { + * }} + */ + + } + // /////////// + else + { + operande = false; + return (calcul.pop()); + } + } + return (""); + } + + private int chercheParenthese() + { // position ou s'arrete la prochaine + // parenthese + boolean continuer = true; + int of_ouvrant; + int of_fermant = 0; + int from_index_ouvrant = 1; + int from_index_fermant = 1; + while (continuer) + { + of_ouvrant = instructionBuffer.indexOf("(", from_index_ouvrant); + of_fermant = instructionBuffer.indexOf(")", from_index_fermant); + if (of_fermant == -1) + break; + if (of_ouvrant != -1 && of_ouvrant < of_fermant) + { + from_index_ouvrant = of_ouvrant + 1; + from_index_fermant = of_fermant + 1; + } + else + continuer = false; + ; + } + return of_fermant; + } + + protected String chercheListe() throws LogoError + { + String liste = "[ "; + String element = ""; + while (instructionBuffer.getLength() != 0) + { + element = instructionBuffer.getNextWord(); + // SI crochet ouvrant, on l'empile dans la pile de calcul + if (element.equals("[")) + { + calcul.push("["); + instructionBuffer.deleteFirstWord(element); + liste += "[ "; + } + + else if (element.equals("]")) + { // Si on atteint un crochet fermant + instructionBuffer.deleteFirstWord(element); + // if (((Stack)instruction.peek()).isEmpty()) instruction.pop(); + liste += "] "; + if (calcul.empty()) + { + return (liste); + } // 1er cas: rien dans la pile de calcul, on renvoie la liste + else if (!calcul.peek().toString().equals("[")) + { + return (liste); + } // 2eme cas: pas de crochet ouvrant en haut de la pile, idem + else + calcul.pop(); // 3eme cas: un crochet ouvrant en haut de + // la pile, on l'enleve + } + else + { + instructionBuffer.deleteFirstWord(element); + liste += element + " "; + } + } + throw new LogoError(Logo.messages.getString("erreur_crochet")); + } + + private boolean testoperateur(String st) + { // l'élément trouvé est-il un + // opérateur + int i = "+-*/<>=!&|".indexOf(st); + if (i == -1) + return (false); + return (true); + } + + /** + * This method compares the two operators op and str.<br> + * Cette methode teste si l'operateur op (sommet de la pile d'appel) + * est de priorite strictement inferieur a str + * + * @param op + * The first operator + * @param str + * The second operator + * @return true if op has a minor priority than str. + */ + + private boolean prioriteinf(String op, String str) + { /* + * if (parenthesefermante>0) return(false); // + * else + */ + if (isTimesDiv(str) && !isTimesDiv(op)) + return (true); + else if (isPlusMinus(str) && isLogicOperator(op)) + return (true); + else if (">=<=".indexOf(str) > -1 && "|&".indexOf(op) > -1) + return (true); + return (false); + } + + /* + * private int isProcedure(String mot) { // vérifie si mot est une + * procédure + * for (int i = 0; i < wp.getNumberOfProcedure(); i++) { + * if (wp.getProcedure(i).name.equals(mot)) + * return (i); + * } + * return (-1); + * } + */ + + protected void setWorkspace(UserSpace workspace) + { + wp = workspace; + lanceprim.setWorkspace(workspace); + } + + private boolean hasGeneralForm(String name, int i) + { + // If it's a procedure + if (wp.isExecutable(name)) + return !wp.getExecutable(name).optVariables.isEmpty(); + return kernel.primitive.generalForm[i]; + } + + private void checkParenthesis() throws LogoError + { + if (!nom.isEmpty()) + { + String name = nom.peek(); + if (name.equals("(")) { throw new LogoError(Logo.messages.getString("too_much_arguments")); + + } + } + + } + + private void deleteLineNumber() + { + lineNumber = ""; + } + + /** + * This method indicates if a primitive is an infixed operator<br> + * Infixed operators are for example: +,-,*-,/,&,>=..... + * + * @param id + * The integer identifiant for the primitive + * @return true or false if it's an infixed operator + */ + private boolean isInfixedOperator(int id) + { + boolean b1 = (29 < id) && (id < 39); + boolean b2 = (id == 273) || (id == 274); + return b1 || b2; + } + + /** + * This metods tests if the String op is a logic operator, ie a string like + * |,&,<,>,=,>=,<= + * + * @param op + * The operator to test + * @return true if op is a logic operator + */ + private boolean isLogicOperator(String op) + { + return ("|&>=<=".indexOf(op) != -1); + + } + + /** + * This metods tests if the String op is + or - + * + * @param op + * The operator to test + * @return true if op is + or - + */ + private boolean isPlusMinus(String op) + { + return (op.equals("+") || op.equals("-")); + } + + /** + * This metods tests if the String op is / or * + * + * @param op + * The operator to test + * @return true if op is * or / + */ + private boolean isTimesDiv(String op) + { + return (op.equals("*") || op.equals("/")); + } + + /** + * @return + * @uml.property name="instructionBuffer" + */ + protected InstructionBuffer getInstructionBuffer() + { + return instructionBuffer; + } +} diff --git a/logo/src/xlogo/kernel/Kernel.java b/logo/src/xlogo/kernel/Kernel.java new file mode 100644 index 0000000..108fef4 --- /dev/null +++ b/logo/src/xlogo/kernel/Kernel.java @@ -0,0 +1,211 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.util.ArrayList; +import java.awt.Color; + +import xlogo.kernel.userspace.UserSpace; +import xlogo.storage.user.DrawQuality; +import xlogo.storage.workspace.Language; +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +import xlogo.Application; + +public class Kernel +{ + protected static long chrono = 0; + + protected ArrayFlow flows = new ArrayFlow(); // Contient les + // flux de + // lecture ou + // d'écriture + + protected static boolean mode_trace = false; // true si le + // mode trace + // est + // enclenchée + // (permet de + // suivre les + // procédures) + + // interprete the user command and launch primitive and procedure + private Interprete interprete; + // For all drawing operation + // protected DrawPanel dg; + // For primitive + protected Primitive primitive = null; + private UserSpace userSpace; + private Application app; + private MP3Player mp3Player; + private MyCalculator myCalculator; + + public Kernel(Application app, UserSpace userSpace) + { + this.app = app; + this.userSpace = userSpace; + initCalculator(-1); + } + + public UserSpace getWorkspace() + { + return userSpace; + } + + public void setWorkspace(UserSpace workspace) + { + userSpace = workspace; + interprete.setWorkspace(userSpace); + } + + protected String listSearch() throws xlogo.kernel.LogoError + { + return interprete.chercheListe(); + } + + public void fcfg(Color color) + { + app.getDrawPanel().fcfg(color); + } + + public Turtle getActiveTurtle() + { + return app.getDrawPanel().tortue; + } + + public MyCalculator getCalculator() + { + return myCalculator; + } + + public void fcc(Color color) + { + app.getDrawPanel().fcc(color); + } + + public void vide_ecran() + { + app.getDrawPanel().videecran(); + } + + public void setNumberOfTurtles(int i) + { + app.getDrawPanel().setNumberOfTurtles(i); + } + + public void setDrawingQuality(DrawQuality q) + { + app.getDrawPanel().setQuality(q); + } + + public Color getScreenBackground() + { + return app.getDrawPanel().getBackgroundColor(); + } + + public void change_image_tortue(String chemin) + { + app.getDrawPanel().change_image_tortue(app, chemin); + } + + public void initGraphics() + { + app.getDrawPanel().initGraphics(); + } + + public void buildPrimitiveTreemap(Language lang) + { + primitive.buildPrimitiveTreemap(lang); + } + + public String execute(StringBuffer st) throws LogoError + { + return interprete.execute(st); + } + + protected void initCalculator(int s) + { + myCalculator = new MyCalculator(s); + + } + + public void initPrimitive() + { + primitive = new Primitive(app); + } + + public void initInterprete() + { + interprete = new Interprete(app); + } + + /** + * Returns the InstructionBuffer containing all commands to execute + */ + public InstructionBuffer getInstructionBuffer() + { + return interprete.getInstructionBuffer(); + } + + public void setMp3Player(MP3Player mp3Player) + { + this.mp3Player = mp3Player; + } + + public MP3Player getMp3Player() + { + return mp3Player; + } + + class ArrayFlow extends ArrayList<MyFlow> + { + ArrayFlow() + { + super(); + } + + private static final long serialVersionUID = 1L; + + protected int search(int id) + { + for (int i = 0; i < size(); i++) + { + if (get(i).getId() == id) + return i; + } + return -1; + } + + } +} diff --git a/logo/src/xlogo/kernel/LaunchPrimitive.java b/logo/src/xlogo/kernel/LaunchPrimitive.java new file mode 100644 index 0000000..47827cd --- /dev/null +++ b/logo/src/xlogo/kernel/LaunchPrimitive.java @@ -0,0 +1,4751 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +package xlogo.kernel; + +import java.util.Stack; +import java.util.Vector; +import java.util.Iterator; +import java.util.HashMap; +import java.util.StringTokenizer; +import java.util.Calendar; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import javax.imageio.*; + +import java.io.*; + +import javax.swing.JOptionPane; +import javax.swing.ImageIcon; +import javax.swing.Icon; +import javax.vecmath.Point3d; + +import java.math.BigDecimal; + +import xlogo.storage.WSManager; +import xlogo.storage.global.GlobalConfig; +import xlogo.storage.user.DrawQuality; +import xlogo.storage.user.PenShape; +import xlogo.storage.user.UserConfig; +import xlogo.storage.workspace.Language; +import xlogo.utils.Utils; +import xlogo.gui.Lis; +import xlogo.gui.MyTextAreaDialog; +import xlogo.kernel.DrawPanel; +import xlogo.gui.HistoryPanel; +import xlogo.Application; +import xlogo.Logo; +import xlogo.kernel.network.*; +import xlogo.kernel.gui.*; +import xlogo.kernel.perspective.ElementPolygon; +import xlogo.kernel.perspective.ElementLine; +import xlogo.kernel.perspective.ElementPoint; +import xlogo.kernel.userspace.UserSpace; +import xlogo.kernel.userspace.files.LogoFile; +import xlogo.kernel.userspace.procedures.Procedure; +import xlogo.messages.async.history.HistoryMessenger; + +/******************************************************************************* + * When a primitive or a procedure has all arguments, LauchPrimitive executes + * the appropriate code. + ******************************************************************************/ +public class LaunchPrimitive +{ + /** + * Default Application frame + */ + private Application cadre; + /** + * Default kernel + */ + private Kernel kernel; + /** + * Default workspace + */ + private UserSpace wp; + + private Procedure procedure; + // private MathContext mc=MathContext.DECIMAL64; + /** + * This is the start for the String returned by primitive or procedure.<br> + * It is "\"" for words and "" for numbers. <br> + * <br> + * Ceci est le début de la chaine générique renvoyé par les primitives<br> + * Elle vaut "\"" pour les mots et "" pour les nombres<br> + */ + private String debut_chaine = ""; + /** + * When we launch the primitive "listentcp", we have to save workspaces + */ + //private Stack<LogoContext> savedWorkspace; + + /** + * @param cadre + * Default frame Application + * @param wp + * Default workspace + */ + public LaunchPrimitive(Application cadre, UserSpace wp) + { + this.wp = wp; + this.cadre = cadre; + this.kernel = cadre.getKernel(); + } + + /** + * Execute the primitive number "id" with the arguments contained in "param"<br> + * <ul> + * <li>if id<0: it is a procedure. <br> + * For example, if id=-3, it is procedure number -i-2=-(-3)-2=1</li> + * <li>if d>=0: it is primitive number "id"</li> + * </ul> + * + * @param id + * The number representing the procedure or the primitive + * @param param + * The Stack that contains all arguments + */ + protected void execute(int id, String element_minuscule, Stack<String> param) throws LogoError + { + UserConfig uc = WSManager.getUserConfig(); + int w = uc.getImageWidth(); + int h = uc.getImageHeight(); + Font font = WSManager.getWorkspaceConfig().getFont(); + String defaultFolder; + + // identifiant procédure ou primitive, valeur des paramètres + if (id < 0) + { + procedure = wp.getExecutable(element_minuscule); + Interprete.stockvariable.push(Interprete.locale); + Interprete.locale = new HashMap<String, String>(); + // Read local Variable + int optSize = procedure.optVariables.size(); + int normSize = procedure.variable.size(); + for (int j = 0; j < optSize + normSize; j++) + { + // Add local Variable + if (j < normSize) + { + Interprete.locale.put(procedure.variable.get(j), param.get(j)); + } // add optional variables + else + { + String value = ""; + if (j < param.size()) + value = param.get(j); + else + value = procedure.optVariablesExp.get(j - param.size()).toString(); + Interprete.locale.put(procedure.optVariables.get(j - normSize), value); + + } + } + // Add Optional variable + if (Kernel.mode_trace) + { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < Interprete.en_cours.size(); i++) + buffer.append(" "); + buffer.append(procedure.name); + for (int i = 0; i < param.size(); i++) + buffer.append(" " + Utils.SortieTexte(param.get(i))); + String msg = buffer + "\n"; + HistoryMessenger.getInstance().dispatchMessage(msg); + } + Interprete.en_cours.push(procedure.name); + procedure.decoupe(); + // Add Procedure code in Interprete.instruction + kernel.getInstructionBuffer().insert("\n "); + kernel.getInstructionBuffer().insertCode(procedure.instr); + // System.out.println("instr " +Interprete.instruction); + // System.out.println("stock "+Interprete.stockInstruction); + // System.out.println("a"+Interprete.instruction+"a"); + Interprete.nom.push("\n"); + } + else + { + Language lang = WSManager.getInstance().getWorkspaceConfigInstance().getLanguage(); + + switch (id) + { + case 0: // av + delay(); + cadre.getDrawPanel().av(kernel.getCalculator().numberDouble(param.pop())); + break; + case 1: // re + delay(); + cadre.getDrawPanel().av(-kernel.getCalculator().numberDouble(param.pop())); + break; + case 2: // td + delay(); + cadre.getDrawPanel().td(kernel.getCalculator().numberDouble(param.pop())); + break; + case 3: // tg + delay(); + cadre.getDrawPanel().td(-kernel.getCalculator().numberDouble(param.pop())); + break; + case 4: // arithmetic.power puissance + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().power(param.get(0), param.get(1))); + break; + case 5: // repete controls.repeat + String liste = getList(param.get(1)); + kernel.primitive.repete(kernel.getCalculator().getInteger(param.get(0)), liste); + break; + case 6: // ve + cadre.getDrawPanel().videecran(); + break; + case 7: // ct + if (kernel.getActiveTurtle().isVisible()) + { + cadre.getDrawPanel().ct_mt(); + cadre.getDrawPanel().tortues_visibles.remove(String.valueOf(kernel.getActiveTurtle().id)); + } + kernel.getActiveTurtle().setVisible(false); + break; + case 8: // mt + if (!kernel.getActiveTurtle().isVisible()) + { + cadre.getDrawPanel().ct_mt(); + cadre.getDrawPanel().tortues_visibles.push(String.valueOf(kernel.getActiveTurtle().id)); + } + kernel.getActiveTurtle().setVisible(true); + break; + case 9: // ecris, ec + int size = param.size(); + String result = ""; + String mot; + for (int i = 0; i < size; i++) + { + String par = param.get(i).trim(); + if (isList(par)) + par = formatList(par.substring(1, par.length() - 1)); + mot = getWord(param.get(i)); + if (null == mot) + result += Utils.SortieTexte(par) + " "; + else + result += Utils.SortieTexte(mot) + " "; + } + HistoryMessenger.getInstance().dispatchLogoOutput(result + "\n"); + break; + case 10: // si // if + + liste = getList(param.get(1)); + liste = new String(Utils.decoupe(liste)); + String liste2 = null; + boolean predicat = predicat(param.get(0)); + InstructionBuffer instruction = cadre.getKernel().getInstructionBuffer(); + if (instruction.getLength() != 0) + { + try + { + String element = instruction.getNextWord(); + // System.out.println("a"+element+"a"); + if (element.startsWith("\\l")) + { + instruction.deleteFirstWord(element); + Interprete.lineNumber = element + " "; + } + if (instruction.charAt(0) == '[') + { + instruction.deleteFirstWord("["); + liste2 = getFinalList(kernel.listSearch()); + liste2 = new String(Utils.decoupe(liste2)); + } + } + catch (Exception e) + {} + } + kernel.primitive.si(predicat, liste, liste2); + Interprete.renvoi_instruction = true; + break; + case 11: // STOP + kernel.primitive.stop(); + break; + case 12: // origine + delay(); + cadre.getDrawPanel().origine(); + break; + case 13: // fpos + delay(); + String list = getFinalList(param.get(0)); + cadre.getDrawPanel().fpos(list); + break; + case 14: // fixex + delay(); + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + { + double x = kernel.getCalculator().numberDouble(param.get(0)); + double y = h / 2 - kernel.getActiveTurtle().corY; + cadre.getDrawPanel().fpos(x + " " + y); + } + else + cadre.getDrawPanel().fpos( + kernel.getCalculator().numberDouble(param.get(0)) + " " + kernel.getActiveTurtle().Y + + " " + kernel.getActiveTurtle().Z); + break; + case 15: // fixey + delay(); + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + { + double y = kernel.getCalculator().numberDouble(param.get(0)); + double x = kernel.getActiveTurtle().corX - w / 2; + cadre.getDrawPanel().fpos(x + " " + y); + } + else + cadre.getDrawPanel().fpos( + kernel.getActiveTurtle().X + " " + kernel.getCalculator().numberDouble(param.get(0)) + + " " + kernel.getActiveTurtle().Z); + break; + case 16: // fixexy + delay(); + primitive2D("drawing.fixexy"); + cadre.getDrawPanel().fpos( + kernel.getCalculator().numberDouble(param.get(0)) + " " + + kernel.getCalculator().numberDouble(param.get(1))); + break; + case 17: // fixecap + delay(); + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + cadre.getDrawPanel().td( + 360 - kernel.getActiveTurtle().heading + + kernel.getCalculator().numberDouble(param.pop())); + else + { + cadre.getDrawPanel().setHeading(kernel.getCalculator().numberDouble(param.pop())); + } + break; + case 18: // lc + kernel.getActiveTurtle().setPenDown(false); + break; + case 19: // bc + kernel.getActiveTurtle().setPenDown(true); + break; + case 20: // gomme + kernel.getActiveTurtle().setPenDown(true); + // if mode penerase isn't active yet + if (kernel.getActiveTurtle().couleurmodedessin.equals(kernel.getActiveTurtle().couleurcrayon)) + { + kernel.getActiveTurtle().couleurmodedessin = kernel.getActiveTurtle().couleurcrayon; + kernel.getActiveTurtle().couleurcrayon = cadre.getDrawPanel().getBackgroundColor(); + kernel.getActiveTurtle().stroke = new BasicStroke(3); // TODO + // make + // member + } + break; + case 21: // inversecrayon + kernel.getActiveTurtle().setPenDown(true); + kernel.getActiveTurtle().setPenReverse(true); + break; + case 22: // dessine + kernel.getActiveTurtle().setPenReverse(false); + kernel.getActiveTurtle().setPenDown(true); + kernel.getActiveTurtle().couleurcrayon = kernel.getActiveTurtle().couleurmodedessin; + kernel.getActiveTurtle().stroke = new BasicStroke(1); // TODO + // make + // member + break; + case 23: // somme + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().add(param)); + break; + + case 24: // difference + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().substract(param)); + break; + case 25: // arithmetic.minus moins (opposé) + Interprete.calcul.push(kernel.getCalculator().minus(param.get(0))); + Interprete.operande = true; + break; + case 26: // produit + Interprete.calcul.push(kernel.getCalculator().multiply(param)); + Interprete.operande = true; + break; + case 27: // div + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().divide(param)); + break; + case 28: // reste + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().remainder(param.get(0), param.get(1))); + break; + case 29: // retourne + kernel.primitive.retourne(param.get(0)); + break; + case 30: // * + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().multiply(param)); + break; + case 31: // diviser / + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().divide(param)); + break; + case 32: // + + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().add(param)); + break; + case 33: // - + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().substract(param)); + break; + case 34: // = + equal(param); + break; + case 35: // < + inf(param); + break; + case 36: // > + sup(param); + break; + case 37: // | + boolean b1 = predicat(param.get(0)); + boolean b2 = predicat(param.get(1)); + b1 = b1 | b2; + if (b1) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + Interprete.operande = true; + break; + case 38: // & + b1 = predicat(param.get(0)); + b2 = predicat(param.get(1)); + b1 = b1 & b2; + if (b1) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + Interprete.operande = true; + break; + case 39: // opérateur interne \n signalant une fin de + // procédure + Interprete.locale = Interprete.stockvariable.pop(); + if (Interprete.nom.peek().equals("\n")) + { + Interprete.nom.pop(); + Interprete.lineNumber = ""; + } + else + { + /* + * Example + * to bug + * av + * end + */ + throw new LogoError(Logo.messages.getString("pas_assez_de") + " " + Interprete.nom.peek()); + } + /* + * to bug [:a] | (bug 10) + * av :a | + * end | + */ + if (!Interprete.nom.isEmpty() && !Interprete.nom.peek().equals("\n") + && !Interprete.nom.peek().equals("(")) + { + if (!cadre.error) + throw new LogoError(Interprete.en_cours.peek() + " " + + Logo.messages.getString("ne_renvoie_pas") + " " + + Interprete.nom.peek().toString()); + } + if (!Interprete.en_cours.isEmpty()) + Interprete.en_cours.pop(); + break; + case 40: // opérateur interne \ signalant une fin de boucle + + LoopProperties loop = Primitive.stackLoop.peek(); + // LOOP REPEAT + if (loop.isRepeat()) + { + BigDecimal compteur = loop.getCounter(); + BigDecimal fin = loop.getEnd(); + if (compteur.compareTo(fin) < 0) + { + loop.incremente(); + Primitive.stackLoop.pop(); + Primitive.stackLoop.push(loop); + cadre.getKernel().getInstructionBuffer().insert(loop.getInstr() + Primitive.END_LOOP + " "); + } + else if (compteur.compareTo(fin) == 0) + { + Primitive.stackLoop.pop(); + } + } + // LOOP FOR or LOOP FOREACH + else if (loop.isFor() || loop.isForEach()) + { + BigDecimal inc = loop.getIncrement(); + BigDecimal compteur = loop.getCounter(); + BigDecimal fin = loop.getEnd(); + if ((inc.compareTo(BigDecimal.ZERO) == 1 && (compteur.add(inc).compareTo(fin) <= 0)) + || (inc.compareTo(BigDecimal.ZERO) == -1 && (compteur.add(inc).compareTo(fin) >= 0))) + { + loop.incremente(); + ((LoopFor) loop).AffecteVar(false); + Primitive.stackLoop.pop(); + Primitive.stackLoop.push(loop); + cadre.getKernel().getInstructionBuffer().insert(loop.getInstr() + Primitive.END_LOOP + " "); + } + else + { + ((LoopFor) loop).DeleteVar(); + Primitive.stackLoop.pop(); + } + } + // LOOP FOREVER + else if (loop.isForEver()) + { + cadre.getKernel().getInstructionBuffer().insert(loop.getInstr() + Primitive.END_LOOP + " "); + } + // LOOP FILL POLYGON + else if (loop.isFillPolygon()) + { + cadre.getDrawPanel().stopRecord2DPolygon(); + Primitive.stackLoop.pop(); + } + break; + case 41: // pos + Interprete.operande = true; + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + { + double a = kernel.getActiveTurtle().corX - w / 2; + double b = h / 2 - kernel.getActiveTurtle().corY; + Interprete.calcul.push("[ " + MyCalculator.teste_fin_double(a) + " " + + MyCalculator.teste_fin_double(b) + " ] "); + } + else + { + Interprete.calcul.push("[ " + kernel.getActiveTurtle().X + " " + kernel.getActiveTurtle().Y + + " " + kernel.getActiveTurtle().Z + " ] "); + + } + break; + case 42: // cap + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(kernel.getActiveTurtle().heading)); + break; + case 43: // arrondi + Interprete.operande = true; + Interprete.calcul + .push(String.valueOf(Math.round(kernel.getCalculator().numberDouble(param.get(0))))); + break; + case 44: // log10 + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().log10(param.get(0))); + break; + case 45: // arithmetic.sin + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().sin(param.get(0))); + break; + case 46: // arithmetic.cos + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().cos(param.get(0))); + break; + case 47: // ou + ou(param); + break; + case 48: // et + et(param); + break; + case 49: // non + Interprete.operande = true; + b1 = predicat(param.get(0)); + if (b1) + Interprete.calcul.push(Logo.messages.getString("faux")); + else + Interprete.calcul.push(Logo.messages.getString("vrai")); + break; + case 50: // liste + liste = "[ "; + Interprete.operande = true; + String mot2; + for (int i = 0; i < param.size(); i++) + { + mot2 = param.get(i); + mot = getWord(param.get(i)); + if (null == mot) + { + liste += mot2; + // System.out.println("a"+mot2+"a"); + } + else + { + if (mot.equals("")) + mot = "\\v"; + liste += mot + " "; + } + } + Interprete.calcul.push(liste + "] "); + break; + case 51: // phrase + liste = "[ "; + Interprete.operande = true; + for (int i = 0; i < param.size(); i++) + { + mot = getWord(param.get(i)); + mot2 = param.get(i).trim(); + if (null == mot) + { + if (isList(mot2)) + liste += mot2.substring(1, mot2.length() - 1).trim() + " "; + else + liste += mot2 + " "; + } + else + { + if (mot.equals("")) + mot = "\\v"; + liste += mot + " "; + } + } + Interprete.calcul.push(liste + "] "); + break; + case 52: // metspremier + liste = getFinalList(param.get(1)); + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null != mot && mot.equals("")) + mot = "\\v"; + if (null == mot) + { + if (!liste.equals("")) + Interprete.calcul.push("[ " + param.get(0).trim() + " " + liste.trim() + " ] "); + else + Interprete.calcul.push("[ " + param.get(0).trim() + " ] "); + } + else + { + if (!liste.equals("")) + Interprete.calcul.push("[ " + mot + " " + liste.trim() + " ] "); + else + Interprete.calcul.push("[ " + mot + " ] "); + } + break; + case 53: // metsdernier + liste = getFinalList(param.get(1)).trim(); + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null != mot && mot.equals("")) + mot = "\\v"; + if (null == mot) + { // Si c'est une liste + Interprete.calcul.push(("[ " + liste).trim() + " " + param.get(0).trim() + " ] "); + + } + else + Interprete.calcul.push(("[ " + liste).trim() + " " + mot + " ] "); + + break; + case 54: // inverse liste + liste = getFinalList(param.get(0)).trim(); + Interprete.operande = true; + StringTokenizer st = new StringTokenizer(liste); + liste = " ] "; + String element = ""; + while (st.hasMoreTokens()) + { + element = st.nextToken(); + if (element.equals("[")) + element = extractList(st); + liste = " " + element + liste; + } + Interprete.calcul.push("[" + liste); + break; + case 55: // choix + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + { + liste = getFinalList(param.get(0)); + int nombre = (int) Math.floor(numberOfElements(liste) * Math.random()) + 1; + String tmp = item(liste, nombre); + if (tmp.equals("\"\\v")) + tmp = "\""; + Interprete.calcul.push(tmp); + } + else + { + int nombre = (int) Math.floor(Math.random() * getWordLength(mot)) + 1; + String str = ""; + try + { + str = itemWord(nombre, mot); + Double.parseDouble(str); + Interprete.calcul.push(str); + } + catch (NumberFormatException e1) + { + Interprete.calcul.push("\"" + str); + } + } + break; + case 56: // enleve + Interprete.operande = true; + liste = getFinalList(param.get(1)); + st = new StringTokenizer(liste); + liste = "[ "; + mot = getWord(param.get(0)); + String str; + if (null != mot && mot.equals("")) + mot = "\\v"; + if (null == mot) + mot = param.get(0).trim(); + + while (st.hasMoreTokens()) + { + str = st.nextToken(); + if (str.equals("[")) + str = extractList(st); + if (!str.equals(mot)) + liste += str + " "; + } + Interprete.calcul.push(liste.trim() + " ] "); + break; + case 57: // item + Interprete.operande = true; + mot = getWord(param.get(1)); + if (null == mot) + Interprete.calcul.push(item(getFinalList(param.get(1)), + kernel.getCalculator().getInteger(param.get(0)))); + else + { + int i = kernel.getCalculator().getInteger(param.get(0)); + if (i < 1 || i > getWordLength(mot)) + throw new LogoError(Utils.primitiveName("item") + " " + + Logo.messages.getString("n_aime_pas") + i + " " + + Logo.messages.getString("comme_parametre") + "."); + else + { + str = itemWord(i, mot); + try + { + Double.parseDouble(str); + Interprete.calcul.push(str); + } + catch (NumberFormatException e1) + { + Interprete.calcul.push("\"" + str); + } + } + } + break; + case 58: // saufdernier + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + { + liste = getFinalList(param.get(0)).trim(); + element = item(liste, numberOfElements(liste)); + int longueur = element.length(); + + if (element.startsWith("\"") || element.startsWith("[")) + longueur--; + Interprete.calcul.push("[ " + liste.substring(0, liste.length() - longueur) + "] "); + } + else if (mot.equals("")) + { + throw new LogoError(Logo.messages.getString("mot_vide")); + } + else if (getWordLength(mot) == 1) + Interprete.calcul.push("\""); + else + { + String tmp = mot.substring(0, mot.length() - 1); + if (tmp.endsWith("\\")) + tmp = tmp.substring(0, tmp.length() - 1); + try + { + Double.parseDouble(tmp); + Interprete.calcul.push(tmp); + } + catch (NumberFormatException e) + { + Interprete.calcul.push(debut_chaine + tmp); + } + } + break; + case 59: // saufpremier + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + { + liste = getFinalList(param.get(0)).trim(); + element = item(liste, 1); + int longueur = element.length(); + if (element.startsWith("\"") || element.startsWith("[")) + longueur--; + Interprete.calcul.push("[" + liste.substring(longueur, liste.length()) + " ] "); + } + else if (mot.equals("")) + { + throw new LogoError(Logo.messages.getString("mot_vide")); + } + else if (getWordLength(mot) == 1) + Interprete.calcul.push("\""); + else + { + if (!mot.startsWith("\\")) + mot = mot.substring(1); + else + mot = mot.substring(2); + try + { + Double.parseDouble(mot); + Interprete.calcul.push(mot); + } + catch (NumberFormatException e) + { + Interprete.calcul.push(debut_chaine + mot); + } + } + + break; + case 60: // dernier + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + { // Si c'est une liste + liste = getFinalList(param.get(0)); + Interprete.calcul.push(item(liste, numberOfElements(liste))); + } + else if (getWordLength(mot) == 1) + Interprete.calcul.push(debut_chaine + mot); + else + { + str = ""; + try + { + str = itemWord(getWordLength(mot), mot); + Double.parseDouble(str); + Interprete.calcul.push(str); + } + catch (NumberFormatException e1) + { + Interprete.calcul.push("\"" + str); + } + } + break; + case 61: // premier first + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + { // SI c'est une liste + liste = getFinalList(param.get(0)); + // System.out.println("b"+item(liste, 1)+"b"); + Interprete.calcul.push(item(liste, 1)); + } + else if (getWordLength(mot) == 1) + Interprete.calcul.push(debut_chaine + mot); + else + { + str = ""; + try + { + str = itemWord(1, mot); + Double.parseDouble(str); + Interprete.calcul.push(str); + } + catch (NumberFormatException e2) + { + Interprete.calcul.push("\"" + str); + } + } + break; + case 62: // compte + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + { + liste = getFinalList(param.get(0)); + Interprete.calcul.push(String.valueOf(numberOfElements(liste))); + } + else + Interprete.calcul.push(String.valueOf(getWordLength(mot))); + break; + case 63: // mot? + mot = getWord(param.get(0)); + if (null == mot) + Interprete.calcul.push(Logo.messages.getString("faux")); + else + Interprete.calcul.push(Logo.messages.getString("vrai")); + Interprete.operande = true; + break; + case 64: // nombre? + try + { + Double.parseDouble(param.get(0)); + Interprete.calcul.push(Logo.messages.getString("vrai")); + } + catch (NumberFormatException e) + { + Interprete.calcul.push(Logo.messages.getString("faux")); + } + Interprete.operande = true; + break; + case 65: // liste? + liste = param.get(0).trim(); + if (isList(liste)) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + Interprete.operande = true; + break; + case 66: // vide? + liste = param.get(0).trim(); + mot = getWord(param.get(0)); + if (null == mot) + { // si c'est une liste ou un nombre + liste = getFinalList(liste).trim(); + if (liste.equals("")) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + } + else + { // Si c'est un mot + if (mot.equals("")) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + } + Interprete.operande = true; + break; + case 67: // egal? + equal(param); + break; + case 68: // precede? + precede(param); + break; + case 69: // membre ? + membre(param, id); + break; + case 70: // racine arithmetic.sqrt + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().sqrt(param.get(0))); + break; + case 71: // membre + membre(param, id); + break; + case 72: // donne + donne(param); + Interprete.operande = false; + + break; + case 73: // locale + locale(param); + Interprete.operande = false; + break; + case 74: // donnelocale + locale(param); + donne(param); + Interprete.operande = false; + break; + case 75: // fcc + Color color = null; + if (isList(param.get(0))) + { + color = rgb(param.get(0), Utils.primitiveName("fcc")); + } + else + { + int coul = kernel.getCalculator().getInteger(param.get(0)) % DrawPanel.defaultColors.length; + if (coul < 0) + coul += DrawPanel.defaultColors.length; + color = DrawPanel.defaultColors[coul]; + } + cadre.getDrawPanel().fcc(color); + break; + case 76: // fcfg setscreencolor + color = null; + if (isList(param.get(0))) + { + color = rgb(param.get(0), Utils.primitiveName("fcfg")); + } + else + { + int coul = kernel.getCalculator().getInteger(param.get(0)) % DrawPanel.defaultColors.length; + if (coul < 0) + coul += DrawPanel.defaultColors.length; + color = DrawPanel.defaultColors[coul]; + } + cadre.getDrawPanel().fcfg(color); + break; + case 77: // hasard + Interprete.operande = true; + int i = kernel.getCalculator().getInteger(param.get(0)); + i = (int) Math.floor(Math.random() * i); + Interprete.calcul.push(String.valueOf(i)); + break; + case 78: // attends + try + { + int temps = kernel.getCalculator().getInteger(param.get(0)); + if (temps < 0) + { + String attends = Utils.primitiveName("attends"); + throw new LogoError(attends + " " + Logo.messages.getString("attend_positif")); + } + else + { + int nbsecondes = temps / 60; + int reste = temps % 60; + for (i = 0; i < nbsecondes; i++) + { + Thread.sleep(1000); + if (cadre.error) + break; + } + if (!cadre.error) + Thread.sleep(reste * 50 / 3); + } + + } + catch (InterruptedException e2) + {} + break; + case 79: // procedures + Interprete.operande = true; + Interprete.calcul.push(new String(getAllProcedures())); + break; + case 80: // effaceprocedure efp + erase(param.get(0), "procedure"); + break; + + case 81: // effacevariable + erase(param.get(0), "variable"); + break; + case 82: // effacetout erall + /* + * Marko Zivkovic: + * In XLogo4Schools, we delete all files (together with the + * procedures) and clear all variables and property lists. + */ + wp.eraseAll(); + break; + case 83: // mot + Interprete.operande = true; + result = ""; + for (i = 0; i < param.size(); i++) + { + mot = getWord(param.get(i)); + if (null == mot) + throw new LogoError(param.get(i) + " " + Logo.messages.getString("error.word")); + result += mot; + } + try + { + Double.parseDouble(result); + } + catch (NumberFormatException e) + { + result = "\"" + result; + } + Interprete.calcul.push(result); + break; + case 84: // etiquette + String par = param.get(0).trim(); + if (isList(par)) + par = formatList(par.substring(1, par.length() - 1)); + mot = getWord(param.get(0)); + if (null == mot) + cadre.getDrawPanel().etiquette(Utils.SortieTexte(par)); + else + cadre.getDrawPanel().etiquette(Utils.SortieTexte(mot)); + break; + case 85: // /trouvecouleur + if (kernel.getActiveTurtle().isVisible()) + cadre.getDrawPanel().montrecacheTortue(false); + + liste = getFinalList(param.get(0)); + Color r = cadre.getDrawPanel().guessColorPoint(liste); + Interprete.operande = true; + Interprete.calcul.push("[ " + r.getRed() + " " + r.getGreen() + " " + r.getBlue() + " ] "); + if (kernel.getActiveTurtle().isVisible()) + cadre.getDrawPanel().montrecacheTortue(true); + break; + case 86: // fenetre + cadre.getDrawPanel().setWindowMode(DrawPanel.WINDOW_CLASSIC); + break; + case 87: // enroule + cadre.getDrawPanel().setWindowMode(DrawPanel.WINDOW_WRAP); + break; + case 88: // clos + cadre.getDrawPanel().setWindowMode(DrawPanel.WINDOW_CLOSE); + break; + case 89: // videtexte + cadre.getHistoryPanel().vide_texte(); + break; + case 90: // chargeimage + BufferedImage image = null; + + primitive2D("ci"); + image = getImage(param.get(0)); + if (null != image) + cadre.getDrawPanel().chargeimage(image); + break; + case 91: // ftc, fixetaillecrayon + double nombre = kernel.getCalculator().numberDouble(param.get(0)); + if (nombre < 0) + nombre = Math.abs(nombre); + if (DrawPanel.record3D == DrawPanel.record3D_LINE || DrawPanel.record3D == DrawPanel.record3D_POINT) + { + if (kernel.getActiveTurtle().getPenWidth() != (float) nombre) + DrawPanel.poly.addToScene(); + } + kernel.getActiveTurtle().fixe_taille_crayon((float) nombre); + cadre.getDrawPanel().setStroke(kernel.getActiveTurtle().crayon); + if (DrawPanel.record3D == DrawPanel.record3D_LINE) + { + DrawPanel.poly = new ElementLine(cadre.getViewer3D(), cadre.getKernel().getActiveTurtle().getPenWidth()); + DrawPanel.poly.addVertex( + new Point3d(kernel.getActiveTurtle().X / 1000, kernel.getActiveTurtle().Y / 1000, + kernel.getActiveTurtle().Z / 1000), kernel.getActiveTurtle().couleurcrayon); + } + else if (DrawPanel.record3D == DrawPanel.record3D_POINT) + { + DrawPanel.poly = new ElementPoint(cadre.getViewer3D(), cadre.getKernel().getActiveTurtle().getPenWidth()); + } + break; + case 92: // tantque + String li1 = getList(param.get(0)); + li1 = new String(Utils.decoupe(li1)); + String li2 = getList(param.get(1)); + li2 = new String(Utils.decoupe(li2)); + String instr = "\\siwhile " + li1 + "[ " + li2 + "] "; + LoopWhile bp = new LoopWhile(BigDecimal.ONE, BigDecimal.ZERO, BigDecimal.ONE, instr); + Primitive.stackLoop.push(bp); + cadre.getKernel().getInstructionBuffer().insert(instr + Primitive.END_LOOP + " "); + + break; + case 93: // lis + liste = getFinalList(param.get(0)); + mot = getWord(param.get(1)); + if (null == mot) + throw new LogoError(Logo.messages.getString("error.word")); + java.awt.FontMetrics fm = cadre.getFrame().getGraphics().getFontMetrics(font); + int longueur = fm.stringWidth(liste) + 100; + Lis lis = new Lis(liste, longueur); + while (lis.isVisible()) + { + try + { + Thread.sleep(50); + } + catch (InterruptedException e) + {} + } + param = new Stack<String>(); + param.push("\"" + mot); + String phrase = lis.getText(); + // phrase="[ "+Logo.rajoute_backslash(phrase)+" ] "; + StringBuffer tampon = new StringBuffer(); + for (int j = 0; j < phrase.length(); j++) + { + char c = phrase.charAt(j); + if (c == '\\') + tampon.append("\\\\"); + else + tampon.append(c); + } + int offset = tampon.indexOf(" "); + if (offset != -1) + { + tampon.insert(0, "[ "); + tampon.append(" ] "); + } + else + { + try + { + Double.parseDouble(phrase); + } + catch (NumberFormatException e) + { + tampon.insert(0, "\""); + } + } + phrase = new String(tampon); + param.push(phrase); + donne(param); + String texte = liste + "\n" + phrase; + HistoryMessenger.getInstance().dispatchComment(Utils.SortieTexte(texte) + "\n"); + cadre.focus_Commande(); + lis.dispose(); + cadre.focus_Commande(); + break; + case 94: // touche? + Interprete.operande = true; + if (cadre.getCar() != -1) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 95: // siwhile --> Evalue l'expression test du while + liste = getFinalList(param.get(1)); + boolean pred = predicat(param.get(0)); + kernel.primitive.whilesi(pred, liste); + break; + case 96: // liscar + while (cadre.getCar() == -1) + { + try + { + Thread.sleep(100); + } + catch (InterruptedException e) + {} + //if (LogoError.lance) //TODO this was always false + // break; + } + Interprete.calcul.push(String.valueOf(cadre.getCar())); + Interprete.operande = true; + cadre.setCar(-1); + break; + case 97: // remplis + cadre.getDrawPanel().remplis(); + break; + case 98: // point + if (kernel.getActiveTurtle().isVisible()) + cadre.getDrawPanel().montrecacheTortue(false); + + cadre.getDrawPanel().point(getFinalList(param.get(0))); + if (kernel.getActiveTurtle().isVisible()) + cadre.getDrawPanel().montrecacheTortue(true); + break; + case 99: // vers=towards vers + + Interprete.operande = true; + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + { + double angle = cadre.getDrawPanel().vers2D(getFinalList(param.get(0))); + Interprete.calcul.push(MyCalculator.teste_fin_double(angle)); + } + else + { + double[] orientation = cadre.getDrawPanel().vers3D(getFinalList(param.get(0))); + Interprete.calcul.push("[ " + orientation[0] + " " + orientation[1] + " " + orientation[2] + + " ] "); + } + break; + case 100: // distance + Interprete.operande = true; + double distance = cadre.getDrawPanel().distance(getFinalList(param.get(0))); + Interprete.calcul.push(MyCalculator.teste_fin_double(distance)); + break; + case 101: // couleurcrayon + Interprete.operande = true; + Interprete.calcul.push("[ " + kernel.getActiveTurtle().couleurcrayon.getRed() + " " + + kernel.getActiveTurtle().couleurcrayon.getGreen() + " " + + kernel.getActiveTurtle().couleurcrayon.getBlue() + " ] "); + break; + case 102: // couleurfond + Interprete.operande = true; + color = cadre.getDrawPanel().getBackgroundColor(); + Interprete.calcul.push("[ " + color.getRed() + " " + color.getGreen() + " " + color.getBlue() + + " ] "); + break; + case 103: // bc? + Interprete.operande = true; + if (kernel.getActiveTurtle().isPenDown()) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 104: // visible? + Interprete.operande = true; + if (kernel.getActiveTurtle().isVisible()) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 105: // prim? + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + if (Primitive.primitives.containsKey(mot)) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 106: // proc? + Interprete.operande = true; + mot = getWord(param.get(0)); + if (wp.isExecutable(mot)) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 107: // exec + mot = getWord(param.get(0)); + if (null == mot) + { + mot = getList(param.get(0).trim()); + mot = new String(Utils.decoupe(mot)); + } + else + mot = mot + " "; + cadre.getKernel().getInstructionBuffer().insert(mot); + Interprete.renvoi_instruction = true; + break; + case 108: // catalogue + defaultFolder = uc.getDefaultFolder(); + str = Utils.SortieTexte(defaultFolder); + File f = new File(str); + String fichier = ""; + String dossier = ""; + int nbdossier = 0; + int nbfichier = 0; + String[] l = f.list(); + for (i = 0; i < l.length; i++) + { + if ((new File(str + File.separator + l[i])).isDirectory()) + { + nbdossier++; + if (nbdossier % 5 == 0) + dossier += l[i] + "\n"; + else + dossier += l[i] + " "; + } + else + { + nbfichier++; + if (nbfichier % 5 == 0) + fichier += l[i] + "\n"; + else + fichier += l[i] + " "; + } + } + texte = ""; + if (!dossier.equals("")) + texte += Logo.messages.getString("repertoires") + ":\n" + dossier + "\n"; + if (!fichier.equals("")) + texte += Logo.messages.getString("fichiers") + ":\n" + fichier + "\n"; + HistoryMessenger.getInstance().dispatchComment(texte); + break; + case 109: // frepertoire + liste = getWord(param.get(0)); + if (null == liste) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + String chemin = Utils.SortieTexte(liste); + if ((new File(chemin)).isDirectory() && !chemin.startsWith("..")) + { + defaultFolder = Utils.rajoute_backslash(chemin); + uc.setDefaultFolder(defaultFolder); + } + else + throw new LogoError(liste + " " + Logo.messages.getString("erreur_pas_repertoire")); + break; + case 110: // repertoire + Interprete.operande = true; + defaultFolder = uc.getDefaultFolder(); + Interprete.calcul.push("\"" + defaultFolder); + break; + case 111: // sauve + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(Logo.messages.getString("error.word")); + liste = getFinalList(param.get(1)); + st = new StringTokenizer(liste); + Stack<String> pile = new Stack<String>(); + while (st.hasMoreTokens()) + pile.push(st.nextToken()); + saveProcedures(mot, pile); + break; + case 112: // sauved + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + saveProcedures(mot, null); + break; + case 113: // ramene load + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + defaultFolder = uc.getDefaultFolder(); + String path = Utils.SortieTexte(defaultFolder) + File.separator + mot; + String fileName = wp.makeUniqueFileName(mot); + try + { + String txt = Utils.readLogoFile(path); // TODO this + // does not + // work... + // should + // load from + // path.... + // later: + // looks ok, + // not? + wp.createFile(fileName); + wp.writeFileText(fileName, txt); + } + catch (IOException e1) + { + throw new LogoError(Logo.messages.getString("error.iolecture")); + } + + break; + case 114: // pi + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().pi()); + break; + case 115: // tangente arithmetic.tan + Interprete.operande = true; + + Interprete.calcul.push(kernel.getCalculator().tan(param.get(0))); + + break; + case 116: // acos + + Interprete.calcul.push(kernel.getCalculator().acos(param.get(0))); + Interprete.operande = true; + break; + case 117: // asin + + Interprete.calcul.push(kernel.getCalculator().asin(param.get(0))); + Interprete.operande = true; + break; + case 118: // atan + Interprete.calcul.push(kernel.getCalculator().atan(param.get(0))); + Interprete.operande = true; + break; + case 119: // vrai + Interprete.operande = true; + Interprete.calcul.push(Logo.messages.getString("vrai")); + break; + case 120: // faux + Interprete.operande = true; + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 121: // forme + primitive2D("turtle.forme"); + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(kernel.getActiveTurtle().getShape())); + break; + case 122: // fixeforme setshape + primitive2D("turtle.fforme"); + i = kernel.getCalculator().getInteger(param.get(0)) % 7; + if (kernel.getActiveTurtle().id == 0) + { + uc.setActiveTurtle(i); + } + chemin = "tortue" + i + ".png"; + kernel.change_image_tortue(chemin); + break; + case 123: // definis workspace.define + define(param); // Method extracted by Marko Zivkovic + // 21.6.2013 + break; + + case 124: // tortue + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(kernel.getActiveTurtle().id)); + break; + case 125: // tortues + Interprete.operande = true; + String li = "[ "; + for (i = 0; i < cadre.getDrawPanel().tortues.length; i++) + { + if (null != cadre.getDrawPanel().tortues[i]) + li += String.valueOf(i) + " "; + } + li += "]"; + Interprete.calcul.push(li); + break; + case 126: // fixetortue + try + { + i = Integer.parseInt(param.get(0)); + if (i > -1 && i < uc.getMaxTurtles()) + { + if (null == cadre.getDrawPanel().tortues[i]) + { + cadre.getDrawPanel().tortues[i] = new Turtle(cadre); + cadre.getDrawPanel().tortues[i].id = i; + cadre.getDrawPanel().tortues[i].setVisible(false); + } + cadre.getDrawPanel().tortue = cadre.getDrawPanel().tortues[i]; + cadre.getDrawPanel().setStroke(kernel.getActiveTurtle().crayon); + String police = cadre.getDrawPanel().getGraphicsFont().getName(); + cadre.getDrawPanel().setGraphicsFont( + new java.awt.Font(police, java.awt.Font.PLAIN, kernel.getActiveTurtle().police)); + + } + else + { + throw new LogoError(Logo.messages.getString("tortue_inaccessible")); + } + } + catch (NumberFormatException e) + { + kernel.getCalculator().getInteger(param.get(0)); + } + break; + case 127: // police + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(kernel.getActiveTurtle().police)); + break; + case 128: // fixetaillepolice + int taille = kernel.getCalculator().getInteger(param.get(0)); + kernel.getActiveTurtle().police = taille; + Font police = font; + cadre.getDrawPanel().setGraphicsFont(police.deriveFont((float) kernel.getActiveTurtle().police)); + + break; + case 129: // tuetortue + try + { + id = Integer.parseInt(param.get(0)); + if (id > -1 && id < uc.getMaxTurtles()) + { + // On compte le nombre de tortues à l'écran + int compteur = 0; + int premier_dispo = -1; + for (i = 0; i < uc.getMaxTurtles(); i++) + { + if (null != cadre.getDrawPanel().tortues[i]) + { + if (i != id && premier_dispo == -1) + premier_dispo = i; + compteur++; + } + } + // On vérifie que ce n'est pas la seule tortue + // dispopnible: + if (null != cadre.getDrawPanel().tortues[id]) + { + if (compteur > 1) + { + int tortue_utilisee = kernel.getActiveTurtle().id; + cadre.getDrawPanel().tortue = cadre.getDrawPanel().tortues[id]; + cadre.getDrawPanel().ct_mt(); + cadre.getDrawPanel().tortue = cadre.getDrawPanel().tortues[tortue_utilisee]; + cadre.getDrawPanel().tortues[id] = null; + if (cadre.getDrawPanel().tortues_visibles.search(String.valueOf(id)) > 0) + cadre.getDrawPanel().tortues_visibles.remove(String.valueOf(id)); + if (kernel.getActiveTurtle().id == id) + { + cadre.getDrawPanel().tortue = cadre.getDrawPanel().tortues[premier_dispo]; + cadre.getDrawPanel().setStroke(kernel.getActiveTurtle().crayon); // on + // adapte + // le + // nouveau + // crayon + str = cadre.getDrawPanel().getGraphicsFont().getName(); + cadre.getDrawPanel().setFont( + new java.awt.Font(str, java.awt.Font.PLAIN, + kernel.getActiveTurtle().police)); + + } + } + else + { + throw new LogoError(Logo.messages.getString("seule_tortue_dispo")); + } + } + } + } + catch (NumberFormatException e) + { + kernel.getCalculator().getInteger(param.get(0)); + } + break; + case 130: // sequence + liste = getFinalList(param.get(0)); + cadre.getSon().cree_sequence(Utils.decoupe(liste).toString()); + break; + case 131: // instrument + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(cadre.getSon().getInstrument())); + break; + case 132: // fixeinstrument + i = kernel.getCalculator().getInteger(param.get(0)); + cadre.getSon().setInstrument(i); + + break; + case 133: // joue + cadre.getSon().joue(); + break; + case 134: // effacesequence + cadre.getSon().efface_sequence(); + break; + case 135: // indexsequence + Interprete.operande = true; + double d = (double) cadre.getSon().getTicks() / 64; + Interprete.calcul.push(MyCalculator.teste_fin_double(d)); + + break; + case 136: // fixeindexsequence + i = kernel.getCalculator().getInteger(param.get(0)); + cadre.getSon().setTicks(i * 64); + break; + case 137:// fpt + i = kernel.getCalculator().getInteger(param.get(0)); + cadre.getHistoryPanel().getDsd().fixepolice(i); + break; + case 138: // ptexte + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(cadre.getHistoryPanel().police())); + break; + case 139: // fct,fixecouleurtexte + if (isList(param.get(0))) + { + cadre.getHistoryPanel().getDsd().fixecouleur(rgb(param.get(0), Utils.primitiveName("fct"))); + } + else + { + int coul = kernel.getCalculator().getInteger(param.get(0)) % DrawPanel.defaultColors.length; + if (coul < 0) + coul += DrawPanel.defaultColors.length; + cadre.getHistoryPanel().getDsd().fixecouleur(DrawPanel.defaultColors[coul]); + } + break; + case 140: // couleurtexte + Interprete.operande = true; + Color c = cadre.getHistoryPanel().getCouleurtexte(); + Interprete.calcul.push("[ " + c.getRed() + " " + c.getGreen() + " " + c.getBlue() + " ] "); + break; + case 141: // lissouris readmouse + while (!cadre.getDrawPanel().get_lissouris()) + { + try + { + Thread.sleep(100); + } + catch (InterruptedException e) + {} + //if (LogoError.lance) //TODO Marko: this was always false + // break; + } + Interprete.calcul.push(String.valueOf(cadre.getDrawPanel().get_bouton_souris())); + Interprete.operande = true; + break; + case 142: // possouris + Interprete.calcul.push(cadre.getDrawPanel().get_possouris()); + Interprete.operande = true; + break; + case 143: // msg message + liste = getFinalList(param.get(0)); + st = new StringTokenizer(liste); // On + // découpe + // le + // message + // en + // tranche + // de + // longueurs + // acceptables + fm = cadre.getFrame().getGraphics().getFontMetrics(font); + liste = ""; + String buf = ""; + while (st.hasMoreTokens()) + { + buf += st.nextToken() + " "; + if (fm.stringWidth(buf) > 200) + { + liste += buf + "\n"; + buf = ""; + } + } + liste += buf; + liste = Utils.SortieTexte(liste); + + MyTextAreaDialog jt = new MyTextAreaDialog(liste, cadre.getHistoryPanel().getDsd()); + ImageIcon icone = new ImageIcon(Utils.class.getResource("icone.png")); + JOptionPane.showMessageDialog(cadre.getFrame(), jt, "", JOptionPane.INFORMATION_MESSAGE, + (Icon) icone); + break; + case 144: // date + Interprete.operande = true; + Calendar cal = Calendar.getInstance(lang.getLocale()); + int jour = cal.get(Calendar.DAY_OF_MONTH); + int mois = cal.get(Calendar.MONTH) + 1; + int annee = cal.get(Calendar.YEAR); + Interprete.calcul.push("[ " + jour + " " + mois + " " + annee + " ] "); + break; + case 145: // heure + Interprete.operande = true; + cal = Calendar.getInstance(lang.getLocale()); + int heure = cal.get(Calendar.HOUR_OF_DAY); + int minute = cal.get(Calendar.MINUTE); + int seconde = cal.get(Calendar.SECOND); + Interprete.calcul.push("[ " + heure + " " + minute + " " + seconde + " ] "); + break; + case 146: // temps + Interprete.operande = true; + long heure_actuelle = Calendar.getInstance().getTimeInMillis(); + Interprete.calcul.push(String.valueOf((heure_actuelle - uc.getHeure_demarrage()) / 1000)); + break; + case 147: // debuttemps + int temps = kernel.getCalculator().getInteger(param.get(0)); + Kernel.chrono = Calendar.getInstance().getTimeInMillis() + 1000 * temps; + break; + case 148: // fintemps? + Interprete.operande = true; + if (Calendar.getInstance().getTimeInMillis() > Kernel.chrono) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 149: // fnp fixenompolice + int int_police = kernel.getCalculator().getInteger(param.get(0)); + cadre.getDrawPanel().police_etiquette = int_police % UserConfig.fontes.length; + break; + case 150: // np nompolice + Interprete.operande = true; + Interprete.calcul.push("[ " + cadre.getDrawPanel().police_etiquette + " [ " + + UserConfig.fontes[cadre.getDrawPanel().police_etiquette].getFontName() + " ] ] "); + break; + case 151: // fnpt fixenompolicetexte + int_police = kernel.getCalculator().getInteger(param.get(0)); + HistoryPanel.fontPrint = int_police % UserConfig.fontes.length; + cadre.getHistoryPanel().getDsd().fixenompolice(int_police); + + break; + case 152: // npt nompolicetexte + Interprete.operande = true; + Interprete.calcul.push("[ " + HistoryPanel.fontPrint + " [ " + + UserConfig.fontes[HistoryPanel.fontPrint].getFontName() + " ] ] "); + break; + case 153: // listeflux + liste = "[ "; + for (MyFlow flow : kernel.flows) + { + liste += "[ " + flow.getId() + " " + flow.getPath() + " ] "; + } + liste += "] "; + Interprete.operande = true; + Interprete.calcul.push(liste); + break; + case 154: // lisligneflux + try + { + int ident = kernel.getCalculator().getInteger(param.get(0)); + int index = kernel.flows.search(ident); + if (index == -1) + throw new LogoError(Logo.messages.getString("flux_non_disponible") + " " + ident); + MyFlow flow = kernel.flows.get(index); + MyFlowReader flowReader; + // If the flow is a writable flow, throw error + if (flow.isWriter()) + throw new LogoError(Logo.messages.getString("flux_lecture")); + // else if the flow is a readable flow, convert to + // MyFlowReader + else if (flow.isReader()) + { + flowReader = ((MyFlowReader) flow); + } + // else the flow isn't yet defined, initialize + else + flowReader = new MyFlowReader(flow); + + if (flowReader.isFinished()) + throw new LogoError(Logo.messages.getString("fin_flux") + " " + ident); + // Reading line + String line = flowReader.readLine(); + if (null == line) + { + flow.setFinished(true); + throw new LogoError(Logo.messages.getString("fin_flux") + " " + ident); + } + Interprete.operande = true; + Interprete.calcul.push("[ " + Utils.decoupe(line.trim()) + " ] "); + kernel.flows.set(index, flowReader); + } + catch (FileNotFoundException e1) + { + throw new LogoError(Logo.messages.getString("error.iolecture")); + } + catch (IOException e2) + {} + break; + case 155: // liscaractereflux + try + { + int ident = kernel.getCalculator().getInteger(param.get(0)); + int index = kernel.flows.search(ident); + if (index == -1) + throw new LogoError(Logo.messages.getString("flux_non_disponible") + " " + ident); + MyFlow flow = kernel.flows.get(index); + MyFlowReader flowReader; + // If the flow is a writable flow, throw error + if (flow.isWriter()) + throw new LogoError(Logo.messages.getString("flux_lecture")); + // else if the flow is reader, convert to MyFlowReader + else if (flow.isReader()) + { + flowReader = ((MyFlowReader) flow); + } + // else the flow isn't yet defined, initialize + else + flowReader = new MyFlowReader(flow); + + if (flowReader.isFinished()) + throw new LogoError(Logo.messages.getString("fin_flux") + " " + ident); + + int character = ((MyFlowReader) flow).readChar(); + if (character == -1) + { + flow.setFinished(true); + throw new LogoError(Logo.messages.getString("fin_flux") + " " + ident); + } + Interprete.operande = true; + String car = String.valueOf(character); + if (car.equals("\\")) + car = "\\\\"; + Interprete.calcul.push(car); + kernel.flows.set(index, flowReader); + } + catch (FileNotFoundException e1) + { + throw new LogoError(Logo.messages.getString("error.iolecture")); + } + catch (IOException e2) + {} + break; + case 156: // ecrisligneflux + try + { + int ident = kernel.getCalculator().getInteger(param.get(0)); + int index = kernel.flows.search(ident); + liste = getFinalList(param.get(1)); + if (index == -1) + throw new LogoError(Logo.messages.getString("flux_non_disponible") + " " + ident); + MyFlow flow = kernel.flows.get(index); + MyFlowWriter flowWriter; + // If the flow is a readable flow, throw an error + if (flow.isReader()) + throw new LogoError(Logo.messages.getString("flux_ecriture")); + // Else if the flow is a writable flow , convert to + // MrFlowWriter + else if (flow.isWriter()) + flowWriter = (MyFlowWriter) flow; + // Else the flow isn't defined yet, initialize + else + flowWriter = new MyFlowWriter(flow); + + // System.out.println(flow.isReader()+" "+flow.isWriter()); + // Write the line + flowWriter.write(Utils.SortieTexte(liste)); + kernel.flows.set(index, flowWriter); + } + catch (FileNotFoundException e1) + {} + catch (IOException e2) + {} + break; + case 157: // finficher? + try + { + int ident = kernel.getCalculator().getInteger(param.get(0)); + int index = kernel.flows.search(ident); + if (index == -1) + throw new LogoError(Logo.messages.getString("flux_non_disponible") + " " + ident); + else + { + MyFlow flow = kernel.flows.get(index); + MyFlowReader flowReader = null; + // If the flow isn't defined yet, initialize + if (!flow.isWriter() && !flow.isReader()) + { + flowReader = new MyFlowReader(flow); + } + else if (flow.isReader()) + flowReader = (MyFlowReader) flow; + if (null != flowReader) + { + if (flow.isFinished()) + { + Interprete.operande = true; + Interprete.calcul.push(Logo.messages.getString("vrai")); + } + else + { + int read = flowReader.isReadable(); + if (read == -1) + { + Interprete.operande = true; + Interprete.calcul.push(Logo.messages.getString("vrai")); + flow.setFinished(true); + } + else + { + Interprete.operande = true; + Interprete.calcul.push(Logo.messages.getString("faux")); + } + } + } + else + throw new LogoError(Logo.messages.getString("flux_lecture")); + } + } + catch (FileNotFoundException e1) + {} + catch (IOException e2) + {} + break; + case 158: // ouvreflux + mot = getWord(param.get(1)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + defaultFolder = uc.getDefaultFolder(); + liste = Utils.SortieTexte(defaultFolder) + File.separator + Utils.SortieTexte(mot); + int ident = kernel.getCalculator().getInteger(param.get(0)); + if (kernel.flows.search(ident) == -1) + kernel.flows.add(new MyFlow(ident, liste, false)); + else + throw new LogoError(ident + " " + Logo.messages.getString("flux_existant")); + break; + case 159: // fermeflux + try + { + ident = kernel.getCalculator().getInteger(param.get(0)); + int index = kernel.flows.search(ident); + if (index == -1) + throw new LogoError(Logo.messages.getString("flux_non_disponible") + " " + ident); + MyFlow flow = kernel.flows.get(index); + // If the flow is a readable flow + if (flow.isReader()) + ((MyFlowReader) flow).close(); + // Else if it's a writable flow + else if (flow.isWriter()) + ((MyFlowWriter) flow).close(); + kernel.flows.remove(index); + } + catch (IOException e2) + {} + break; + case 160: // ajouteligneflux + try + { + ident = kernel.getCalculator().getInteger(param.get(0)); + int index = kernel.flows.search(ident); + liste = getFinalList(param.get(1)); + if (index == -1) + throw new LogoError(Logo.messages.getString("flux_non_disponible") + " " + ident); + MyFlow flow = kernel.flows.get(index); + MyFlowWriter flowWriter; + // If the flow is a readable flow, throw an error + if (flow.isReader()) + throw new LogoError(Logo.messages.getString("flux_ecriture")); + // Else if the flow is a writable flow , convert to + // MrFlowWriter + else if (flow.isWriter()) + flowWriter = (MyFlowWriter) flow; + // Else the flow isn't defined yet, initialize + else + flowWriter = new MyFlowWriter(flow); + + // Write the line + flowWriter.append(Utils.SortieTexte(liste)); + kernel.flows.set(index, flowWriter); + } + catch (FileNotFoundException e1) + {} + catch (IOException e2) + {} + break; + case 161: // souris? + Interprete.operande = true; + if (cadre.getDrawPanel().get_lissouris()) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 162: // variables + Interprete.operande = true; + Interprete.calcul.push(new String(getAllVariables())); + break; + case 163: // chose thing + mot = getWord(param.get(0)); + if (null == mot) + { + throw new LogoError(Logo.messages.getString("error.word")); + } // si c'est une liste + else if (debut_chaine.equals("")) { throw new LogoError( + Logo.messages.getString("erreur_variable")); } // si + // c'est + // un + // nombre + Interprete.operande = true; + String value; + mot = mot.toLowerCase(); + if (!Interprete.locale.containsKey(mot)) + { + if (!wp.getGlobals().getVariables().contains(mot)) + throw new LogoError(mot + " " + Logo.messages.getString("erreur_variable")); + else + value = wp.getGlobals().getValue(mot); + } + else + { + value = Interprete.locale.get(mot); + } + if (null == value) + throw new LogoError(mot + " " + Logo.messages.getString("erreur_variable")); + Interprete.calcul.push(value); + break; + case 164: // nettoie + cadre.getDrawPanel().nettoie(); + break; + case 165: // tape + par = param.get(0).trim(); + if (isList(par)) + par = formatList(par.substring(1, par.length() - 1)); + mot = getWord(param.get(0)); + if (null == mot) + HistoryMessenger.getInstance().dispatchLogoOutput(Utils.SortieTexte(par)); + else + HistoryMessenger.getInstance().dispatchLogoOutput(Utils.SortieTexte(mot)); + break; + case 166: // cercle + cadre.getDrawPanel().circle((kernel.getCalculator().numberDouble(param.pop()))); + break; + case 167: // arc + cadre.getDrawPanel().arc(kernel.getCalculator().numberDouble(param.get(0)), + kernel.getCalculator().numberDouble(param.get(1)), + kernel.getCalculator().numberDouble(param.get(2))); + break; + case 168: // rempliszone + cadre.getDrawPanel().rempliszone(); + break; + case 169: // animation + cadre.getDrawPanel().setAnimation(true); + Interprete.operande = false; + break; + case 170: // rafraichis + if (DrawPanel.classicMode == DrawPanel.MODE_ANIMATION) + { + cadre.getDrawPanel().refresh(); + } + break; + + case 171: // tailledessin + Interprete.operande = true; + StringBuffer sb = new StringBuffer(); + sb.append("[ "); + sb.append(w); + sb.append(" "); + sb.append(h); + sb.append(" ] "); + Interprete.calcul.push(new String(sb)); + break; + case 172: // quotient + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().quotient(param.get(0), param.get(1))); + break; + case 173: // entier? + Interprete.operande = true; + double ent = kernel.getCalculator().numberDouble(param.get(0)); + if ((int) ent == ent) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 174: // fixeseparation + nombre = kernel.getCalculator().numberDouble(param.get(0)); + if (nombre < 0 || nombre > 1) + throw new LogoError(nombre + " " + Logo.messages.getString("entre_zero_un")); + cadre.drawingAndHistory.setResizeWeight(nombre); + cadre.drawingAndHistory.setDividerLocation(nombre); + break; + case 175: // separation + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(cadre.drawingAndHistory.getResizeWeight())); + break; + case 176: // tronque + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().truncate(param.get(0))); + break; + case 177: // trace + Kernel.mode_trace = true; + Interprete.operande = false; + break; + case 178:// changedossier + Interprete.operande = false; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + chemin = ""; + defaultFolder = uc.getDefaultFolder(); + if (defaultFolder.endsWith(File.separator)) + chemin = Utils.SortieTexte(defaultFolder + mot); + else + chemin = Utils.SortieTexte(defaultFolder + Utils.rajoute_backslash(File.separator) + mot); + if ((new File(chemin)).isDirectory()) + { + try + { + defaultFolder = Utils.rajoute_backslash((new File(chemin)).getCanonicalPath()); + uc.setDefaultFolder(defaultFolder); + } + catch (NullPointerException e1) + {} + catch (IOException e2) + {} + } + else + throw new LogoError(Utils.rajoute_backslash(chemin) + " " + + Logo.messages.getString("erreur_pas_repertoire")); + + break; + case 179:// unicode + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + else if (getWordLength(mot) != 1) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("un_caractere")); + else + { + Interprete.operande = true; + str = String.valueOf((int) Utils.SortieTexte(itemWord(1, mot)).charAt(0)); + Interprete.calcul.push(str); + } + break; + case 180:// caractere + i = kernel.getCalculator().getInteger(param.get(0)); + if (i < 0 || i > 65535) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("nombre_unicode")); + else + { + str = ""; + Interprete.operande = true; + if (i == 92) + str = "\"\\\\"; + else if (i == 10) + str = "\"\\n"; + else if (i == 32) + str = "\"\\e"; + else + { + str = String.valueOf((char) i); + try + { + Double.parseDouble(str); + } + catch (NumberFormatException e) + { + str = "\"" + str; + } + } + Interprete.calcul.push(str); + } + break; + case 181: // stoptout + cadre.error = true; + break; + case 182: // compteur + boolean erreur = false; + if (!Primitive.stackLoop.isEmpty()) + { + LoopProperties lp = Primitive.stackLoop.peek(); + if (lp.isRepeat()) + { + Interprete.operande = true; + Interprete.calcul.push(lp.getCounter().toString()); + } + else + erreur = true; + } + else + erreur = true; + if (erreur) { throw new LogoError(Logo.messages.getString("erreur_compteur")); } + break; + case 183: // controls.for repetepour + li2 = getList(param.get(1)); + li2 = new String(Utils.decoupe(li2)); + li1 = getFinalList(param.get(0)); + int nb = numberOfElements(li1); + if (nb < 3 || nb > 4) + throw new LogoError(Logo.messages.getString("erreur_repetepour")); + st = new StringTokenizer(li1); + String var = st.nextToken().toLowerCase(); + BigDecimal deb = kernel.getCalculator().numberDecimal(st.nextToken()); + BigDecimal fin = kernel.getCalculator().numberDecimal(st.nextToken()); + BigDecimal increment = BigDecimal.ONE; + if (nb == 4) + increment = kernel.getCalculator().numberDecimal(st.nextToken()); + if (var.equals("")) + throw new LogoError(Logo.messages.getString("variable_vide")); + try + { + Double.parseDouble(var); + throw new LogoError(Logo.messages.getString("erreur_nom_nombre_variable")); + } + catch (NumberFormatException e) + { + LoopFor lf = new LoopFor(deb, fin, increment, li2, var); + lf.AffecteVar(true); + + if ((increment.compareTo(BigDecimal.ZERO) == 1 && fin.compareTo(deb) >= 0) + || (increment.compareTo(BigDecimal.ZERO) == -1 && fin.compareTo(deb) <= 0)) + { + cadre.getKernel().getInstructionBuffer().insert(li2 + Primitive.END_LOOP + " "); + Primitive.stackLoop.push(lf); + } + } + break; + case 184: // absolue + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().abs(param.get(0))); + break; + case 185: // remplace + String reponse = ""; + liste = getFinalList(param.get(0)); + int entier = kernel.getCalculator().getInteger(param.get(1)); + mot = getWord(param.get(2)); + if (null != mot && mot.equals("")) + mot = "\\v"; + if (null == mot) + mot = "[ " + getFinalList(param.get(2)) + "]"; + char ch; + int compteur = 1; + boolean espace = true; + boolean crochet = false; + boolean error = true; + for (int j = 0; j < liste.length(); j++) + { + if (compteur == entier) + { + error = false; + compteur = j; + break; + } + ch = liste.charAt(j); + if (ch == '[') + { + if (espace) + crochet = true; + espace = false; + } + if (ch == ' ') + { + espace = true; + if (crochet) + { + crochet = false; + j = extractList(liste, j); + } + compteur++; + } + } + if (error) + throw new LogoError(Logo.messages.getString("y_a_pas") + " " + entier + " " + + Logo.messages.getString("element_dans_liste") + liste + "]"); + reponse = "[ " + liste.substring(0, compteur) + mot; + // On extrait le mot suivant + if (compteur + 1 < liste.length() && liste.charAt(compteur) == '[' + && liste.charAt(compteur + 1) == ' ') + { + compteur = extractList(liste, compteur + 2); + reponse += liste.substring(compteur) + "] "; + + } + else + { + for (i = compteur + 1; i < liste.length(); i++) + { + if (liste.charAt(i) == ' ') + { + compteur = i; + break; + } + } + reponse += liste.substring(compteur) + "] "; + } + Interprete.operande = true; + Interprete.calcul.push(reponse); + break; + case 186: // ajoute + reponse = ""; + liste = getFinalList(param.get(0)); + entier = kernel.getCalculator().getInteger(param.get(1)); + mot = getWord(param.get(2)); + if (null != mot && mot.equals("")) + mot = "\\v"; + if (null == mot) + mot = "[ " + getFinalList(param.get(2)) + "]"; + compteur = 1; + espace = true; + crochet = false; + error = true; + for (int j = 0; j < liste.length(); j++) + { + if (compteur == entier) + { + error = false; + compteur = j; + break; + } + ch = liste.charAt(j); + if (ch == '[') + { + if (espace) + crochet = true; + espace = false; + } + if (ch == ' ') + { + espace = true; + if (crochet) + { + crochet = false; + j = extractList(liste, j); + } + compteur++; + if (j == liste.length() - 1 && compteur == entier) + { + error = false; + compteur = liste.length(); + } + } + } + if (error && entier != compteur) + throw new LogoError(Logo.messages.getString("y_a_pas") + " " + entier + " " + + Logo.messages.getString("element_dans_liste") + liste + "]"); + if (!liste.trim().equals("")) + reponse = "[ " + liste.substring(0, compteur) + mot + " " + liste.substring(compteur) + "] "; + else + reponse = "[ " + mot + " ] "; + Interprete.operande = true; + Interprete.calcul.push(reponse); + break; + case 187: // gris + colorCode(8); + break; + case 188: // grisclair + colorCode(9); + break; + case 189: // rougefonce + colorCode(10); + break; + case 190: // vertfonce + colorCode(11); + break; + case 191: // bleufonce + colorCode(12); + break; + case 192: // orange + colorCode(13); + break; + case 193: // rose + colorCode(14); + break; + case 194: // violet + colorCode(15); + break; + case 195: // marron + colorCode(16); + break; + case 196: // noir + colorCode(0); + break; + case 197: // rouge + colorCode(1); + break; + case 198: // vert + colorCode(2); + break; + case 199: // jaune + colorCode(3); + break; + case 200: // bleu + colorCode(4); + break; + case 201: // magenta + colorCode(5); + break; + case 202: // cyan + colorCode(6); + break; + case 203: // blanc + colorCode(7); + break; + case 204: // Parenthese fermante + // Distinguons les deux cas : (3)*2 et (4+3)*2 + // Le 3 est ici a retourner au + + boolean a_retourner = true; + // On enleve le "(" correspondant a la parenthese ouvrante + // de la + // pile nom + // a condition que l'element attendant de la pile nom ne + // soit + // pas une procedure + boolean est_procedure = false; + int pos = Interprete.nom.lastIndexOf("("); + if (pos == -1) + { + // Parenthese fermante sans parenthese ouvrante au + // prealable + throw new LogoError(Logo.messages.getString("parenthese_ouvrante")); + } + else + { // Evitons l'erreur en cas de par exemple: "ec )" + // (parenthese fermante sans ouvrante)--> else a + // executer qu'en cas de non erreur + if (Interprete.drapeau_ouvrante) + { + // parenthese vide + throw new LogoError(Logo.messages.getString("parenthese_vide")); + + } + for (int j = pos; j < Interprete.nom.size(); j++) + { + String proc = Interprete.nom.get(j).toLowerCase(); + if (Primitive.primitives.containsKey(proc)) + est_procedure = true; + else + { + if (wp.isExecutable(proc)) // TODO changed + { + est_procedure = true; + break; + } + } + } + } + // Si une procedure est presente dans la pile nom, on garde + // les parenteses + // System.out.println(Primitive.primitives.containsKey("puissance")+" + // "+est_procedure); + if (est_procedure) + { + cadre.getKernel().getInstructionBuffer().insert(") "); + } + // Sinon on les enleve avec leurs imbrications eventuelles + else + { + if (Interprete.en_cours.isEmpty() || !Interprete.en_cours.peek().equals("(")) + { + throw new LogoError(Logo.messages.getString("parenthese_ouvrante")); + } + else + Interprete.en_cours.pop(); + if (!Interprete.nom.isEmpty()) + { + if (Interprete.nom.peek().equals("(")) + a_retourner = false; + pos = Interprete.nom.lastIndexOf("("); + if (pos == -1) + { + // Parenthese fermante sans parenthese ouvrante + // au prelable + throw new LogoError(Logo.messages.getString("parenthese_ouvrante")); + } + else + { + Interprete.nom.removeElementAt(pos); + // S'il y a imbrication de parentheses (((20))) + pos--; + instruction = cadre.getKernel().getInstructionBuffer(); + while (instruction.getNextWord().equals(")") && (pos > -1)) + { + if (!Interprete.nom.isEmpty() && Interprete.nom.get(pos).equals("(")) + { + instruction.deleteFirstWord(")"); + Interprete.nom.removeElementAt(pos); + pos--; + } + else + break; + } + } + } + } + if (Interprete.calcul.isEmpty()) + { + Interprete.operande = false; + } + else + { + Interprete.operande = true; + Interprete.drapeau_fermante = a_retourner; + } + break; + case 205: // fixestyle + boolean gras = false; + boolean italique = false; + boolean souligne = false; + boolean exposant = false; + boolean indice = false; + boolean barre = false; + mot = getWord(param.get(0)); + if (null == mot) + liste = getFinalList(param.get(0)); + else + liste = mot; + if (liste.trim().equals("")) + liste = Logo.messages.getString("style.none"); + st = new StringTokenizer(liste); + while (st.hasMoreTokens()) + { + element = st.nextToken().toLowerCase(); + if (element.equals(Logo.messages.getString("style.underline").toLowerCase())) + { + souligne = true; + } + else if (element.equals(Logo.messages.getString("style.bold").toLowerCase())) + { + gras = true; + } + else if (element.equals(Logo.messages.getString("style.italic").toLowerCase())) + { + italique = true; + } + else if (element.equals(Logo.messages.getString("style.exposant").toLowerCase())) + { + exposant = true; + } + else if (element.equals(Logo.messages.getString("style.subscript").toLowerCase())) + { + indice = true; + } + else if (element.equals(Logo.messages.getString("style.strike").toLowerCase())) + { + barre = true; + } + else if (element.equals(Logo.messages.getString("style.none").toLowerCase())) + {} + else + throw new LogoError(Logo.messages.getString("erreur_fixestyle")); + } + cadre.getHistoryPanel().getDsd().fixegras(gras); + cadre.getHistoryPanel().getDsd().fixeitalique(italique); + cadre.getHistoryPanel().getDsd().fixesouligne(souligne); + cadre.getHistoryPanel().getDsd().fixeexposant(exposant); + cadre.getHistoryPanel().getDsd().fixeindice(indice); + cadre.getHistoryPanel().getDsd().fixebarre(barre); + break; + case 206: // style + StringBuffer buffer = new StringBuffer(); + compteur = 0; + if (cadre.getHistoryPanel().getDsd().estgras()) + { + buffer.append(Logo.messages.getString("style.bold").toLowerCase() + " "); + compteur++; + } + if (cadre.getHistoryPanel().getDsd().estitalique()) + { + buffer.append(Logo.messages.getString("style.italic").toLowerCase() + " "); + compteur++; + } + if (cadre.getHistoryPanel().getDsd().estsouligne()) + { + buffer.append(Logo.messages.getString("style.underline").toLowerCase() + " "); + compteur++; + } + if (cadre.getHistoryPanel().getDsd().estexposant()) + { + buffer.append(Logo.messages.getString("style.exposant").toLowerCase() + " "); + compteur++; + } + if (cadre.getHistoryPanel().getDsd().estindice()) + { + buffer.append(Logo.messages.getString("style.subscript").toLowerCase() + " "); + compteur++; + } + if (cadre.getHistoryPanel().getDsd().estbarre()) + { + buffer.append(Logo.messages.getString("style.strike").toLowerCase() + " "); + compteur++; + } + Interprete.operande = true; + if (compteur == 0) + Interprete.calcul.push("\"" + Logo.messages.getString("style.none").toLowerCase()); + else if (compteur == 1) + Interprete.calcul.push("\"" + new String(buffer).trim()); + else if (compteur > 1) + Interprete.calcul.push("[ " + new String(buffer) + "]"); + break; + case 207: // listaillefenetre + Interprete.operande = true; + java.awt.Point p = cadre.scrollArea.getViewport().getViewPosition(); + Rectangle rec = cadre.scrollArea.getVisibleRect(); + sb = new StringBuffer(); + int x1 = p.x - w / 2; + int y1 = h / 2 - p.y; + int x2 = x1 + rec.width - cadre.scrollArea.getVerticalScrollBar().getWidth(); + int y2 = y1 - rec.height + cadre.scrollArea.getHorizontalScrollBar().getHeight(); + sb.append("[ "); + sb.append(x1); + sb.append(" "); + sb.append(y1); + sb.append(" "); + sb.append(x2); + sb.append(" "); + sb.append(y2); + sb.append(" ] "); + Interprete.calcul.push(new String(sb)); + break; + case 208: // LongueurEtiquette + mot = getWord(param.get(0)); + if (null != mot) + mot = Utils.SortieTexte(mot); + else + mot = getFinalList(param.get(0)).trim(); + Interprete.operande = true; + fm = cadre.getDrawPanel().getGraphics().getFontMetrics(cadre.getDrawPanel().getGraphicsFont()); + longueur = fm.stringWidth(mot); + Interprete.calcul.push(String.valueOf(longueur)); + break; + case 209: // envoietcp // sendtcp // enviatcp etcp + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) { throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); } + mot = mot.toLowerCase(); + liste = ""; + liste = getFinalList(param.get(1)); + NetworkClientSend ncs = new NetworkClientSend(mot, liste); + Interprete.calcul.push("[ " + ncs.getAnswer() + " ] "); + /* + * { + * liste = "[ "; mot2 = + * getFinalList(param.get(0).toString()); liste += mot2 + " + * ]"; String rip = liste.substring(2,17); // cadre.ecris("perso + * ", rip + "\n"); + * //para debug String rdat = "_" + liste.substring(18,23) + + * "*\n\r"; // + * cadre.ecris("perso", rdat + "\n"); //para debug Socket + * echoSocket = null; + * DataOutputStream tcpout = null; BufferedReader tcpin = + * null; String resp = + * null; { echoSocket = new Socket(rip, 1948); tcpout = + * new + * DataOutputStream(echoSocket.getOutputStream()); tcpin= + * new BufferedReader(new + * InputStreamReader(echoSocket.getInputStream())); + * tcpout.writeBytes(rdat); + * resp = tcpin.readLine(); // readLine detiene el programa + * hasta que recibe una + * respuesta del robot. Que hacer si no recibe nada? + * tcpout.close(); + * tcpin.close(); echoSocket.close(); } catch + * (UnknownHostException e) { throw + * new myException( Logo.messages.getString("erreur_tcp")); + * } catch + * (IOException e) { throw new myException( + * Logo.messages.getString("erreur_tcp")); } + * Interprete.calcul.push("[ " + resp + " + * ]"); } catch(myException e){} + */ + break; + case 210: // ecoutetcp + /** + * Marko Zivkovic : new implementation of context switch. + * saving of workspace (now context) is done in {@link ContextManager} + */ + Interprete.operande = false; + new NetworkServer(cadre); + + break; + case 211: // executetcp + mot = getWord(param.get(0)); + if (null == mot) { throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); } + mot = mot.toLowerCase(); + liste = ""; + liste = getFinalList(param.get(1)); + new NetworkClientExecute(cadre.getKernel(), mot, liste); + break; + case 212: // \x internal operator to specify + // the end of network instructions with + // "executetcp" + // have to replace workspace + Interprete.operande = false; + + /* + * Marko Zivkovic : new implementation of network context + */ + wp.popNetworkMode(); + + break; + case 213: // chattcp + Interprete.operande = false; + mot = getWord(param.get(0)); + if (null == mot) { throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); } + mot = mot.toLowerCase(); + liste = ""; + liste = getFinalList(param.get(1)); + new NetworkClientChat(cadre, mot, liste); + break; + case 214: // init resetall + Interprete.operande = false; + // resize drawing zone if necessary + if (h != 1000 || w != 1000) + { + h = 1000; + w = 1000; + cadre.resizeDrawingZone(); + } + uc.setDrawGrid(false); + uc.setDrawXAxis(false); + uc.setDrawYAxis(false); + cadre.getDrawPanel().origine(); + kernel.getActiveTurtle().stroke = new BasicStroke(1); + cadre.getDrawPanel().setBackgroundColor(Color.WHITE); + if (kernel.getActiveTurtle().id == 0) + { + uc.setActiveTurtle(0); + } + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_CLASSIC; + chemin = "tortue0.png"; + kernel.change_image_tortue(chemin); + cadre.getDrawPanel().fcfg(Color.WHITE); + cadre.getDrawPanel().fcc(Color.BLACK); + cadre.getDrawPanel().setAnimation(false); + font = new Font("dialog", Font.PLAIN, 12); + WSManager.getWorkspaceConfig().setFont(font); + kernel.getActiveTurtle().police = 12; + cadre.getDrawPanel().setGraphicsFont(font); + HistoryPanel.fontPrint = UserConfig.police_id(font); + cadre.getHistoryPanel().getDsd().fixepolice(12); + cadre.getHistoryPanel().getDsd().fixenompolice(HistoryPanel.fontPrint); + cadre.getHistoryPanel().getDsd().fixecouleur(Color.black); + uc.setPenShape(PenShape.SQUARE); + uc.setQuality(DrawQuality.NORMAL); + kernel.setDrawingQuality(uc.getQuality()); + kernel.setNumberOfTurtles(16); + uc.setTurtleSpeed(0); + Kernel.mode_trace = false; + DrawPanel.WINDOW_MODE = DrawPanel.WINDOW_CLASSIC; + cadre.getDrawPanel().zoom(1, false); + break; + case 215: // tc taillecrayon + Interprete.operande = true; + double penwidth = 2 * kernel.getActiveTurtle().getPenWidth(); + Interprete.calcul.push(String.valueOf(MyCalculator.teste_fin_double(penwidth))); + break; + case 216: // setpenshape=ffc fixeformecrayon + Interprete.operande = false; + i = kernel.getCalculator().getInteger(param.get(0)); + if (i != PenShape.OVAL.getValue() && i != PenShape.SQUARE.getValue()) + { + str = Utils.primitiveName("setpenshape") + " " + Logo.messages.getString("error_bad_values"); + str += " " + PenShape.SQUARE.getValue() + " " + PenShape.OVAL.getValue(); + throw new LogoError(str); + } + uc.setPenShape(PenShape.getPenShape(i)); + cadre.getDrawPanel().updateAllTurtleShape(); + cadre.getDrawPanel().setStroke(kernel.getActiveTurtle().crayon); + break; + case 217: // penshape=fc formecrayon + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(uc.getPenShape().getValue())); + break; + case 218: // setdrawingquality=fqd fixequalitedessin + Interprete.operande = false; + i = kernel.getCalculator().getInteger(param.get(0)); + if (i != DrawQuality.NORMAL.getValue() && i != DrawQuality.HIGH.getValue() + && i != DrawQuality.LOW.getValue()) + { + str = Utils.primitiveName("setdrawingquality") + " " + + Logo.messages.getString("error_bad_values") + " 0 1 2"; + throw new LogoError(str); + } + uc.setQuality(DrawQuality.getDrawQuality(i)); + kernel.setDrawingQuality(uc.getQuality()); + break; + case 219: // drawingquality=qd qualitedessin + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(uc.getQuality().getValue())); + break; + case 220: // setturtlesnumber=fmt fixemaxtortues + Interprete.operande = false; + i = kernel.getCalculator().getInteger(param.get(0)); + if (i < 0) + { + String fmt = Utils.primitiveName("setturtlesnumber"); + throw new LogoError(fmt + " " + Logo.messages.getString("attend_positif")); + } + else if (i == 0) + i = 1; + kernel.setNumberOfTurtles(i); + break; + case 221: // turtlesnumber=maxtortues + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(uc.getMaxTurtles())); + + break; + case 222: // setscreensize=ftd fixetailledessin + Interprete.operande = false; + + String prim = Utils.primitiveName("setscreensize"); + liste = getFinalList(param.get(0)); + int width, + height; + st = new StringTokenizer(liste); + try + { + if (!st.hasMoreTokens()) + throw new LogoError(prim + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + width = Integer.parseInt(st.nextToken().toString()); + if (!st.hasMoreTokens()) + throw new LogoError(prim + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + height = Integer.parseInt(st.nextToken().toString()); + } + catch (NumberFormatException e) + { + throw new LogoError(prim + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + } + if (st.hasMoreTokens()) + throw new LogoError(prim + " " + Logo.messages.getString("n_aime_pas") + liste + + Logo.messages.getString("comme_parametre")); + boolean changement = false; + if (height != h) + changement = true; + int tmp_hauteur = h; + h = height; + if (width != w) + changement = true; + int tmp_largeur = w; + w = width; + if (w < 100 || h < 100) + { + w = 1000; + h = 1000; + } + if (changement) + { + int memoire_necessaire = w * h * 4 / 1024 / 1024; + int memoire_image = tmp_hauteur * tmp_largeur * 4 / 1024 / 1024; + long free = Runtime.getRuntime().freeMemory() / 1024 / 1024; + long total = Runtime.getRuntime().totalMemory() / 1024 / 1024; + /* + * System.out.println("memoire nécessaire + * "+memoire_necessaire); System.out.println("memoire + * image + * "+memoire_image); System.out.println("memoire + * libre "+free); System.out.println("memoire totale + * "+total); System.out.println("memoire envisagee + * "+(total-free+memoire_necessaire-memoire_image)); + * System.out.println(); + */ + if (total - free + memoire_necessaire - memoire_image < GlobalConfig.getMaximumMemory() * 0.8) + { + cadre.resizeDrawingZone(); + } + else + { + w = tmp_largeur; + h = tmp_hauteur; + long conseil = 64 * ((total - free + memoire_necessaire - memoire_image) / 64) + 64; + if (total - free + memoire_necessaire - memoire_image > 0.8 * conseil) + conseil += 64; + if (conseil == GlobalConfig.getMaximumMemory()) + conseil += 64; + String message = Logo.messages.getString("erreur_memoire") + " " + conseil + "\n" + + Logo.messages.getString("relancer"); + jt = new MyTextAreaDialog(message); + JOptionPane.showMessageDialog(cadre.getFrame(), jt, Logo.messages.getString("erreur"), + JOptionPane.ERROR_MESSAGE); + } + } + break; + case 223: // guibutton guibouton + String identifier = getWord(param.get(0)); + if (null == identifier) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + mot = getWord(param.get(1)); + if (null == mot) + throw new LogoError(param.get(1) + " " + Logo.messages.getString("error.word")); + GuiButton gb = new GuiButton(identifier.toLowerCase(), mot, cadre); + cadre.getDrawPanel().addToGuiMap(gb); + break; + case 224: // guiaction + identifier = getWord(param.get(0)); + if (null == identifier) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + liste = getFinalList(param.get(1)); + cadre.getDrawPanel().guiAction(identifier, liste); + break; + case 225: // guiremove + identifier = getWord(param.get(0)); + if (null == identifier) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + cadre.getDrawPanel().guiRemove(identifier); + break; + case 226: // guiposition + identifier = getWord(param.get(0)); + if (null == identifier) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + liste = getFinalList(param.get(1)); + cadre.getDrawPanel().guiposition(identifier, liste, Utils.primitiveName("guiposition")); + break; + case 227: // guidraw + identifier = getWord(param.get(0)); + if (null == identifier) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + cadre.getDrawPanel().guiDraw(identifier); + break; + case 228: // zoom + Interprete.operande = false; + d = kernel.getCalculator().numberDouble(param.get(0)); + if (d <= 0) + { + String name = Utils.primitiveName("zoom"); + throw new LogoError(name + " " + Logo.messages.getString("attend_positif")); + } + cadre.getDrawPanel().zoom(d, false); + break; + case 229: // grille + Interprete.operande = false; + primitive2D("grille"); + int[] args = new int[2]; + for (i = 0; i < 2; i++) + { + args[i] = kernel.getCalculator().getInteger(param.get(i)); + if (args[i] < 0) + { + String grille = Utils.primitiveName("grille"); + throw new LogoError(grille + " " + Logo.messages.getString("attend_positif")); + } + else if (args[i] == 0) + { + args[i] = 1; + } + } + uc.setDrawGrid(true); + uc.setXGrid(args[0]); + uc.setYGrid(args[1]); + cadre.getDrawPanel().videecran(); + break; + case 230: // stopgrille + Interprete.operande = false; + uc.setDrawGrid(false); + cadre.getDrawPanel().videecran(); + break; + case 231: // stopanimation + cadre.getDrawPanel().setAnimation(false); + Interprete.operande = false; + break; + case 232: // stoptrace + Kernel.mode_trace = false; + Interprete.operande = false; + break; + case 233: // guimenu + identifier = getWord(param.get(0)); + if (null == identifier) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + liste = getFinalList(param.get(1)); + GuiMenu gm = new GuiMenu(identifier.toLowerCase(), liste, cadre); + cadre.getDrawPanel().addToGuiMap(gm); + break; + case 234: // axis + + Interprete.operande = false; + + primitive2D("axis"); + i = kernel.getCalculator().getInteger(param.get(0)); + if (i < 0) + { + String name = Utils.primitiveName("axis"); + throw new LogoError(name + " " + Logo.messages.getString("attend_positif")); + } + else if (i < 25) + i = 25; + uc.setDrawXAxis(true); + uc.setXAxis(i); + uc.setDrawYAxis(true); + uc.setYAxis(i); + cadre.getDrawPanel().videecran(); + break; + case 235: // xaxis + Interprete.operande = false; + primitive2D("xaxis"); + i = kernel.getCalculator().getInteger(param.get(0)); + if (i < 0) + { + String name = Utils.primitiveName("xaxis"); + throw new LogoError(name + " " + Logo.messages.getString("attend_positif")); + } + else if (i < 25) + i = 25; + uc.setDrawXAxis(true); + uc.setXAxis(i); + cadre.getDrawPanel().videecran(); + break; + case 236: // yaxis + Interprete.operande = false; + primitive2D("yaxis"); + i = kernel.getCalculator().getInteger(param.get(0)); + if (i < 0) + { + String name = Utils.primitiveName("yaxis"); + throw new LogoError(name + " " + Logo.messages.getString("attend_positif")); + } + else if (i < 25) + i = 25; + uc.setDrawYAxis(true); + uc.setYAxis(i); + cadre.getDrawPanel().videecran(); + break; + case 237: // stopaxis + uc.setDrawXAxis(false); + uc.setDrawYAxis(false); + Interprete.operande = false; + cadre.getDrawPanel().videecran(); + break; + case 238: // bye + cadre.closeWindow(); + break; + case 239: // var? variable? + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + mot = mot.toLowerCase(); + if (wp.getGlobals().getVariables().contains(mot) || Interprete.locale.containsKey(mot)) // TODO + // changed + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 240: // axiscolor= couleuraxes + Interprete.operande = true; + c = new Color(uc.getAxisColor()); + Interprete.calcul.push("[ " + c.getRed() + " " + c.getGreen() + " " + c.getBlue() + " ] "); + + break; + case 241: // gridcolor=couleurgrille + Interprete.operande = true; + c = new Color(uc.getGridColor()); + Interprete.calcul.push("[ " + c.getRed() + " " + c.getGreen() + " " + c.getBlue() + " ] "); + break; + case 242: // grid?=grille? + Interprete.operande = true; + if (uc.isDrawGrid()) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 243: // xaxis?=axex? + Interprete.operande = true; + if (uc.isDrawXAxis()) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 244: // yaxis?=axey? + Interprete.operande = true; + if (uc.isDrawYAxis()) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + break; + case 245: // setgridcolor=fcg fixecouleurgrille + Interprete.operande = false; + if (isList(param.get(0))) + { + uc.setGridColor(rgb(param.get(0), Utils.primitiveName("setgridcolor")).getRGB()); + } + else + { + int coul = kernel.getCalculator().getInteger(param.get(0)) % DrawPanel.defaultColors.length; + if (coul < 0) + coul += DrawPanel.defaultColors.length; + uc.setGridColor(DrawPanel.defaultColors[coul].getRGB()); + } + break; + case 246: // setaxiscolor=fca fixecouleuraxes + Interprete.operande = false; + if (isList(param.get(0))) + { + uc.setAxisColor(rgb(param.get(0), Utils.primitiveName("setaxiscolor")).getRGB()); + } + else + { + int coul = kernel.getCalculator().getInteger(param.get(0)) % DrawPanel.defaultColors.length; + if (coul < 0) + coul += DrawPanel.defaultColors.length; + uc.setAxisColor(DrawPanel.defaultColors[coul].getRGB()); + } + break; + case 247: // perspective + + cadre.getDrawPanel().perspective(); + + break; + case 248:// rightroll=rd roulisdroite + delay(); + primitive3D("3d.rightroll"); + cadre.getDrawPanel().rightroll(kernel.getCalculator().numberDouble(param.pop())); + break; + case 249:// uppitch=cabre + delay(); + primitive3D("3d.uppitch"); + cadre.getDrawPanel().uppitch(kernel.getCalculator().numberDouble(param.pop())); + break; + case 250:// leftroll=rg roulisgauche + delay(); + primitive3D("3d.leftroll"); + cadre.getDrawPanel().rightroll(-kernel.getCalculator().numberDouble(param.pop())); + break; + case 251:// downpitch=pique + delay(); + primitive3D("3d.downpitch"); + cadre.getDrawPanel().uppitch(-kernel.getCalculator().numberDouble(param.pop())); + break; + case 252:// roll=roulis + primitive3D("3d.roll"); + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(kernel.getActiveTurtle().roll)); + break; + case 253:// pitch=cabrement tangage + primitive3D("3d.pitch"); + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(kernel.getActiveTurtle().pitch)); + break; + case 254:// setroll=fixeroulis + primitive3D("3d.setroll"); + delay(); + cadre.getDrawPanel().setRoll(kernel.getCalculator().numberDouble(param.pop())); + break; + case 255:// setpitch=fixetangage + primitive3D("3d.setpitch"); + delay(); + cadre.getDrawPanel().setPitch(kernel.getCalculator().numberDouble(param.pop())); + break; + case 256:// setorientation=fixeorientation + primitive3D("3d.setorientation"); + delay(); + cadre.getDrawPanel().setOrientation(getFinalList(param.pop())); + break; + case 257: // orientation=orientation + primitive3D("3d.orientation"); + Interprete.operande = true; + String pitch = MyCalculator.teste_fin_double(kernel.getActiveTurtle().pitch); + String roll = MyCalculator.teste_fin_double(kernel.getActiveTurtle().roll); + String heading = MyCalculator.teste_fin_double(kernel.getActiveTurtle().heading); + Interprete.calcul.push("[ " + roll + " " + pitch + " " + heading + " ] "); + break; + case 258: // setxyz=fposxyz + primitive3D("3d.setxyz"); + cadre.getDrawPanel().fpos( + kernel.getCalculator().numberDouble(param.get(0)) + " " + + kernel.getCalculator().numberDouble(param.get(1)) + " " + + kernel.getCalculator().numberDouble(param.get(2))); + break; + case 259: // setz=fixez + delay(); + primitive3D("3d.setz"); + cadre.getDrawPanel().fpos( + kernel.getActiveTurtle().X + " " + kernel.getActiveTurtle().Y + " " + + kernel.getCalculator().numberDouble(param.get(0))); + break; + case 260: // pprop=dprop + Interprete.operande = false; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + mot2 = getWord(param.get(1)); + if (null == mot2) + throw new LogoError(param.get(1) + " " + Logo.messages.getString("error.word")); + wp.getPropertyLists().addPropList(mot, mot2, param.get(2)); // TODO + // changed + break; + case 261: // gprop=rprop + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + mot2 = getWord(param.get(1)); + if (null == mot2) + throw new LogoError(param.get(1) + " " + Logo.messages.getString("error.word")); + value = wp.getPropertyLists().getPropList(mot, mot2); // TODO + // CHANGED + if (value.startsWith("[")) + value += " "; + Interprete.calcul.push(value); + break; + case 262: // remprop=efprop + Interprete.operande = false; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + mot2 = getWord(param.get(1)); + if (null == mot2) + throw new LogoError(param.get(1) + " " + Logo.messages.getString("error.word")); + wp.getPropertyLists().removePropList(mot, mot2); // TODO + // CHANGED + break; + case 263: // plist=lprop + Interprete.operande = true; + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + Interprete.calcul.push(wp.getPropertyLists().displayPropList(mot)); // TODO + // CHANGED + + break; + case 264: // polystart=polydef + DrawPanel.record3D = DrawPanel.record3D_POLYGON; + cadre.initViewer3D(); + // if (null==DrawPanel.listPoly) DrawPanel.listPoly=new + // java.util.Vector<Shape3D>(); + DrawPanel.poly = new ElementPolygon(cadre.getViewer3D()); + break; + case 265: // polyend=polyfin + DrawPanel.record3D = DrawPanel.record3D_NONE; + DrawPanel.poly.addToScene(); + break; + case 266: // polyview=polyaf vue3d + primitive3D("3d.polyview"); + cadre.viewerOpen(); + break; + case 267: // linestart=lignedef + DrawPanel.record3D = DrawPanel.record3D_LINE; + cadre.initViewer3D(); + // if (null==DrawPanel.listPoly) DrawPanel.listPoly=new + // java.util.Vector<Shape3D>(); + DrawPanel.poly = new ElementLine(cadre.getViewer3D(), cadre.getKernel().getActiveTurtle().getPenWidth()); + DrawPanel.poly.addVertex(new Point3d(kernel.getActiveTurtle().X / 1000, + kernel.getActiveTurtle().Y / 1000, kernel.getActiveTurtle().Z / 1000), kernel + .getActiveTurtle().couleurcrayon); + break; + case 268: // lineend=lignefin + DrawPanel.record3D = DrawPanel.record3D_NONE; + DrawPanel.poly.addToScene(); + break; + case 269: // pointstart=pointdef + DrawPanel.record3D = DrawPanel.record3D_POINT; + cadre.initViewer3D(); + // if (null==DrawPanel.listPoly) DrawPanel.listPoly=new + // java.util.Vector<Shape3D>(); + DrawPanel.poly = new ElementPoint(cadre.getViewer3D(), cadre.getKernel().getActiveTurtle().getPenWidth()); + break; + case 270: // pointend=pointfin + DrawPanel.record3D = DrawPanel.record3D_NONE; + DrawPanel.poly.addToScene(); + break; + case 271: // textstart=textedef + DrawPanel.record3D = DrawPanel.record3D_TEXT; + cadre.initViewer3D(); + // if (null==DrawPanel.listText) DrawPanel.listText=new + // java.util.Vector<TransformGroup>(); + DrawPanel.poly = null; + break; + case 272: // textend=textefin + DrawPanel.record3D = DrawPanel.record3D_NONE; + break; + case 273: // operator <= + infequal(param); + break; + case 274: // operator >= + supequal(param); + break; + case 275: // primitives + Interprete.operande = true; + Interprete.calcul.push(kernel.primitive.getAllPrimitives()); + break; + case 276: // listesproprietes propertylists + Interprete.operande = true; + Interprete.calcul.push(new String(getAllpropertyLists())); + break; + case 277: // contenu + Interprete.operande = true; + sb = new StringBuffer("[ "); + sb.append(this.getAllProcedures()); + sb.append(this.getAllVariables()); + sb.append(this.getAllpropertyLists()); + sb.append("] "); + Interprete.calcul.push(new String(sb)); + break; + case 278: // erpl=eflp effacelistepropriete + Interprete.operande = false; + this.erase(param.get(0), "propertylist"); + break; + case 279: // arithmetic.exp + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().exp(param.get(0))); + break; + case 280: // arithmetic.log + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().log(param.get(0))); + break; + case 281: // controls.ifelse + liste = getList(param.get(1)); + liste = new String(Utils.decoupe(liste)); + pred = predicat(param.get(0)); + liste2 = getList(param.get(2)); + liste = new String(Utils.decoupe(liste)); + kernel.primitive.si(pred, liste, liste2); + Interprete.renvoi_instruction = true; + break; + case 282: // workspace.ed + + /* + * Marko Zivkovic: + * With the new Workspace (UserSpace + LogoFile) ed makes + * not so much sense, because we work with + * multiple files at the same time. + * I therefore restrict this command to allow only a single + * word as parameter, to open the file, + * where the specified procedure is defined, and scroll to + * the procedure's line. + */ + + mot = this.getWord(param.get(0)); + if (mot == null) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + if (!wp.isExecutable(mot)) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.proc.does.not.exist")); + + cadre.displayProcedure(mot); + break; + case 283: // workspace.edall + /* + * Marko Zivkovic: + * Again, it makes no sense to open all files at a time. + * Instead, I just open the last edited file. + */ + wp.editAll(); + break; + case 284: // controls.foreach pourchaque + // Variable name + var = getWord(param.get(0)); + // If it isn't a word + if (null == var) + throw new LogoError(param.get(0).toString() + " " + Logo.messages.getString("error.word")); + // If it's a number + else + { + try + { + Double.parseDouble(var); + throw new LogoError(Logo.messages.getString("erreur_nom_nombre_variable")); + } + catch (NumberFormatException e1) + {} + } + li2 = getList(param.get(2)); + li2 = new String(Utils.decoupe(li2)); + li1 = getWord(param.get(1)); + boolean isList = false; + if (null == li1) + { + isList = true; + li1 = getFinalList(param.get(1)); + } + Vector<String> elements = new Vector<String>(); + while (!li1.equals("")) + { + String character = ""; + // If it's a list + if (isList) + { + character = this.item(li1, 1); + // If it's a number + try + { + // Fix Bug: foreach "i [1 2 3][pr :i] + // character=1 , 2 , 3 (without quote) + Double.parseDouble(character); + li1 = li1.substring(character.length() + 1); + } + catch (NumberFormatException e) + { + // Fix Bug: foreach "i [r s t][pr :i] + // character="r , "s or "t + li1 = li1.substring(character.length()); + } + } + // If it's a word + else + { + character = this.itemWord(1, li1); + li1 = li1.substring(character.length()); + // If it isn't a number, adding a quote + try + { + Double.parseDouble(character); + } + catch (NumberFormatException e) + { + character = "\"" + character; + } + } + + elements.add(character); + } + if (elements.size() > 0) + { + LoopForEach lfe = new LoopForEach(BigDecimal.ZERO, new BigDecimal(elements.size() - 1), + BigDecimal.ONE, li2, var.toLowerCase(), elements); + lfe.AffecteVar(true); + cadre.getKernel().getInstructionBuffer().insert(li2 + Primitive.END_LOOP + " "); + Primitive.stackLoop.push(lfe); + } + break; + case 285: // controls.forever repetetoujours + li2 = getList(param.get(0)); + li2 = new String(Utils.decoupe(li2)); + LoopProperties lp = new LoopProperties(BigDecimal.ONE, BigDecimal.ZERO, BigDecimal.ONE, li2); + cadre.getKernel().getInstructionBuffer().insert(li2 + Primitive.END_LOOP + " "); + Primitive.stackLoop.push(lp); + break; + case 286: // arithmetic.setdigits + Interprete.operande = false; + kernel.initCalculator(kernel.getCalculator().getInteger(param.get(0))); + break; + case 287: // arithmetic.digits + Interprete.operande = true; + Interprete.calcul.push(String.valueOf(kernel.getCalculator().getDigits())); + break; + case 288: // workspace.text + var = getWord(param.get(0)); + if (null == var) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + + Procedure proc = wp.getExecutable(var); + if (proc != null) + { + sb = new StringBuffer(); + sb.append("[ [ "); + // Append variable names + for (int j = 0; j < proc.nbparametre; j++) + { + sb.append(proc.variable.get(j)); + sb.append(" "); + } + for (int j = 0; j < proc.optVariables.size(); j++) + { + sb.append("[ "); + sb.append(proc.optVariables.get(j)); + sb.append(" "); + sb.append(proc.optVariablesExp.get(j).toString()); + sb.append(" ] "); + } + sb.append("] "); + // Append body procedure + sb.append(proc.cutInList()); + sb.append("] "); + Interprete.operande = true; + Interprete.calcul.push(sb.toString()); + } + else + throw new LogoError(var + " " + Logo.messages.getString("error.procedure.must.be")); + break; + case 289: // workspace.externalcommand + Interprete.operande = false; + + { + list = getFinalList(param.get(0)); + int index = numberOfElements(list); + String[] cmd = new String[index]; + for (i = 0; i < index; i++) + { + String liste1 = item(list, i + 1); + cmd[i] = Utils.SortieTexte(getFinalList(liste1).trim()); + } + try + { + /* + * String com=""; + * for(int i=0;i<cmd.length;i++){ + * com+=cmd[i]+" "; + * } + * System.out.println(com); + */ + Runtime.getRuntime().exec(cmd); + } + catch (IOException e2) + { + // System.out.println("a"); + } + + } + + { + // System.out.println("coucou"); + } + break; + case 290: // drawing.saveimage + String word = getWord(param.get(0)); + if (null == word) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + if (word.equals("")) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("mot_vide")); + // xmin, ymin, width, height + int[] coord = new int[4]; + list = getFinalList(param.get(1)); + st = new StringTokenizer(list); + if (st.countTokens() == 4) + { + try + { + int j = 0; + while (st.hasMoreTokens()) + { + coord[j] = Integer.parseInt(st.nextToken()); + j++; + } + coord[0] += w / 2; + coord[2] += w / 2; + coord[1] = h / 2 - coord[1]; + coord[3] = h / 2 - coord[3]; + if (coord[2] < coord[0]) + { + int tmp = coord[0]; + coord[0] = coord[2]; + coord[2] = tmp; + } + if (coord[3] < coord[1]) + { + int tmp = coord[1]; + coord[1] = coord[3]; + coord[3] = tmp; + } + coord[2] = coord[2] - coord[0]; + coord[3] = coord[3] - coord[1]; + } + catch (NumberFormatException e) + { + coord[0] = 0; + coord[2] = w; + coord[1] = 0; + coord[3] = h; + } + } + else + { + coord[0] = 0; + coord[2] = w; + coord[1] = 0; + coord[3] = h; + } + if (coord[2] == 0 || coord[3] == 0) + { + coord[0] = 0; + coord[2] = w; + coord[1] = 0; + coord[3] = h; + } + cadre.getDrawPanel().saveImage(word, coord); + Interprete.operande = false; + break; + case 291: // sound.mp3play + Interprete.operande = false; + if (kernel.getMp3Player() != null) + kernel.getMp3Player().getPlayer().close(); + mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(mot + " " + Logo.messages.getString("error.word")); + MP3Player player = new MP3Player(cadre, mot); + kernel.setMp3Player(player); + kernel.getMp3Player().start(); + break; + case 292: // sound.mp3stop + Interprete.operande = false; + if (null != kernel.getMp3Player()) + kernel.getMp3Player().getPlayer().close(); + break; + case 293: // zoom + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(DrawPanel.zoom)); + break; + case 294: // drawing.x + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(kernel.getActiveTurtle().getX())); + break; + case 295:// drawing.y + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(kernel.getActiveTurtle().getY())); + break; + case 296: // drawing.z + Interprete.operande = true; + primitive3D("drawing.z"); + Interprete.calcul.push(MyCalculator.teste_fin_double(kernel.getActiveTurtle().Z)); + break; + case 297: // drawing.fillpolygon + Interprete.operande = false; + list = getFinalList(param.get(0)); + LoopFillPolygon lfp = new LoopFillPolygon(); + Primitive.stackLoop.push(lfp); + cadre.getKernel().getInstructionBuffer().insert(Utils.decoupe(list) + Primitive.END_LOOP + " "); + cadre.getDrawPanel().startRecord2DPolygon(); + break; + case 298: // arithmetic.alea + Interprete.operande = true; + Interprete.calcul.push(MyCalculator.teste_fin_double(Math.random())); + break; + case 299: // loop.dountil + li1 = getList(param.get(0)); + li1 = new String(Utils.decoupe(li1)); + li2 = getList(param.get(1)); + li2 = new String(Utils.decoupe(li2)); + instr = "\\siwhile " + Utils.primitiveName("non") + " " + li2 + "[ " + li1 + "] "; + LoopWhile lw = new LoopWhile(BigDecimal.ONE, BigDecimal.ZERO, BigDecimal.ONE, instr); + Primitive.stackLoop.push(lw); + cadre.getKernel().getInstructionBuffer().insert(instr + Primitive.END_LOOP + " "); + break; + case 300: // loop.dowhile + li1 = getList(param.get(0)); + li1 = new String(Utils.decoupe(li1)); + li2 = getList(param.get(1)); + li2 = new String(Utils.decoupe(li2)); + instr = "\\siwhile " + li2 + "[ " + li1 + "] "; + lw = new LoopWhile(BigDecimal.ONE, BigDecimal.ZERO, BigDecimal.ONE, instr); + Primitive.stackLoop.push(lw); + cadre.getKernel().getInstructionBuffer().insert(li1 + instr + Primitive.END_LOOP + " "); + break; + case 301: // arithmetic.modulo + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().modulo(param.get(0), param.get(1))); + break; + case 302: // drawing.setfontjustify + Interprete.operande = false; + li1 = getFinalList(param.get(0)); + kernel.getActiveTurtle().setFontJustify(li1); + break; + case 303: // drawing.fontjustify + Interprete.operande = true; + Interprete.calcul.push(kernel.getActiveTurtle().getFontJustify()); + break; + case 304: // arithmetic.inf + inf(param); + break; + case 305: // arithmetic.sup + sup(param); + break; + case 306: // arithmetic.infequal + infequal(param); + break; + case 307: // arithmetic.supequal + supequal(param); + break; + + } + } + } + + /** + * This implementation of the Logo command "define" is slightly changed towards the original XLogo + * implementation. + * In {@link xlogo.gui.Editor#analyseprocedure()} (which is now {@link LogoFile#setText(String)}), + * I added the line statement {@code wp.deleteAllProcedures()} + * because we don't want the procedures to + * be ordered by definition time in the editor. + * We want the programmer to have the procedures in the editor exactly in + * the same order as the programmer writes them. + * + * @param params + * @author Marko Zivkovic + * @throws LogoError + */ + private void define(Stack<String> params) throws LogoError + { + String procedureName; + String procedureText = null; + procedureName = getWord(params.get(0)); + if (null == procedureName) + throw new LogoError(params.get(0) + " " + Logo.messages.getString("error.word")); + if (procedureName.equals("")) + throw new LogoError(Logo.messages.getString("procedure_vide")); + String list = getFinalList(params.get(1)); + StringBuffer sb = new StringBuffer(); + for (int i = 1; i <= numberOfElements(list); i++) + { + String liste1 = item(list, i); + liste1 = getFinalList(liste1); + + // First line + if (i == 1) + { + StringTokenizer st = new StringTokenizer(liste1); + sb.append(Logo.messages.getString("pour")); + sb.append(" "); + sb.append(procedureName); + sb.append(" "); + + while (st.hasMoreTokens()) + { + // Optional variables + String token = st.nextToken(); + if (token.equals("[")) + { + sb.append("[ :"); + while (st.hasMoreTokens()) + { + token = st.nextToken(); + if (token.equals("]")) + { + sb.append("] "); + break; + } + else + { + sb.append(token); + sb.append(" "); + } + } + } + else + { + sb.append(":"); + sb.append(token); + sb.append(" "); + } + } + } + // Body of the procedure + else if (i > 1) + { + sb.append("\n"); + sb.append(liste1); + } + } + sb.append("\n"); + sb.append(Logo.messages.getString("fin")); + + /* + * Marko Zivkovic: + * In XLogo4Schools, procedures are not created by setting the text + * of the editor, + * we directly define them in LogoFiles. + * Because we have multiple files, the defined procedure will be put + * in a special file for programatically defined procedures. + * If the procedure name was already defined, then it will be + * redefined, as before in XLogo. + * If there is an ambiguity with the procedure name, an error will + * be displayed "I don't know which one to redefine..." + */ + + if (wp.isProcedureAmbiguous(procedureName)) + throw new LogoError(procedureName + " " + Logo.messages.getString("ws.redefine.ambiguous.procedure")); + // procedureText is generated above => it is executable + procedureText = "\n" + new String(sb); + Procedure procedure = new Procedure(procedureText); + + Procedure other = wp.getExecutable(procedureName); + String fileName = other != null ? other.getOwnerName() : Logo.messages.getString("ws.generated.procedure"); + procedure.setOwnerName(fileName); + + try + { + wp.defineProcedure(procedure); + } + catch (IOException e) + { + throw new LogoError(Logo.messages.getString("ws.could.not.create.file") + " " + fileName); + } + } + + /** + * This method tests if the primitive name exist in 2D mode + * + * @param name + * The primitive name + * @throws LogoError + */ + private void primitive2D(String name) throws LogoError + { + if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_3D) + throw new LogoError(Utils.primitiveName(name) + " " + Logo.messages.getString("error.primitive2D")); + } + + /** + * This method tests if the primitive name exist in 2D mode + * + * @param name + * The primitive name + * @throws LogoError + */ + private void primitive3D(String name) throws LogoError + { + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + throw new LogoError(Utils.primitiveName(name) + " " + Logo.messages.getString("error.primitive3D")); + } + + /** + * Returns the code [r g b] for the color i + * + * @param i + * Integer representing the Color + */ + private void colorCode(int i) + { + Interprete.operande = true; + Color co = DrawPanel.defaultColors[i]; + Interprete.calcul.push("[ " + co.getRed() + " " + co.getGreen() + " " + co.getBlue() + " ] "); + } + + /** + * Save all procedures whose name are contained in the Stack pile + * + * @param fichier + * The patch to the saved file + * @param pile + * Stack Stack containing all procedure names + */ + private void saveProcedures(String fichier, Stack<String> pile) + { + try + { + String aecrire = ""; + boolean bool = true; + if (!fichier.endsWith(".lgo")) + fichier += ".lgo"; + String path = Utils.SortieTexte(WSManager.getUserConfig().getDefaultFolder()) + File.separator + fichier; + try + { + // TODO CHANGED + for (Procedure procedure : wp.getExecutables()) + { + if (null == pile) + bool = true; + else + bool = (pile.search(procedure.name) != -1); + if (bool) + { + aecrire += Logo.messages.getString("pour") + " " + procedure.name; + for (int j = 0; j < procedure.nbparametre; j++) + { + aecrire += " :" + procedure.variable.get(j); + } + aecrire += "\n" + procedure.instruction + Logo.messages.getString("fin") + "\n\n"; + } + } + } + catch (NullPointerException ex) + {} // Si aucune procédure n'a été définie. + Utils.writeLogoFile(path, aecrire); + } + catch (IOException e2) + { + HistoryMessenger.getInstance().dispatchError(Logo.messages.getString("error.ioecriture")); + } + } + + /** + * Returns the Image defined by the path "chemin" + * + * @param chemin + * The absolute path for the image + * @return BufferedImage defined by the path "chemin" + * @throws LogoError + * If Image format isn't valid(jpg or png) + */ + private BufferedImage getImage(String path) throws LogoError + { + BufferedImage image = null; + String pathWord = getWord(path); + if (null == pathWord) + throw new LogoError(path + " " + Logo.messages.getString("error.word")); + if (!(pathWord.endsWith(".png") || pathWord.endsWith(".jpg"))) + throw new LogoError(Logo.messages.getString("erreur_format_image")); + else + { + try + { + pathWord = Utils.SortieTexte(pathWord); + File f = new File(Utils.SortieTexte(WSManager.getUserConfig().getDefaultFolder()) + File.separator + + pathWord); + image = ImageIO.read(f); + } + catch (Exception e1) + { + throw new LogoError(Logo.messages.getString("error.iolecture")); + } + } + return image; + } + + /** + * Create a local variable called "mot" with no value. + * + * @param mot + * Variable name + */ + private void createLocaleName(String mot) + { + mot = mot.toLowerCase(); + if (!Interprete.locale.containsKey(mot)) + { + Interprete.locale.put(mot, null); + } + } + + /** + * Create a new local variable + * + * @param param + * The variable name or a list of variable names + * @throws LogoError + * If "param" isn't a list containing all variable names, or a + * word + */ + + private void locale(Stack<String> param) throws LogoError + { + String li = param.get(0); + if (LaunchPrimitive.isList(li)) + { + li = getFinalList(li); + StringTokenizer st = new StringTokenizer(li); + while (st.hasMoreTokens()) + { + String item = st.nextToken(); + isVariableName(item); + createLocaleName(item); + } + } + else + { + String mot = getWord(param.get(0)); + if (null != mot) + { + createLocaleName(mot); + } + else + throw new LogoError(param.get(0) + Logo.messages.getString("error.word")); + } + } + + /** + * returns the color defined by [r g b] contained in "ob" + * + * @param obj + * the list [r g b] + * @param name + * The name of the calling primitive + * @return The Object Color + * @throws LogoError + * If the list doesn't contain 3 numbers + */ + + private Color rgb(String obj, String name) throws LogoError + { + String liste = getFinalList(obj); + StringTokenizer st = new StringTokenizer(liste); + if (st.countTokens() != 3) + throw new LogoError(name + " " + Logo.messages.getString("color_3_arguments")); + int[] entier = new int[3]; + for (int i = 0; i < 3; i++) + { + String element = st.nextToken(); + try + { + entier[i] = (int) (Double.parseDouble(element) + 0.5); + } + catch (NumberFormatException e) + { + throw new LogoError(element + " " + Logo.messages.getString("pas_nombre")); + } + if (entier[i] < 0) + entier[i] = 0; + if (entier[i] > 255) + entier[i] = 255; + + } + return (new Color(entier[0], entier[1], entier[2])); + } + + /** + * Primitive member or member? + * + * @param param + * Stack that contains arguments for the primitive member + * @param id + * 69 --> member? or 70--> member + * @throws LogoError + * Incorrect arguments + */ + private void membre(Stack<String> param, int id) throws LogoError + { + Interprete.operande = true; + String mot_retourne = null; + boolean b = false; + String mot = getWord(param.get(1)); + String liste = "[ "; + if (null == mot) + { // on travaille sur une liste + + liste = getFinalList(param.get(1)); + StringTokenizer st = new StringTokenizer(liste); + liste = "[ "; + mot = getWord(param.get(0)); + String str; + if (null != mot && mot.equals("")) + mot = "\\v"; + if (null == mot) + mot = param.get(0).trim(); + while (st.hasMoreTokens()) + { + str = st.nextToken(); + if (str.equals("[")) + str = extractList(st); + if (!liste.equals("[ ")) + liste += str + " "; + if (str.equals(mot) && liste.equals("[ ")) + { + if (id == 69) + { + b = true; + break; + } + else + liste += str + " "; + } + } + } + else + { // on travaille sur un mot + String mot2 = getWord(param.get(0)); + if (null != mot2) + { + boolean backslash = false; + for (int i = 0; i < mot.length(); i++) + { + char c = mot.charAt(i); + if (!backslash && c == '\\') + backslash = true; + else + { + String tmp = Character.toString(c); + if (backslash) + tmp = "\\" + tmp; + if (tmp.equals(mot2)) + { + if (id == 69) + { + b = true; + break; + } + else + { + if (!backslash) + mot_retourne = mot.substring(i, mot.length()); + else + mot_retourne = mot.substring(i - 1, mot.length()); + break; + } + } + backslash = false; + } + } + } + } + if (!liste.equals("[ ")) + Interprete.calcul.push(liste + "] "); + else if (null != mot_retourne) + { + try + { + Double.parseDouble(mot_retourne); + Interprete.calcul.push(mot_retourne); + } + catch (NumberFormatException e) + { + Interprete.calcul.push(debut_chaine + mot_retourne); + } + } + else if (b) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + } + + /** + * Primitive before? + * + * @param param + * Stack that contains all arguments + * @throws LogoError + * Bad argument type + */ + + private void precede(Stack<String> param) throws LogoError + { + Interprete.operande = true; + boolean b = false; + String ope[] = { "", "" }; + String mot = ""; + for (int i = 0; i < 2; i++) + { + mot = getWord(param.get(i)); + if (null == mot) + throw new LogoError(param.get(i) + " " + Logo.messages.getString("pas_mot")); + else + ope[i] = mot; + } + if (ope[1].compareTo(ope[0]) > 0) + b = true; + if (b) + mot = Logo.messages.getString("vrai"); + else + mot = Logo.messages.getString("faux"); + Interprete.calcul.push(mot); + } + + private void infequal(Stack<String> param) throws LogoError + { + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().infequal(param)); + } + + private void supequal(Stack<String> param) throws LogoError + { + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().supequal(param)); + } + + private void inf(Stack<String> param) throws LogoError + { + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().inf(param)); + } + + private void sup(Stack<String> param) throws LogoError + { + Interprete.operande = true; + Interprete.calcul.push(kernel.getCalculator().sup(param)); + } + + /** + * / Primitive equal? + * + * @param param + * Stack that contains all arguments + * @throws LogoError + */ + private void equal(Stack<String> param) throws LogoError + { + try + { + Double.parseDouble(param.get(0)); + Double.parseDouble(param.get(1)); + Interprete.calcul.push(kernel.getCalculator().equal(param)); + } + catch (NumberFormatException e) + { + if (param.get(0).toString().equals(param.get(1).toString())) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + } + Interprete.operande = true; + } + + /** + * this method returns the boolean corresponding to the string st + * + * @param st + * true or false + * @return The boolean corresponding to the string st + * @throws LogoError + * If st isn't equal to true or false + */ + + private boolean predicat(String st) throws LogoError + { + if (st.toLowerCase().equals(Logo.messages.getString("vrai"))) + return true; + else if (st.toLowerCase().equals(Logo.messages.getString("faux"))) + return false; + else + throw new LogoError(st + " " + Logo.messages.getString("pas_predicat")); + + } + + /** + * Returns the word contained in st. If it isn't a word, returns null + * + * @param st + * The Object to convert + * @return The word corresponding to st + */ + private String getWord(Object st) + { // Si c'est un mot + String liste = st.toString(); + if (liste.equals("\"")) + { + debut_chaine = ""; + return ""; + } + if (liste.length() > 0 && liste.substring(0, 1).equals("\"")) + { + debut_chaine = "\""; + return (liste.substring(1, liste.length())); + } + else + try + { + if (liste == String.valueOf(Double.parseDouble(liste))) + debut_chaine = ""; + else + debut_chaine = "\""; + return Utils.SortieTexte(liste); + } + catch (NumberFormatException e) + {} + return (null); + } + + /** + * Returns the list contained in the string li without any lineNumber + * + * @param li + * The String corresponding to the list + * @return A list without any line Number tag (\0, \1, \2 ...) + * @throws LogoError + * List bad format + */ + + private String getFinalList(String li) throws LogoError + { + // remove line number + li = li.replaceAll("\\\\l([0-9])+ ", ""); + // return list + return getList(li); + } + + /** + * Returns the list contained in the string li + * + * @param li + * The String corresponding to the list + * @return A list with line Number tag (\0, \1, \2 ...) + * @throws LogoError + * List bad format + */ + private String getList(String li) throws LogoError + { + li = li.trim(); + // Retourne la liste sans crochets; + if (li.substring(0, 1).equals("[") && li.substring(li.length() - 1, li.length()).equals("]")) + { + li = li.substring(1, li.length() - 1).trim() + " "; + if (!li.equals(" ")) + return li; + else + return (""); + } + else + throw new LogoError(li + " " + Logo.messages.getString("pas_liste")); + } + + /** + * Tests if "li" is a list + * + * @param li + * The String to test + * @return true if it is a list, else false + */ + // + protected static boolean isList(String li) + { + li = li.trim(); + if (li.length() > 0 && li.substring(0, 1).equals("[") && li.substring(li.length() - 1, li.length()).equals("]")) + return (true); + return false; + } + + // Format the List (only one space between two elements) + private String formatList(String li) + { + String tampon = ""; + String precedent = ""; + StringTokenizer st = new StringTokenizer(li, " []", true); + String element = ""; + while (st.hasMoreTokens()) + { + element = st.nextToken(); + while (st.hasMoreTokens() && element.equals(" ")) + { + element = st.nextToken(); + } + if (element.equals("]")) + tampon = tampon.trim() + "] "; + else if (element.equals("[")) + { + if (precedent.equals("[")) + tampon += "["; + else + tampon = tampon.trim() + " ["; + } + else + tampon += element + " "; + precedent = element; + } + return (tampon.trim()); + } + + private String extractList(StringTokenizer st) + { + int compteur = 1; + String crochet = "[ "; + String element = ""; + while (st.hasMoreTokens()) + { + element = st.nextToken(); + if (element.equals("[")) + { + compteur++; + crochet += "[ "; + } + else if (!element.equals("]")) + crochet += element + " "; + else if (compteur != 1) + { + compteur--; + crochet += "] "; + } + else + { + crochet += element + " "; + break; + } + } + element = crochet; + compteur = 0; + return element.trim(); + } + + private int extractList(String st, int deb) + { + int compteur = 1; + char element; + boolean espace = true; + boolean crochet_ouvert = false; + boolean crochet_ferme = false; + for (int i = deb; i < st.length(); i++) + { + element = st.charAt(i); + if (element == '[') + { + if (espace) + crochet_ouvert = true; + espace = false; + crochet_ferme = false; + } + else if (element == ']') + { + if (espace) + crochet_ferme = true; + espace = false; + crochet_ouvert = false; + } + else if (element == ' ') + { + espace = true; + if (crochet_ouvert) + { + compteur++; + crochet_ouvert = false; + } + else if (crochet_ferme) + { + crochet_ferme = false; + if (compteur != 1) + compteur--; + else + { + compteur = i; + break; + } + } + } + } + return compteur; + } + + // returns how many elements contains the list "liste" + private int numberOfElements(String liste) + { // calcule le nombre + // d'éléments dans une + // liste + StringTokenizer st = new StringTokenizer(liste); + int i = 0; + String element = ""; + while (st.hasMoreTokens()) + { + element = st.nextToken(); + if (element.equals("[")) + element = extractList(st); + i++; + } + return i; + } + + // returns the item "i" from the list "liste" + private String item(String liste, int i) throws LogoError + { // retourne + // l'élément i d'une + // liste + StringTokenizer st = new StringTokenizer(liste); + String element = ""; + int j = 0; + while (st.hasMoreTokens()) + { + j++; + element = st.nextToken(); + if (element.equals("[")) + element = extractList(st); + if (j == i) + break; + } + if (j != i) + throw new LogoError(Logo.messages.getString("y_a_pas") + " " + i + " " + + Logo.messages.getString("element_dans_liste") + liste + "]"); + else if (i == 0 && j == 0) + throw new LogoError(Logo.messages.getString("liste_vide")); + try + { + Double.parseDouble(element); + return element; + } // Si c'est un nombre, on le renvoie. + catch (Exception e) + {} + if (element.startsWith("[")) + return element + " "; // C'est une liste, on la renvoie telle + // quelle. + if (element.equals("\\v")) + element = ""; + return "\"" + element; // C'est forcément un mot, on le renvoie. + } + + // Test if the name of the variable is valid + private void isVariableName(String st) throws LogoError + { + if (st.equals("")) + throw new LogoError(Logo.messages.getString("variable_vide")); + if (":+-*/() []=<>&|".indexOf(st) > -1) + throw new LogoError(st + " " + Logo.messages.getString("erreur_variable")); + + try + { + Double.parseDouble(st); + throw new LogoError(Logo.messages.getString("erreur_nom_nombre_variable")); + } + catch (NumberFormatException e) + { + + } + + } + + // primitve make + private void donne(Stack<String> param) throws LogoError + { + String mot = getWord(param.get(0)); + if (null == mot) + throw new LogoError(param.get(0) + " " + Logo.messages.getString("error.word")); + mot = mot.toLowerCase(); + isVariableName(mot); + if (Interprete.locale.containsKey(mot)) + { + Interprete.locale.put(mot, param.get(1)); + } + else + { + wp.getGlobals().define(mot, param.get(1)); // TODO changed + } + } + + private void delay() + { + if (WSManager.getUserConfig().getTurtleSpeed() != 0) + { + try + { + Thread.sleep((long) (WSManager.getUserConfig().getTurtleSpeed()*3)); + } + catch (InterruptedException e) + {} + } + } + + // How many characters in the word "mot" + private int getWordLength(String mot) + {// retourne le nombre de caractères + // d'un mot + int compteur = 0; + boolean backslash = false; + for (int i = 0; i < mot.length(); i++) + { + if (!backslash && mot.charAt(i) == '\\') + backslash = true; + else + { + backslash = false; + compteur++; + } + } + return compteur; + } + + // the character number "i" in the word "mot" + private String itemWord(int entier, String mot) throws LogoError + { + String reponse = ""; + int compteur = 1; + boolean backslash = false; + if (mot.equals("")) + throw new LogoError(Logo.messages.getString("mot_vide")); + for (int i = 0; i < mot.length(); i++) + { + char c = mot.charAt(i); + if (!backslash && c == '\\') + backslash = true; + else + { + if (compteur == entier) + { + if (backslash) + reponse = "\\" + Character.toString(c); + else + reponse = Character.toString(c); + break; + } + else + { + compteur++; + backslash = false; + } + } + } + return reponse; + } + + protected void setWorkspace(UserSpace workspace) + { + wp = workspace; + } + + private void ou(Stack<String> param) throws LogoError + { + int size = param.size(); + boolean result = false; + boolean b; + for (int i = 0; i < size; i++) + { + b = predicat(param.get(i).toString()); + result = result | b; + } + if (result) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + Interprete.operande = true; + } + + private void et(Stack<String> param) throws LogoError + { + int size = param.size(); + boolean result = true; + boolean b; + for (int i = 0; i < size; i++) + { + b = predicat(param.get(i).toString()); + result = result & b; + } + Interprete.operande = true; + if (result) + Interprete.calcul.push(Logo.messages.getString("vrai")); + else + Interprete.calcul.push(Logo.messages.getString("faux")); + + } + + /** + * This methods returns a list that contains all procedures name + * + * @return A list with all procedure names + */ + private StringBuffer getAllProcedures() + { + StringBuffer sb = new StringBuffer("[ "); + // TODO CHANGED + for (Procedure proc : wp.getExecutables()) + { + sb.append(proc.getName()); + sb.append(" "); + } + sb.append("] "); + return sb; + } + + /** + * This methods returns a list that contains all variables name + * + * @return A list with all variables names + */ + + private StringBuffer getAllVariables() + { + StringBuffer sb = new StringBuffer("[ "); + Iterator<String> it = Interprete.locale.keySet().iterator(); + while (it.hasNext()) + { + String name = it.next(); + sb.append(name); + sb.append(" "); + } + // TODO changed + for (String key : wp.getGlobals().getVariables()) + { + if (!Interprete.locale.containsKey(key)) + { + sb.append(key.toString()); + sb.append(" "); + } + } + sb.append("] "); + return sb; + } + + /** + * This methods returns a list that contains all Property Lists name + * + * @return A list with all Property Lists names + */ + private StringBuffer getAllpropertyLists() + { + StringBuffer sb = new StringBuffer("[ "); + // TODO changed + for (String propList : wp.getPropertyLists().getPropListKeys()) + { + sb.append(propList); + sb.append(" "); + } + sb.append("] "); + return sb; + } + + /** + * Delete The variable called "name" from the workspace if it exists + * + * @param name + * The variable name + */ + private void deleteVariable(String name) + { + if (!Interprete.locale.isEmpty()) + { + if (Interprete.locale.containsKey(name)) + { + Interprete.locale.remove(name); + } + } + else + { + wp.getGlobals().deleteVariable(name.toLowerCase()); + } + } + + /** + * Delete the procedure called "name" from the workspace + * + * @param name + * The procedure name + */ + private void deleteProcedure(String name) + { + wp.eraseProcedure(name.toLowerCase()); + } + + /** + * According to the type of the data, erase from workspace the resource + * called "name" + * + * @param name + * The name of the deleted resource, it couls be a list with all + * resource names + * @param type + * The type for the data, it could be "variable", "procedure" or + * "propertylist" + * @throws LogoError + */ + + private void erase(String name, String type) throws LogoError + { + Interprete.operande = false; + if (LaunchPrimitive.isList(name)) + { + name = getFinalList(name); + StringTokenizer st = new StringTokenizer(name); + while (st.hasMoreTokens()) + { + String item = st.nextToken(); + this.eraseItem(item, type); + } + } + else + { + name = getWord(name); + if (null != name) + { + this.eraseItem(name, type); + } + else + throw new LogoError(name + Logo.messages.getString("error.word")); + + } + } + + /** + * According to the type of the data, erase from workspace the resource + * called "name" + * + * @param name + * The name of the deleted resource + * @param type + * The type for the data, it could be "variable", "procedure" or + * "propertylist" + */ + private void eraseItem(String name, String type) + { + if (type.equals("procedure")) + { + this.deleteProcedure(name.toLowerCase()); + } + else if (type.equals("variable")) + { + this.deleteVariable(name.toLowerCase()); + } + else if (type.equals("propertylist")) + { + wp.getPropertyLists().removePropList(name.toLowerCase()); + } + + } +} diff --git a/logo/src/xlogo/kernel/LogoError.java b/logo/src/xlogo/kernel/LogoError.java new file mode 100644 index 0000000..175c243 --- /dev/null +++ b/logo/src/xlogo/kernel/LogoError.java @@ -0,0 +1,89 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were entirely written Marko Zivkovic + */ + +package xlogo.kernel; + +/** + * In XLogo, myException was used. My exception was something rather funny. + * Actually it was really bad. myException was an exception that handled itself, by showing an error dialog and by aborting execution of the running Logo program. + * Thus throwing a myException was more like a function call with the side effect, that execution jumped to some other place, wherever it was caught. + * Note that to handle itself, myException had to have a reference to {@link Application}. Thus every part of the interpreter that wanted to throw Logo errors + * had to have such a reference, even though Application was not used otherwise.<br> + * By moving the exception handling at the root, where interpretation is started, in {@link Affichage}, I managed to decouple several classes from Application. + * (Still, many of them are unnecessarily dependent on Application, but I cannot refactor everything in the given time) + * + * Also note how ugly myException was used before. LaunchPrimitive is the best example. The general pattern was this:<br> + * + * <pre> + * {@code + * case i: // i : the id of some Logo primitive + * try + * { + * ... + * if (the next token is not as expected) + * throw new myException(application, errorMessage); + * ... + * } + * catch (myException) + * {} + * break; // => end of execute() + * // Because myException "handled itself", Affichage and Interprete will not continue execution + * } + * </pre> + * + * Note that almost all of the more than 300 Logo primitives contained such a statement, sometimes even more. + * That is more than 5x300 = 1500 unnecessary lines of code (after my style guide) that make the reading very hard, + * and introducing multiple levels of blocks { } to the structure. + * + * I took myself the time to remove all these unnecessary try-catches, place only one in Affichage and thus make the core of the application much more readable. + * <p><p> + * Note that I cannot test all the 300 Logo procedures for every case, but since throwing a myException caused the Interpreter to stop anyway, + * Redirecting the exception up to the root in Affichage will not change the flow of correct Logo Execution. Only executions which caused an exception can maybe behave slightly different now. + * I will for sure test all the procedures that we use in our school projects and a few more. + * + * <p><p> + * Another interesting thing, or again, really bad. + * The {@code static boolean lance} in myException was initialized with false. There are several assignments that set, again, false to it, but there is no single set to true. + * In most cases where lance is tested in a if-statement, it is tested in conjunction with Application.error (which can be true or false) + * + * <p> And then, there was also the nested class Affiche, which was never used. + * + *@author Marko Zivkovic + */ +public class LogoError extends Exception +{ + private static final long serialVersionUID = 9184760816698357437L; + + public LogoError() + { + } + + public LogoError(String st) + { + super(st); + } +} diff --git a/logo/src/xlogo/kernel/LoopFillPolygon.java b/logo/src/xlogo/kernel/LoopFillPolygon.java new file mode 100644 index 0000000..f2cb0fd --- /dev/null +++ b/logo/src/xlogo/kernel/LoopFillPolygon.java @@ -0,0 +1,48 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.math.BigDecimal; + +public class LoopFillPolygon extends LoopProperties { + /** + * The super constructor for Fill Polygon Loops + * @param instr The instruction to execute each loop + */ + + LoopFillPolygon(){ + super(BigDecimal.ONE,BigDecimal.ONE,BigDecimal.ONE,""); + } + protected boolean isForEver(){ + return false; + } + protected boolean isFillPolygon(){ + return true; + } +} diff --git a/logo/src/xlogo/kernel/LoopFor.java b/logo/src/xlogo/kernel/LoopFor.java new file mode 100644 index 0000000..473fd28 --- /dev/null +++ b/logo/src/xlogo/kernel/LoopFor.java @@ -0,0 +1,94 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; +import java.math.BigDecimal; + +public class LoopFor extends LoopProperties{ + /** + * This boolean indicates + * @uml.property name="conserver" + */ + protected boolean conserver=false; + + /** + * The variable name + * @uml.property name="var" + */ + + String var=""; + /** + * Constructor Loop: For + * @param counter The beginning integer + * @param end The end integer + * @param increment The increment between two values + * @param instr The instruction to execute between two values + * @param var The name of the variable + */ + + LoopFor(BigDecimal counter,BigDecimal end,BigDecimal increment,String instr,String var){ + super(counter,end,increment,instr); + this.var=var; + } + + protected boolean isFor(){ + return true; + } + protected boolean isForEver(){ + return false; + } + /** + * This method affects the variable counter the correct value + * @param first boolean that indicates if it is the first affectation + */ + protected void AffecteVar(boolean first){ + String element=String.valueOf(super.getCounter()); + if (element.endsWith(".0")) element=element.substring(0,element.length()-2) ; + if (element.startsWith(".")||element.equals("")) element="0"+element; + + if (Interprete.locale.containsKey(var)){ + if (first) conserver=true; + Interprete.locale.put(var, element); + } + else { + Interprete.locale.put(var,element); + } + } + /** + * This method deletes the variable var from the local stack variable + */ + void DeleteVar(){ + if (!conserver){ + if (Interprete.locale.containsKey(var)){ + Interprete.locale.remove(var); + } + + } + } + +} diff --git a/logo/src/xlogo/kernel/LoopForEach.java b/logo/src/xlogo/kernel/LoopForEach.java new file mode 100644 index 0000000..3d0c518 --- /dev/null +++ b/logo/src/xlogo/kernel/LoopForEach.java @@ -0,0 +1,69 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.math.BigDecimal; +import java.util.Vector; + +public class LoopForEach extends LoopFor{ + private Vector<String> vec; + /** + * Constructor Loop: For + * @param counter The beginning integer + * @param end The end integer + * @param increment The increment between two values + * @param instr The instruction to execute between two values + * @param var The name of the variable + * @param vec The Vec with all value for the variable + */ + LoopForEach(BigDecimal counter,BigDecimal end,BigDecimal increment,String instr,String var,Vector<String> vec){ + super(counter,end,increment,instr,var); + this.vec=vec; + } + protected boolean isForEach(){ + return true; + } + protected boolean isForEver(){ + return false; + } + /** + * This method affects the variable counter the correct value + * @param first boolean that indicates if it is the first affectation + */ + protected void AffecteVar(boolean first){ + String element=vec.get(getCounter().intValue()); + if (Interprete.locale.containsKey(var)){ + if (first) conserver=true; + Interprete.locale.put(var, element); + } + else { + Interprete.locale.put(var,element); + } + } +} diff --git a/logo/src/xlogo/kernel/LoopProperties.java b/logo/src/xlogo/kernel/LoopProperties.java new file mode 100644 index 0000000..ac252e4 --- /dev/null +++ b/logo/src/xlogo/kernel/LoopProperties.java @@ -0,0 +1,149 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +package xlogo.kernel; +import java.math.BigDecimal; +/** + * This class saves all Loop Properties (repeat, while, for) such as increment, end integer .... + * @author loic + */ +public class LoopProperties { + /** + * Counter: The counter value for the current loop End: The end value for the loop Increment the increment between two values + * @uml.property name="counter" + */ + private BigDecimal counter; + /** + * Counter: The counter value for the current loop End: The end value for the loop Increment the increment between two values + * @uml.property name="end" + */ + private BigDecimal end; + /** + * Counter: The counter value for the current loop End: The end value for the loop Increment the increment between two values + * @uml.property name="increment" + */ + private BigDecimal increment; + /** + * The Instruction to execute on each iteration + * @uml.property name="instr" + */ + String instr; +/** + * The super constructor for all loops + * @param counter The beginning integer + * @param fin The end integer + * @param increment The increment between two values + * @param instr The instruction to execute each loop + */ + LoopProperties(BigDecimal counter,BigDecimal end,BigDecimal increment,String instr){ + this.counter=counter; + this.end=end; + this.increment=increment; + this.instr=instr; + } + + + /** + * Adds the increment to the variable counter + */ + + protected void incremente(){ + counter=counter.add(increment); + counter=new BigDecimal(MyCalculator.eraseZero(counter)); + } + /** + * This method returns the Loop Id + * @return the Loop Id (TYPE_FOR, TYPE_WHILE...) + */ +/* protected int getId(){ + return id; + }*/ + /** + * This method returns the Loop Id + * @return the Loop Id (TYPE_FOR, TYPE_WHILE...) + * @uml.property name="counter" + */ + protected BigDecimal getCounter(){ + return counter; + } + /** + * This method returns the end Value + * @return the end value for the loop + * @uml.property name="end" + */ + protected BigDecimal getEnd(){ + return end; + } + /** + * this method returns the increment for the loop + * @return The variable increment + * @uml.property name="increment" + */ + protected BigDecimal getIncrement(){ + return increment; + } + /** + * This method returns the instructions to execute each loop + * @return the instruction block + * @uml.property name="instr" + */ + protected String getInstr(){ + return instr; + } + /** + * This method returns a loop description + */ + public String toString(){ + return(counter+" "+end+" "+increment+"\n"+instr+"\n"); + } + + protected boolean isFor(){ + return false; + } + protected boolean isWhile(){ + return false; + } + protected boolean isForEach(){ + return false; + } + protected boolean isRepeat(){ + return false; + } + protected boolean isForEver(){ + return true; + } + protected boolean isFillPolygon(){ + return false; + } +} diff --git a/logo/src/xlogo/kernel/LoopRepeat.java b/logo/src/xlogo/kernel/LoopRepeat.java new file mode 100644 index 0000000..5362d46 --- /dev/null +++ b/logo/src/xlogo/kernel/LoopRepeat.java @@ -0,0 +1,43 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.math.BigDecimal; + +public class LoopRepeat extends LoopProperties{ + LoopRepeat(BigDecimal counter,BigDecimal end,BigDecimal increment,String instr){ + super(counter,end,increment,instr); + } + protected boolean isRepeat(){ + return true; + } + protected boolean isForEver(){ + return false; + } +} diff --git a/logo/src/xlogo/kernel/LoopWhile.java b/logo/src/xlogo/kernel/LoopWhile.java new file mode 100644 index 0000000..c4451c8 --- /dev/null +++ b/logo/src/xlogo/kernel/LoopWhile.java @@ -0,0 +1,44 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.math.BigDecimal; + +public class LoopWhile extends LoopProperties{ + + LoopWhile(BigDecimal counter,BigDecimal end,BigDecimal increment,String instr){ + super(counter,end,increment,instr); + } + protected boolean isForEver(){ + return false; + } + protected boolean isWhile(){ + return true; + } +} diff --git a/logo/src/xlogo/kernel/MP3Player.java b/logo/src/xlogo/kernel/MP3Player.java new file mode 100644 index 0000000..e996bd2 --- /dev/null +++ b/logo/src/xlogo/kernel/MP3Player.java @@ -0,0 +1,86 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; + +import xlogo.Application; +import xlogo.Logo; +import xlogo.storage.WSManager; +import xlogo.utils.Utils; +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.advanced.AdvancedPlayer; +public class MP3Player extends Thread{ + + private AdvancedPlayer player; + + MP3Player(Application app,String path) throws LogoError{ + try { + // Build absolutePath + String absolutePath= Utils.SortieTexte(WSManager.getUserConfig().getDefaultFolder()) + + File.separator + Utils.SortieTexte(path); + player=new AdvancedPlayer(new FileInputStream(absolutePath)); + } + catch(FileNotFoundException e){ + // tentative fichier réseau + try{ + URL url =new java.net.URL(path); + java.io.InputStream fr = url.openStream(); + player=new AdvancedPlayer(fr); + } + catch( java.net.MalformedURLException e1){ + + throw new LogoError(Logo.messages.getString("error.iolecture")); + + + } + catch(IOException e2){} + catch(JavaLayerException e3){} + } + catch(JavaLayerException e4){} + + } + public void run(){ + try{ + player.play(); + } + catch(JavaLayerException e){} + } + /** + * @return + * @uml.property name="player" + */ + protected AdvancedPlayer getPlayer(){ + return player; + } + +} diff --git a/logo/src/xlogo/kernel/MyCalculator.java b/logo/src/xlogo/kernel/MyCalculator.java new file mode 100644 index 0000000..1fde09c --- /dev/null +++ b/logo/src/xlogo/kernel/MyCalculator.java @@ -0,0 +1,1221 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.math.MathContext; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Stack; + +import xlogo.Logo; +import xlogo.utils.Utils; + +public class MyCalculator +{ + private final BigDecimal tenth = new BigDecimal(0.1); + + private MathContext mc = null; + + // If precision is lesser than 16 (operation for double) + /** + * @uml.property name="lowPrecision" + */ + private boolean lowPrecision = true; + + /** + * Indicates if the log table have been created + * + * @uml.property name="initLogTable" + */ + private boolean initLogTable; + /** + * This is a table containing all BigDecimal ln(1+10^ (-k) ), k in + * {0,1....,digits-1} This are constants for the Cordic method to calculate + * ln, exp + * + * @uml.property name="logTable" multiplicity="(0 -1)" dimension="1" + */ + private BigDecimal[] logTable; + /** + * Indicates if the trigonometric table have been created + * + * @uml.property name="initCosTable" + */ + private boolean initCosTable; + /** + * This is a table containing all BigDecimal arctan 10^ (-k) , k in + * {0,1....,digits-1} This are constants for the Cordic method to calculate + * trigonometric functions + * + * @uml.property name="cosTable" multiplicity="(0 -1)" dimension="1" + */ + private BigDecimal[] cosTable; + + private static int digits; + + protected MyCalculator(int digits) + { + MyCalculator.digits = digits; + initLogTable = false; + initCosTable = false; + if (digits < 16) + { + mc = new MathContext(16); + lowPrecision = true; + logTable = new BigDecimal[16]; + cosTable = new BigDecimal[16]; + } + else + { + mc = new MathContext(digits); + lowPrecision = false; + logTable = new BigDecimal[digits]; + cosTable = new BigDecimal[digits]; + } + } + + /** + * Return The exponential of s according to matContext Precision + * + * @param s + * The number + * @return Exp(s) + * @throws LogoError + * if s isn't a number + */ + + protected String exp(String s) throws LogoError + { + if (lowPrecision) + { + double nombre = numberDouble(s); + return teste_fin_double(Math.exp(nombre)); + } + else + { + BigDecimal bd = numberDecimal(s); + return expBD(bd).toPlainString(); + } + } + + /** + * Return The logarithm of s according to matContext Precision + * + * @param s + * The number + * @return log(s) + * @throws LogoError + * if s isn't a number or negative + */ + + protected String log(String s) throws LogoError + { + if (lowPrecision) + { + double nombre = numberDouble(s); + if (nombre < 0 || nombre == 0) + { + String log = Utils.primitiveName("arithmetic.log"); + throw new LogoError(log + " " + Logo.messages.getString("attend_positif")); + } + return teste_fin_double(Math.log(nombre)); + } + else + { + BigDecimal bd = numberDecimal(s); + if (bd.signum() != 1) + { + String log = Utils.primitiveName("arithmetic.log"); + throw new LogoError(log + " " + Logo.messages.getString("attend_positif")); + } + return logBD(bd).toPlainString(); + } + } + + /** + * Return The square root of s according to matContext Precision + * + * @param s + * The number + * @return sqrt(s) + * @throws LogoError + * if s isn't a number or negative + */ + + protected String sqrt(String s) throws LogoError + { + if (lowPrecision) + { + double number = numberDouble(s); + if (number < 0) + { + String sqrt = Utils.primitiveName("arithmetic.racine"); + throw new LogoError(sqrt + " " + Logo.messages.getString("attend_positif")); + } + return teste_fin_double(Math.sqrt(number)); + } + else + { + BigDecimal bd = numberDecimal(s); + if (bd.signum() == -1) + { + String sqrt = Utils.primitiveName("arithmetic.racine"); + throw new LogoError(sqrt + " " + Logo.messages.getString("attend_positif")); + } + return sqrtBD(bd).toPlainString(); + } + } + + /** + * Return the product of all elements in stack param + * + * @param param + * The stack of operands + * @return The product + * @throws LogoError + */ + protected String multiply(Stack<String> param) throws LogoError + { + int size = param.size(); + BigDecimal product = BigDecimal.ONE; + BigDecimal a; + for (int i = 0; i < size; i++) + { + a = numberDecimal(param.get(i)); + product = product.multiply(a, mc); + } + return product.stripTrailingZeros().toPlainString(); + } + + protected String divide(Stack<String> param) throws LogoError + { + if (lowPrecision) + { + double a = numberDouble(param.get(0)); + double b = numberDouble(param.get(1)); + if (b == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + return (teste_fin_double(a / b)); + } + else + { + BigDecimal a = new BigDecimal(param.get(0), mc); + BigDecimal b = new BigDecimal(param.get(1), mc); + if (b.signum() == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + return (a.divide(b, mc).stripTrailingZeros().toPlainString()); + } + } + + /** + * Return the sum of all elements in stack param + * + * @param param + * The stack of operands + * @return The sum + * @throws LogoError + */ + protected String add(Stack<String> param) throws LogoError + { + int size = param.size(); + BigDecimal sum = BigDecimal.ZERO; + BigDecimal a; + for (int i = 0; i < size; i++) + { + a = numberDecimal(param.get(i)); + sum = sum.add(a, mc); + } + + return sum.stripTrailingZeros().toPlainString(); + } + + protected String inf(Stack<String> param) throws LogoError + { + BigDecimal a = numberDecimal(param.get(0)); + BigDecimal b = numberDecimal(param.get(1)); + if (a.compareTo(b) < 0) + return Logo.messages.getString("vrai"); + return Logo.messages.getString("faux"); + } + + protected String sup(Stack<String> param) throws LogoError + { + BigDecimal a = numberDecimal(param.get(0)); + BigDecimal b = numberDecimal(param.get(1)); + if (a.compareTo(b) > 0) + return Logo.messages.getString("vrai"); + return Logo.messages.getString("faux"); + } + + protected String infequal(Stack<String> param) throws LogoError + { + BigDecimal a = numberDecimal(param.get(0)); + BigDecimal b = numberDecimal(param.get(1)); + if (a.compareTo(b) <= 0) + return Logo.messages.getString("vrai"); + return Logo.messages.getString("faux"); + } + + protected String supequal(Stack<String> param) throws LogoError + { + BigDecimal a = numberDecimal(param.get(0)); + BigDecimal b = numberDecimal(param.get(1)); + if (a.compareTo(b) >= 0) + return Logo.messages.getString("vrai"); + return Logo.messages.getString("faux"); + } + + protected String equal(Stack<String> param) throws LogoError + { + BigDecimal a = numberDecimal(param.get(0)); + BigDecimal b = numberDecimal(param.get(1)); + if (a.compareTo(b) == 0) + return Logo.messages.getString("vrai"); + return Logo.messages.getString("faux"); + } + + protected String substract(Stack<String> param) throws LogoError + { + BigDecimal a = numberDecimal(param.get(0)); + BigDecimal b = numberDecimal(param.get(1)); + return a.subtract(b, mc).stripTrailingZeros().toPlainString(); + } + + /** + * Returns the opposite of s + * + * @param s + * @return + */ + protected String minus(String s) throws LogoError + { + BigDecimal a = numberDecimal(s); + return a.negate(mc).stripTrailingZeros().toPlainString(); + } + + protected String remainder(String a, String b) throws LogoError + { + if (lowPrecision) + { + int aa = getInteger(a); + int bb = getInteger(b); + if (bb == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + return teste_fin_double(aa % bb); + } + else + { + BigDecimal aa = getBigInteger(a); + BigDecimal bb = getBigInteger(b); + if (bb.signum() == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + return aa.remainder(bb, mc).stripTrailingZeros().toPlainString(); + + } + } + + protected String modulo(String a, String b) throws LogoError + { + if (lowPrecision) + { + int aa = getInteger(a); + int bb = getInteger(b); + if (bb == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + double rem = aa % bb; + if (aa * bb < 0 && rem != 0) + rem = rem + bb; + return teste_fin_double(rem); + } + else + { + BigDecimal aa = getBigInteger(a); + BigDecimal bb = getBigInteger(b); + if (bb.signum() == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + BigDecimal rem = aa.remainder(bb, mc); + if (aa.multiply(bb).compareTo(BigDecimal.ZERO) == -1 && (!rem.equals(BigDecimal.ZERO))) + rem = rem.add(bb); + return rem.stripTrailingZeros().toPlainString(); + + } + } + + protected String quotient(String a, String b) throws LogoError + { + if (lowPrecision) + { + double aa = numberDouble(a); + double bb = numberDouble(b); + if (bb == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + return String.valueOf((int) (aa / bb)); + } + else + { + BigDecimal aa = numberDecimal(a); + BigDecimal bb = numberDecimal(b); + if (bb.signum() == 0) + throw new LogoError(Logo.messages.getString("division_par_zero")); + return aa.divideToIntegralValue(bb, mc).stripTrailingZeros().toPlainString(); + + } + } + + protected String truncate(String a) throws LogoError + { + BigDecimal ent = numberDecimal(a); + return ent.toBigInteger().toString(); + } + + protected String abs(String a) throws LogoError + { + BigDecimal e = numberDecimal(a); + return e.abs().stripTrailingZeros().toPlainString(); + } + + protected String power(String a, String b) throws LogoError + { + if (lowPrecision) + { + double p = Math.pow(numberDouble(a), numberDouble(b)); + // Bug pr power -1 0.5 + Double p1 = new Double(p); + if (p1.equals(Double.NaN)) + throw new LogoError(Utils.primitiveName("arithmetic.puissance") + " " + + Logo.messages.getString("attend_positif")); + // End Bug + return teste_fin_double(p); + } + else + { + // if the exposant is an integer + try + { + int n = Integer.parseInt(b); + BigDecimal aa = numberDecimal(a); + return aa.pow(n, mc).toPlainString(); + } + catch (NumberFormatException e) + { + BigDecimal aa = numberDecimal(a); + BigDecimal bb = numberDecimal(b); + if (aa.signum() == 1) + { + return expBD(bb.multiply(logBD(aa), mc)).toPlainString(); + } + else if (aa.signum() == 0) + return "0"; + else + return String.valueOf(getInteger(b)); + } + } + } + + protected String log10(String s) throws LogoError + { + Stack<String> tmp = new Stack<String>(); + tmp.push(log(s)); + tmp.push(log("10")); + return divide(tmp); + } + + protected String pi() + { + if (lowPrecision) + { + return String.valueOf(Math.PI); + } + else + { + return piBD().toPlainString(); + } + } + + protected String sin(String s) throws LogoError + { + if (lowPrecision) + { + return teste_fin_double(Math.sin(Math.toRadians(numberDouble(s)))); + } + else + { + BigDecimal bd = numberDecimal(s); + return sinBD(bd).toPlainString(); + + } + } + + protected String cos(String s) throws LogoError + { + if (lowPrecision) + { + return teste_fin_double(Math.cos(Math.toRadians(numberDouble(s)))); + } + else + { + BigDecimal bd = numberDecimal(s); + return cosBD(bd).toPlainString(); + + } + } + + protected String tan(String s) throws LogoError + { + if (lowPrecision) + { + return teste_fin_double(Math.tan(Math.toRadians(numberDouble(s)))); + } + else + { + BigDecimal bd = numberDecimal(s); + return tanBD(bd).toPlainString(); + } + } + + protected String atan(String s) throws LogoError + { + if (lowPrecision) + { + return teste_fin_double(Math.toDegrees(Math.atan(numberDouble(s)))); + } + else + { + BigDecimal bd = numberDecimal(s); + return toDegree(atanBD(bd)).toPlainString(); + } + } + + protected String acos(String s) throws LogoError + { + if (lowPrecision) + { + return teste_fin_double(Math.toDegrees(Math.acos(numberDouble(s)))); + } + else + { + BigDecimal bd = numberDecimal(s); + return toDegree(acosBD(bd)).toPlainString(); + } + } + + protected String asin(String s) throws LogoError + { + if (lowPrecision) + { + return teste_fin_double(Math.toDegrees(Math.asin(numberDouble(s)))); + } + else + { + BigDecimal bd = numberDecimal(s); + return toDegree(asinBD(bd)).toPlainString(); + } + } + + /** + * This method returns the exp of bd + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal expBD(BigDecimal bd) + { + if (!initLogTable) + { + initLogTable(); + } + int signum = bd.signum(); + if (signum == -1) + { + BigDecimal exp = expCordic(bd.negate(mc)); + exp = BigDecimal.ONE.divide(exp, mc); + return exp; + } + else if (signum == 0) + return BigDecimal.ONE; + else + { + return expCordic(bd); + } + } + + private BigDecimal expCordic(BigDecimal bd) + { + int i = 0; + BigDecimal y = BigDecimal.ONE; + while (i < mc.getPrecision()) + { + while (logTable[i].subtract(bd).signum() == -1) + { + bd = bd.subtract(logTable[i], mc); + y = y.add(y.multiply(tenth.pow(i, mc), mc), mc); + } + i++; + } + y = y.multiply(bd.add(BigDecimal.ONE, mc), mc); + return y; + + } + + /** + * This method returns the log of bd + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal logBD(BigDecimal bd) + { + if (!initLogTable) + { + initLogTable(); + } + // If bd > 1 + int signum = bd.subtract(BigDecimal.ONE, mc).signum(); + if (signum == 1) + { + bd = bd.subtract(BigDecimal.ONE, mc); + return logCordic(bd); + } + else if (signum == 0) + return BigDecimal.ZERO; + else + { + bd = BigDecimal.ONE.divide(bd, mc).subtract(BigDecimal.ONE, mc); + return logCordic(bd).negate(mc); + } + } + + private BigDecimal logCordic(BigDecimal bd) + { + int i = 0; + BigDecimal y = BigDecimal.ZERO; + while (i < mc.getPrecision()) + { + BigDecimal tenthi = tenth.pow(i, mc); + while (bd.subtract(tenthi, mc).signum() > 0) + { + bd = bd.subtract(tenthi, mc).divide(BigDecimal.ONE.add(tenthi, mc), mc); + y = y.add(logTable[i], mc); + } + i++; + } + y = y.add(bd, mc).subtract(bd.pow(2, mc).multiply(new BigDecimal(0.5), mc), mc); + return y; + + } + + /** + * This method returns the sqrt of bd + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal sqrtBD(BigDecimal bd) + { + if (bd.signum() == 0) + return BigDecimal.ZERO; + BigDecimal three = new BigDecimal(3); + BigDecimal half = new BigDecimal(0.5); + BigDecimal x = BigDecimal.ZERO; + BigDecimal y = BigDecimal.ONE.min(BigDecimal.ONE.divide(bd, mc)); + while (x.compareTo(y) == -1) + { + x = y; + // y=(3x-bd*x^3)/2 + y = x.multiply(three, mc).subtract(bd.multiply(x.pow(3, mc), mc), mc).multiply(half, mc); + } + return BigDecimal.ONE.divide(y, mc); + } + + /** + * This method returns the cos of bd + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal cosBD(BigDecimal bd) + { + // bd is in degree + BigDecimal period = new BigDecimal(360); + BigDecimal a90 = new BigDecimal(90); + BigDecimal a135 = new BigDecimal(135); + BigDecimal a180 = new BigDecimal(180); + BigDecimal a225 = new BigDecimal(225); + BigDecimal a270 = new BigDecimal(270); + BigDecimal a315 = new BigDecimal(315); + + bd = bd.remainder(period, mc); + if (bd.signum() == -1) + bd = bd.add(period, mc); + BigDecimal quarterpi = new BigDecimal(45); + // Now bd between 0 and 360. + if (bd.compareTo(quarterpi) == -1) + { + // Between 0 and 45 + return cosCordic(toRadian(bd)); + } + else if (bd.compareTo(a90) == -1) + { + // Between 45 and 90 + return sinCordic(toRadian(a90.subtract(bd, mc))); + } + else if (bd.compareTo(a135) == -1) + { + // Between 90 and 135 + return sinCordic(toRadian(bd.subtract(a90, mc))).negate(mc); + } + else if (bd.compareTo(a180) == -1) + { + // Between 135 and 180 + return cosCordic(toRadian(a180.subtract(bd, mc))).negate(mc); + } + else if (bd.compareTo(a225) == -1) + { + // Between 180 and 225 + return cosCordic(toRadian(bd.subtract(a180, mc))).negate(mc); + } + else if (bd.compareTo(a270) == -1) + { + // Between 225 and 270 + return sinCordic(toRadian(a270.subtract(bd, mc))).negate(mc); + } + else if (bd.compareTo(a315) == -1) + { + // Between 270 and 315 + return sinCordic(toRadian(bd.subtract(a270, mc))); + } + else + { + return cosCordic(toRadian(new BigDecimal(360).subtract(bd, mc))); + } + } + + /** + * This method returns the cos of bd with 0<bd<pi/4 + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal cosCordic(BigDecimal bd) + { + return BigDecimal.ONE.divide(sqrtBD(tanCordic(bd).pow(2, mc).add(BigDecimal.ONE, mc)), mc); + } + + /** + * This method returns the cos of bd + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal sinBD(BigDecimal bd) + { + BigDecimal a90 = new BigDecimal(90); + return cosBD(a90.subtract(bd, mc)); + + } + + /** + * This method returns the sin of bd with 0<bd<pi/4 + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal sinCordic(BigDecimal bd) + { + BigDecimal tan = tanCordic(bd); + return tan.divide(sqrtBD(tan.pow(2, mc).add(BigDecimal.ONE, mc)), mc); + } + + /** + * This method returns the tan of bd (in degree) + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal tanBD(BigDecimal bd) + { + // bd is in degree + BigDecimal pi = new BigDecimal(180); + BigDecimal halfpi = new BigDecimal(90); + BigDecimal quarterpi = new BigDecimal(45); + bd = bd.remainder(pi, mc); + if (bd.compareTo(halfpi.negate(mc)) == -1) + bd = bd.add(pi, mc); + if (bd.compareTo(halfpi) == 1) + bd = bd.subtract(pi, mc); + // Now bd is in -90;+90 degrees + + if (bd.compareTo(quarterpi) == 1) + { + BigDecimal x = toRadian(new BigDecimal(0.5).multiply(bd, mc)); + return new BigDecimal(2).multiply(tanCordic(x), mc).divide( + BigDecimal.ONE.subtract(tanCordic(x).pow(2, mc), mc), mc); + } + else if (bd.signum() == 1) + { + return tanCordic(toRadian(bd)); + } + else if (bd.compareTo(quarterpi.negate(mc)) == 1) + { + return tanCordic(toRadian(bd.negate(mc))).negate(mc); + } + else + { + BigDecimal x = toRadian(new BigDecimal(0.5).multiply(bd, mc)).negate(mc); + return new BigDecimal(2).multiply(tanCordic(x), mc) + .divide(BigDecimal.ONE.subtract(tanCordic(x).pow(2, mc), mc), mc).negate(mc); + } + } + + /** + * This method returns the tan of bd with 0<bd<pi/4 + * based on the Cordic algorithm + * + * @param bd + * The first BigDecimal + * @return The result + */ + private BigDecimal tanCordic(BigDecimal bd) + { + if (!initCosTable) + initCosTable(); + BigDecimal three = new BigDecimal(3); + int k = 1; + BigDecimal x = BigDecimal.ONE; + BigDecimal y = BigDecimal.ZERO; + BigDecimal tenthk = tenth; + while (k < mc.getPrecision()) + { + while (cosTable[k].compareTo(bd) == -1) + { + bd = bd.subtract(cosTable[k], mc); + BigDecimal tmp = x; + x = x.subtract(tenthk.multiply(y, mc), mc); + y = y.add(tenthk.multiply(tmp, mc), mc); + } + tenthk = tenthk.multiply(tenth, mc); + k++; + } + BigDecimal tmp = bd.pow(3, mc).add(three.multiply(bd, mc), mc); + // return (3*y+(3t+t^3)*x)/(3x-(3t+t^3)*y + return three.multiply(y, mc).add(x.multiply(tmp, mc), mc) + .divide(three.multiply(x, mc).subtract(y.multiply(tmp, mc), mc), mc); + } + + private BigDecimal piBD() + { + if (!initCosTable) + { + initCosTable(); + } + return cosTable[0].multiply(new BigDecimal(4), mc); + } + + /** + * This method creates the log Table using + * log h=(h-1)-(h-1)^2/2+(h-1)^3/3-..... + * + * @param bd + * The first BigDecimal + * @return The result + */ + private void initLogTable() + { + initLogTable = true; + // calculate ln 2 + // Using ln 2=2*(x+x^3/3+x^5/5+....) with x=1/3 + + BigDecimal sum = BigDecimal.ZERO; + BigDecimal previous = BigDecimal.ONE; + BigDecimal i = BigDecimal.ONE; + BigDecimal nine = new BigDecimal(9); + BigDecimal two = new BigDecimal(2); + BigDecimal power = new BigDecimal(3); + while (sum.subtract(previous, mc).abs(mc).compareTo(BigDecimal.ZERO) != 0) + { + previous = sum; + sum = sum.add(BigDecimal.ONE.divide(i.multiply(power, mc), mc), mc); + i = i.add(two, mc); + power = power.multiply(nine, mc); + } + logTable[0] = sum.multiply(two, mc); + + // Calculate ln (1+10^-j) j in 1 ... digits-1 + + for (int j = 1; j < mc.getPrecision(); j++) + { + // count=0; + sum = BigDecimal.ZERO; + previous = BigDecimal.ONE; + i = BigDecimal.ONE; + // 10^(-j) + BigDecimal bd = tenth.pow(j, mc); + power = bd; + while (sum.subtract(previous, mc).abs(mc).compareTo(BigDecimal.ZERO) != 0) + { + previous = sum; + sum = sum.add(power.divide(i, mc), mc); + if (i.signum() == 1) + i = i.add(BigDecimal.ONE, mc).negate(mc); + else + i = i.subtract(BigDecimal.ONE, mc).negate(mc); + power = power.multiply(bd, mc); + // count++; + } + logTable[j] = sum; + } + } + + /** + * This method creates the cos Table using + * arctan h=x-x^3/3+x^5/5-x^7/7... + * + * @param bd + * The first BigDecimal + * @return The result + */ + private void initCosTable() + { + initCosTable = true; + // calculate pi/4 + + cosTable[0] = calcPI().multiply(new BigDecimal(0.25), mc); + + // Calculate arctan (10^-j) j in 1 ... digits-1 + + for (int j = 1; j < mc.getPrecision(); j++) + { + // 10^(-j) + BigDecimal bd = tenth.pow(j, mc); + cosTable[j] = arctanSE(bd); + // System.out.println(cosTable[j].toPlainString()); + } + } + + // Using PI = 16arctg(1/5) - 4arctg(1/239) + private BigDecimal calcPI() + { + return new BigDecimal(16).multiply(arctanSE(new BigDecimal("0.2")), mc).subtract( + new BigDecimal(4).multiply(arctanSE(BigDecimal.ONE.divide(new BigDecimal(239), mc)), mc), mc); + } + + private BigDecimal arctanSE2(BigDecimal bd) + { + BigDecimal i = BigDecimal.ONE; + // BigDecimal j=new BigDecimal(3); + BigDecimal two = new BigDecimal(2); + BigDecimal square = bd.multiply(bd, mc); + BigDecimal power = bd.divide(square.add(BigDecimal.ONE, mc), mc); + BigDecimal cst = new BigDecimal(4).multiply(square, mc).divide(square.add(BigDecimal.ONE, mc), mc); + BigDecimal previous = BigDecimal.ZERO; + BigDecimal sum = power; + int count = 0; + while (sum.subtract(previous, mc).abs(mc).compareTo(BigDecimal.ZERO) != 0) + { + previous = sum; + power = power.multiply(cst, mc); + power = power.multiply(i.pow(2, mc), mc); + BigDecimal doublei = two.multiply(i, mc); + doublei = doublei.multiply(doublei.add(BigDecimal.ONE, mc), mc); + power = power.divide(doublei, mc); + sum = sum.add(power, mc); + i = i.add(BigDecimal.ONE); + count++; + } + System.out.println("Itérations " + count); + return sum; + + } + + private BigDecimal atanBD(BigDecimal bd) + { + if (bd.signum() == -1) + return atanBD(bd.negate(mc)).negate(mc); + if (bd.compareTo(BigDecimal.ONE) == 1) + // pi/2 -arctan (1/x) + return piBD().multiply(new BigDecimal(0.5), mc).subtract(arctanSE(BigDecimal.ONE.divide(bd, mc)), mc); + else if (bd.compareTo(BigDecimal.ONE) == 0) + return piBD().multiply(new BigDecimal("0.25"), mc); + else + return arctanSE(bd); + } + + private BigDecimal acosBD(BigDecimal bd) + { + if (bd.compareTo(new BigDecimal("-1")) == 0) + { + return piBD(); + } + // acos x= 2 atan (sqrt(1-x^2)/1+x + else + { + return new BigDecimal("2").multiply( + atanBD(sqrtBD(BigDecimal.ONE.subtract(bd.pow(2, mc), mc)).divide(BigDecimal.ONE.add(bd, mc), mc)), + mc); + + } + } + + private BigDecimal asinBD(BigDecimal bd) + { + // acos x= 2 atan (x/(1+sqrt(1-x^2)) + return new BigDecimal("2").multiply( + atanBD(bd.divide(BigDecimal.ONE.add(sqrtBD(BigDecimal.ONE.subtract(bd.pow(2, mc), mc)), mc), mc)), mc); + } + + // arctan h=x-x^3/3+x^5/5-x^7/7... + private BigDecimal arctanSE(BigDecimal bd) + { + BigDecimal i = BigDecimal.ONE; + BigDecimal two = new BigDecimal(2, mc); + BigDecimal square = bd.multiply(bd, mc); + BigDecimal sum = BigDecimal.ZERO; + BigDecimal previous = BigDecimal.ONE; + while (sum.subtract(previous, mc).abs(mc).compareTo(BigDecimal.ZERO) != 0) + { + previous = sum; + sum = sum.add(bd.divide(i, mc), mc); + if (i.signum() == 1) + i = i.add(two, mc).negate(mc); + else + i = i.subtract(two, mc).negate(mc); + bd = bd.multiply(square, mc); + } + return sum; + } + + private BigDecimal toRadian(BigDecimal n) + { + return n.multiply(piBD(), mc).divide(new BigDecimal(180), mc); + } + + private BigDecimal toDegree(BigDecimal n) + { + return n.multiply(new BigDecimal(180), mc).divide(piBD(), mc); + } + + /** + * This method converts st to double + * + * @param st + * The String + * @return The double corresponding to st + * @throws LogoError + * If st can't be convert + */ + + protected double numberDouble(String st) throws LogoError + { // Si un nombre est + // un double + try + { + return (Double.parseDouble(st)); + } + catch (NumberFormatException e) + { + throw new LogoError(st + " " + Logo.messages.getString("pas_nombre")); + } + } + + /** + * If a double ends with the suffix ".0", remove it + * + * @param d + * @return + */ + + static protected String teste_fin_double(double d) + { + String st = String.valueOf(d); + if (st.endsWith(".0")) + st = st.substring(0, st.length() - 2); + return st; + } + + /** + * Converts st to BigDecimal number + * + * @param st + * The String to convert + * @return The BigDecimal Number + * @throws LogoError + * if st isn't a number + */ + + protected BigDecimal numberDecimal(String st) throws LogoError + { + /* + * if (null==mc){ + * try { + * BigDecimal bd = new BigDecimal(st).setScale(16, + * BigDecimal.ROUND_HALF_EVEN); + * return (new BigDecimal(eraseZero(bd))); + * } catch (NumberFormatException e) { + * throw new myException( st + " " + * + Logo.messages.getString("pas_nombre")); + * } + * } + * else { + */ + try + { + return new BigDecimal(st, mc); + } + catch (NumberFormatException e) + { + throw new LogoError(st + " " + Logo.messages.getString("pas_nombre")); + } + // } + + } + + /** + * Erase unused Zeros in decimal Format + * + * @param bd + * The decimal number + * @return The formatted number + */ + static protected String eraseZero(BigDecimal bd) + { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(); + dfs.setDecimalSeparator('.'); + DecimalFormat df = new DecimalFormat("#####.################", dfs); + String st = df.format(bd); + return st; + + } + + /** + * Test if the number contained in st is an integer + * + * @param st + * The Object to convert + * @return The integer corresponding to st + * @throws LogoError + * If it isn't an integer + */ + + protected int getInteger(String st) throws LogoError + { // Si c'est un + // entier + try + { + return Integer.parseInt(st); + } + catch (NumberFormatException e) + { + throw new LogoError(st + " " + Logo.messages.getString("pas_entier")); + } + } + + /** + * Test if the number contained in st is an integer + * + * @param st + * The Object to convert + * @return The integer corresponding to st + * @throws LogoError + * If it isn't an integer + */ + + protected BigDecimal getBigInteger(String st) throws LogoError + { // Si c'est un + // entier + try + { + return new BigDecimal(new BigInteger(st)); + } + catch (NumberFormatException e) + { + throw new LogoError(st + " " + Logo.messages.getString("pas_entier")); + } + } + + protected int getDigits() + { + if (digits < 0) + return -1; + else + return mc.getPrecision(); + } + + public static String getOutputNumber(String s) + { + try + { + if (digits >= 0 && digits < 16) + { + BigDecimal bd = new BigDecimal(s); + s = bd.toPlainString(); + // is it a decimal number? + int index = s.indexOf("."); + if (index != -1) + { + if (digits == 0) + return s.substring(0, index); + else if (s.length() > index + digits) + { + s = s.substring(0, index + digits + 1); + int a = Integer.parseInt(String.valueOf(s.charAt(s.length() - 1))); + if (a > 4) + { + a++; + s = s.substring(0, s.length() - 1) + a; + } + return s; + } + } + else + return s; + } + } + catch (NumberFormatException e) + {} + return s; + } +} diff --git a/logo/src/xlogo/kernel/MyFlow.java b/logo/src/xlogo/kernel/MyFlow.java new file mode 100644 index 0000000..2c7b5e3 --- /dev/null +++ b/logo/src/xlogo/kernel/MyFlow.java @@ -0,0 +1,110 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +public class MyFlow +{ + + private String path; + private int id; + private boolean finished; + + MyFlow(int id, String path, boolean finished) + { + this.id = id; + this.path = path; + this.finished = finished; + } + + MyFlow(MyFlow flow) + { + this.id = flow.getId(); + this.path = flow.getPath(); + this.finished = flow.isFinished(); + } + + /** + * @return + */ + String getPath() + { + return path; + } + + /** + * @param p + */ + void setPath(String p) + { + path = p; + } + + /** + * @return + */ + int getId() + { + return id; + } + + /** + * @param i + */ + void setId(int i) + { + id = i; + } + + /** + * @return + */ + boolean isFinished() + { + return finished; + } + + /** + * @param b + */ + void setFinished(boolean b) + { + finished = b; + } + + boolean isReader() + { + return false; + } + + boolean isWriter() + { + return false; + } + +} diff --git a/logo/src/xlogo/kernel/MyFlowReader.java b/logo/src/xlogo/kernel/MyFlowReader.java new file mode 100644 index 0000000..2b3409b --- /dev/null +++ b/logo/src/xlogo/kernel/MyFlowReader.java @@ -0,0 +1,81 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +public class MyFlowReader extends MyFlow +{ + BufferedReader bfr; + + boolean isReader() + { + return true; + } + + MyFlowReader(MyFlow flow) + { + super(flow); + } + + String readLine() throws FileNotFoundException, IOException + { + if (null == bfr) + bfr = new BufferedReader(new FileReader(getPath())); + String line = bfr.readLine(); + return line; + } + + int readChar() throws FileNotFoundException, IOException + { + if (null == bfr) + bfr = new BufferedReader(new FileReader(getPath())); + int character = bfr.read(); + return character; + } + + int isReadable() throws FileNotFoundException, IOException + { + if (null == bfr) + bfr = new BufferedReader(new FileReader(getPath())); + bfr.mark(2); + int id = bfr.read(); + bfr.reset(); + return id; + } + + void close() throws IOException + { + if (null != bfr) + bfr.close(); + } +} diff --git a/logo/src/xlogo/kernel/MyFlowWriter.java b/logo/src/xlogo/kernel/MyFlowWriter.java new file mode 100644 index 0000000..7651aee --- /dev/null +++ b/logo/src/xlogo/kernel/MyFlowWriter.java @@ -0,0 +1,74 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel; + +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +import xlogo.utils.Utils; + +public class MyFlowWriter extends MyFlow +{ + BufferedWriter bfw; + + MyFlowWriter(MyFlow flow) + { + super(flow); + } + + void append(String line) throws FileNotFoundException, IOException + { + if (null == bfw) + bfw = new BufferedWriter(new FileWriter(getPath(), true)); + PrintWriter pw = new PrintWriter(bfw); + pw.println(Utils.SortieTexte(line)); + } + + void write(String line) throws FileNotFoundException, IOException + { + if (null == bfw) + bfw = new BufferedWriter(new FileWriter(getPath())); + PrintWriter pw = new PrintWriter(bfw); + pw.println(Utils.SortieTexte(line)); + } + + boolean isWriter() + { + return true; + } + + void close() throws IOException + { + if (null != bfw) + bfw.close(); + } +} diff --git a/logo/src/xlogo/kernel/Primitive.java b/logo/src/xlogo/kernel/Primitive.java new file mode 100644 index 0000000..0d0d8d1 --- /dev/null +++ b/logo/src/xlogo/kernel/Primitive.java @@ -0,0 +1,573 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo Description : XLogo is an interpreter for the Logo programming + * language + * + * @author Loïc Le Coq + */ +package xlogo.kernel; + +import java.util.Vector; +import java.util.Collections; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.math.BigDecimal; + +import xlogo.kernel.LoopProperties; +import xlogo.messages.async.history.HistoryMessenger; +import xlogo.storage.WSManager; +import xlogo.storage.workspace.Language; +import xlogo.utils.Utils; +import xlogo.Application; + +import java.io.*; + +import xlogo.Logo; + +import java.util.Enumeration; + +public class Primitive +{ + /** + * This character indicates the end of a procedure in instructionBuffer + */ + protected static final String END_PROCEDURE = "\n"; + /** + * This character indicates the end of a loop in instructionBuffer + */ + protected static final String END_LOOP = "\\"; + + // float taille_crayon=(float)0; + private Application app; + protected static final int PRIMITIVE_NUMBER = 310; + protected static int[] parametres = new int[PRIMITIVE_NUMBER]; + protected static boolean[] generalForm = new boolean[PRIMITIVE_NUMBER]; + + // Treemap for primitives (better efficiency in searching) + public static TreeMap<String, String> primitives = new TreeMap<String, String>(); + + public static Stack<LoopProperties> stackLoop = new Stack<LoopProperties>(); + + public Primitive() + { + } + + public Primitive(Application app) + { + this.app = app; + // build treemap for primitives + buildPrimitiveTreemap(WSManager.getInstance().getWorkspaceConfigInstance().getLanguage()); + } + + /** + * This methods returns a list which contains all the primitive for the + * current language + * + * @return The primitives list + */ + protected String getAllPrimitives() + { + Vector<String> list = new Vector<String>(); + Locale locale = WSManager.getInstance().getWorkspaceConfigInstance().getLanguage().getLocale(); + ResourceBundle prim = ResourceBundle.getBundle("primitives", locale); + try + { + BufferedReader bfr = new BufferedReader(new InputStreamReader( + Primitive.class.getResourceAsStream("genericPrimitive"))); + while (bfr.ready()) + { + String line = bfr.readLine(); + // read the generic keyword for the primitive + StringTokenizer cut = new StringTokenizer(line); + // read the standard number of arguments for the primitive + String cle = cut.nextToken(); + // Exclude internal primitive \n \x and siwhile + if (!cle.equals("\\n") && !cle.equals("\\siwhile") && !cle.equals("\\x")) + { + // Exclude all arithmetic symbols + - / * & | + if (cle.length() != 1) + { + if (!cle.equals(">=") && !cle.equals("<=")) + { + cle = prim.getString(cle).trim(); + list.add(cle); + } + } + } + } + } + catch (IOException e) + { + System.out.println("Impossible de lire le fichier d'initialisation des primitives"); + } + Collections.sort(list); + StringBuffer sb = new StringBuffer("[ "); + for (int i = 0; i < list.size(); i++) + { + sb.append("[ "); + sb.append(list.get(i)); + sb.append("] "); + } + sb.append("] "); + return (sb.toString()); + } + + // Exécution des primitives + public static void buildPrimitiveTreemap(Language lang) + { + // this.exportPrimCSV(); + primitives = new TreeMap<String, String>(); + Locale locale = lang.getLocale(); + ResourceBundle prim = ResourceBundle.getBundle("primitives", locale); + try + { + BufferedReader bfr = new BufferedReader(new InputStreamReader( + Primitive.class.getResourceAsStream("genericPrimitive"))); + int i = 0; + while (bfr.ready()) + { + String line = bfr.readLine(); + // read the generic keyword for the primitive + StringTokenizer cut = new StringTokenizer(line); + // read the standard number of arguments for the primitive + String cle = cut.nextToken(); + parametres[i] = Integer.parseInt(cut.nextToken()); + // Read if the primitive has a general form + // eg (sum 2 3 4 5) --> 14 + // eg (list 3 4 5) ---> [3 4 5] + if (cut.hasMoreTokens()) + { + generalForm[i] = true; + } + else + generalForm[i] = false; + + if (i == 39) + primitives.put("\n", "39"); + // Internal Primitive siwhile + else if (i == 95) + { + primitives.put("\\siwhile", "95"); + } + // Internal Primitive \x + else if (i == 212) + primitives.put("\\x", "212"); + else + { + if (cle.length() != 1) + { + if (!cle.equals(">=") && !cle.equals("<=")) + cle = prim.getString(cle); + } + StringTokenizer st = new StringTokenizer(cle.toLowerCase()); + int compteur = 0; + while (st.hasMoreTokens()) + { + primitives.put(st.nextToken(), String.valueOf(i + Primitive.PRIMITIVE_NUMBER * compteur)); + compteur++; + } + } + i++; + } + /* + * System.out.println(i+ " primitives"); + * java.util.Iterator it=primitives.keySet().iterator(); + * while(it.hasNext()){ + * String next=it.next().toString(); + * System.out.println(next+" "+primitives.get(next)); + * } + */ + } + catch (IOException e) + { + System.out.println("Impossible de lire le fichier d'initialisation des primitives"); + } + } + + /** + * This method creates the loop "repeat" + * + * @param i + * The number of iteration + * @param st + * The instruction to execute + * @throws LogoError + */ + protected void repete(int i, String st) throws LogoError + { + if (i > 0) + { + st = new String(Utils.decoupe(st)); + LoopProperties bp = new LoopRepeat(BigDecimal.ONE, new BigDecimal(i), BigDecimal.ONE, st); + stackLoop.push(bp); + app.getKernel().getInstructionBuffer().insert(st + "\\ "); + } + else if (i != 0) { throw new LogoError(Utils.primitiveName("controls.repete") + " " + + Logo.messages.getString("attend_positif")); } + } + + /** + * This method is an internal primitive for the primitive "while" + * + * @param b + * Do we still execute the loop body? + * @param li + * The loop body instructions + * @throws LogoError + */ + protected void whilesi(boolean b, String li) throws LogoError + { + if (b) + { + app.getKernel().getInstructionBuffer().insert(li + Primitive.stackLoop.peek().getInstr()); + } + else + { + eraseLevelStop(app); + } + } + + // primitive if + protected void si(boolean b, String li, String li2) + { + if (b) + { + app.getKernel().getInstructionBuffer().insert(li); + } + else if (null != li2) + { + app.getKernel().getInstructionBuffer().insert(li2); + } + } + + // primitive stop + protected void stop() throws LogoError + { + Interprete.operande = false; + String car = ""; + car = eraseLevelStop(app); + + // A procedure has been stopped + if (car.equals("\n")) + { + String en_cours = Interprete.en_cours.pop(); + Interprete.locale = Interprete.stockvariable.pop(); + // Example: to bug + // fd stop + // end + // -------- + // bug + // stop doesn't output to fd + if (!Interprete.nom.isEmpty() && !Interprete.nom.peek().equals("\n")) + { + // System.out.println(Interprete.nom); + throw new LogoError(Utils.primitiveName("controls.stop") + " " + + Logo.messages.getString("ne_renvoie_pas") + " " + Interprete.nom.peek()); + } + else if (!Interprete.nom.isEmpty()) + { + // Removing the character "\n" + Interprete.nom.pop(); + // Example: to bug | to bug2 + // fd bug2 | stop + // end | end + // ------------------------ + // bug + // bug2 doesn't output to fd + if (!Interprete.nom.isEmpty() && !Interprete.nom.peek().equals("\n")) + { + // System.out.println(Interprete.nom); + throw new LogoError(en_cours + " " + Logo.messages.getString("ne_renvoie_pas") + " " + + Interprete.nom.peek()); + } + } + } + } + + // primitive output + protected void retourne(String val) throws LogoError + { + Interprete.calcul.push(val); + Interprete.operande = true; + if (Kernel.mode_trace) + { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < Interprete.en_cours.size() - 1; i++) + buffer.append(" "); + buffer.append(Interprete.en_cours.peek()); + buffer.append(" " + Utils.primitiveName("ret") + " " + val); + HistoryMessenger.getInstance().dispatchMessage(Utils.SortieTexte(buffer.toString()) + "\n"); + } + Interprete.en_cours.pop(); + Interprete.locale = Interprete.stockvariable.pop(); + if ((!Interprete.nom.isEmpty()) && Interprete.nom.peek().equals("\n")) + { + eraseLevelReturn(app); + Interprete.nom.pop(); + } + else if (!Interprete.nom.isEmpty()) + throw new LogoError(Utils.primitiveName("ret") + " " + Logo.messages.getString("ne_renvoie_pas") + " " + + Interprete.nom.peek()); + else + throw new LogoError(Logo.messages.getString("erreur_retourne")); + } + + /** + * This method deletes all instruction since it encounters the end of a loop + * or the end of a procedure + * + * @param app + * The runnning frame Application + * @return The specific character \n or \ if found + * @throws LogoError + */ + private String eraseLevelStop(Application app) throws LogoError + { + boolean error = true; + String caractere = ""; + int marqueur = 0; + InstructionBuffer instruction = app.getKernel().getInstructionBuffer(); + for (int i = 0; i < instruction.getLength(); i++) + { + caractere = String.valueOf(instruction.charAt(i)); + if (caractere.equals(Primitive.END_LOOP) | caractere.equals(Primitive.END_PROCEDURE)) + { + marqueur = i; + if (caractere.equals(Primitive.END_LOOP) && i != instruction.getLength() - 1) + { + /* + * On test si le caractère "\" est bien un caractère de + * fin + * de boucle et non du style "\e" ou "\#" + */ + if (instruction.charAt(i + 1) == ' ') + { + error = false; + break; + } + } + else + { + error = false; + break; + } + } + } + + if (error) { throw new LogoError(Logo.messages.getString("erreur_stop")); } + if (marqueur + 2 > instruction.getLength()) + instruction = new InstructionBuffer(" "); + else + instruction.delete(0, marqueur + 2); + if (!caractere.equals("\n")) + { + Primitive.stackLoop.pop(); + } + return (caractere); + } + + /** + * This method deletes all instruction since it encounters the end of a + * procedure + * + * @param app + * The running frame Application + * @return an integer that indicates the number of loop to delete from + * Primitive.stackLoop + * @throws LogoError + */ + private void eraseLevelReturn(Application app) throws LogoError + { + boolean error = true; + String caractere = ""; + int loopLevel = 0; + int marqueur = 0; + InstructionBuffer instruction = app.getKernel().getInstructionBuffer(); + for (int i = 0; i < instruction.getLength(); i++) + { + caractere = String.valueOf(instruction.charAt(i)); + if (caractere.equals(Primitive.END_PROCEDURE)) + { + marqueur = i; + error = false; + break; + } + else if (caractere.equals(Primitive.END_LOOP)) + { + /* + * On test si le caractère "\" est bien un caractère de fin + * de boucle et non du style "\e" ou "\#" + */ + if (instruction.charAt(i + 1) == ' ') + { + loopLevel++; + } + } + } + if (error) { throw new LogoError(Logo.messages.getString("erreur_retourne")); } + if (marqueur + 2 > instruction.getLength()) + instruction = new InstructionBuffer(" "); + else + instruction.delete(0, marqueur + 2); + for (int i = 0; i < loopLevel; i++) + { + Primitive.stackLoop.pop(); + } + } + + private void exportPrimCSV() + { + StringBuffer sb = new StringBuffer(); + Locale locale = new Locale("fr", "FR"); + ResourceBundle prim_fr = ResourceBundle.getBundle("primitives", locale); + locale = new Locale("en", "US"); + ResourceBundle prim_en = ResourceBundle.getBundle("primitives", locale); + locale = new Locale("ar", "MA"); + ResourceBundle prim_ar = ResourceBundle.getBundle("primitives", locale); + locale = new Locale("es", "ES"); + ResourceBundle prim_es = ResourceBundle.getBundle("primitives", locale); + locale = new Locale("pt", "BR"); + ResourceBundle prim_pt = ResourceBundle.getBundle("primitives", locale); + locale = new Locale("eo", "EO"); + ResourceBundle prim_eo = ResourceBundle.getBundle("primitives", locale); + locale = new Locale("de", "DE"); + ResourceBundle prim_de = ResourceBundle.getBundle("primitives", locale); + // locale=new Locale("nl","NL"); + ResourceBundle[] prim = { prim_fr, prim_en, prim_es, prim_pt, prim_ar, prim_eo, prim_de }; + try + { + BufferedReader bfr = new BufferedReader(new InputStreamReader( + Primitive.class.getResourceAsStream("genericPrimitive"))); + int i = 0; + while (bfr.ready()) + { + String line = bfr.readLine(); + StringTokenizer cut = new StringTokenizer(line); + String cle = cut.nextToken(); + parametres[i] = Integer.parseInt(cut.nextToken()); + if (i != 39 && i != 95 && i != 212 && cle.length() != 1) + { + sb.append("$"); + sb.append(cle); + sb.append("$"); + sb.append(";"); + for (int j = 0; j < prim.length; j++) + { + String txt = cle; + txt = prim[j].getString(cle); + sb.append("$"); + sb.append(txt); + sb.append("$"); + sb.append(";"); + } + sb.append("\n"); + } + i++; + } + Utils.writeLogoFile("/home/loic/primTable.csv", new String(sb)); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + private void exportMessageCSV() + { + StringBuffer sb = new StringBuffer(); + Locale locale = new Locale("fr", "FR"); + ResourceBundle lang_fr = ResourceBundle.getBundle("langage", locale); + locale = new Locale("en", "US"); + ResourceBundle lang_en = ResourceBundle.getBundle("langage", locale); + locale = new Locale("ar", "MA"); + ResourceBundle lang_ar = ResourceBundle.getBundle("langage", locale); + locale = new Locale("es", "ES"); + ResourceBundle lang_es = ResourceBundle.getBundle("langage", locale); + locale = new Locale("pt", "BR"); + ResourceBundle lang_pt = ResourceBundle.getBundle("langage", locale); + locale = new Locale("eo", "EO"); + ResourceBundle lang_eo = ResourceBundle.getBundle("langage", locale); + locale = new Locale("de", "DE"); + ResourceBundle lang_de = ResourceBundle.getBundle("langage", locale); + // locale=new Locale("nl","NL"); + ResourceBundle[] lang = { lang_fr, lang_en, lang_es, lang_pt, lang_ar, lang_eo, lang_de }; + try + { + Enumeration<String> en = lang_fr.getKeys(); + while (en.hasMoreElements()) + { + String cle = en.nextElement(); + sb.append("$"); + sb.append(cle); + sb.append("$"); + sb.append(";"); + for (int j = 0; j < lang.length; j++) + { + String txt = lang[j].getString(cle); + sb.append("$"); + sb.append(txt); + sb.append("$"); + if (j != lang.length - 1) + sb.append(";"); + } + + sb.append("\n"); + } + Utils.writeLogoFile("/home/loic/messageTable.csv", new String(sb)); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + public static int isPrimitive(String s) + { + String index = Primitive.primitives.get(s.toLowerCase()); + if (null == index) + return -1; + try + { + int id = Integer.parseInt(index); + return id % Primitive.PRIMITIVE_NUMBER; + } + catch (NumberFormatException e) + { + System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!\n" + + "The file xlogo/kernel/genericPrimitive has been corrupted...\n" + + " Please, check the integrity of xlogo.jar \n!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + return -1; + } + +} diff --git a/logo/src/xlogo/kernel/Turtle.java b/logo/src/xlogo/kernel/Turtle.java new file mode 100644 index 0000000..82f3a76 --- /dev/null +++ b/logo/src/xlogo/kernel/Turtle.java @@ -0,0 +1,434 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ + +package xlogo.kernel; + +import java.awt.Toolkit; +import java.awt.MediaTracker; +import java.awt.geom.GeneralPath; +import java.awt.Color; +import java.awt.Image; +import java.awt.BasicStroke; +import java.awt.Stroke; +import java.util.StringTokenizer; + +import xlogo.Logo; +import xlogo.storage.WSManager; +import xlogo.storage.user.PenShape; +import xlogo.storage.user.UserConfig; +import xlogo.utils.Utils; +import xlogo.Application; + +public class Turtle +{ + + private Application app; + + public Color couleurcrayon = Color.black; + public Stroke stroke = new BasicStroke(1); + + Color couleurmodedessin = Color.black; + + public int id = -1; + + BasicStroke crayon = null; + + int police = 12; + + private int labelHorizontalAlignment = 0; + protected static final int LABEL_HORIZONTAL_ALIGNMENT_LEFT = 0; + protected static final int LABEL_HORIZONTAL_ALIGNMENT_CENTER = 1; + protected static final int LABEL_HORIZONTAL_ALIGNMENT_RIGHT = 2; + + private int labelVerticalAlignment = 0; + protected static final int LABEL_VERTICAL_ALIGNMENT_BOTTOM = 0; + protected static final int LABEL_VERTICAL_ALIGNMENT_CENTER = 1; + protected static final int LABEL_VERTICAL_ALIGNMENT_TOP = 2; + + // Image for the turtle + // If null then draw the triangle + + Image tort = null; + + GeneralPath triangle; + /** + * The turtle heading (degree) + */ + public double heading; + /** + * The turtle roll (degree) + */ + public double roll; + /** + * The turtle pitch (degree) + */ + public double pitch; + + /** + * The X coordinates on the screen + */ + public double corX; + /** + * The Y coordinates on the screen + */ + public double corY; + + public double angle; + /** + * The X coordinates in real World (3D or 2D) + */ + public double X = 0; + /** + * The Y coordinates in real World (3D or 2D) + */ + public double Y = 0; + /** + * The Z coordinates in real World (3D or 2D) + */ + public double Z = 0; + /** + * Identity Matrix + */ + private final double[][] identity = new double[3][3]; + { + identity[0][0] = identity[1][1] = identity[2][2] = 1; + identity[0][1] = identity[0][2] = identity[1][2] = 0; + identity[1][0] = identity[2][1] = identity[2][0] = 0; + } + /** + * This is the rotation Matrix (3x3) in 3D world + */ + private double[][] rotationMatrix = identity; + + int largeur = 0; + + int hauteur = 0; + + int gabarit = 0; + + private boolean pendown = true; + + private boolean penReverse = false; + + private boolean visible = true; + + private int shape = WSManager.getUserConfig().getActiveTurtle(); + + private float penWidth = 0; // half + // of + // the + // pen + // width + + public Turtle(Application app) + { + UserConfig uc = WSManager.getUserConfig(); + + this.app = app; + fixe_taille_crayon(1); + String chemin = "tortue" + uc.getActiveTurtle() + ".png"; + couleurcrayon = uc.getPencolor(); + couleurmodedessin = uc.getPencolor(); + if (uc.getActiveTurtle() == 0) + { + tort = null; + largeur = 26; + hauteur = 26; + } + else + { + // ON teste tout d'abord si le chemin est valide + if (null == Utils.class.getResource(chemin)) + chemin = "tortue1.png"; + tort = Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(chemin)); + MediaTracker tracker = new MediaTracker(app.getFrame()); + tracker.addImage(tort, 0); + try + { + tracker.waitForID(0); + } + catch (InterruptedException e1) + {} + largeur = tort.getWidth(app.getFrame()); + hauteur = tort.getHeight(app.getFrame()); + double largeur_ecran = Toolkit.getDefaultToolkit().getScreenSize().getWidth(); + // On fait attention à la résolution de l'utilisateur + double facteur = largeur_ecran / 1024.0; + if ((int) (facteur + 0.001) != 1) + { + tort = tort.getScaledInstance((int) (facteur * largeur), (int) (facteur * hauteur), Image.SCALE_SMOOTH); + tracker = new MediaTracker(app.getFrame()); + tracker.addImage(tort, 0); + try + { + tracker.waitForID(0); + } + catch (InterruptedException e1) + {} + } + largeur = tort.getWidth(app.getFrame()); + hauteur = tort.getHeight(app.getFrame()); + } + gabarit = Math.max(hauteur, largeur); + corX = uc.getImageWidth() / 2; + corY = uc.getImageHeight() / 2; + angle = Math.PI / 2; + heading = 0.0; + pitch = 0; + roll = 0; + X = 0; + Y = 0; + Z = 0; + } + + protected void init() + { + UserConfig uc = WSManager.getUserConfig(); + + corX = uc.getImageWidth() / 2; + corY = uc.getImageHeight() / 2; + X = 0; + Y = 0; + Z = 0; + heading = 0; + pitch = 0; + roll = 0; + rotationMatrix = identity; + angle = Math.PI / 2; + pendown = true; + stroke = new BasicStroke(1); + fixe_taille_crayon(1); + couleurcrayon = uc.getPencolor(); + couleurmodedessin = uc.getPencolor(); + penReverse = false; + } + + void drawTriangle() + { + if (null == tort) + { + if (null == triangle) + { + triangle = new GeneralPath(); + } + else + triangle.reset(); + if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D) + { + triangle.moveTo((float) (corX - 10.0 * Math.sin(angle)), (float) (corY - 10.0 * Math.cos(angle))); + triangle.lineTo((float) (corX + 24.0 * Math.cos(angle)), (float) (corY - 24.0 * Math.sin(angle))); + triangle.lineTo((float) (corX + 10.0 * Math.sin(angle)), (float) (corY + 10.0 * Math.cos(angle))); + triangle.lineTo((float) (corX - 10.0 * Math.sin(angle)), (float) (corY - 10.0 * Math.cos(angle))); + } + else + { + double[] screenCoord = new double[2]; + // The triangle has coordinates: (-10,0,0);(0,24,0);(10,0,0) + double[] x1 = new double[3]; + x1[0] = X - 20 * rotationMatrix[0][0]; + x1[1] = Y - 20 * rotationMatrix[1][0]; + x1[2] = Z - 20 * rotationMatrix[2][0]; + screenCoord = app.getDrawPanel().toScreenCoord(x1, false); + triangle.moveTo((float) screenCoord[0], (float) screenCoord[1]); + x1[0] = X + 48 * rotationMatrix[0][1]; + x1[1] = Y + 48 * rotationMatrix[1][1]; + x1[2] = Z + 48 * rotationMatrix[2][1]; + screenCoord = app.getDrawPanel().toScreenCoord(x1, false); + triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]); + x1[0] = X + 20 * rotationMatrix[0][0]; + x1[1] = Y + 20 * rotationMatrix[1][0]; + x1[2] = Z + 20 * rotationMatrix[2][0]; + screenCoord = app.getDrawPanel().toScreenCoord(x1, false); + triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]); + triangle.closePath(); + + // the "aileron" has coordinates: (0,10,0);(0,0,10);(0,0,0) + x1[0] = X + 15 * rotationMatrix[0][1]; + x1[1] = Y + 15 * rotationMatrix[1][1]; + x1[2] = Z + 15 * rotationMatrix[2][1]; + screenCoord = app.getDrawPanel().toScreenCoord(x1, false); + triangle.moveTo((float) screenCoord[0], (float) screenCoord[1]); + x1[0] = X + 15 * rotationMatrix[0][2]; + x1[1] = Y + 15 * rotationMatrix[1][2]; + x1[2] = Z + 15 * rotationMatrix[2][2]; + screenCoord = app.getDrawPanel().toScreenCoord(x1, false); + triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]); + x1[0] = X; + x1[1] = Y; + x1[2] = Z; + screenCoord = app.getDrawPanel().toScreenCoord(x1, false); + triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]); + } + } + } + + public void fixe_taille_crayon(float nb) + { + UserConfig uc = WSManager.getUserConfig(); + + if (nb < 0) + nb = 1; + else if (uc.getMaxPenWidth() != -1 && nb > uc.getMaxPenWidth()) + nb = 1; + if (uc.getPenShape() == PenShape.SQUARE) + crayon = new BasicStroke(nb, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER); + else + crayon = new BasicStroke(nb, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); + penWidth = nb / 2; + } + + public float getPenWidth() + { + return penWidth; + } + + protected int getShape() + { + return shape; + } + + public void setShape(int id) + { + shape = id; + } + + protected boolean isVisible() + { + return visible; + } + + protected void setVisible(boolean b) + { + visible = b; + } + + protected boolean isPenDown() + { + return pendown; + } + + protected void setPenDown(boolean b) + { + pendown = b; + } + + protected boolean isPenReverse() + { + return penReverse; + } + + protected void setPenReverse(boolean b) + { + penReverse = b; + } + + protected void setRotationMatrix(double[][] m) + { + rotationMatrix = m; + } + + protected double[][] getRotationMatrix() + { + return rotationMatrix; + } + + protected double getX() + { + if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_3D) + return X; + return corX - WSManager.getUserConfig().getImageWidth() / 2; + + } + + protected double getY() + { + if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_3D) + return Y; + return WSManager.getUserConfig().getImageHeight() / 2 - corY; + + } + + protected int getLabelHorizontalAlignment() + { + return labelHorizontalAlignment; + } + + protected int getLabelVerticalAlignment() + { + return labelVerticalAlignment; + } + + protected void setFontJustify(String list) throws LogoError + { + StringTokenizer st = new StringTokenizer(list); + int i = 0; + while (st.hasMoreTokens()) + { + String s = st.nextToken(); + try + { + int j = Integer.parseInt(s); + if (j < 0 || j > 2) + throw new LogoError(list + " " + Logo.messages.getString("pas_argument")); + else + { + if (i == 0) + labelHorizontalAlignment = j; + else if (i == 1) + labelVerticalAlignment = j; + } + } + catch (NumberFormatException e) + { + throw new LogoError(list + " " + Logo.messages.getString("pas_argument")); + } + + i++; + } + if (i != 2) + throw new LogoError(list + " " + Logo.messages.getString("pas_argument")); + } + + public String getFontJustify() + { + StringBuffer sb = new StringBuffer("[ "); + sb.append(labelHorizontalAlignment); + sb.append(" "); + sb.append(labelVerticalAlignment); + sb.append(" ] "); + return new String(sb); + } +} diff --git a/logo/src/xlogo/kernel/genericPrimitive b/logo/src/xlogo/kernel/genericPrimitive new file mode 100644 index 0000000..bec63b7 --- /dev/null +++ b/logo/src/xlogo/kernel/genericPrimitive @@ -0,0 +1,308 @@ +drawing.av 1 +drawing.re 1 +drawing.td 1 +drawing.tg 1 +arithmetic.puissance 2 +controls.repete 2 +ve 0 +ct 0 +mt 0 +ec 1 + +si 2 +controls.stop 0 +drawing.origine 0 +drawing.fpos 1 +drawing.fixex 1 +drawing.fixey 1 +drawing.fixexy 2 +drawing.fixecap 1 +lc 0 +bc 0 +go 0 +ic 0 +de 0 +arithmetic.somme 2 + +arithmetic.difference 2 +arithmetic.moins 1 +arithmetic.produit 2 + +arithmetic.div 2 +arithmetic.reste 2 +ret 1 +* 1 +/ 1 ++ 1 +- 1 += 1 +< 1 +> 1 +| 1 +& 1 +\n 0 +\ 0 +pos 0 +cap 0 +arithmetic.arrondi 1 +arithmetic.log10 1 +arithmetic.sin 1 +arithmetic.cos 1 +ou 2 + +et 2 + +non 1 +liste 2 + +ph 2 + +mp 2 +md 2 +inverse 1 +choix 1 +enleve 2 +item 2 +sd 1 +sp 1 +dernier 1 +premier 1 +compte 1 +mot? 1 +nombre? 1 +liste? 1 +vide? 1 +egal? 2 +precede? 2 +membre? 2 +arithmetic.racine 1 +membre 2 +workspace.donne 2 +workspace.locale 1 +workspace.donnelocale 2 +fcc 1 +fcfg 1 +arithmetic.hasard 1 +attends 1 +workspace.imts 0 +workspace.efn 1 +workspace.efv 1 +workspace.efns 0 +mot 2 + +drawing.etiquette 1 +tc 1 +fen 0 +enr 0 +clos 0 +vt 0 +ci 1 +ftc 1 +controls.tantque 2 +lis 2 +touche? 0 +\siwhile 2 +liscar 0 +remplis 0 +drawing.point 1 +vers 1 +distance 1 +cc 0 +cf 0 +bc? 0 +visible? 0 +prim? 1 +proc? 1 +workspace.exec 1 +cat 0 +frep 1 +rep 0 +sauve 2 +sauved 1 +ramene 1 +arithmetic.pi 0 +arithmetic.tan 1 +arithmetic.acos 1 +arithmetic.asin 1 +arithmetic.atan 1 +vrai 0 +faux 0 +turtle.forme 0 +turtle.fforme 1 +workspace.def 2 +tortue 0 +tortues 0 +ftortue 1 +police 0 +fpolice 1 +tuetortue 1 +seq 1 +instr 0 +finstr 1 +joue 0 +efseq 0 +indseq 0 +findseq 1 +fpt 1 +ptexte 0 +fct 1 +couleurtexte 0 +lissouris 0 +possouris 0 +message 1 +date 0 +heure 0 +temps 0 +debuttemps 1 +fintemps? 0 +fixenompolice 1 +nompolice 0 +fixenompolicetexte 1 +nompolicetexte 0 +listeflux 0 +lisligneflux 1 +liscarflux 1 +ecrisligneflux 2 +finflux? 1 +ouvreflux 2 +fermeflux 1 +ajouteligneflux 2 +souris? 0 +workspace.listevariables 0 +workspace.chose 1 +nettoie 0 +tape 1 +drawing.cercle 1 +drawing.arc 3 +rempliszone 0 +animation 0 +rafraichis 0 +tailleimage 0 +arithmetic.quotient 2 +entier? 1 +fixeseparation 1 +separation 0 +arithmetic.tronque 1 +workspace.trace 0 +changedossier 1 +unicode 1 +caractere 1 +controls.stoptout 0 +controls.compteur 0 +controls.repetepour 2 +arithmetic.absolue 1 +remplace 3 +ajoute 3 +color.gris 0 +color.grisclair 0 +color.rougefonce 0 +color.vertfonce 0 +color.bleufonce 0 +color.orange 0 +color.rose 0 +color.violet 0 +color.marron 0 +color.noir 0 +color.rouge 0 +color.vert 0 +color.jaune 0 +color.bleu 0 +color.magenta 0 +color.cyan 0 +color.blanc 0 +) 0 +fixestyle 1 +style 0 +taillefenetre 0 +drawing.longueuretiquette 1 +envoietcp 2 +ecoutetcp 0 +executetcp 2 +\x 0 +chattcp 2 +resetall 0 +penwidth 0 +setpenshape 1 +penshape 0 +setdrawingquality 1 +drawingquality 0 +setturtlesnumber 1 +turtlesnumber 0 +setscreensize 1 +guibutton 2 +guiaction 2 +guiremove 1 +guiposition 2 +guidraw 1 +setzoom 1 +grille 2 +stopgrille 0 +stopanimation 0 +workspace.stoptrace 0 +guimenu 2 +axis 1 +xaxis 1 +yaxis 1 +stopaxis 0 +bye 0 +var? 1 +axiscolor 0 +gridcolor 0 +grid? 0 +xaxis? 0 +yaxis? 0 +setgridcolor 1 +setaxiscolor 1 +3d.perspective 0 +3d.rightroll 1 +3d.uppitch 1 +3d.leftroll 1 +3d.downpitch 1 +3d.roll 0 +3d.pitch 0 +3d.setroll 1 +3d.setpitch 1 +3d.setorientation 1 +3d.orientation 0 +3d.setxyz 3 +3d.setz 1 +workspace.pprop 3 +workspace.gprop 2 +workspace.remprop 2 +workspace.plist 1 +3d.polystart 0 +3d.polyend 0 +3d.polyview 0 +3d.linestart 0 +3d.lineend 0 +3d.pointstart 0 +3d.pointend 0 +3d.textstart 0 +3d.textend 0 +<= 1 +>= 1 +workspace.primitives 0 +workspace.propertylists 0 +workspace.content 0 +workspace.erpl 1 +arithmetic.exp 1 +arithmetic.log 1 +controls.ifelse 3 +workspace.ed 1 +workspace.edall 0 +controls.foreach 3 +controls.forever 1 +arithmetic.setdigits 1 +arithmetic.digits 0 +workspace.text 1 +workspace.externalcommand 1 +drawing.saveimage 2 +sound.mp3play 1 +sound.mp3stop 0 +zoom 0 +drawing.x 0 +drawing.y 0 +drawing.z 0 +drawing.fillpolygon 1 +arithmetic.alea 0 +loop.dountil 2 +loop.dowhile 2 +aritmetic.modulo 2 +drawing.setfontjustify 1 +drawing.fontjustify 0 +arithmetic.inf 2 +arithmetic.sup 2 +arithmetic.infequal 2 +arithmetic.supequal 2
\ No newline at end of file diff --git a/logo/src/xlogo/kernel/grammar/LogoException.java b/logo/src/xlogo/kernel/grammar/LogoException.java new file mode 100644 index 0000000..225a677 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoException.java @@ -0,0 +1,69 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +/** + * @author loic + * + */ +public class LogoException extends LogoType +{ + + private String message; + + public LogoException(String message) + { + this.message = message; + } + + public boolean isException() + { + return true; + } + + public String toString() + { + return message; + } + + @Override + public String toDebug() + { + return "(EXCEPTION) " + message; + } + +} diff --git a/logo/src/xlogo/kernel/grammar/LogoList.java b/logo/src/xlogo/kernel/grammar/LogoList.java new file mode 100644 index 0000000..1cd6ea5 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoList.java @@ -0,0 +1,93 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +import java.util.Vector; + +public class LogoList extends LogoType +{ + private Vector<LogoType> vector; + + LogoList(Vector<LogoType> vector) + { + this.vector = vector; + } + + LogoList() + { + vector = new Vector<LogoType>(); + } + + public boolean isList() + { + return true; + } + + public void add(LogoType type) + { + vector.add(type); + } + + public Vector<LogoType> getVector() + { + return vector; + } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + sb.append("[ "); + for (int i = 0; i < vector.size(); i++) + { + sb.append(vector.get(i).toString()); + sb.append(" "); + } + sb.append("]"); + return sb.toString(); + } + + @Override + public String toDebug() + { + StringBuffer sb = new StringBuffer(); + sb.append("(LIST) "); + sb.append(toString()); + return sb.toString(); + + } + +} diff --git a/logo/src/xlogo/kernel/grammar/LogoNumber.java b/logo/src/xlogo/kernel/grammar/LogoNumber.java new file mode 100644 index 0000000..fd367bb --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoNumber.java @@ -0,0 +1,76 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +/** + * @author loic + * + */ +public class LogoNumber extends LogoType +{ + private double value; + + LogoNumber(double value) + { + this.value = value; + } + public double getValue() + { + return value; + } + + public boolean isWord() + { + return true; + } + + public boolean isNumber() + { + return true; + } + + public String toString() + { + return String.valueOf(value); + } + + @Override + public String toDebug() + { + return "(NUMBER) " + String.valueOf(value); + } +} diff --git a/logo/src/xlogo/kernel/grammar/LogoParser.java b/logo/src/xlogo/kernel/grammar/LogoParser.java new file mode 100644 index 0000000..ccf3436 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoParser.java @@ -0,0 +1,289 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ + +package xlogo.kernel.grammar; + +import xlogo.Logo; +import xlogo.kernel.DrawPanel; +import xlogo.kernel.Primitive; +import xlogo.storage.global.GlobalConfig; + +public class LogoParser +{ + private char c; + private int cursor; + private String text; + + /** + * + * @param sr + * The String input reader + */ + public LogoParser(String text) + { + this.text = text; + cursor = 0; + while (cursor < text.length()) + { + LogoType lt = getToken(); + if (GlobalConfig.DEBUG) + System.out.println("[DEBUG] Token " + lt.toDebug() + " cursor " + cursor); + } + } + + private LogoType getToken() + { + boolean isQuotedWord = false; + boolean isVariable = false; + + StringBuffer sb = new StringBuffer(); + boolean start = false; + boolean backslash = false; + do + { + c = text.charAt(cursor); + // Skip White Spaces + if (c == ' ' || c == '\t') + { + if (start) + break; + else + cursor++; + } + else + { + if (backslash) + { + if (c == ' ') + sb.append(" "); + else if (c == '#') + sb.append("#"); + else if (c == '\\') + sb.append("\\"); + else if (c == '(') + sb.append("("); + else if (c == ')') + sb.append(")"); + else if (c == '[') + sb.append("["); + else if (c == ']') + sb.append("]"); + else if (c == 'n') + sb.append("\n"); + else + sb.append(c); + cursor++; + } + else + { + // If it's the first character, check for type + if (!start) + { + if (c == ':') + isVariable = true; + else if (c == '\"') + isQuotedWord = true; + } + if (c == '\\') + backslash = true; + + else if (c == '[') + { + if (start) + break; + else + { + cursor++; + return extractList(); + } + } + else if (c == '(') + { + if (start) + break; + } + else if (c == '*' || c == '/' || c == '+' || c == '-' || c == '|' || c == '&' || c == '=') + { + if (!isQuotedWord) + { + if (!start) + { + sb.append(c); + cursor++; + } + break; + + } + else + cursor++; + } + else if (c == ')') + return new LogoException(Logo.messages.getString("parenthese_ouvrante")); + else if (c == ']') + return new LogoException(Logo.messages.getString("error.whattodo") + " ]"); + else + { + sb.append(c); + cursor++; + } + } + start = true; + } + } while (cursor < text.length()); + if (sb.length() == 0) + return DrawPanel.nullType; + else if (isQuotedWord) + return new LogoWord(sb.substring(1)); + else if (isVariable) + return new LogoVariable(sb.substring(1)); + try + { + double d = Double.parseDouble(sb.toString()); + return new LogoNumber(d); + } + catch (NumberFormatException e) + { + int id = Primitive.isPrimitive(sb.toString()); + if (id != -1) { return new LogoPrimitive(id, sb.toString()); } + return new LogoException(Logo.messages.getString("je_ne_sais_pas") + " " + sb.toString()); + } + + } + + /** + * This method extracts a list. + * + * @return a LogoList if operation succeed, + * a LogoException otherwise + */ + + private LogoType extractList() + { + LogoList list = new LogoList(); + while (cursor < text.length()) + { + LogoType lt = getListToken(); + if (lt.isNull()) + { + return new LogoException(Logo.messages.getString("erreur_crochet")); + } + else if (lt.isRightDelimiter()) + return list; + else + { + list.add(lt); + } + } + return new LogoException(Logo.messages.getString("erreur_crochet")); + } + + private LogoType getListToken() + { + StringBuffer sb = new StringBuffer(); + boolean start = false; + boolean backslash = false; + for (int i = cursor; i < text.length(); i++) + { + cursor = i; + c = text.charAt(i); + // Skip White Spaces + if (c == ' ' || c == '\t') + { + if (start) + break; + } + else + { + if (backslash) + { + if (c == ' ') + sb.append(" "); + else if (c == '#') + sb.append("#"); + else if (c == '\\') + sb.append("\\"); + else if (c == '(') + sb.append("("); + else if (c == ')') + sb.append(")"); + else if (c == '[') + sb.append("["); + else if (c == ']') + sb.append("]"); + else if (c == 'n') + sb.append("\n"); + else + sb.append(c); + } + else + { + if (c == '\\') + { + backslash = true; + } + else if (c == '[') + { + if (start) + break; + else + { + cursor++; + return extractList(); + } + } + else if (c == ']') + { + if (start) + break; + else + { + System.out.println("coucou"); + cursor++; + return new LogoRightDelimiter(); + } + } + else + sb.append(c); + } + start = true; + } + } + if (sb.length() == 0) + return DrawPanel.nullType; + return new LogoWord(sb.toString()); + } + +} diff --git a/logo/src/xlogo/kernel/grammar/LogoPrimitive.java b/logo/src/xlogo/kernel/grammar/LogoPrimitive.java new file mode 100644 index 0000000..52044a3 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoPrimitive.java @@ -0,0 +1,74 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +public class LogoPrimitive extends LogoType +{ + private int id; + private String name; + + LogoPrimitive(int id, String name) + { + this.id = id; + this.name = name; + } + + public boolean isPrimitive() + { + return true; + } + + /** + * @return + * @uml.property name="id" + */ + public int getId() + { + return id; + } + + public String toString() + { + return name; + } + + @Override + public String toDebug() + { + return "(PRIMITIVE id=" + id + ") " + name; + } +} diff --git a/logo/src/xlogo/kernel/grammar/LogoRightDelimiter.java b/logo/src/xlogo/kernel/grammar/LogoRightDelimiter.java new file mode 100644 index 0000000..fb46026 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoRightDelimiter.java @@ -0,0 +1,56 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +/** + * @author loic + * + */ +public class LogoRightDelimiter extends LogoType +{ + public boolean isRightDelimiter() + { + return true; + } + + @Override + public String toDebug() + { + return null; + } + +} diff --git a/logo/src/xlogo/kernel/grammar/LogoTree.java b/logo/src/xlogo/kernel/grammar/LogoTree.java new file mode 100644 index 0000000..4e6b66e --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoTree.java @@ -0,0 +1,96 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.grammar; + +import java.util.Vector; + +public class LogoTree +{ + private Vector<LogoTree> children; + private LogoTree parent; + private LogoType value; + private boolean isRoot = false; + private boolean isProcedure = false; + private boolean isPrimitive = false; + private boolean isLeaf = false; + + LogoTree() + { + children = new Vector<LogoTree>(); + } + + protected void setParent(LogoTree lt) + { + this.parent = lt; + } + + protected LogoTree getParent() + { + return parent; + } + + protected boolean isRoot() + { + return isRoot; + } + + protected void addChild(LogoTree child) + { + children.add(child); + } + + protected void setValue(LogoType value) + { + this.value = value; + } + + protected LogoType getValue() + { + return value; + } + + protected boolean isLeaf() + { + return isLeaf; + } + + LogoType evaluate() + { + Vector<LogoType> args = new Vector<LogoType>(); + for (int i = 0; i < children.size(); i++) + { + LogoTree child = children.get(i); + if (child.isLeaf()) + args.add(child.getValue()); + else + args.add(child.evaluate()); + } + return null; + } +} diff --git a/logo/src/xlogo/kernel/grammar/LogoType.java b/logo/src/xlogo/kernel/grammar/LogoType.java new file mode 100644 index 0000000..d407431 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoType.java @@ -0,0 +1,129 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ + +package xlogo.kernel.grammar; + +public abstract class LogoType +{ + + /** + * If this token is a word ? + * + * @return true for a word, false otherwise + */ + public boolean isWord() + { + return false; + } + + /** + * If this token is a list? + * + * @return true for a list, false otherwise + */ + public boolean isList() + { + return false; + } + + /** + * If this token is a number? + * + * @return true for a number, false otherwise + */ + public boolean isNumber() + { + return false; + } + + /** + * If this token is a variable? + * + * @return true for a variable, false otherwise + */ + public boolean isVariable() + { + return false; + } + + /** + * If this token is a primitive? + * + * @return true for a primitive, false otherwise + */ + public boolean isPrimitive() + { + return false; + } + + /** + * If this token is a procedure? + * + * @return true for a procedure, false otherwise + */ + public boolean isProcedure() + { + return false; + } + + /** + * If this token is an exception? + * + * @return true for an exception, false otherwise + */ + public boolean isException() + { + return false; + } + + public boolean isNull() + { + return false; + } + + public boolean isRightDelimiter() + { + return false; + } + + /** + * Util for debugging + * + * @return the type and value for LogoType + */ + abstract public String toDebug(); +} diff --git a/logo/src/xlogo/kernel/grammar/LogoTypeNull.java b/logo/src/xlogo/kernel/grammar/LogoTypeNull.java new file mode 100644 index 0000000..b764063 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoTypeNull.java @@ -0,0 +1,56 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +/** + * @author loic + * + */ +public class LogoTypeNull extends LogoType +{ + public boolean isNull() + { + return true; + } + + @Override + public String toDebug() + { + return "(LogoTypeNull)"; + } + +} diff --git a/logo/src/xlogo/kernel/grammar/LogoVariable.java b/logo/src/xlogo/kernel/grammar/LogoVariable.java new file mode 100644 index 0000000..d2a7e91 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoVariable.java @@ -0,0 +1,68 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.grammar; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +public class LogoVariable extends LogoType +{ + String name; + + LogoVariable(String name) + { + this.name = name; + } + + public boolean isVariable() + { + return true; + } + + public String getName() + { + return name; + } + + public String toString() + { + return ":" + name; + } + + @Override + public String toDebug() + { + return "(VARIABLE) :" + name; + } +} diff --git a/logo/src/xlogo/kernel/grammar/LogoWord.java b/logo/src/xlogo/kernel/grammar/LogoWord.java new file mode 100644 index 0000000..e155180 --- /dev/null +++ b/logo/src/xlogo/kernel/grammar/LogoWord.java @@ -0,0 +1,68 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * Licence : GPL + * + * @author Loïc Le Coq + */ +package xlogo.kernel.grammar; + +public class LogoWord extends LogoType +{ + private String value; + + LogoWord(String value) + { + this.value = value; + } + + public String getQuotedValue() + { + return "\"" + value; + } + + public String toString() + { + return value; + } + + public boolean isWord() + { + return true; + } + + @Override + public String toDebug() + { + return "(WORD) " + value; + } +} diff --git a/logo/src/xlogo/kernel/gui/GuiButton.java b/logo/src/xlogo/kernel/gui/GuiButton.java new file mode 100644 index 0000000..1d440a5 --- /dev/null +++ b/logo/src/xlogo/kernel/gui/GuiButton.java @@ -0,0 +1,92 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.gui; + +import javax.swing.JButton; + +import xlogo.kernel.Interprete; + +import java.awt.Font; +import java.awt.event.*; + +import xlogo.Application; +import xlogo.storage.WSManager; +import xlogo.utils.Utils; + +public class GuiButton extends GuiComponent +{ + + private StringBuffer action; + + private Application app; + + public GuiButton(String id, String text, Application app) + { + Font font = WSManager.getWorkspaceConfig().getFont(); + super.setId(id); + guiObject = new JButton(Utils.SortieTexte(text)); + this.app = app; + java.awt.FontMetrics fm = app.getFrame().getGraphics().getFontMetrics(font); + originalWidth = fm.stringWidth(((JButton) (getGuiObject())).getText()) + 50; + originalHeight = font.getSize() + 10; + setSize(originalWidth, originalHeight); + } + + public void actionPerformed(ActionEvent e) + { + if (!app.commande_isEditable()) + { + Interprete.actionInstruction.append(action); + } + else + { + app.startInterpretation(action); + } + } + + public boolean isButton() + { + return true; + } + + public boolean isMenu() + { + return false; + } + + /** + * @param action + * @uml.property name="action" + */ + public void setAction(StringBuffer action) + { + this.action = action; + } + +} diff --git a/logo/src/xlogo/kernel/gui/GuiComponent.java b/logo/src/xlogo/kernel/gui/GuiComponent.java new file mode 100644 index 0000000..c144432 --- /dev/null +++ b/logo/src/xlogo/kernel/gui/GuiComponent.java @@ -0,0 +1,95 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.gui; + +import java.awt.event.ActionEvent; +import java.awt.Point; +import java.awt.event.ActionListener; +import javax.swing.JComponent; + +public abstract class GuiComponent implements ActionListener +{ + public boolean hasAction = false; + protected int originalWidth; + protected int originalHeight; + private String id; + protected JComponent guiObject; + protected boolean actionFinished; + + public String getId() + { + return id; + } + + protected void setId(String id) + { + this.id = id; + } + + public boolean hasAction() + { + return hasAction; + } + + public JComponent getGuiObject() + { + return guiObject; + } + + public void setLocation(int x, int y) + { + guiObject.setLocation(x, y); + } + + public Point getLocation() + { + return guiObject.getLocation(); + } + + public void setSize(int width, int height) + { + guiObject.setSize(width, height); + } + + public int getOriginalWidth() + { + return originalWidth; + } + + public int getOriginalHeight() + { + return originalHeight; + } + + public abstract void actionPerformed(ActionEvent e); + + public abstract boolean isButton(); + + public abstract boolean isMenu(); +} diff --git a/logo/src/xlogo/kernel/gui/GuiMap.java b/logo/src/xlogo/kernel/gui/GuiMap.java new file mode 100644 index 0000000..d2c071e --- /dev/null +++ b/logo/src/xlogo/kernel/gui/GuiMap.java @@ -0,0 +1,72 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.gui; + +import xlogo.kernel.LogoError; + +import java.util.HashMap; + +import xlogo.Logo; + +public class GuiMap extends HashMap<String, GuiComponent> +{ + private static final long serialVersionUID = 1L; + + public GuiMap() + { + } + + public void put(GuiComponent gc) throws LogoError + { + if (this.containsKey(gc.getId())) + { + throw new LogoError(Logo.messages.getString("gui_exists") + " " + gc.getId()); + } + else + this.put(gc.getId(), gc); + } + + public GuiComponent get(Object key) + { + String k = key.toString().toLowerCase(); + return super.get(k); + } + + /* + * public void remove(GuiComponent gc) throws myException{ + * if (this.containsKey(gc.getId())){ + * this.remove(gc.getId()); + * } + * else{ + * throw new + * myException(app,Logo.messages.getString("no_gui")+" "+gc.getId()); + * } + * } + */ +} diff --git a/logo/src/xlogo/kernel/gui/GuiMenu.java b/logo/src/xlogo/kernel/gui/GuiMenu.java new file mode 100644 index 0000000..2a424f3 --- /dev/null +++ b/logo/src/xlogo/kernel/gui/GuiMenu.java @@ -0,0 +1,101 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.gui; + +import javax.swing.JComboBox; + +import xlogo.storage.WSManager; +import xlogo.utils.Utils; + +import java.util.StringTokenizer; + +import xlogo.kernel.Interprete; + +import java.awt.event.*; + +import xlogo.Application; + +public class GuiMenu extends GuiComponent +{ + private Application app; + private String[] item; + private StringBuffer[] action; + + public GuiMenu(String id, String text, Application app) + { + this.app = app; + setId(id); + StringTokenizer st = new StringTokenizer(text); + item = new String[st.countTokens()]; + action = new StringBuffer[st.countTokens()]; + int i = 0; + originalWidth = 0; + while (st.hasMoreTokens()) + { + item[i] = Utils.SortieTexte(st.nextToken()); + java.awt.FontMetrics fm = app.getFrame().getGraphics() + .getFontMetrics(WSManager.getWorkspaceConfig().getFont()); + originalWidth = Math.max(originalWidth, fm.stringWidth(item[i])); + i++; + } + originalWidth += 50; + guiObject = new JComboBox(item); + originalHeight = WSManager.getWorkspaceConfig().getFont().getSize() + 10; + setSize(originalWidth, originalHeight); + } + + public void actionPerformed(ActionEvent e) + { + // System.out.println("coucou"); + int select = ((JComboBox) guiObject).getSelectedIndex(); + if (!app.commande_isEditable()) + { + Interprete.actionInstruction.append(action[select]); + } + else + { + app.startInterpretation(action[select]); + } + } + + public boolean isButton() + { + return false; + } + + public boolean isMenu() + { + return true; + } + + public void setAction(StringBuffer action, int id) + { + this.action[id] = action; + } +} diff --git a/logo/src/xlogo/kernel/network/ChatFrame.java b/logo/src/xlogo/kernel/network/ChatFrame.java new file mode 100644 index 0000000..227f4ca --- /dev/null +++ b/logo/src/xlogo/kernel/network/ChatFrame.java @@ -0,0 +1,160 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.network; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Toolkit; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.JTextField; + +import java.awt.event.*; +import java.awt.Dimension; +import java.io.PrintWriter; + +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultStyledDocument; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; + +import java.awt.BorderLayout; + +import xlogo.Application; +import xlogo.storage.WSManager; +import xlogo.utils.Utils; +import xlogo.Logo; + +public class ChatFrame extends JFrame implements ActionListener +{ + private static final long serialVersionUID = 1L; + + private MutableAttributeSet local; + + private MutableAttributeSet distant; + + private JTextPane textPane; + + private DefaultStyledDocument dsd; + + private JScrollPane scroll; + + private JTextField textField; + + private Application app; + + private PrintWriter out; + + protected ChatFrame(PrintWriter out, Application app) + { + this.app = app; + this.out = out; + initStyle(); + initGui(); + textField.addActionListener(this); + } + + private void initStyle() + { + Font font = WSManager.getWorkspaceConfig().getFont(); + local = new SimpleAttributeSet(); + StyleConstants.setFontFamily(local, font.getFamily()); + StyleConstants.setForeground(local, Color.black); + StyleConstants.setFontSize(local, font.getSize()); + + distant = new SimpleAttributeSet(); + StyleConstants.setFontFamily(distant, font.getFamily()); + StyleConstants.setForeground(distant, Color.RED); + StyleConstants.setFontSize(distant, font.getSize()); + } + + private void initGui() + { + setTitle(Logo.messages.getString("chat")); + setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("icone.png"))); + dsd = new DefaultStyledDocument(); + textPane = new JTextPane(); + textPane.setDocument(dsd); + textPane.setEditable(false); + textPane.setBackground(new Color(255, 255, 220)); + this.getContentPane().setLayout(new BorderLayout()); + textField = new JTextField(); + java.awt.FontMetrics fm = app.getFrame().getGraphics().getFontMetrics(WSManager.getWorkspaceConfig().getFont()); + int width = fm.stringWidth(Logo.messages.getString("stop_chat")) + 30; + if (width < 200) + width = 200; + + textPane.setPreferredSize(new Dimension(width, 300)); + textField.setPreferredSize(new Dimension(width, WSManager.getWorkspaceConfig().getFont().getSize() + 10)); + scroll = new JScrollPane(textPane); + getContentPane().add(scroll, BorderLayout.CENTER); + getContentPane().add(textField, BorderLayout.SOUTH); + textPane.setBorder(BorderFactory.createLineBorder(Color.BLUE, 3)); + textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + pack(); + setVisible(true); + } + + protected void append(String sty, String st) + { + st += "\n"; + try + { + if (sty.equals("local")) + dsd.insertString(dsd.getLength(), st, local); + if (sty.equals("distant")) + dsd.insertString(dsd.getLength(), ">" + st, distant); + textPane.setCaretPosition(dsd.getLength()); + + } + catch (BadLocationException e) + {} + } + + protected void processWindowEvent(WindowEvent e) + { + if (e.getID() == WindowEvent.WINDOW_CLOSING) + { + out.println(NetworkServer.END_OF_FILE); + dispose(); + } + } + + public void actionPerformed(ActionEvent e) + { + String txt = textField.getText(); + append("local", txt); + textField.setText(""); + out.println(txt); + } +} diff --git a/logo/src/xlogo/kernel/network/NetworkClientChat.java b/logo/src/xlogo/kernel/network/NetworkClientChat.java new file mode 100644 index 0000000..cf9ce0b --- /dev/null +++ b/logo/src/xlogo/kernel/network/NetworkClientChat.java @@ -0,0 +1,115 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.network; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import xlogo.Application; +import xlogo.Logo; +import xlogo.kernel.LogoError; +import xlogo.storage.WSManager; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ + +public class NetworkClientChat +{ + private InetAddress ip; + private String st; + private Application app; + private PrintWriter out; + private BufferedReader in; + private Socket socket; + ChatFrame cf; + + public NetworkClientChat(Application app, String ip, String st) throws LogoError + { + this.app = app; + try + { + this.ip = InetAddress.getByName(ip); + } + catch (UnknownHostException e) + { + throw new LogoError(Logo.messages.getString("no_host") + " " + ip); + } + this.st = st; + init(); + } + + private void init() throws LogoError + { + try + { + socket = new Socket(ip, WSManager.getUserConfig().getTcpPort()); + java.io.OutputStream os = socket.getOutputStream(); + BufferedOutputStream b = new BufferedOutputStream(os); + OutputStreamWriter osw = new OutputStreamWriter(b, "UTF8"); + out = new PrintWriter(osw, true); + in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8")); + String cmd = NetworkServer.CHATTCP + "\n"; + cmd += st + "\n"; + cmd += NetworkServer.END_OF_FILE; + cf = new ChatFrame(out, app); + cf.append("local", st); + out.println(cmd); + while ((cmd = in.readLine()) != null) + { + if (cmd.equals(NetworkServer.END_OF_FILE)) + { + cf.append("local", Logo.messages.getString("stop_chat")); + break; + } + cf.append("distant", cmd); + } + out.close(); + in.close(); + socket.close(); + } + catch (IOException e) + { + throw new LogoError(Logo.messages.getString("no_host") + ip.getHostAddress()); + } + + } + +} diff --git a/logo/src/xlogo/kernel/network/NetworkClientExecute.java b/logo/src/xlogo/kernel/network/NetworkClientExecute.java new file mode 100644 index 0000000..22c3753 --- /dev/null +++ b/logo/src/xlogo/kernel/network/NetworkClientExecute.java @@ -0,0 +1,114 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.network; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ + +import java.net.Socket; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.UnknownHostException; + +import xlogo.storage.WSManager; + +import java.net.InetAddress; + +import xlogo.Logo; +import xlogo.kernel.Kernel; +import xlogo.kernel.LogoError; + +public class NetworkClientExecute +{ + private InetAddress ip; + private String cmd; + private PrintWriter out; + private BufferedReader in; + private Socket socket; + private Kernel kernel; + + public NetworkClientExecute(Kernel kernel, String ip, String cmd) throws LogoError + { + this.kernel = kernel; + try + { + this.ip = InetAddress.getByName(ip); + } + catch (UnknownHostException e) + { + throw new LogoError(Logo.messages.getString("no_host") + " " + ip); + } + this.cmd = cmd; + init(); + } + + private void init() throws LogoError + { + try + { + socket = new Socket(ip, WSManager.getUserConfig().getTcpPort()); + java.io.OutputStream os = socket.getOutputStream(); + BufferedOutputStream b = new BufferedOutputStream(os); + OutputStreamWriter osw = new OutputStreamWriter(b, "UTF8"); + out = new PrintWriter(osw, true); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String wp = NetworkServer.EXECUTETCP + "\n"; + wp += kernel.getWorkspace().getSerializedContext(); // Marko : changed + wp += NetworkServer.END_OF_FILE; + out.println(wp); + String input; + while ((input = in.readLine()) != null) + { + // System.out.println("je vais envoyer: OK"); + if (input.equals("OK")) + { + // System.out.println("chargement reussi"); + break; + } + } + out.println(cmd); + out.close(); + in.close(); + socket.close(); + } + catch (IOException e) + { + throw new LogoError(Logo.messages.getString("no_host") + ip.getHostAddress()); + } + } +} diff --git a/logo/src/xlogo/kernel/network/NetworkClientSend.java b/logo/src/xlogo/kernel/network/NetworkClientSend.java new file mode 100644 index 0000000..2954436 --- /dev/null +++ b/logo/src/xlogo/kernel/network/NetworkClientSend.java @@ -0,0 +1,100 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.network; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import xlogo.Logo; +import xlogo.kernel.LogoError; +import xlogo.storage.WSManager; + +public class NetworkClientSend +{ + + private InetAddress ip; + private String data; + private BufferedReader in; + private PrintWriter out; + private Socket socket; + private String answer; + + public NetworkClientSend(String ip, String data) throws LogoError + { + try + { + this.ip = InetAddress.getByName(ip); + } + catch (UnknownHostException e) + { + throw new LogoError(Logo.messages.getString("no_host") + " " + ip); + } + this.data = data; + init(); + } + + /** + * @return + * @uml.property name="answer" + */ + public String getAnswer() + { + return answer; + } + + private void init() throws LogoError + { + try + { + socket = new Socket(ip, WSManager.getUserConfig().getTcpPort()); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + java.io.OutputStream os = socket.getOutputStream(); + BufferedOutputStream b = new BufferedOutputStream(os); + OutputStreamWriter osw = new OutputStreamWriter(b, "UTF8"); + out = new PrintWriter(osw, true); + out.println(data); + answer = ""; + answer = in.readLine(); + out.close(); + socket.close(); + } + catch (IOException e) + { + throw new LogoError(Logo.messages.getString("no_host") + ip.getHostAddress()); + } + } +} diff --git a/logo/src/xlogo/kernel/network/NetworkServer.java b/logo/src/xlogo/kernel/network/NetworkServer.java new file mode 100644 index 0000000..f12b383 --- /dev/null +++ b/logo/src/xlogo/kernel/network/NetworkServer.java @@ -0,0 +1,194 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.network; + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +import java.net.ServerSocket; +import java.net.Socket; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import xlogo.storage.WSManager; +import xlogo.Application; +import xlogo.Logo; +import xlogo.kernel.LogoError; +import xlogo.kernel.Kernel; +import xlogo.messages.MessageKeys; +import xlogo.messages.async.history.HistoryMessenger; + +public class NetworkServer +{ + public static boolean isActive; + private ServerSocket serverSocket; + private Application app; + private PrintWriter out; + private BufferedReader in; + private ChatFrame cf; + + protected static final String EXECUTETCP = "executetcp" + "\u001B"; + protected static final String CHATTCP = "chattcp" + "\u001B"; + protected static final String END_OF_FILE = "*/EOF\\*" + "\u001B"; + private Kernel kernel; + + public NetworkServer(Application app) throws LogoError + { + isActive = true; + this.app = app; + this.kernel = app.getKernel(); + init(); + + } + + private void init() throws LogoError + { + try + { + serverSocket = new ServerSocket(WSManager.getUserConfig().getTcpPort()); + } + catch (IOException e) + { + throw (new LogoError(Logo.messages.getString("pb_port") + WSManager.getUserConfig().getTcpPort())); + } + Socket clientSocket = null; + try + { + clientSocket = serverSocket.accept(); + java.io.OutputStream os = clientSocket.getOutputStream(); + BufferedOutputStream b = new BufferedOutputStream(os); + OutputStreamWriter osw = new OutputStreamWriter(b, "UTF8"); + out = new PrintWriter(osw, true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF8")); + String inputLine = ""; + inputLine = in.readLine(); + // ******************* Executetcp ************************** + if (inputLine.equals(NetworkServer.EXECUTETCP)) + { + StringBuffer remoteNetworkContext = new StringBuffer(); + while ((inputLine = in.readLine()) != null) + { + if (inputLine.equals(NetworkServer.END_OF_FILE)) + break; + remoteNetworkContext.append(inputLine); + remoteNetworkContext.append("\n"); + } + + /* + * Marko Zivkovic : New implementation of this context switch + */ + + try + { + kernel.getWorkspace().pushNetworkMode(remoteNetworkContext.toString()); + } + catch(Exception e) + { + throw new LogoError(Logo.messages.getString(MessageKeys.ERROR_NETWORK_CONTEXT)); + } + + // We say the workspace is fully created + out.println("OK"); + // What is the command to execute? + inputLine = in.readLine(); + // System.out.println("a exécuter: "+inputLine); + out.close(); + in.close(); + clientSocket.close(); + serverSocket.close(); + + kernel.execute(new StringBuffer(inputLine + "\\x ")); + + } + // ******************* Chattcp ************************** + else if (inputLine.equals(NetworkServer.CHATTCP)) + { + String sentence = ""; + while ((inputLine = in.readLine()) != null) + { + if (inputLine.equals(NetworkServer.END_OF_FILE)) + break; + sentence = inputLine; + } + cf = new ChatFrame(out, app); + cf.append("distant", sentence); + while ((sentence = in.readLine()) != null) + { + if (sentence.equals(NetworkServer.END_OF_FILE)) + { + cf.append("local", Logo.messages.getString("stop_chat")); + break; + } + cf.append("distant", sentence); + } + out.close(); + in.close(); + clientSocket.close(); + serverSocket.close(); + } + // ******************* Envoietcp ************************** + else + { + HistoryMessenger.getInstance().dispatchMessage(inputLine); + out.println(Logo.messages.getString("pref.ok")); + out.close(); + in.close(); + clientSocket.close(); + serverSocket.close(); + + } + } + catch (IOException e) + { + throw new LogoError(Logo.messages.getString("erreur_tcp")); + } + isActive = false; + } + + public static void stopServer() + { + String st = NetworkServer.EXECUTETCP + "\n" + NetworkServer.END_OF_FILE + "\n\n"; + try + { + Socket socket = new Socket("127.0.0.1", WSManager.getUserConfig().getTcpPort()); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true); + out.println(st); + } + catch (IOException e) + {} + } +} diff --git a/logo/src/xlogo/kernel/perspective/Conic.java b/logo/src/xlogo/kernel/perspective/Conic.java new file mode 100644 index 0000000..6963b57 --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/Conic.java @@ -0,0 +1,214 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import java.math.BigDecimal; + +import xlogo.kernel.DrawPanel; + +/** + * @author Marko : This is now decoupled from Application + * + */ +public class Conic +{ + private DrawPanel dp; + BigDecimal a; + BigDecimal b; + BigDecimal c; + BigDecimal d; + BigDecimal e; + BigDecimal f; + BigDecimal deux = new BigDecimal(2); + private final BigDecimal un = BigDecimal.ONE; + private final BigDecimal zero = BigDecimal.ZERO; + BigDecimal[][] A = new BigDecimal[2][2]; + private BigDecimal[] eigenValue = new BigDecimal[2]; + private BigDecimal[][] eigenVect = new BigDecimal[2][2]; + private BigDecimal[] center = new BigDecimal[2]; + private double halfXAxis; + private double halfYAxis; + + public Conic(DrawPanel dp, BigDecimal[] v) + { + this.dp = dp; + this.a = v[0]; + this.b = v[1]; + this.c = v[2]; + this.d = v[3]; + this.e = v[4]; + this.f = v[5]; + A[0][0] = a; + A[1][1] = c; + // b/2 + A[0][1] = b.divide(deux); + A[1][0] = b.divide(deux); + drawConic(); + } + + private void drawConic() + { + calculateEigenVect(); + // ellipse + BigDecimal det = det(A); + if (det.compareTo(zero) == 1) + { + // Looking for center + calculateCenter(); + // The main equation becomes with the center as Origin: + // aX^2+bXY+cY^2+omega=0 + + // double omega=a*Math.pow(center[0],2)+c*Math.pow(center[1],2) + // +b*center[0]*center[1]+d*center[0]+e*center[1]+f; + + BigDecimal omega = a.multiply(center[0].pow(2)).add(c.multiply(center[1].pow(2))) + .add(center[0].multiply(center[1]).multiply(b)).add(d.multiply(center[0])) + .add(e.multiply(center[1])).add(f); + + // We apply the rotation with the Eigen Vect Matrix + // Now the equation becomes: lambda*X^2+mu*Y^2+omega=0 + // with lambda and mu the eigen Values + // 1/sqrt(eigenValue[0]/-omega) + halfXAxis = 1 / Math.sqrt(eigenValue[0].divide(omega.negate(), 20, BigDecimal.ROUND_HALF_EVEN) + .doubleValue()); + // 1/sqrt(eigenValue[1]/-omega) + halfYAxis = 1 / Math.sqrt(eigenValue[1].divide(omega.negate(), 20, BigDecimal.ROUND_HALF_EVEN) + .doubleValue()); + double angle = Math.atan(eigenVect[1][0].divide(eigenVect[0][0], 20, BigDecimal.ROUND_HALF_EVEN) + .doubleValue()); + // System.out.println(toString()); + dp.drawEllipseArc(halfXAxis, halfYAxis, angle, center[0].doubleValue(), + center[1].doubleValue(), 0, 360); + + } + // hyperbola + else if (det.compareTo(zero) == -1) + { + calculateCenter(); + + } + // parabola + else + {} + } + + private void calculateEigenValue() + { + // Polynom: acX^2-(a+c)X+A[0][1]^2 + // tmp=a+c + BigDecimal tmp = A[0][0].add(A[1][1]); + // Discriminant delta=(a-c)^2+4*A[0][1]^2 + BigDecimal delta = A[0][0].subtract(A[1][1]).pow(2).add(new BigDecimal(4).multiply(A[0][1].pow(2))); + // calculate the eigen Values + eigenValue[0] = tmp.subtract(sqrt(delta)).divide(deux); + eigenValue[1] = tmp.add(sqrt(delta)).divide(deux); + } + + private void calculateEigenVect() + { + if (A[0][1].compareTo(zero) == 0) + { + eigenValue[0] = A[0][0]; + eigenValue[1] = A[1][1]; + eigenVect[0][0] = un; + eigenVect[1][0] = zero; + eigenVect[0][1] = zero; + eigenVect[1][1] = un; + } + else + { + calculateEigenValue(); + BigDecimal tmp = A[0][0].subtract(eigenValue[0]); + eigenVect[0][0] = un; + // System.out.println("pb: "+tmp+"\n"+A[0][1]); + eigenVect[1][0] = tmp.negate().divide(A[0][1], 20, BigDecimal.ROUND_HALF_EVEN); + // vector length and then normalize + tmp = sqrt(eigenVect[0][0].pow(2).add(eigenVect[1][0].pow(2))); + eigenVect[0][0] = eigenVect[0][0].divide(tmp, 20, BigDecimal.ROUND_HALF_EVEN); + eigenVect[1][0] = eigenVect[1][0].divide(tmp, 20, BigDecimal.ROUND_HALF_EVEN); + eigenVect[0][1] = eigenVect[1][0].negate(); + eigenVect[1][1] = un; + + } + } + + private void calculateCenter() + { + // System determinant + // df/dx=0 and df/dy=0 + + // double det=4*a*c-Math.pow(b,2); + BigDecimal det = new BigDecimal(4).multiply(a).multiply(c).subtract(b.pow(2)); + // xCenter=(-2*c*d+b*e)/det; + center[0] = (deux.negate().multiply(c).multiply(d).add(b.multiply(e))).divide(det, 20, + BigDecimal.ROUND_HALF_EVEN); + // yCenter=(-2*a*e+b*d)/det; + center[1] = (deux.negate().multiply(a).multiply(e).add(b.multiply(d))).divide(det, 20, + BigDecimal.ROUND_HALF_EVEN); + } + + private BigDecimal det(BigDecimal[][] M) + { + return M[0][0].multiply(M[1][1]).subtract(M[0][1].multiply(M[1][0])); + } + + public String toString() + { + String st = "centre: " + center[0] + " " + center[1] + "\n" + "Valeurs propres: " + eigenValue[0] + " " + + eigenValue[1] + "\n" + "Vecteurs propres:\n" + eigenVect[0][0] + " " + eigenVect[0][1] + "\n" + + eigenVect[1][0] + " " + eigenVect[1][1] + "\n" + "Demi Axe: X " + halfXAxis + " Y " + halfYAxis; + return st; + } + + private BigDecimal sqrt(BigDecimal b) + { + BigDecimal precision = new BigDecimal(0.00000000001); + int scale = precision.scale(); + if (b.scale() < scale) + { + b = b.setScale(scale); + } + // Initial guess + // G = A/2 + BigDecimal g = new BigDecimal(Math.sqrt(b.doubleValue())); + + // Iterate until we're done + while (true) + { + // G* = ((A/G)+G)/2 + BigDecimal gStar = b.divide(g, BigDecimal.ROUND_HALF_EVEN).add(g).divide(deux, BigDecimal.ROUND_HALF_EVEN); + BigDecimal delta = gStar.subtract(g); + delta = delta.abs(); + if (delta.compareTo(precision) < 0) + break; + g = gStar; + } + return g; + } +} diff --git a/logo/src/xlogo/kernel/perspective/Element3D.java b/logo/src/xlogo/kernel/perspective/Element3D.java new file mode 100644 index 0000000..d3473cf --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/Element3D.java @@ -0,0 +1,115 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import java.awt.Color; +import java.util.Vector; + +import javax.vecmath.Point3d; + +import xlogo.kernel.LogoError; + +/** + * @author Marko - I decoupled this and its subclasses from Application + * + */ +abstract public class Element3D +{ + protected Viewer3D v3d; + + /** + * Color for each vertex + * + * @uml.property name="color" + * @uml.associationEnd multiplicity="(0 -1)" elementType="java.awt.Color" + */ + protected Vector<Color> color; + + /** + * Vertex coordinates in virtual world + * + * @uml.property name="vertex" + * @uml.associationEnd multiplicity="(0 -1)" + * elementType="javax.vecmath.Point3d" + */ + protected Vector<Point3d> vertex; + + public Element3D(Viewer3D v3d) + { + this.v3d = v3d; + vertex = new Vector<Point3d>(); + color = new Vector<Color>(); + + } + + public void addVertex(Point3d p, Color c) + { + vertex.add(p); + color.add(c); + } + + /** + * This method calculates all attributes for polygon and add it in the 3D + * Viewer + */ + abstract public void addToScene() throws LogoError; + + /** + * This method indicates if the Element3D is a Point. + * + * @return true if this Element3D is a Point, false otherwise + */ + abstract public boolean isPoint(); + + /** + * This method indicates if the Element3D is a Polygon. + * + * @return true if this Element3D is a Polygon, false otherwise + */ + abstract public boolean isPolygon(); + + /** + * This method indicates if the Element3D is a line. + * + * @return true if this Element3D is a line, false otherwise + */ + abstract public boolean isLine(); + + /** + * This method indicates if the Element3D is a Text2D. + * + * @return true if this Element3D is a Text2D, false otherwise + */ + abstract public boolean isText(); + + public int getVertexCount() + { + return vertex.size(); + } +} diff --git a/logo/src/xlogo/kernel/perspective/ElementLine.java b/logo/src/xlogo/kernel/perspective/ElementLine.java new file mode 100644 index 0000000..5aa0a8a --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/ElementLine.java @@ -0,0 +1,374 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import javax.media.j3d.Appearance; +import javax.media.j3d.LineStripArray; +import javax.media.j3d.Material; +import javax.media.j3d.PolygonAttributes; +import javax.media.j3d.Shape3D; +import javax.media.j3d.LineAttributes; +import javax.media.j3d.TransformGroup; + +import com.sun.j3d.utils.geometry.Sphere; + +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.AxisAngle4d; + +import com.sun.j3d.utils.geometry.Cylinder; + +import javax.vecmath.Vector3d; + +import xlogo.kernel.LogoError; + +/** + * + * @author Marko Zivkovic - I decoupled this from Application + * + */ +public class ElementLine extends Element3D +{ + /** + * This float stores the line Width for each 3D line + * + * @uml.property name="lineWidth" + */ + private float lineWidth; + + public ElementLine(Viewer3D v3d, float lineWidth) + { + super(v3d); + this.lineWidth = lineWidth; //app.getKernel().getActiveTurtle().getPenWidth(); + } + + public void addToScene() throws LogoError + { + int size = vertex.size(); + if (size > 1) + { + if (lineWidth == 0.5) + createSimpleLine(size); + else + createComplexLine(size); + } + } + + /** + * This method draws a line with width 1 + * + * @param size + */ + private void createSimpleLine(int size) + { + int[] tab = { size }; + LineStripArray line = new LineStripArray(size, LineStripArray.COORDINATES | LineStripArray.COLOR_3, tab); + for (int i = 0; i < size; i++) + { + line.setCoordinate(i, vertex.get(i)); + // System.out.println("sommet "+(2*i-1)+" "+vertex.get(i).x+" "+vertex.get(i).y+" "+vertex.get(i).z+" "); + line.setColor(i, new Color3f(color.get(i))); + } + Shape3D s = new Shape3D(line); + Appearance appear = new Appearance(); + Material mat = new Material(new Color3f(1.0f, 1.0f, 1.0f), new Color3f(0.0f, 0f, 0f), new Color3f(1f, 1.0f, + 1.0f), new Color3f(1f, 1f, 1f), 64); + appear.setMaterial(mat); + appear.setLineAttributes(new LineAttributes(2 * lineWidth, LineAttributes.PATTERN_SOLID, false)); + s.setAppearance(appear); + // DrawPanel.listPoly.add(s); + v3d.add3DObject(s); + /* + * for (int i=0;i<line.getVertexCount();i++){ + * double[] d=new double[3]; + * line.getCoordinate(i, d); + * for(int j=0;j<d.length;j++){ + * System.out.println(i+" "+d[j]); + * } + * } + */ + } + + /** + * This method draws a sequence of lines with a width different from 1 + * Draws a cylinder around the line + * + * @param size + */ + + private void createComplexLine(int size) + { + for (int i = 0; i < size - 1; i++) + { + createLine(vertex.get(i), vertex.get(i + 1), new Color3f(color.get(i + 1))); + } + + } + + /** + * This method creates an elementary line with a width different from 1 + * It draws a cylinder around the line and two spheres on each extremities + * + * @param p1 + * the first point + * @param p2 + * the second point + * @param color + * the sphere color + */ + private void createLine(Point3d p1, Point3d p2, Color3f color) + { + // create a new CylinderTransformer between the two atoms + CylinderTransformer cT = new CylinderTransformer(p1, p2); + + // get the length + double length = cT.getLength(); + float radius = lineWidth / 1000; + // holds the translation + Transform3D transform1 = new Transform3D(); + // ...move the coordinates there + transform1.setTranslation(cT.getTranslation()); + + // get the axis and angle for rotation + AxisAngle4d rotation = cT.getAxisAngle(); + Transform3D transform2 = new Transform3D(); + transform2.setRotation(rotation); + + // combine the translation and rotation into transform1 + transform1.mul(transform2); + + // create a new Cylinder + Appearance appear = new Appearance(); + Material mat = new Material(new Color3f(1.0f, 1.0f, 1.0f), color, new Color3f(1f, 1.0f, 1.0f), new Color3f(1f, + 1f, 1f), 64); + appear.setMaterial(mat); + PolygonAttributes pa = new PolygonAttributes(); + pa.setCullFace(PolygonAttributes.CULL_NONE); + pa.setBackFaceNormalFlip(true); + appear.setPolygonAttributes(pa); + Cylinder cyl = new Cylinder(radius, (float) length, appear); + + // and add it to the TransformGroup + TransformGroup tg = new TransformGroup(); + tg.setTransform(transform1); + tg.addChild(cyl); + v3d.add2DText(tg); + + // Add Sphere to the line extremities. + Sphere sphere1 = new Sphere(radius, appear); + TransformGroup tg2 = new TransformGroup(); + Transform3D transform3 = new Transform3D(); + transform3.setTranslation(new Vector3d(p1)); + tg2.setTransform(transform3); + tg2.addChild(sphere1); + v3d.add2DText(tg2); + + Sphere sphere2 = new Sphere(radius, appear); + TransformGroup tg3 = new TransformGroup(); + Transform3D transform4 = new Transform3D(); + transform4.setTranslation(new Vector3d(p2)); + tg3.setTransform(transform4); + tg3.addChild(sphere2); + v3d.add2DText(tg3); + + } + + public boolean isLine() + { + return true; + } + + public boolean isPoint() + { + return false; + } + + public boolean isPolygon() + { + return false; + } + + public boolean isText() + { + return false; + } + + /** + * A class to calculate the length and transformations necessary to produce + * a cylinder to connect two points. Useful for Java3D and VRML where a + * cylinder object is created aligned along the y-axis. + * + * @author Alastair Hill + */ + class CylinderTransformer + { + + /** point A */ + private final Point3d pointA; + /** point B */ + private final Point3d pointB; + /** + * the angle through which to rotate the cylinder + */ + private double angle; + /** + * the axis around which to rotate the cylinder + * + */ + private Vector3d axis; + /** + * The translation required to translate the cylinder to the midpoint of + * the two points + */ + private Vector3d translation; + /** + * The length of the cylinder required to join the two points + * + */ + private double length; + + /** + * Creates a new instance of CylinderTransformer + * + * @param a + * point a + * @param b + * point b + */ + CylinderTransformer(Point3d a, Point3d b) + { + pointA = a; + pointB = b; + + // carry out the calculations + doCalculations(); + } + + /** + * Carries out the necessary calculations so that values may be returned + */ + private void doCalculations() + { + length = pointA.distance(pointB); + + double[] arrayA = new double[3]; + pointA.get(arrayA); + double[] arrayB = new double[3]; + pointB.get(arrayB); + double[] arrayMid = new double[3]; + + for (int i = 0; i < arrayA.length; i++) + { + arrayMid[i] = (arrayA[i] + arrayB[i]) / 2f; + } + + // the translation needed is + translation = new Vector3d(arrayMid); + + // the initial orientation of the bond is in the y axis + Vector3d init = new Vector3d(0.0f, 1.0f, 0.0f); + + // the vector needed is the same as that from a to b + Vector3d needed = new Vector3d(pointB.x - pointA.x, pointB.y - pointA.y, pointB.z - pointA.z); + + // so the angle to rotate the bond by is: + angle = needed.angle(init); + + // and the axis to rotate by is the cross product of the initial and + // needed vectors - ie the vector orthogonal to them both + axis = new Vector3d(); + axis.cross(init, needed); + } + + /** + * Returns the angle (in radians) through which to rotate the cylinder + * + * @return the angle. + */ + double getAngle() + { + return angle; + } + + /** + * The axis around which the cylinder must be rotated + * + * @return the axis + */ + Vector3d getAxis() + { + return axis; + } + + /** + * The length required for the cylinder to join the two points + * + * @return the length + */ + double getLength() + { + return length; + } + + /** + * The translation required to move the cylinder to the midpoint of the + * two points + * + * @return the translation + */ + Vector3d getTranslation() + { + return translation; + } + + /** + * Generates a (pretty) string representation of the the + * CylinderTransformer + * + * @return the string representation + */ + public String toString() + { + return "tr: " + translation + ", ax: " + axis + ", an: " + angle + ", le: " + length; + } + + /** + * Generates the required axis and angle combined into an AxisAngle4f + * object + * + * @return the axis and angle + */ + public AxisAngle4d getAxisAngle() + { + return new AxisAngle4d(axis.x, axis.y, axis.z, angle); + } + } + +} diff --git a/logo/src/xlogo/kernel/perspective/ElementPoint.java b/logo/src/xlogo/kernel/perspective/ElementPoint.java new file mode 100644 index 0000000..c77011a --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/ElementPoint.java @@ -0,0 +1,129 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import javax.media.j3d.Appearance; +import javax.media.j3d.Material; +import javax.media.j3d.PointArray; +import javax.media.j3d.PolygonAttributes; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.vecmath.Point3d; +import javax.vecmath.Color3f; +import javax.vecmath.Vector3d; + +import xlogo.kernel.LogoError; + +import javax.media.j3d.Shape3D; + +import com.sun.j3d.utils.geometry.Sphere; + +/** + * @author Marko - I decoupled this from Application + */ +public class ElementPoint extends Element3D +{ + float pointWidth; + + public ElementPoint(Viewer3D v3d, float pointWidth) + { + super(v3d); + this.pointWidth = pointWidth; //app.getKernel().getActiveTurtle().getPenWidth(); + } + + public void addToScene() throws LogoError + { + if (vertex.size() == 0) + return; + if (pointWidth == 0.5) + { + int[] tab = new int[1]; + tab[0] = vertex.size(); + PointArray point = new PointArray(vertex.size(), PointArray.COORDINATES | PointArray.COLOR_3); + for (int i = 0; i < vertex.size(); i++) + { + point.setCoordinate(i, vertex.get(i)); + point.setColor(i, new Color3f(color.get(i))); + } + v3d.add3DObject(new Shape3D(point)); + } + else + { + for (int i = 0; i < vertex.size(); i++) + { + createBigPoint(vertex.get(i), new Color3f(color.get(i))); + } + + } + } + + private void createBigPoint(Point3d p, Color3f color) + { + // Add a Sphere to main 3D scene. + Appearance appear = new Appearance(); + Material mat = new Material(new Color3f(1.0f, 1.0f, 1.0f), color,// new + // Color3f(0.0f,0f,0f), + new Color3f(1f, 1.0f, 1.0f), new Color3f(1f, 1f, 1f), 64); + appear.setMaterial(mat); + PolygonAttributes pa = new PolygonAttributes(); + pa.setCullFace(PolygonAttributes.CULL_NONE); + pa.setBackFaceNormalFlip(true); + appear.setPolygonAttributes(pa); + + Sphere sphere = new Sphere(pointWidth / 1000, appear); + + TransformGroup tg = new TransformGroup(); + Transform3D transform = new Transform3D(); + transform.setTranslation(new Vector3d(p)); + tg.setTransform(transform); + tg.addChild(sphere); + v3d.add2DText(tg); + } + + public boolean isLine() + { + return false; + } + + public boolean isPoint() + { + return true; + } + + public boolean isPolygon() + { + return false; + } + + public boolean isText() + { + return false; + } + +} diff --git a/logo/src/xlogo/kernel/perspective/ElementPolygon.java b/logo/src/xlogo/kernel/perspective/ElementPolygon.java new file mode 100644 index 0000000..d0aa85b --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/ElementPolygon.java @@ -0,0 +1,179 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +package xlogo.kernel.perspective; + +import javax.media.j3d.Appearance; +import javax.media.j3d.Material; +import javax.media.j3d.PolygonAttributes; +import javax.media.j3d.TriangleFanArray; +import javax.vecmath.Point3d; +import javax.media.j3d.Shape3D; +import javax.vecmath.Vector3f; +import javax.vecmath.Color3f; + +import xlogo.Logo; +import xlogo.kernel.LogoError; + +/** + * This class represent A polygon surface in 3D mode + * + * @author loic + * + * @author Marko Zivkovic - I decoupled this from Application + */ +public class ElementPolygon extends Element3D +{ + public ElementPolygon(Viewer3D v3d) + { + super(v3d); + } + + /** + * This method calculates all attributes for polygon and add it to the + * Polygon's list + */ + public void addToScene() throws LogoError + { + + if (vertex.size() < 3) + throw new LogoError(Logo.messages.getString("error.3d.3vertex")); + + // Create normal vector + + Point3d origine = vertex.get(0); + // System.out.println(" origine "+origine.x+" "+origine.y+" "+origine.z); + + Point3d point1; + Vector3f vec1 = null; + Vector3f vec2 = null; + for (int i = 1; i < vertex.size(); i++) + { + point1 = vertex.get(i); + if (!point1.equals(origine)) + { + // System.out.println(" point1 "+point1.x+" "+point1.y+" "+point1.z); + vec1 = new Vector3f((float) (point1.x - origine.x), (float) (point1.y - origine.y), + (float) (point1.z - origine.z)); + break; + } + } + if (null == vec1) + throw new LogoError(Logo.messages.getString("error.3d.emptypolygon")); + for (int i = 2; i < vertex.size(); i++) + { + point1 = vertex.get(i); + // System.out.println(" point1 "+point1.x+" "+point1.y+" "+point1.z); + vec2 = new Vector3f((float) (point1.x - origine.x), (float) (point1.y - origine.y), + (float) (point1.z - origine.z)); + if (vec1.dot(vec2) == 0) + vec2 = null; + else + { + // System.out.println(" vec1 "+vec1.x+" "+vec1.y+" "+vec1.z); + // System.out.println(" vec2 "+vec2.x+" "+vec2.y+" "+vec2.z); + vec2.cross(vec1, vec2); + vec2.normalize(); + vec1 = new Vector3f(vec2); + vec1.negate(); + // System.out.println("Après"+" vec1 "+vec1.x+" "+vec1.y+" "+vec1.z); + // System.out.println("Après"+" vec2 "+vec2.x+" "+vec2.y+" "+vec2.z); + // if (vec1.x!=0&& vec1.y!=0&& vec1.z!=0) + // System.out.println("coucou"+" vec1 "+vec1.x+" "+vec1.y+" "+vec1.z); + break; + } + if (null == vec2) + throw new LogoError(Logo.messages.getString("error.3d.emptypolygon")); + } + + // Create Geometry + + int[] tab = new int[1]; + tab[0] = vertex.size(); + TriangleFanArray tfa = new TriangleFanArray(vertex.size(), TriangleFanArray.COORDINATES + | TriangleFanArray.COLOR_3 | TriangleFanArray.NORMALS, tab); + // TriangleFanArray tfa2=new + // TriangleFanArray(vertex.size(),TriangleFanArray.COORDINATES|TriangleFanArray.COLOR_3|TriangleFanArray.NORMALS,tab); + for (int i = 0; i < vertex.size(); i++) + { + + tfa.setCoordinate(i, vertex.get(i)); + // tfa2.setCoordinate(i, vertex.get(vertex.size()-1-i)); + + tfa.setColor(i, new Color3f(color.get(i))); + // tfa2.setColor(i, new Color3f(color.get(color.size()-i-1))); + + tfa.setNormal(i, vec2); + // tfa2.setNormal(i, vec1); + + } + + Shape3D s = new Shape3D(tfa); + Appearance appear = new Appearance(); + Material mat = new Material(new Color3f(1.0f, 1.0f, 1.0f), new Color3f(0.0f, 0f, 0f), new Color3f(1f, 1.0f, + 1.0f), new Color3f(1f, 1f, 1f), 64); + appear.setMaterial(mat); + PolygonAttributes pa = new PolygonAttributes(); + pa.setCullFace(PolygonAttributes.CULL_NONE); + pa.setBackFaceNormalFlip(true); + appear.setPolygonAttributes(pa); + + s.setAppearance(appear); + v3d.add3DObject(s); + // DrawPanel.listPoly.add(s); + // DrawPanel.listPoly.add(new Shape3D(tfa2)); + // System.out.println(DrawPanel.listPoly.size()+" "+vertex.get(i).x+" "+vertex.get(i).y+" "+vertex.get(i).z); + } + + public boolean isPoint() + { + return false; + } + + public boolean isPolygon() + { + return true; + } + + public boolean isLine() + { + return false; + } + + public boolean isText() + { + return false; + } +} diff --git a/logo/src/xlogo/kernel/perspective/FogDialog.java b/logo/src/xlogo/kernel/perspective/FogDialog.java new file mode 100644 index 0000000..24b8bd1 --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/FogDialog.java @@ -0,0 +1,256 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import xlogo.Logo; +import xlogo.storage.WSManager; + +public class FogDialog extends JDialog implements ActionListener +{ + private static final long serialVersionUID = 1L; + + private String[] type = { Logo.messages.getString("3d.fog.none"), + Logo.messages.getString("3d.fog.linear"), Logo.messages.getString("3d.fog.exponential") }; + + private JComboBox comboType; + + private PanelValue panelDensity; + + private PanelValue panelFront; + + private PanelValue panelBack; + + private JLabel labelType; + + private JButton ok; + + private JButton refresh; + + private Viewer3D viewer3d; + + private MyFog fog; + + FogDialog(Viewer3D viewer3d, MyFog fog, String title) + { + super(viewer3d, title, true); + this.viewer3d = viewer3d; + this.fog = fog; + initGui(); + } + + private void initGui() + { + getContentPane().setLayout(new GridBagLayout()); + setSize(450, 200); + labelType = new JLabel(Logo.messages.getString("3d.fog.type")); + comboType = new JComboBox(type); + comboType.setSelectedIndex(fog.getType()); + + panelDensity = new PanelValue(fog.getDensity(), Logo.messages.getString("3d.fog.density")); + panelFront = new PanelValue((int) (fog.getFront() * 1000), Logo.messages.getString("3d.fog.frontdistance")); + panelBack = new PanelValue((int) (fog.getBack() * 1000), Logo.messages.getString("3d.fog.backdistance")); + + Font font = WSManager.getWorkspaceConfig().getFont(); + + ok = new JButton(Logo.messages.getString("pref.ok")); + refresh = new JButton(Logo.messages.getString("3d.light.apply")); + labelType.setFont(font); + comboType.setFont(font); + ok.setFont(font); + refresh.setFont(font); + + comboType.addActionListener(this); + comboType.setActionCommand("combo"); + ok.addActionListener(this); + ok.setActionCommand("ok"); + refresh.addActionListener(this); + refresh.setActionCommand("refresh"); + + getContentPane().add( + labelType, + new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + comboType, + new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelFront, + new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelBack, + new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelDensity, + new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + refresh, + new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + ok, + new GridBagConstraints(1, 4, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + selectComponents(); + setVisible(true); + + } + + public void actionPerformed(ActionEvent e) + { + String cmd = e.getActionCommand(); + // The selected item in the combo Box has changed + if (cmd.equals("combo")) + selectComponents(); + // Button Ok pressed + else if (cmd.equals("ok")) + { + updateFog(); + dispose(); + } + // Button Apply pressed + else if (cmd.equals("refresh")) + { + updateFog(); + } + } + + private void updateFog() + { + int t = comboType.getSelectedIndex(); + float d = panelDensity.getTextValue(); + float back = panelBack.getTextValue(); + float front = panelFront.getTextValue(); + fog.setType(t); + fog.setDensity(d); + fog.setBack(back / 1000); + fog.setFront(front / 1000); + fog.detach(); + fog.removeAllChildren(); + fog.createFog(); + viewer3d.addNode(fog); + } + + private void selectComponents() + { + int id = comboType.getSelectedIndex(); + // None + if (id == MyFog.FOG_OFF) + { + panelDensity.setEnabled(false); + panelBack.setEnabled(false); + panelFront.setEnabled(false); + } + // Linear Fog + else if (id == MyFog.FOG_LINEAR) + { + panelDensity.setEnabled(false); + panelBack.setEnabled(true); + panelFront.setEnabled(true); + } + // Exponential Fog + else if (id == MyFog.FOG_EXPONENTIAL) + { + panelBack.setEnabled(false); + panelFront.setEnabled(false); + panelDensity.setEnabled(true); + } + } + + class PanelValue extends JPanel + { + private static final long serialVersionUID = 1L; + private JLabel label; + private JTextField text; + private String title; + private float textValue; + + PanelValue(float textValue, String title) + { + this.textValue = textValue; + this.title = title; + initGui(); + } + + private void initGui() + { + label = new JLabel(title); + label.setFont(WSManager.getWorkspaceConfig().getFont()); + String st; + int i = (int) textValue; + if (i == textValue) + { + st = String.valueOf(i); + + } + else + st = String.valueOf(textValue); + text = new JTextField(st, 4); + add(label); + add(text); + } + + public void setEnabled(boolean b) + { + super.setEnabled(b); + label.setEnabled(b); + text.setEnabled(b); + } + + float getTextValue() + { + try + { + float f = Float.parseFloat(text.getText()); + return f; + } + catch (NumberFormatException e) + {} + return 0; + } + } + +} diff --git a/logo/src/xlogo/kernel/perspective/LightDialog.java b/logo/src/xlogo/kernel/perspective/LightDialog.java new file mode 100644 index 0000000..13aa671 --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/LightDialog.java @@ -0,0 +1,378 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Color; + +import xlogo.Logo; + +import javax.vecmath.Color3f; +import javax.vecmath.Tuple3f; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JComboBox; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JLabel; +import javax.swing.JButton; +import javax.swing.border.TitledBorder; + +import java.awt.event.*; + +import xlogo.gui.preferences.PanelColor; +import xlogo.storage.WSManager; + +public class LightDialog extends JDialog implements ActionListener +{ + private static final long serialVersionUID = 1L; + private String[] type = { Logo.messages.getString("3d.light.none"), + Logo.messages.getString("3d.light.ambient"), Logo.messages.getString("3d.light.directional"), + Logo.messages.getString("3d.light.point"), Logo.messages.getString("3d.light.spot") }; + + private JComboBox comboType; + + PanelColor panelColor; + + private PanelPosition panelPosition; + + private PanelPosition panelDirection; + + private PanelAngle panelAngle; + + private JLabel labelType; + + private JButton ok; + + private JButton refresh; + + private Viewer3D viewer3d; + + private MyLight light; + + LightDialog(Viewer3D viewer3d, MyLight light, String title) + { + super(viewer3d, title, true); + this.viewer3d = viewer3d; + this.light = light; + initGui(); + } + + private void initGui() + { + getContentPane().setLayout(new GridBagLayout()); + setSize(500, 200); + labelType = new JLabel(Logo.messages.getString("3d.light.type")); + comboType = new JComboBox(type); + comboType.setSelectedIndex(light.getType()); + + Color3f col = light.getColor(); + if (null != col) + panelColor = new PanelColor(col.get()); + else + panelColor = new PanelColor(Color.white); + panelColor.setBackground(comboType.getBackground()); + + panelPosition = new PanelPosition(Logo.messages.getString("3d.light.position"), light.getPosition()); + panelDirection = new PanelPosition(Logo.messages.getString("3d.light.direction"), light.getDirection()); + panelAngle = new PanelAngle(light.getAngle()); + ok = new JButton(Logo.messages.getString("pref.ok")); + refresh = new JButton(Logo.messages.getString("3d.light.apply")); + + Font font = WSManager.getWorkspaceConfig().getFont(); + + labelType.setFont(font); + comboType.setFont(font); + ok.setFont(font); + refresh.setFont(font); + + comboType.addActionListener(this); + comboType.setActionCommand("combo"); + ok.addActionListener(this); + ok.setActionCommand("ok"); + refresh.addActionListener(this); + refresh.setActionCommand("refresh"); + + getContentPane().add( + labelType, + new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + comboType, + new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelColor, + new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelPosition, + new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelDirection, + new GridBagConstraints(1, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + panelAngle, + new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + refresh, + new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + ok, + new GridBagConstraints(1, 4, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + selectComponents(); + setVisible(true); + + } + + public void actionPerformed(ActionEvent e) + { + String cmd = e.getActionCommand(); + // The selected item in the combo Box has changed + if (cmd.equals("combo")) + selectComponents(); + // Button Ok pressed + else if (cmd.equals("ok")) + { + updateLight(); + dispose(); + } + // Button Apply pressed + else if (cmd.equals("refresh")) + { + updateLight(); + } + } + + private void updateLight() + { + int t = comboType.getSelectedIndex(); + Color3f c = new Color3f(panelColor.getValue()); + Point3f p = panelPosition.getPosition(); + Vector3f d = panelDirection.getDirection(); + float a = panelAngle.getAngleValue(); + light.setType(t); + light.setColor(c); + light.setPosition(p); + light.setDirection(d); + light.setAngle(a); + light.detach(); + light.removeAllChildren(); + light.createLight(); + // System.out.println(c+" "+" "+p+" "+d); + viewer3d.addNode(light); + + } + + private void selectComponents() + { + int id = comboType.getSelectedIndex(); + // None + if (id == MyLight.LIGHT_OFF) + { + panelColor.setEnabled(false); + panelPosition.setEnabled(false); + panelDirection.setEnabled(false); + panelAngle.setEnabled(false); + } + // Ambient + else if (id == MyLight.LIGHT_AMBIENT) + { + panelColor.setEnabled(true); + panelPosition.setEnabled(false); + panelDirection.setEnabled(false); + panelAngle.setEnabled(false); + } + // Directional + else if (id == MyLight.LIGHT_DIRECTIONAL) + { + panelColor.setEnabled(true); + panelPosition.setEnabled(false); + panelDirection.setEnabled(true); + panelAngle.setEnabled(false); + } + // PointLight + else if (id == MyLight.LIGHT_POINT) + { + panelColor.setEnabled(true); + panelPosition.setEnabled(true); + panelDirection.setEnabled(false); + panelAngle.setEnabled(false); + } + // Spot + else if (id == MyLight.LIGHT_SPOT) + { + panelColor.setEnabled(true); + panelPosition.setEnabled(true); + panelDirection.setEnabled(true); + panelAngle.setEnabled(true); + } + } + + class PanelAngle extends JPanel + { + private static final long serialVersionUID = 1L; + private JLabel label; + private JTextField angle; + private float angleValue; + + PanelAngle(float angleValue) + { + this.angleValue = angleValue; + + initGui(); + } + + private void initGui() + { + label = new JLabel(Logo.messages.getString("3d.light.angle")); + label.setFont(WSManager.getWorkspaceConfig().getFont()); + angle = new JTextField(String.valueOf(angleValue)); + angle.setSize(30, WSManager.getWorkspaceConfig().getFont().getSize() + 10); + add(label); + add(angle); + } + + public void setEnabled(boolean b) + { + super.setEnabled(b); + label.setEnabled(b); + angle.setEnabled(b); + } + + /** + * @return + * @uml.property name="angleValue" + */ + float getAngleValue() + { + try + { + float f = Float.parseFloat(angle.getText()); + return f; + } + catch (NumberFormatException e) + {} + return MyLight.DEFAULT_ANGLE; + } + } + + class PanelPosition extends JPanel + { + private static final long serialVersionUID = 1L; + private String title; + private JTextField Xpos; + private JTextField Ypos; + private JTextField Zpos; + private JLabel sep1; + private JLabel sep2; + Tuple3f tuple; + + PanelPosition(String title, Tuple3f tuple) + { + this.title = title; + this.tuple = tuple; + initGui(); + } + + private void initGui() + { + TitledBorder tb = BorderFactory.createTitledBorder(title); + tb.setTitleFont(WSManager.getWorkspaceConfig().getFont()); + setBorder(tb); + sep1 = new JLabel("x"); + sep2 = new JLabel("x"); + Xpos = new JTextField(4); + Ypos = new JTextField(4); + Zpos = new JTextField(4); + if (null != tuple) + { + Xpos.setText(String.valueOf((int) (tuple.x * 1000))); + Ypos.setText(String.valueOf((int) (tuple.y * 1000))); + Zpos.setText(String.valueOf((int) (tuple.z * 1000))); + } + add(Xpos); + add(sep1); + add(Ypos); + add(sep2); + add(Zpos); + } + + Point3f getPosition() + { + try + { + float x = Float.parseFloat(Xpos.getText()); + float y = Float.parseFloat(Ypos.getText()); + float z = Float.parseFloat(Zpos.getText()); + return new Point3f(x / 1000, y / 1000, z / 1000); + } + catch (NumberFormatException e) + {} + return (new Point3f(0, 0, 0)); + } + + Vector3f getDirection() + { + try + { + float x = Float.parseFloat(Xpos.getText()); + float y = Float.parseFloat(Ypos.getText()); + float z = Float.parseFloat(Zpos.getText()); + return new Vector3f(x / 1000, y / 1000, z / 1000); + } + catch (NumberFormatException e) + {} + return (new Vector3f(0, 0, 0)); + + } + + public void setEnabled(boolean b) + { + super.setEnabled(b); + sep1.setEnabled(b); + sep2.setEnabled(b); + Xpos.setEnabled(b); + Ypos.setEnabled(b); + Zpos.setEnabled(b); + } + + } + +} diff --git a/logo/src/xlogo/kernel/perspective/MyFog.java b/logo/src/xlogo/kernel/perspective/MyFog.java new file mode 100644 index 0000000..1961fcc --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/MyFog.java @@ -0,0 +1,134 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import javax.media.j3d.BranchGroup; +import javax.media.j3d.LinearFog; +import javax.media.j3d.ExponentialFog; +import javax.media.j3d.Fog; +import javax.media.j3d.BoundingSphere; + +import javax.vecmath.Color3f; + +public class MyFog extends BranchGroup +{ + protected final static int FOG_OFF = 0; + protected final static int FOG_LINEAR = 1; + protected final static int FOG_EXPONENTIAL = 2; + private int type = FOG_OFF; + private float density = 1; + private float backDistance = 3.5f; + private float frontDistance = 0.5f; + private Fog fog; + Color3f color; + + MyFog(int type, Color3f color) + { + super(); + setCapability(BranchGroup.ALLOW_DETACH); + setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + this.type = type; + this.color = color; + } + + /** + * This method creates a light according to each parameter:<br> + * type, color, position, direction and angle + */ + void createFog() + { + this.setCapability(BranchGroup.ALLOW_DETACH); + this.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + switch (type) + { + case FOG_OFF: + fog = null; + break; + case FOG_LINEAR: + fog = new LinearFog(color); + ((LinearFog) fog).setBackDistance(backDistance); + ((LinearFog) fog).setFrontDistance(frontDistance); + fog.setInfluencingBounds(new BoundingSphere()); + break; + case FOG_EXPONENTIAL: + fog = new ExponentialFog(color, density); + fog.setInfluencingBounds(new BoundingSphere()); + break; + } + if (null != fog) + addChild(fog); + } + + /** + * This method returns the light type + * + * @return an integer which represents the light type + * @uml.property name="type" + */ + int getType() + { + return type; + } + + void setType(int t) + { + type = t; + } + + float getDensity() + { + return density; + } + + void setDensity(float f) + { + density = f; + } + + float getBack() + { + return backDistance; + } + + void setBack(float f) + { + backDistance = f; + } + + float getFront() + { + return frontDistance; + } + + void setFront(float f) + { + frontDistance = f; + } + +} diff --git a/logo/src/xlogo/kernel/perspective/MyLight.java b/logo/src/xlogo/kernel/perspective/MyLight.java new file mode 100644 index 0000000..9c5c054 --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/MyLight.java @@ -0,0 +1,190 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Light; +import javax.media.j3d.PointLight; +import javax.media.j3d.SpotLight; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; +import javax.media.j3d.BranchGroup; + +public class MyLight extends BranchGroup +{ + protected final static int LIGHT_OFF = 0; + protected final static int LIGHT_AMBIENT = 1; + protected final static int LIGHT_DIRECTIONAL = 2; + protected final static int LIGHT_POINT = 3; + protected final static int LIGHT_SPOT = 4; + protected final static float DEFAULT_ANGLE = 15; + private int type = LIGHT_OFF; + private Color3f color; + private Point3f position; + private Vector3f direction; + private float angle = DEFAULT_ANGLE; + private Light light; + + MyLight(int type) + { + super(); + this.type = type; + } + + MyLight(int type, Color3f color, Point3f position) + { + super(); + this.type = type; + this.color = color; + this.position = position; + } + + /** + * This method creates a light according to each parameter:<br> + * type, color, position, direction and angle + */ + void createLight() + { + this.setCapability(BranchGroup.ALLOW_DETACH); + this.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + switch (type) + { + case LIGHT_OFF: + light = null; + break; + case LIGHT_AMBIENT: + light = new AmbientLight(color); + light.setInfluencingBounds(new BoundingSphere(new Point3d(position), Double.MAX_VALUE)); + break; + case LIGHT_DIRECTIONAL: + light = new DirectionalLight(color, direction); + light.setInfluencingBounds(new BoundingSphere(new Point3d(position), Double.MAX_VALUE)); + break; + case LIGHT_POINT: + light = new PointLight(color, position, new Point3f(1, 0, 0)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(position), Double.MAX_VALUE)); + break; + case LIGHT_SPOT: + light = new SpotLight(color, position, new Point3f(1, 0, 0), direction, (float) Math.toRadians(angle), + 64); + light.setInfluencingBounds(new BoundingSphere(new Point3d(position), Double.MAX_VALUE)); + break; + } + if (null != light) + addChild(light); + } + + /** + * This method returns the light type + * + * @return an integer which represents the light type + */ + int getType() + { + return type; + } + + /** + * @param t + */ + void setType(int t) + { + type = t; + } + + /** + * @return + */ + Color3f getColor() + { + return color; + } + + /** + * @param c + */ + void setColor(Color3f c) + { + color = c; + } + + /** + * @return + */ + Point3f getPosition() + { + return position; + } + + /** + * @param p + */ + void setPosition(Point3f p) + { + + position = p; + } + + /** + * @return + */ + Vector3f getDirection() + { + return direction; + } + + /** + * @param v + */ + void setDirection(Vector3f v) + { + direction = v; + } + + /** + * @return + */ + float getAngle() + { + return angle; + } + + /** + * @param f + */ + void setAngle(float f) + { + angle = f; + } + +} diff --git a/logo/src/xlogo/kernel/perspective/Viewer3D.java b/logo/src/xlogo/kernel/perspective/Viewer3D.java new file mode 100644 index 0000000..e7bce56 --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/Viewer3D.java @@ -0,0 +1,493 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.awt.Toolkit; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Canvas3D; + +import java.awt.image.BufferedImage; + +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.ImageComponent; +import javax.media.j3d.GraphicsContext3D; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Raster; +import javax.vecmath.Point3f; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.media.j3d.Node; +import javax.media.j3d.Background; + +import java.awt.GridBagLayout; +import java.awt.Color; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.border.TitledBorder; + +import java.awt.GridLayout; + +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; + +import xlogo.storage.WSManager; +import xlogo.utils.Utils; +import xlogo.utils.WriteImage; +import xlogo.Logo; + +import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; +import com.sun.j3d.utils.universe.SimpleUniverse; + +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +/** + * This Frame displays the 3D main Scene + * + * BG scene + * + * BG backBranchGroup | BG Mylight (4) | BG + * Background Light 1,2,3,4 Other objects + */ + +public class Viewer3D extends JFrame implements ActionListener +{ + private final static String ACTION_SCREENSHOT = "screenshot"; + private final static String ACTION_LIGHT0 = "light0"; + private final static String ACTION_LIGHT1 = "light1"; + private final static String ACTION_LIGHT2 = "light2"; + private final static String ACTION_LIGHT3 = "light3"; + private final static String ACTION_FOG = "fog"; + + // To store the Light attributes + private MyLight[] myLights; + // To store the Fog attributes + private MyFog myFog; + // Gui Components + private ImageIcon iscreenshot = Utils.dimensionne_image("screenshot.png", this); + private JButton screenshot; + private static final long serialVersionUID = 1L; + private World3D w3d; + private Canvas3D canvas3D; + /** + * Main scene's Branchgroup + */ + private BranchGroup scene; + private BranchManager branchManager; + private SimpleUniverse universe; + private Color3f backgroundColor; + private BranchGroup backBranchgroup; + private Background back; + private PanelLight panelLight; + private PanelFog panelFog; + + public Viewer3D(World3D w3d, Color c) + { + this.w3d = w3d; + this.backgroundColor = new Color3f(c); + initGui(); + } + + public void actionPerformed(ActionEvent e) + { + String cmd = e.getActionCommand(); + // Take a screenshot + if (cmd.equals(Viewer3D.ACTION_SCREENSHOT)) + { + WriteImage wi = new WriteImage(this, null); + int id = wi.chooseFile(); + if (id == JFileChooser.APPROVE_OPTION) + { + GraphicsContext3D ctx = canvas3D.getGraphicsContext3D(); + java.awt.Dimension scrDim = canvas3D.getSize(); + + // setting raster component + Raster ras = new Raster(new Point3f(-1.0f, -1.0f, -1.0f), Raster.RASTER_COLOR, 0, 0, scrDim.width, + scrDim.height, new ImageComponent2D(ImageComponent.FORMAT_RGB, new BufferedImage(scrDim.width, + scrDim.height, java.awt.image.BufferedImage.TYPE_INT_RGB)), null); + ctx.readRaster(ras); + BufferedImage img = ras.getImage().getImage(); + wi.setImage(img); + wi.start(); + } + } + // Click on Button Light1 + else if (cmd.equals(Viewer3D.ACTION_LIGHT0)) + { + new LightDialog(this, myLights[0], Logo.messages.getString("3d.light") + " 1"); + } + // Click on Button Light2 + else if (cmd.equals(Viewer3D.ACTION_LIGHT1)) + { + new LightDialog(this, myLights[1], Logo.messages.getString("3d.light") + " 2"); + } + // Click on Button Light3 + else if (cmd.equals(Viewer3D.ACTION_LIGHT2)) + { + new LightDialog(this, myLights[2], Logo.messages.getString("3d.light") + " 3"); + } + // Click on Button Light4 + else if (cmd.equals(Viewer3D.ACTION_LIGHT3)) + { + new LightDialog(this, myLights[3], Logo.messages.getString("3d.light") + " 4"); + } + // Click on the Fog Button + else if (cmd.equals(Viewer3D.ACTION_FOG)) + { + new FogDialog(this, myFog, Logo.messages.getString("3d.fog")); + + } + } + + public void setText() + { + setTitle(Logo.messages.getString("3d.viewer")); + panelFog.setText(); + panelLight.setText(); + + } + + private void initGui() + { + this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setIconImage(Toolkit.getDefaultToolkit().createImage(Utils.class.getResource("icone.png"))); + + // Creation d'un composant de classe Canvas3D permettant de visualiser + // une scène 3D + canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + // Création d'un univers 3D rattaché au composant 3D + universe = new SimpleUniverse(canvas3D); + + // Install the camera at the valid position with correct orientation + TransformGroup tg = universe.getViewingPlatform().getViewPlatformTransform(); + Transform3D trans = new Transform3D(); + if (null == w3d) + { + w3d = new World3D(); + } + trans.setTranslation(new Vector3d(-w3d.xCamera / 1000, -w3d.yCamera / 1000, -w3d.zCamera / 1000)); + Transform3D rot = new Transform3D(); + rot.lookAt(new Point3d(-w3d.xCamera / 1000, -w3d.yCamera / 1000, -w3d.zCamera / 1000), new Point3d(0, 0, 0), + new Vector3d(0, 1, 0)); + rot.invert(); + trans.mul(rot); + tg.setTransform(trans); + OrbitBehavior ob = new OrbitBehavior(canvas3D, OrbitBehavior.REVERSE_ALL); + ob.setRotationCenter(new Point3d(0, 0, 0)); + ob.setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0), 2 * w3d.r / 1000)); + universe.getViewingPlatform().setViewPlatformBehavior(ob); + + // Create the root of the branch graph + scene = new BranchGroup(); + branchManager = new BranchManager(); + // scene.setName("Main Branch"); + // We can add New BranchGroup dynamically in the main scene + scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); + // We can remove BranchGroup dynamically in the main scene + scene.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + + // Configure and create background + createBackground(); + + // Configure Lights + initLights(); + + // Configure Fog + myFog = new MyFog(MyFog.FOG_OFF, backgroundColor); + scene.addChild(myFog); + + // Rattachement de la scène 3D à l'univers + universe.addBranchGraph(scene); + + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + int width = d.width * 9 / 10; + int height = d.height * 9 / 10; + setSize(width, height); + getContentPane().setLayout(new GridBagLayout()); + screenshot = new JButton(iscreenshot); + screenshot.addActionListener(this); + screenshot.setMaximumSize(new Dimension(100, 100)); + screenshot.setActionCommand(Viewer3D.ACTION_SCREENSHOT); + + panelLight = new PanelLight(this); + panelFog = new PanelFog(this); + + getContentPane().add( + canvas3D, + new GridBagConstraints(0, 0, 1, 3, 2.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add( + screenshot, + new GridBagConstraints(1, 0, 1, 1, 0.1, 0.8, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(10, 10, 10, 10), 0, 0)); + getContentPane().add( + panelLight, + new GridBagConstraints(1, 1, 1, 1, 0.1, 0.1, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(10, 10, 10, 10), 0, 0)); + getContentPane().add( + panelFog, + new GridBagConstraints(1, 2, 1, 1, 0.1, 0.1, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(10, 10, 10, 10), 0, 0)); + setText(); + getContentPane().validate(); + } + + /** + * This method adds a shape3D to the main scene + * + * @param s + * The Shape to add + */ + public void add3DObject(Shape3D s) + { + branchManager.add3DObject(s); + } + + public void add2DText(TransformGroup tg) + { + branchManager.add2DText(tg); + } + + public void insertBranch() + { + branchManager.insertBranch(); + branchManager = new BranchManager(); + } + + /** + * This methods adds two default PointLight int the 3d Scene + */ + private void initLights() + { + myLights = new MyLight[4]; + // First Default Point Light + Color3f color = new Color3f(1f, 1f, 1f); + Point3f pos = new Point3f((float) w3d.xCamera / 1000, (float) w3d.yCamera / 1000, (float) w3d.zCamera / 1000); + myLights[0] = new MyLight(MyLight.LIGHT_POINT, color, pos); + + // Second default Point Light + pos = new Point3f(-(float) w3d.xCamera / 1000, -(float) w3d.yCamera / 1000, -(float) w3d.zCamera / 1000); + myLights[1] = new MyLight(MyLight.LIGHT_POINT, color, pos); + + myLights[2] = new MyLight(MyLight.LIGHT_OFF); + myLights[3] = new MyLight(MyLight.LIGHT_OFF); + for (int i = 0; i < 4; i++) + { + myLights[i].createLight(); + } + addAllLights(scene); + } + + /** + * Add all lights in the main 3D scene + */ + private void addAllLights(BranchGroup bg) + { + for (int i = 0; i < 4; i++) + { + bg.addChild(myLights[i]); + } + } + + /** + * add a light in the main scene + */ + protected void addNode(Node l) + { + scene.addChild(l); + } + + /** + * This methods erase all drawings on the 3D Viewer Drawing Area + */ + public void clearScreen() + { + scene.removeAllChildren(); + createBackground(); + initLights(); + /* + * Enumeration<Locale> locales=universe.getAllLocales(); + * while(locales.hasMoreElements()){ + * Locale lo=locales.nextElement(); + * Enumeration<BranchGroup> en=lo.getAllBranchGraphs(); + * while(en.hasMoreElements()){ + * BranchGroup bg=en.nextElement(); + * // System.out.println(bg.getName()); + * if (null!=bg.getName()&&bg.getName().equals("Main Branch")){ + * // Detach scene + * bg.detach(); + * // Delete all nodes + * bg.removeAllChildren(); + * // create background + * createBackground(bg); + * // Add lights + * addAllLights(bg); + * // Attach scene + * lo.addBranchGraph(bg); + * } + * } + * } + */ + + } + + public void updateBackGround(Color c) + { + backgroundColor = new Color3f(c); + backBranchgroup.detach(); + createBackground(); + } + + /** + * This method creates the Background with the defined color + */ + public void createBackground() + { + backBranchgroup = new BranchGroup(); + backBranchgroup.setCapability(BranchGroup.ALLOW_DETACH); + backBranchgroup.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + + back = new Background(backgroundColor); + back.setApplicationBounds(new BoundingSphere()); + back.setCapability(Background.ALLOW_COLOR_WRITE); + backBranchgroup.addChild(back); + scene.addChild(backBranchgroup); + } + + class BranchManager + { + BranchGroup bg; + + BranchManager() + { + bg = new BranchGroup(); + bg.setCapability(BranchGroup.ALLOW_DETACH); + } + + /** + * This method adds a shape3D to the main scene + * + * @param s + * The Shape to add + */ + void add3DObject(Shape3D s) + { + bg.addChild(s); + } + + void add2DText(TransformGroup tg) + { + bg.addChild(tg); + } + + void insertBranch() + { + bg.compile(); + scene.addChild(bg); + } + } + + class PanelLight extends JPanel + { + private static final long serialVersionUID = 1L; + private JButton[] buttonLights; + private Viewer3D viewer3d; + + PanelLight(Viewer3D viewer3d) + { + this.viewer3d = viewer3d; + initGui(); + } + + private void initGui() + { + buttonLights = new JButton[4]; + setLayout(new GridLayout(2, 2, 10, 10)); + for (int i = 0; i < 4; i++) + { + ImageIcon ilight = Utils.dimensionne_image("light" + i + ".png", viewer3d); + buttonLights[i] = new JButton(ilight); + add(buttonLights[i]); + buttonLights[i].addActionListener(viewer3d); + buttonLights[i].setActionCommand("light" + i); + } + setText(); + } + + void setText() + { + TitledBorder tb = BorderFactory.createTitledBorder(Logo.messages.getString("3d.light")); + tb.setTitleFont(WSManager.getWorkspaceConfig().getFont()); + setBorder(tb); + } + } + + class PanelFog extends JPanel + { + + private static final long serialVersionUID = 1L; + private JButton buttonFog; + private Viewer3D viewer3d; + + PanelFog(Viewer3D viewer3d) + { + this.viewer3d = viewer3d; + initGui(); + } + + private void initGui() + { + ImageIcon ifog =Utils.dimensionne_image("fog.png", viewer3d); + buttonFog = new JButton(ifog); + buttonFog.setActionCommand(Viewer3D.ACTION_FOG); + buttonFog.addActionListener(viewer3d); + add(buttonFog); + setText(); + } + + void setText() + { + TitledBorder tb = BorderFactory.createTitledBorder(Logo.messages.getString("3d.fog")); + tb.setTitleFont(WSManager.getWorkspaceConfig().getFont()); + setBorder(tb); + } + } + +} diff --git a/logo/src/xlogo/kernel/perspective/World3D.java b/logo/src/xlogo/kernel/perspective/World3D.java new file mode 100644 index 0000000..d3ffcc5 --- /dev/null +++ b/logo/src/xlogo/kernel/perspective/World3D.java @@ -0,0 +1,318 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.kernel.perspective; + +import xlogo.storage.WSManager; +import xlogo.storage.user.UserConfig; + +public class World3D +{ + + double theta = Math.toRadians(45); + + double phi = Math.toRadians(30); + + public double r = 1500; + + public double xCamera = r * Math.cos(theta) * Math.cos(phi); + + public double yCamera = r * Math.sin(theta) * Math.cos(phi); + + public double zCamera = r * Math.sin(phi); ; + + public double screenDistance = 1000; + + private double[][] array3D; + + public World3D() + { + initArray3D(); + + } + + /** + * This method converts the coordinates in coord to the screen coord + */ + public void toScreenCoord(double[] coord) + { + // Coord in the camera world + toCameraWorld(coord); + /* + * double x=array3D[0][0]*coord[0]+array3D[1][0]*coord[1]; + * double + * y=array3D[0][1]*coord[0]+array3D[1][1]*coord[1]+array3D[2][1]*coord + * [2]; + * double + * z=array3D[0][2]*coord[0]+array3D[1][2]*coord[1]+array3D[2][2]*coord + * [2]+r; + */ + cameraToScreen(coord); + } + + /** + * This method converts coordinates conatined in coord from camera world to + * screen + */ + public void cameraToScreen(double[] coord) + { + UserConfig uc = WSManager.getUserConfig(); + + double x = coord[0]; + double y = coord[1]; + double z = coord[2]; + coord[0] = screenDistance * x / z + uc.getImageWidth() / 2; + coord[1] = uc.getImageHeight() / 2 - screenDistance * y / z; + } + + /** + * This method initializes the 3D array + */ + private void initArray3D() + { + double cost = Math.cos(theta); + double sint = Math.sin(theta); + double cosp = Math.cos(phi); + double sinp = Math.sin(phi); + array3D = new double[4][4]; + array3D[0][0] = -sint; + array3D[0][1] = -cost * sinp; + array3D[0][2] = -cost * cosp; + array3D[0][3] = 0; + array3D[1][0] = cost; + array3D[1][1] = -sint * sinp; + array3D[1][2] = -sint * cosp; + array3D[1][3] = 0; + array3D[2][0] = 0; + array3D[2][1] = cosp; + array3D[2][2] = -sinp; + array3D[2][3] = 0; + array3D[3][0] = 0; + array3D[3][1] = 0; + array3D[3][2] = r; + array3D[3][3] = 1; + } + + /** + * This method converts coordinates from Real world to coodinates in camera + * world + * + * @param coord + * The real World coordinates + * @return Array that contains coordinates in camera world + */ + + public void toCameraWorld(double[] coord) + { + double x = array3D[0][0] * coord[0] + array3D[1][0] * coord[1]; + double y = array3D[0][1] * coord[0] + array3D[1][1] * coord[1] + array3D[2][1] * coord[2]; + double z = array3D[0][2] * coord[0] + array3D[1][2] * coord[1] + array3D[2][2] * coord[2] + r; + coord[0] = x; + coord[1] = y; + coord[2] = z; + } + + /** + * This method multiply two matrices + * + * @param a + * The first matrix + * @param b + * The second matrix + * @return The matrix product + */ + public double[][] multiply(double[][] a, double[][] b) + { + int n = a.length; + int p = b[0].length; + int s = a[0].length; + double[][] m = new double[n][p]; + for (int i = 0; i < n; i++) + { + for (int j = 0; j < p; j++) + { + m[i][j] = 0; + for (int k = 0; k < s; k++) + { + m[i][j] += a[i][k] * b[k][j]; + } + } + } + return m; + } + + /** + * This method returns a matrix for a Z Axis rotation + * + * @param angle + * The rotation angle + * @return The rotation matrix + */ + public double[][] rotationZ(double angle) + { + double[][] m = new double[3][3]; + double cos = Math.cos(Math.toRadians(angle)); + double sin = Math.sin(Math.toRadians(angle)); + m[0][0] = cos; + m[1][0] = sin; + m[0][1] = -sin; + m[1][1] = cos; + m[2][2] = 1; + m[2][1] = m[2][0] = m[0][2] = m[1][2] = 0; + return m; + } + + /** + * This method returns a matrix for a Y Axis rotation + * + * @param angle + * The rotation angle + * @return The rotation matrix + */ + public double[][] rotationY(double angle) + { + double[][] m = new double[3][3]; + double cos = Math.cos(Math.toRadians(angle)); + double sin = Math.sin(Math.toRadians(angle)); + m[0][0] = cos; + m[2][0] = sin; + m[0][2] = -sin; + m[2][2] = cos; + m[1][1] = 1; + m[0][1] = m[1][0] = m[1][2] = m[2][1] = 0; + return m; + } + + /** + * This method returns a matrix for a X Axis rotation + * + * @param angle + * The rotation angle + * @return The rotation matrix + */ + public double[][] rotationX(double angle) + { + double[][] m = new double[3][3]; + double cos = Math.cos(Math.toRadians(angle)); + double sin = Math.sin(Math.toRadians(angle)); + m[0][0] = 1; + m[1][1] = cos; + m[2][1] = sin; + m[1][2] = -sin; + m[2][2] = cos; + m[1][0] = m[2][0] = m[0][1] = m[0][2] = 0; + return m; + } + + /** + * This method with the 3 Euler's angle builds a rotation matrix + * + * @param heading + * The turtle heading + * @param roll + * The turtle roll + * @param pitch + * The turtle pitch + * @return The rotation Matrix + */ + + public double[][] EulerToRotation(double roll, double pitch, double heading) + { + double[][] m = new double[3][3]; + double rpitch = Math.toRadians(pitch); + double rheading = Math.toRadians(heading); + double rroll = Math.toRadians(roll); + double a = Math.cos(rpitch); + double b = Math.sin(rpitch); + double c = Math.cos(rroll); + double d = Math.sin(rroll); + double e = Math.cos(rheading); + double f = Math.sin(rheading); + double bd = b * d; + double bc = b * c; + m[0][0] = c * e - bd * f; + m[0][1] = -c * f - bd * e; + m[0][2] = -a * d; + m[1][0] = a * f; + m[1][1] = a * e; + m[1][2] = -b; + m[2][0] = d * e + bc * f; + m[2][1] = -d * f + bc * e; + m[2][2] = a * c; + return m; + } + + /** + * + */ + public double[] rotationToEuler(double[][] m) + { + double[] v = new double[3]; + + double angle_x, angle_y, angle_z; + double a, tr_x, tr_y; + // Angle x + angle_x = -Math.asin(m[1][2]); + + a = Math.cos(angle_x); + // Gimbal Lock? + if (Math.abs(a) > 0.005) + { + // No gimbal Lock + // Angle z + tr_x = m[1][1] / a; + tr_y = m[1][0] / a; + angle_z = Math.atan2(tr_y, tr_x); + // Angle y + tr_x = m[2][2] / a; + tr_y = -m[0][2] / a; + angle_y = Math.atan2(tr_y, tr_x); + v[0] = Math.toDegrees(angle_x); + v[1] = -Math.toDegrees(angle_y); + v[2] = -Math.toDegrees(angle_z); + } + else + { // Gimbal Lock + angle_y = 0; + // Angle z + tr_x = m[0][0]; + tr_y = m[2][0]; + angle_z = Math.atan2(tr_y, tr_x); + v[0] = 270; + v[1] = 0; + v[2] = Math.toDegrees(angle_z); + } + + for (int i = 0; i < v.length; i++) + { + if (v[i] < 0) + v[i] += 360; + } + return v; + } +} diff --git a/logo/src/xlogo/kernel/userspace/ErrorManager.java b/logo/src/xlogo/kernel/userspace/ErrorManager.java new file mode 100644 index 0000000..f1b18ec --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/ErrorManager.java @@ -0,0 +1,201 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import xlogo.interfaces.ErrorDetector.AmbiguityDetector.AmbiguityListener;
+import xlogo.interfaces.ErrorDetector.FileErrorCollector;
+import xlogo.kernel.userspace.procedures.Procedure;
+
+public class ErrorManager implements FileErrorCollector
+{
+ private final FileErrorCollector fileErrorDetector;
+ private final AmbiguityDetector ambiguityDetector;
+
+ private final HashMap<String, Void> errorFiles = new HashMap<String, Void>();
+ private final HashMap<String, Collection<String>> ambiguousProcToFiles = new HashMap<String, Collection<String>>();
+
+ private final ArrayList<ErrorListener> errorListeners = new ArrayList<ErrorListener>();
+
+ public ErrorManager(FileErrorCollector fileErrorDetector, AmbiguityDetector ambiguityDetector)
+ {
+ this.fileErrorDetector = fileErrorDetector;
+ this.ambiguityDetector = ambiguityDetector;
+
+ initListeners();
+ }
+
+ private void initListeners()
+ {
+ fileErrorDetector.addErrorListener(new ErrorListener(){
+
+ @Override
+ public void errorsDetected(String fileName)
+ {
+ errorFiles.put(fileName, null);
+ notifyErrorDetected(fileName);
+ }
+
+ @Override
+ public void allErrorsCorrected(String fileName)
+ {
+ errorFiles.remove(fileName);
+
+ for (Collection<String> fileNames : ambiguousProcToFiles.values())
+ {
+ if (fileNames.contains(fileName))
+ return;
+ }
+ // no more errors or ambiguities found
+ notifyAllErrorsCorrected(fileName);
+ }
+ });
+
+ ambiguityDetector.addAmbiguityListener(new AmbiguityListener(){
+
+ @Override
+ public void ambiguityResolved(String procedureName, String fileName)
+ {
+ Collection<String> ambigFiles = ambiguousProcToFiles.get(procedureName);
+
+ ambigFiles.remove(fileName);
+
+ if (ambigFiles.size() == 0)
+ ambiguousProcToFiles.remove(procedureName);
+
+ // [this check is not necessary. if it was ambiguous, it did not have errors.]
+ //if (errorFiles.containsKey(fileName))
+ // return;
+ // No more file errors
+
+ for (Collection<String> fileNames : ambiguousProcToFiles.values())
+ {
+ if (fileNames.contains(fileName))
+ return;
+ }
+ // No more ambiguities for file
+
+ notifyAllErrorsCorrected(fileName);
+ }
+
+ @Override
+ public void ambiguityDetected(String procedureName, Map<String, Procedure> fileToProcedure)
+ {
+ ambiguousProcToFiles.put(procedureName, new ArrayList<String>(fileToProcedure.keySet()));
+ for (String fileName : fileToProcedure.keySet())
+ notifyErrorDetected(fileName);
+ }
+ });
+ }
+
+ @Override
+ public boolean hasErrors()
+ {
+ return errorFiles.size() > 0 || ambiguousProcToFiles.size() > 0;
+ }
+
+ @Override
+ public boolean hasErrors(String fileName)
+ {
+ if (errorFiles.containsKey(fileName))
+ return true;
+
+ for (Collection<String> conflictingFiles : ambiguousProcToFiles.values())
+ if (conflictingFiles.contains(fileName))
+ return true;
+ return false;
+ }
+
+ @Override
+ public Collection<ProcedureErrorMessage> getAllErrors()
+ {
+ ArrayList<ProcedureErrorMessage> allErrorMessages = new ArrayList<ProcedureErrorMessage>();
+ // Not the most efficient impl possible
+ allErrorMessages.addAll(fileErrorDetector.getAllErrors());
+ allErrorMessages.addAll(ambiguityDetector.getAllErrors());
+ return allErrorMessages;
+ }
+
+ @Override
+ public Collection<String> getAllErroneousFiles()
+ {
+ TreeMap<String, Void> allErrorFiles = new TreeMap<String, Void>();
+
+ for(String fileName : errorFiles.keySet())
+ allErrorFiles.put(fileName, null);
+
+ for(Collection<String> files : ambiguousProcToFiles.values())
+ for(String fileName : files)
+ allErrorFiles.put(fileName, null);
+
+ return allErrorFiles.keySet();
+ }
+
+ public Collection<String> getErrorMessages(String fileName)
+ {
+ ArrayList<String> messages = new ArrayList<String>();
+
+ for(ProcedureErrorMessage pem : getAllErrors())
+ if(pem.fileNames.contains(fileName))
+ messages.add(pem.toString());
+
+ return messages;
+ }
+
+ // These error event will directly update the gui => run on event dispatcher thread
+
+ @Override
+ public void addErrorListener(ErrorListener listener)
+ {
+ errorListeners.add(listener);
+ }
+
+ @Override
+ public void removeErrorListener(ErrorListener listener)
+ {
+ errorListeners.remove(listener);
+ }
+
+ private void notifyErrorDetected(final String fileName)
+ {
+ for (ErrorListener listener : errorListeners)
+ listener.errorsDetected(fileName);
+ }
+
+ private void notifyAllErrorsCorrected(final String fileName)
+ {
+ for (ErrorListener listener : errorListeners)
+ listener.allErrorsCorrected(fileName);
+ }
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/GlobalVariableTable.java b/logo/src/xlogo/kernel/userspace/GlobalVariableTable.java new file mode 100644 index 0000000..7d74560 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/GlobalVariableTable.java @@ -0,0 +1,73 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace;
+
+import java.util.HashMap;
+import java.util.Set;
+
+public class GlobalVariableTable
+{
+ /**
+ * All defined variables with their current value.
+ */
+ protected HashMap<String, String> globale;
+
+ public GlobalVariableTable()
+ {
+ globale = new HashMap<String, String>();
+ }
+
+ public Set<String> getVariables()
+ {
+ return globale.keySet();
+ }
+
+ public String getValue(String var)
+ {
+ return globale.get(var.toLowerCase());
+ }
+
+ public void define(String var, String value)
+ {
+ globale.put(var.toLowerCase(), value);
+ }
+
+ public void deleteVariable(String st)
+ {
+ globale.remove(st.toLowerCase());
+ }
+
+ /**
+ * Delete all Variables from the workspace
+ */
+ public void deleteAllVariables()
+ {
+ globale.clear();
+ }
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/ProcedureErrorMessage.java b/logo/src/xlogo/kernel/userspace/ProcedureErrorMessage.java new file mode 100644 index 0000000..2e2afc8 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/ProcedureErrorMessage.java @@ -0,0 +1,106 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import xlogo.Logo;
+import xlogo.kernel.userspace.procedures.ProcedureErrorType;
+
+/**
+ * This is used to report document structure errors
+ * or ambiguity errors, either within or among files.
+ * @author Marko Zivkovic
+ *
+ */
+public class ProcedureErrorMessage
+{
+ ProcedureErrorType type;
+ String procedureDescription;
+ Collection <String> fileNames;
+
+ /**
+ * The description may be either the name (if known) or the line, where the error was found.
+ * @param type
+ * @param procedureDescription
+ * @param fileName
+ */
+ public ProcedureErrorMessage(ProcedureErrorType type, String procedureDescription, String fileName)
+ {
+ this.type = type;
+ this.procedureDescription = procedureDescription;
+ this.fileNames = new ArrayList<String>();
+ this.fileNames.add(fileName);
+ }
+
+ /**
+ * This can be used for ambiguity messages
+ * @see #ProcedureErrorMessage(ProcedureErrorType, String, String)
+ */
+ public ProcedureErrorMessage(ProcedureErrorType type, String procedureDescription, Collection<String> fileNames)
+ {
+ this.type = type;
+ this.procedureDescription = procedureDescription;
+ this.fileNames = fileNames;
+ }
+
+ public ProcedureErrorType getErrorType()
+ {
+ return type;
+ }
+
+ public String getProcedureDescription()
+ {
+ return procedureDescription;
+ }
+
+ public Collection<String> getFileNames()
+ {
+ return fileNames;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ for (String fileName : fileNames)
+ {
+ sb.append(fileName);
+ sb.append(", ");
+ }
+ sb.delete(sb.length()-2, sb.length()-1);
+
+ sb.append(procedureDescription);
+ sb.append(": ");
+ sb.append(Logo.messages.getString(type.getDescription()));
+
+ return sb.toString();
+ }
+
+}
\ No newline at end of file diff --git a/logo/src/xlogo/kernel/userspace/PropertyListTable.java b/logo/src/xlogo/kernel/userspace/PropertyListTable.java new file mode 100644 index 0000000..7764d60 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/PropertyListTable.java @@ -0,0 +1,165 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace;
+
+import java.util.HashMap;
+import java.util.Set;
+
+public class PropertyListTable
+{
+
+ /**
+ * For all Property Lists
+ */
+ private HashMap<String, HashMap<String, String>> propList;
+
+ public PropertyListTable()
+ {
+ propList = new HashMap<String, HashMap<String,String>>();
+ }
+
+
+ /**
+ * This method adds in the property List called "name" a value for the
+ * corresponding key
+ *
+ * @param name
+ * The property List 's name
+ * @param key
+ * The key for the value to add
+ * @param value
+ * The value to add
+ */
+ public void addPropList(String name, String key, String value)
+ {
+ if (!propList.containsKey(name))
+ {
+ propList.put(name, new HashMap<String, String>());
+ }
+ propList.get(name).put(key, value);
+ }
+
+ /**
+ * This method removes a Property List
+ *
+ * @param name
+ * The property List 's name
+ */
+ public void removePropList(String name)
+ {
+ if (propList.containsKey(name))
+ {
+ propList.remove(name);
+ }
+ }
+
+ /**
+ * This method removes a couple (key, value) from a Property List
+ *
+ * @param name
+ * The property List 's name
+ * @param key
+ * The key to delete
+ */
+ public void removePropList(String name, String key)
+ {
+ if (propList.containsKey(name))
+ {
+ if (propList.get(name).containsKey(key))
+ propList.get(name).remove(key);
+ if (propList.get(name).isEmpty())
+ propList.remove(name);
+ }
+ }
+
+ /**
+ * This method returns a list that contains all couple key value
+ *
+ * @param name
+ * The Property List's name
+ * @return A list with all keys-values
+ */
+ public String displayPropList(String name)
+ {
+ if (propList.containsKey(name))
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[ ");
+ Set<String> set = propList.get(name).keySet();
+ for (String key : set)
+ {
+ sb.append(key);
+ sb.append(" ");
+ String value = propList.get(name).get(key);
+ if (value.startsWith("\""))
+ value = value.substring(1);
+ sb.append(value);
+ sb.append(" ");
+ }
+ sb.append("] ");
+ return sb.toString();
+ }
+ else
+ return "[ ] ";
+ }
+
+ /**
+ * This method return a value from a Property List
+ *
+ * @param name
+ * The Property List's name
+ * @param key
+ * The key for the chosen value
+ * @return The value for this key
+ */
+ public String getPropList(String name, String key)
+ {
+ if (!propList.containsKey(name)) { return "[ ]"; }
+ if (!propList.get(name).containsKey(key))
+ return "[ ]";
+ return propList.get(name).get(key);
+ }
+
+ /**
+ * Returns all defined Property List names
+ *
+ * @return A list with all Property List names
+ */
+ public Set<String> getPropListKeys()
+ {
+ return propList.keySet();
+ }
+
+ /**
+ * Delete all property Lists from the workspace
+ */
+ public void deleteAllPropertyLists()
+ {
+ propList.clear();
+ }
+}
diff --git a/logo/src/xlogo/kernel/userspace/UserSpace.java b/logo/src/xlogo/kernel/userspace/UserSpace.java new file mode 100644 index 0000000..d3b79d6 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/UserSpace.java @@ -0,0 +1,790 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were entirely written by Marko Zivkovic + */ + +package xlogo.kernel.userspace; + +import java.util.ArrayList; +import java.util.Collection; + +import xlogo.Logo; +import xlogo.interfaces.BroadcasterErrorFileContainer; +import xlogo.interfaces.X4SModeSwitcher; +import xlogo.interfaces.ErrorDetector.FileErrorCollector; +import xlogo.kernel.gui.GuiMap; +import xlogo.kernel.userspace.context.ContextManager; +import xlogo.kernel.userspace.context.LogoContext; +import xlogo.kernel.userspace.files.LogoFileContainer; +import xlogo.kernel.userspace.files.LogoFilesManager; +import xlogo.kernel.userspace.procedures.ExecutablesProvider; +import xlogo.kernel.userspace.procedures.Procedure; +import xlogo.kernel.userspace.procedures.ProceduresManager; +import xlogo.messages.MessageKeys; +import xlogo.messages.async.dialog.DialogMessenger; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * This is a facade for what was before called Workspace in XLogo, and much more. + * XLogo's Workspace had: + * <p> + * - All Defined Procedures <br> + * - All Global variables <br> + * - All GUI Objects (generated by a Logo program)<br> + * - All Property lists + * <p> + * The new "Workspace" does not resemble the old workspace at all, although it still provides access to these symbol tables. + * <p> + * New in XLogo4Schools: multiple Files. Procedures must be unique within all files of a context. + * If multiple procedures with the same name are defined <br> + * - within one file : The file will not be usable, until errors and ambiguities are fixed (like in XLogo), <br> + * - among multiple files : All of these files will not be executable, <br> //TODO or the ambiguous procedures will not be executed + * unless the ambiguity is resolved. + * <p> + * New are also the Contexts for user mode, contest mode, network mode. + * The contest mode is completely new. In XLogo, Network mode was implemented by replacing the whole workspace. + * Now only the Contexts with symbol tables are replaced. Why? Because we have an event driven architecture now. + * If the whole workspace (referring to XLogo's workspace, including event dispatchers) would be replaced, then all subscribers to the workspace would have to be re-mapped. + * By keeping the LogoFileManager and the ProceduresManager, subscribers to the user space (which are redirected to the managers) must not be re-mapped when a context switch happens. + * <p> + * (Option for future: Procedures can be qualified with + * {@code fileName.procedureName}. But : A dot is not a legal character for a + * name anymore) + * + * @author Marko Zivkovic + * + */ +public class UserSpace implements X4SModeSwitcher, LogoFileContainer, BroadcasterErrorFileContainer, + ExecutablesProvider, FileErrorCollector +{ + + /** + * This is included for every call that is delegated. This way all errors are caught and if we're lucky, + * The application can still be used or terminated normally. At least the user has discovered a new bug and he or she + * can report it. + * + * TODO write a log file? + * + * @param e + */ + public static void showErrorDialog(Exception e) + { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + + DialogMessenger.getInstance().dispatchError(Logo.messages.getString(MessageKeys.WS_ERROR_TITLE), + sw.toString()); + } + + private final ContextManager contextManager; // Switches context when modes change, notifies the other managers. & causes mode and clock events + private final LogoFilesManager filesManager; // handles file specific requests & causes file events + private final ProceduresManager proceduresManager; // handles procedure specific requests & causes defined/undefined events + private final ErrorManager errorManager; // handles error specific requests & causes error events + + public UserSpace() + { + contextManager = new ContextManager(); + proceduresManager = new ProceduresManager(contextManager); + filesManager = new LogoFilesManager(contextManager); + errorManager = new ErrorManager(filesManager, proceduresManager); + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * X4S MODE SWITCHER + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + @Override + public String getSerializedContext() + { + try + { + return contextManager.getSerializedContext(); + } + catch (Exception e) { showErrorDialog(e); } + return ""; + } + + @Override + public boolean isNetworkMode() + { + try + { + return contextManager.isNetworkMode(); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public boolean isRecordMode() + { + try + { + return contextManager.isRecordMode(); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public boolean isUserMode() + { + try + { + return contextManager.isUserMode(); + } + catch (Exception e) { showErrorDialog(e); } + return true; + } + + @Override + public void startRecordMode(String[] fileNames) throws IllegalArgumentException, IOException + { + try + { + contextManager.startRecordMode(fileNames); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void stopRecordMode() + { + try + { + contextManager.stopRecordMode(); + } + catch (Exception e) { showErrorDialog(e); } + } + + public void pushNetworkMode(String networkContext) + { + try + { + contextManager.pushNetworkMode(networkContext); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void popNetworkMode() + { + try + { + contextManager.popNetworkMode(); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void addModeChangedListener(ModeChangeListener listener) + { + try + { + contextManager.addModeChangedListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeModeChangedListener(ModeChangeListener listener) + { + try + { + contextManager.removeModeChangedListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void addBroadcastListener(MessageListener listener) + { + try + { + contextManager.addBroadcastListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeBroadcastListener(MessageListener listener) + { + try + { + contextManager.removeBroadcastListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * LOGO FILE CONTAINER + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + @Override + public String[] getFileNames() + { + try + { + return filesManager.getFileNames(); + } + catch (Exception e) { showErrorDialog(e); } + return new String[0]; + } + + @Override + public String readFile(String name) + { + try + { + return filesManager.readFile(name); + } + catch (Exception e) { showErrorDialog(e); } + return ""; + } + + @Override + public String getOpenFileName() + { + try + { + return filesManager.getOpenFileName(); + } + catch (Exception e) { showErrorDialog(e); } + return null; + } + + @Override + public boolean existsFile(String name) + { + try + { + return filesManager.existsFile(name); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public void createFile(String fileName) throws IOException + { + try + { + filesManager.createFile(fileName); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeFile(String fileName) + { + try + { + filesManager.removeFile(fileName); + } + catch (Exception e) { showErrorDialog(e); } + } + + /** + * The file is expected to exist on the file system and to have a .lgo extension + * @param filePath + * @throws IOException + */ + public void importFile(File filePath) throws IOException + { + try + { + filesManager.importFile(filePath); + } + catch (Exception e) { showErrorDialog(e); } + } + + /** + * @throws IOException + * @see {@link LogoFilesManager#exportFile(String, File)} + */ + public void exportFile(String fileName, File dest) throws IOException + { + try + { + filesManager.exportFile(fileName, dest); + } + catch (Exception e) { showErrorDialog(e); } + } + + /** + * @throws IOException + * @see {@link LogoFilesManager#exportFile(String, File, String)} + */ + public void exportFile(String fileName, File location, String targetName) throws IOException + { + try + { + filesManager.exportFile(fileName, location, targetName); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public String makeUniqueFileName(String base) + { + try + { + return filesManager.makeUniqueFileName(base); + } + catch (Exception e) { showErrorDialog(e); } + return null; + } + + @Override + public void renameFile(String oldName, String newName) + { + try + { + filesManager.renameFile(oldName, newName); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void openFile(String fileName) + { + try + { + filesManager.openFile(fileName); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void closeFile(String fileName) + { + try + { + filesManager.closeFile(fileName); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void writeFileText(String fileName, String content) throws IOException + { + try + { + filesManager.writeFileText(fileName, content); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void storeFile(String fileName) throws IOException + { + try + { + filesManager.storeFile(fileName); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void addFileListener(FileContainerChangeListener listener) + { + try + { + filesManager.addFileListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeFileListener(FileContainerChangeListener listener) + { + try + { + filesManager.removeFileListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + public String getLastEditedFileName() + { + try + { + return filesManager.getLastEditedFileName(); + } + catch (Exception e) { showErrorDialog(e); } + return null; + } + + public boolean isFilesListEditable() + { + try + { + return filesManager.isFilesListEditable(); + } + catch (Exception e) { showErrorDialog(e); } + return true; + } + + public boolean hasErrors(String fileName) + { + try + { + return filesManager.hasErrors(fileName) || proceduresManager.hasAmbiguousProcedures(fileName); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public void editAll() + { + try + { + filesManager.editAll(); + } + catch (Exception e) { showErrorDialog(e); } + } + + /** + * Resets the UserSpace by deleting all files (and procedures), all + * variables and all property lists. + * <p> + * Note : deleting all files will cause a chain of events. + */ + public void eraseAll() + { + try + { + filesManager.eraseAll(); // should remove all files and procedures and fire the right events + LogoContext context = contextManager.getContext(); + context.getGlobals().deleteAllVariables(); + context.getPropertyLists().deleteAllPropertyLists(); + context.getGuiMap().clear(); + } + catch (Exception e) { showErrorDialog(e); } + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * PROCEDURE CONTAINER + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + /** + * This is the implementation of the Logo Command define. + * Its effect has changed since we have multiple files now, but the semantics are preserved. + * Logo programs will behave exactly as before. <p> + * If the procedure is ambiguous, cannot decide which one to redefine => IllegalArgumentException <br> + * If the procedure is already defined once, that definition will be redefined in its original LogoFile. <br> + * If the procedure is not yet defined, a new File will be created "Generated Procedures" if does not yet exist, + * and the new procedure will be put there. + * + * @throws IllegalArgumentException if the procedure's name is ambiguous in the current context: I Don't know which one to redefine. + * @throws IllegalArgumentException if the procedure is not executable or it's owner does not exist in this context. + * @throws IOException - if the file "gerated procedure" could not be created in the context. + */ + @Override + public void defineProcedure(Procedure procedure) throws IOException + { + try + { + String procedureName = procedure.getName(); + if (proceduresManager.isProcedureAmbiguous(procedureName)) + throw new IllegalArgumentException("Attempt to redefine ambiguous procedure."); + + if (!isExecutable(procedureName)) + { + String fileName = Logo.messages.getString("ws.generated.procedure"); + if (!existsFile(fileName)) + createFile(fileName); + } + + proceduresManager.defineProcedure(procedure); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public Collection<Procedure> getExecutables() + { + try + { + return proceduresManager.getExecutables(); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<Procedure>(); + } + + @Override + public Procedure getExecutable(String procedureName) + { + try + { + return proceduresManager.getExecutable(procedureName); + } + catch (Exception e) { showErrorDialog(e); } + return null; + } + + @Override + public boolean isExecutable(String procedureName) + { + try + { + return proceduresManager.isExecutable(procedureName); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public void eraseProcedure(String procedureName) + { + try + { + proceduresManager.eraseProcedure(procedureName); + } + catch (Exception e) { showErrorDialog(e); } + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * The following symbol tables do not need a manager and no events + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + public GuiMap getGuiMap() + { + try + { + return contextManager.getContext().getGuiMap(); + } + catch (Exception e) { showErrorDialog(e); } + return new GuiMap(); + } + + public PropertyListTable getPropertyLists() + { + try + { + return contextManager.getContext().getPropertyLists(); + } + catch (Exception e) { showErrorDialog(e); } + return new PropertyListTable(); + } + + public GlobalVariableTable getGlobals() + { + try + { + return contextManager.getContext().getGlobals(); + } + catch (Exception e) { showErrorDialog(e); } + return new GlobalVariableTable(); + } + + @Override + public Collection<String> getAllProcedureNames() + { + try + { + return proceduresManager.getAllProcedureNames(); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<String>(); + } + + @Override + public Collection<String> getAllProcedureNames(String fileName) + { + try + { + return proceduresManager.getAllProcedureNames(fileName); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<String>(); + } + + @Override + public String getProcedureOwner(String procedureName) + { + try + { + return proceduresManager.getProcedureOwner(procedureName); + } + catch (Exception e) { showErrorDialog(e); } + return null; + } + + @Override + public void addProcedureMapListener(ProcedureMapListener listener) + { + try + { + proceduresManager.addProcedureMapListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeProcedureMapListener(ProcedureMapListener listener) + { + try + { + proceduresManager.removeProcedureMapListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + /* + * Errors & Ambiguities + */ + + /** + * conflicting w.r.t. ambiguity of their procedures + */ + @Override + public Collection<String> getAllConflictingFiles() + { + try + { + return proceduresManager.getAllConflictingFiles(); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<String>(); + } + + @Override + public boolean hasAmbiguousProcedures(String fileName) + { + try + { + return proceduresManager.hasAmbiguousProcedures(fileName); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public boolean isProcedureAmbiguous(String procedureName) + { + try + { + return proceduresManager.isProcedureAmbiguous(procedureName); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public void addAmbiguityListener(AmbiguityListener listener) + { + try + { + proceduresManager.addAmbiguityListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeAmbiguityListener(AmbiguityListener listener) + { + try + { + proceduresManager.removeAmbiguityListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public boolean hasErrors() + { + try + { + return errorManager.hasErrors(); + } + catch (Exception e) { showErrorDialog(e); } + return false; + } + + @Override + public Collection<ProcedureErrorMessage> getAllErrors() + { + try + { + return errorManager.getAllErrors(); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<ProcedureErrorMessage>(); + } + + @Override + public Collection<String> getAllErroneousFiles() + { + try + { + return errorManager.getAllErroneousFiles(); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<String>(); + + } + + @Override + public void addErrorListener(ErrorListener listener) + { + try + { + errorManager.addErrorListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + @Override + public void removeErrorListener(ErrorListener listener) + { + try + { + errorManager.removeErrorListener(listener); + } + catch (Exception e) { showErrorDialog(e); } + } + + public Collection<String> getErrorMessages(String fileName) + { + try + { + return errorManager.getErrorMessages(fileName); + } + catch (Exception e) { showErrorDialog(e); } + return new ArrayList<String>(); + } + +} diff --git a/logo/src/xlogo/kernel/userspace/context/ContextManager.java b/logo/src/xlogo/kernel/userspace/context/ContextManager.java new file mode 100644 index 0000000..fe5dab7 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/context/ContextManager.java @@ -0,0 +1,301 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.context;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Stack;
+
+import xlogo.interfaces.MessageBroadcaster;
+import xlogo.interfaces.X4SModeSwitcher;
+
+/**
+ * One of the four main roles in the {@link xlogo.kernel.userspace.UserSpace} <br>
+ * <b> The Contexts and Priorities and multiplicity</b>
+ * 1. UserContext [1] : default context, lowest priority, cannot be killed.
+ * 2. RecordContext [0..1] : medium priority, killing it will kill all networking contexts too.
+ * 3. NetworkContext [0..*] : highest priority, can be stacked.
+ *
+ * @author Marko
+ */
+public class ContextManager implements X4SModeSwitcher, ContextSwitcher, MessageBroadcaster
+{
+ private LogoContext currentContext;
+
+ private final UserContext userContext = new UserContext();
+ private RecordContext recordContext;
+ private final Stack<NetworkContext> networkStack = new Stack<NetworkContext>();
+
+ private MessageListener contextMessageListener;
+
+ public ContextManager()
+ {
+ currentContext = userContext;
+ initContextMessageListener();
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * CONTEXT PROVIDER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * After a context has been removed by stopXXXMode(), contextSwitch() will determine the next current context.
+ * It only peeks at the context collections, but does not modify them. Calling this does never harm,
+ * but after one of the context collections has been changed, it should be called.<br>
+ * It notifies ContextProviderListeners if the context has actually changed after calling this.
+ * <p>
+ * The policy for context switches is defines in the interface here : {@link X4SModeSwitcher}
+ * <p>
+ * Note, this should be called before the mode switch events, because we first want to completely context switch, before we change the mode.
+ * Generally always publish events after the event has actually occurred.
+ *
+ */
+ protected void contextSwitch()
+ {
+ LogoContext old = currentContext;
+
+ if (networkStack.size() > 0)
+ currentContext = networkStack.peek();
+ else
+ currentContext = recordContext != null ? recordContext : userContext;
+
+ if(old != currentContext)
+ notifyContextSwitched(currentContext);
+ }
+
+ /**
+ * returns the current context after the policy described in the in the interface {@link X4SModeSwitcher}
+ */
+ @Override
+ public LogoContext getContext()
+ {
+ return currentContext;
+ }
+
+ // Context switch : internal communication : no direct gui update, must not run on event dispatcher thread
+
+ private final ArrayList<ContextSwitchListener> contextSwitchListeners = new ArrayList<ContextSwitcher.ContextSwitchListener>();
+
+ @Override
+ public void addContextSwitchListener(ContextSwitchListener listener)
+ {
+ contextSwitchListeners.add(listener);
+ }
+
+ @Override
+ public void removeContextSwitchListener(ContextSwitchListener listener)
+ {
+ contextSwitchListeners.remove(listener);
+ }
+
+ public void notifyContextSwitched(LogoContext newContext)
+ {
+ for (ContextSwitchListener listener : contextSwitchListeners)
+ listener.contextSwitched(newContext);
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * MODE SWITCHER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ @Override
+ public String getSerializedContext()
+ {
+ return currentContext.toString();
+ }
+
+ @Override
+ public boolean isUserMode()
+ {
+ return currentContext instanceof UserContext;
+ }
+
+ @Override
+ public boolean isRecordMode()
+ {
+ return currentContext instanceof RecordContext;
+ }
+
+ @Override
+ public boolean isNetworkMode()
+ {
+ return currentContext instanceof NetworkContext;
+ }
+
+ /**
+ * A record mode can only be started from user mode. In other words,
+ * a record mode cannot be started, if there is another <b>record or network</b> mode active.
+ * @throws IllegalStateException If current mode is not user mode.
+ * @throws IllegalArgumentException If the fileNames are not well formed, null, or ambiguous
+ * @throws IOException If the record files could not be created => recording is impossible => record mode is impossible
+ */
+ @Override
+ public void startRecordMode(String[] fileNames) throws IllegalArgumentException, IOException
+ {
+ if (!isUserMode())
+ throw new IllegalStateException();
+
+ recordContext = new RecordContext(fileNames);
+ recordContext.addBroadcastListener(contextMessageListener);
+
+ contextSwitch();
+
+ notifyContestModeStarted();
+ }
+
+ /**
+ * This will first regularly kill all network contexts, one after the other. Listeners will be notified for every kill. <br>
+ * Afterwards it will kill the current record context. <br>
+ * When this call returns, current mode is user mode.
+ *
+ * @throws IllegalStateException If there is no recordContext available
+ */
+ @Override
+ public void stopRecordMode() throws IllegalStateException
+ {
+ if (recordContext == null)
+ return; // might be a quick double klick that causes this
+
+ while(isNetworkMode())
+ popNetworkMode();
+
+ recordContext = null;
+
+ contextSwitch();
+
+ notifyRecordModeStopped();
+ }
+
+ /**
+ * @throws IllegalArgumentException If serializedContext is corrupted
+ */
+ @Override
+ public void pushNetworkMode(String serializedContext) throws IllegalArgumentException
+ {
+ NetworkContext nc = new NetworkContext(serializedContext);
+ networkStack.push(nc);
+
+ contextSwitch();
+
+ if (networkStack.size() == 1)
+ notifyNetworkModeStarted();
+ }
+
+ /**
+ * This will kill the current network context.
+ * @throws IllegalStateException - if there is no network context to kill.
+ */
+ @Override
+ public void popNetworkMode() throws IllegalStateException
+ {
+ if (!isNetworkMode())
+ throw new IllegalStateException("There is no network context to kill.");
+
+ networkStack.pop();
+
+ contextSwitch();
+
+ if (!isNetworkMode())
+ notifyNetworkModeStopped();
+ }
+
+ // Mode Change Listeners : update GUI => run on event dispatcher thread
+
+ private ArrayList<ModeChangeListener> modeChangeListeners = new ArrayList<ModeChangeListener>();
+
+ @Override
+ public void addModeChangedListener(ModeChangeListener listener)
+ {
+ modeChangeListeners.add(listener);
+ }
+
+ @Override
+ public void removeModeChangedListener(ModeChangeListener listener)
+ {
+ modeChangeListeners.remove(listener);
+ }
+
+ private void notifyContestModeStarted()
+ {
+ for (ModeChangeListener listener : modeChangeListeners)
+ listener.recordModeStarted();
+ }
+
+ private void notifyRecordModeStopped()
+ {
+ for (ModeChangeListener listener : modeChangeListeners)
+ listener.recordModeStopped();
+ }
+
+ private void notifyNetworkModeStarted()
+ {
+ for (ModeChangeListener listener : modeChangeListeners)
+ listener.networkModeStarted();
+ }
+
+ private void notifyNetworkModeStopped()
+ {
+ for (ModeChangeListener listener : modeChangeListeners)
+ listener.networkModeStopped();
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * CONTEXT MESSAGE LISTENERS (used to broadcast clock events from record mode)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ private void initContextMessageListener()
+ {
+ contextMessageListener = new MessageListener(){
+
+ @Override
+ public void messageEvent(String source, String message)
+ {
+ for (MessageListener listener : broadcastListeners)
+ listener.messageEvent(source, message);
+ }
+ };
+ }
+
+ private final ArrayList<MessageListener> broadcastListeners = new ArrayList<MessageListener>();
+
+ @Override
+ public void addBroadcastListener(MessageListener listener)
+ {
+ broadcastListeners.add(listener);
+ }
+
+ @Override
+ public void removeBroadcastListener(MessageListener listener)
+ {
+ broadcastListeners.remove(listener);
+ }
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/context/ContextSwitcher.java b/logo/src/xlogo/kernel/userspace/context/ContextSwitcher.java new file mode 100644 index 0000000..e38c645 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/context/ContextSwitcher.java @@ -0,0 +1,43 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.context;
+
+
+public interface ContextSwitcher
+{
+ public LogoContext getContext();
+
+ public void addContextSwitchListener(ContextSwitchListener listener);
+
+ public void removeContextSwitchListener(ContextSwitchListener listener);
+
+ public interface ContextSwitchListener
+ {
+ public void contextSwitched(LogoContext newContext);
+ }
+}
diff --git a/logo/src/xlogo/kernel/userspace/context/LogoContext.java b/logo/src/xlogo/kernel/userspace/context/LogoContext.java new file mode 100644 index 0000000..15bdc1f --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/context/LogoContext.java @@ -0,0 +1,312 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.context;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import xlogo.Logo;
+import xlogo.interfaces.ProcedureMapper.ProcedureMapListener;
+import xlogo.kernel.gui.GuiMap;
+import xlogo.kernel.userspace.GlobalVariableTable;
+import xlogo.kernel.userspace.PropertyListTable;
+import xlogo.kernel.userspace.files.LogoFile;
+import xlogo.kernel.userspace.procedures.Procedure;
+import xlogo.storage.global.GlobalConfig;
+/**
+ * A LogoContext contains all the symbol tables for execution of Logo programs <p>
+ * Parts of this resemble the old Workspace class, but this has a new purpose and it is used differently.
+ * In XLogo4Schools, a LogoContext is only a container for a Logo environment - all the symbol tables.
+ * <p>
+ * Note: To be consistent, the execution stack should be included in the context too, but this would (for now) need too much work
+ * to refactor the existing interpreter. It is for sure something that should be done in the future, when the entire interpreter is refactored.
+ *
+ * @author Marko Zivkovic -
+ * @author Lo�c Le Coq - methods inherited from XLogo are marked with author-tag
+ */
+public class LogoContext
+{
+ private LogoFile openFile;
+
+ private final GlobalVariableTable globals = new GlobalVariableTable();
+
+ private final PropertyListTable propertyLists = new PropertyListTable();
+
+ private final Map<String, LogoFile> files = new HashMap<String, LogoFile>();
+
+ private final HashMap<String, HashMap<String, Procedure>> procedureTable = new HashMap<String, HashMap<String, Procedure>>();
+
+ // private Map<String, Procedure> executables = new HashMap<String,
+ // Procedure>();
+
+ private final GuiMap guiMap = new GuiMap();
+
+ public LogoContext() { }
+
+ /*
+ * Symbol table getters.
+ */
+
+ /**
+ * All the files in this context
+ * @return
+ */
+ public Map<String, LogoFile> getFilesTable()
+ {
+ return files;
+ }
+
+ /**
+ * All Executable procedures from all files. Procedures with equal names,
+ * from different files, will be included in the same list. <br>
+ * This Map is used to keep track of all defined procedures and to resolve
+ * name conflicts.
+ */
+ public HashMap<String, HashMap<String, Procedure>> getProcedureTable()
+ {
+ return procedureTable;
+ }
+
+ /**
+ * Global Logo variables
+ * @return
+ */
+
+ public GlobalVariableTable getGlobals()
+ {
+ return globals;
+ }
+
+ /**
+ * Logo property lists
+ * @return
+ */
+ public PropertyListTable getPropertyLists()
+ {
+ return propertyLists;
+ }
+
+ /**
+ * For all Gui Objects (Buttons, ComboBoxes...)
+ */
+ public GuiMap getGuiMap()
+ {
+ return guiMap;
+ }
+
+ /*
+ * Context dependent operations
+ */
+
+ public String[] getFileOrder()
+ {
+ return files.keySet().toArray(new String[files.size()]);
+ }
+
+ public void openFile(String fileName)
+ {
+ openFile = files.get(fileName);
+ }
+
+ public void closeFile()
+ {
+ openFile = null;
+ }
+
+ public LogoFile getOpenFile()
+ {
+ return openFile;
+ }
+
+ /**
+ * This is the preferred method to create a file within a context, because different contexts prefer different LogoFile configurations.
+ * @throws IllegalStateException if fileName already exists in the files table
+ * @throws IOException If the file could not be created on the file system and the text not written.
+ */
+ public void createFile(String fileName, String text) throws IOException
+ {
+ if (files.containsKey(fileName))
+ throw new IllegalStateException("Attempt to create already existing file.");
+
+ LogoFile file = LogoFile.createNewFile(fileName);
+ file.setText(text);
+ file.store();
+
+ files.put(fileName, file);
+ installListeners(file);
+ }
+
+ public void importFile(File path, String newFileName) throws IOException
+ {
+ if (files.containsKey(newFileName))
+ throw new IllegalStateException("Attempt to create already existing file.");
+
+ if (!path.isFile())
+ throw new IllegalArgumentException("The specified file does not exist : " + path.toString());
+
+ String extension = GlobalConfig.LOGO_FILE_EXTENSION;
+ if(!path.getName().endsWith(extension))
+ throw new IllegalArgumentException("Only accept " + extension + " files, but received : " + path.toString());
+
+ String fileName = path.getName();
+ fileName = path.getName().substring(0, fileName.length() - extension.length());
+
+ LogoFile file = LogoFile.importFile(path, newFileName);
+ files.put(newFileName, file);
+ installListeners(file);
+ }
+
+ /**
+ * Note: does not perform checks on validity of file names.
+ * @param oldName
+ * @param newName
+ */
+ public void renameFile(String oldName, String newName)
+ {
+ if (oldName.equals(newName))
+ return;
+
+ LogoFile file = files.get(oldName);
+
+ // must first re-map in files table because file.setFileName fires events
+ files.remove(oldName);
+ files.put(newName, file);
+
+ file.setFileName(newName);
+ }
+
+ private final ArrayList<ProcedureMapListener> procedureMapListener = new ArrayList<ProcedureMapListener>();
+
+ /**
+ * This should be used when a file is created or added to this context.
+ * Listeners that were previously added with {@link #addProcedureMapListener(ProcedureMapListener)} will be installed.
+ * @param file
+ */
+ public void installListeners(LogoFile file)
+ {
+ for (ProcedureMapListener listener : procedureMapListener)
+ file.addProcedureMapListener(listener);
+ }
+
+ /**
+ * This helps the Procedure Manager to register to ProcedureMap events from the logo files.
+ * The ProcedureManager does not need to be notified explicitly when a new file is created.
+ * @see #installListeners(LogoFile)
+ * @param listener
+ */
+ public void addProcedureMapListener(ProcedureMapListener listener)
+ {
+ procedureMapListener.add(listener);
+ for (LogoFile file : files.values())
+ file.addProcedureMapListener(listener);
+ }
+
+ public void removeProcedureMapListener(ProcedureMapListener listener)
+ {
+ procedureMapListener.remove(listener);
+ for (LogoFile file : files.values())
+ file.removeProcedureMapListener(listener);
+ }
+
+ /*
+ * MISC
+ */
+
+ /**
+ * That's the String that is sent via TCP, and interpreted by the receiver in {@link NetworkContext},
+ * using {@link #setWorkspace(String)}
+ * @author Lo�c Le Coq
+ * @author Marko Zivkovic
+ * refactored using the new data structures.
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for (String key : getGlobals().getVariables())
+ {
+ sb.append("-");
+ sb.append(key);
+ sb.append("\n");
+ sb.append(getGlobals().getValue(key));
+ sb.append("\n");
+ }
+
+ for (HashMap<String, Procedure> fileToProc : procedureTable.values())
+ {
+ if (fileToProc.size() != 1)
+ continue;
+
+ Procedure procedure = null;
+ for (Procedure uniqueProc : fileToProc.values())
+ procedure = uniqueProc; // retrieve the only procedure in fileToProc
+
+ sb.append(Logo.messages.getString("pour") + " " + procedure.name);
+ for (int j = 0; j < procedure.nbparametre; j++)
+ {
+ sb.append(" :" + procedure.variable.get(j));
+ }
+ sb.append("\n");
+ sb.append(procedure.instruction);
+ sb.append(Logo.messages.getString("fin"));
+ sb.append("\n\n");
+ }
+ return (new String(sb));
+ }
+
+ /**
+ * @return true : {@link FileContainerChangeListener} should be fired.
+ */
+ public boolean fireFileEvents()
+ {
+ return true;
+ }
+
+ /**
+ * @return true : {@link AmbiguityListener},
+ * {@link ExecutablesChangedListener},
+ * {@link ProceduresDefinedListener} should be fired.
+ */
+ public boolean fireProcedureEvents()
+ {
+ return true;
+ }
+
+ /**
+ * Default is true. Other contexts might override this.
+ * @return Whether it is allowed to create, delete, or rename files.
+ * @note : this is only a suggestion for the files manager and the gui, modification of the table is still possible
+ */
+ public boolean isFilesListEditAllowed()
+ {
+ return true;
+ }
+}
diff --git a/logo/src/xlogo/kernel/userspace/context/NetworkContext.java b/logo/src/xlogo/kernel/userspace/context/NetworkContext.java new file mode 100644 index 0000000..937e513 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/context/NetworkContext.java @@ -0,0 +1,206 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.context;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+
+import xlogo.Logo;
+import xlogo.kernel.userspace.files.LogoFile;
+
+/**
+ * The network context is very different compared to the other contexts. <br>
+ * 1. It parses its contents from a serialized context string ({@link #toString()}) <br>
+ * 2. Its files are created virtually ({@link xlogo.storage.Storable#isVirtual()}). They are gone when the network mode stops, leaving no trace. <br>
+ * 3. {@link #fireFileEvents()}} and {@link fireProcedureEvents()}} suggest the managers to not fire events,
+ * because the network files are not meant to be displayed in the editor.
+ * In XLogo this effect was achieved by setting the property affichable of procedures.
+ * @author Marko Zivkovic
+ */
+public class NetworkContext extends LogoContext
+{
+
+ public NetworkContext(String networkContext) throws IllegalArgumentException
+ {
+ super();
+ setContext(networkContext);
+ }
+
+ /**
+ * This is used to include a remote context into XLogo4Schools and allow remote
+ * procedure calls via tcp. XLogo had this implemented in the Workspace class.
+ * <p>
+ * Initially, in remote mode, the workspace was temporarily replaced by a new one.
+ * To indicate that the workspace with its procedures should not be displayed
+ * in the editor, Lo�c had added setAffichable(false), meaning not displayable.<br>
+ *
+ * Note that in XLogo, the workspace contained exactly one file. Therefore
+ * a simple swap in swap would do. However, in XLogo4Schools, we need more
+ * state information, and some of the state must be preserved.
+ * For example, in network mode, I do not want the user's procedures
+ * to be removed from the procedure list. I just want to disable the list.<br>
+ * <p>
+ * With this Network context, no events will be fired that would indicate,
+ * that some procedures or files have changed. But the ContextChangedListeners
+ * will be notified that we are now in network mode, thus they can disable
+ * the files list.
+ * <p>
+ * <p>
+ * Note that in XLogo, the workspace text has to be set in the editor just
+ * because analysProcedure() reads the Logo source code from there.
+ * In the network mode, It was actually not necessary to have it in the editor,
+ * because they didn't intend do display the text anyway (setAffichable(false)).
+ * setWorkspace and toString have probably been added late, so they just "hacked"
+ * that new property in.
+ * The existing "architecture" did not allow a cleaner extension of the
+ * system, so they must have added "affichable" for this only purpose.
+ * <p>
+ * In the current implementation, "affichable" is completely removed. <br>
+ * I regulate this effect by either firing events or not.
+ * <p>
+ * Note, parsing of the context is inherited from XLogo. Its implementation is very optimistic.
+ * It assumes that only well-formed strings are provided. Therefore it throws no actual exceptions.
+ * I added IllegalArgumentException to provide a more general interface,
+ * and to prepare clients for the future (?) when this parsing is re-implemented.
+ *
+ * @param app
+ * @param wp
+ * @author Marko Zivkovic, Loic
+ */
+ protected void setContext(String wp) throws IllegalArgumentException
+ {
+ StringReader sr = new StringReader(wp);
+ BufferedReader bfr = new BufferedReader(sr);
+ try
+ {
+ String input = parseVariables(bfr);
+
+ if (input != null)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(input);
+ sb.append("\n");
+ readerToBuilder(sb, bfr);
+
+ String vFileName = "netowork_file";
+ createFile(vFileName, "");
+ LogoFile file = getFilesTable().get(vFileName);
+ file.setText(sb.toString());
+ }
+ }
+ catch (IOException e)
+ {}
+ finally
+ {
+ try
+ {
+ bfr.close();
+ }
+ catch (IOException e)
+ {}
+ sr.close();
+ }
+ }
+
+ /**
+ * append all lines of br to sb
+ */
+ private void readerToBuilder(StringBuilder sb, BufferedReader br) throws IOException
+ {
+ String line = null;
+ while((line = br.readLine()) != null)
+ {
+ sb.append(line);
+ sb.append("\n");
+ }
+ sb.deleteCharAt(sb.length()-1);
+ }
+
+ private String parseVariables(BufferedReader bfr) throws IOException, IllegalArgumentException
+ {
+ String input = "";
+ while ((input = bfr.readLine()) != null)
+ {
+ if (!input.startsWith(Logo.messages.getString("pour")))
+ {
+ String var = input.substring(1); // - expected
+ String value = bfr.readLine();
+ getGlobals().define(var, value);
+ }
+ else
+ break;
+ }
+ return input;
+ }
+
+ /**
+ * Files created in network mode are virtual.
+ */
+ @Override
+ public void createFile(String fileName, String text) throws IllegalArgumentException
+ {
+ LogoFile vFile = LogoFile.createNewVirtualFile(fileName);
+ getFilesTable().put(fileName, vFile);
+
+ LogoFile file = LogoFile.createNewVirtualFile(fileName);
+ file.setText(text);
+
+ getFilesTable().put(fileName, file);
+
+ installListeners(file);
+ }
+
+ /**
+ * @return In network mode : false : {@link FileContainerChangeListener} events will not be fired.
+ */
+ public boolean fireFileEvents()
+ {
+ return false;
+ }
+
+ /**
+ * @return In network mode : false : {@link AmbiguityListener},
+ * {@link xlogo.interfaces.ExecutablesChangedListener},
+ * {@link xlogo.interfaces.ProceduresDefinedListener} events will not be fired.
+ */
+ public boolean fireProcedureEvents()
+ {
+ return false;
+ }
+
+ /**
+ * The Network context suggest that the user should not be allowed to create files from the gui.
+ * @see LogoContext#isFilesListEditAllowed()
+ */
+ @Override
+ public boolean isFilesListEditAllowed()
+ {
+ return false;
+ }
+}
diff --git a/logo/src/xlogo/kernel/userspace/context/RecordContext.java b/logo/src/xlogo/kernel/userspace/context/RecordContext.java new file mode 100644 index 0000000..48237de --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/context/RecordContext.java @@ -0,0 +1,146 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.context;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import xlogo.interfaces.MessageBroadcaster;
+import xlogo.kernel.userspace.files.RecordFile;
+
+/**
+ * The context for contest/record mode.
+ * When creating a new RecordContext, a number of RecordFiles are created, for each name provided in the constructor
+ * <p>
+ * Note that a RecordContext only works correctly with RecordFiles.
+ * Therefore FileManagers should always use context.createFile(); to add new files, and never put them directly into the files table.
+ * <p>
+ * Besides, RecordContext suggests to not create new files ({@link #isFilesListEditAllowed()}),
+ * but files can still be created by using Logo commands, such as define or load.
+ *
+ * @author Marko
+ */
+public class RecordContext extends LogoContext implements MessageBroadcaster
+{
+ private String[] fileOrder;
+
+ private MessageListener fileTimerListener;
+ private ArrayList<MessageListener> timerEventListeners = new ArrayList<MessageListener>();
+
+ public RecordContext(final String[] recordModeFileNames) throws IOException
+ {
+ super();
+ this.fileOrder = recordModeFileNames;
+ initFileTimerListener();
+ setupRecordFiles();
+ }
+
+ protected void setupRecordFiles() throws IOException
+ {
+ for(String fileName : fileOrder)
+ createFile(fileName, "");
+ }
+
+ private void initFileTimerListener()
+ {
+ fileTimerListener = new MessageListener(){
+
+ @Override
+ public void messageEvent(String source, String message)
+ {
+ for (MessageListener listener : timerEventListeners)
+ listener.messageEvent(source, message);
+ }
+ };
+ }
+
+ @Override
+ public void createFile(String fileName, String text) throws IOException
+ {
+ RecordFile file = RecordFile.createNewFile(fileName);
+
+ if (text != null && text.length() > 0)
+ {
+ file.setText(text);
+ file.store();
+ }
+
+ installListeners(file);
+ file.addBroadcastListener(fileTimerListener);
+
+ getFilesTable().put(fileName, file);
+ }
+
+ public void openFile(String fileName)
+ {
+ super.openFile(fileName);
+ RecordFile file = (RecordFile) getFilesTable().get(fileName);
+ file.startRecord();
+ }
+
+ @Override
+ public void closeFile()
+ {
+ RecordFile file = (RecordFile) getOpenFile();
+ file.pauseRecord();
+ super.closeFile();
+ }
+
+ @Override
+ public String[] getFileOrder()
+ {
+ // TODO must extend file order for command "define" [otherwise constant number of files in record mode]
+ // - although it's not really correct, no visible consequences in app => no priority ... program works just as well
+ return fileOrder;
+ }
+
+ /**
+ * The Record context suggest that the user should not be allowed to create files from the gui.
+ * @see LogoContext#isFilesListEditAllowed()
+ */
+ @Override
+ public boolean isFilesListEditAllowed()
+ {
+ return false;
+ }
+
+
+ @Override
+ public void addBroadcastListener(MessageListener listener)
+ {
+ timerEventListeners.add(listener);
+ }
+
+ @Override
+ public void removeBroadcastListener(MessageListener listener)
+ {
+ timerEventListeners.add(listener);
+ }
+
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/context/UserContext.java b/logo/src/xlogo/kernel/userspace/context/UserContext.java new file mode 100644 index 0000000..064e665 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/context/UserContext.java @@ -0,0 +1,191 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.context;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import xlogo.Logo;
+import xlogo.kernel.userspace.files.LogoFile;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.WSManager;
+import xlogo.storage.global.GlobalConfig;
+import xlogo.storage.user.UserConfig;
+
+public class UserContext extends LogoContext
+{
+
+ /**
+ * Load and parse all the files in current user's source directory. <br>
+ * This happens only once, in the constructor. <br>
+ * Refresh is currently not planned, but it would be easy to add.
+ *
+ * @param userDir
+ */
+ public UserContext()
+ {
+ loadUserFiles();
+ }
+
+ private void loadUserFiles()
+ {
+ UserConfig userConfig = WSManager.getUserConfig();
+
+ if (userConfig.isVirtual())
+ return;
+
+ File sourceDir = userConfig.getSourceDirectory();
+ if (!sourceDir.exists())
+ sourceDir.mkdirs();
+
+ if (!sourceDir.isDirectory())
+ {
+ DialogMessenger.getInstance().dispatchMessage(Logo.messages.getString("ws.error.title"),
+ Logo.messages.getString("ws.error.userdir.not.dir"));
+ return;
+ }
+
+ StringBuilder ioErrors = new StringBuilder();
+
+ for (String fileName : getLogoFileNamesFromDirectory(sourceDir))
+ {
+ String name = fileName.substring(0, fileName.length() - GlobalConfig.LOGO_FILE_EXTENSION.length());
+ userConfig.addFile(name);
+ try
+ {
+ LogoFile file = LogoFile.loadFile(name);
+ getFilesTable().put(file.getPlainName(), file);
+
+ }
+ catch (IOException e)
+ {
+ ioErrors.append(e.toString());
+ ioErrors.append("\n\n");
+ }
+ }
+
+ // must remove files from fileOrder that could not be found anymore.
+ for (String fileName : new ArrayList<String>(userConfig.getFileOrder()))
+ {
+ if (!getFilesTable().containsKey(fileName))
+ userConfig.getFileOrder().remove(fileName);
+ }
+
+ if (ioErrors.length() > 0)
+ {
+ DialogMessenger.getInstance().dispatchMessage(Logo.messages.getString("ws.error.title"),
+ Logo.messages.getString("ws.error.could.not.load.logo.files") + "\n" + ioErrors.toString());
+ }
+ }
+
+ /**
+ * Caller must make sure that newName does not already exist.
+ */
+ @Override
+ public void renameFile(String oldName, String newName)
+ {
+ super.renameFile(oldName, newName);
+ WSManager.getUserConfig().renameFile(oldName, newName);
+ }
+
+ @Override
+ public void createFile(String fileName, String text) throws IOException
+ {
+ /*
+ * Eager creation of files in file order list in user config.
+ */
+
+ if (!WSManager.getUserConfig().isVirtual())
+ super.createFile(fileName, text);
+ else
+ {
+ LogoFile file = LogoFile.createNewVirtualFile(fileName);
+ file.setText(text);
+ getFilesTable().put(fileName, file);
+ installListeners(file);
+ }
+ WSManager.getUserConfig().addFile(fileName);
+ }
+
+ @Override
+ public void importFile(File path, String newFileName)
+ {
+ try
+ {
+ super.importFile(path, newFileName);
+ }
+ catch (IOException e)
+ {
+ DialogMessenger.getInstance().dispatchError(MessageKeys.GENERAL_ERROR_TITLE, "Could not import file : \n" + e.toString());
+ }
+ WSManager.getUserConfig().addFile(newFileName);
+ }
+
+ private String[] getLogoFileNamesFromDirectory(File dir)
+ {
+ return dir.list(new FilenameFilter(){
+ public boolean accept(File file, String name)
+ {
+ return name.endsWith(".lgo");
+ }
+ });
+ }
+
+ @Override
+ public String[] getFileOrder()
+ {
+ /*
+ * Lazy deletion from file order list in user config.
+ */
+ ArrayList<String> list = new ArrayList<String>(WSManager.getUserConfig().getFileOrder());
+ Map<String,LogoFile> filesTable = getFilesTable();
+
+ if (filesTable.size() != list.size())
+ {
+ Iterator<String> iter = list.iterator();
+ String current;
+
+ while(iter.hasNext())
+ {
+ current = iter.next();
+ if(!filesTable.containsKey(current))
+ iter.remove();
+ }
+ }
+
+ return list.toArray(new String[list.size()]);
+ }
+
+
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/files/LogoFile.java b/logo/src/xlogo/kernel/userspace/files/LogoFile.java new file mode 100644 index 0000000..92fe23c --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/files/LogoFile.java @@ -0,0 +1,755 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.files;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import xlogo.Logo;
+import xlogo.interfaces.ErrorDetector;
+import xlogo.interfaces.ProcedureMapper;
+import xlogo.kernel.userspace.ProcedureErrorMessage;
+import xlogo.kernel.userspace.procedures.ExecutablesContainer;
+import xlogo.kernel.userspace.procedures.Procedure;
+import xlogo.kernel.userspace.procedures.Procedure.State;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.StorableDocument;
+import xlogo.storage.WSManager;
+import xlogo.storage.global.GlobalConfig;
+import xlogo.storage.user.UserConfig;
+import xlogo.storage.workspace.NumberOfBackups;
+import xlogo.storage.workspace.WorkspaceConfig;
+import xlogo.utils.Utils;
+
+/**
+ * This class holds the text file a user entered in the editor.
+ * It analyzes the text and maintains a symbol table for all defined procedures that live within it.
+ * <p>
+ * The file does never store itself implicitly, except for when it is created using {@link #createNewFile(String)} or renamed using {@link #setFileName(String)}
+ * In every other case, {@link #store()}} or {@link #storeCopyToFile(File)}} must be invoked explicitly.
+ * <p>
+ * The file's text can be set using {@link #setTextFromReader(BufferedReader)}} (preferred) or {@link #setText(String)}}.
+ * Both will try to parse the signature of all procedures using the constructor of {@link xlogo.kernel.userspace.procedures.Procedure}
+ *
+ * @author Marko Zivkovic, (Lo�c Le Coq's parsing of procedures is not recognizable anymore.)
+ *
+ */
+public class LogoFile extends StorableDocument implements ExecutablesContainer, ProcedureMapper, ErrorDetector
+{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1117062836862782516L;
+
+ /**
+ * UserConfig of the owner of this file
+ */
+ private UserConfig userConfig;
+
+ /**
+ * Contains only executable procedures
+ */
+ private Map<String, Procedure> executables;
+
+ /**
+ * Contains all procedures, no matter what the state is.
+ * The order of the list is relevant to reproduce the editor text after the Logo command 'eraseprocedure'
+ * (after {@link #deleteProcedure(String)}})
+ */
+ private ArrayList<Procedure> allProcedures;
+
+ /**
+ * A flag that indicated whether the last parsing ended with errors or ambiguities
+ */
+ private boolean hasError;
+
+ /*
+ * CONSTRUCTOR & STATIC CONSTRUCTORS, FILE LOADERS
+ */
+
+ /**
+ * The LogoFile automatically sets its location to the current user's src directory, if that user is not virtual.
+ * @param fileName
+ * @throws IllegalArgumentException see : {@link Storable#setFileName()}
+ */
+ protected LogoFile(String fileName) throws IllegalArgumentException
+ {
+ super();
+ this.userConfig = WSManager.getUserConfig();
+ if (!userConfig.isVirtual())
+ setLocation(userConfig.getSourceDirectory());
+ setFileName(fileName);
+ executables = new HashMap<String, Procedure>();
+ allProcedures = new ArrayList<Procedure>();
+ }
+
+ public static LogoFile createNewVirtualFile(String fileName)
+ {
+ LogoFile file = null;
+ try
+ {
+ file = new LogoFile(fileName);
+ file.makeVirtual();
+ }
+ catch (IllegalArgumentException ignore) { }
+ return file;
+ }
+ /**
+ * Create a new file and store it in the user's source directory.
+ * @throws IOException
+ * @throws IllegalArgumentException
+ */
+ public static LogoFile createNewFile(String fileName) throws IOException, IllegalArgumentException
+ {
+ LogoFile file = new LogoFile(fileName);
+ file.setupFileSystem();
+ return file;
+ }
+
+ /**
+ * Load the specified file from the user's source directory and parse procedure structures.
+ * @param fileName - without extension
+ * @return
+ * @throws IOException
+ */
+ public static LogoFile loadFile(String fileName) throws IOException
+ {
+ UserConfig userConfig = WSManager.getUserConfig();
+ File path = userConfig.getLogoFilePath(fileName);
+ String text = Utils.readLogoFile(path.toString());
+ LogoFile file = new LogoFile(fileName);
+ file.setText(text);
+ if (userConfig.isVirtual())
+ file.makeVirtual();
+ return file;
+ }
+
+ /**
+ * Open any file on the file system and integrate it in the UserSpace.
+ * The file will be stored and made visible under the specified newFileName
+ * @param file
+ * @param newFileName
+ * @throws IOException
+ */
+ public static LogoFile importFile(File path, String newFileName) throws IOException
+ {
+ String text = Utils.readLogoFile(path.toString());
+ LogoFile file = new LogoFile(newFileName);
+ file.setText(text);
+ if (WSManager.getUserConfig().isVirtual())
+ file.makeVirtual();
+ file.store();
+ return file;
+ }
+
+ protected UserConfig getUserConfig()
+ {
+ return userConfig;
+ }
+ /**
+ * This assumes that the file name is well formed. No additional checks are performed
+ * Rename this LogoFile and the file on the file system, if it exists there. Notify all FileChangeListeners.
+ * This accepts name with or without .lgo extension.
+ * @param newFileName - without extension
+ */
+ @Override
+ public void setFileName(String newFileName)
+ {
+ if (newFileName == null || newFileName.length() == 0)
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.EMPTY_NAME));
+ return;
+ }
+
+ if (!Storable.checkLegalName(newFileName))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME) + " : " + newFileName);
+ return;
+ }
+
+ String oldPlainName = getPlainName();
+ super.setFileName(newFileName);
+ String newPlainName = getPlainName();
+
+ if (oldPlainName != null)
+ notifyRenamed(oldPlainName, newPlainName);
+ }
+
+ @Override
+ public String getFileNameExtension()
+ {
+ return GlobalConfig.LOGO_FILE_EXTENSION;
+ }
+
+ private void notifyRenamed(String oldName, String newName)
+ {
+ for(ProcedureMapListener listener : procedureMapListeners)
+ listener.ownerRenamed(oldName, newName);
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * STORE & LOAD FILE
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * If this is not virtual, create this file on the file system and create a backup folder for it.
+ * @throws IOException
+ */
+ protected void setupFileSystem() throws IOException
+ {
+ if (isVirtual())
+ return;
+
+ File source = getFilePath();
+ File backupFolder = userConfig.getFileBackupDir(getPlainName());
+
+ if (!source.getParentFile().exists())
+ source.getParentFile().mkdirs();
+
+ if (!backupFolder.exists())
+ backupFolder.mkdirs();
+
+ storeCopyToFile(source);
+ }
+
+ /**
+ * If this is not virtual, store the file in the source folder of the UserSpace, <br>
+ * and another copy in the backup folder, if this is required by {@link WorkspaceConfig#getNumberOfBackups()}.
+ */
+ @Override
+ public void store() throws IOException
+ {
+ super.store();
+ if (isVirtual())
+ return;
+ doBackup();
+ }
+
+ @Override
+ public void delete()
+ {
+ super.delete();
+ Collection<String> procedures = new ArrayList<String>(executables.keySet());
+ executables.clear();
+ allProcedures.clear();
+ notifyDeleted(procedures);
+ }
+
+
+ /**
+ * Store a backup copy of this file.
+ * If the number of maximally allowed backups is exceeded,
+ * delete the oldest copies until the number of backups equals the limit
+ * defined by {@link WorkspaceConfig#getNumberOfBackups()}}
+ * @throws IOException
+ */
+ private void doBackup() throws IOException
+ {
+ WorkspaceConfig wc = WSManager.getInstance().getWorkspaceConfigInstance();
+ NumberOfBackups nob = wc.getNumberOfBackups();
+
+ File backupFile = userConfig.getBackupFilePath(getPlainName());
+ File backupFolder = backupFile.getParentFile();
+ if (!backupFolder.exists())
+ backupFolder.mkdirs();
+
+ if (nob != NumberOfBackups.NO_BACKUPS)
+ storeCopyToFile(backupFile);
+
+ if (nob == NumberOfBackups.INFINITE)
+ return;
+
+ int max = nob.getNumber(); // max is >= 0
+ // Assume no outer manipulation of that directory
+ File[] backups = backupFolder.listFiles();
+
+ int actual = backups.length;
+ if (actual <= max)
+ return;
+
+ // must delete the oldest backups
+ Arrays.sort(backups, new Comparator<File>(){
+ public int compare(File f1, File f2)
+ {
+ return f2.getName().compareTo(f1.getName().toString());
+ }
+ });
+
+ while (actual > max)
+ {
+ actual--;
+ backups[actual].delete();
+ }
+ }
+
+ /**
+ * The file path of this LogoFile in the source directory.
+ */
+ @Override
+ public File getFilePath()
+ {
+ if (super.getFilePath() != null)
+ return super.getFilePath();
+ return userConfig.getLogoFilePath(getPlainName());
+ }
+
+ @Override
+ public File getLocation()
+ {
+ if (super.getLocation() != null)
+ return super.getLocation();
+ return userConfig.getSourceDirectory();
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * SERIALIZATION AND DESERIALIZATION
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ @Override
+ protected String generateText()
+ {
+ StringBuilder text = new StringBuilder();
+
+ for(Procedure proc : allProcedures)
+ {
+ text.append(proc.getText());
+ text.append("\n");
+ }
+
+ return text.toString();
+ }
+
+ /**
+ * Changes made 21.6.2013 and July 2013
+ * <p>
+ * In XLogo, this was {@code Editor.analyseprocedure()}
+ * <p><p>
+ * <b>Refactored:</b><br>
+ * Initially all that happens in
+ * <li> {@link #setText(String)}
+ * <li> {@link #parseText(BufferedReader)}
+ * <li> {@link #nextProcedure(BufferedReader)}
+ * <li> {@link Procedure#Procedure() }
+ * <li> {@link #untilEnd() }<br>
+ * was composed into one big and unreadable procedure {@code Editor.analyseprocedure()}.
+ * Note that the Editor (a GUI Controller) was responsible to parse text.
+ * {@code Editor.analyseprocedure()} took the text it was analyzing from the Editor's text component directly.
+ * Thus, whenever a procedure was programmatically defined, or if a workspace was received from the network,
+ * the text had to be written to the editor first before {@code Editor.analyseprocedure()} was called.<p>
+ * Note that in the networking case, the received text was never meant to be displayed.
+ * In that case the Editor served merely as a temporary container such that analyseProcedure() could read the text from it.
+ * This was the only reason why the property "affichable" (displayable) was added to so many classes.
+ *
+ * <p><p>
+ * <b>New Mechanism:</b><br>
+ * In XLogo, as soon as an error was found in the document, an exception was thrown and displayed to the user. <br>
+ * The new approach is to first split the document wherever a line starts with a token 'end'.
+ * <p>
+ * [#belongs to procedure 1<br>
+ * ... <br>
+ * end][#belongs to procedure 2 <br>
+ * ... <br>
+ * end] ...
+ * <p>
+ * These parts of the document are given to the constructor {@code Procedure#Procedure(String)},
+ * so the procedure can maintain its own state
+ * <br>
+ * Based on the type of errors, a Procedure can now detect several errors at a time and report them.
+ * The LogoFile can then report all errors that have been collected from its procedures.
+ * This approach allows to give more precise error messages to the user.
+ * Example: It is now possible to say which procedure is missing an 'end'
+ * <br>
+ * In the new implementation, a Procedure is not necessarily executable.
+ * Whether it is executable, can be read from its state {@link Procedure.State}.
+ * Its state can be
+ * <li> UNINITIALIZED
+ * <li> EXECUTABLE
+ * <li> COMMENT_ONLY (for white space and comments at the end of the document)
+ * <li> ERROR
+ * <li> AMBIGUOUS_NAME <br>
+ * <p>
+ * Only EXECUTABLE procedures are included in the procedureTable of the {@link xlogo.kernel.userspace.context.LogoContext},
+ * but all procedures are maintained by LogoFile.
+ * @param str
+ * @throws DocumentStructureException
+ * @throws IOException
+ */
+ @Override
+ protected void parseText(BufferedReader br)
+ {
+ /*
+ * Keep old procedures before reset of procedure tables.
+ * procedures that remain in the end, will count as deleted.
+ * procedures that existed before, but have errors now, count as deleted.
+ */
+ HashMap<String, Void> deleted = new HashMap<String, Void>();
+ for (Procedure proc : executables.values())
+ deleted.put(proc.getName(), null);
+
+ /*
+ * Must notify that all old executables are deleted as soon as a single procedure has an error,
+ * We want the whole file to be not executable when there exists an error
+ */
+ Collection<String> oldExecutables = new ArrayList<String>(executables.keySet());
+
+ /*
+ * We don't want the procedures to become ordered by creation time in the editor.
+ * The Logo command "define" was affected by this change, hence it was adapted to work as before.
+ * <p>
+ * Because we delete all the procedures from the tables [unlike XLogo] every time before reading the file,
+ * the procedures will be stored in the order in which the user defined them last.
+ */
+ resetProcedureTables(); // Added by Marko Zivkovic, 21.6.2013
+
+ // When the file is empty, it has no errors...
+ hasError = false;
+
+ try
+ {
+ while (br.ready()) // next procedure
+ {
+ Procedure proc;
+ String procedureText = untilEnd(br);
+ if (procedureText.equals(""))
+ break;
+ proc = new Procedure(procedureText);
+ proc.setOwnerName(getPlainName());
+
+ if (proc.getState() == State.EXECUTABLE)
+ {
+ deleted.remove(proc.getName());
+ }
+ addProcedure(proc);
+
+ if(proc.getState() == State.ERROR || proc.getState() == State.AMBIGUOUS_NAME)
+ hasError = true;
+ }
+ }
+ catch (IOException e){} // This should not happen, because no actual IO happens
+ finally { try { br.close(); } catch (IOException e) { } }
+
+ if(hasError)
+ {
+ notifyDeleted(oldExecutables);
+ return;
+ }
+
+ if (deleted.size() > 0)
+ notifyDeleted(deleted.keySet());
+
+ if (executables.size() > 0)
+ notifyDefined(executables.keySet());
+ }
+
+ /**
+ * @return String until the token 'end' is found on a line, or until the end of the BufferedReader
+ * @throws IOException
+ */
+ private static String untilEnd(BufferedReader br) throws IOException
+ {
+ String end = Logo.messages.getString("fin").toLowerCase();
+ StringBuffer text = new StringBuffer();
+ String line;
+
+ while (br.ready())
+ {
+ line = br.readLine();
+ if (line == null)
+ break;
+ else if (line.trim().toLowerCase().equals(end))
+ {
+ text.append(end);
+ break;
+ }
+ else
+ text.append(line + "\n");
+ }
+
+ return text.toString();
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * PROCEDURE CONTAINER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * Note: does not notify <br>
+ * Delete all procedures
+ */
+ private void resetProcedureTables()
+ {
+ allProcedures.clear();
+ executables.clear();
+ invalidateText();
+ setText(null);
+ }
+
+ /**
+ * Implementation of the Logo Command "define". <br>
+ * FileChangeListeners are notified.
+ * <p>
+ * In XLogo, the command define had no effect, when an error was detected while parsing.
+ * The same is true here, because an IllegalStateException is thrown if procedure is not executable.
+ * <p>
+ * In XLogo4Schools, to preserve semantics, we create a {@link Procedure} using its normal constructor and then check for errors.
+ * If errors exist in the procedure text, the procedure should not be defined in its destined file either.
+ * The responsibility whether a procedure is added to a file lies therefore in the interpreter.
+ * <p>
+ * Existing procedures with the same name are just redefined, as in XLogo.
+ * <p>
+ * @param procedure Expects an executable procedure.
+ * @throws IllegalStateException - if procedure is not Executable or its name is ambiguous in this file.
+ */
+ @Override
+ public void defineProcedure(Procedure procedure)
+ {
+ if (procedure.getState() != State.EXECUTABLE)
+ throw new IllegalStateException("Attempt to define procedure which is not executable.");
+
+ Procedure other = executables.get(procedure.name);
+
+ invalidateText();
+
+ if (other != null)
+ {
+ if (other.getState() == State.AMBIGUOUS_NAME)
+ throw new IllegalStateException("Attempt to redefine ambiguous procedure.");
+
+ other.redefine(procedure);
+
+ }else
+ {
+ allProcedures.add(procedure);
+ executables.put(procedure.name, procedure);
+ }
+ notifyDefined(procedure.getName());
+ }
+
+ /**
+ * This is for the Logo command 'eraseprocedure'
+ * @param name
+ * @throws IllegalArgumentException
+ */
+ @Override
+ public void eraseProcedure(String name)
+ {
+ Procedure proc = getExecutable(name);
+ if(proc == null)
+ throw new IllegalStateException("Attempt to erase procedure which exists not.");
+ allProcedures.remove(proc);
+ executables.remove(name);
+ invalidateText();
+ notifyDeleted(proc.getName());
+ }
+
+ /**
+ * Note: Does not notify listeners! <br>
+ * Semantics: If more than one procedures with the same name are defined in a document,
+ * all are marked ambiguous. The first one is kept in the executables list to track ambiguity.
+ * @param pr
+ */
+ protected void addProcedure(Procedure pr)
+ {
+ if (pr.getState() == State.EXECUTABLE)
+ {
+ Procedure other = executables.get(pr.name);
+
+ if(other != null)
+ {
+ other.makeAmbiguous();
+ pr.makeAmbiguous();
+ }
+ else
+ executables.put(pr.name, pr);
+ }
+ allProcedures.add(pr);
+ invalidateText();
+ }
+
+ @Override
+ public Procedure getExecutable(String name)
+ {
+ return executables.get(name);
+ }
+
+ /**
+ * @param name
+ * @return Whether an executable procedure with the specified name exists
+ */
+ @Override
+ public boolean isExecutable(String name)
+ {
+ return executables.get(name) != null;
+ }
+
+ @Override
+ public Collection<Procedure> getExecutables()
+ {
+ if (hasErrors())
+ return new ArrayList<Procedure>();
+ return executables.values();
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * ERROR DETECTOR
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ @Override
+ public boolean hasErrors()
+ {
+ return hasError;
+ }
+
+ public Collection<ProcedureErrorMessage> getAllErrors()
+ {
+ ArrayList<ProcedureErrorMessage> allErrors = new ArrayList<ProcedureErrorMessage>();
+ for(Procedure proc : allProcedures)
+ {
+ for (xlogo.kernel.userspace.procedures.ProcedureErrorType e : proc.getErrors())
+ {
+ String description = proc.getName();
+ if (description == null)
+ {
+ description = proc.getText().length() < 100 ?
+ proc.getText() :
+ proc.getText().substring(0, 100) + "...";
+ }
+
+ allErrors.add(new ProcedureErrorMessage(e, description, getPlainName()));
+ }
+ }
+ return allErrors;
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * PROCEDURE MAPPER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * Only executables.
+ * If the file has errors, no procedure is returned.
+ */
+ @Override
+ public Collection<String> getAllProcedureNames()
+ {
+ if (hasErrors())
+ return new ArrayList<String>();
+
+ ArrayList<String> procedureNames = new ArrayList<String>();
+
+ for (Procedure p : executables.values())
+ procedureNames.add(p.getName());
+
+ return procedureNames;
+ }
+
+ @Override
+ public Collection<String> getAllProcedureNames(String fileName)
+ {
+ if (fileName.equals(getPlainName()))
+ return getAllProcedureNames();
+ return null;
+ }
+
+ /**
+ * Behaves similar like contains(). If the procedure is in the file's executable list, then returns this file's plainName. Otherwise null.
+ */
+ @Override
+ public String getProcedureOwner(String procedureName)
+ {
+ if (executables.containsKey(procedureName))
+ return getPlainName();
+ return null;
+ }
+
+ // Procedure Map Listeners
+
+ private final ArrayList<ProcedureMapListener> procedureMapListeners = new ArrayList<ProcedureMapListener>();
+
+ @Override
+ public void addProcedureMapListener(ProcedureMapListener listener)
+ {
+ procedureMapListeners.add(listener);
+
+ if(executables.size() > 0)
+ notifyDefined(executables.keySet()); // TODO hmmm
+ }
+
+ @Override
+ public void removeProcedureMapListener(ProcedureMapListener listener)
+ {
+ procedureMapListeners.remove(listener);
+ }
+
+ protected void notifyDefined(Collection<String> procedures)
+ {
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.defined(getPlainName(), procedures);
+ }
+
+ protected void notifyDefined(String procedure)
+ {
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.defined(getPlainName(), procedure);
+ }
+
+ protected void notifyDeleted(Collection<String> collection)
+ {
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.undefined(getPlainName(), collection);
+ }
+
+ protected void notifyDeleted(String procedure)
+ {
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.undefined(getPlainName(), procedure);
+ }
+
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/files/LogoFileContainer.java b/logo/src/xlogo/kernel/userspace/files/LogoFileContainer.java new file mode 100644 index 0000000..9c077a9 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/files/LogoFileContainer.java @@ -0,0 +1,39 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.files;
+
+import xlogo.interfaces.BasicFileContainer;
+
+
+public interface LogoFileContainer extends BasicFileContainer
+{
+ /**
+ * Logo Command implementation
+ */
+ public void editAll();
+}
diff --git a/logo/src/xlogo/kernel/userspace/files/LogoFilesManager.java b/logo/src/xlogo/kernel/userspace/files/LogoFilesManager.java new file mode 100644 index 0000000..7a54902 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/files/LogoFilesManager.java @@ -0,0 +1,560 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.files;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+
+import xlogo.Logo;
+import xlogo.interfaces.ErrorDetector.FileErrorCollector;
+import xlogo.kernel.userspace.ProcedureErrorMessage;
+import xlogo.kernel.userspace.context.ContextSwitcher;
+import xlogo.kernel.userspace.context.LogoContext;
+import xlogo.kernel.userspace.context.ContextSwitcher.ContextSwitchListener;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.global.GlobalConfig;
+
+/**
+ * This Manager is completely new, because XLogo did not support multiple files. <br>
+ * During the requirements analysis, we have decided to maintain a global scope for procedures.
+ * That means a procedure defined in file A is visible in file B.
+ * <p>
+ * If we find during testing that the global scope is confusing for children and it leads to many ambiguity conflicts,
+ * then the current architecture allows to easily switch to file-wide scope. Instead of retrieving executables from the context's procedure table,
+ * we can directly retrieve them from the currently open/active file.
+ *
+ * @author Marko Zivkovic
+ */
+public class LogoFilesManager implements LogoFileContainer, FileErrorCollector
+{
+ private final ContextSwitcher contextProvider;
+ private LogoContext context;
+
+ private final ArrayList<FileContainerChangeListener> fileListeners = new ArrayList<FileContainerChangeListener>();
+
+ public LogoFilesManager(ContextSwitcher contextProvider)
+ {
+ this.contextProvider = contextProvider;
+ initContextSwitchListener();
+ setContext(contextProvider.getContext());
+ }
+
+ private void initContextSwitchListener()
+ {
+ contextProvider.addContextSwitchListener(new ContextSwitchListener(){
+ @Override
+ public void contextSwitched(LogoContext newContext)
+ {
+ setContext(newContext);
+ }
+ });
+ }
+
+ private void setContext(LogoContext newContext)
+ {
+ LogoContext old = context;
+ context = newContext;
+
+ LogoFile openFile = newContext.getOpenFile();
+ if (openFile != null)
+ closeFile(openFile.getPlainName());
+
+ if (newContext.fireFileEvents()) // Example : Network context does not change GUI, only internal change => no events
+ {
+ if (old != null && old.fireFileEvents())
+ for(LogoFile file : old.getFilesTable().values())
+ notifyFileRemoved(file.getPlainName());
+
+ for (String fileName : newContext.getFileOrder())
+ {
+ notifyFileAdded(fileName);
+ if (context.getFilesTable().get(fileName).hasErrors())
+ notifyErrorsDetected(fileName);
+ }
+ }
+
+ if (old == null || old.isFilesListEditAllowed() != newContext.isFilesListEditAllowed())
+ notifyRightsChanged();
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * X4S Specific features and Logo command implementations
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * The implementation of the Logo command {@code editall} or {@code edall} <br>
+ * In XLogo4Schools, we cannot open all files simultaneously to show all procedures. Instead, editall opens the file that was edited last.
+ */
+ public void editAll()
+ {
+ String fileName = getLastEditedFileName();
+ if (fileName == null)
+ return;
+ openFile(fileName);
+ }
+
+ @Override
+ public void importFile(File filePath) throws IOException
+ {
+ String name = filePath.getName().substring(0,
+ filePath.getName().length()
+ - GlobalConfig.LOGO_FILE_EXTENSION.length());
+
+ if(existsFile(name))
+ name = makeUniqueFileName(name);
+ context.importFile(filePath, name);
+ notifyFileAdded(name);
+ }
+
+ /**
+ * If file is a directory, the exported file will be named fileName.
+ * Otherwise the Logo-file will be exported to the file specified by dest
+ * @param fileName
+ * @param dest
+ * @throws IOException
+ */
+ public void exportFile(String fileName, File dest) throws IOException
+ {
+
+ if (dest.isDirectory())
+ exportFile(fileName, dest, fileName);
+ else
+ {
+ File parent = dest.getParentFile();
+ String targetName = dest.getName();
+ exportFile(fileName, parent, targetName);
+ }
+ }
+
+ /**
+ * @param fileName - of a file in the current context
+ * @param location - an existing directory on the file system
+ * @param targetName - the exported file's name
+ * @throws IOException
+ */
+ public void exportFile(String fileName, File location, String targetName) throws IOException
+ {
+ LogoFile file = context.getFilesTable().get(fileName);
+
+ if(file == null)
+ throw new IllegalArgumentException("The specified fileName does not exist in the context.");
+
+ if (!location.isDirectory())
+ throw new IllegalArgumentException("The specified location does not exist : " + location.toString());
+
+ String extendedName = targetName;
+
+ if(extendedName == null || extendedName.length() == 0)
+ extendedName = fileName;
+
+ String extension = GlobalConfig.LOGO_FILE_EXTENSION;
+
+ if(!extendedName.endsWith(extension))
+ extendedName += extension;
+
+ File target = new File(location.toString() + File.separator + extendedName);
+ file.storeCopyToFile(target);
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * LOGO FILE CONTAINER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ @Override
+ public String[] getFileNames()
+ {
+ return context.getFileOrder();
+ }
+
+ @Override
+ public void createFile(String fileName) throws IOException
+ {
+ context.createFile(fileName, "");
+ notifyFileAdded(fileName);
+ }
+
+ @Override
+ public void writeFileText(String fileName, String content)
+ {
+ LogoFile file = context.getFilesTable().get(fileName);
+
+ if (file == null)
+ throw new IllegalStateException("Attempt to write to inexistent file.");
+
+ boolean hadErrors = file.hasErrors();
+
+ file.setText(content);
+
+ if (file.hasErrors())
+ notifyErrorsDetected(fileName); // notify anyway
+ else if (hadErrors)
+ notifyErrorsCorrected(fileName);
+ }
+
+ @Override
+ public void storeFile(String fileName) throws IOException
+ {
+ context.getFilesTable().get(fileName).store();
+ }
+
+ /**
+ * The file is also deleted from the file system
+ */
+ @Override
+ public void removeFile(String fileName)
+ {
+ LogoFile file = context.getFilesTable().get(fileName);
+ file.delete();
+ context.getFilesTable().remove(fileName);
+ notifyFileRemoved(fileName);
+ }
+
+ /**
+ * Deletes all files from the context and removes them from the context's tables. <br>
+ * Note: The events caused be deleting the files should cause all the procedures to disappear from the tables as well.
+ * [But the files manager doesn't care about procedures]
+ */
+ @Override
+ public void eraseAll()
+ {
+ Collection<LogoFile> files = context.getFilesTable().values();
+
+ while (!files.isEmpty())
+ {
+ LogoFile nextVictim = null;
+ for (LogoFile file : files)
+ {
+ nextVictim = file;
+ break;
+ }
+ nextVictim.delete();
+ context.getFilesTable().remove(nextVictim.getPlainName());
+ notifyFileRemoved(nextVictim.getPlainName());
+ }
+ context.getFilesTable().clear();
+ }
+
+ @Override
+ public boolean existsFile(String name)
+ {
+ return context.getFilesTable().containsKey(name);
+ }
+
+ @Override
+ public String readFile(String name)
+ {
+ return context.getFilesTable().get(name).getText();
+ }
+
+ /**
+ * Please make sure the renaming makes sense, otherwise an IllegalStateException is thrown at you.
+ */
+ @Override
+ public void renameFile(String oldName, String newName)
+ {
+ if (oldName.equals(newName))
+ return;
+
+ if(!existsFile(oldName))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.RENAME_INEXISTENT_FILE));
+ return;
+ }
+
+ if (existsFile(newName))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.WS_FILENAME_EXISTS_ALREADY));
+ return;
+ }
+
+ if (newName == null || newName.length() == 0)
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.EMPTY_NAME));
+ return;
+ }
+
+ if (!Storable.checkLegalName(newName))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME) + " : " + newName);
+ return;
+ }
+
+ context.renameFile(oldName, newName);
+ notifyFileRenamed(oldName, newName);
+ }
+
+ @Override
+ public String makeUniqueFileName(String base)
+ {
+ int i = 0;
+ String name = null;
+ do
+ {
+ name = base + i;
+ i++;
+ } while (existsFile(name));
+ return name;
+ }
+
+ /**
+ * @throws IllegalArgumentException if the specified file does not exist in the current context.
+ */
+ @Override
+ public void openFile(String fileName)
+ {
+ if(!existsFile(fileName))
+ throw new IllegalStateException("The specified file to open does not exist in the current context.");
+
+ LogoFile openFile = context.getOpenFile();
+ if(openFile != null)
+ closeFile(openFile.getPlainName());
+
+ context.openFile(fileName);
+ notifyFileOpened(fileName);
+ }
+
+ /**
+ * This can handle only one open file.
+ * If the wrong filename is closed, nothing happens<p>
+ * @throws IllegalStateException
+ */
+ @Override
+ public void closeFile(String fileName)
+ {
+ LogoFile openFile = context.getOpenFile();
+ if (openFile == null || !openFile.getPlainName().equals(fileName))
+ throw new IllegalStateException("Attempting to close a file that was not opened.");
+ context.closeFile();
+ notifyFileClosed(openFile.getPlainName());
+ }
+
+ /**
+ * returns null if no file is open.
+ */
+ @Override
+ public String getOpenFileName()
+ {
+ LogoFile file = context.getOpenFile();
+ if (file == null)
+ return null;
+ return file.getPlainName();
+ }
+
+ public boolean isFilesListEditable()
+ {
+ return context.isFilesListEditAllowed();
+ }
+
+ /**
+ * the name of the file that was edited last in this context.
+ */
+ @Override
+ public String getLastEditedFileName()
+ {
+ Calendar latest = Calendar.getInstance();
+ latest.setTimeInMillis(0);
+
+ LogoFile result = null;
+ for (LogoFile file : context.getFilesTable().values())
+ {
+ Calendar fileDefinedAt = file.getLastSync();
+ if (latest.before(fileDefinedAt))
+ {
+ result = file;
+ latest = fileDefinedAt;
+ }
+ }
+ if (result == null)
+ return null;
+
+ return result.getPlainName();
+ }
+
+ // Change listeners : these event update the gui, they must run on the event dispatcher thread
+
+ @Override
+ public void addFileListener(FileContainerChangeListener listener)
+ {
+ if (listener == null)
+ throw new IllegalArgumentException("listener must not be null.");
+ fileListeners.add(listener);
+ }
+
+ @Override
+ public void removeFileListener(FileContainerChangeListener listener)
+ {
+ fileListeners.remove(listener);
+ }
+
+ private void notifyFileAdded(final String fileName)
+ {
+ if (!context.fireFileEvents())
+ return;
+
+ for (FileContainerChangeListener listener : fileListeners)
+ listener.fileAdded(fileName);
+ }
+
+ private void notifyFileRemoved(final String fileName)
+ {
+ if (!context.fireFileEvents())
+ return;
+
+ for (FileContainerChangeListener listener : fileListeners)
+ listener.fileRemoved(fileName);
+ }
+
+ private void notifyFileRenamed(final String oldName, final String newName)
+ {
+ if (!context.fireFileEvents())
+ return;
+
+ for (FileContainerChangeListener listener : fileListeners)
+ listener.fileRenamed(oldName, newName);
+ }
+
+ private void notifyFileOpened(final String fileName)
+ {
+ if (!context.fireFileEvents())
+ return;
+
+ for (FileContainerChangeListener listener : fileListeners)
+ listener.fileOpened(fileName);
+ }
+
+ private void notifyFileClosed(final String fileName)
+ {
+ if (!context.fireFileEvents())
+ return;
+
+ for (FileContainerChangeListener listener : fileListeners)
+ listener.fileClosed(fileName);
+ }
+
+ private void notifyRightsChanged()
+ {
+ for (FileContainerChangeListener listener : fileListeners)
+ listener.editRightsChanged(context.isFilesListEditAllowed());
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * ERROR COLLECTOR : these events do not update the gui directly, they must not run on the event dispatcher thread
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ @Override
+ public Collection<String> getAllErroneousFiles()
+ {
+ ArrayList<String> erroneousFiles = new ArrayList<String>();
+
+ for(LogoFile file : context.getFilesTable().values())
+ if(file.hasErrors())
+ erroneousFiles.add(file.getPlainName());
+
+ return erroneousFiles;
+ }
+
+ @Override
+ public boolean hasErrors()
+ {
+ for(LogoFile file : context.getFilesTable().values())
+ if(file.hasErrors())
+ return true;
+ return false;
+ }
+
+ @Override
+ public boolean hasErrors(String fileName)
+ {
+ LogoFile file = context.getFilesTable().get(fileName);
+ if (file == null)
+ throw new IllegalStateException("The specified fileName does not exist in this context.");
+
+ return file.hasErrors();
+ }
+
+ @Override
+ public Collection<ProcedureErrorMessage> getAllErrors()
+ {
+ ArrayList<ProcedureErrorMessage> allErrors = new ArrayList<ProcedureErrorMessage>();
+ for (LogoFile file : context.getFilesTable().values())
+ allErrors.addAll(file.getAllErrors());
+ return allErrors;
+ }
+
+ // Error listeners
+
+ private final ArrayList<ErrorListener> errorListeners = new ArrayList<ErrorListener>();
+
+ @Override
+ public void addErrorListener(ErrorListener listener)
+ {
+ errorListeners.add(listener);
+ }
+
+ @Override
+ public void removeErrorListener(ErrorListener listener)
+ {
+ errorListeners.add(listener);
+ }
+
+
+ private void notifyErrorsDetected(String fileName)
+ {
+ if (!context.fireFileEvents())
+ return;
+ for (ErrorListener listener : errorListeners)
+ listener.errorsDetected(fileName);
+ }
+
+ private void notifyErrorsCorrected(String fileName)
+ {
+ if (!context.fireFileEvents())
+ return;
+ for (ErrorListener listener : errorListeners)
+ listener.allErrorsCorrected(fileName);
+ }
+
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/files/RecordFile.java b/logo/src/xlogo/kernel/userspace/files/RecordFile.java new file mode 100644 index 0000000..9220f28 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/files/RecordFile.java @@ -0,0 +1,234 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.files;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+import javax.swing.Timer;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+import xlogo.Logo;
+import xlogo.interfaces.MessageBroadcaster;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.WSManager;
+import xlogo.storage.user.UserConfig;
+import xlogo.utils.Utils;
+
+/**
+ * This is a {@link LogoFile} which is used in contest/record mode.
+ * @author Marko
+ */
+public class RecordFile extends LogoFile implements MessageBroadcaster
+{
+ private static final long serialVersionUID = -9137220313285199168L;
+
+ private Timer timer; // the SWING Timer dispatchers on the EventDispatcher Thread => update GUI ok
+ private Date started;
+ private Date last;
+ private long totalMillis;
+
+ /**
+ * @param fileName
+ */
+ protected RecordFile(String fileName)
+ {
+ super(fileName);
+ }
+
+ public static RecordFile createNewFile(String fileName) throws IOException
+ {
+ RecordFile file = new RecordFile(fileName);
+ file.setupFileSystem();
+ return file;
+ }
+
+
+ /**
+ * @throws NotImplementedException A virtual contest/record mode makes no sense.
+ */
+ public static RecordFile createNewVirtualFile(UserConfig userConfig, String fileName)
+ {
+ throw new NotImplementedException();
+ }
+
+ @Override
+ protected void setupFileSystem() throws IOException
+ {
+ File contestFileDir = getUserConfig().getContestFileDir(getPlainName());
+
+ if (!contestFileDir.exists())
+ contestFileDir.mkdirs();
+ }
+
+ @Override
+ public File getFilePath()
+ {
+ return getUserConfig().getContestFilePath(getPlainName());
+ }
+
+ @Override
+ public void store()
+ {
+ long now = Calendar.getInstance().getTime().getTime();
+ recordFile(getTimeStampHeader(totalMillis, started.getTime(), now));
+ //pauseRecord(); // This is already called by Context at open/close.
+ // We actually never store normally, and we don't export these files.
+ }
+
+ /**
+ * Set the timer
+ */
+ public void startRecord()
+ {
+ this.started = Calendar.getInstance().getTime();
+ this.last = Calendar.getInstance().getTime();
+
+ timer = new Timer(1000,
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent arg0)
+ {
+ Date now = Calendar.getInstance().getTime();
+ totalMillis += now.getTime() - last.getTime();
+ last = now;
+
+ String time = UserConfig.getMinSec(totalMillis);
+ String fileName = getPlainName();
+
+ for(MessageListener listener : timerEventListeners)
+ listener.messageEvent(fileName, time);
+ }
+ }
+ );
+ timer.setRepeats(true);
+ timer.start();
+ }
+
+ /**
+ * Stop the timer and record recent changes with time stamp in contest directory.
+ * (Make sure the recent changes from the editor are before calling this)
+ */
+ public void pauseRecord()
+ {
+ timer.stop();
+ }
+
+
+ private void recordFile(final String header)
+ {
+ new Thread(new Runnable(){
+
+ @Override
+ public void run()
+ {
+ // Write to file's folder
+ File recordFile = getUserConfig().getRecordFilePath(getPlainName());
+ File recordFolder = recordFile.getParentFile();
+ if (!recordFolder.exists())
+ recordFolder.mkdirs();
+
+ String content = header + getText();
+
+ try
+ {
+ Utils.writeLogoFile(recordFile.toString(), content);
+ }
+ catch (IOException e)
+ {
+ DialogMessenger.getInstance().dispatchMessage(
+ Logo.messages.getString("contest.error.title"),
+ Logo.messages.getString("contest.error.could.not.record.file") + "\n\n " + e.toString());
+ }
+
+ // append to command line too ...
+ PrintWriter out = null;
+ File logoFile = WSManager.getUserConfig().getCommandLineContestFile();
+ try
+ {
+ out = new PrintWriter(new BufferedWriter(new FileWriter(logoFile, true)));
+ out.println("");
+ out.println(getPlainName());
+ out.println(content);
+ out.println("\n");
+ }
+ catch (Exception e)
+ {
+ DialogMessenger.getInstance().dispatchMessage(Logo.messages.getString("contest.error.title"),
+ Logo.messages.getString("contest.could.not.store") + "\n" + e.toString());
+ }
+ finally
+ {
+ if (out != null)
+ out.close();
+ }
+ }
+ }).run();
+
+ }
+
+
+ private String getTimeStampHeader(long totalTime, long lastEditStarted, long lastEditEnded)
+ {
+ String tot = UserConfig.getMinSec(totalTime);
+ String lastStart = UserConfig.getTimeString(lastEditStarted);
+ String now = UserConfig.getTimeString(lastEditEnded);
+
+ return "# Total Time : " + tot + "\n# Edited from : " + lastStart + "\n# Until : " + now + "\n\n";
+ }
+
+ /*
+ * Timer Listeners
+ */
+
+ private final ArrayList<MessageListener> timerEventListeners = new ArrayList<MessageListener>();
+
+ @Override
+ public void addBroadcastListener(MessageListener listener)
+ {
+ if(listener == null)
+ throw new IllegalArgumentException("Listener must not be null.");
+ timerEventListeners.add(listener);
+ listener.messageEvent(getPlainName(), UserConfig.getMinSec(totalMillis));
+ }
+
+ @Override
+ public void removeBroadcastListener(MessageListener listener)
+ {
+ timerEventListeners.remove(listener);
+ }
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/procedures/ExecutablesContainer.java b/logo/src/xlogo/kernel/userspace/procedures/ExecutablesContainer.java new file mode 100644 index 0000000..73c7295 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/procedures/ExecutablesContainer.java @@ -0,0 +1,59 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.procedures;
+
+import java.io.IOException;
+import java.util.Collection;
+
+public interface ExecutablesContainer
+{
+
+ public Collection<Procedure> getExecutables();
+
+ public Procedure getExecutable(String procedureName);
+
+ public boolean isExecutable(String name);
+
+ /**
+ * The Logo command {@code eraseProcedure} <p>
+ * Delete the specified procedure. <br>
+ * If there exists an ambiguity and multiple procedures with the same name
+ * are defined, remove all of them.
+ *
+ * @param name
+ */
+ public void eraseProcedure(String procedureName);
+
+ /**
+ * The Logo command {@code define}
+ * @param procedure
+ * @throws IOException
+ */
+ public void defineProcedure(Procedure procedure) throws IOException;
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/procedures/ExecutablesProvider.java b/logo/src/xlogo/kernel/userspace/procedures/ExecutablesProvider.java new file mode 100644 index 0000000..6ae20ea --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/procedures/ExecutablesProvider.java @@ -0,0 +1,36 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.procedures;
+
+import xlogo.interfaces.ProcedureMapper;
+import xlogo.interfaces.ErrorDetector.AmbiguityDetector;
+
+public interface ExecutablesProvider extends ExecutablesContainer, ProcedureMapper, AmbiguityDetector
+{
+
+}
diff --git a/logo/src/xlogo/kernel/userspace/procedures/Procedure.java b/logo/src/xlogo/kernel/userspace/procedures/Procedure.java new file mode 100644 index 0000000..c485432 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/procedures/Procedure.java @@ -0,0 +1,763 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written Lo�c Le Coq. + * The were heavily refactored, changed and extended by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * + * @author Loïc Le Coq + */ +package xlogo.kernel.userspace.procedures; + +import java.util.Calendar; +import java.util.Stack; +import java.util.ArrayList; +import java.util.StringTokenizer; +import java.io.*; + +import xlogo.Logo; +import xlogo.kernel.Primitive; +import xlogo.utils.Utils; + +/** + * The Procedure in XLogo4Schools receives pieces of text, where a single procedure is expected to be defined. + * It parses the text and sets its fields accordingly. + * It maintains states, so we know whether a procedure is executable or whether it has errors and what type of error. + * With the new implementation, multiple types of errors can be detected at the same time. + * + * <p> + * Affichable (displayable) is removed. In XLogo4Schools, every procedure is displayable. + * In XLogo, affichable was added to mark procedures that have been received over the network. + * They should only be running while the TCPConnection is open. + * They won't ever get displayed in the editor and they are removed, after the TCP connection is closed. + * In the new implementation, I can treat the received workspace as a virtual file, + * add its procedures to the UserSpace, without adding the file to the file list. + * Hence it cannot be opened while the procedures can still be executed. + * + * @author Marko Zivkovic, Loic + */ +public class Procedure +{ + public static final String specialCharacters = ":+-*/() []=<>&|"; + + /* Marko : TODO the following properties need to be encapsulated completely (Legacy from XLogo) + * I removed those properties that were named _sauve etc. which was used to temporarily redefine procedures, + * and then restore them in case there was an error while parsing. + */ + + // false lorsque c'est une procédure d'un fichier de démarrage + /** + * Whitespace and comments above a procedure in the editor + */ + public String comment; + public int nbparametre; + public String name; + public ArrayList<String> variable = new ArrayList<String>(); + public Stack<String> optVariables = new Stack<String>(); // Marko : why Stack??? [so bad] + public Stack<StringBuffer> optVariablesExp = new Stack<StringBuffer>(); // Marko : why Stack?? [so bad] + public String instruction = ""; + public StringBuffer instr = null; + + // Marko : I added these + private String text = null; + private String ownerName = null; + private Calendar defineTime = null; + + /** + * Create a procedure from a piece of text from the editor. + * The expected structure is as follows. + * <p> + * [leading <b>empty lines</b> and <b>comments</b> => stored into comment] <br> + * <b>to procedureName</b> [<b>variables</b>] [<b>optional variables</b>] <br> + * [<b>body</b>] <br> + * <b>end</b><br> + * + * @param text + * @throws IOException + */ + public Procedure(String text) + { + try + { + defineTime = Calendar.getInstance(); + this.text = text; + StringReader sr = new StringReader(text); + BufferedReader br = new BufferedReader(sr); + String line = parseComments(br); + if (state == State.COMMENT_ONLY) + return; + StringTokenizer st = new StringTokenizer(line); + parseName(st); + if (errors.contains(ProcedureErrorType.MISSING_TO)) + return; + parseVariables(st); + parseBody(br); + + if (state == State.UNINITIALIZED) + setState(State.EXECUTABLE); + } + catch(IOException ignore) { + /* this should not happen, no actual IO */ + } + } + + /** + * Create a procedure with all necessary values.<br> + * If name is not legal, the Procedure state will switch to error, + * otherwise it will be executable + */ + public void redefine(Procedure newDefinition) + { + defineTime = Calendar.getInstance(); + this.name = newDefinition.name; + this.nbparametre = newDefinition.nbparametre; + this.variable = newDefinition.variable; + this.optVariables = newDefinition.optVariables; + this.optVariablesExp = newDefinition.optVariablesExp; + this.text = newDefinition.text; + this.errors = newDefinition.errors; + + ProcedureErrorType e = checkName(name); + if (e != ProcedureErrorType.NO_ERROR) + addError(e); + else + setState(State.EXECUTABLE); + } + + public Calendar getDefineTime() + { + return defineTime; + } + + public String getText() + { + return text; + } + + /* + * PROCEDURE STATE + */ + + private State state = State.UNINITIALIZED; + + private ArrayList<ProcedureErrorType> errors = new ArrayList<ProcedureErrorType>(); + + /** + * @see {@link State} + * @return + */ + public State getState() + { + return state; + } + + private void setState(State state) + { + this.state = state; + } + + /** + * Use this to indicate that this procedure is not executable because there is an ambiguity within its file. + */ + public void makeAmbiguous() + { + this.state = State.AMBIGUOUS_NAME; + if (!errors.contains(ProcedureErrorType.AMBIGUOUS)) + errors.add(ProcedureErrorType.AMBIGUOUS); + } + + /** + * States are: UNINITIALIZED, EXECUTABLE, COMMENT_ONLY, ERROR + * @author Marko + */ + public enum State + { + /** + * No values are set, or no check has been performed. + */ + UNINITIALIZED("procedure.unititialized"), + /** + * The procedure has a correct structure and can be executed. + */ + EXECUTABLE("procedure.executable"), + /** + * The procedure contains only a comment, no procedure definition. It is not executable + */ + COMMENT_ONLY("procedure.not.executable"), + /** + * The procedure structure could no be parsed entirely because it contains errors. + */ + ERROR("procedure.error"), + /** + * There is another procedures with the same name in the same file. + */ + AMBIGUOUS_NAME("procedure.ambiguous"); + + private String description; + + private State(String description) + { + this.description = description; + } + + public String getDescription() + { + return description; + } + + /** + * @return {@link #getDescription()} + */ + public String toString() + { + return getDescription(); + } + } + + /* + * ERROR REPORTING + */ + + public ArrayList<ProcedureErrorType> getErrors() + { + return errors; + } + + private void addError(ProcedureErrorType e) + { + errors.add(e); + state = State.ERROR; + } + + public String getName() + { + return name; + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * OLD XLOGO FEATURES ... TODO behavior not always clear + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * @author Lo�c Le Coq + */ + public void decoupe() + { + // Only cut procedures which are visible in the editor + if (null == instr) + { + instr = new StringBuffer(); + try + { + String line = ""; + StringReader sr = new StringReader(instruction); + BufferedReader bfr = new BufferedReader(sr); + int lineNumber = 0; + // Append the number of the line + instr.append("\\l"); + instr.append(lineNumber); + instr.append(" "); + while (bfr.ready()) + { + lineNumber++; + // read the line + try + { + line = bfr.readLine().trim(); + } + catch (NullPointerException e1) + { + break; + } + // delete comments + line = deleteComments(line); + line = Utils.decoupe(line).toString().trim(); + instr.append(line); + if (!line.equals("")) + { + instr.append(" "); + // Append the number of the line + instr.append("\\l"); + instr.append(lineNumber); + instr.append(" "); + } + } + } + catch (IOException e) + {} + // System.out.println("****************************"+name+"\n"+instr+"\n\n"); + } + } + + /** + * @author Lo�c Le Coq + */ + private String deleteComments(String line) + { + int index = line.indexOf("#"); + while (index != -1) + { + if (index == 0) + { + return ""; + } + else if (line.charAt(index - 1) != '\\') + { + return line.substring(0, index); + } + else + index = line.indexOf("#", index + 1); + } + return line; + } + + /** + * @author Lo�c Le Coq + */ + public String toString() + { + // return("nom "+name+" nombre paramètres "+nbparametre+" identifiant "+id+"\n"+variable.toString()+"\n"+instr+"\ninstrction_sauve"+instruction_sauve+"\ninstr_sauve\n"+instr_sauve); + StringBuffer sb = new StringBuffer(); + + sb.append(comment); + sb.append(Logo.messages.getString("pour") + " " + name); + for (int j = 0; j < nbparametre; j++) + { + sb.append(" :"); + sb.append(variable.get(j)); + } + for (int j = 0; j < optVariables.size(); j++) + { + sb.append(" [ :"); + sb.append(optVariables.get(j)); + sb.append(" "); + sb.append(optVariablesExp.get(j)); + sb.append(" ]"); + } + sb.append("\n"); + sb.append(instruction); + sb.append(Logo.messages.getString("fin")); + sb.append("\n"); + // System.out.println("a"+sb+"a"); + return new String(sb); + } + + /** + * @author Lo�c Le Coq + */ + public StringBuffer cutInList() + { + // Only cut procedures which are visible in the editor + StringBuffer sb = new StringBuffer(); + try + { + String line = ""; + StringReader sr = new StringReader(instruction); + BufferedReader bfr = new BufferedReader(sr); + while (bfr.ready()) + { + try + { + line = bfr.readLine().trim(); + } + catch (NullPointerException e1) + { + break; + } + // delete comments + // line=deleteComments(line); + line = Utils.decoupe(line).toString().trim(); + sb.append("[ "); + sb.append(line); + sb.append(" ] "); + } + } + catch (IOException e) + {} + return sb; + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * PARSING + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Read and save the comments that appear before the procedure + * @param br + * @return the first line that (probably) contains a procedure definition, + * or null if there are no more procedures + * @throws IOException + * @throws DocumentStructureException + */ + String parseComments(BufferedReader br) throws IOException + { + String line = null; + comment = ""; + while (br.ready()) + { + line = br.readLine(); + if (line == null) + break; + + if (isComment(line)) + { + comment += line + "\n"; + line = null; + } + else if (line.trim().equals("")) + { + comment += "\n"; + line = null; + } + else + break; + } + + if (line == null) + { + setState(State.COMMENT_ONLY); + } + + return line; + } + + /** + * Expects a line that starts with "to procedName" + * @return Error, NO_ERROR if name is ok + * @throws DocumentStructureException + */ + void parseName(StringTokenizer st) + { + String token = st.nextToken(); + + if (!token.toLowerCase().equals(Logo.messages.getString("pour").toLowerCase())) + { + addError(ProcedureErrorType.MISSING_TO); + return; + } + + if (!st.hasMoreTokens()) + { + addError(ProcedureErrorType.MISSING_NAME); + return; + } + + name = st.nextToken().toLowerCase(); + + ProcedureErrorType e = checkName(name); + if (!e.equals(ProcedureErrorType.NO_ERROR)) + addError(e); + } + + void parseVariables(StringTokenizer st) + { + // Then, We read the variables + // :a :b :c :d ..... + String token = null; + while (st.hasMoreTokens()) + { + token = st.nextToken(); + if (token.startsWith(":")) + { + String var = token.substring(1); + ProcedureErrorType e = checkValidVariable(var); + if (e != ProcedureErrorType.NO_ERROR) + { + addError(e); + return; + } + var = var.toLowerCase(); + variable.add(var); + } + else + break; + } + + nbparametre = variable.size(); + + if (token == null || token.startsWith(":")) + return; + + // read all remaining tokens into string buffer + StringBuffer sb = new StringBuffer(); + sb.append(token); + //sb.append(token); + while (st.hasMoreTokens()) + { + sb.append(" "); + sb.append(st.nextToken()); + } + // And finally, optional variables if there are some. + // [:a 100] [:b 20] [:c 234] ........... + + while (sb.length() > 0) + { + if (sb.indexOf("[") != 0) + { + addError(ProcedureErrorType.VAR_EXTRA_CHARS); + return; + } + + sb.deleteCharAt(0); + String[] arg = new String[2]; + extractOptionalVariable(sb, arg); + optVariables.push(arg[0].toLowerCase()); + /* Bug Fixed: list as Optionnal arguments + ** Eg: + ** to a [:var [a b c]] + * end + * when the string is formatted, we check that a white space + * is needed at the end of the argument + */ + + StringBuffer exp = Utils.decoupe(arg[1]); + if (exp.charAt(exp.length() - 1) != ' ') + exp.append(" "); + optVariablesExp.push(exp); + } + } + + /** + * Reads from sb into args the name and the default value of an optional variable [:a value]. <br> + * value can be expression: number, word, list, ... + * @author Lo�c Le Coq + * @author Marko Zivkovic refactored + */ + void extractOptionalVariable(StringBuffer sb, String[] args) + { + + String variable=""; + String expression=""; + int compteur=1; + int id=0; + int id2=0; + boolean espace = false; + for (int i = 0; i < sb.length(); i++) + { + char ch = sb.charAt(i); + if (ch == '[') + compteur++; + else if (ch == ']') + { + if (id == 0) + { + addError(ProcedureErrorType.OPT_VAR_BRACKET); + return; + } + compteur--; + } + else if (ch == ' ') + { + if (!variable.equals("")) + { + if (!espace) + id = i; + espace = true; + } + } + else + { + if (!espace) + variable += ch; + } + if (compteur == 0) + { + id2 = i; + break; + } + } + if (!variable.startsWith(":")) + { + addError(ProcedureErrorType.VAR_COLON_EXPECTED); + return; + } + + variable = variable.substring(1, variable.length()).toLowerCase(); + ProcedureErrorType pet = checkValidVariable(variable); + + if (pet != ProcedureErrorType.NO_ERROR) + { + addError(pet); + return; + } + + + if (compteur != 0) + { + addError(ProcedureErrorType.OPT_VAR_BRACKET); + return; + } + + expression = sb.substring(id + 1, id2).trim(); + + if (expression.equals("")) + { + addError(ProcedureErrorType.VAR_MISSING_EXPRESSION); + return; + } + /* System.out.println(id+" "+id2); + System.out.println("a"+expression+"a"); + System.out.println("a"+variable+"a");*/ + sb.delete(0, id2 + 1); + // delete unnecessary space + while (sb.length() != 0 && sb.charAt(0) == ' ') + sb.deleteCharAt(0); + args[0] = variable; + args[1] = expression; + } + + /** + * Sets as body everything up the 'end' key word. + */ + private void parseBody(BufferedReader br) throws IOException + { + StringBuffer body = new StringBuffer(); + String to = Logo.messages.getString("pour").toLowerCase() + " "; + String end = Logo.messages.getString("fin").toLowerCase(); + instruction = null; + String line; + String lower; + + while (br.ready()) + { + line = br.readLine(); + if (null == line) + break; + lower = line.toLowerCase(); + if (lower.trim().equals(end)) // end of procedure + { + instruction = body.toString(); + if (br.ready() && br.readLine() != null) // Additional characters after end + addError(ProcedureErrorType.CHARS_AFTER_END); + return; // We are done + } + if (lower.startsWith(to)) // new procedure definition before end + { + addError(ProcedureErrorType.TO_BEFORE_END); + return; + } + body.append(line); + body.append("\n"); + } + + // no end was found + addError(ProcedureErrorType.MISSING_END); + + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * UTILITY + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * @return true if and only if line starts with '#' + */ + static boolean isComment(String line) + { + if (line.trim().startsWith("#")) + return true; + else + return false; + } + + static boolean isNumber(String token) + { + try + { + Double.parseDouble(token); + return true; + } + catch (NumberFormatException e) + { + return false; + } + } + + /** + * This method is essentially changed to fit with the new workspace (=UserSpace & LogoFile).<br> + * On the fly it was rewritten completely, because of its initial programming style and inefficiency. <br> + * (note that it was very long, and now it is only 3 lines) + * + * @param token + * @return Error - NO_ERROR if token is a legal procedure name + * @author Marko Zivkovic + */ + static ProcedureErrorType checkName(String token) + { + if (isNumber(token)) + return ProcedureErrorType.NAME_IS_NUMBER; + ProcedureErrorType e = checkSpecialCharacter(token); + if (e != ProcedureErrorType.NO_ERROR) + return e; + + if(Primitive.primitives.containsKey(token)) + return ProcedureErrorType.NAME_IS_KEY_WORD; + + return ProcedureErrorType.NO_ERROR; + } + + /** + * @param token + * @return null if a valid variable name, error message otherwise + */ + static ProcedureErrorType checkValidVariable(String token) + { + if (token.length() == 0) + return ProcedureErrorType.VAR_WHITESPACE_AFTER_COLON; + + if (isNumber(token)) + return ProcedureErrorType.VAR_IS_NUMBER; + + return checkSpecialCharacter(token); + } + + static ProcedureErrorType checkSpecialCharacter(String var) + { + StringTokenizer check = new StringTokenizer(var, specialCharacters, true); + + if ((check.countTokens() > 1) || ":+-*/() []=<>&|".indexOf(check.nextToken()) > -1) + return ProcedureErrorType.VAR_HAS_SPECIAL; + return ProcedureErrorType.NO_ERROR; + } + + /* + * OWNER : This is typically a file, but a procedure must not know whether it is owned by a file or something else + */ + + public String getOwnerName() + { + return ownerName; + } + + public void setOwnerName(String ownerName) + { + this.ownerName = ownerName; + } + +} diff --git a/logo/src/xlogo/kernel/userspace/procedures/ProcedureErrorType.java b/logo/src/xlogo/kernel/userspace/procedures/ProcedureErrorType.java new file mode 100644 index 0000000..3029320 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/procedures/ProcedureErrorType.java @@ -0,0 +1,80 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.procedures;
+
+import xlogo.messages.MessageKeys;
+
+public enum ProcedureErrorType
+{
+ NO_ERROR(MessageKeys.LOGO_ERROR_NO_ERROR),
+ MISSING_TO(MessageKeys.LOGO_ERROR_MISSING_TO),
+ MISSING_NAME(MessageKeys.LOGO_ERROR_MISSING_NAME),
+ NAME_IS_NUMBER(MessageKeys.LOGO_ERROR_NAME_IS_NUMBER), //Logo.messages.getString("erreur_nom_nombre_procedure")
+ /*
+ * Logo.messages.getString("caractere_special1") + "\n" + Logo.messages.getString("caractere_special2")
+ * + "\n" + Logo.messages.getString("caractere_special3") + " " + token
+ */
+ NAME_HAS_SPECIAL_CHAR(MessageKeys.LOGO_ERROR_NAME_SPECIAL),
+ VAR_WHITESPACE_AFTER_COLON(MessageKeys.LOGO_ERROR_VAR_WHITE_AFTER_COLON),
+ /*
+ * Logo.messages.getString("caractere_special_variable") + "\n"
+ + Logo.messages.getString("caractere_special2") + "\n"
+ + Logo.messages.getString("caractere_special3") + " :" + var
+ */
+ VAR_HAS_SPECIAL(MessageKeys.LOGO_ERROR_VAR_SPECIAL),
+ VAR_IS_NUMBER(MessageKeys.LOGO_ERROR_VAR_IS_NUMBER),
+ VAR_COLON_EXPECTED(MessageKeys.LOGO_ERROR_VAR_MISSING_COLON),
+ OPT_VAR_BRACKET(MessageKeys.LOGO_ERROR_OPT_VAR_BRACKET),
+ VAR_EXTRA_CHARS(MessageKeys.LOGO_ERROR_VAR_EXTRA_CHARS),
+ VAR_MISSING_EXPRESSION(MessageKeys.LOGO_ERROR_MISSING_EXPR),
+ CHARS_AFTER_END(MessageKeys.LOGO_ERROR_MORE_CHARS_AFTER_END),
+ MISSING_END(MessageKeys.LOGO_ERROR_MISSING_END),
+ TO_BEFORE_END(MessageKeys.LOGO_ERROR_TO_BEFORE_END),
+ NAME_IS_KEY_WORD(MessageKeys.LOGO_ERROR_NAME_IS_KEY_WORD),
+ AMBIGUOUS(MessageKeys.LOGO_ERROR_AMBIGUOUS);
+
+ private String description;
+
+ private ProcedureErrorType(String description)
+ {
+ this.description = description;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ /**
+ * @return {@link #getDescription()}
+ */
+ public String toString()
+ {
+ return getDescription();
+ }
+}
\ No newline at end of file diff --git a/logo/src/xlogo/kernel/userspace/procedures/ProceduresManager.java b/logo/src/xlogo/kernel/userspace/procedures/ProceduresManager.java new file mode 100644 index 0000000..bcaea16 --- /dev/null +++ b/logo/src/xlogo/kernel/userspace/procedures/ProceduresManager.java @@ -0,0 +1,557 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.kernel.userspace.procedures;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import xlogo.kernel.userspace.ProcedureErrorMessage;
+import xlogo.kernel.userspace.context.ContextSwitcher;
+import xlogo.kernel.userspace.context.LogoContext;
+import xlogo.kernel.userspace.context.ContextSwitcher.ContextSwitchListener;
+import xlogo.kernel.userspace.files.LogoFile;
+import xlogo.kernel.userspace.procedures.Procedure.State;
+
+/**
+ * This class maintains the procedure table of all files in a context, and it reports ambiguity among them.
+ * @author Marko Zivkovic
+ */
+public class ProceduresManager implements ExecutablesProvider
+{
+ private LogoContext context;
+
+ private final ArrayList<AmbiguityListener> ambiguityListeners = new ArrayList<AmbiguityListener>();
+
+ private ProcedureMapListener procedureMapListener;
+
+ public ProceduresManager(ContextSwitcher contextProvider)
+ {
+ initProcedureMapListener();
+ installContextSwitchListener(contextProvider);
+ setContext(contextProvider.getContext());
+ }
+
+ private void setContext(LogoContext newContext)
+ {
+ LogoContext old = this.context;
+ this.context = newContext;
+
+ if (old != null)
+ old.removeProcedureMapListener(procedureMapListener);
+
+ mapProcedures(newContext);
+
+ /* Record Mode => new files => events
+ // Network Mode => only virtual files, invisible => no events
+ // that was achieved with the boolean "affichable" (displayable) in XLogo
+ if (!newContext.fireProcedureEvents())
+ {
+
+ return;
+ }
+ */
+ if (old != null && old.fireProcedureEvents() && newContext.fireProcedureEvents()) // TODO changed
+ for(LogoFile file : old.getFilesTable().values())
+ notifyDeleted(file.getPlainName(), file.getAllProcedureNames());
+
+ // Note : context will immediately fire event to notify what his contents are.
+ // Then these events are forwarded here, in procedureMapListener.
+ newContext.addProcedureMapListener(procedureMapListener);
+ }
+
+ private void mapProcedures(LogoContext context)
+ {
+ context.getProcedureTable().clear();
+ for (LogoFile file : context.getFilesTable().values())
+ for (Procedure procedure : file.getExecutables())
+ addProcedure(procedure);
+ }
+
+ private void installContextSwitchListener(ContextSwitcher provider)
+ {
+ provider.addContextSwitchListener(new ContextSwitchListener(){
+
+ @Override
+ public void contextSwitched(LogoContext newContext)
+ {
+ setContext(newContext);
+ }
+ });
+ }
+
+ private void initProcedureMapListener()
+ {
+ // This one listens for changes in files.
+ procedureMapListener = new ProcedureMapListener()
+ {
+ /**
+ * This event is received when a document is assigned a new text and it contains no errors,
+ * or when this ProcedureManager is assigned a new context that already contains files.
+ */
+ @Override
+ public void defined(String fileName, Collection<String> procedures)
+ {
+ for (String procedureName : procedures)
+ addProcedure(fileName, procedureName);
+
+ if (procedures.size() > 0)
+ notifyDefined(fileName, procedures);
+
+ for (String procedureName : procedures)
+ {
+ Map<String, Procedure> fileNameToProcedure = context.getProcedureTable().get(procedureName);
+ if (fileNameToProcedure.size() > 1)
+ {
+ notifyAmbiguityDetected(procedureName, context.getProcedureTable().get(procedureName));
+ }
+ }
+
+ }
+
+ /**
+ * This event is received when the Logo command "define" (re-)defined a command in a file (which already exists!)
+ */
+ @Override
+ public void defined(String fileName, String procedureName)
+ {
+ addProcedure(fileName, procedureName);
+
+ notifyDefined(fileName, procedureName);
+
+ // Check ambiguity
+ Map<String, Procedure> fileNameToProcedure = context.getProcedureTable().get(procedureName);
+ if (fileNameToProcedure.size() > 1)
+ {
+ notifyAmbiguityDetected(procedureName, fileNameToProcedure);
+ return;
+ }
+ }
+
+ /**
+ * This event is received when a file is deleted or when it is assigned a new text in which old procedures are missing.
+ */
+ @Override
+ public void undefined(String fileName, Collection<String> procedures)
+ {
+ for (String procedure : procedures)
+ undefined(fileName, procedure);
+ }
+
+ /**
+ * This event is received when the Logo command "eraseProcedure" removes a single procedure from a document
+ * Depending on how many procedures with the same name are left across files after this procedure is removed,
+ * this will fire ExecutableChanged events or AmbiguityResolved events.
+ */
+ @Override
+ public void undefined(String fileName, String procedureName)
+ {
+ Map<String,HashMap<String, Procedure>> procedureTable = context.getProcedureTable();
+
+ Map<String, Procedure> fileToProc = procedureTable.get(procedureName);
+
+ if (fileToProc == null)
+ return;
+
+ // remove from fileToProc entry
+ fileToProc.remove(fileName);
+
+ notifyDeleted(fileName, procedureName);
+
+ if (fileToProc.size() == 0)
+ procedureTable.remove(procedureName);
+ else
+ notifyAmbiguityResolved(procedureName, fileName);
+
+ if (fileToProc.size() == 1)
+ {
+ String winnerFile = null;
+ for (String wf : fileToProc.keySet())
+ winnerFile = wf; // size == 1 => only 1 iteration
+
+ notifyAmbiguityResolved(procedureName, winnerFile);
+ }
+ }
+
+ @Override
+ public void ownerRenamed(String oldName, String newName)
+ {
+ // Note : very important that this event is catched after filemanager has renamed files
+ // very critical. but implementation guarantees this order.
+ LogoFile file = context.getFilesTable().get(newName);
+ // Rename keys in procedureTable
+ Map<String, Procedure> fileToProc;
+ for (Procedure proc : file.getExecutables())
+ {
+ fileToProc = context.getProcedureTable().get(proc.getName());
+ fileToProc.remove(oldName);
+ fileToProc.put(newName, proc);
+ }
+ }
+ };
+ }
+
+ /**
+ * @see #addProcedure(Procedure)
+ */
+ protected void addProcedure(String fileName, String procedureName) throws IllegalArgumentException
+ {
+ Procedure procedure = context.getFilesTable().get(fileName).getExecutable(procedureName.toLowerCase());
+ addProcedure(procedure);
+ }
+
+ /**
+ * Adds the procedure to the procedureTable without firing events.
+ * Use {@link #defineProcedure(Procedure)}} if you want to notify listeners
+ * @param procedure
+ * @throws IllegalArgumentException
+ */
+ protected void addProcedure(Procedure procedure) throws IllegalArgumentException
+ {
+ String procedureName = procedure.getName();
+
+ if (procedure.getState() != State.EXECUTABLE && procedure.getState() != State.AMBIGUOUS_NAME)
+ throw new IllegalArgumentException("Only executable procedures should be added to the context.");
+
+ HashMap<String, HashMap<String, Procedure>> procedureTable = context.getProcedureTable();
+ HashMap<String, Procedure> fileToProc = procedureTable.get(procedureName);
+
+ if (fileToProc == null) // The procedure name is not yet defined in the context.
+ {
+ // Must create fileToProc entry in procedureTable
+ fileToProc = new HashMap<String, Procedure>();
+ procedureTable.put(procedureName, fileToProc);
+ }
+
+ fileToProc.put(procedure.getOwnerName(), procedure);
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * EXECUTABLES CONTAINER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * @param {@link Procedure#getOwnerName()} is supposed to be already mapped in the filesTable, and the procedure should be executable
+ * @throws IllegalArgumentException if the procedure's owner name is not mapped;
+ * @see {@link LogoFile#defineProcedure(Procedure)}
+ */
+ @Override
+ public void defineProcedure(Procedure procedure)
+ {
+ LogoFile file = context.getFilesTable().get(procedure.getOwnerName());
+ if (file == null)
+ throw new IllegalArgumentException("The file name \""
+ + procedure.getOwnerName()
+ + "\" specified in procedure is not mapped to a file.");
+
+ //addProcedure(procedure);
+ file.defineProcedure(procedure); // this will cause the necessary event cascade
+ }
+
+ /**
+ * Erase
+ */
+ @Override
+ public void eraseProcedure(String procedureName)
+ {
+ String lower = procedureName.toLowerCase();
+ while(context.getProcedureTable().containsKey(lower))
+ {
+ // contains key => there must be one
+ Procedure nextVictim = null;
+ for (Procedure proc : context.getProcedureTable().get(lower).values())
+ {
+ // iterate only once : otherwise concurrent modification exception
+ nextVictim = proc;
+ break;
+ }
+ context.getFilesTable().get(nextVictim.getOwnerName()).eraseProcedure(nextVictim.getName());
+ }
+ }
+
+ /**
+ * Executable procedures of all files. Ambiguous procedures are not included. <br>
+ * This list should not be used to do computations on it, because it must be created every time.
+ * Its purpose is to feed GUI lists
+ */
+ @Override
+ public ArrayList<Procedure> getExecutables()
+ {
+ ArrayList<Procedure> executables = new ArrayList<Procedure>();
+ for(Map<String, Procedure> fileToProc : context.getProcedureTable().values())
+ if (fileToProc.size() == 1) // only one exists
+ for(Procedure proc : fileToProc.values())
+ executables.add(proc); // only one is added
+ return executables;
+ }
+
+ /**
+ * @return The specified procedure if and only if there is exactly one
+ * procedure definition for this name in the context, otherwise null.
+ */
+ @Override
+ public Procedure getExecutable(String procedureName)
+ {
+ Map<String, Procedure> fileToProc = context.getProcedureTable().get(procedureName.toLowerCase());
+
+ if (fileToProc == null || fileToProc.size() > 1)
+ return null;
+ // There is exactly 1 procedure
+ for (Procedure proc : fileToProc.values())
+ return proc;
+ // Code won't reach here
+ return null;
+ }
+
+ /**
+ * @return true if and only if there exists exactly one procedure definition for the specified name in this context
+ */
+ @Override
+ public boolean isExecutable(String procedureName)
+ {
+ Map<String, Procedure> fileToProc = context.getProcedureTable().get(procedureName.toLowerCase());
+ return (fileToProc != null && fileToProc.size() == 1);
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * PROCEDURE MAPPER
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * Get all executable procedure names
+ * @see #getExecutables()
+ */
+ @Override
+ public Collection<String> getAllProcedureNames()
+ {
+ ArrayList<String> executables = new ArrayList<String>();
+ for(Map<String, Procedure> fileToProc : context.getProcedureTable().values())
+ if (fileToProc.size() == 1) // only one exists
+ for(Procedure proc : fileToProc.values())
+ executables.add(proc.getName()); // only one is added
+ return executables;
+ }
+
+ /**
+ * Get all procedures of that file, if its procedures are not conflicting with other files' procedures.
+ */
+ @Override
+ public Collection<String> getAllProcedureNames(String fileName)
+ {
+ if (!hasAmbiguousProcedures(fileName))
+ return context.getFilesTable().get(fileName).getAllProcedureNames();
+ return null;
+ }
+
+ /**
+ * @return null if procedure does not exist or if it is ambiguous
+ */
+ @Override
+ public String getProcedureOwner(String procedureName)
+ {
+ Procedure procedure = getExecutable(procedureName.toLowerCase());
+ return procedure == null ? null : procedure.getOwnerName();
+ }
+
+ // Procedure Map Listeners : update gui => run on event dispatcher thread
+
+ private final ArrayList<ProcedureMapListener> procedureMapListeners = new ArrayList<ProcedureMapListener>();
+
+ @Override
+ public void addProcedureMapListener(ProcedureMapListener listener)
+ {
+ procedureMapListeners.add(listener);
+ }
+
+ @Override
+ public void removeProcedureMapListener(ProcedureMapListener listener)
+ {
+ procedureMapListeners.remove(listener);
+ }
+
+ protected void notifyDefined(final String fileName, final Collection<String> procedures)
+ {
+ if (!context.fireProcedureEvents())
+ return;
+ if (procedures.size() == 0)
+ return;
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.defined(fileName, procedures);
+ }
+
+ protected void notifyDefined(final String fileName, final String procedure)
+ {
+ if (!context.fireProcedureEvents())
+ return;
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.defined(fileName, procedure);
+
+ }
+
+ protected void notifyDeleted(final String fileName, final Collection<String> procedures)
+ {
+ if (!context.fireProcedureEvents())
+ return;
+ if (procedures.size() == 0)
+ return;
+
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.undefined(fileName, procedures);
+ }
+
+ protected void notifyDeleted(final String fileName, final String procedure)
+ {
+ if (!context.fireProcedureEvents())
+ return;
+ for (ProcedureMapListener listener : procedureMapListeners)
+ listener.undefined(fileName, procedure);
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * AMBIGUITY DETECTOR
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * @return Whether there exists a procedure name that is defined in more
+ * than one file in the UserSpace
+ */
+ @Override
+ public boolean hasErrors()
+ {
+ for (Entry<String, ? extends Map<String, Procedure>> entry : context.getProcedureTable().entrySet())
+ {
+ if (entry.getValue().size() > 1)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns all ambiguity problems
+ */
+ @Override
+ public Collection<ProcedureErrorMessage> getAllErrors()
+ {
+ ArrayList<ProcedureErrorMessage> ambiguities = new ArrayList<ProcedureErrorMessage>();
+
+ for (Entry<String, HashMap<String, Procedure>> entry : context.getProcedureTable().entrySet())
+ {
+ HashMap<String, Procedure> fileToProc = entry.getValue();
+
+ if (fileToProc.size() < 2)
+ continue;
+
+ ambiguities.add(
+ new ProcedureErrorMessage(
+ ProcedureErrorType.AMBIGUOUS,
+ entry.getKey(),
+ fileToProc.keySet()
+ )
+ );
+ }
+
+ return ambiguities;
+ }
+
+ @Override
+ public Collection<String> getAllConflictingFiles()
+ {
+ ArrayList<String> conflictingFiles = new ArrayList<String>();
+
+ for (Entry<String, HashMap<String, Procedure>> entry : context.getProcedureTable().entrySet())
+ {
+ HashMap<String, Procedure> fileToProc = entry.getValue();
+
+ if (fileToProc.size() < 2)
+ continue;
+
+ conflictingFiles.addAll(fileToProc.keySet());
+ }
+
+ return conflictingFiles;
+ }
+
+ @Override
+ public boolean hasAmbiguousProcedures(String fileName)
+ {
+ for (Procedure proc : context.getFilesTable().get(fileName).getExecutables())
+ {
+ if(isProcedureAmbiguous(proc.getName()))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isProcedureAmbiguous(String name)
+ {
+ Map<String, Procedure> ambigs = context.getProcedureTable().get(name.toLowerCase());
+ if (ambigs == null)
+ return false;
+ return ambigs.size() > 1;
+ }
+
+
+ @Override
+ public void addAmbiguityListener(AmbiguityListener listener)
+ {
+ ambiguityListeners.add(listener);
+ }
+
+ @Override
+ public void removeAmbiguityListener(AmbiguityListener listener)
+ {
+ ambiguityListeners.remove(listener);
+ }
+
+ private void notifyAmbiguityDetected(String procedureName, Map<String, Procedure> fileToProcedure)
+ {
+ if(!context.fireProcedureEvents())
+ return;
+ for (AmbiguityListener listener : ambiguityListeners)
+ listener.ambiguityDetected(procedureName, fileToProcedure);
+ }
+
+ private void notifyAmbiguityResolved(String procedureName, String winnerFile)
+ {
+ if(!context.fireProcedureEvents())
+ return;
+ for (AmbiguityListener listener : ambiguityListeners)
+ listener.ambiguityResolved(procedureName, winnerFile);
+ }
+
+
+
+
+}
diff --git a/logo/src/xlogo/messages/Message.java b/logo/src/xlogo/messages/Message.java new file mode 100644 index 0000000..50a6749 --- /dev/null +++ b/logo/src/xlogo/messages/Message.java @@ -0,0 +1,52 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages;
+
+public abstract class Message
+{
+ private String title;
+ private String message;
+
+ public Message(String title, String message)
+ {
+ this.title = title;
+ this.message = message;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public String getTitle()
+ {
+ return title;
+ }
+
+ public abstract void displayMessage();
+}
\ No newline at end of file diff --git a/logo/src/xlogo/messages/MessageKeys.java b/logo/src/xlogo/messages/MessageKeys.java new file mode 100644 index 0000000..8da9013 --- /dev/null +++ b/logo/src/xlogo/messages/MessageKeys.java @@ -0,0 +1,180 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages;
+
+/**
+ * XLogo4Schools keys for the language property files.
+ * Old XLogo keys are not included.
+ * @author Marko
+ */
+public class MessageKeys
+{
+ public static final String WS_SETTINGS_REQUIRE_PW = "ws.settings.require_password";
+ public static final String WS_SETTINGS_PASSWORD = "ws.settings.password";
+ public static final String WS_SETTINGS_RETYPE_PW = "ws.settings.retype.password";
+ public static final String WS_SETTINGS_SAVE_PW = "ws.settings.save.password";
+ public static final String WS_SETTINGS_WORKSPACE_LABEL = "ws.settings.workspace.label";
+ public static final String WS_SETTINGS_LOCATION = "ws.settings.location";
+ public static final String WS_SETTINGS_LANGUAGE = "ws.settings.language";
+ public static final String WS_SETTINGS_BACKUPS = "ws.settings.backups";
+ public static final String WS_SETTINGS_USER = "ws.settings.user";
+ public static final String WS_SETTINGS_ADD = "ws.settings.add";
+ public static final String WS_SETTINGS_REMOVE = "ws.settings.remove";
+ public static final String WS_SETTINGS_IMPORT = "ws.settings.import";
+ public static final String WS_SETTINGS_ENABLE_USER_ACCOUNT_CREATION = "ws.settings.enable.user.account.creation";
+ public static final String WS_SETTINGS_SAVE_AND_CLOSE = "ws.settings.save.and.close";
+ public static final String WS_SETTINGS_TITLE = "ws.settings.title";
+ public static final String WS_SETTINGS_GLOBAL = "ws.settings.global";
+ public static final String WS_SETTINGS_GLOBAL_SETTINGS = "ws.settings.global.settings";
+ public static final String WS_SETTINGS_WORKSPACE = "ws.settings.workspace";
+ public static final String WS_SETTINGS_WORKSPACE_SETTINGS = "ws.settings.workspace.settings";
+ public static final String WS_SETTINGS_CANNOT_STORE_PW = "ws.settings.cannot.store.pw";
+ public static final String WS_SETTINGS_PW_MUST_BE_EQUAL = "ws.settings.pw.must.be.equal";
+ public static final String WS_SETTINGS_VIRTUAL_WS_NOT_STORED = "ws.settings.virtual.ws.not.stored";
+ public static final String WS_SETTINGS_COULD_NOT_ENTER_WP = "ws.settings.could.not.enter.wp";
+ public static final String WS_SETTINGS_CREATE_NEW_WP = "ws.settings.create.new.wp";
+ public static final String WS_SETTINGS_WP_NAME_NOT_EMPTY = "ws.settings.wp.name.non.empty";
+ public static final String WS_SETTINGS_WP_EXISTS_ALREADY = "ws.settings.wp.exists.already";
+ public static final String WS_SETTINGS_COULD_NOT_CREATE_DIRECTORY = "ws.settings.could.not.create.directory";
+ public static final String WS_SETTINGS_NEED_DIR_NOT_FILE = "ws.settings.need.dir.not.file";
+ public static final String WS_SETTINGS_COULD_NOT_CREATE_WS = "ws.settings.could.not.create.ws";
+ public static final String WS_SETTINGS_WANT_DELETE_DIR_1 = "ws.settings.want.delete.dir.1";
+ public static final String WS_SETTINGS_WANT_DELETE_DIR_2 = "ws.settings.want.delete.dir.2";
+ public static final String WS_SETTINGS_COULD_NOT_ENTER_VIRTUAL_WS = "ws.settings.could.not.enter.virtual.ws";
+ public static final String WS_SETTINGS_DELETE_FROM_FS = "ws.settings.delete.from.fs";
+ public static final String WS_SETTINGS_NOT_LEGAL_WS_DIR = "ws.settings.not.legal.ws.dir";
+ public static final String WS_SETTINGS_ENTER_USER_NAME = "ws.settings.enter.user.name";
+ public static final String WS_SETTINGS_CREATE_NEW_USER = "ws.settings.create.new.user";
+ public static final String WS_SETTINGS_USER_EXISTS_ALREADY = "ws.settings.user.exists.already";
+ public static final String WS_SETTINGS_REMOVE_USER = "ws.settings.remove.user";
+ public static final String WS_SETTINGS_NOT_LEGAL_USER_DIR = "ws.settings.not.legal.user.dir";
+ public static final String WS_SETTINGS_CHOOSE_OTHER_NAME = "ws.settings.choose.other.name";
+ public static final String WS_SETTINGS_NAME_CONFLICT = "ws.settings.name.conflict";
+ public static final String WS_SETTINGS_COULD_NOT_IMPORT_USER = "ws.settings.could.not.import.user";
+ public static final String WS_CREATION_PANEL_NAME = "ws.creation.panel.name";
+ public static final String WS_CREATION_PANEL_LOCATION = "ws.creation.panel.location";
+ public static final String WS_CREATION_PANEL_BROWSE = "ws.creation.panel.browse";
+ public static final String WELCOME_WORKSPACE = "welcome.workspace";
+ public static final String WELCOME_USERNAME = "welcome.username";
+ public static final String WELCOME_SETTINGS = "welcome.settings";
+ public static final String WELCOME_ENTER = "welcome.enter";
+ public static final String WELCOME_TITLE = "welcome.title";
+ public static final String WELCOME_WRONG_PW = "welcome.wrong.pw";
+ public static final String WELCOME_ENTER_PW = "welcome.enter.pw";
+ public static final String WELCOME_COULD_NOT_ENTER_USER = "welcome.could.not.enter.user";
+ public static final String WS_COULD_NOT_STORE_GC = "storage.could.not.store.gc";
+ public static final String GERMAN_ENGLISH = "pref.general.abz.german.english";
+ public static final String WS_SETTINGS_DAMAGED = "ws.settings.damaged";
+
+ public static final String WS_PROC_UNINITIALIZED = "procedure.unititialized";
+ public static final String WS_PROC_EXECUTABLE = "procedure.executable";
+ public static final String WS_PROC_NOT_EXECUTABLE = "procedure.not.executable";
+ public static final String WS_PROC_ERROR = "procedure.error";
+ public static final String ERROR_PROC_DOES_NOT_EXIST = "error.proc.does.not.exist";
+
+ public static final String WS_GENERATED_PROCEDURES = "ws.generated.procedure";
+ public static final String WS_REDEFINE_AMBIG_PROC = "ws.redefine.ambiguous.procedure";
+ public static final String ERROR_CALL_AMBIG_PROC = "error.call.ambiguous.procedure.name";
+ public static final String WS_COULD_NOT_CREATE_FILE = "ws.could.not.create.file";
+ public static final String WS_ERROR_TITLE = "ws.error.title";
+ public static final String WS_ERROR_COULD_NOT_LOAD_LOGO_FILES = "ws.error.could.not.load.logo.files";
+ public static final String I_AM_SORRY = "i.am.sorry";
+ public static final String WS_ERROR_USERDIR_NOT_DIR = "ws.error.userdir.not.dir";
+ public static final String WS_ERROR_COULD_NOT_STORE_CONFIGS = "ws.error.could.not.store.configs";
+ public static final String WS_ERROR_COULD_NOT_CREATE_FILE = "ws.error.could.not.create.logo.file";
+ public static final String NEW_FILE = "new.file";
+
+ public static final String CONTEST_ERROR_TITLE = "contest.error.title";
+ public static final String CONTEST_ERROR_RECORD_FAILED = "contest.error.could.not.record.file";
+ public static final String CONTEST_MODE_START = "contest.mode.start";
+ public static final String CONTEST_MODE_STOP = "contest.mode.stop";
+ public static final String CONTEST_MODE_FILENAME = "contest.mode.filename";
+ public static final String CONTEST_MODE_BONUS_FILENAME = "contest.mode.bonus.filename";
+ public static final String CONTEST_COULD_NOT_create = "contest.could.not.create";
+ public static final String CONTEST_COULD_NOT_STORE_ = "contest.could.not.store";
+
+ public static final String WS_FILENAME_EXISTS_ALREADY = "ws.filename.exists.already";
+ public static final String WS_ATTEMPT_OPEN_INEXISTENT_FILE = "ws.attempt.open.inexistent.file";
+ public static final String WS_ATTEMPT_CLOSE_NOT_OPEN_FILE = "ws.attempt.close.not.open.file";
+ public static final String WS_AUTO_SAVE_FAILED = "ws.automatic.save.failed";
+ public static final String GENERAL_ERROR_TITLE = "general.error.title";
+ public static final String EDITOR_DISPLAY_PROC_NOT_FOUND = "editor.display.procedure.not.found";
+
+ public static final String NAME_ERROR_TITLE = "name.error.dialog.title";
+ public static final String RENAME_INEXISTENT_FILE = "name.error.rename.inexistent.file";
+ public static final String EMPTY_NAME = "name.error.empty.name";
+ public static final String ILLEGAL_NAME = "illegal.name.msg";
+
+ public static final String COLOR_BLUE = "color.blue";
+ public static final String COLOR_DARK = "color.dark";
+ public static final String COLOR_GRAY = "color.gray";
+ public static final String COLOR_GREEN = "color.green";
+ public static final String COLOR_LIGHT = "color.light";
+ public static final String COLOR_ORANGE = "color.orange";
+ public static final String COLOR_PURPLE = "color.purple";
+ public static final String COLOR_RED = "color.red";
+ public static final String COLOR_YELLOW = "color.yellow";
+ public static final String LOGO_FILE_HAS_ERROR = "logo.file.has.error";
+ public static final String ERROR_WHILE_CREATING_EDITOR = "error.while.creating.editor";
+
+ public static final String LOGO_ERROR_NO_ERROR = "error.no.error";
+ public static final String LOGO_ERROR_MISSING_TO = "error.missing.to";
+ public static final String LOGO_ERROR_MISSING_NAME = "error.missing.name";
+ public static final String LOGO_ERROR_NAME_IS_NUMBER = "error.name.is.number";
+ public static final String LOGO_ERROR_NAME_SPECIAL = "error.name.special";
+ public static final String LOGO_ERROR_VAR_WHITE_AFTER_COLON = "error.var.white.after.colon";
+ public static final String LOGO_ERROR_VAR_SPECIAL = "error.var.special";
+ public static final String LOGO_ERROR_VAR_IS_NUMBER = "error.var.is.number";
+ public static final String LOGO_ERROR_VAR_MISSING_COLON = "error.var.missing.colon";
+ public static final String LOGO_ERROR_OPT_VAR_BRACKET = "error.opt.var.bracket";
+ public static final String LOGO_ERROR_VAR_EXTRA_CHARS = "error.var.extra.chars";
+ public static final String LOGO_ERROR_MISSING_EXPR = "error.missing.expr";
+ public static final String LOGO_ERROR_MORE_CHARS_AFTER_END = "error.more.chars.after.end";
+ public static final String LOGO_ERROR_MISSING_END = "error.missing.end";
+ public static final String LOGO_ERROR_TO_BEFORE_END = "error.to.before.end";
+ public static final String LOGO_ERROR_NAME_IS_KEY_WORD = "error.name.is.key.word";
+ public static final String LOGO_ERROR_AMBIGUOUS = "error.procedure.ambiguous";
+
+ public static final String HIST_MSG_PROCEDURES_UNDEFINED = "hist.msg.procedures.undefined";
+ public static final String ERROR_NETWORK_CONTEXT = "error.network.context";
+
+ public static final String DIALOG_YES = "dialog.yes";
+ public static final String DIALOG_NO = "dialog.no";
+ public static final String US_COULD_NOT_STORE_RECENT_DATA = "us.could.not.store.recent.data";
+ public static final String WS_DOES_NOT_EXIST = "ws.does.not.exist";
+ public static final String WS_NOT_A_WORKSPACE_DIRECTORY = "ws.not.a.workspace.dir";
+ public static final String APP_HELLO = "app.hello";
+
+ public static final String FILE_CONTAINS_ERRORS = "file.contains.errors";
+
+ public static final String US_IMPORT = "us.import";
+ public static final String US_EXPORT = "us.export";
+ public static final String US_SAVE_IMAGE = "us.save.image";
+ public static final String US_EXPORT_MSG = "us.export.msg";
+
+}
diff --git a/logo/src/xlogo/messages/Messenger.java b/logo/src/xlogo/messages/Messenger.java new file mode 100644 index 0000000..d27dc9c --- /dev/null +++ b/logo/src/xlogo/messages/Messenger.java @@ -0,0 +1,33 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages;
+
+public interface Messenger
+{
+ public void dispatchMessage(String message);
+}
diff --git a/logo/src/xlogo/messages/async/AbstractAsyncMessenger.java b/logo/src/xlogo/messages/async/AbstractAsyncMessenger.java new file mode 100644 index 0000000..e75fec5 --- /dev/null +++ b/logo/src/xlogo/messages/async/AbstractAsyncMessenger.java @@ -0,0 +1,141 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import xlogo.Application;
+
+/**
+ * <p> This class was implemented with the purpose to decouple various parts of XLogo4Schools from the Application-class. <br>
+ * Before, almost every part had to have a reference to {@link Application}. Without the reference to the current frame, no errors or other messages could be displayed.
+ * <p>
+ * This class also allows to dispatch messages before a Medium (such as JFrame for dialogs or HistoryPanel for history messages) is set up. Therefore it maintains an internal queue of messages.
+ * As soon as the medium is set up and ready, the queue will be emptied by displaying all the messages, one after the other.
+ * <p>
+ * This class is thread-safe.
+ */
+public abstract class AbstractAsyncMessenger<M extends AsyncMessage<T>, T> implements AsyncMessenger
+{
+ AsyncMediumAdapter<M, T> mediumAdapter;
+ private ConcurrentLinkedQueue<M> messageQueue;
+ private boolean isWorking;
+
+ public AbstractAsyncMessenger()
+ {
+ messageQueue = new ConcurrentLinkedQueue<M>();
+ }
+
+ /**
+ * @return whether medium is set (not null) and ready
+ */
+ protected synchronized boolean isMediumReady()
+ {
+ return mediumAdapter != null && mediumAdapter.isReady();
+ }
+
+ /**
+ * @return Whether the worker thread is currently not working off the message
+ */
+ protected synchronized boolean isReady()
+ {
+ return isMediumReady() && !isWorking;
+ }
+
+ private synchronized void setIsWorking(boolean isWorking)
+ {
+ this.isWorking = isWorking;
+ }
+
+ public synchronized void setMedium(AsyncMediumAdapter<M, T> medium)
+ {
+ this.mediumAdapter = medium;
+
+ if (medium == null)
+ return;
+
+ if (isReady())
+ workOffQueue();
+ else
+ medium.addMediumReadyListener(this);
+ }
+
+ /**
+ * This should be called by
+ */
+ public void onMediumReady()
+ {
+ workOffQueue();
+ }
+
+ protected void installReadyEventListener(AsyncMediumAdapter<M, T> medium)
+ {
+ medium.addMediumReadyListener(this);
+ }
+
+ protected synchronized AsyncMediumAdapter<M, T> getMedium()
+ {
+ return mediumAdapter;
+ }
+
+ protected void deliverMessage(M message)
+ {
+ messageQueue.add(message);
+ if (isReady())
+ workOffQueue();
+ }
+
+ protected synchronized void workOffQueue()
+ {
+ setIsWorking(true);
+
+ new Thread(new Runnable(){
+ @Override
+ public void run()
+ {
+ while(!messageQueue.isEmpty() && isMediumReady())
+ {
+ M msg = messageQueue.peek();
+ prepareMessage(msg);
+ msg.displayMessage();
+ messageQueue.remove();
+ }
+
+ setIsWorking(false);
+ }
+ }).run();
+ }
+
+ /**
+ * @param message
+ */
+ protected void prepareMessage(M message){
+ message.setMedium(mediumAdapter.getMedium());
+ }
+
+}
diff --git a/logo/src/xlogo/messages/async/AsyncMediumAdapter.java b/logo/src/xlogo/messages/async/AsyncMediumAdapter.java new file mode 100644 index 0000000..a52c617 --- /dev/null +++ b/logo/src/xlogo/messages/async/AsyncMediumAdapter.java @@ -0,0 +1,35 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async;
+
+public interface AsyncMediumAdapter<MessageType extends AsyncMessage<Medium>, Medium>
+{
+ public void addMediumReadyListener(AsyncMessenger messenger);
+ public boolean isReady();
+ public Medium getMedium();
+}
diff --git a/logo/src/xlogo/messages/async/AsyncMessage.java b/logo/src/xlogo/messages/async/AsyncMessage.java new file mode 100644 index 0000000..5c3c4a8 --- /dev/null +++ b/logo/src/xlogo/messages/async/AsyncMessage.java @@ -0,0 +1,51 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async;
+
+import xlogo.messages.Message;
+
+public abstract class AsyncMessage<Medium> extends Message
+{
+ Medium medium;
+
+ public AsyncMessage(String title, String message)
+ {
+ super(title, message);
+ }
+
+ public void setMedium(Medium medium)
+ {
+ this.medium = medium;
+ }
+
+ public Medium getMedium()
+ {
+ return medium;
+ }
+
+}
diff --git a/logo/src/xlogo/messages/async/AsyncMessenger.java b/logo/src/xlogo/messages/async/AsyncMessenger.java new file mode 100644 index 0000000..99b3c3c --- /dev/null +++ b/logo/src/xlogo/messages/async/AsyncMessenger.java @@ -0,0 +1,35 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async;
+
+import xlogo.messages.Messenger;
+
+public interface AsyncMessenger extends Messenger
+{
+ public void onMediumReady();
+}
diff --git a/logo/src/xlogo/messages/async/dialog/DialogMessage.java b/logo/src/xlogo/messages/async/dialog/DialogMessage.java new file mode 100644 index 0000000..2ab099d --- /dev/null +++ b/logo/src/xlogo/messages/async/dialog/DialogMessage.java @@ -0,0 +1,75 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async.dialog;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+import xlogo.messages.async.AsyncMessage;
+
+class DialogMessage extends AsyncMessage<JFrame>
+{
+ private DialogMessageType type;
+
+ public DialogMessage(DialogMessageType type, String title, String message)
+ {
+ super(title, message);
+ this.type = type;
+ }
+
+ @Override
+ public void displayMessage()
+ {
+ JOptionPane.showMessageDialog(getMedium(),
+ getMessage(),
+ getTitle(),
+ type.getOptionPaneInt());
+ }
+
+ public enum DialogMessageType
+ {
+ ERROR(JOptionPane.ERROR_MESSAGE),
+ WARNING(JOptionPane.WARNING_MESSAGE),
+ PLAIN(JOptionPane.PLAIN_MESSAGE),
+ QUESTION(JOptionPane.QUESTION_MESSAGE),
+ INFORMATION(JOptionPane.INFORMATION_MESSAGE);
+
+ private int msgType;
+
+ private DialogMessageType(int optionPaneInt)
+ {
+ msgType = optionPaneInt;
+ }
+
+ public int getOptionPaneInt()
+ {
+ return msgType;
+ }
+ }
+
+}
diff --git a/logo/src/xlogo/messages/async/dialog/DialogMessenger.java b/logo/src/xlogo/messages/async/dialog/DialogMessenger.java new file mode 100644 index 0000000..95fa512 --- /dev/null +++ b/logo/src/xlogo/messages/async/dialog/DialogMessenger.java @@ -0,0 +1,74 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async.dialog;
+
+import javax.swing.JFrame;
+
+import xlogo.messages.async.AbstractAsyncMessenger;
+import xlogo.messages.async.AsyncMessage;
+import xlogo.messages.async.dialog.DialogMessage.DialogMessageType;
+
+/**
+ * The MessageManager is a singleton class that can be globally used to display error messages in dialogs.
+ *
+ * @author Marko Zivkovic
+ *
+ */
+public class DialogMessenger extends AbstractAsyncMessenger<AsyncMessage<JFrame>, JFrame>
+{
+ /**
+ * Implementation for thread-safe singleton found here : http://www.theserverside.de/singleton-pattern-in-java/ [accessed 14.8.2013]
+ */
+ private static DialogMessenger instance = new DialogMessenger();
+
+ public static DialogMessenger getInstance()
+ {
+ return instance;
+ }
+
+ protected DialogMessenger()
+ {
+ super();
+ }
+
+ @Override
+ public void dispatchMessage(String message)
+ {
+ deliverMessage(new DialogMessage(DialogMessageType.PLAIN, "", message));
+ }
+
+ public void dispatchMessage(String title, String message)
+ {
+ deliverMessage(new DialogMessage(DialogMessageType.PLAIN, title, message));
+ }
+
+ public void dispatchError(String title, String message)
+ {
+ deliverMessage(new DialogMessage(DialogMessageType.ERROR, title, message));
+ }
+}
diff --git a/logo/src/xlogo/messages/async/history/HistoryMessage.java b/logo/src/xlogo/messages/async/history/HistoryMessage.java new file mode 100644 index 0000000..ae3222c --- /dev/null +++ b/logo/src/xlogo/messages/async/history/HistoryMessage.java @@ -0,0 +1,79 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async.history;
+
+import xlogo.messages.async.AsyncMessage;
+
+class HistoryMessage extends AsyncMessage<HistoryWriter>
+{
+
+ public HistoryMessage(HistoryMessageType messageType, String message)
+ {
+ super(messageType.toString(), message);
+ }
+
+ @Override
+ public void displayMessage()
+ {
+ getMedium().writeMessage(getTitle(), getMessage());
+ }
+
+
+ public enum HistoryMessageType
+ {
+ /*
+ * Note: String values inherited from XLogo, such that HistoryPanel must not be changed too much (for now)
+ */
+
+ /**
+ * Syntax highlighted
+ */
+ NORMAL("normal"),
+ ERROR("erreur"),
+ /**
+ * When the user leaves the editor "You defined ..."
+ */
+ COMMENT("commentaire"),
+ /**
+ * Commands write or print
+ */
+ LOGO_OUTPUT("perso");
+
+ String type;
+
+ private HistoryMessageType(String type)
+ {
+ this.type = type;
+ }
+
+ public String toString()
+ {
+ return type;
+ }
+ }
+}
diff --git a/logo/src/xlogo/messages/async/history/HistoryMessenger.java b/logo/src/xlogo/messages/async/history/HistoryMessenger.java new file mode 100644 index 0000000..e6bbbf7 --- /dev/null +++ b/logo/src/xlogo/messages/async/history/HistoryMessenger.java @@ -0,0 +1,85 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async.history;
+
+import xlogo.gui.HistoryPanel;
+import xlogo.messages.async.AbstractAsyncMessenger;
+import xlogo.messages.async.AsyncMessage;
+import xlogo.messages.async.history.HistoryMessage.HistoryMessageType;
+
+/**
+ * This class helps to decouple various old XLogo classes from {@link Application} and {@link HistoryPanel}
+ * @author Marko Zivkovic
+ * @superclass {@link AbstractAsyncMessenger}
+ */
+public class HistoryMessenger extends AbstractAsyncMessenger<AsyncMessage<HistoryWriter>, HistoryWriter>
+{
+ /**
+ * Implementation for thread-safe singleton found here : http://www.theserverside.de/singleton-pattern-in-java/ [accessed 14.8.2013]
+ */
+ private static HistoryMessenger instance = new HistoryMessenger();
+
+ private HistoryMessenger() {}
+
+ public static HistoryMessenger getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Normal Logo style : syntax highlighter
+ */
+ @Override
+ public void dispatchMessage(String message)
+ {
+ deliverMessage(new HistoryMessage(HistoryMessageType.NORMAL, message));
+ }
+
+ /**
+ * Printed in red.
+ * @param message
+ */
+ public void dispatchError(String message)
+ {
+ deliverMessage(new HistoryMessage(HistoryMessageType.ERROR, message));
+ }
+
+ /**
+ * Printed in blue
+ * @param message
+ */
+ public void dispatchComment(String message)
+ {
+ deliverMessage(new HistoryMessage(HistoryMessageType.COMMENT, message));
+ }
+
+ public void dispatchLogoOutput(String message)
+ {
+ deliverMessage(new HistoryMessage(HistoryMessageType.LOGO_OUTPUT, message));
+ }
+}
\ No newline at end of file diff --git a/logo/src/xlogo/messages/async/history/HistoryWriter.java b/logo/src/xlogo/messages/async/history/HistoryWriter.java new file mode 100644 index 0000000..65bcff6 --- /dev/null +++ b/logo/src/xlogo/messages/async/history/HistoryWriter.java @@ -0,0 +1,33 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.messages.async.history;
+
+public interface HistoryWriter
+{
+ public void writeMessage(String messageType, String message);
+}
diff --git a/logo/src/xlogo/storage/Storable.java b/logo/src/xlogo/storage/Storable.java new file mode 100644 index 0000000..ad5adf2 --- /dev/null +++ b/logo/src/xlogo/storage/Storable.java @@ -0,0 +1,267 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.StringTokenizer;
+
+public abstract class Storable implements Serializable
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3506253939129765438L;
+
+ /**
+ * The file's name with extension
+ */
+ private String fileName;
+
+ /**
+ * The Directory where this is stored
+ */
+ private File location;
+
+ /**
+ * Dirty : an object is dirty if it was changed since it was loaded or stored the last time.
+ */
+ private transient boolean dirty = true;
+
+ /**
+ * Will not be stored if virtual.
+ */
+ private transient boolean isVirtual = false;
+
+ /*
+ * PATH BUILDERS
+ */
+
+ public static File getFile(File dir, String fileName)
+ {
+ return new File(dir.toString() + File.separator + fileName);
+ }
+
+
+ public static File getDirectory(File prefix, String dirName)
+ {
+ return new File(prefix.toString() + File.separator + dirName);
+ }
+
+ /*
+ * Abstract
+ */
+
+ /**
+ * Store this object to the file specified by {@link #getFilePath()} if it is dirty
+ * @throws IOException
+ */
+ public abstract void store() throws IOException;
+
+ public abstract void storeCopyToFile(File file) throws IOException, IllegalArgumentException;
+
+ /**
+ * Store this object to the specified file, regardless of whether this is virtual or not.
+ * @param file
+ * @throws IOException
+ * @throws IllegalArgumentException - null is not accepted
+ */
+
+ /*
+ * file name & location
+ */
+
+ public abstract String getFileNameExtension();
+
+ public String getFileName()
+ {
+ return getPlainName() + getFileNameExtension();
+ }
+
+ /**
+ * @return FileName without file extension
+ */
+ public String getPlainName()
+ {
+ return fileName;
+ }
+
+ /**
+ * If this exists on the file system, that file will be renamed. <p>
+ * If newFileName already existed, it is deleted first.
+ * @param newFileName
+ * @throws IllegalArgumentException - If the provided name is not legal.
+ */
+ public void setFileName(String newFileName) throws IllegalArgumentException //TODO make sure callers conform with contract
+ {
+ if (newFileName == null || newFileName.length() == 0)
+ throw new IllegalArgumentException("File name must not be null or empty.");
+
+ if (!checkLegalName(newFileName))
+ throw new IllegalArgumentException("The chose file name contains illegal characters.");
+
+ String ext = getFileNameExtension();
+ String oldName = getPlainName();
+ String newName = newFileName.endsWith(ext) && newFileName.length() > ext.length() ?
+ newFileName.substring(0, newFileName.length() - ext.length())
+ : newFileName;
+
+ if (newName.equals(oldName) && oldName != null)
+ return;
+
+ if (isVirtual || oldName == null)
+ {
+ this.fileName = newFileName;
+ return;
+ }
+
+ File oldPath = getFilePath();
+ this.fileName = newName;
+
+ if (!oldPath.exists())
+ return;
+
+ File newPath = getFilePath();
+ if(newPath.exists())
+ newPath.delete();
+
+ oldPath.renameTo(newPath);
+ }
+
+ /**
+ * @return the directory where this should be stored to.
+ */
+ public File getLocation()
+ {
+ return location;
+ }
+
+ /**
+ * If the specified location does not exist yet, it is created using mkdirs.<br>
+ * To set null or a file that is not a directory or a directory with no write permissions is an error, as long as this is not virtual.<br>
+ * Setting location has no effect if this is virtual.<br>
+ * @param location - the directory where this should be stored to.
+ * @throws IOException
+ * @throws IOException If the specified location is not a directory or no write permissions exist, or the chosen name is not legal.
+ */
+ public void setLocation(File location) throws IllegalArgumentException
+ {
+ if(isVirtual)
+ return;
+
+ if (location == null)
+ throw new IllegalArgumentException("Location must not be null.");
+
+ if(!location.isDirectory())
+ {
+ location.mkdirs();
+ }
+ if(!location.isDirectory() || !location.canWrite())
+ throw new IllegalArgumentException("Cannot store this to specified location : " + location.toString());
+ this.location = location;
+ makeDirty();
+ }
+
+ /**
+ * @return the file where this should be stored to. Returns null if {@link getLocation()} returns null.
+ */
+ public File getFilePath()
+ {
+ if (getLocation() == null)
+ return null;
+ return getFile(getLocation(), getFileName());
+ }
+
+ /**
+ * @return whether the file specified by {@link #getFilePath()} exists.
+ */
+ public boolean existsPhysically()
+ {
+ if (getFilePath() == null)
+ return false;
+
+ return getFilePath().exists();
+ }
+
+ /*
+ * isDirty
+ */
+
+ public boolean isDirty() { return dirty; }
+
+ /**
+ * Should be called from every setter that sets a property that should be stored later
+ * @see StorableObject#makeClean()
+ */
+ protected void makeDirty() { dirty = true; }
+
+ /**
+ * Should be called whenever this was synchronized with its version on the file system (load or store)
+ * @see StorableObject#makeDirty()
+ */
+ protected void makeClean() { dirty = false; }
+
+
+ /*
+ * isVirtual
+ */
+
+ /**
+ * @see #isVirtual()
+ */
+ protected void makeVirtual() { isVirtual = true; }
+ /**
+ * A virtual object will not be stored on the file system, even though {@link store()} was called.
+ * This allows to use the application without having an actual user account and without automatic saving.
+ * @return
+ */
+ public boolean isVirtual() { return isVirtual; }
+
+ // The best I found : http://stackoverflow.com/questions/893977/java-how-to-find-out-whether-a-file-name-is-valid
+ // some windows specific chars are not contained...
+ public static final String ILLEGAL_NAME_CHARACTERS = "/\n\r\t\0\f`?*\\<>|\":";
+
+ public static boolean checkLegalName(String name)
+ {
+ if (name == null || name.length() == 0)
+ return false;
+
+ //StringTokenizer check = new StringTokenizer(name, ILLEGAL_NAME_CHARACTERS, true);
+ //return (check.countTokens() == 1);
+
+ for(char c : name.toCharArray())
+ {
+ if (ILLEGAL_NAME_CHARACTERS.indexOf(c) > -1)
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/logo/src/xlogo/storage/StorableDocument.java b/logo/src/xlogo/storage/StorableDocument.java new file mode 100644 index 0000000..104f64d --- /dev/null +++ b/logo/src/xlogo/storage/StorableDocument.java @@ -0,0 +1,198 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.util.Calendar;
+
+import xlogo.storage.user.UserConfig;
+import xlogo.storage.workspace.WorkspaceConfig;
+
+public abstract class StorableDocument extends Storable
+{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8218323197066522297L;
+
+ /**
+ * Contents of the file
+ */
+ private String text;
+
+ /**
+ * DEFINE TIME
+ */
+ private Calendar lastSync;
+
+ /**
+ * When this was created or saved the last time using {@link #store()}.
+ * Other store methods will not affect the time.
+ * @return
+ */
+ public Calendar getLastSync()
+ {
+ return lastSync;
+ }
+
+ public StorableDocument()
+ {
+ super();
+ text = "";
+ synced();
+ }
+
+ /**
+ * If this is not virtual, store the file in the source folder of the UserSpace, <br>
+ * and it also stores a copy in the backup folder, if this is required by {@link WorkspaceConfig#getNumberOfBackups()}.
+ */
+ @Override
+ public void store() throws IOException
+ {
+ synced();
+ if (isVirtual())
+ return;
+
+ File file = getFilePath();
+
+ if (!file.getParentFile().exists())
+ file.getParentFile().mkdirs();
+
+ storeCopyToFile(file);
+ }
+
+ protected void synced()
+ {
+ lastSync = Calendar.getInstance();
+ }
+
+ /**
+ *
+ * This is the counterpart to {@link #openFromAnyFile(UserConfig, File)} <br>
+ * Save (export) to any file on the file system.
+ * This works, even if the file is declared virtual.
+ */
+ @Override
+ public void storeCopyToFile(File file) throws IOException, IllegalArgumentException
+ {
+ try
+ {
+ FileOutputStream f = new FileOutputStream(file);
+ BufferedOutputStream b = new BufferedOutputStream(f);
+ OutputStreamWriter osw = new OutputStreamWriter(b, "UTF8");
+ osw.write(getText());
+ osw.close();
+ b.close();
+ f.close();
+
+ }
+ catch (FileNotFoundException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+
+ /**
+ * Deletes the current file path
+ */
+ public void delete()
+ {
+ if (isVirtual())
+ return;
+ File file = getFilePath();
+ if (file != null && file.exists())
+ file.delete();
+ }
+
+ public String getText()
+ {
+ if (text == null)
+ text = generateText();
+ return text;
+ }
+
+ /**
+ * This is invoked in {@link getText()} when the current text string is currently not defined. <br>
+ * Implement this to map your data to a string. This is the counterpart to {@link #parseText(BufferedReader)}.
+ * @return
+ */
+ protected abstract String generateText();
+
+ /**
+ * Setting text will invalidate the current text.
+ * The new text is then parsed to the concrete document structure.
+ * If possible, use {@link #setTextFromReader(BufferedReader)} for performance reasons.
+ * @param text
+ */
+ public void setText(String text)
+ {
+ invalidateText();
+ if(text == null)
+ return;
+
+ String replIndent = text.replaceAll("\t", " ");
+ StringReader sr = new StringReader(replIndent);
+ BufferedReader br = new BufferedReader(sr);
+ parseText(br);
+ }
+
+ /**
+ * Setting text will invalidate the current text.
+ * The new text is then parsed to the concrete document structure.
+ * @param br
+ */
+ public void setTextFromReader(BufferedReader br)
+ {
+ invalidateText();
+ parseText(br);
+ }
+
+ protected abstract void parseText(BufferedReader text);
+
+ /**
+ * @return Whether the set text could be parsed without errors.
+ */
+ public abstract boolean hasErrors();
+
+ /**
+ * Call this whenever the internal object structure has changed and it should be serialized first, using {@link #generateText()},
+ * when {@link #getText()} is called the next time.
+ */
+ protected void invalidateText()
+ {
+ this.text = null;
+ }
+}
diff --git a/logo/src/xlogo/storage/StorableObject.java b/logo/src/xlogo/storage/StorableObject.java new file mode 100644 index 0000000..085936a --- /dev/null +++ b/logo/src/xlogo/storage/StorableObject.java @@ -0,0 +1,148 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * The base class for anything that must be stored persistently.
+ * @author Marko Zivkovic
+ */
+public abstract class StorableObject extends Storable implements Serializable {
+
+ private static final long serialVersionUID = -1738873382662156052L;
+
+ /*
+ * PATH BUILDERS
+ */
+
+ /**
+ * @param c
+ * @return X4S_ClassName.ser
+ */
+ @SuppressWarnings("rawtypes")
+ public static String getX4SObjectFileName(Class c)
+ {
+ return "X4S_" + c.getSimpleName();
+ }
+
+ /**
+ * This naming scheme shall be used to store Objects in XLogo4Schools
+ * @param dir - where the instance of c should be stored.
+ * @param c - Class of Objects to be stored persistently
+ * @return pathname for dir/X4S_ClassName.ser
+ */
+ @SuppressWarnings("rawtypes")
+ public static String getFilePath(File dir, Class c)
+ {
+ return dir.toString() + File.separator + getX4SObjectFileName(c);
+ }
+
+ /**
+ * @param dir
+ * @param c
+ * @return file for pathname as defined by {@link #getFilePath(File, Class)}
+ */
+ @SuppressWarnings("rawtypes")
+ public static File getFile(File dir, Class c)
+ {
+ String path = getFilePath(dir, c) + ".ser";
+ return new File(path);
+ }
+
+ @Override
+ public String getFileNameExtension()
+ {
+ return ".ser";
+ }
+
+ /**
+ * Constructor. The FileName will be equal to
+ */
+ public StorableObject()
+ {
+ setFileName(getX4SObjectFileName(getClass()));
+ }
+
+ /*
+ * Store & Load
+ */
+
+ public void store() throws IOException
+ {
+ if(isDirty() && !isVirtual())
+ storeCopyToFile(getFilePath());
+ }
+
+ public void storeCopyToFile(File file) throws IOException, IllegalArgumentException
+ {
+ if(file == null)
+ throw new IllegalArgumentException("file must not be null.");
+
+ if (!isVirtual())
+ {
+ FileOutputStream fileOut = new FileOutputStream(file);
+ ObjectOutputStream out = new ObjectOutputStream(fileOut);
+ out.writeObject(this);
+ out.close();
+ fileOut.close();
+ }
+ makeClean();
+ }
+
+ /**
+ * Load a Storable object from the specified file
+ * @param file
+ * @return the loaded Storable
+ * @throws IOException
+ * @throws ClassNotFoundException
+ * @throws ClassCastException
+ */
+ public static StorableObject loadObject(File file) throws IOException, ClassNotFoundException, ClassCastException
+ {
+ FileInputStream fileIn = new FileInputStream(file);
+ ObjectInputStream in = new ObjectInputStream(fileIn);
+ Object object = in.readObject();
+ in.close();
+ fileIn.close();
+
+ if (!(object instanceof StorableObject))
+ throw new ClassCastException("The specified file (" + file.toString() + ") does not contain an instance of Storable: " + object.getClass().toString());
+
+ StorableObject storable = (StorableObject) object;
+ storable.makeClean();
+ return storable;
+ }
+
+}
diff --git a/logo/src/xlogo/storage/WSManager.java b/logo/src/xlogo/storage/WSManager.java new file mode 100644 index 0000000..73ef556 --- /dev/null +++ b/logo/src/xlogo/storage/WSManager.java @@ -0,0 +1,443 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage;
+
+import java.io.File;
+import java.io.IOException;
+
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.global.GlobalConfig;
+import xlogo.storage.user.UserConfig;
+import xlogo.storage.workspace.WorkspaceConfig;
+import xlogo.utils.Utils;
+
+/**
+ * Singleton Class for maintaining XLogo4Schools workspace, properties, reading and writing the various config files
+ * <p>
+ * The workspace can be entered without using a user account. in that case, one enters as a <b>virtual user</b>.
+ * While working as virtual user, the changes of preferences and the programs are not stored persistently.
+ * However, one can still export and import program files. This behavior is similar to XLogo's file management that uses the classic save/open machanisms.
+ * <br><br>
+ * <p> XLogo4Schools maintains the following files and directories on the file system
+ * <p>
+ * <li> user_home/X4S_GlobalConfig.ser - this file stores information about how to access the various workspaces ({@link GlobalConfig})</li>
+ *
+ * <p>
+ * <li> workspaceLocation/ - the folder of a workspace on the file system</li>
+ * <li> workspaceLocation/X4S_WorkspaceConfig.ser - Information about the workspace ({@link WorkspaceConfig})</li>
+ * <li> workspaceLocation/user_i/ - Project folder of "user i" in the workspace</li>
+ * <li> workspaceLocation/user_i/X4S_UserConfig.ser - User preferences and settings ({@link UserConfig})</li>
+ * <li> workspaceLocation/user_i/file_j_v.lgo - Version v of file_j.lgo (the last n versions are kept)</li>
+ * <li> workspaceLocation/user_i/competition_protocol_k.txt - the protocol of the k'th recorded competition/session of user i</li>
+ * <p>
+ * The files with the ending .ser are serialized objects. They are loaded from the file system when a workspace or userspace is entered.
+ * The files are (re-)written to the file system whenever a user space, a workspace or XLogo4Schools is left.
+ * <p>
+ * <br><br>
+ * <p> <b>Invariant</b> : there is always an active GlobalConfig, WorkspaceConfig, and UserConfig.
+ * <p> Upon creation or loading of some config, it decides which sub-config should be loaded.
+ * <li> GlobalConfig tries to enter the last used workspace if possible, otherwise it enters the virtual workspace. </li>
+ * <li> WorksspaceConfig tries to enter the last active userspace if possible, otherwise it enters the virtual userspace. </li>
+ *
+ * @author Marko
+ */
+public class WSManager {
+
+
+ /*
+ * Singleton instantiation
+ */
+ private static WSManager instance;
+
+ public static WSManager getInstance(){
+ if (instance == null){
+ instance = new WSManager();
+ }
+ return instance;
+ }
+
+ /**
+ * This is a shortcut for {@code WSManager.getInstance().getWorkspaceConfigInstance()}
+ * This is usually not null {@link WSManager},
+ * but it is for a short time while a workspace is being switched or the program fails to enter a workspace.
+ * @return
+ */
+ public static WorkspaceConfig getWorkspaceConfig()
+ {
+ return getInstance().getWorkspaceConfigInstance();
+ }
+
+ /**
+ * This is a shortcut for {@code WSManager.getInstance().getGlobalConfigInstance()}
+ * This is never null by definition of {@link WSManager}
+ * @return
+ */
+ public static GlobalConfig getGlobalConfig()
+ {
+ return getInstance().getGlobalConfigInstance();
+ }
+
+ /**
+ * This is a shortcut for {@code WSManager.getInstance().getUserConfigInstance()}
+ * <p> Note that this might be null, if no user has entered his user space.
+ * @return
+ */
+ public static UserConfig getUserConfig()
+ {
+ return getInstance().getUserConfigInstance();
+ }
+
+ private WSManager() {
+ globalConfig = GlobalConfig.create();
+ }
+
+ /*
+ * Config access
+ */
+ private final GlobalConfig globalConfig;
+
+ /**
+ * @return the instance of the GlobalConfig
+ */
+ public GlobalConfig getGlobalConfigInstance()
+ {
+ return globalConfig;
+ }
+
+ /**
+ * @return the active workspace
+ */
+ public WorkspaceConfig getWorkspaceConfigInstance()
+ {
+ return getGlobalConfigInstance().getCurrentWorkspace();
+ }
+
+ /**
+ * @return the active user
+ */
+ public UserConfig getUserConfigInstance()
+ {
+ WorkspaceConfig wc = getWorkspaceConfigInstance();
+ if (wc == null)
+ return null;
+ else
+ return wc.getActiveUser();
+ }
+
+ /*
+ * WORKSPACE CONFIG : create, delete, enter
+ */
+
+ /**
+ * A new workspace is created in the defined directory.
+ * All Necessary files and folders are created and the workspace is logically added to the globalConfig.
+ * @see WorkspaceConfig#loadWorkspace(File)
+ * @param dir
+ * @param name
+ * @throws IOException
+ */
+ public void createWorkspace(File dir, String name) throws IOException
+ {
+ getGlobalConfigInstance().createWorkspace(dir, name);
+ }
+
+ public void deleteWorkspace(String wsName, boolean deleteFromDisk) throws SecurityException
+ {
+ File wsDir = getGlobalConfigInstance().getWorkspaceDirectory(wsName);
+ getGlobalConfigInstance().removeWorkspace(wsName);
+ if (deleteFromDisk)
+ deleteFullyRecursive(wsDir);
+ }
+
+ /**
+ * @param wsDir
+ * @throws IllegalArgumentException if wsDir is not a legal workspace directory
+ */
+ public void importWorkspace(File wsDir, String wsName) throws IllegalArgumentException
+ {
+ getGlobalConfigInstance().importWorkspace(wsDir, wsName);
+ }
+
+ /**
+ * Load the workspace
+ * <p>Always succeeds if workspaceName equals {@link WorkspaceConfig#VIRTUAL_WORKSPACE}
+ * @param workspaceName - the workspace to load and enter
+ * @throws IOException - if the old workspace could not be loaded
+ */
+ public void enterWorkspace(String workspaceName) throws IOException
+ {
+ getGlobalConfigInstance().enterWorkspace(workspaceName);
+ }
+
+ /* *
+ * @throws IOException If workspace could not be saved.
+ * /
+ public void leaveWorkspace() throws IOException
+ {
+ getGlobalConfig().leaveWorkspace();
+ }*/
+
+
+ /*
+ * USER CONFIG : create, delete, enter
+ */
+
+ /**
+ * A new user is created in the current workspace.
+ * All Necessary files and folders are created and the workspace is logically added to the globalConfig.
+ * @param username
+ */
+ public void createUser(String username)
+ {
+ getWorkspaceConfigInstance().createUser(username);
+ }
+
+ /**
+ * @param username
+ * @param deleteFromDisk
+ */
+ public void deleteUser(String username, boolean deleteFromDisk)
+ {
+ File location = StorableObject.getDirectory(getWorkspaceConfigInstance().getLocation(), username);
+ getWorkspaceConfigInstance().removeUser(username);
+ if (deleteFromDisk)
+ {
+ try{
+ deleteFullyRecursive(location);
+ }
+ catch(SecurityException e) {
+ System.out.println("Files not deleted: " + e.toString());
+ }
+ }
+ }
+
+ public void importUser(File userDir, String newUserName) throws IllegalArgumentException, IOException
+ {
+ getWorkspaceConfigInstance().importUser(userDir, newUserName);
+ }
+
+ /**
+ * @throws IOException If the old userConfig could not be stored.
+ */
+ public void enterUserSpace(String name) throws IOException
+ {
+ if (getWorkspaceConfigInstance() == null)
+ throw new IllegalStateException("Must be in WorkspaceDirectory first to enter UserSpace.");
+
+ getWorkspaceConfigInstance().enterUserSpace(name);
+ }
+
+ /*
+ * DIRECTORIES & FILE MANIPULATION
+ */
+
+ public static File[] listDirectories(File dir)
+ {
+ return dir.listFiles(new java.io.FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ });
+ }
+
+ /**
+ * A directory is considered a workspace directory,
+ * if it contains a file for {@link WorkspaceConfig}, as defined by {@link StorableObject#getFilePath(File, Class)}
+ * @param dir
+ * @return
+ */
+ public static boolean isWorkspaceDirectory(File dir)
+ {
+ if (dir == null)
+ return false;
+
+ if(!dir.isDirectory())
+ return false;
+
+ File wcf = WorkspaceConfig.getFile(dir, WorkspaceConfig.class);
+ if(!wcf.isFile())
+ return false;
+
+ return true;
+ }
+
+ /**
+ * A directory is considered a user directory,
+ * if it contains a file for {@link UserConfig}, as defined by {@link StorableObject#getFilePath(File, Class)}
+ * @param dir
+ * @return
+ */
+ public static boolean isUserDirectory(File dir)
+ {
+ if (dir == null)
+ return false;
+
+ if(!dir.isDirectory())
+ return false;
+
+ File ucf = UserConfig.getFile(dir, UserConfig.class);
+ if(!ucf.isFile())
+ return false;
+
+ return true;
+ }
+
+ /**
+ * If "from" denotes a file, then "to" should be a file too.
+ * The contents of file "from" are copied to file "to".
+ * "to" is created, if it does not exists, using mkdirs.
+ *
+ * <p>If "from" denotes a directory, then "to" should be a directory too.
+ * The contents of directory "from" are copied recursively to directory "to".
+ * "to" is created, if it does not exists, using mkdirs.
+ * @param from - must exist
+ * @param to - must not exist
+ * @throws IOException
+ */
+ public static void copyFullyRecursive(File from, File to) throws IOException
+ {
+ if (!from.exists())
+ throw new IllegalArgumentException("'from' (" + from.toString() + ") must exist.");
+
+ if(from.isFile())
+ {
+ copyFile(from, to);
+ return;
+ }
+
+ // else to is directory
+ to.mkdirs();
+
+ for(File src : from.listFiles())
+ {
+ File dest = new File(to.toString() + File.separator + src.getName());
+ if (src.isFile())
+ {
+ copyFile(src, dest);
+ }else if (src.isDirectory())
+ {
+ copyFullyRecursive(src, dest);
+ }
+ }
+
+ }
+
+ public static void copyFile(File from, File to) throws IOException
+ {
+ if (!from.isFile())
+ throw new IllegalArgumentException("File 'from' (" + from.toString() + ") must exist.");
+
+ if (to.exists())
+ {
+ if (!to.isFile())
+ throw new IllegalArgumentException("File 'to' (" + from.toString() + ") must be a file.");
+ }
+ else
+ {
+ File parent = to.getParentFile();
+ if (!parent.exists())
+ to.getParentFile().mkdirs();
+ }
+
+ Utils.copyFile(from, to);
+ }
+
+ /**
+ * @param victim
+ * @throws SecurityException If one tries to delete some directory that is not under control of this application (Workspace or User)
+ */
+ public static void deleteFullyRecursive(File victim) throws SecurityException
+ {
+ if (!victim.exists())
+ return;
+
+ if (victim.isFile())
+ {
+ victim.delete();
+ return;
+ }
+
+ if (!isGlobalConfigDirectory(victim) && !isWorkspaceDirectory(victim) && !isUserDirectory(victim))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ "Security Violation",
+ "Attempt to delete a directory that is not under control of this application: " + victim.toString());
+ throw new SecurityException();
+ }
+
+ // Delete all sub-directories
+ for (File f : victim.listFiles())
+ {
+ uncheckedRecursiveDelete(f);
+ victim.delete();
+ }
+
+ // Delete directory itself
+ victim.delete();
+ }
+
+ /**
+ * CAUTION : Don't use this unless you are sure that the directory you want to delete is a XLogo4Schools directory.
+ * Otherwise it could delete just everything.
+ * @param victim
+ */
+ private static void uncheckedRecursiveDelete(File victim)
+ {
+ if (!victim.exists())
+ return;
+
+ if (victim.isFile())
+ {
+ victim.delete();
+ return;
+ }
+
+ // Delete all sub-directories
+ for (File f : victim.listFiles())
+ {
+ uncheckedRecursiveDelete(f);
+ victim.delete();
+ }
+
+ // Delete directory itself
+ victim.delete();
+ }
+
+ public static boolean isGlobalConfigDirectory(File dir)
+ {
+ if(!dir.isDirectory())
+ return false;
+
+ String name = dir.getName();
+ if(!name.startsWith("X4S_"))
+ return false;
+
+
+ return true;
+ }
+}
diff --git a/logo/src/xlogo/storage/global/GlobalConfig.java b/logo/src/xlogo/storage/global/GlobalConfig.java new file mode 100644 index 0000000..6cd9124 --- /dev/null +++ b/logo/src/xlogo/storage/global/GlobalConfig.java @@ -0,0 +1,545 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.global;
+
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+import xlogo.Logo;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.StorableObject;
+import xlogo.storage.WSManager;
+import xlogo.storage.workspace.WorkspaceConfig;
+
+/**
+ * This Config is stored in default location : "user.home". It contains information about the currently used workspaces on the computer
+ * @author Marko Zivkovic
+ */
+public class GlobalConfig extends StorableObject implements Serializable {
+
+ private static final long serialVersionUID = 2787615728665011813L;
+
+ public static final String LOGO_FILE_EXTENSION = ".lgo";
+ public static boolean DEBUG = true; // TODO set false
+
+ /**
+ * Creates the global config at default location, together with a virtual workspace
+ */
+ protected GlobalConfig()
+ {
+ try
+ {
+ setLocation(getDefaultLocation());
+ }
+ catch (IllegalArgumentException ignore) { } // This is thrown if name illegal, but it is legal
+ workspaces = new TreeMap<String, String>();
+ workspaces.put(WorkspaceConfig.VIRTUAL_WORKSPACE, "");
+ }
+
+ /**
+ * If GlobalConfig exists on the file system in default location, it is loaded, otherwise it will be created there.
+ * @return
+ */
+ public static GlobalConfig create()
+ {
+ File gcf = getFile(getDefaultLocation(), GlobalConfig.class);
+
+ GlobalConfig globalConfig = null;
+
+ try
+ {
+ if (gcf.exists())
+ globalConfig = (GlobalConfig) loadObject(gcf);
+ else
+ {
+ globalConfig = new GlobalConfig();
+ globalConfig.store();
+ }
+ }catch(Exception e)
+ {
+ // Best effort : We will try to operate the program without storing anything on disk
+ globalConfig = getNewVirtualInstance();
+ DialogMessenger.getInstance().dispatchError("Error while setting up XLogo4Schools", "Could not create or open GlobalConfig file at default location: " + e.toString());
+ }
+ globalConfig.enterLastUsedWorkspace();// This is used to have a workspace ready at the beginning, without any user interaction.
+ return globalConfig;
+ }
+
+ public static GlobalConfig getNewVirtualInstance()
+ {
+ GlobalConfig gc = new GlobalConfig();
+ gc.makeVirtual();
+ return gc;
+ }
+
+ /**
+ * @return File from system property "user.home"
+ */
+ public static File getDefaultLocation()
+ {
+ return new File(System.getProperty("user.home"));
+ }
+
+ /*
+ * Physical Workspaces (stored on file system)
+ */
+
+ public void createWorkspace(File dir, String workspaceName) throws IOException
+ {
+ if (WorkspaceConfig.createNewWorkspace(dir, workspaceName) != null)
+ addWorkspace(workspaceName, dir.toString());
+ }
+
+ public void importWorkspace(File workspaceDir, String wsName)
+ {
+ if(!WSManager.isWorkspaceDirectory(workspaceDir))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.WS_ERROR_TITLE),
+ workspaceDir + " " + Logo.messages.getString(MessageKeys.WS_NOT_A_WORKSPACE_DIRECTORY));
+ return;
+ }
+
+ addWorkspace(wsName, workspaceDir.getParent());
+ }
+
+ /**
+ * Load the specified workspace from the file system.
+ * @param workspaceName
+ * @return the specified workspace or null if it does not exist.
+ * @throws IOException
+ */
+ private WorkspaceConfig retrieveWorkspace(String workspaceName) throws IOException
+ {
+ if(!existsWorkspace(workspaceName))
+ {
+ System.out.print("Attempting to load an inexistent workspace.");
+ return null;
+ }
+ File dir = getWorkspaceLocation(workspaceName);
+ WorkspaceConfig wc = WorkspaceConfig.loadWorkspace(dir, workspaceName);
+
+ if (wc == null)
+ {
+ WSManager.getInstance().deleteWorkspace(workspaceName, false);
+ }
+ return wc;
+
+ }
+
+ /*
+ * Logical Workspaces (name and location stored in Map)
+ */
+
+ private TreeMap<String,String> workspaces;
+
+ /**
+ * @param workspaceName
+ * @param location where the workspace is located: location/workspaceName/
+ */
+ public void addWorkspace(String workspaceName, String location)
+ {
+ workspaces.put(workspaceName, location);
+ makeDirty();
+ notifyWorkspaceListChanged();
+ }
+
+ public void removeWorkspace(String workspaceName)
+ {
+ workspaces.remove(workspaceName);
+ makeDirty();
+ notifyWorkspaceListChanged();
+ }
+
+ /**
+ * @param wsName
+ * @return the location of the workspace in the file system, or null if the workspace does not exist
+ */
+ public File getWorkspaceLocation(String wsName)
+ {
+ String location = workspaces.get(wsName);
+ if(location == null)
+ return null;
+ return new File(location);
+ }
+
+ public File getWorkspaceDirectory(String wsName)
+ {
+ File wsLocation = getWorkspaceLocation(wsName);
+ if(wsLocation == null)
+ return null;
+ return new File(wsLocation.toString() + File.separator + wsName);
+ }
+
+ /**
+ * @return the names of all existing workspaces
+ */
+ public String[] getAllWorkspaces()
+ {
+ return (String[]) workspaces.keySet().toArray(new String[workspaces.size()]);
+ }
+
+ /**
+ * A workspace exists logically, if its location is known by the GlobalConfig.
+ * @param workspace
+ * @return
+ */
+ public boolean existsWorkspace(String workspace)
+ {
+ return getWorkspaceLocation(workspace) != null;
+ }
+
+ /*
+ * Last used workspace
+ */
+ private String lastUsedWorkspace;
+
+ public String getLastUsedWorkspace()
+ {
+ return lastUsedWorkspace;
+ }
+
+ /**
+ * Succeeds if the workspace exists
+ * @param workspace
+ */
+ private void setLastUsedWorkspace(String workspace)
+ {
+ if(existsWorkspace(workspace))
+ {
+ lastUsedWorkspace = new String(workspace);
+ makeDirty();
+ }
+ }
+
+ /**
+ * This is used to have a workspace ready at the beginning, without any user interaction.
+ * <p>
+ * Enters the workspace that was used the last time XLogo4Schools was run on this computer.
+ * If no regular workspace is available, a purely logical "virtual workspace" is entered instead.
+ */
+ private void enterLastUsedWorkspace()
+ {
+ String last = getLastUsedWorkspace();
+
+ if(last == null || !existsWorkspace(last))
+ last = WorkspaceConfig.VIRTUAL_WORKSPACE; // this exists, see constructor
+
+ try {
+ enterWorkspace(last);
+ } catch (IOException e1) {
+ try { enterWorkspace(WorkspaceConfig.VIRTUAL_WORKSPACE); } catch (IOException e2) { }
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "Cannot enter workspace: " + e1.toString());
+ }
+ }
+
+ /*
+ * Current Workspace
+ */
+
+ private transient WorkspaceConfig currentWorkspace;
+
+ public WorkspaceConfig getCurrentWorkspace()
+ {
+ return currentWorkspace;
+ }
+
+ /**
+ * Load the workspace
+ * <p>Always succeeds if workspaceName equals {@link WorkspaceConfig#VIRTUAL_WORKSPACE}
+ * @param workspaceName - the workspace to load and enter
+ * @throws IOException - if the workspace could not be loaded
+ */
+ public void enterWorkspace(String workspaceName) throws IOException
+ {
+ if(currentWorkspace != null)
+ {
+ leaveWorkspace();
+ }
+ currentWorkspace = retrieveWorkspace(workspaceName);
+ if (currentWorkspace == null)
+ currentWorkspace = retrieveWorkspace(WorkspaceConfig.VIRTUAL_WORKSPACE);
+
+ setLastUsedWorkspace(workspaceName);
+
+ notifyWorkspacEntered();
+ }
+
+ /**
+ * @throws IOException If workspace could not be saved.
+ */
+ void leaveWorkspace() throws IOException
+ {
+ if(currentWorkspace == null)
+ throw new IllegalStateException("Attempt to leave workspace without being in one.");
+
+ if(currentWorkspace.getActiveUser() != null)
+ {
+ currentWorkspace.leaveUserSpace();
+ }
+
+ if(currentWorkspace.isDirty())
+ currentWorkspace.store();
+
+ currentWorkspace = null;
+ }
+
+ /*
+ * Password protection
+ */
+
+ /**
+ * if null, no password is requested
+ */
+ private byte[] masterPassword = null;
+
+ /**
+ * Need old password to authenticate
+ * @param oldPw initially null
+ * @param newPw
+ * @return success
+ */
+ public boolean setNewPassword(String oldPw, String newPw)
+ {
+ if(masterPassword == null || authenticate(oldPw))
+ {
+ if (newPw == null)
+ masterPassword = null;
+ else
+ masterPassword = hash(newPw);
+ makeDirty();
+ return true;
+ }else
+ {
+ return false;
+ }
+ }
+
+ public boolean isPasswordRequired()
+ {
+ return masterPassword != null;
+ }
+
+ public boolean authenticate(String password){
+ if (masterPassword == null)
+ return true;
+ String entered = null;
+ if (password != null)
+ entered = new String(hash(password));
+ String master = new String(masterPassword);
+ boolean auth = master.equals(entered);
+ return auth;
+ }
+
+ /**
+ * Hashing the password with MD5 is enough for this application. We just don't want to store readable plain text.
+ * Note that MD5 is generally considered insecure for security critical applications.
+ * @param text
+ * @return hashed bytes
+ */
+ private byte[] hash(String text)
+ {
+ if (text == null)
+ return null;
+
+ byte[] bytesOfMessage;
+ try {
+ bytesOfMessage = text.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e1) {
+ bytesOfMessage = text.getBytes(); // this should not happen anyway
+ }
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ return md.digest(bytesOfMessage);
+ } catch (NoSuchAlgorithmException e) {
+ return bytesOfMessage; // this should not happen anyway
+ }
+ }
+
+ /*
+ * PATH
+ */
+
+ /**
+ * This Stack contains all startup files
+ */
+ private ArrayList<String> path = new ArrayList<String>();
+
+ public ArrayList<String> getPath() {
+ return path;
+ }
+
+
+ public void setPath(ArrayList<String> path) {
+ this.path = path;
+ makeDirty();
+ }
+
+ public static String getVersion() {
+ return "XLogo4Schools 0.0.1";
+ }
+
+ /**
+ * Note : should be equal as in {@link Lanceur}
+ */
+ //private static String PROPERTIES_PREFIX = "ch.ethz.abz.xlogo4schools";
+
+ /**
+ * Note : should be equal as in {@link Lanceur}
+ */
+ private static int DEFAULT_MEMORY_ALLOC = 128;
+
+ private static int maximumMemory;
+
+ /**
+ * The Maximum amount of memory that this application is allowed to consume by the JVM
+ * @return
+ */
+ public static int getMaximumMemory()
+ {
+ if (maximumMemory < 64)
+ {
+ // This doesn't work as expected :-(
+ //Preferences prefs = Preferences.systemRoot().node(PROPERTIES_PREFIX);
+ //maximumMemory = prefs.getInt("appMemory", DEFAULT_MEMORY_ALLOC);
+ maximumMemory = DEFAULT_MEMORY_ALLOC;
+ }
+ return maximumMemory;
+ }
+
+ private transient int maxMemoryAtNextStart = getMaximumMemory();
+
+ public static final Font[] fonts = GraphicsEnvironment
+ .getLocalGraphicsEnvironment().getAllFonts();// Toolkit.getDefaultToolkit().getFontList();
+
+ /**
+ * @return The amount of memory in MB that Lanceur will cause JVM to allocate to XLogo4Schools the next time this application is started.
+ */
+ public int getMaxMemoryAtNextStart()
+ {
+ if (maxMemoryAtNextStart < 64)
+ maxMemoryAtNextStart = getMaximumMemory();
+ return maxMemoryAtNextStart;
+ }
+ /**
+ * @see #getMaxMemoryAtNextStart()
+ * cannot set this below 64MB
+ * @param maxMemory
+ */
+ public void setMaxMemoryAtNextStart(int maxMemory)
+ {
+ if (maxMemory < 64)
+ return;
+ // This doesn't work as well :-(
+ //Preferences prefs = Preferences.systemRoot().node(PROPERTIES_PREFIX);
+ //prefs.putInt("appMemory", maxMemory);
+ }
+
+ static public int police_id(Font font) {
+ for (int i = 0; i < fonts.length; i++) {
+ if (fonts[i].getFontName().equals(font.getFontName()))
+ return i;
+ }
+ return 0;
+ }
+
+ /**
+ * The amount of memory that the memory checker allows the application to consume.
+ * It's 0.9*{@link #getMaximumMemory()}} in bytes.
+ */
+ public static long getMemoryThreshold()
+ {
+ return (long) (0.9 * ((long) GlobalConfig.getMaximumMemory() * 1024L * 1024L));
+ }
+
+
+ /* * * * * * *
+ * Event Handling
+ * * * * * * */
+
+ // workspace list change
+
+ private transient ArrayList<ActionListener> workspaceListChangeListeners;
+
+ public void addWorkspaceListChangeListener(ActionListener listener)
+ {
+ if (workspaceListChangeListeners == null)
+ workspaceListChangeListeners = new ArrayList<ActionListener>();
+ workspaceListChangeListeners.add(listener);
+ }
+
+ public void removeWorkspaceListChangeListener(ActionListener listener)
+ {
+ workspaceListChangeListeners.remove(listener);
+ }
+
+ private void notifyWorkspaceListChanged()
+ {
+ ActionEvent event = new ActionEvent(this, 0, "workspaceListChanged");
+ for (ActionListener listener : workspaceListChangeListeners)
+ listener.actionPerformed(event);
+ }
+
+ // enter workspace event
+
+ private transient ArrayList<ActionListener> enterWorkspaceListeners;
+
+ public void addEnterWorkspaceListener(ActionListener listener)
+ {
+ if (enterWorkspaceListeners == null)
+ enterWorkspaceListeners = new ArrayList<ActionListener>();
+ enterWorkspaceListeners.add(listener);
+ }
+
+ public void removeEnterWorkspaceListener(ActionListener listener)
+ {
+ enterWorkspaceListeners.remove(listener);
+ }
+
+ private void notifyWorkspacEntered()
+ {
+ if (enterWorkspaceListeners == null)
+ return;
+ ActionEvent event = new ActionEvent(this, 0, "workspaceEntered");
+ for (ActionListener listener : enterWorkspaceListeners)
+ listener.actionPerformed(event);
+ }
+
+}
diff --git a/logo/src/xlogo/storage/user/DrawQuality.java b/logo/src/xlogo/storage/user/DrawQuality.java new file mode 100644 index 0000000..565bb53 --- /dev/null +++ b/logo/src/xlogo/storage/user/DrawQuality.java @@ -0,0 +1,55 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.user;
+
+public enum DrawQuality {
+ NORMAL(0), HIGH(1), LOW(2);
+
+ int value;
+
+ private DrawQuality(int value)
+ {
+ this.value = value;
+ }
+
+ public int getValue()
+ {
+ return value;
+ }
+
+ public static DrawQuality getDrawQuality(int q)
+ {
+ switch(q)
+ {
+ case 2: return LOW;
+ case 1: return HIGH;
+ case 0:
+ default: return NORMAL;
+ }
+ }
+}
diff --git a/logo/src/xlogo/storage/user/LookAndFeel.java b/logo/src/xlogo/storage/user/LookAndFeel.java new file mode 100644 index 0000000..b4a2187 --- /dev/null +++ b/logo/src/xlogo/storage/user/LookAndFeel.java @@ -0,0 +1,32 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.user;
+
+public enum LookAndFeel {
+ JAVA, MOTIF, NATIVE;
+}
diff --git a/logo/src/xlogo/storage/user/PenShape.java b/logo/src/xlogo/storage/user/PenShape.java new file mode 100644 index 0000000..cce19ee --- /dev/null +++ b/logo/src/xlogo/storage/user/PenShape.java @@ -0,0 +1,52 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.user;
+
+public enum PenShape {
+ OVAL(1), SQUARE(0);
+
+ private int value;
+
+ private PenShape(int value)
+ {
+ this.value = value;
+ }
+
+ public int getValue()
+ {
+ return value;
+ }
+
+ public static PenShape getPenShape(int value)
+ {
+ if (value == 1)
+ return OVAL;
+ else
+ return SQUARE;
+ }
+}
diff --git a/logo/src/xlogo/storage/user/UserConfig.java b/logo/src/xlogo/storage/user/UserConfig.java new file mode 100644 index 0000000..c2f85c5 --- /dev/null +++ b/logo/src/xlogo/storage/user/UserConfig.java @@ -0,0 +1,918 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.user;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.awt.Toolkit;
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+import xlogo.Logo;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.StorableObject;
+import xlogo.storage.WSManager;
+import xlogo.storage.global.GlobalConfig;
+import xlogo.storage.workspace.WorkspaceConfig;
+import xlogo.utils.Utils;
+
+/**
+ * This Config is user specific. It is stored in the {@link #workspaceLocation} in the user's folder.
+ * @author Marko Zivkovic
+ */
+public class UserConfig extends StorableObject implements Serializable
+{
+ private static final long serialVersionUID = 8897730869795295485L;
+
+ // This was initially in Panel_Font, which is not used anymore.
+ public static final Font[] fontes = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
+
+ static public int police_id(Font font)
+ {
+ for (int i = 0; i < fontes.length; i++)
+ {
+ if (fontes[i].getFontName().equals(font.getFontName()))
+ return i;
+ }
+ return 0;
+ }
+
+
+ /**
+ * Name of the virtual user
+ * @see #isVirtual()
+ * @see #createVirtualUser()
+ */
+ public static final String VIRTUAL_USER = "Guest";
+
+ private static final String SRC_DIR_NAME = "src";
+ private static final String BACKUPS_DIR_NAME = "backups";
+ private static final String CONTEST_DIR_NAME = "contest";
+ private static final String COMMAND_LINE_RECORD_NAME = "commandLineHistory";
+
+ protected UserConfig()
+ {
+ super();
+ }
+
+ /*
+ * Static constructors
+ */
+
+ /**
+ * A virtual user can enter the application in a virtual workspace without having an actual user account on the file system. Hence nothing will be stored.
+ * A regular user (not virtual) will have his own folder in a regular workspace on the file system and all his preferences and files are stored there.
+ * To create a regular user, use {@link #createNewUser(File, String)},
+ * to load a regular user from the file system, user {@link #loadUser(File, String)}}.
+ * @see #isVirtual()
+ * @return a virtual workspace
+ */
+ public static UserConfig createVirtualUser()
+ {
+ UserConfig vuc = new UserConfig();
+ vuc.makeVirtual();
+ return vuc;
+ }
+
+ /**
+ * Loads the UserConfig from the specified user, or creates it, if it's missing or corrupted.
+ * If workspace specifies a virtual workspace, a virtual user is created instead. In that case the error manager is informed.
+ * @param workspace
+ * @param username
+ * @return the loaded UserConfig
+ * @throws IOException
+ */
+ public static UserConfig loadUser(WorkspaceConfig workspace, String username)
+ {
+ if(workspace.isVirtual())
+ return createVirtualUser();
+
+ if (!WSManager.isWorkspaceDirectory(workspace.getLocation()))
+ throw new IllegalArgumentException(workspace.toString() + " is not a valid Workspace.");
+
+ File userDirectory = getDirectory(workspace.getLocation(), username);
+ File userConfigFile = getFile(userDirectory, UserConfig.class);
+
+ UserConfig userConfig = null;
+
+ if(userConfigFile.exists())
+ {
+ try
+ {
+ userConfig = (UserConfig) loadObject(userConfigFile);
+ userConfig.setLocation(userDirectory);
+ }catch(ClassNotFoundException e1) { } // this won't happen
+ catch(IOException e2) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "Could not load user config file: " + e2.toString());
+ }
+ }
+
+ // If file is missing, it will be created again.
+ if (userConfig == null)
+ userConfig = createNewUser(workspace, username);
+
+ return userConfig;
+ }
+
+ /**
+ * If workspace is valid, then a new userSpace is created within that workspace.
+ * All necessary files and directories are created.
+ * <p>
+ * If a UserConfig file for the specified user already exists, it will be overwritten.
+ * If an error occurs while creating the file, the userConfig is just returned without saving to file.
+ * TODO In that case, the global ErrorManager is informed.
+ * @param workspace - must exist physically
+ * @param username
+ * @return the created UserConfig - or null, if one of the arguments was not legal
+ */
+ public static UserConfig createNewUser(WorkspaceConfig workspace, String username)
+ {
+ if(workspace.isVirtual())
+ return createVirtualUser();
+
+ if (!WSManager.isWorkspaceDirectory(workspace.getLocation()))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.WS_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.WS_DOES_NOT_EXIST));
+ return null;
+ }
+
+ if(!Storable.checkLegalName(username))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME));
+ return null;
+ }
+
+ File userDirectory = getDirectory(workspace.getLocation(), username);
+
+ if(!userDirectory.exists())
+ {
+ userDirectory.mkdirs();
+ }
+
+ // userDirectory exists
+
+ //File userFile = getFile(userDirectory, UserConfig.class);
+ UserConfig userConfig = new UserConfig();
+ try {
+ userConfig.setLocation(userDirectory);
+ userConfig.store();
+ } catch (IOException e) {
+ // Best effort. Continue without saving to disk.
+ System.out.print("Could not create UserConfig file: " + e.toString());
+ }
+
+ return userConfig;
+ }
+
+ public String getUserName()
+ {
+ if (isVirtual())
+ return VIRTUAL_USER;
+ String result = null;
+ if(getLocation() != null)
+ result = getLocation().getName();
+ return result;
+ }
+
+ /*
+ * File List
+ */
+
+ /**
+ * @return ../WorkspaceDir/UserDir/src/ or null if {@link #isVirtual()}
+ */
+ public File getSourceDirectory()
+ {
+ if (isVirtual())
+ return null;
+ return new File(getLocation().toString() + File.separator + SRC_DIR_NAME);
+ }
+
+ /**
+ * @param fileName - without extension
+ * @return
+ */
+ public File getLogoFilePath(String fileName)
+ {
+ if(isVirtual())
+ return null;
+
+ String path = getSourceDirectory().toString()
+ + File.separator + fileName
+ + GlobalConfig.LOGO_FILE_EXTENSION;
+
+ return new File(path);
+ }
+
+ /**
+ * @return ../WorkspaceDir/UserDir/backups/ or null if {@link #isVirtual()}
+ */
+ public File getBackupDirectory()
+ {
+ if (isVirtual())
+ return null;
+ return new File(getLocation().toString() + File.separator + BACKUPS_DIR_NAME);
+ }
+
+ /**
+ * @param fileName - without extension
+ * @return
+ */
+ public File getFileBackupDir(String fileName)
+ {
+ if (isVirtual())
+ return null;
+ String path = getBackupDirectory().toString()
+ + File.separator + fileName;
+ return new File(path);
+ }
+
+ public File getContestDir()
+ {
+ if (isVirtual())
+ return null;
+ return new File(getLocation().toString() + File.separator + CONTEST_DIR_NAME);
+ }
+
+ public File getContestFilePath(String fileName)
+ {
+ if (isVirtual())
+ return null;
+ String path = getContestDir().toString()
+ + File.separator + SRC_DIR_NAME
+ + File.separator + fileName
+ + GlobalConfig.LOGO_FILE_EXTENSION;
+ return new File(path);
+ }
+
+ public File getContestFileDir(String fileName)
+ {
+ if (isVirtual())
+ return null;
+ String path = getContestDir().toString()
+ + File.separator + fileName;
+ return new File(path);
+ }
+
+ /**
+ * @param fileName
+ * @return File descriptor for a backup file with the current timestamp
+ */
+ public File getBackupFilePath(String fileName)
+ {
+ String path = getFileBackupDir(fileName)
+ + File.separator + getTimeStamp()
+ + GlobalConfig.LOGO_FILE_EXTENSION;
+
+ return new File(path);
+ }
+
+ /**
+ * @param fileName
+ * @return File descriptor for a contest/record file with the current timestamp
+ */
+ public File getRecordFilePath(String fileName)
+ {
+ String path = getContestFileDir(fileName)
+ + File.separator + getTimeStamp()
+ + GlobalConfig.LOGO_FILE_EXTENSION;
+
+ return new File(path);
+ }
+
+ public File getCommandLineContestFile()
+ {
+ if (isVirtual())
+ return null;
+ String path = getContestDir().toString()
+ + File.separator + COMMAND_LINE_RECORD_NAME
+ + GlobalConfig.LOGO_FILE_EXTENSION;
+ return new File(path);
+ }
+
+ public static final String dateTimeFormat = "yyyy-MM-dd-HH-mm-ss";
+ public static final String timeFormat = "HH:mm:ss";
+ public static final String minSecFormat = "mm:ss";
+
+ public static String getTimeStamp()
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern(dateTimeFormat);
+ Calendar cal = Calendar.getInstance();
+ return sdf.format(cal.getTime());
+ }
+
+ /**
+ * @param millis
+ * @return yyyy-MM-dd-HH-mm-ss
+ */
+ public static String getDateTimeString(long millis)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern(dateTimeFormat);
+ return sdf.format(new Date(millis));
+ }
+
+ /**
+ * @param millis
+ * @return HH:mm:ss
+ */
+ public static String getTimeString(long millis)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern(timeFormat);
+ return sdf.format(new Date(millis));
+ }
+
+ public static String getMinSec(long millis)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern(minSecFormat);
+ return sdf.format(new Date(millis));
+ }
+
+ /**
+ * The list of files UserSpace in the workspace.
+ */
+ private ArrayList<String> fileOrder = new ArrayList<String>();
+
+ public void addFile(String fileName)
+ {
+ if (!fileOrder.contains(fileName))
+ fileOrder.add(fileName);
+ }
+
+ public void removeFile(String fileName)
+ {
+ fileOrder.remove(fileName);
+ }
+
+ public void renameFile(String oldName, String newName)
+ {
+ int i = fileOrder.indexOf(oldName);
+ if (i < 0)
+ return;
+ fileOrder.remove(i);
+ fileOrder.add(i, newName);
+ }
+
+ public ArrayList<String> getFileOrder()
+ {
+ return fileOrder;
+ }
+
+ // The below properties are essentially copied from the old XLogo
+ // they might get (re)moved or changed
+
+ final String version="0.9.96pre 27/06/12"; // TODO not needed? new version?
+
+ /**
+ * Drawing Quality
+ */
+ private DrawQuality quality= DrawQuality.HIGH;
+
+ /**
+ * This integer represents the selected looknfeel for the appplication
+ */
+ private LookAndFeel looknfeel=LookAndFeel.JAVA;
+
+ /**
+ * This integer represents the drawing area width
+ */
+ private int imageWidth= Math.max(1000, Toolkit.getDefaultToolkit().getScreenSize().width);
+ /**
+ * This integer represents the drawing area height
+ */
+ private int imageHeight= Math.max(1000, Toolkit.getDefaultToolkit().getScreenSize().height);
+ /**
+ * Integer that represents the active turtle's shape
+ */
+ private int activeTurtle=0;
+ /**
+ * Maximum allowed pen size
+ */
+ private int maxPenWidth=-1;
+ /**
+ * This boolean indicates if the drawing area has to be cleaned when the editor is left.
+ */
+ private boolean eraseImage = false;
+ /**
+ * This boolean indicates if variables are deleted when closing the editor.
+ */
+ private boolean clearVariables = false;
+ /**
+ * Max value for the turtles number
+ */
+ private int maxTurtles = 16;
+ /**
+ * Default screen color: This color is used when the primitive "clearscreen" is used.
+ */
+ private Color screencolor=Color.WHITE;
+ /**
+ * Default pen color: This color is used when the primitive "clearscreen" is used.
+ */
+ private Color pencolor=Color.BLACK;
+
+
+ /**
+ * This represents the pen shape
+ */
+ private PenShape penShape = PenShape.SQUARE;
+
+ /**
+ * This integer represents the turtle's speed for drawing <br>
+ * Slow: 100
+ * Fast: 0
+ */
+ private int turtleSpeed=0;
+ /**
+ * This String contains the command to execute on Startup. <br>
+ * Configured in the dialog box "startup files"
+ */
+ private String a_executer="";
+ /** Marko Zivkovic : this is used for a few Logo Commands that operate with files <br>
+ * Loic:
+ * The default folder for the user when the application starts.<br>
+ * This folder corresponds to the last opened or saved file in format lgo // Marko : not true anymore
+ */
+ private String defaultFolder=Utils.rajoute_backslash(System.getProperty("user.home"));
+
+ /**
+ * This boolean indicates if the grid is enabled
+ */
+ private boolean drawGrid=false;
+ /**
+ * This integer represents the X distance for the grid
+ */
+ private int XGrid=20;
+ /**
+ * This integer represents the Y distance for the grid
+ */
+ private int YGrid=20;
+ /**
+ * This integer represents the grid Color
+ */
+ private int gridColor=Color.DARK_GRAY.getRGB();
+ /**
+ * This boolean indicates if the X axis is enabled
+ */
+ private boolean drawXAxis=false;
+ /**
+ * This boolean indicates if the Y axis is enabled
+ */
+ private boolean drawYAxis=false;
+ /**
+ * This integer represents the axis Color
+ */
+ private int axisColor=new Color(255,0,102).getRGB();
+ /**
+ * This integer represents the X distance between two divisions on the X Axis
+ */
+ private int XAxis=30;
+ /**
+ * This integer represents the X distance between two divisions on the Y Axis
+ */
+ private int YAxis=30;
+
+ /**
+ * This long represents the hour of XLogo starting
+ */
+ private long heure_demarrage;
+ /**
+ * Color for the border around drawing area
+ */
+ private Color borderColor=null;
+ /**
+ * The Image is for the border around drawing area
+ */
+ private String borderImageSelected="background.png";
+
+ /**
+ * This Vector contains all images added by the user for image Border
+ */
+ private ArrayList<String> borderExternalImage=new ArrayList<String>();
+ /**
+ * The default image defined by default that are included in XLogo
+ */
+ private String[] borderInternalImage={"background.png"};
+ /**
+ * This String represents the main command accessible with the button play in the toolbar
+ */
+ private String mainCommand="";
+ /**
+ * This boolean indicates if Xlogo must launch the main Command on XLogo startup
+ * It overrides the String a_executer
+ */
+ private boolean autoLaunch=false;
+
+
+ /**
+ * TCP Port for robotics and network flows
+ */
+ private int tcpPort = 1948;
+
+ public int searchInternalImage(String st) {
+ for (int i = 0; i < borderInternalImage.length; i++) {
+ if (st.equals(borderInternalImage[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Generated Getters & Setters
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ public DrawQuality getQuality() {
+ return quality;
+ }
+
+
+ public void setQuality(DrawQuality quality) {
+ this.quality = quality;
+ makeDirty();
+ }
+
+ public LookAndFeel getLooknfeel() {
+ return looknfeel;
+ }
+
+ public void setLooknfeel(LookAndFeel looknfeel) {
+ this.looknfeel = looknfeel;
+ makeDirty();
+ }
+
+
+ public int getImageWidth() {
+ return imageWidth;
+ }
+
+
+ public void setImageWidth(int imageWidth) {
+ this.imageWidth = imageWidth;
+ makeDirty();
+ }
+
+
+ public int getImageHeight() {
+ return imageHeight;
+ }
+
+
+ public void setImageHeight(int imageHeight) {
+ this.imageHeight = imageHeight;
+ makeDirty();
+ }
+
+ public int getActiveTurtle() {
+ return activeTurtle;
+ }
+
+
+ public void setActiveTurtle(int activeTurtle) {
+ this.activeTurtle = activeTurtle;
+ makeDirty();
+ }
+
+
+ public int getMaxPenWidth() {
+ return maxPenWidth;
+ }
+
+
+ public void setMaxPenWidth(int maxPenWidth) {
+ this.maxPenWidth = maxPenWidth;
+ makeDirty();
+ }
+
+
+ public boolean isEraseImage() {
+ return eraseImage;
+ }
+
+
+ public void setEraseImage(boolean eraseImage) {
+ this.eraseImage = eraseImage;
+ makeDirty();
+ }
+
+
+ public boolean isClearVariables() {
+ return clearVariables;
+ }
+
+
+ public void setClearVariables(boolean clearVariables) {
+ this.clearVariables = clearVariables;
+ makeDirty();
+ }
+
+
+ public int getMaxTurtles() {
+ return maxTurtles;
+ }
+
+
+ public void setMaxTurtles(int maxTurtles) {
+ this.maxTurtles = maxTurtles;
+ makeDirty();
+ }
+
+
+ public Color getScreencolor() {
+ return screencolor;
+ }
+
+
+ public void setScreencolor(Color screencolor) {
+ this.screencolor = screencolor;
+ makeDirty();
+ }
+
+
+ public Color getPencolor() {
+ return pencolor;
+ }
+
+
+ public void setPencolor(Color pencolor) {
+ this.pencolor = pencolor;
+ makeDirty();
+ }
+
+
+ public PenShape getPenShape() {
+ return penShape;
+ }
+
+
+ public void setPenShape(PenShape penShape) {
+ this.penShape = penShape;
+ makeDirty();
+ }
+
+
+ public int getTurtleSpeed() {
+ return turtleSpeed;
+ }
+
+
+ public void setTurtleSpeed(int turtleSpeed) {
+ this.turtleSpeed = turtleSpeed;
+ makeDirty();
+ }
+
+
+ public String getA_executer() {
+ return a_executer;
+ }
+
+
+ public void setA_executer(String a_executer) {
+ this.a_executer = a_executer;
+ makeDirty();
+ }
+
+ /**
+ * Default : User source directory
+ * @return the current defaultDirectory
+ * @author Marko Zivkovic
+ */
+ public String getDefaultFolder() {
+ if (defaultFolder == null)
+ return getSourceDirectory().toString();
+ return defaultFolder;
+ }
+
+
+ public void setDefaultFolder(String defaultFolder) {
+ this.defaultFolder = defaultFolder;
+ makeDirty();
+ }
+
+
+
+
+ public boolean isDrawGrid() {
+ return drawGrid;
+ }
+
+
+ public void setDrawGrid(boolean drawGrid) {
+ this.drawGrid = drawGrid;
+ makeDirty();
+ }
+
+
+ public int getXGrid() {
+ return XGrid;
+ }
+
+
+ public void setXGrid(int xGrid) {
+ XGrid = xGrid;
+ makeDirty();
+ }
+
+
+ public int getYGrid() {
+ return YGrid;
+ }
+
+
+ public void setYGrid(int yGrid) {
+ YGrid = yGrid;
+ makeDirty();
+ }
+
+
+ public int getGridColor() {
+ return gridColor;
+ }
+
+
+ public void setGridColor(int gridColor) {
+ this.gridColor = gridColor;
+ makeDirty();
+ }
+
+
+ public boolean isDrawXAxis() {
+ return drawXAxis;
+ }
+
+
+ public void setDrawXAxis(boolean drawXAxis) {
+ this.drawXAxis = drawXAxis;
+ makeDirty();
+ }
+
+
+ public boolean isDrawYAxis() {
+ return drawYAxis;
+ }
+
+
+ public void setDrawYAxis(boolean drawYAxis) {
+ this.drawYAxis = drawYAxis;
+ makeDirty();
+ }
+
+
+ public int getAxisColor() {
+ return axisColor;
+ }
+
+
+ public void setAxisColor(int axisColor) {
+ this.axisColor = axisColor;
+ makeDirty();
+ }
+
+
+ public int getXAxis() {
+ return XAxis;
+ }
+
+
+ public void setXAxis(int xAxis) {
+ XAxis = xAxis;
+ makeDirty();
+ }
+
+
+ public int getYAxis() {
+ return YAxis;
+ }
+
+
+ public void setYAxis(int yAxis) {
+ YAxis = yAxis;
+ makeDirty();
+ }
+
+
+ public long getHeure_demarrage() {
+ return heure_demarrage;
+ }
+
+
+ public void setHeure_demarrage(long heure_demarrage) {
+ this.heure_demarrage = heure_demarrage;
+ makeDirty();
+ }
+
+
+ public Color getBorderColor() {
+ return borderColor;
+ }
+
+
+ public void setBorderColor(Color borderColor) {
+ this.borderColor = borderColor;
+ makeDirty();
+ }
+
+
+ public String getBorderImageSelected() {
+ return borderImageSelected;
+ }
+
+
+ public void setBorderImageSelected(String borderImageSelected) {
+ this.borderImageSelected = borderImageSelected;
+ makeDirty();
+ }
+
+
+ public ArrayList<String> getBorderExternalImage() {
+ return borderExternalImage;
+ }
+
+
+ public void setBorderExternalImage(ArrayList<String> borderExternalImage) {
+ this.borderExternalImage = borderExternalImage;
+ makeDirty();
+ }
+
+
+ public String[] getBorderInternalImage() {
+ return borderInternalImage;
+ }
+
+
+ public void setBorderInternalImage(String[] borderInternalImage) {
+ this.borderInternalImage = borderInternalImage;
+ makeDirty();
+ }
+
+
+ public String getMainCommand() {
+ return mainCommand;
+ }
+
+
+ public void setMainCommand(String mainCommand) {
+ this.mainCommand = mainCommand;
+ makeDirty();
+ }
+
+
+ public boolean isAutoLaunch() {
+ return autoLaunch;
+ }
+
+
+ public void setAutoLaunch(boolean autoLaunch) {
+ this.autoLaunch = autoLaunch;
+ makeDirty();
+ }
+
+ public int getTcpPort() {
+ return tcpPort;
+ }
+
+
+ public void setTcpPort(int tcpPort) {
+ this.tcpPort = tcpPort;
+ makeDirty();
+ }
+
+}
diff --git a/logo/src/xlogo/storage/workspace/ContestConfig.java b/logo/src/xlogo/storage/workspace/ContestConfig.java new file mode 100644 index 0000000..197e4d5 --- /dev/null +++ b/logo/src/xlogo/storage/workspace/ContestConfig.java @@ -0,0 +1,59 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.io.Serializable;
+
+public class ContestConfig implements Serializable {
+
+ private static final long serialVersionUID = 3323633026648762889L;
+
+ private int nOfContestFiles = 6;
+ private int nOfContestBonusFiles = 2;
+
+ public int getNOfContestFiles()
+ {
+ return nOfContestFiles;
+ }
+
+ public void setNOfContestFiles(int nOfContestFiles)
+ {
+ this.nOfContestFiles = nOfContestFiles;
+ }
+
+ public int getNOfContestBonusFiles()
+ {
+ return nOfContestBonusFiles;
+ }
+
+ public void setNOfContestBonusFiles(int nOfContestBonusFiles)
+ {
+ this.nOfContestBonusFiles = nOfContestBonusFiles;
+ }
+
+}
diff --git a/logo/src/xlogo/storage/workspace/Language.java b/logo/src/xlogo/storage/workspace/Language.java new file mode 100644 index 0000000..f19b3ac --- /dev/null +++ b/logo/src/xlogo/storage/workspace/Language.java @@ -0,0 +1,111 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+public enum Language {
+ LANGUAGE_FRENCH(0, "French", "fr", "FR"),
+ LANGUAGE_ENGLISH(1, "English", "en", "US"),
+ LANGUAGE_ARABIC(2, "Arabic", "ar", "MA"),
+ LANGUAGE_SPANISH(3, "Spanish", "es", "ES"),
+ LANGUAGE_PORTUGAL(4, "Portuguese", "pt", "BR"),
+ LANGUAGE_ESPERANTO(5, "Esperanto", "eo", "EO"),
+ LANGUAGE_GERMAN(6, "German", "de", "DE"),
+ LANGUAGE_GALICIAN(7, "Galician", "gl", "ES"),
+ LANGUAGE_ASTURIAN(8, "Asturian", "al", "ES"),
+ LANGUAGE_GREEK(9, "Greek", "el", "GR"),
+ LANGUAGE_ITALIAN(10, "Italian", "it", "IT"),
+ LANGUAGE_CATALAN(11, "Catalan", "ca", "ES"),
+ LANGUAGE_HUNGARIAN(12, "Hungarian", "hu", "HU"),
+ LANGUAGE_ENGLISH_GERMAN(13, "ABZ German/English", "en", "DE");
+
+ private int value;
+ private String englishName;
+ private String languageCode;
+ private String countryCode;
+
+ private static Map<Integer, Language> valueToLanguage;
+
+ private Language(int value, String englishName, String languageCode, String countryCode) {
+ this.value = value;
+ this.englishName = englishName;
+ this.languageCode = languageCode;
+ this.countryCode = countryCode;
+ }
+
+ public static Language getLanguage(int i)
+ {
+ if (valueToLanguage == null)
+ initMapping();
+ return valueToLanguage.get(i);
+ }
+
+ public static void initMapping()
+ {
+ valueToLanguage = new HashMap<Integer, Language>();
+ for (Language lang : values()) {
+ valueToLanguage.put(lang.value, lang);
+ }
+ }
+
+ public int getValue()
+ {
+ return value;
+ }
+
+ public String getEnglishName()
+ {
+ return englishName;
+ }
+
+ /**
+ * return English name
+ */
+ @Override
+ public String toString() {
+ return getEnglishName();
+ }
+
+ public Locale getLocale()
+ {
+ return new Locale(languageCode, countryCode);
+ }
+
+ public String getLanguageCode()
+ {
+ return languageCode;
+ }
+
+ public String getCountryCode()
+ {
+ return countryCode;
+ }
+}
diff --git a/logo/src/xlogo/storage/workspace/NumberOfBackups.java b/logo/src/xlogo/storage/workspace/NumberOfBackups.java new file mode 100644 index 0000000..1c8d4b2 --- /dev/null +++ b/logo/src/xlogo/storage/workspace/NumberOfBackups.java @@ -0,0 +1,57 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+public enum NumberOfBackups {
+ NO_BACKUPS(0),
+ ONE(1),
+ THREE(3),
+ TEN(10),
+ FIFTY(50),
+ INFINITE(-1);
+
+ private int number;
+
+ private NumberOfBackups(int number) {
+ this.number = number;
+ }
+
+ public int getNumber()
+ {
+ return number;
+ }
+
+ public String toString()
+ {
+ if (number == -1)
+ {
+ return "infinite";
+ }
+ return Integer.toString(number);
+ }
+}
diff --git a/logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java b/logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java new file mode 100644 index 0000000..ac89e64 --- /dev/null +++ b/logo/src/xlogo/storage/workspace/SyntaxHighlightConfig.java @@ -0,0 +1,151 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.io.Serializable;
+
+public class SyntaxHighlightConfig implements Serializable{
+
+ private static final long serialVersionUID = 7137977560063481685L;
+
+ /**
+ * syntax Highlighting: Color for primitives
+ */
+ private int primitiveColor=new Color(0,128,0).getRGB();
+ /**
+ * syntax Highlighting: Style for primitives
+ */
+ private int primitiveStyle=Font.PLAIN;
+ /**
+ * syntax Highlighting: Color for operands: numbers....
+ */
+ private int operatorColor=Color.BLUE.getRGB();
+ /**
+ * syntax Highlighting: Style for operands
+ */
+ private int operatorStyle=Font.PLAIN;
+ /**
+ * syntax Highlighting: Color for comments
+ */
+ private int commentColor=Color.GRAY.getRGB();
+ /**
+ * syntax Highlighting: Style for comments
+ */
+ private int commentStyle=Font.PLAIN;
+ /**
+ * syntax Highlighting: Color for parenthesis
+ */
+ private int braceColor=Color.RED.getRGB();
+ /**
+ * syntax Highlighting: Style for parenthesis
+ */
+ private int braceStyle=Font.BOLD;
+ /**
+ * boolean that indicates if syntax Highlighting is enabled
+ */
+ private boolean colorEnabled=true;
+
+ public SyntaxHighlightConfig() {
+
+ }
+
+ public int getPrimitiveColor() {
+ return primitiveColor;
+ }
+
+ public void setPrimitiveColor(int primitiveColor) {
+ this.primitiveColor = primitiveColor;
+ }
+
+ public int getPrimitiveStyle() {
+ return primitiveStyle;
+ }
+
+ public void setPrimitiveStyle(int primitiveStyle) {
+ this.primitiveStyle = primitiveStyle;
+ }
+
+ public int getOperatorColor() {
+ return operatorColor;
+ }
+
+ public void setOperatorColor(int operatorColor) {
+ this.operatorColor = operatorColor;
+ }
+
+ public int getOperatorStyle() {
+ return operatorStyle;
+ }
+
+ public void setOperatorStyle(int operatorStyle) {
+ this.operatorStyle = operatorStyle;
+ }
+
+ public int getCommentColor() {
+ return commentColor;
+ }
+
+ public void setCommentColor(int commentColor) {
+ this.commentColor = commentColor;
+ }
+
+ public int getCommentStyle() {
+ return commentStyle;
+ }
+
+ public void setCommentStyle(int commentStyle) {
+ this.commentStyle = commentStyle;
+ }
+
+ public int getBraceColor() {
+ return braceColor;
+ }
+
+ public void setBraceColor(int braceColor) {
+ this.braceColor = braceColor;
+ }
+
+ public int getBraceStyle() {
+ return braceStyle;
+ }
+
+ public void setBraceStyle(int braceStyle) {
+ this.braceStyle = braceStyle;
+ }
+
+ public boolean isColorEnabled() {
+ return colorEnabled;
+ }
+
+ public void setColorEnabled(boolean colorEnabled) {
+ this.colorEnabled = colorEnabled;
+ }
+
+}
diff --git a/logo/src/xlogo/storage/workspace/WorkspaceConfig.java b/logo/src/xlogo/storage/workspace/WorkspaceConfig.java new file mode 100644 index 0000000..9a3b60a --- /dev/null +++ b/logo/src/xlogo/storage/workspace/WorkspaceConfig.java @@ -0,0 +1,688 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * 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.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were entirely written by Marko Zivkovic
+ */
+
+package xlogo.storage.workspace;
+
+import java.awt.Font;
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import xlogo.AppSettings;
+import xlogo.Logo;
+import xlogo.messages.MessageKeys;
+import xlogo.messages.async.dialog.DialogMessenger;
+import xlogo.storage.Storable;
+import xlogo.storage.StorableObject;
+import xlogo.storage.WSManager;
+import xlogo.storage.user.UserConfig;
+
+/**
+ * WorkspaceConfig maintains a workspace (i.e. a "class room") that consists of several projects or "Users".
+ * It defines a common language for the project (English, French, ...) and a master password for the workspace owner.
+ * The password is intended to allow certain settings only for the workspace owner. Therefore the corresponding methods will require a password.
+ * <br> A directory on the file system is an XLogo4Schools workspace, if it contains a file named "X4S_WorkspaceConfig.ser",
+ * no matter what it contains.
+ * <br> If a workspace is made virtual, it is not stored on the file system. ({@link #createVirtualWorkspace()})
+ * <p>
+ * A user belongs to the workspace, if it is contained logically in the user list.
+ * For a user to work correctly in its user space, a user directory {@code workspaceDir/username/}
+ * and the file {@code workspaceDir/username/X4S_UserConfig.ser} are required.
+ * As long as a user exists logically in the workspace, missing or corrupted files are recreated if needed.
+ * If a user is deleted, it is deleted only logically, so it can be reintegrated later again.
+ * @author Marko Zivkovic
+ */
+public class WorkspaceConfig extends StorableObject implements Serializable {
+
+ private static final long serialVersionUID = -3554871695113998509L;
+
+ /**
+ * Name of the virtual workspace
+ */
+ public static final String VIRTUAL_WORKSPACE = "Guest Workspace (no automatic save)";
+
+ protected WorkspaceConfig()
+ {
+ super();
+ userList = new ArrayList<String>();
+ language = Language.LANGUAGE_ENGLISH;
+ font = new Font("dialog",Font.PLAIN,14); // TODO on access check if it is null.
+ // TODO what if incompatible?
+ syntaxHighlightingStyles = new SyntaxHighlightConfig();
+ AppSettings.getInstance().setFont(font);
+ }
+
+ /**
+ * @return
+ * @throws IllegalStateException if this is not virtual and {@link #getLocation()} returns null
+ */
+ public String getWorkspaceName() throws IllegalStateException
+ {
+ if (isVirtual())
+ return VIRTUAL_WORKSPACE;
+
+ File wsDir = getLocation();
+ if (wsDir == null)
+ throw new IllegalStateException("Name is not available because location is null.");
+ return wsDir.getName();
+ }
+
+ /*
+ * Static constructors
+ */
+ private static WorkspaceConfig virtualWS;
+
+ /**
+ * A virtual user can enter the application in a virtual workspace without having an actual user account on the file system. Hence nothing will be stored.
+ * A regular user (not virtual) will have his own folder in a regular workspace on the file system and all his preferences and files are stored there.
+ * To create a regular workspace, use {@link #createNewWorkspace(File, String)},
+ * to load a regular workspace from the file system, user {@link #loadWorkspace(File)}}.
+ * @see #isVirtual()
+ * @return a virtual workspace
+ */
+ public static WorkspaceConfig createVirtualWorkspace()
+ {
+ if (virtualWS == null)
+ {
+ virtualWS = new WorkspaceConfig();
+ virtualWS.makeVirtual();
+ }
+ return virtualWS;
+ }
+
+ @Override
+ protected void makeVirtual()
+ {
+ super.makeVirtual();
+ userList = new ArrayList<String>();
+ userList.add(UserConfig.VIRTUAL_USER);
+ lastActiveUser = UserConfig.VIRTUAL_USER;
+ try { enterUserSpace(UserConfig.VIRTUAL_USER); } catch (IOException e) { /* Does not happen */ }
+ }
+
+ /**
+ * @param dir
+ * @param workspaceName
+ * @return
+ * @throws IOException
+ */
+ public static WorkspaceConfig createNewWorkspace(File dir, String workspaceName) throws IOException
+ {
+ if (!Storable.checkLegalName(workspaceName))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME));
+ return null;
+ }
+
+ File wsd = getDirectory(dir, workspaceName);
+ boolean existed = wsd.exists();
+ if (!existed)
+ {
+ wsd.mkdirs();
+ }
+ // wsd exists and it is empty
+ WorkspaceConfig wsc = new WorkspaceConfig();
+ wsc.setLocation(wsd);
+ //if(existed && WSManager.isUserDirectory(wsd))
+ // wsc.refreshUserList();
+ wsc.store();
+ return wsc;
+ }
+
+ /**
+ * @see #loadWorkspace(File)
+ * @param dir - location of the workspace
+ * @param workspaceName
+ * @return
+ * @throws IOException
+ */
+ public static WorkspaceConfig loadWorkspace(File dir, String workspaceName) throws IOException
+ {
+ File wsc = getDirectory(dir, workspaceName);
+ return loadWorkspace(wsc);
+ }
+
+ /**
+ * @param workspaceDir
+ * @return Load an existing workspace from the file system.
+ * If workspaceDir specifies a {@link WorkspaceConfig#VIRTUAL_WORKSPACE}, the virtual workspace is returned instead.
+ * @throws IOException
+ */
+ public static WorkspaceConfig loadWorkspace(File workspaceDir) throws IOException
+ {
+ if(workspaceDir.getName().equals(WorkspaceConfig.VIRTUAL_WORKSPACE))
+ {
+ return createVirtualWorkspace();
+ }
+
+ File wsf = getFile(workspaceDir, WorkspaceConfig.class);
+
+ WorkspaceConfig wsc;
+ try {
+ wsc = (WorkspaceConfig) WorkspaceConfig.loadObject(wsf);
+ wsc.setLocation(workspaceDir);
+ return wsc;
+ } catch (ClassNotFoundException e) {
+ return null; // this won't happen
+ }
+ }
+
+ /*
+ * User list
+ */
+
+ /**
+ * @see #getUserList()
+ */
+ private ArrayList<String> userList;
+
+ /**
+ * The names of the logical users in the workspace
+ * @return
+ */
+ public String[] getUserList()
+ {
+ String[] users = new String[userList.size()];
+ return userList.toArray(users);
+ }
+
+ public File getUserDirectroy(String username)
+ {
+ if (!existsUserLogically(username) || isVirtual())
+ return null;
+
+ return getDirectory(getLocation(), username);
+ }
+
+ /**
+ * Create new user directory and UserConfig file in this workspace on the file system, and add it logically to the userList.
+ * If either existed, only the non-existing parts are created.
+ * To create a user in a virtual workspace will have no effect, but an error message is printed.
+ * <p> Has no effect if this is virtual.
+ * @param username
+ */
+ public void createUser(String username)
+ {
+ if (!Storable.checkLegalName(username))
+ {
+ DialogMessenger.getInstance().dispatchError(
+ Logo.messages.getString(MessageKeys.NAME_ERROR_TITLE),
+ Logo.messages.getString(MessageKeys.ILLEGAL_NAME));
+ return;
+ }
+
+ if(isVirtual())
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "Attempt to create new user to virtual workspace.");
+ return;
+ }
+
+ File userDir = getDirectory(getLocation(), username);
+
+ if(!userDir.mkdirs())
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not make required directories: " + userDir.toString());
+ return;
+ }
+
+ if (!existsUserLogically(username))
+ {
+ userList.add(username);
+ makeDirty();
+ }
+
+ // Make new user logically existent in workspace config file
+ try { store(); } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not store workspace.");
+ }
+ if(!existsUserPhysically(username))
+ UserConfig.createNewUser(this, username);
+ }
+
+ /**
+ * Import a user directory from anywhere in the file system to this workspace.
+ * All files in the user directory are copied. Already existing files might get overwritten.
+ * <p> This has no effect if this is virtual.
+ * @param srcUserDir - a legal user directory anywhere on the file system
+ * @param destUsername - Existing files of targetUser are overwritten. If targetUser does not exist, it will be created first.
+ * @throws IllegalArgumentException
+ * @throws IOException
+ * @see WSManager#isUserDirectory(File)
+ */
+ public void importUser(File srcUserDir, String destUsername) throws IllegalArgumentException, IOException
+ {
+ if (isVirtual())
+ return;
+
+ if (!WSManager.isUserDirectory(srcUserDir))
+ throw new IllegalArgumentException();
+
+ createUser(destUsername);
+ File targetUserDir = getDirectory(getLocation(), destUsername);
+
+ WSManager.copyFullyRecursive(srcUserDir, targetUserDir);
+ }
+
+ /**
+ * @param userName will be removed logically only
+ */
+ public void removeUser(String userName)
+ {
+ if(existsUserLogically(userName))
+ makeDirty();
+
+ userList.remove(userName);
+ }
+
+ /**
+ * @param username - if this exists not logically in the workspace, null is returned.
+ * @return a {@link UserConfig} generated from the file system. If this is a virtual workspace, a virtual user is created instead.
+ * @throws IOException if the UserConfig could not be loaded
+ * @see UserConfig#loadUser(File, String)
+ */
+ public UserConfig loadUser(String username) throws IOException
+ {
+ if(!existsUserLogically(username))
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Attempt to load inexistent user: " + username + ". Try to import this user.");
+ return null;
+ }
+
+ if(isVirtual())
+ return UserConfig.createVirtualUser();
+
+ // exists logically and is not virtual
+
+ if(!existsUserPhysically(username))
+ {
+ // but it does exist logically => it must have been corrupted externally.
+ // => restore it.
+ if(!getLocation().mkdirs())
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not make required directories.");
+ return null;
+ }
+ // user creation requires existence of the workspace on file system
+ try { store(); } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error","Could not store workspace.");
+ }
+ return UserConfig.createNewUser(this, username);
+ }
+ // exists physically
+ return UserConfig.loadUser(this, username);
+ }
+
+ /**
+ * Produces a list of user names by reading the contents of the current workspace directory.
+ * The users in this list may contain users that have been deleted logically before.
+ * @return
+ */
+ public ArrayList<String> getPhysicalUserList()
+ {
+ if(isVirtual())
+ return new ArrayList<String>();
+
+ ArrayList<String> users = new ArrayList<String>();
+
+ if (WSManager.isWorkspaceDirectory(getLocation()))
+ {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "Current workspace was probably deleted. I will recreate it.");
+ try { store(); } catch (IOException e) {
+ DialogMessenger.getInstance().dispatchError("Workspace Error", "I could not recreate the Workspace. Try to delete the Workspace and recreate it manually.");
+ return users;
+ }
+ }
+
+
+ for(File dir : WSManager.listDirectories(getLocation()))
+ {
+ if(WSManager.isUserDirectory(dir))
+ {
+ users.add(dir.getName());
+ }
+ }
+ return users;
+ }
+
+ /**
+ * A user exists logically, if its name is known by the workspace.
+ * @param userName
+ * @return
+ */
+ public boolean existsUserLogically(String username)
+ {
+ return userList.contains(username);
+ }
+
+ /**
+ * A user exists physically, if a folder with the user's name exists in this workspace and if it contains a UserConfig file.
+ * @param username
+ * @return
+ * @see WSManager#isUserDirectory(File)
+ */
+ public boolean existsUserPhysically(String username)
+ {
+ File userDir = getDirectory(getLocation(), username);
+ return WSManager.isUserDirectory(userDir);
+ }
+
+ /*
+ * last active user
+ */
+
+ private String lastActiveUser;
+
+ /**
+ * @return name of the last active user
+ */
+ public String getLastActiveUser()
+ {
+ return lastActiveUser;
+ }
+
+ /**
+ * Succeeds if the user exists
+ * @param workspace
+ */
+ public void setLastActiveUser(String username)
+ {
+ if(existsUserLogically(username) && !username.equals(lastActiveUser))
+ {
+ lastActiveUser = new String(username);
+ makeDirty();
+ }
+ }
+
+ /*
+ * active user
+ */
+
+ private transient UserConfig activeUser;
+
+ public UserConfig getActiveUser()
+ {
+ return activeUser;
+ }
+
+ /**
+ * @throws IOException If the old userConfig could not be stored.
+ */
+ public void enterUserSpace(String username) throws IOException
+ {
+ if(activeUser != null)
+ {
+ leaveUserSpace();
+ }
+
+ if (isVirtual())
+ activeUser = UserConfig.createVirtualUser();
+ else
+ activeUser = UserConfig.loadUser(this, username);
+
+ setLastActiveUser(username);
+ }
+
+ /**
+ * @throws IOException If userConfig could not be stored.
+ */
+ public void leaveUserSpace() throws IOException
+ {
+ if (activeUser.isDirty())
+ activeUser.store();
+ activeUser = null;
+ }
+
+ /*
+ * Version control
+ */
+
+ /**
+ * How many old versions of a file should be kept, in addition to the most recent one?
+ * Default is infinite.
+ */
+ private NumberOfBackups numberOfBackups = NumberOfBackups.INFINITE;
+
+ /**
+ * @see #numberOfBackups
+ */
+ public NumberOfBackups getNumberOfBackups()
+ {
+ return numberOfBackups;
+ }
+
+ /**
+ * @see #numberOfBackups
+ */
+ public void setNumberOfBackups(NumberOfBackups n)
+ {
+ numberOfBackups = n;
+ makeDirty();
+ }
+
+ /*
+ * Workspace language
+ */
+
+ /**
+ * The language to be used within this workspace
+ */
+ public Language language;
+
+ public void setLanguage(Language language)
+ {
+ this.language = language;
+ AppSettings.getInstance().setLanguage(language);
+ makeDirty();
+ }
+
+ public Language getLanguage()
+ {
+ return language;
+ }
+
+ /*
+ * Allow users (children) to create new user accounts in workspaces?
+ */
+
+ private boolean allowUserCreation = true;
+
+ public void setAllowUserCreation(boolean allowed)
+ {
+ this.allowUserCreation = allowed;
+ makeDirty();
+ }
+
+ public boolean isUserCreationAllowed()
+ {
+ return allowUserCreation && !isVirtual();
+ }
+
+ /*
+ * Contest //TODO create options in workspace settings
+ */
+
+ private ContestConfig contestConfig;
+
+ protected ContestConfig getContestSettings()
+ {
+ return contestConfig;
+ }
+
+ public int getNOfContestFiles()
+ {
+ if (contestConfig == null)
+ contestConfig = new ContestConfig();
+ return getContestSettings().getNOfContestFiles();
+ }
+
+ public void setNOfContestFiles(int nOfContestFiles)
+ {
+ getContestSettings().setNOfContestFiles(nOfContestFiles);
+ }
+
+ public int getNOfContestBonusFiles()
+ {
+ return getContestSettings().getNOfContestBonusFiles();
+ }
+
+ public void setNOfContestBonusFiles(int nOfContestBonusFiles)
+ {
+ getContestSettings().setNOfContestBonusFiles(nOfContestBonusFiles);
+ }
+
+ /*
+ * Syntax Highlighting
+ */
+ private SyntaxHighlightConfig syntaxHighlightingStyles; // TODO = new SyntaxHighlightStyles();
+
+ /**
+ * This font is the default font for all menus ... in XLogo Application
+ */
+ private Font font;// TODO =new Font("dialog",Font.PLAIN,14);
+
+ public SyntaxHighlightConfig getSyntaxHighlightStyles()
+ {
+ if (syntaxHighlightingStyles == null)
+ {
+ syntaxHighlightingStyles = new SyntaxHighlightConfig();
+ makeDirty();
+ }
+ return syntaxHighlightingStyles;
+ }
+
+ public void setSyntaxHighlightConfig(SyntaxHighlightConfig syntaxHighlightingStyles)
+ {
+ this.syntaxHighlightingStyles = syntaxHighlightingStyles;
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(syntaxHighlightingStyles);
+ }
+
+ public int getPrimitiveColor() {
+ return getSyntaxHighlightStyles().getPrimitiveColor();
+ }
+
+
+ public void setPrimitiveColor(int primitiveColor) {
+ getSyntaxHighlightStyles().setPrimitiveColor(primitiveColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getPrimitiveStyle() {
+ return getSyntaxHighlightStyles().getPrimitiveStyle();
+ }
+
+ public void setPrimitiveStyle(int primitiveStyle) {
+ getSyntaxHighlightStyles().setPrimitiveStyle(primitiveStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getOperatorColor() {
+ return getSyntaxHighlightStyles().getOperatorColor();
+ }
+
+ public void setOperandColor(int operatorColor) {
+ getSyntaxHighlightStyles().setOperatorColor(operatorColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getOperatorStyle() {
+ return getSyntaxHighlightStyles().getOperatorStyle();
+ }
+
+ public void setOperandStyle(int operatorStyle) {
+ getSyntaxHighlightStyles().setOperatorStyle(operatorStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getCommentColor() {
+ return getSyntaxHighlightStyles().getCommentColor();
+ }
+
+ public void setCommentColor(int commentColor) {
+ getSyntaxHighlightStyles().setCommentColor(commentColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getCommentStyle() {
+ return getSyntaxHighlightStyles().getCommentStyle();
+ }
+
+ public void setCommentStyle(int commentStyle) {
+ getSyntaxHighlightStyles().setCommentStyle(commentStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getBraceColor() {
+ return getSyntaxHighlightStyles().getBraceColor();
+ }
+
+ public void setBraceColor(int braceColor) {
+ getSyntaxHighlightStyles().setBraceColor(braceColor);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public int getBraceStyle() {
+ return getSyntaxHighlightStyles().getBraceStyle();
+ }
+
+ public void setBraceStyle(int braceStyle) {
+ getSyntaxHighlightStyles().setBraceStyle(braceStyle);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public boolean isSyntaxHighlightingEnabled() {
+ return getSyntaxHighlightStyles().isColorEnabled();
+ }
+
+ public void setSyntaxHighlightingEnabled(boolean colorEnabled) {
+ getSyntaxHighlightStyles().setColorEnabled(colorEnabled);
+ makeDirty();
+ AppSettings.getInstance().setSyntaxHighlightingStyles(getSyntaxHighlightStyles());
+ }
+
+ public Font getFont() {
+ return font;
+ }
+
+ public void setFont(Font font) {
+ this.font = font;
+ makeDirty();
+ AppSettings.getInstance().setFont(font);
+ }
+
+}
diff --git a/logo/src/xlogo/utils/ExtensionFichier.java b/logo/src/xlogo/utils/ExtensionFichier.java new file mode 100644 index 0000000..4fcf708 --- /dev/null +++ b/logo/src/xlogo/utils/ExtensionFichier.java @@ -0,0 +1,75 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */package xlogo.utils; +import javax.swing.filechooser.*; +import java.io.File; +//Permet de filtrer les fichiers dans un FileChooser +// You can add a filter in a FileChooser + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +public class ExtensionFichier extends FileFilter { +/** + * @uml.property name="description" + */ +private String description; //Description du type de fichiers (Ex: "Fichiers JPEG") +/** + * @uml.property name="extension" multiplicity="(0 -1)" dimension="1" + */ +private String[] extension; //Extension (incluant le '.') Ex: .jpg .java + public ExtensionFichier() { + } + public ExtensionFichier(String description,String[] extension){ + this.description=description; + this.extension=extension; + } + public boolean accept(File f) { + if (f.isDirectory()) return true; + String nomFichier = f.getPath().toLowerCase(); + for (int i=0;i<extension.length;i++){ + if (nomFichier.endsWith(extension[i])) return true; + + } + return false; + } + public String getDescription() { + StringBuffer sb=new StringBuffer(); + sb.append(description); + sb.append(" ("); + for (int i=0;i<extension.length;i++){ + sb.append("*"); + sb.append(extension[i]); + if (i!=extension.length-1) sb.append(", "); + } + sb.append(")"); + return new String(sb); + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/utils/Icon_x4s.png b/logo/src/xlogo/utils/Icon_x4s.png Binary files differnew file mode 100644 index 0000000..1cbd384 --- /dev/null +++ b/logo/src/xlogo/utils/Icon_x4s.png diff --git a/logo/src/xlogo/utils/Logo_xlogo4schools.png b/logo/src/xlogo/utils/Logo_xlogo4schools.png Binary files differnew file mode 100644 index 0000000..3898176 --- /dev/null +++ b/logo/src/xlogo/utils/Logo_xlogo4schools.png diff --git a/logo/src/xlogo/utils/Utils.java b/logo/src/xlogo/utils/Utils.java new file mode 100644 index 0000000..3c2e703 --- /dev/null +++ b/logo/src/xlogo/utils/Utils.java @@ -0,0 +1,481 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +package xlogo.utils; +import java.awt.Container; +import java.awt.Font; +import java.awt.Image; +import java.awt.Component; +import java.awt.Toolkit; +import java.io.BufferedReader; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.URL; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.StringTokenizer; + +import javax.swing.ImageIcon; + +import xlogo.kernel.MyCalculator; +import xlogo.kernel.Affichage; +import xlogo.storage.WSManager; +import xlogo.storage.workspace.Language; +import xlogo.Logo; + +public class Utils { + + /** + * Marko : Here a technique was used for loading images, that happens to be from the last milenium. + * https://weblogs.java.net/blog/chet/archive/2004/07/imageio_just_an.html + * + * The way of the 3rs millenium is ImageIO + * + * @param nom + * @param jf + * @return + */ + public static ImageIcon dimensionne_image(String name,Component jf){ + + Image img = Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(name)); + + return new ImageIcon(img.getScaledInstance(20, 20, Image.SCALE_SMOOTH)); + + /* + Image image; + try + { + image = ImageIO.read(new File("xlogo/utils/"+nom)); + return image.getScaledInstance(22, 22, Image.SCALE_SMOOTH); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + / * + Image image=null; + image= Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(nom)); + MediaTracker tracker=new MediaTracker(jf); + tracker.addImage(image,0); + try{tracker.waitForID(0);} + catch(InterruptedException e1){} + double largeur_ecran=Toolkit.getDefaultToolkit().getScreenSize().getWidth(); + int largeur=image.getWidth(jf); + int hauteur=image.getHeight(jf); + // On fait attention à la résolution de l'utilisateur + double facteur = largeur_ecran/1024.0; //les images sont prévues pour 1024x768 + if ((int)(facteur+0.001)!=1){ + image=image.getScaledInstance((int)(facteur*largeur),(int)(facteur*hauteur),Image.SCALE_SMOOTH); + tracker=new MediaTracker(jf); + tracker.addImage(image,0); + try{tracker.waitForID(0);} + catch(InterruptedException e1){} + } + return image; + */ + } + public static void recursivelySetFonts(Component comp, Font font) { + comp.setFont(font); + if (comp instanceof Container) { + Container cont = (Container) comp; + for(int j=0, ub=cont.getComponentCount(); j<ub; ++j) + recursivelySetFonts(cont.getComponent(j), font); + } + } + public static String rajoute_backslash(String st){ + StringBuffer tampon=new StringBuffer(); + for(int j=0;j<st.length();j++){ + char c=st.charAt(j); + if (c=='\\') tampon.append("\\\\"); + else if (c==' ') tampon.append("\\e"); + else if ("()[]#".indexOf(c)!=-1) tampon.append("\\"+c); + else tampon.append(c); + } + return(new String(tampon)); + } + + /** + * Escape string, backslash ... + * @param chaine + * @return + */ + public static String SortieTexte(String chaine){ // Enlève les backslash + StringBuffer buffer=new StringBuffer(); + boolean backslash=false; + boolean ignore=false; + for (int j=0;j<chaine.length();j++){ + char c=chaine.charAt(j); + if (backslash) { + if (c=='e') buffer.append(' '); +// else if (c=='\\') buffer.append('\\'); + else if (c=='n') buffer.append("\n"); + else if(c=='v') buffer.append(""); + else if(c=='l') { + ignore=true; + } + else if("[]()#\\".indexOf(c)>-1) buffer.append(c); + backslash=false; + } + else { + if (c=='\\') backslash=true; + else if (!ignore) buffer.append(c); + else if (c==' ') ignore=false; + } + } + return MyCalculator.getOutputNumber(new String(buffer)); + } + /** + * This method is formatting the String st.<br> + * - Unused white spaces are deleted.<br> + * - The character \ is modified to \\ <br> + * - The sequence "\ " is modified to "\e"<br> + * - The sequence "\ " is modified to "\e"<br> + * - The sequence "\ " is modified to "\e"<br> + * - The sequence "\ " is modified to "\e"<br> + * @param st The String instruction to format + * @return The formatted instructions + */ + public static StringBuffer decoupe(String st) { + StringBuffer buffer = new StringBuffer(); + // If last character is a white space + boolean espace=false; + // If last character is a backslash + boolean backslash=false; + // If last character is a word + boolean mot=false; + + int crochet_liste=0; +// boolean variable=false; + // If XLogo is running a program + boolean execution_lancee=Affichage.execution_lancee; + for(int i=0;i<st.length();i++){ + char c=st.charAt(i); + if (c==' ') { + if (!espace&&buffer.length()!=0) { + if (backslash) buffer.append("\\e"); + else { + buffer.append(c); + espace=true; + mot=false; + // variable=false; + } + backslash=false; + } + } + else if(c=='\\'&&!backslash) { + espace=false; + backslash=true; + } + else if(c=='\"'){ + if (espace&&crochet_liste<=0){ + mot=true; + } + buffer.append(c); + espace=false; + backslash=false; + } + else if (c==':'){ + /* if (espace&&crochet_liste<=0){ + variable=true; + }*/ + buffer.append(c); + espace=false; + backslash=false; + } + else if (c=='['||c==']'||c=='('||c==')'){ + //Modifications apportées + if (backslash) { + buffer.append("\\"+c); + backslash=false; + } + else { + if (c=='[') crochet_liste++; + else if (c==']') crochet_liste--; + if (espace||buffer.length()==0) {buffer.append(c+" ");espace=true;} + else { + buffer.append(" "+c+" "); + mot=false; + espace=true; + } + } + } + else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='='||c=='<'||c=='>'||c=='&'||c=='|'){ + //System.out.println(mot+" "+espace); + // à modifier (test + fin) + if (mot||crochet_liste>0) { + buffer.append(c); + if (espace) espace=false; + } + else { + String op=String.valueOf(c); + // Looking for operator <= or >= + if (c=='<'||c=='>'){ + if (i+1<st.length()){ + if (st.charAt(i+1)=='='){ + op+="="; + i++; + } + } + } + if (espace) buffer.append(op+" "); + else { + espace=true; + if (buffer.length()!=0) buffer.append(" "+op+" "); + // If buffer is empty no white space before + else buffer.append(op+" "); + } + } + } + else{ + if (backslash){ + if (c=='n') buffer.append("\\n"); + else if (c=='\\') buffer.append("\\\\"); + else if (c=='v'&& execution_lancee) buffer.append("\""); + else if(c=='e'&& execution_lancee) buffer.append("\\e"); + else if (c=='#') buffer.append("\\#"); + else if (c=='l'&&execution_lancee) buffer.append("\\l"); + else { + buffer.append(c); + } + } + else { + buffer.append(c); + } + backslash=false; + espace=false; + } + } +// System.out.println(buffer); + // Remove the space when the user write only "*" or "+" in the command line + //if (buffer.length()>0&&buffer.charAt(0)==' ') buffer.deleteCharAt(0); + return (buffer); + } + + + + public static String specialCharacterXML(String st){ + st=st.replaceAll("&","&"); + st=st.replaceAll("<","<"); + st=st.replaceAll("\"","""); + st=st.replaceAll(">",">"); + st=st.replaceAll("'","'"); + + return st; + } + public static String readLogoFile(String path) throws IOException{ // ADAPT READ LOGO FILE + String txt=""; + // The old format before XLogo 0.9.23 is no longer supported from version 0.9.30 + try{ + // New format for XLogo >=0.923 + // Encoded with UTF-8 + StringBuffer sb=new StringBuffer(); + FileInputStream fr = new FileInputStream(path); + InputStreamReader isr = new InputStreamReader(fr, "UTF8"); + BufferedReader brd=new BufferedReader(isr); + while (brd.ready()){ + sb.append(brd.readLine()); + sb.append("\n"); + } + txt=new String(sb); + } + catch(FileNotFoundException e1){ + // tentative fichier réseau + try{ + URL url =new java.net.URL(path); + StringBuffer sb=new StringBuffer(); + java.io.InputStream fr = url.openStream(); + InputStreamReader isr = new InputStreamReader(fr, "UTF8"); + BufferedReader brd=new BufferedReader(isr); + while (brd.ready()){ + String st=brd.readLine(); + sb.append(st); + sb.append("\n"); + } + txt=new String(sb); + } + catch( java.net.MalformedURLException e){ + System.out.println("File not found: "+path.toString()); + } + } + catch(Exception e){e.printStackTrace();} + if (txt.startsWith("# "+Logo.messages.getString("mainCommand"))){ + int id=txt.indexOf("\n"); + if (id!=-1){ + WSManager.getUserConfig().setMainCommand(txt.substring(("# "+Logo.messages.getString("mainCommand")).length(),id).trim()); + txt=txt.substring(id+1); + } + }; + return txt; + } + + /** + * Store a string to a logo file path, UTF9 encoding, + * Write the main command to the head of the file with a # + * @param path + * @param txt + * @throws IOException + */ + public static void writeLogoFile(String path,String txt) throws IOException{ // ADAPT write logo file + try{ + if (!WSManager.getUserConfig().getMainCommand().trim().equals("")) { + String heading="# "+Logo.messages.getString("mainCommand")+" "+WSManager.getUserConfig().getMainCommand()+"\n"; + txt=heading+txt; + } + FileOutputStream f = new FileOutputStream(path); + BufferedOutputStream b = new BufferedOutputStream(f); + OutputStreamWriter osw = new OutputStreamWriter(b, "UTF8"); + osw.write(txt); + osw.close(); + b.close(); + f.close(); + + } + catch(FileNotFoundException e1){e1.printStackTrace();} + } + public static boolean fileExists(String name){ + File f=new File(name); + return f.exists(); + } + + /** + * @param name + * @return + * @author Marko Zivkovic + */ + public static boolean isFile(String path){ + File f = new File(path); + return f.isFile(); + } + /** + * @param path + * @return + * @author Marko Zivkovic + */ + public static boolean isDirectory(String path){ + File f = new File(path); + return f.isDirectory(); + } + + /** + * Implementation inspired by "JAVA ist auch eine Insel" - Christian Ullenboom, Galileo Computing + * <p> If destination exists, it will be replaced + * @param src + * @param dest + * @throws IOException If there is a problem with either src or dest + * @author Marko Zivkovic + */ + public static void copyFile(String src, String dest) throws IOException + { + copyFile(new File(src), new File(dest)); + } + /** + * Implementation inspired by "JAVA ist auch eine Insel" - Christian Ullenboom, Galileo Computing + * <p> If destination exists, it will be replaced + * @param src + * @param dest + * @throws IOException If there is a problem with either src or dest + * @author Marko Zivkovic + */ + public static void copyFile(File src, File dest) throws IOException + { + FileInputStream fis = null; + FileOutputStream fos = null; + + try + { + fis = new FileInputStream(src); + fos = new FileOutputStream(dest); + byte[] buffer = new byte[0xFFFF]; + for (int len; (len = fis.read(buffer)) != -1;) + { + fos.write(buffer, 0, len); + } + }catch (IOException e) { + throw e; + } + finally { + if (fis != null) + try { fis.close(); } catch (IOException e) {} + if (fos != null) + try { fos.close(); } catch (IOException e) {} + } + } + + /** + * First copy file to dest and then delete file. + * @param file + * @param dest + * @throws IOException If there is a problem with either file or dest + * @author Marko Zivkovic + */ + public static void moveFile(String file, String dest) throws IOException + { + moveFile(new File(file), new File(dest)); + } + + /** + * First copy file to dest and then delete file. + * @param file + * @param dest + * @throws IOException If there is a problem with either file or dest + * @author Marko Zivkovic + */ + public static void moveFile(File file, File dest) throws IOException + { + copyFile(file, dest); + file.delete(); + } + + + public static String primitiveName(String generic){ + Language lang = WSManager.getInstance().getWorkspaceConfigInstance().getLanguage(); + Locale locale = lang.getLocale(); + ResourceBundle prim = ResourceBundle.getBundle( + "primitives", locale); + String st = prim.getString(generic); + StringTokenizer str = new StringTokenizer(st); + while (str.hasMoreTokens()) { + st = str.nextToken(); + } + return st; + } +} diff --git a/logo/src/xlogo/utils/WebPage.java b/logo/src/xlogo/utils/WebPage.java new file mode 100644 index 0000000..56f1528 --- /dev/null +++ b/logo/src/xlogo/utils/WebPage.java @@ -0,0 +1,66 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +/** + * Title : XLogo + * Description : XLogo is an interpreter for the Logo + * programming language + * @author Loïc Le Coq + */ +package xlogo.utils; + +import javax.swing.event.*; +import javax.swing.text.html.*; +import javax.swing.JEditorPane; +import javax.swing.event.HyperlinkListener; + + + +public class WebPage extends JEditorPane implements HyperlinkListener { + private static final long serialVersionUID = 1L; + public WebPage() { + super(); + addHyperlinkListener(this); + } + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + JEditorPane pane = (JEditorPane) e.getSource(); + if (e instanceof HTMLFrameHyperlinkEvent) { + HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e; + HTMLDocument doc = (HTMLDocument)pane.getDocument(); + doc.processHTMLFrameHyperlinkEvent(evt); + } else { + try { + pane.setPage(e.getURL()); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + } +} diff --git a/logo/src/xlogo/utils/WriteImage.java b/logo/src/xlogo/utils/WriteImage.java new file mode 100644 index 0000000..13426f9 --- /dev/null +++ b/logo/src/xlogo/utils/WriteImage.java @@ -0,0 +1,122 @@ +/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq + * Copyright (C) 2013 Marko Zivkovic + * + * Contact Information: marko88zivkovic at gmail dot com + * + * 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. + * + * + * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic + * during his Bachelor thesis at the computer science department of ETH Z�rich, + * in the year 2013 and/or during future work. + * + * It is a reengineered version of XLogo written by Lo�c Le Coq, published + * under the GPL License at http://xlogo.tuxfamily.org/ + * + * Contents of this file were initially written by Lo�c Le Coq, + * modifications, extensions, refactorings might have been applied by Marko Zivkovic + */ + +package xlogo.utils; + +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import xlogo.Logo; +import xlogo.storage.WSManager; + +import java.awt.image.BufferedImage; +import java.awt.Dimension; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JProgressBar; +import javax.swing.JDialog; + +public class WriteImage extends Thread{ + private BufferedImage image; + private JFrame owner; + private String path; + public WriteImage(JFrame owner,BufferedImage image){ + this.image=image; + this.owner=owner; + } + public void setImage(BufferedImage img){ + image=img; + } + public int chooseFile(){ + JFileChooser jf = new JFileChooser(); + String[] ext={".jpg",".png"}; + jf.addChoosableFileFilter(new ExtensionFichier(Logo.messages.getString("imagefile"), + ext )); + int retval = jf.showDialog(owner, Logo.messages.getString("menu.file.save")); + // Si l'utilisateur appuie sur enregistrer du JFileChooser + if (retval == JFileChooser.APPROVE_OPTION) { + // On rajoute l'extension convenable au fichier + path=jf.getSelectedFile().getPath(); + String copie_path=path.toLowerCase(); // + if (!copie_path.endsWith(".jpg") && !copie_path.endsWith(".png")) { + String st = jf.getFileFilter().getDescription().toLowerCase(); + if (st.endsWith("jpg)")) + path += ".jpg"; + else if (st.endsWith("png)")) + path += ".png"; + else + path += ".jpg"; + } + } + return retval; + } + + public void run(){ + + ProgressDialog progress=new ProgressDialog(owner); + + + Thread.currentThread().setPriority(Thread.MAX_PRIORITY); + // On écrit le fichier + try { + if (path.endsWith(".jpg")) { + File f = new File(path); + ImageIO.write(image, "jpg", f); + } + else if (path.endsWith(".png")) { + File f = new File(path); + ImageIO.write(image, "png", f); + } + } + catch (IOException ex) {System.out.println(ex.toString());} + progress.dispose(); + } + private class ProgressDialog extends JDialog{ + + private static final long serialVersionUID = 1L; + private JProgressBar prog=new JProgressBar(); + ProgressDialog(JFrame owner){ + super(owner); + initGui(); + } + private void initGui(){ + setFont(WSManager.getWorkspaceConfig().getFont()); + setTitle(Logo.messages.getString("titredialogue2")); + prog.setIndeterminate(true); + java.awt.FontMetrics fm = owner.getGraphics() + .getFontMetrics(WSManager.getWorkspaceConfig().getFont()); + int width = fm.stringWidth(Logo.messages.getString("titredialogue2")); + setSize(new Dimension(width+150,100)); + getContentPane().add(prog); + setVisible(true); + } + } +}
\ No newline at end of file diff --git a/logo/src/xlogo/utils/animation.png b/logo/src/xlogo/utils/animation.png Binary files differnew file mode 100644 index 0000000..ec96348 --- /dev/null +++ b/logo/src/xlogo/utils/animation.png diff --git a/logo/src/xlogo/utils/background.png b/logo/src/xlogo/utils/background.png Binary files differnew file mode 100644 index 0000000..fa16b1b --- /dev/null +++ b/logo/src/xlogo/utils/background.png diff --git a/logo/src/xlogo/utils/chercher.png b/logo/src/xlogo/utils/chercher.png Binary files differnew file mode 100644 index 0000000..f3d0e70 --- /dev/null +++ b/logo/src/xlogo/utils/chercher.png diff --git a/logo/src/xlogo/utils/close_icon.png b/logo/src/xlogo/utils/close_icon.png Binary files differnew file mode 100644 index 0000000..003e5af --- /dev/null +++ b/logo/src/xlogo/utils/close_icon.png diff --git a/logo/src/xlogo/utils/down_arrow.png b/logo/src/xlogo/utils/down_arrow.png Binary files differnew file mode 100644 index 0000000..4cfbf80 --- /dev/null +++ b/logo/src/xlogo/utils/down_arrow.png diff --git a/logo/src/xlogo/utils/drapeau0.png b/logo/src/xlogo/utils/drapeau0.png Binary files differnew file mode 100644 index 0000000..1b03ba5 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau0.png diff --git a/logo/src/xlogo/utils/drapeau1.png b/logo/src/xlogo/utils/drapeau1.png Binary files differnew file mode 100644 index 0000000..f7c5c02 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau1.png diff --git a/logo/src/xlogo/utils/drapeau10.png b/logo/src/xlogo/utils/drapeau10.png Binary files differnew file mode 100644 index 0000000..41cfe91 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau10.png diff --git a/logo/src/xlogo/utils/drapeau11.png b/logo/src/xlogo/utils/drapeau11.png Binary files differnew file mode 100644 index 0000000..0d8ceab --- /dev/null +++ b/logo/src/xlogo/utils/drapeau11.png diff --git a/logo/src/xlogo/utils/drapeau12.png b/logo/src/xlogo/utils/drapeau12.png Binary files differnew file mode 100644 index 0000000..bcddaf4 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau12.png diff --git a/logo/src/xlogo/utils/drapeau13.png b/logo/src/xlogo/utils/drapeau13.png Binary files differnew file mode 100644 index 0000000..2b8e820 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau13.png diff --git a/logo/src/xlogo/utils/drapeau2.png b/logo/src/xlogo/utils/drapeau2.png Binary files differnew file mode 100644 index 0000000..22af90c --- /dev/null +++ b/logo/src/xlogo/utils/drapeau2.png diff --git a/logo/src/xlogo/utils/drapeau3.png b/logo/src/xlogo/utils/drapeau3.png Binary files differnew file mode 100644 index 0000000..1444d86 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau3.png diff --git a/logo/src/xlogo/utils/drapeau4.png b/logo/src/xlogo/utils/drapeau4.png Binary files differnew file mode 100644 index 0000000..e16dcb1 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau4.png diff --git a/logo/src/xlogo/utils/drapeau5.png b/logo/src/xlogo/utils/drapeau5.png Binary files differnew file mode 100644 index 0000000..31378fd --- /dev/null +++ b/logo/src/xlogo/utils/drapeau5.png diff --git a/logo/src/xlogo/utils/drapeau6.png b/logo/src/xlogo/utils/drapeau6.png Binary files differnew file mode 100644 index 0000000..68d1cbb --- /dev/null +++ b/logo/src/xlogo/utils/drapeau6.png diff --git a/logo/src/xlogo/utils/drapeau7.png b/logo/src/xlogo/utils/drapeau7.png Binary files differnew file mode 100644 index 0000000..9f9f9b1 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau7.png diff --git a/logo/src/xlogo/utils/drapeau8.png b/logo/src/xlogo/utils/drapeau8.png Binary files differnew file mode 100644 index 0000000..1a5a07c --- /dev/null +++ b/logo/src/xlogo/utils/drapeau8.png diff --git a/logo/src/xlogo/utils/drapeau9.png b/logo/src/xlogo/utils/drapeau9.png Binary files differnew file mode 100644 index 0000000..81001a3 --- /dev/null +++ b/logo/src/xlogo/utils/drapeau9.png diff --git a/logo/src/xlogo/utils/editcopy.png b/logo/src/xlogo/utils/editcopy.png Binary files differnew file mode 100644 index 0000000..28b5162 --- /dev/null +++ b/logo/src/xlogo/utils/editcopy.png diff --git a/logo/src/xlogo/utils/editcut.png b/logo/src/xlogo/utils/editcut.png Binary files differnew file mode 100644 index 0000000..275571d --- /dev/null +++ b/logo/src/xlogo/utils/editcut.png diff --git a/logo/src/xlogo/utils/editpaste.png b/logo/src/xlogo/utils/editpaste.png Binary files differnew file mode 100644 index 0000000..42c2122 --- /dev/null +++ b/logo/src/xlogo/utils/editpaste.png diff --git a/logo/src/xlogo/utils/error.png b/logo/src/xlogo/utils/error.png Binary files differnew file mode 100644 index 0000000..3dd3b55 --- /dev/null +++ b/logo/src/xlogo/utils/error.png diff --git a/logo/src/xlogo/utils/fileprint.png b/logo/src/xlogo/utils/fileprint.png Binary files differnew file mode 100644 index 0000000..669b738 --- /dev/null +++ b/logo/src/xlogo/utils/fileprint.png diff --git a/logo/src/xlogo/utils/fog.png b/logo/src/xlogo/utils/fog.png Binary files differnew file mode 100644 index 0000000..8cd7bfd --- /dev/null +++ b/logo/src/xlogo/utils/fog.png diff --git a/logo/src/xlogo/utils/gnu_gpl.png b/logo/src/xlogo/utils/gnu_gpl.png Binary files differnew file mode 100644 index 0000000..8ac8564 --- /dev/null +++ b/logo/src/xlogo/utils/gnu_gpl.png diff --git a/logo/src/xlogo/utils/icone.png b/logo/src/xlogo/utils/icone.png Binary files differnew file mode 100644 index 0000000..20484b8 --- /dev/null +++ b/logo/src/xlogo/utils/icone.png diff --git a/logo/src/xlogo/utils/info_icon.png b/logo/src/xlogo/utils/info_icon.png Binary files differnew file mode 100644 index 0000000..4d7fe39 --- /dev/null +++ b/logo/src/xlogo/utils/info_icon.png diff --git a/logo/src/xlogo/utils/light0.png b/logo/src/xlogo/utils/light0.png Binary files differnew file mode 100644 index 0000000..2ce6bd6 --- /dev/null +++ b/logo/src/xlogo/utils/light0.png diff --git a/logo/src/xlogo/utils/light1.png b/logo/src/xlogo/utils/light1.png Binary files differnew file mode 100644 index 0000000..70e5149 --- /dev/null +++ b/logo/src/xlogo/utils/light1.png diff --git a/logo/src/xlogo/utils/light2.png b/logo/src/xlogo/utils/light2.png Binary files differnew file mode 100644 index 0000000..a5d6c42 --- /dev/null +++ b/logo/src/xlogo/utils/light2.png diff --git a/logo/src/xlogo/utils/light3.png b/logo/src/xlogo/utils/light3.png Binary files differnew file mode 100644 index 0000000..4dc827e --- /dev/null +++ b/logo/src/xlogo/utils/light3.png diff --git a/logo/src/xlogo/utils/menubtn.png b/logo/src/xlogo/utils/menubtn.png Binary files differnew file mode 100644 index 0000000..ec6a2bf --- /dev/null +++ b/logo/src/xlogo/utils/menubtn.png diff --git a/logo/src/xlogo/utils/play.png b/logo/src/xlogo/utils/play.png Binary files differnew file mode 100644 index 0000000..ea86208 --- /dev/null +++ b/logo/src/xlogo/utils/play.png diff --git a/logo/src/xlogo/utils/preview0.png b/logo/src/xlogo/utils/preview0.png Binary files differnew file mode 100644 index 0000000..4e428f5 --- /dev/null +++ b/logo/src/xlogo/utils/preview0.png diff --git a/logo/src/xlogo/utils/preview1.png b/logo/src/xlogo/utils/preview1.png Binary files differnew file mode 100644 index 0000000..632ffa7 --- /dev/null +++ b/logo/src/xlogo/utils/preview1.png diff --git a/logo/src/xlogo/utils/preview2.png b/logo/src/xlogo/utils/preview2.png Binary files differnew file mode 100644 index 0000000..69468cf --- /dev/null +++ b/logo/src/xlogo/utils/preview2.png diff --git a/logo/src/xlogo/utils/preview3.png b/logo/src/xlogo/utils/preview3.png Binary files differnew file mode 100644 index 0000000..5b34a32 --- /dev/null +++ b/logo/src/xlogo/utils/preview3.png diff --git a/logo/src/xlogo/utils/preview4.png b/logo/src/xlogo/utils/preview4.png Binary files differnew file mode 100644 index 0000000..1173235 --- /dev/null +++ b/logo/src/xlogo/utils/preview4.png diff --git a/logo/src/xlogo/utils/preview5.png b/logo/src/xlogo/utils/preview5.png Binary files differnew file mode 100644 index 0000000..b6f276a --- /dev/null +++ b/logo/src/xlogo/utils/preview5.png diff --git a/logo/src/xlogo/utils/preview6.png b/logo/src/xlogo/utils/preview6.png Binary files differnew file mode 100644 index 0000000..d7d1d2c --- /dev/null +++ b/logo/src/xlogo/utils/preview6.png diff --git a/logo/src/xlogo/utils/quit.png b/logo/src/xlogo/utils/quit.png Binary files differnew file mode 100644 index 0000000..54be95d --- /dev/null +++ b/logo/src/xlogo/utils/quit.png diff --git a/logo/src/xlogo/utils/redo.png b/logo/src/xlogo/utils/redo.png Binary files differnew file mode 100644 index 0000000..4766577 --- /dev/null +++ b/logo/src/xlogo/utils/redo.png diff --git a/logo/src/xlogo/utils/remove_256.png b/logo/src/xlogo/utils/remove_256.png Binary files differnew file mode 100644 index 0000000..51e436d --- /dev/null +++ b/logo/src/xlogo/utils/remove_256.png diff --git a/logo/src/xlogo/utils/screenshot.png b/logo/src/xlogo/utils/screenshot.png Binary files differnew file mode 100644 index 0000000..792558e --- /dev/null +++ b/logo/src/xlogo/utils/screenshot.png diff --git a/logo/src/xlogo/utils/stop.png b/logo/src/xlogo/utils/stop.png Binary files differnew file mode 100644 index 0000000..0c1a0a9 --- /dev/null +++ b/logo/src/xlogo/utils/stop.png diff --git a/logo/src/xlogo/utils/tortue0.png b/logo/src/xlogo/utils/tortue0.png Binary files differnew file mode 100644 index 0000000..ba7057b --- /dev/null +++ b/logo/src/xlogo/utils/tortue0.png diff --git a/logo/src/xlogo/utils/tortue1.png b/logo/src/xlogo/utils/tortue1.png Binary files differnew file mode 100644 index 0000000..dd97517 --- /dev/null +++ b/logo/src/xlogo/utils/tortue1.png diff --git a/logo/src/xlogo/utils/tortue2.png b/logo/src/xlogo/utils/tortue2.png Binary files differnew file mode 100644 index 0000000..5ba638f --- /dev/null +++ b/logo/src/xlogo/utils/tortue2.png diff --git a/logo/src/xlogo/utils/tortue3.png b/logo/src/xlogo/utils/tortue3.png Binary files differnew file mode 100644 index 0000000..1234947 --- /dev/null +++ b/logo/src/xlogo/utils/tortue3.png diff --git a/logo/src/xlogo/utils/tortue4.png b/logo/src/xlogo/utils/tortue4.png Binary files differnew file mode 100644 index 0000000..499fbef --- /dev/null +++ b/logo/src/xlogo/utils/tortue4.png diff --git a/logo/src/xlogo/utils/tortue5.png b/logo/src/xlogo/utils/tortue5.png Binary files differnew file mode 100644 index 0000000..bf622f2 --- /dev/null +++ b/logo/src/xlogo/utils/tortue5.png diff --git a/logo/src/xlogo/utils/tortue6.png b/logo/src/xlogo/utils/tortue6.png Binary files differnew file mode 100644 index 0000000..2be5e71 --- /dev/null +++ b/logo/src/xlogo/utils/tortue6.png diff --git a/logo/src/xlogo/utils/undo.png b/logo/src/xlogo/utils/undo.png Binary files differnew file mode 100644 index 0000000..e7bc8ec --- /dev/null +++ b/logo/src/xlogo/utils/undo.png diff --git a/logo/src/xlogo/utils/up_arrow.png b/logo/src/xlogo/utils/up_arrow.png Binary files differnew file mode 100644 index 0000000..06d5aee --- /dev/null +++ b/logo/src/xlogo/utils/up_arrow.png diff --git a/logo/src/xlogo/utils/zoomin.png b/logo/src/xlogo/utils/zoomin.png Binary files differnew file mode 100644 index 0000000..c896f8f --- /dev/null +++ b/logo/src/xlogo/utils/zoomin.png diff --git a/logo/src/xlogo/utils/zoomout.png b/logo/src/xlogo/utils/zoomout.png Binary files differnew file mode 100644 index 0000000..a3da47d --- /dev/null +++ b/logo/src/xlogo/utils/zoomout.png diff --git a/logo/vecmath.jar b/logo/vecmath.jar Binary files differnew file mode 100644 index 0000000..3eda5f9 --- /dev/null +++ b/logo/vecmath.jar diff --git a/logo/windows/amd64/j3dcore-ogl.dll b/logo/windows/amd64/j3dcore-ogl.dll Binary files differnew file mode 100644 index 0000000..2afec5f --- /dev/null +++ b/logo/windows/amd64/j3dcore-ogl.dll diff --git a/logo/windows/x86/j3dcore-d3d.dll b/logo/windows/x86/j3dcore-d3d.dll Binary files differnew file mode 100644 index 0000000..e9a3901 --- /dev/null +++ b/logo/windows/x86/j3dcore-d3d.dll diff --git a/logo/windows/x86/j3dcore-ogl-cg.dll b/logo/windows/x86/j3dcore-ogl-cg.dll Binary files differnew file mode 100644 index 0000000..2ec07eb --- /dev/null +++ b/logo/windows/x86/j3dcore-ogl-cg.dll diff --git a/logo/windows/x86/j3dcore-ogl-chk.dll b/logo/windows/x86/j3dcore-ogl-chk.dll Binary files differnew file mode 100644 index 0000000..37afe01 --- /dev/null +++ b/logo/windows/x86/j3dcore-ogl-chk.dll diff --git a/logo/windows/x86/j3dcore-ogl.dll b/logo/windows/x86/j3dcore-ogl.dll Binary files differnew file mode 100644 index 0000000..fb9b600 --- /dev/null +++ b/logo/windows/x86/j3dcore-ogl.dll |