package org.gingercal; import java.text.DateFormatSymbols; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; /** * Interface language. English text is the key; Galician comes from the table below. * Android 2.3 ships no Galician locale data, so month and weekday names live here too. * tools/check_i18n.py checks that every L.t()/L.f() key has a translation with matching * placeholders. */ public final class L { private L() {} /** Galician on (the app default); the desktop tests run in English. */ public static volatile boolean gl; private static final Map GL = new HashMap(); public static String t(String en) { if (!gl) return en; String v = GL.get(en); return v == null ? en : v; } public static String f(String en, Object... args) { return String.format(Locale.US, t(en), args); } // ------------------------------------------------------------------ dates static final String[] GL_MONTHS = {"xaneiro", "febreiro", "marzo", "abril", "maio", "xuño", "xullo", "agosto", "setembro", "outubro", "novembro", "decembro"}; static final String[] GL_MONTHS_SHORT = {"xan", "feb", "mar", "abr", "mai", "xuñ", "xul", "ago", "set", "out", "nov", "dec"}; static final String[] GL_DAYS = {"", "domingo", "luns", "martes", "mércores", "xoves", "venres", "sábado"}; static final String[] GL_DAYS_SHORT = {"", "dom", "lun", "mar", "mér", "xov", "ven", "sáb"}; public static DateFormatSymbols symbols() { if (!gl) return new DateFormatSymbols(Locale.US); // English names, whatever the phone's language DateFormatSymbols s = new DateFormatSymbols(Locale.US); s.setMonths(GL_MONTHS); s.setShortMonths(GL_MONTHS_SHORT); s.setWeekdays(GL_DAYS); s.setShortWeekdays(GL_DAYS_SHORT); s.setAmPmStrings(new String[] {"a.m.", "p.m."}); return s; } public static SimpleDateFormat df(String pattern) { return new SimpleDateFormat(pattern, symbols()); } /** "Outubro de 2026" / "October 2026". */ public static String monthTitle(long t) { String s = df(gl ? "MMMM 'de' yyyy" : "MMMM yyyy").format(new Date(t)); return s.length() > 0 ? Character.toUpperCase(s.charAt(0)) + s.substring(1) : s; } public static int firstDayOfWeek() { return gl ? Calendar.MONDAY : Calendar.getInstance().getFirstDayOfWeek(); } // ------------------------------------------------------------ translations private static void put(String en, String gal) { GL.put(en, gal); } static { // main screen put("Not set up yet: press Menu > Settings.", "Aínda sen configurar: preme Menú > Configuración."); put("Syncing…", "Sincronizando…"); put("Loading %s from the server…", "Cargando %s do servidor…"); put("Couldn't load this month: %s", "Non se puido cargar este mes: %s"); put("never", "nunca"); put("Sync failed: %s\nLast good sync: %s", "Erro de sincronización: %s\nÚltima sincronización correcta: %s"); put("Synced %s", "Sincronizado: %s"); put("No upcoming events. Menu > New event, or Menu > Sync.", "Non hai eventos próximos. Menú > Novo evento ou Menú > Sincronizar."); put("Nothing on %s. Long-press a day to add an event.", "Non hai nada o %s. Mantén premido un día para engadir un evento."); put("View", "Vista"); put("Agenda", "Axenda"); put("Month", "Mes"); put("New event", "Novo evento"); put("Sync", "Sincronizar"); put("Today", "Hoxe"); put("Calendars", "Calendarios"); put("Settings", "Configuración"); put("Sync first: no writable calendar yet.", "Sincroniza primeiro: aínda non hai ningún calendario con permiso de escritura."); put("Calendar: %s", "Calendario: %s"); put("Repeating event: edit the series in Nextcloud. Delete removes the whole series.", "Evento periódico: edita a serie en Nextcloud. Eliminar borra a serie completa."); put("(no title)", "(sen título)"); put("(repeats)", "(repítese)"); put("Close", "Pechar"); put("Edit", "Editar"); put("Delete", "Eliminar"); put("Delete event?", "Eliminar o evento?"); put("This deletes EVERY occurrence of \"%s\".", "Isto elimina TODAS as repeticións de «%s»."); put("\"%s\" will be deleted on the server.", "«%s» eliminarase no servidor."); put("Cancel", "Cancelar"); put("Deleting…", "Eliminando…"); put("Delete failed", "Non se puido eliminar"); put("OK", "Aceptar"); // dates and times put("Today · %s", "Hoxe · %s"); put("Tomorrow · %s", "Mañá · %s"); put("All day", "Todo o día"); put("All day, until %s", "Todo o día, ata o %s"); put("No reminder", "Sen aviso"); put("At start time", "Á hora de comezo"); put("%d min before", "%d min antes"); put("%d h before", "%d h antes"); put("%d day before", "%d día antes"); // event editor put("Edit event", "Editar evento"); put("Title", "Título"); put("Starts", "Comeza"); put("Ends", "Remata"); put("Location", "Lugar"); put("Notes", "Notas"); put("Save", "Gardar"); put("Alarm: %s", "Aviso: %s"); put("Alarm (saved in the event)", "Aviso (gárdase no evento)"); put("Calendar", "Calendario"); put("The end is before the start.", "O final é anterior ao comezo."); put("No writable calendar. Sync first.", "Non hai ningún calendario con permiso de escritura. Sincroniza primeiro."); put("Loading…", "Cargando…"); put("Can't load event", "Non se puido cargar o evento"); put("Repeating event", "Evento periódico"); put("Repeating events can't be edited on the phone yet. Edit the series in Nextcloud.", "Os eventos periódicos aínda non se poden editar no teléfono. Edita a serie en Nextcloud."); put("Can't edit", "Non se pode editar"); put("The server returned no event data.", "O servidor non devolveu os datos do evento."); put("Saving…", "Gardando…"); put("Not saved", "Non se gardou"); put("Saved", "Gardado"); // calendars put("No calendars yet. Set up the account in Settings and sync.", "Aínda non hai calendarios. Configura a conta en Configuración e sincroniza."); put("(read-only)", "(só lectura)"); put("first writable", "o primeiro con escritura"); put("New events go to: %s", "Os eventos novos gárdanse en: %s"); put("Default calendar", "Calendario predeterminado"); // settings put("Calendar Lite settings", "Configuración de Calendar Lite"); put("Nextcloud server: your normal https:// address. This app brings its own modern TLS, so no bridge is needed, at home or away. Use an app password, not your real one.", "Servidor Nextcloud: o teu enderezo https:// de sempre. Esta aplicación trae o seu propio TLS moderno, así que non fai falta ningunha ponte, nin na casa nin fóra. Usa un contrasinal de aplicación, non o teu contrasinal real."); put("Server address", "Enderezo do servidor"); put("User name", "Usuario"); put("App password", "Contrasinal de aplicación"); put("Pinned certificate SHA-256 (filled in for you)", "SHA-256 do certificado fixado (énchese automaticamente)"); put("optional", "opcional"); put("Days ahead to sync", "Días futuros que sincronizar"); put("Save and test connection", "Gardar e probar a conexión"); put("Re-download everything", "Descargar todo de novo"); put("Background sync", "Sincronización automática"); put("Background sync: %s", "Sincronización automática: %s"); put("Manual only", "Só manual"); put("Every hour", "Cada hora"); put("Every %d hours", "Cada %d horas"); put("Phone notification", "Notificación no teléfono"); put("Notification: %s", "Notificación: %s"); put("Off", "Desactivada"); put("off", "desactivada"); put("Language: %s", "Lingua: %s"); put("Re-downloading in the background", "Descargando todo de novo en segundo plano"); put("Server address and user name are required.", "O enderezo do servidor e o usuario son obrigatorios."); put("Unencrypted connection", "Conexión sen cifrar"); put("http:// sends your password in clear text over the internet. Use the https:// address instead, or only use http:// to a LAN address.", "Con http:// o contrasinal viaxa sen cifrar por internet. Usa o enderezo https://, ou usa http:// só cun enderezo da rede local."); put("Use anyway", "Usar igualmente"); put("Connecting…", "Conectando…"); put("Connection failed", "Erro de conexión"); put("Connected. Calendars found: %d\n", "Conectado. Calendarios atopados: %d\n"); put("It works", "Funciona"); put("Sync now", "Sincronizar agora"); // certificate trust put("WARNING: the server certificate changed since you trusted it. That happens when a self-signed certificate is regenerated - or when someone is intercepting the connection.\n\n", "AVISO: o certificado do servidor cambiou desde que confiaches nel. Isto pasa se se rexenera un certificado autoasinado, ou se alguén está a interceptar a conexión.\n\n"); put("The server certificate isn't signed by a known authority (normal for a self-signed server or an old TLS 1.0 bridge).\n\n", "O certificado do servidor non está asinado por unha autoridade coñecida (é normal nun servidor autoasinado ou nunha ponte TLS 1.0 antiga).\n\n"); put("Subject: %s\nIssuer: %s\nExpires: %s\n\nSHA-256:\n%s\n\nOnly trust it if this matches the fingerprint printed on your server.", "Suxeito: %s\nEmisor: %s\nCaduca: %s\n\nSHA-256:\n%s\n\nConfía nel só se coincide coa pegada dixital que mostra o teu servidor."); put("Certificate changed!", "O certificado cambiou!"); put("Trust this certificate?", "Confiar neste certificado?"); put("Trust", "Confiar"); put("Interrupted", "Interrompido"); put("The server certificate is for a different address (%1$s).", "O certificado do servidor é doutro enderezo (%1$s)."); put("The server certificate has expired, or the phone's date is wrong.", "O certificado do servidor caducou ou a data do teléfono é incorrecta."); put("Server certificate changed (does not match the pinned fingerprint)", "O certificado do servidor cambiou (non coincide coa pegada fixada)"); put("Server certificate is not trusted by this phone", "Este teléfono non confía no certificado do servidor"); // errors put("Can't resolve %s. No connection, or a typo in the server address.", "Non se pode resolver %s. Non hai conexión ou hai un erro no enderezo do servidor."); put("Can't connect to the server (%s). Wrong address or port, or the server is down?", "Non se pode conectar co servidor (%s). Enderezo ou porto incorrecto, ou servidor caído?"); put("The server took too long to answer.", "O servidor tardou de máis en responder."); put("TLS error: %s", "Erro TLS: %s"); put("Network error: %s", "Erro de rede: %s"); put("Out of memory. Lower 'Days ahead' in Settings.", "Sen memoria. Reduce «Días futuros» na configuración."); put("Error: %s", "Erro: %s"); put("Login refused (401). Check the user name and use a Nextcloud app password (Settings > Security > Devices & sessions).", "Acceso rexeitado (401). Comproba o usuario e usa un contrasinal de aplicación de Nextcloud (Configuración > Seguranza > Dispositivos e sesións)."); put("Not allowed to write to this calendar (403). It may be read-only/shared.", "Non tes permiso para escribir neste calendario (403). Pode ser de só lectura ou compartido."); put("Too many redirects from the server.", "O servidor fixo demasiadas redireccións."); put("The server redirected to %s, not the address set in the app. Put that address in Settings.", "O servidor redirixiu a %s, que non é o enderezo configurado na aplicación. Pon ese enderezo na configuración."); put("Redirect loop (HTTP %d back to the same address). Use the server's https:// address in Settings.", "Bucle de redirección (HTTP %d ao mesmo enderezo). Usa o enderezo https:// do servidor na configuración."); put("%s %s failed: HTTP %d%s", "%s %s fallou: HTTP %d%s"); put(" (not found)", " (non atopado)"); put(" (not a WebDAV URL?)", " (non é un URL WebDAV?)"); put("Server did not report a CalDAV principal", "O servidor non informou de ningún principal CalDAV"); put("Could not load event: HTTP %d", "Non se puido cargar o evento: HTTP %d"); put("Saving failed: HTTP %d", "Non se puido gardar: HTTP %d"); put("Event was changed on the server meanwhile. Sync and try again.", "O evento cambiou no servidor mentres tanto. Sincroniza e téntao de novo."); put("Delete failed: HTTP %d", "Non se puido eliminar: HTTP %d"); put("Bad XML from server: %s", "XML incorrecto do servidor: %s"); put("Empty XML from server", "XML baleiro do servidor"); put("%d calendars: %d refreshed (%d events)", "Calendarios: %d, actualizados: %d (eventos: %d)"); put(", %d unchanged", ", sen cambios: %d"); } }