Downloads Documentation Community Contribute Demo






Show Sidebar
Login | Register

Ticket #713: locale_search.patch

File locale_search.patch, 76.7 kB (added by akollegger, 8 months ago)

Patch that provides the proposed functionality.

  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/.classpath

    old new  
    55        <classpathentry kind="src" path="src/web"/> 
    66        <classpathentry kind="src" path="test/api"/> 
    77        <classpathentry kind="src" path="test/web"/> 
    8         <classpathentry kind="lib" path="lib/ant-contrib/ant-contrib-1.0b2.jar"/> 
    98        <classpathentry kind="lib" path="lib/antlr/antlr_2.7.6.jar"/> 
    109        <classpathentry kind="lib" path="lib/cglib/cglib-2.1_3.jar"/> 
    1110        <classpathentry kind="lib" path="lib/commons-beanutils/commons-beanutils-1.7.0.jar"/> 
     
    5756        <classpathentry kind="lib" path="metadata/api/spring"/> 
    5857        <classpathentry kind="lib" path="metadata/api/hibernate"/> 
    5958        <classpathentry kind="lib" path="metadata/api/log4j"/> 
     59        <classpathentry kind="lib" path="lib/ant-contrib/ant-contrib-1.0b2.jar"/> 
    6060        <classpathentry kind="output" path="build/"/> 
    6161</classpath> 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/api/ConceptService.java

    old new  
    350350                        List<ConceptClass> requireClasses, List<ConceptClass> excludeClasses, 
    351351                        List<ConceptDatatype> requireDatatypes,List<ConceptDatatype> excludeDatatypes); 
    352352 
     353 
     354        /** 
     355         * Searches on given phrase via the concept word table within a sorted list of Locales 
     356         *  
     357         * @param phrase/search/words 
     358         *            String 
     359         * @param searchLocales 
     360         *            ordered List of Locales within which to search 
     361         * @param includeRetired 
     362         *            boolean 
     363         * @param requireClasses 
     364         *            List<ConceptClass> 
     365         * @param excludeClasses 
     366         *            List<ConceptClass> 
     367         * @param requireDatatypes 
     368         *            List<ConceptDatatype> 
     369         * @param excludeDatatypes 
     370         *            List<ConceptDatatype> 
     371         * @return 
     372         *  
     373         * @see ConceptService.findConcepts(String,Locale,boolean) 
     374         */ 
     375        @Transactional(readOnly=true) 
     376        @Authorized({"View Concepts"}) 
     377        public List<ConceptWord> findConcepts(String phrase, List<Locale> searchLocales, boolean includeRetired,  
     378                        List<ConceptClass> requireClasses, List<ConceptClass> excludeClasses, 
     379                        List<ConceptDatatype> requireDatatypes,List<ConceptDatatype> excludeDatatypes); 
     380         
    353381        /** 
    354382         *  
    355383         * Finds concepts but only returns the given range 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/api/db/ConceptDAO.java

    old new  
    212212        /** 
    213213         * Searches on given phrase via the concept word table 
    214214         * @param phrase/search/words String 
    215          * @param locale Locale 
     215         * @param locales Locales to include in search 
    216216         * @param includeRetired boolean 
    217217         * @param requireClasses List<ConceptClass> 
    218218         * @param excludeClasses List<ConceptClass> 
     
    220220         * @param excludeDatatypes List<ConceptDatatype> 
    221221         * @return 
    222222         */ 
    223         public List<ConceptWord> findConcepts(String phrase, Locale locale, boolean includeRetired,  
     223        public List<ConceptWord> findConcepts(String phrase, List<Locale> locales, boolean includeRetired,  
    224224                        List<ConceptClass> requireClasses, List<ConceptClass> excludeClasses, 
    225225                        List<ConceptDatatype> requireDatatypes, List<ConceptDatatype> excludeDatatypes); 
    226226         
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/api/db/hibernate/HibernateConceptDAO.java

    old new  
    499499        } 
    500500 
    501501        // TODO below are functions worthy of a second tier 
    502          
     502 
    503503        /** 
    504504         * @see org.openmrs.api.db.ConceptService#findConcepts(java.lang.String,java.util.Locale,boolean) 
    505505         */ 
     
    504504         * @see org.openmrs.api.db.ConceptService#findConcepts(java.lang.String,java.util.Locale,boolean) 
    505505         */ 
    506506        @SuppressWarnings("unchecked") 
    507         public List<ConceptWord> findConcepts(String phrase, Locale loc, boolean includeRetired,  
     507        public List<ConceptWord> findConcepts(String phrase, List<Locale> locales, boolean includeRetired,  
    508508                        List<ConceptClass> requireClasses, List<ConceptClass> excludeClasses, 
    509509                        List<ConceptDatatype> requireDatatypes, List<ConceptDatatype> excludeDatatypes)  
    510510                        { 
    511                 String locale = loc.getLanguage().substring(0, 2);             //only get language portion of locale 
     511                 
    512512                List<String> words = ConceptWord.getUniqueWords(phrase); //assumes getUniqueWords() removes quote(') characters.  (otherwise we would have a security leak) 
    513513                 
    514514                List<ConceptWord> conceptWords = new Vector<ConceptWord>(); 
     
    514514                List<ConceptWord> conceptWords = new Vector<ConceptWord>(); 
    515515                 
    516516                if (words.size() > 0) { 
    517                  
     517                        
    518518                        Criteria searchCriteria = sessionFactory.getCurrentSession().createCriteria(ConceptWord.class, "cw1"); 
    519                         searchCriteria.add(Restrictions.eq("locale", locale)); 
     519                        searchCriteria.add(Expression.in("locale", locales)); 
     520                        // searchCriteria.add(Restrictions.eq("locale", locale)); 
    520521                        if (includeRetired == false) { 
    521522                                searchCriteria.createAlias("concept", "concept"); 
    522523                                searchCriteria.add(Expression.eq("concept.retired", false)); 
     
    531532                                                        .setProjection(Property.forName("concept")) 
    532533                                                        .add(Expression.eqProperty("concept", "cw1.concept")) 
    533534                                                        .add(Restrictions.like("word", w, MatchMode.START)) 
    534                                                         .add(Restrictions.eq("locale", locale)); 
     535                                                        .add(Expression.in("locale", locales)); 
    535536                                junction.add(Subqueries.exists(crit)); 
    536537                        } 
    537538                        searchCriteria.add(junction); 
     
    560561                 
    561562                return conceptWords; 
    562563        } 
     564 
    563565         
    564566        /** 
    565567         * @see org.openmrs.api.db.ConceptService#findConcepts(java.lang.String,java.util.Locale,org.openmrs.Concept,boolean) 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/api/impl/ConceptServiceImpl.java

    old new  
    476476                        requireDatatypes = new Vector<ConceptDatatype>(); 
    477477                if (excludeDatatypes == null) 
    478478                        excludeDatatypes = new Vector<ConceptDatatype>(); 
     479 
     480                List<Locale> searchLocales = new ArrayList<Locale>(); 
     481                searchLocales.add(locale); 
    479482                 
    480483                List<ConceptWord> conceptWords = getConceptDAO().findConcepts(phrase, 
    481                                locale, includeRetired, requireClasses, excludeClasses, requireDatatypes, excludeDatatypes); 
     484                                                                              searchLocales, includeRetired, requireClasses, excludeClasses, requireDatatypes, excludeDatatypes); 
    482485 
    483486                return weightWords(phrase, locale, conceptWords); 
    484487        } 
     
    484487        } 
    485488 
    486489        /** 
     490     * @see org.openmrs.api.ConceptService#findConcepts(java.lang.String, java.util.List, boolean, java.util.List, java.util.List, java.util.List, java.util.List) 
     491     */ 
     492    public List<ConceptWord> findConcepts(String phrase, 
     493            List<Locale> searchLocales, boolean includeRetired, 
     494            List<ConceptClass> requireClasses, 
     495            List<ConceptClass> excludeClasses, 
     496            List<ConceptDatatype> requireDatatypes, 
     497            List<ConceptDatatype> excludeDatatypes) { 
     498 
     499                if (requireClasses == null) 
     500                        requireClasses = new Vector<ConceptClass>(); 
     501                if (excludeClasses == null) 
     502                        excludeClasses = new Vector<ConceptClass>(); 
     503                if (requireDatatypes == null) 
     504                        requireDatatypes = new Vector<ConceptDatatype>(); 
     505                if (excludeDatatypes == null) 
     506                        excludeDatatypes = new Vector<ConceptDatatype>(); 
     507                 
     508                List<ConceptWord> conceptWords = getConceptDAO(). 
     509                        findConcepts(phrase, searchLocales, includeRetired, requireClasses,  
     510                                     excludeClasses, requireDatatypes, excludeDatatypes); 
     511 
     512                return weightWords(phrase, searchLocales, conceptWords); 
     513    } 
     514     
     515        /** 
    487516         *  
    488517         * Finds concepts but only returns the given range 
    489518         *  
     
    529558 
    530559        /** 
    531560         * This will weight and sort the concepts we are assuming the hits are 
    532          * sorted with synonym matches at the bottom 
     561         * sorted with synonym matches at the bottom. 
     562         *  
     563         * @deprecated use weightWords() with multiple locales instead 
    533564         *  
    534565         * @param phrase 
    535566         *            that was used to get this search 
     
    540571         */ 
    541572        protected List<ConceptWord> weightWords(String phrase, Locale locale, 
    542573                        List<ConceptWord> conceptWords) { 
     574                List<Locale> locales = new ArrayList<Locale>(); 
     575                locales.add(locale); 
     576                return weightWords(phrase, locales, conceptWords); 
     577        } 
     578         
     579        /** 
     580         * This will weight and sort the concepts we are assuming the hits are 
     581         * sorted with synonym matches at the bottom 
     582         *  
     583         * @param phrase 
     584         *            that was used to get this search 
     585         * @param locales 
     586         *            that were used to get this search 
     587         * @param conceptWords 
     588         * @return 
     589         */ 
     590        protected List<ConceptWord> weightWords(String phrase, List<Locale> locales, 
     591                        List<ConceptWord> conceptWords) { 
    543592 
    544593                // Map<ConceptId, ConceptWord> 
    545594                Map<Integer, ConceptWord> uniqueConcepts = new HashMap<Integer, ConceptWord>(); 
     
    564613                                // check synonym in case we have multiple synonym hits 
    565614                                String toSplit = initialWord.getSynonym(); 
    566615                                if (toSplit == null || toSplit.equals("")) { 
    567                                         ConceptName cn = initialWord.getConcept().getName(locale); 
    568                                         toSplit = cn.getName(); 
     616                                        ConceptName cn = null; 
     617                                        // find which locale provided the concept name 
     618                                        for (Locale locale : locales) { 
     619                                                cn = initialWord.getConcept().getName(locale); 
     620                                                if (cn != null) { 
     621                                                        toSplit = cn.getName(); 
     622                                                        break; 
     623                                                } 
     624                                        } 
    569625                                } 
    570626                                List<String> nameWords = ConceptWord.getUniqueWords(toSplit); 
    571627 
     
    593649                                if (matchedString.length() == 0) { 
    594650                                        // We weight name matches higher 
    595651                                        tmpWord.increaseWeight(2.0); 
    596                                         matchedString = tmpWord.getConcept().getName(locale) 
    597                                                         .getName(); 
     652                                        for (Locale locale : locales) { 
     653                                                ConceptName cn = tmpWord.getConcept().getName(locale); 
     654                                                if (cn != null) { 
     655                                                        matchedString = cn.getName(); 
     656                                                        break; 
     657                                                } 
     658                                        } 
    598659                                } 
    599660 
    600661                                // increase the weight by a factor of the % of words matched 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/User.java

    old new  
    1313 */ 
    1414package org.openmrs; 
    1515 
     16import java.util.ArrayList; 
    1617import java.util.Collection; 
    1718import java.util.Date; 
    1819import java.util.HashSet; 
     
    1718import java.util.Date; 
    1819import java.util.HashSet; 
    1920import java.util.Iterator; 
     21import java.util.List; 
     22import java.util.Locale; 
    2023import java.util.Map; 
    2124import java.util.Set; 
    2225 
     
    2225 
    2326import org.apache.commons.logging.Log; 
    2427import org.apache.commons.logging.LogFactory; 
     28import org.openmrs.util.LocaleFactory; 
    2529import org.openmrs.util.OpenmrsConstants; 
    2630 
    2731/** 
     
    548552        public String getLastName() { 
    549553                return getFamilyName(); 
    550554        } 
     555 
     556        /** 
     557         * Returns a list of Locales for which the User  
     558         * is considered proficient. 
     559     *  
     560     * @return List of the User's proficient locales 
     561     */ 
     562    public List<Locale> getProficientLocales() { 
     563        List<Locale> proficientLocales = new ArrayList<Locale>(); 
     564                String proficientLocalesValue = getUserProperty(OpenmrsConstants.USER_PROPERTY_PROFICIENT_LOCALES); 
     565                 
     566                String[] proficientLocalesArray = proficientLocalesValue.split(","); 
     567                for (String proficientLocaleSpec : proficientLocalesArray) { 
     568                        if (proficientLocaleSpec.length() > 0) { 
     569                                proficientLocales.add(LocaleFactory.fromSpecification(proficientLocaleSpec)); 
     570                        } 
     571                } 
     572        return proficientLocales; 
     573    } 
    551574} 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/util/LocaleFactory.java

    old new  
     1package org.openmrs.util; 
     2 
     3 
     4import java.util.Collection; 
     5import java.util.List; 
     6import java.util.Locale; 
     7import java.util.Vector; 
     8 
     9/** 
     10 * A factory for creating Locales. 
     11 *  
     12 * @author <a href="mailto:akollegger@tembopublic.org">Andreas Kollegger</a> 
     13 */ 
     14public class LocaleFactory { 
     15 
     16        /** 
     17         * Default internal locale. 
     18         *  
     19         * ABKTODO: this should be defined/configured somewhere else 
     20         */ 
     21        public static final Locale DEFAULT_LOCALE = Locale.ENGLISH; 
     22         
     23        /** 
     24         * Creates a locale based on a string specification. The specification 
     25         * must be conform with the following format: ll_CC_vv 
     26         *  
     27         * Where: 
     28         *      ll two-character lowercase ISO-639 language code 
     29         *  CC two-character uppercase ISO-3166 country code optional 
     30         *  vv arbitrary length variant code 
     31         *  
     32         * For example: 
     33         *      en_US_Traditional_WIN 
     34         * ...represents English language in the United States with the traditional collation for windows. 
     35         *  
     36         * @param localeSpecification encoded locale specification 
     37         * @return the representative Locale, or null if the specification is invalid 
     38         */ 
     39        public static Locale fromSpecification(String localeSpecification) 
     40        { 
     41                Locale createdLocale = null; 
     42                 
     43                localeSpecification = localeSpecification.trim(); 
     44                 
     45                String[] localeComponents = localeSpecification.split("_"); 
     46                if (localeComponents.length == 1) 
     47                { 
     48                        createdLocale = new Locale(localeComponents[0]); 
     49                } 
     50                else if (localeComponents.length == 2) 
     51                { 
     52                        createdLocale = new Locale(localeComponents[0], localeComponents[1]); 
     53                } 
     54                else if (localeComponents.length > 2) 
     55                { 
     56                        String variant = localeSpecification.substring(localeSpecification.indexOf(localeComponents[2])); 
     57                        createdLocale = new Locale(localeComponents[0], localeComponents[1], variant); 
     58                } 
     59                 
     60                return createdLocale; 
     61        } 
     62} 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/api/org/openmrs/util/OpenmrsConstants.java

    old new  
    532532        public static final String USER_PROPERTY_NOTIFICATION                   = "notification"; 
    533533        public static final String USER_PROPERTY_NOTIFICATION_ADDRESS   = "notificationAddress"; 
    534534        public static final String USER_PROPERTY_NOTIFICATION_FORMAT    = "notificationFormat";         // text/plain, text/html 
     535 
     536        /** 
     537         * A user property name. The value should be a comma-separated ordered  
     538         * list of fully qualified locales within which the user is a proficient  
     539         * speaker. The list should be ordered from the most to the least proficiency. 
     540         *  
     541         * Example: 
     542         * <code>proficientLocales = en_US, en_GB, en, fr_RW</code> 
     543         */ 
     544        public static final String USER_PROPERTY_PROFICIENT_LOCALES                     = "proficientLocales"; 
    535545         
    536546        /* 
    537547         * Report object properties 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/web/org/openmrs/web/controller/OptionsFormController.java

    old new  
    2929import org.openmrs.api.EncounterService; 
    3030import org.openmrs.api.UserService; 
    3131import org.openmrs.api.context.Context; 
     32import org.openmrs.util.LocaleFactory; 
    3233import org.openmrs.util.OpenmrsConstants; 
    3334import org.openmrs.web.OptionsForm; 
    3435import org.openmrs.web.WebConstants; 
     
    101102                         
    102103                        properties.put(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCATION, opts.getDefaultLocation()); 
    103104                        properties.put(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE, opts.getDefaultLocale()); 
     105                        properties.put(OpenmrsConstants.USER_PROPERTY_PROFICIENT_LOCALES, opts.getProficientLocales()); 
    104106                        properties.put(OpenmrsConstants.USER_PROPERTY_SHOW_RETIRED, opts.getShowRetiredMessage().toString()); 
    105107                        properties.put(OpenmrsConstants.USER_PROPERTY_SHOW_VERBOSE, opts.getVerbose().toString()); 
    106108                        properties.put(OpenmrsConstants.USER_PROPERTY_NOTIFICATION, opts.getNotification() == null ? "" : opts.getNotification().toString()); 
     
    197199                        Map<String, String> props = user.getUserProperties(); 
    198200                        opts.setDefaultLocation(props.get(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCATION)); 
    199201                        opts.setDefaultLocale(props.get(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)); 
     202                        opts.setProficientLocales(props.get(OpenmrsConstants.USER_PROPERTY_PROFICIENT_LOCALES)); 
    200203                        opts.setShowRetiredMessage(new Boolean(props.get(OpenmrsConstants.USER_PROPERTY_SHOW_RETIRED))); 
    201204                        opts.setVerbose(new Boolean(props.get(OpenmrsConstants.USER_PROPERTY_SHOW_VERBOSE))); 
    202205                        opts.setUsername(user.getUsername()); 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/web/org/openmrs/web/dwr/DWRConceptService.java

    old new  
    7575 
    7676                log.info(userId + "|" + phrase + "|" + includeClassNames.toString()); 
    7777 
    78                 Locale locale = Context.getLocale(); 
     78                Locale defaultLocale = Context.getLocale(); 
     79                List<Locale> searchLocales = u.getProficientLocales(); 
     80                if (searchLocales.size() == 0) { 
     81                        searchLocales.add(defaultLocale); 
     82                         
     83                        // if country is specified, also add the generic language locale 
     84                        if (defaultLocale.getCountry() != "") { 
     85                                searchLocales.add(new Locale(defaultLocale.getLanguage())); 
     86                        } 
     87                                 
     88                } 
     89                 
    7990                if (includeClassNames == null) 
    8091                        includeClassNames = new Vector<String>(); 
    8192                if (excludeClassNames == null) 
     
    94105                                // corresponding conceptId 
    95106                                Concept c = cs.getConcept(Integer.valueOf(phrase)); 
    96107                                if (c != null) { 
    97                                         ConceptWord word = new ConceptWord(phrase, c, locale 
     108                                        ConceptWord word = new ConceptWord(phrase, c, defaultLocale 
    98109                                                        .getLanguage(), "Concept Id #" + phrase); 
    99110                                        words.add(word); 
    100111                                } 
     
    128139                                                excludeDatatypes.add(cs.getConceptDatatypeByName(name)); 
    129140 
    130141                                // perform the search 
    131                                 words.addAll(cs.findConcepts(phrase, locale, includeRetired,  
     142                                words.addAll(cs.findConcepts(phrase, searchLocales, includeRetired,  
    132143                                                includeClasses, excludeClasses, 
    133144                                                includeDatatypes, excludeDatatypes)); 
    134145                        } 
     
    135146 
    136147                        if (words.size() == 0) { 
    137148                                objectList 
    138                                                 .add("No matches found for <b>" + phrase + "</b> in locale: " + Context.getLocale().getDisplayName()); 
     149                                                .add("No matches found for <b>" + phrase + "</b> in locale: " + defaultLocale); 
    139150                        } else { 
    140151                                objectList = new Vector<Object>(words.size()); 
    141152                                int maxCount = 500; 
     
    154165                                                if (classId.equals(OpenmrsConstants.CONCEPT_CLASS_DRUG)) 
    155166                                                        for (Drug d : cs.getDrugs(word.getConcept())) 
    156167                                                                objectList.add(new ConceptDrugListItem(d, 
    157                                                                                 locale)); 
     168                                                                                defaultLocale)); 
    158169                                        } 
    159170                                } 
    160171                        } 
     
    166177                } 
    167178 
    168179                if (objectList.size() == 0) 
    169                         objectList.add("No matches found for <b>" + phrase + "</b> in locale: " + Context.getLocale().getDisplayName()); 
     180                        objectList.add("No matches found for <b>" + phrase + "</b> in locale: " + defaultLocale); 
    170181 
    171182                return objectList; 
    172183        } 
     
    348359                Concept c = Context.getConceptService().getConcept(conceptId); 
    349360                Collection<ConceptAnswer> answers = c.getAnswers(); 
    350361                // TODO: deal with concept answers (e.g. drug) whose answer concept is null. (Not sure if this actually ever happens) 
     362                Locale locale = Context.getLocale(); 
    351363                for (ConceptAnswer ca : answers) 
    352364                        if (ca.getAnswerConcept() != null) 
    353                                 ret.add(new ConceptListItem(ca.getAnswerConcept(), Context.getLocale())); 
     365                                ret.add(new ConceptListItem(ca.getAnswerConcept(), locale)); 
    354366                return ret; 
    355367        } 
    356368 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/src/web/org/openmrs/web/OptionsForm.java

    old new  
    1717 
    1818        private String defaultLocation = ""; 
    1919        private String defaultLocale = ""; 
     20        private String proficientLocales = ""; 
    2021        private Boolean showRetiredMessage = true; 
    2122        private Boolean verbose = false; 
    2223         
     
    160161                this.verbose = verbose; 
    161162        } 
    162163 
    163                  
     164        /** 
     165         * Sets the locales within which the user is proficient. 
     166     *  
     167     * @param proficientLocales a comma-separated list of locales 
     168     */ 
     169    public void setProficientLocales(String proficientLocales) { 
     170        this.proficientLocales = proficientLocales; 
     171    } 
     172 
     173        /** 
     174         * Returns the locales within which the user is proficient. 
     175     *  
     176     */ 
     177        public String getProficientLocales() { 
     178                return proficientLocales; 
     179        } 
    164180 
    165181} 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/web/WEB-INF/messages.properties

    old new  
    77findPatient.title=OpenMRS - Find Patient 
    88optionsForm.title=OpenMRS - User Options 
    99cohortBuilder.title=OpenMRS - Cohort Builder 
    10 dictionary.title=OpenMRS - Concept Dictionary 
     10dictionary.title=Concept Dictionary Maintenance 
    1111 
    1212 
    1313Navigation.home = Home 
     
    121121general.locale=Locale 
    122122general.nMore={0} more 
    123123general.nLess={0} less 
    124 general.optional=Optional 
     124general.optional=optional 
    125125general.onDate=on 
    126126general.hide=Hide 
    127127general.drop=Drop 
     
    145145general.version=Version 
    146146general.includeVoided=Include Voided 
    147147general.dateConstraints=Date range 
    148 general.optional=optional 
    149148general.since=since 
    150149general.nWeeks={0} week(s) 
    151150general.displayingXtoYofZ=Displaying {0} to {1} of {2} 
     
    177176diagnosis.title=Select a Diagnosis 
    178177conceptAnswer.title=Choose an Answer 
    179178conceptAnswer.forConcept= 
    180  
    181 dictionary.title=Concept Dictionary Maintenance 
    182179dictionary.title.short=Dictionary 
    183180dictionary.searchBox=Search Phrase: 
    184181dictionary.includeRetired=Include retired concepts 
     
    219216options.default.legend=Defaults 
    220217options.default.location=Default Location 
    221218options.default.locale=Default Locale 
     219options.proficient.locales=Proficient Locales 
    222220options.default.verbose=Verbose Display On 
    223221options.showRetiredMessage=Show Retired Message? 
    224222options.login.legend=Change Login Info 
     
    271269typeMismatch.java.lang.Long={0} is not a valid value. Do not use decimals or characters. 
    272270 
    273271welcome=Welcome to <span class="webappName">{0}</span>. Please login to proceed. 
    274 welcomeUser=Hello, {0}. Welcome to <span class="webappName">{1}</span>.  
     272welcomeUser=Hello, {0}. Welcome to <span class\="webappName">{1}</span>.  
    275273 
    276274# 
    277275#### Openmrs POJO messages ####  
     
    335333Concept.add=Add new Concept 
    336334Concept.id=Concept Id 
    337335Concept.set=Is Set? 
    338 Concept.checkClassAndDatatype=Please ensure that this concept's class and datatype are correct. (class=Question should typically not be datatype=N/A.)  
     336Concept.checkClassAndDatatype=Please ensure that this concept's class and datatype are correct. (class\=Question should typically not be datatype\=N/A.)  
    339337Concept.search=Find a concept by typing in its name 
    340338Concept.view.title=Viewing Concept {0} 
    341339Concept.edit.title=Editing Concept {0} 
     
    658656Form.javascriptRequired=Javascript must be enabled to use the schema editor. 
    659657 
    660658FormField.add=Add Form Field 
    661 FormField.fieldNumber= Field #  
     659FormField.fieldNumber= Field \#  
    662660FormField.fieldPart= Field Part  
    663 FormField.pageNumber= Page #  
     661FormField.pageNumber= Page \#  
    664662FormField.minOccurs= Min  
    665663FormField.maxOccurs= Max 
    666664FormField.maxOccurs.help=-1 for infinite  
     
    801799Obs.valueModifier=Value Modifier 
    802800Obs.valueText=Value Text 
    803801Obs.valueInvalid.description=Invalid Concept Selected! 
    804 Obs.valueInvalid.didYouMean=Did you mean the concept to be:  
     802Obs.valueInvalid.didYouMean=Did you mean the concept to be\:  
    805803Obs.dateStarted=Date Started 
    806804Obs.dateStopped=Date Stopped 
    807805Obs.comment=Comment 
     
    11381136RelationshipType.null=Relationship type cannot be null 
    11391137RelationshipType.aIsToB=A is to B 
    11401138RelationshipType.bIsToA=B is to A 
    1141 RelationshipType.bIsToA.required=A is to B name is required 
    11421139RelationshipType.bIsToA.required=B is to A name is required 
    11431140RelationshipType.views.title=Manage Relationship Type Views 
    11441141RelationshipType.views.order=Display Order 
     
    11591156Role.add=Add Role 
    11601157Role.inheritedRoles=Inherited Roles 
    11611158Role.inheritedRoles.description=<span class="thisRole">This role</span> inherits privileges from these roles 
    1162 Role.inheritingRoles.description=Roles that contain (inherit privileges from) <span class="thisRole">this role</span>  
     1159Role.inheritingRoles.description=Roles that contain (inherit privileges from) <span class\="thisRole">this role</span>  
    11631160Role.privileges=Privileges 
    11641161Role.list.title=Current Roles 
    11651162Role.delete=Delete Selected Roles 
     
    13551352Module.loaded=Module {0} has been loaded 
    13561353Module.stopped=Module {0} has been stopped 
    13571354Module.error=Error processing Module 
    1358 Module.add=Add Module 
    13591355Module.addJar=Module file to add 
    13601356Module.invalid=Invalid module specified {0} 
    13611357Module.notStarted=Not Started 
     
    13681364Module.help.unload=When a module is unloaded, it is first 'stopped', then the omod file is removed from the repository. 
    13691365Module.help.startStop=A loaded module can be stopped and started.  A stopped module is still loaded, it just doesn't have any effect on the system. 
    13701366Module.help.update=In order to update a module, either click 'Install Update' or: 1) Download the update, 2) unload the current module then 3) upload the new module via the form above. 
    1371 Module.help.findMore=Find and download more modules in the <a target="moduleRepository" href="https://dev.openmrs.org/modules">OpenMRS Module Repository</a>  
     1367Module.help.findMore=Find and download more modules in the <a target\="moduleRepository" href\="https\://dev.openmrs.org/modules">OpenMRS Module Repository</a>  
    13721368Module.unloadWarning=You are about to completely remove this module from the system. 
    13731369Module.allowUploads=Allow Uploads? 
    13741370Module.disallowUploads=Uploads are not allowed from the website at this time.  The runtime property {0} must be set to true. 
     
    14331429 
    14341430Scheduler.scheduleForm.title=Schedule Form 
    14351431Scheduler.scheduleForm.legend=Schedule 
    1436 Scheduler.scheduleForm.instructions=PLEASE NOTE: Changes to the schedule below are NOT passed onto task instances that are already running.  After saving your changes, you MUST stop/start the desired task on the Task List page in order to pass these schedule changes onto that task.   
     1432Scheduler.scheduleForm.instructions=PLEASE NOTE\: Changes to the schedule below are NOT passed onto task instances that are already running.  After saving your changes, you MUST stop/start the desired task on the Task List page in order to pass these schedule changes onto that task.   
    14371433Scheduler.scheduleForm.started=Started 
    14381434Scheduler.scheduleForm.startOnStartup=Start on startup 
    14391435Scheduler.scheduleForm.startTimePattern=Start time pattern 
     
    14871483Program.states=States 
    14881484Program.state=State 
    14891485Program.conversion.manage=Manage Triggered State Conversions 
    1490 Program.conversion.saved=Trigger State Conversion saved 
     1486Program.conversion.saved=Triggered state conversion has been saved 
    14911487Program.conversion.manage.title=Triggered State Conversions 
    14921488Program.conversion.programWorkflow=In this workflow 
    14931489Program.conversion.concept=This concept 
     
    14951491Program.conversion.list.title=Current Triggered State Conversions 
    14961492Program.conversion.add=Add new state conversion 
    14971493Program.conversion.save=Save this state conversion 
    1498 Program.conversion.saved=Triggered state conversion has been saved 
    14991494Program.conversion=Triggered State Conversion 
    15001495Program.conversion.nonedeleted=No Triggered State Conversions deleted 
    15011496Program.conversion.deleteSelected=Delete selected Triggered State Conversion(s) 
  • /Users/akollegger/Developer/OpenMRS/workspace/openmrs-trunk/web/WEB-INF/messages_fr.properties

    old new  
    1 header.logged.in=Vous êtes entrés comme 
    2 header.logged.out=Non entré 
    3 header.login=Ouverture 
    4 header.logout=Sortie du Système 
     1header.logged.in=Vous \u00EAtes entr\u00E9s comme 
     2header.logged.out=Non entr\u00E9 
     3header.login=Entrer 
     4header.logout=Sortir 
    55header.help=Aide 
    66 
    7 require.login=Vous devez ouvrir une session pour continuer. 
     7require.login=Vous devez ouvrir une session pour continuer 
    88 
    9 Report.manage.title=Report Management 
    109Report.manage.title=Manage Reports 
    1110Report.title=Report Form 
    1211Report.name=Report Name 
     
    2019 
    2120Navigation.home=Accueil 
    2221Navigation.findPatient=Chercher un patient 
    23 Navigation.findCreatePatient = Chercher/créer un patient 
     22Navigation.findCreatePatient = Chercher/cr\u00E9er un patient 
    2423Navigation.dictionary=Dictionnaire 
    2524Navigation.administration=Administration 
    2625Navigation.analysis=Analyse 
     
    2928general.select=Choisir 
    3029general.name=Nom 
    3130general.description=Description 
    32 general.creator=créateur 
    33 general.createdBy=Créé par 
    34 general.dateCreated=Date créé
    35 general.voided=Supprimé 
    36 general.voidedBy=Supprimé par 
    37 general.voidReason=Raison Supprimé 
    38 general.dateVoided=Date Supprimé 
    39 general.changedBy=Changé par 
     31general.creator=cr\u00E9ateur 
     32general.createdBy=Cr\u00E9\u00E9 par 
     33general.dateCreated=Date cr\u00E9\u00E9
     34general.voided=Supprim\u00E9 
     35general.voidedBy=Supprim\u00E9 par 
     36general.voidReason=Raison Supprim\u00E9 
     37general.dateVoided=Date Supprim\u00E9 
     38general.changedBy=Chang\u00E9 par 
    4039general.dateChanged=Date de changement 
    4140general.delete=Supprimer 
    42 general.deleted=Supprimé 
    43 general.cannot.delete=Ne peut pas être supprimé 
    44 general.changed=cannot be changed=Ne peut pas être changé 
    45 general.retired=Supprimé 
    46 general.retiredReason=Raison supprimé 
     41general.deleted=Supprim\u00E9 
     42general.cannot.delete=Ne peut pas \u00EAtre supprim\u00E9 
     43general.changed=cannot be changed\=Ne peut pas \u00EAtre chang\u00E9 
     44general.retired=Supprim\u00E9 
     45general.retiredReason=Raison supprim\u00E9 
    4746general.retiredBy=Add=Ajouter 
    4847general.addAnother=Ajouter un autre 
    4948general.new=Nouveau 
     
    5150general.save=Sauvegarder (Enregistrer) 
    5251general.remove=Enlever 
    5352general.view=Voir 
    54 general.move_up=Déplacement en haut 
    55 general.move_down=Déplacement en bas 
     53general.move_up=D\u00E9placement en haut 
     54general.move_down=D\u00E9placement en bas 
    5655general.search=Chercher 
    5756general.searchButton=Chercher 
    5857general.change=Changer 
    59 general.id=Identité (Id) 
     58general.id=Identit\u00E9 (Id) 
    6059general.continue=Continuer 
    61 general.previous=Précédent 
     60general.previous=Pr\u00E9c\u00E9dent 
    6261general.next=Prochaine 
    6362general.true=Vrai 
    6463general.false=Faux 
     
    6362general.true=Vrai 
    6463general.false=Faux 
    6564general.cancel=Terminer 
    66 general.canceled=Action terminé 
    67 general.preferred=Préféré 
     65general.canceled=Action termin\u00E9 
     66general.preferred=Pr\u00E9f\u00E9r\u00E9 
    6867general.submit=Soumettre 
    69 general.answer=Répondre 
    70 general.download=Télécharger 
    71 general.start=Début 
     68general.answer=R\u00E9pondre 
     69general.download=T\u00E9l\u00E9charger 
     70general.start=D\u00E9but 
    7271general.end=Bout 
    7372general.format=Format 
    7473general.yes=Oui 
     
    7877general.type=Type 
    7978general.subType=Sous-type 
    8079general.toggle.description=Montrer/cacher description 
    81 general.toggle.voided=Montrer/cacher options supprimé
     80general.toggle.voided=Montrer/cacher options supprim\u00E9
    8281general.toggle.verbose=Montrer/cacher plus d'information 
    8382general.or=ou 
    8483general.value=Valeur 
     
    8483general.value=Valeur 
    8584general.none=Aucun 
    8685general.instructions=Instructions 
    87 general.discontinued=Cessé 
    88 general.discontinuedBy=Cessé par 
    89 general.dateStart=Date de début 
    90 general.dateAutoExpire=Date de cessation programmé 
     86general.discontinued=Cess\u00E9 
     87general.discontinuedBy=Cess\u00E9 par 
     88general.dateStart=Date de d\u00E9but 
     89general.dateAutoExpire=Date de cessation programm\u00E9 
    9190general.dateDiscontinued=Date de cessation 
    9291general.locale=Lieu 
    9392general.nMore={0} en plus 
     
    9998general.drop=Eliminer 
    10099general.loading=Chargement... 
    101100general.fromDate=depuis 
    102 general.toDate=jusqu'à 
     101general.toDate=jusqu'\u00E0 
    103102 
    104 auth.logged.out=Votre session est fermé 
     103auth.logged.out=Votre session est ferm\u00E9 
    105104auth.login=Identifiez-vous 
    106 auth.password.invalid=Le nom d'utilisateur et le mot de passe ne correspondent pas. Prière d'essayer une autre fois. 
    107 auth.password.help=Pour remettre à zéro votre mot de passe, entrer votre identification et cheque la boîte: "j'ai oublié mon mot de passe"  
    108 auth.answer.invalid=Mot de passe avec la réponse secrète inadmissible. Prière d'essayer une autre fois.  
    109 auth.question.empty=Prière de contacter un administrateur pour remettre à zéro votre mot de passe 
    110 auth.question.fill= Compléter votre réponse à la question secrète  
    111 auth.password.reset=Votre mot de passe a eté remis à zéro. Prière de remplir les bôites pour votre nouveau mot de passe. 
    112  
    113 header.login=Entrer 
    114 header.logout=Sortir 
    115 header.help=Aide 
     105auth.password.invalid=Le nom d'utilisateur et le mot de passe ne correspondent pas. Pri\u00E8re d'essayer une autre fois. 
     106auth.password.help=Pour remettre \u00E0 z\u00E9ro votre mot de passe, entrer votre identification et cheque la bo\u00EEte\: "j'ai oubli\u00E9 mon mot de passe"  
     107auth.answer.invalid=Mot de passe avec la r\u00E9ponse secr\u00E8te inadmissible. Pri\u00E8re d'essayer une autre fois.  
     108auth.question.empty=Pri\u00E8re de contacter un administrateur pour remettre \u00E0 z\u00E9ro votre mot de passe 
     109auth.question.fill= Compl\u00E9ter votre r\u00E9ponse \u00E0 la question secr\u00E8te  
     110auth.password.reset=Votre mot de passe a et\u00E9 remis \u00E0 z\u00E9ro. Pri\u00E8re de remplir les b\u00F4ites pour votre nouveau mot de passe. 
    116111 
    117112options.title=Votres options 
    118 options.default.legend=Défaut 
    119 options.default.location=Location de défaut  
    120 options.default.locale=Addresse de défaut  
    121 options.login.legend=Changer vôtre compte 
     113options.default.legend=D\u00E9faut 
     114options.default.location=Location de d\u00E9faut  
     115options.default.locale=Addresse de d\u00E9faut  
     116options.proficient.locales=Proficient Locales 
     117options.login.legend=Changer v\u00F4tre compte 
    122118options.login.username=Nom d'utilisateur 
    123119options.login.password.old=Vieux mot de passe 
    124120options.login.password.new=Nouveau mot de passe&nbs