return mf.formatDateTime(tm);
}
+//static
+MLocalFormat MLocalFormat::defaultformat((int)1);
-
-MLocalFormat::MLocalFormat()
+MLocalFormat::MLocalFormat(int)
{
m_moneydecimals=2;
m_thousanddigits=3;
setMoneyFormat();setNumberFormat();
}
+MLocalFormat::MLocalFormat(const MOServerFormat& s)
+{
+ //init from current default
+ operator=(defaultformat);
+ //overwrite with new settings
+ QStringList sl;
+ sl=s.weekdays();if(sl.size())setWeekDays(sl);
+ sl=s.shortweekdays();if(sl.size())setShortWeekDays(sl);
+ sl=s.months();if(sl.size())setMonths(sl);
+ sl=s.shortmonths();if(sl.size())setShortMonths(sl);
+ setMoneyFormat(s.currencysymbol(),s.moneydecimals(),s.moneynegative());
+ setNumberFormat(s.decimaldot().value().at(0),s.thousandseparator().value().at(0),s.thousanddigits().value());
+ setAP(s.amtext(),s.pmtext());
+}
+
+
+//static
+void MLocalFormat::setDefaultFormat(const MLocalFormat& f)
+{
+ defaultformat=f;
+}
+
+
+MLocalFormat::MLocalFormat()
+{
+ operator=(defaultformat);
+}
+
+
MLocalFormat::MLocalFormat(const MLocalFormat&f)
{
operator=(f);
//return
return QRegExp(r);
}
+
+qint64 MLocalFormat::localTime2unix(QDateTime ) const
+{
+//TODO!!
+}
+
+void MLocalFormat::setTimeZone(QString olsenname, QList< MOTimeTransition > transitions)
+{
+//TODO!!
+}
+
#include <QStringList>
#include <QRegExp>
+#include "MOServerFormat.h"
+
/**converts special HTML characters into harmless &-codes, so the text can be included*/
QString htmlize(QString str);
class MLocalFormat
{
public:
- /**constructs a formatter object*/
+ /**constructs a formatter object that corresponds to the default*/
MLocalFormat();
/**copies a formatter object inheriting its overrides*/
MLocalFormat(const MLocalFormat&);
+ /**initializes the formatter object from a server format object*/
+ MLocalFormat(const MOServerFormat&);
/**deletes the formatter object*/
virtual ~MLocalFormat();
+ /**sets a new default format*/
+ static void setDefaultFormat(const MLocalFormat&);
+
/**copies a formatter object*/
virtual MLocalFormat& operator=(const MLocalFormat&);
/**overrides the formatting of the AM/PM part of time display, resets to the localization if none given*/
virtual void setAP(QString am="--",QString pm="--");
+ /**overrides the local time zone
+ \param olsenname the name of the local timezone in olsen notation, eg. "Europe/Berlin"
+ \param transitions a list of time transitions, if missing the system attempts to locate the transition DB itself*/
+ virtual void setTimeZone(QString olsenname,QList<MOTimeTransition> transitions=QList<MOTimeTransition>());
+
/**overrides the formatting to be non-localized, numbers use decimal dot and no thousand separator, no currency symbol and "-" as negative sign; otherwise things stay the same; this is a helper for the shortcut methods like cent2str*/
virtual void setNonLocalized();
/**formats a date according to the given format, if none is given, the translation default is used
- \param date a QDate used as input
+ \param date a QDate used as input, it is assumed to be local, even if Qt sais it is UTC
\param format a format string as specified by QDate::toString */
virtual QString formatDate(const QDate&date,QString format=QString())const;
/**formats a date according to the given format, if none is given, the translation default is used
/** \internal helper to convert a unix timestamp to local time*/
virtual QDateTime unix2localTime(qint64)const;
+
+ /** \internal helper to convert a local timestamp to unix time*/
+ virtual qint64 localTime2unix(QDateTime)const;
+
+ /** \internal constructs the default object from the translation*/
+ MLocalFormat(int);
+ /** \internal default format*/
+ static MLocalFormat defaultformat;
};
#endif
<Property name="flag" type="astring"/>
<Property name="description" type="string"/>
</Class>
+
+ <Class name="TimeTransition">
+ <Doc>Helper class: encapsulates a single transition between UTC-offsets for a timezone. This is based on the Olsen TZ database and used by ServerFormat.</Doc>
+ <Property name="ts" type="int64">The Unix timestamp (seconds since Epoch) at which the transition occurs.</Property>
+ <Property name="offset" type="int">Offset in seconds from UTC (positive is east).</Property>
+ <Property name="abbr" type="astring">The abbreviated name of the timezone during this period</Property>
+ <Property name="isdst" type="bool">true if this is a daylight saving time</Property>
+ </Class>
+
+ <Class name="ServerFormat">
+ <Doc>Transport class for server formatting settings. This is used by both UIs to format numbers, dates, money, etc. The XML version of it is stored in the template directory, distributed between main and language dependent directory.</Doc>
+ <Abstract lang="php"/>
+ <Property name="weekdays" type="List:string">The list of week day names, starting with monday</Property>
+ <Property name="shortweekdays" type="List:string">The list of abbreviated week day names, starting with monday</Property>
+ <Property name="months" type="List:string">The list of month names</Property>
+ <Property name="shortmonths" type="List:string">The list of abbreviated month names</Property>
+ <Property name="dateformat" type="astring">The default format for dates, see the docu of MLocalFormat (Qt side) and LanguageManager (PHP side) for details.</Property>
+ <Property name="timeformat" type="astring">The default format for time.</Property>
+ <Property name="datetimeformat" type="astring">The default format for date and time.</Property>
+ <Property name="amtext" type="astring">The text for AM in time stamps</Property>
+ <Property name="pmtext" type="astring">The text for PM in time stamps</Property>
+ <Property name="decimaldot" type="astring">The decimal dot for numbers</Property>
+ <Property name="thousandseparator" type="astring">The thousand separator for numbers, if it is a space the Web UI will actually use &nbsp; to prevent breaking the number.</Property>
+ <Property name="thousanddigits" type="int">The amount of digits between thousand separators, 0 for no thousand separator</Property>
+ <Property name="moneydecimals" type="int">The amount of decimals for money values - this must be the same for all languages on a server, the default is 2</Property>
+ <Property name="currencysymbol" type="astring">The currency used</Property>
+ <Property name="moneynegative" type="astring">One or two characters: for negative money values the first one is placed in front of the money value and the second one behind the money value</Property>
+ <Property name="timezone" type="astring">Olsen database time zone name</Property>
+ <Property name="TZtransitions" type="List:TimeTransition">list of all precalculated transitions in this timezone, how far into the future calculations go depends on the server, usually at the moment till 2037</Property>
+ </Class>
</Wolf>
<Transaction name="GetLanguage" updating="no">
<Doc>This transaction returns basic language and formatting settings from the server - it must be used before the client displays any times or monetary values, even if it does not indend to translate any strings.</Doc>
<Input>
- <Var name="language" type="astring">The language that the client wants to use, use "C" for no translation.</Var>
+ <Var name="language" type="astring">The language that the client wants to use, use "C" for no translation wanted.</Var>
<Var name="format" type="astring">The translation file format that the client supports: either "ts" for Qt translation XML source files, or "qm" for translated binary Qt translation files.</Var>
</Input>
<Call lang="php" method="Translation::getFile($this);"/>
<Output>
<Var name="file" type="blob">The Qt translation file to translate string from the server. All strings are found in the virtual class "::php".</Var>
+ <Var name="formats" type="ServerFormat">The formatting as requested by the server. Please note that the names of days and months does not necessarily correspond to the language that has been request but, to the language that the server wants to set for all printouts.</Var>
</Output>
</Transaction>
private $lang="C";//fallback for unknown language, constructor overrides it
private $config;
private $templateFolder;
+ private $formatcfg;
/** private constructor */
private function __construct()
$this->lang=$l;
break;
}
+ //initialize internal formatting
+ $this->formatcfg=new WOServerFormat($this->lang);
//make sure config manager is initialized
$this->config = ConfigManager::initialize($this->templateFolder()."lang.po");
}
return $this->templateFolder.$this->lang."/";
}
+ /**returns a date in current language formatted to the given format string*/
+ public function formatDate($date,$str)
+ {
+ $ret="";
+ }
+
/** returns date in current language, default: ISO-date */
public function getDate($date)
{
$d=dir($template);
$r=array();
while(false !== ($e=$d->read())){
+ if(!is_dir($template."/".$e))continue;
if(preg_match('/^[a-z]+$/',$e)>0 && $e!="C")
$r[]=$e;
}
{
static public function getFile($trans)
{
- $nlst=explode("_",trim($trans->getlanguage()));
- $form=$trans->getformat();
- if($form!="ts" && $form!="qm")
- $trans->abortWithError(translate("Translation","Format must be either 'ts' or 'qm'."));
+ //split language string into components
+ $nlst=explode("_",trim($trans->getlanguage()));
+ //set format object
+ if(count($nlst)>0)
+ $trans->setformats(new ServerFormat($nlst[0]));
+ else
+ $trans->setformats(new ServerFormat();
+ //if this is "C", abort parsing and return
+ if(strtolower(trim($trans->getlanguage()))=="c")
+ return;
+ //continue to parse language request
+ $form=$trans->getformat();
+ if($form!="ts" && $form!="qm")
+ $trans->abortWithError(translate("Translation","Format must be either 'ts' or 'qm'."));
+ //does the syntax match?
foreach($nlst as $nm)
if(!ereg("^[a-zA-Z]{1,3}$",$nm))
$trans->abortWithError(translate("Translation","Language invalid."));
+ //find the longest match for language
for($i=count($nlst);$i>0;$i--){
$name=implode("_",array_slice($nlst,0,$i));
$fn="translations/_server_".$name.".".$form;
return;
}
}
+ //none found. sadly.
$trans->abortWithError(translate("Translation","Language unknown."));
}
};
'asDate' => new Twig_Filter_Method($this, 'getDate'),
'asTime' => new Twig_Filter_Method($this, 'getTime'),
'asDateTime' => new Twig_Filter_Method($this, 'getDateTime'),
+ 'formatDate' => new Twig_Filter_Method($this, 'formatDate'),
);
}
wob_autoclass("WOPriceCategory","inc/wext/price.php");
wob_autoclass("WORole","inc/wext/role.php");
wob_autoclass("WORoom","inc/wext/room.php");
+wob_autoclass("WOServerFormat","inc/wext/format.php");
wob_autoclass("WOShipping","inc/wext/shipping.php");
wob_autoclass("WOTemplate","inc/wext/template.php");
wob_autoclass("WOTicket","inc/wext/ticket.php");
--- /dev/null
+<?
+// +----------------------------------------------------------------------
+// | PHP Source Format Info Object
+// +----------------------------------------------------------------------
+// | Copyright (C) 2010 by Konrad Rosenbaum <konrad@silmor.de>
+// +----------------------------------------------------------------------
+// |
+// | Copyright: See COPYING.AGPL file that comes with this distribution
+// +----------------------------------------------------------------------
+//
+
+/**this class extends the definition of the Wob class ServerFormat, to actually do something.
+It is used on the other side by the client to configure LocalFormat and by the Web UI to configure LanguageManager.*/
+class WOServerFormat extends WOServerFormatAbstract
+{
+ /**constructs the format object for a specific language*/
+ public function __construct($lang="")
+ {
+ parent::__construct();
+ global $template;
+ $this->loadConfig($template."/format.cfg");
+ if($lang!="")
+ $this->loadConfig($template."/".$lang."/format.cfg");
+ }
+
+ /**load a configuration file and amend internal state by its definitions*/
+ public function loadConfig($file)
+ {
+ //ignore if fiel not found
+ if(!file_exists($file))return;
+ //read file
+ $lines=file($file);
+ foreach($lines as $num=>$ln){
+ //trim line and remove comments
+ $ln=trim($ln);
+ if($ln=="")continue;
+ if(substr($ln,0,1)=="#")continue;
+ //parse
+ $match=array();
+ if(preg_match("/^([a-zA-Z]+) \"(.*)\"$/",$ln,$match)<=0)
+ die("Syntax error in format config $file line ".($num+1));
+ $cmd=strtolower($match[1]);
+ $val=stripcslashes($match[2]);
+ switch($cmd){
+ case "weekdays":$this->setweekdays(explode(" ",$val));break;
+ case "shortweekdays":$this->setshortweekdays(explode(" ",$val));break;
+ case "months":$this->setmonths(explode(" ",$val));break;
+ case "shortmonths":$this->setshortmonths(explode(" ",$val));break;
+ case "date":$this->setdateformat($val);break;
+ case "time":$this->settimeformat($val);break;
+ case "datetime":$this->setdatetimeformat($val);break;
+ case "amtext":$this->setamtext($val);break;
+ case "pmtext":$this->setpmtext($val);break;
+ case "decimaldot":$this->setdecimaldot($val);break;
+ case "thousandseparator":$this->setthousandseparator($val);break;
+ case "thousanddigits":$this->setthousanddigits($val);break;
+ case "moneydecimals":$this->setmoneydecimals($val);break;
+ case "currencysymbol":$this->setcurrencysymbol($val);break;
+ case "moneynegative":$this->setmoneynegative($val);break;
+ case "timezone":$this->settimezone($val);$this->loadtimezone();break;
+ default: die("Unknown keyword in format config $file line ".($num+1));break;
+ }
+ }
+ }
+
+ /** \internal helper for loadConfig to initialize timezone transitions*/
+ protected function loadtimezone()
+ {
+ $dtz=new DateTimeZone($this->prop_timezone);
+ $tr=array();
+ foreach($dtz->getTransitions() as $tran){
+ $t=new WOTimeTransition;
+ $t->setts($tran["ts"]);
+ $t->setoffset($tran["offset"]);
+ $t->setabbr($tran["abbr"]);
+ $t->setisdst($tran["isdst"]);
+ $tr[]=$t;
+ }
+ $this->prop_TZtransitions=$tr;
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+# This is the local Formatting Configuration for the English language
+# it sets new defaults for the properties that are different in English
+#
+# see ../format.cfg for syntax help
+
+#Names of the days of the week, long and abbreviated,
+# start with monday and must be exactly 7 entries long
+WeekDays "Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
+ShortWeekDays "Mon Tue Wed Thu Fri Sat Sun"
+
+#Names of the months, long and abbreviated, the list must be 12 long
+Months "January February March April May June July August September October November December"
+ShortMonths "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
+
+#The format used for the time of day:
+time "%a:%I %P"
+
+#The format used for expressing a date:
+date "%M/%D/%Y"
+
+#The format used when full date and time display is requested,
+datetime "%M/%D/%Y %a:%I %P"
+
+#the text used for AM and PM in time displays that include them
+# use the uppercase version here, lowercase is done automatically
+# by translating all latters to lower case
+AMtext "AM"
+PMtext "PM"
+
+#The characters used for decimal dot and thousand separator on numbers
+#The thousanddigits value tells us how many digits are between separators
+decimaldot "."
+thousandseparator ","
+thousanddigits "3"
--- /dev/null
+# This is the global Formatting Configuration
+# it sets defaults for all formatting properties
+#
+# The files in the language folders only override those
+# properties which are language specific.
+#
+# the syntax is rather simple:
+# empty lines and lines starting with # are ignored;
+# leading and trailing spaces are ignored;
+# all other lines have the format 'keyword "value"';
+# the keyword matching is case insensitive, the case of values is preserved;
+# you see all allowed keywords below;
+# if the parser finds something it cannot interpret it will abort the script and tell you
+
+#Names of the days of the week, long and abbreviated,
+# start with monday and must be exactly 7 entries long
+WeekDays "Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
+ShortWeekDays "Mon Tue Wed Thu Fri Sat Sun"
+
+#Names of the months, long and abbreviated, the list must be 12 long
+Months "January February March April May June July August September October November December"
+ShortMonths "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
+
+#The format used for the time of day:
+# %h hour as simple number (eg. 7) in 24-hour format
+# %H hour as two digit number (eg. 07) in 24-hour format
+# %a hour as simple number (eg. 7) in 12-hour format
+# %A hour as two digit number (eg. 07) in 12-hour format
+# %i minute as simple number (eg. 7)
+# %I minute as two digit number (eg. 07)
+# %s second as simple number (eg. 7)
+# %S second as two digit number (eg. 07)
+# %z milli-seconds as simple number (eg. 7)
+# %Z milli-seconds as three digit number (eg. 007)
+# %p "am" or "pm" according to current time, this is the one set with setAP
+# %P "AM" or "PM" according to current time, this is toUpper executed on the one set with setAP
+# %T ISO timezone as +/-hhmm (eg. -0100 or +0100) - does not work reliably on all systems
+# %% a single % sign
+time "%h:%I"
+
+#The format used for expressing a date:
+# %y two-digit year (eg. 08)
+# %Y four-digit year (eg. 1908)
+# %m month as simple number (eg. 7)
+# %M month as two digit number (eg. 07)
+# %n short name of the month (eg. Jul)
+# %N long name of the month (eg. July)
+# %d day of the month as simple number (eg. 5)
+# %D day of the month as two digit number (eg. 05)
+# %w day of the week as short name (eg. Wed)
+# %W day of the week as long name (eg. Wednesday)
+# %% a single % sign
+date "%Y-%M-%D"
+
+#The format used when full date and time display is requested,
+# see date and time above for the format codes
+datetime "%Y-%M-%D %h:%I"
+
+#the text used for AM and PM in time displays that include them
+# use the uppercase version here, lowercase is done automatically
+# by translating all latters to lower case
+AMtext "AM"
+PMtext "PM"
+
+#The characters used for decimal dot and thousand separator on numbers
+#The thousanddigits value tells us how many digits are between separators
+# if it is 0 or less, no separator is used.
+decimaldot "."
+thousandseparator ","
+thousanddigits "0"
+
+#Currency settings:
+
+# moneydecimals tells us how many digits of money values are cents
+# THIS VALUE MUST NOT BE CHANGED IN SEPARATE LANGUAGES
+# money values are stored as integers in cents, if the number of digits
+# changes the actual monetary value expressed by a stored int value changes!
+moneydecimals "2"
+
+# currencysymbol: the currency used by this server
+# If you change this value in a translation, make sure it still reflects the
+# same currency, otherwise your customers might be surprised if the Web UI shows
+# amounts in US$, but they are billed in Euro.
+currencysymbol "Euro"
+
+# the negative notation of money, it has one or two characters:
+# character 1: the character placed in front of the number, or \n for none
+# character 2: the character placed between number and currency symbol
+moneynegative "-"
+
+#Time Zone in Olsen DB notation
+# THIS VALUE SHOULD NOT BE CHANGED IN LANGUAGE FOLDERS
+# a change of this value directs MagicSmoke to show times for different time zonez
+# this value should be set to the zone where the theater is located
+timezone "Europe/Berlin"