setWeekDays();setShortWeekDays();
setMonths();setShortMonths();
setMoneyFormat();setNumberFormat();
+ setDateTimeFormat();
}
MLocalFormat::MLocalFormat(const MOServerFormat& s)
m_pm=f.m_pm;
m_moneyneg=f.m_moneyneg;
m_timezone=f.m_timezone;
+ m_dateformat=f.m_dateformat;
+ m_timeformat=f.m_timeformat;
+ m_datetimeformat=f.m_datetimeformat;
return *this;
}
if(m.size()==12)
m_smonth=m;
}
+
+void MLocalFormat::setDateTimeFormat(QString dateformat, QString timeformat, QString datetimeformat)
+{
+ if(dateformat=="")m_dateformat=QCoreApplication::translate("MLocalFormat","%Y-%M-%D","date format");
+ else m_dateformat=dateformat;
+ if(timeformat=="")m_timeformat=QCoreApplication::translate("MLocalFormat","%h:%I","time format");
+ else m_timeformat=timeformat;
+ if(datetimeformat=="")m_datetimeformat=QCoreApplication::translate("MLocalFormat","%Y-%M-%D %h:%I","date and time format");
+ else m_datetimeformat=datetimeformat;
+}
+
+
void MLocalFormat::setMoneyFormat(QString c,int n,QString g)
{
m_currency=c;
}
QString MLocalFormat::formatDate(const TimeStamp& date, QString format) const
{
- if(format=="")format=QCoreApplication::translate("MLocalFormat","%Y-%M-%D","date format");
+ if(format=="")format=m_dateformat;
return formatDateTime(date,format);
}
QString MLocalFormat::formatDate(qint64 date,QString format)const
}
QString MLocalFormat::formatTime(const TimeStamp& time, QString format) const
{
- if(format=="")format=QCoreApplication::translate("MLocalFormat","%h:%I","time format");
+ if(format=="")format=m_timeformat;
return formatDateTime(time,format);
}
QString MLocalFormat::formatTime(const QTime&time,QString format)const
}
QString MLocalFormat::formatDateTime(const TimeStamp& ts, QString format) const
{
- if(format=="")format=QCoreApplication::translate("MLocalFormat","%Y-%M-%D %h:%I","date and time format");
+ if(format=="")format=m_datetimeformat;
//parse
TimeStamp time=ts.toZone(m_timezone);
QString out;
}
case 'p':{
int t=time.hour();
- if(t>=1 && t<=12)out+="am";
- else out+="pm";
+ if(t>=1 && t<=12)out+=m_am.toLower();
+ else out+=m_pm.toLower();
break;
}
case 'P':{
int t=time.hour();
- if(t>=1 && t<=12)out+="AM";
- else out+="PM";
+ if(t>=1 && t<=12)out+=m_am;
+ else out+=m_pm;
break;
}
- case 't':out+=time.zoneAbbreviation();break;
+ case 't':
case 'T':{
//get diff from UTC
int d=time.offsetFromUTC()/60;
//west(-) or east(+)?
QString t;
- if(d<0){t="+";d*=-1;}else t="-";
+ if(d<0){t="-";d*=-1;}else t="+";
//hours
QString s=QString::number(d/60);
if(s.size()<2)s="0"+s;
t+=s;
+ //T or t? make a colon?
+ if(format[i].unicode()=='t')t+=":";
//minutes
s=QString::number(d%60);
if(s.size()<2)s="0"+s;
out+=t;
break;
}
- case 'o':out+=m_timezone;break;
+ case 'o':out+=time.zoneAbbreviation();break;
+ case 'O':out+=m_timezone;break;
// % sign
case '%':out+="%";break;
//mistakes
<tr><td>%%Z<td>milli-seconds as three digit number (eg. 007)</tr>
<tr><td>%%p<td>"am" or "pm" according to current time, this is the one set with setAP</tr>
<tr><td>%%P<td>"AM" or "PM" according to current time, this is toUpper executed on the one set with setAP</tr>
-<tr><td>%%T<td>ISO timezone as +/-hhmm (eg. -0100 or +0100) - does not work reliably on all systems</tr>
-<tr><td>%%t<td>timezone as abbreviation - the abbreviation comes from the background time zone DB and is not globally unique (eg. "CET")</tr>
-<tr><td>%%o<td>timezone as Olson name (eg. "Europe/Berlin")</tr>
+<tr><td>%%T<td>ISO timezone as +/-hhmm (eg. -0100 or +0100)</tr>
+<tr><td>%%t<td>ISO timezone as +/-hh:mm (eg. -01:00 or +01:00)</tr>
+<tr><td>%%o<td>timezone as abbreviation - the abbreviation comes from the background time zone DB and is not globally unique (eg. "CET")</tr>
+<tr><td>%%O<td>timezone as Olson name (eg. "Europe/Berlin")</tr>
</table>
Any occurrence of "%%" will be translated to a literal "%" sign.
\param olsenname the name of the local timezone in Olson notation, eg. "Europe/Berlin"*/
virtual void setTimeZone(QString olsonname);
+ /**overrides the default formatting of date and time, if empty the translation default is used*/
+ virtual void setDateTimeFormat(QString dateformat=QString(),QString timeformat=QString(),QString datetimeformat=QString());
+
/**returns the currently set time zone of this formatter*/
virtual QString timeZone()const{return m_timezone;}
/**returns the thousand separator if used, otherwise an empty string*/
QString thousandSeparator()const{if(m_thousanddigits>0)return m_thousand;else return "";}
+ /**returns the amount of digits between thousand separators*/
+ int thousandDigits()const{return m_thousanddigits;}
+
/**returns the amount of decimals in a money value*/
int moneyDecimals()const{return m_moneydecimals;}
QString moneyNegativeSigns()const{return m_moneyneg;}
/**returns a regular expression matching money values
- \param allownegative if given allows to use negative values
- \param allowcurrency if given allows to use the currency symbol */
+ \param allownegative if given the resulting RegExp allows to use negative values
+ \param allowcurrency if given the resulting RegExp allows to use the currency symbol */
QRegExp moneyRegExp(bool allownegative=false,bool allowcurrency=false)const;
+
+ /**returns the default format for dates*/
+ QString dateFormat()const{return m_dateformat;}
+
+ /**returns the default format for times*/
+ QString timeFormat()const{return m_timeformat;}
+
+ /**returns the default format for date/time*/
+ QString dateTimeFormat()const{return m_datetimeformat;}
protected:
QStringList m_day,m_sday,m_month,m_smonth;
- QString m_currency,m_am,m_pm,m_moneyneg,m_timezone;
+ QString m_currency,m_am,m_pm,m_moneyneg,m_timezone,m_dateformat,m_timeformat,m_datetimeformat;
QChar m_decimal,m_thousand;
int m_moneydecimals,m_thousanddigits;
HEADERS += \
misc/debug.h \
misc/misc.h \
- misc/waitcursor.h
+ misc/waitcursor.h \
+ misc/sclock.h
SOURCES += \
misc/code39.cpp \
misc/debug.cpp \
misc/misc.cpp \
- misc/waitcursor.cpp
+ misc/waitcursor.cpp \
+ misc/sclock.cpp
INCLUDEPATH += ./misc
\ No newline at end of file
--- /dev/null
+//
+// C++ Implementation: overview
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "sclock.h"
+
+#include <QActionGroup>
+#include <QDebug>
+#include <QDialog>
+#include <QFormLayout>
+#include <QMenu>
+#include <QMessageBox>
+#include <QMouseEvent>
+#include <QPushButton>
+#include <QTimer>
+#include <QBoxLayout>
+
+#include "tzdata.h"
+#include "misc.h"
+
+MServerClock::MServerClock()
+{
+ QTimer *tm=new QTimer(this);
+ tm->setSingleShot(false);
+ tm->start(1000);
+ connect(tm,SIGNAL(timeout()),this,SLOT(updateClock()));
+
+ connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
+ setContextMenuPolicy(Qt::CustomContextMenu);
+ setFrameStyle(QFrame::Panel|QFrame::Sunken);
+
+ contextmenu=new QMenu(this);
+ contextmenu->addAction(tr("Show Format Info"),this,SLOT(showInfo()));
+ contextmenu->addSeparator();
+ QActionGroup*ag=new QActionGroup(this);
+ QAction*ac=ag->addAction(tr("Show Full Time"));
+ ac->setCheckable(true);ac->setChecked(true);
+ ac->setData(tr("%W, %D %N %Y %a:%I %p %t","full time format"));
+ contextmenu->addAction(ac);showfull=ac;
+ ac=ag->addAction(tr("Show Date Only"));ac->setCheckable(true);
+ ac->setData(tr("%w, %M/%D/%Y","date only format"));
+ contextmenu->addAction(ac);showdate=ac;
+ ac=ag->addAction(tr("Show Time Only"));ac->setCheckable(true);
+ ac->setData(tr("%a:%I %p %t","time only format"));
+ contextmenu->addAction(ac);showtime=ac;
+ ac=ag->addAction(tr("Show Short Date/Time"));ac->setCheckable(true);
+ ac->setData(tr("%w %Y-%M-%D %h:%I %t","ISO like short time format"));
+ contextmenu->addAction(ac);showiso=ac;
+ connect(ag,SIGNAL(triggered(QAction*)),this,SLOT(updateClock()));
+
+ updateClock();
+}
+
+void MServerClock::updateClock()
+{
+ //get time and format
+ TimeStamp ts=TimeStamp::now();
+ QString fm=showfull->data().toString();
+ if(showdate->isChecked())fm=showdate->data().toString();
+ if(showtime->isChecked())fm=showtime->data().toString();
+ if(showiso->isChecked())fm=showiso->data().toString();
+ //set it
+ setText(MLocalFormat().formatDateTime(ts,fm));
+ //make sure tool tip is up to date
+ int off=ts.offsetFromUTC()/60;
+ QString tz=tr("Server Time Zone: %1\nOffset from UTC: %2 minutes %3")
+ .arg(MLocalFormat().timeZone())
+ .arg(off<0?-off:off)
+ .arg(off>=0?tr("east","positive time zone offset"):tr("west","negative time zone offset"));
+ if(toolTip()!=tz)setToolTip(tz);
+}
+
+void MServerClock::mouseDoubleClickEvent(QMouseEvent* event)
+{
+ QWidget::mouseDoubleClickEvent(event);
+ if(event->button()!=Qt::LeftButton)return;
+ showInfo();
+}
+
+static inline QString list2str(const QStringList&l)
+{
+ QString ret,r;
+ for(int i=0;i<l.size();i++){
+ if(i)r+=", ";
+ r+="'"+l[i]+"'";
+ if(r.size()>=30){
+ ret+=r+"\n";
+ r="";
+ }
+ }
+ ret+=r;
+ return ret.trimmed();
+}
+
+void MServerClock::showInfo()
+{
+ QDialog d(this);
+ d.setWindowTitle(tr("Server Format Info"));
+ QVBoxLayout*vl;
+ QFormLayout*fl;
+ QHBoxLayout*hl;
+ d.setLayout(vl=new QVBoxLayout);
+ vl->addLayout(fl=new QFormLayout,10);
+ fl->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
+ MLocalFormat lf;
+ fl->addRow(new QLabel(tr("Number Format:")));
+ fl->addRow(tr("Decimal Dot:"),new QLabel(lf.decimalDot()));
+ fl->addRow(tr("Separator:"),new QLabel(tr("'%1' every %2 digits").arg(lf.thousandSeparator()).arg(lf.thousandDigits())));
+
+ fl->addRow(new QLabel);
+ fl->addRow(new QLabel(tr("Currency Settings:")));
+ fl->addRow(tr("Currency Symbol:"),new QLabel(lf.currency()));
+ fl->addRow(tr("Division Digits:"),new QLabel(QString::number(lf.moneyDecimals())));
+ fl->addRow(tr("Negative Sign:"),new QLabel(lf.moneyNegativeSigns()));
+ fl->addRow(tr("Example:"),new QLabel(lf.formatMoney(-1234567890)));
+
+ fl->addRow(new QLabel);
+ fl->addRow(new QLabel(tr("Date and Time Settings:")));
+ fl->addRow(tr("Day of the Week:"),new QLabel(list2str(lf.weekDayNames())));
+ fl->addRow(tr("Day of the Week Abbreviated:"),new QLabel(list2str(lf.shortWeekDayNames())));
+ fl->addRow(tr("Month Names:"),new QLabel(list2str(lf.monthNames())));
+ fl->addRow(tr("Month Names Abbreviated:"),new QLabel(list2str(lf.shortMonthNames())));
+ fl->addRow(tr("Date Format:"),new QLabel(lf.dateFormat()));
+ fl->addRow(tr("Time Format:"),new QLabel(lf.timeFormat()));
+ fl->addRow(tr("Date and Time Format:"),new QLabel(lf.dateTimeFormat()));
+ MLocalFormat lfs;lfs.setTimeZone(TimeStamp::systemLocalZone());
+ TimeStamp now=TimeStamp::now();
+ fl->addRow(tr("System Time Zone:"),new QLabel(lfs.timeZone()));
+ fl->addRow(tr("Current Local Time:"),new QLabel(lfs.formatDateTime(now)));
+ fl->addRow(tr("Theater/Server Time Zone:"),new QLabel(lf.timeZone()));
+ fl->addRow(tr("Current Theater/Server Time:"),new QLabel(lf.formatDateTime(now)));
+
+ vl->addLayout(hl=new QHBoxLayout,0);
+ hl->addStretch(10);
+ QPushButton*p;
+ hl->addWidget(p=new QPushButton(tr("Close")));
+ p->setDefault(true);
+ connect(p,SIGNAL(clicked()),&d,SLOT(close()));
+
+ d.exec();
+}
+
+void MServerClock::contextMenu(const QPoint& p)
+{
+ contextmenu->popup(mapToGlobal(p));
+}
--- /dev/null
+//
+// C++ Interface: overview
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007-2010
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_SCLOCK_H
+#define MAGICSMOKE_SCLOCK_H
+
+#include <QLabel>
+
+
+class QMenu;
+class QAction;
+
+
+class MServerClock:public QLabel
+{
+ Q_OBJECT
+ public:
+ MServerClock();
+ private slots:
+ void updateClock();
+ void contextMenu(const QPoint&);
+ void showInfo();
+ protected:
+ virtual void mouseDoubleClickEvent ( QMouseEvent * event );
+ private:
+ QMenu*contextmenu;
+ QAction*showfull,*showtime,*showdate,*showiso;
+};
+
+#endif
#include "overview.h"
#include "centbox.h"
+#include "sclock.h"
#include "tzdata.h"
#include <QBoxLayout>
mb->addMenu(MApplication::helpMenu());
//status bar
- statusBar()->setSizeGripEnabled(true);
+ QStatusBar *sb=statusBar();
+ sb->setSizeGripEnabled(true);
+ sb->addPermanentWidget(new MServerClock);
//unused tab disabling...
if(!req->hasRight(req->RGetAllEvents)){
// Description:
//
//
-// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007-2010
//
// Copyright: See README/COPYING files that come with this distribution
//
private $config;
private $templateFolder;
private $formatcfg;
+ private $timezone;
/** private constructor */
private function __construct()
}
//initialize internal formatting
$this->formatcfg=new WOServerFormat($this->lang);
+ $this->timezone=new DateTimeZone($this->formatcfg->gettimezone());
//make sure config manager is initialized
$this->config = ConfigManager::initialize($this->templateFolder()."lang.po");
}
return $this->templateFolder.$this->lang."/";
}
+ /**returns the configured language template folder plus its fallback*/
+ public function templateFolders()
+ {
+ $ret=array();
+ $ret[]=realpath($this->templateFolder());
+ $ret[]=realpath($this->templateFolder."C/");
+ return $ret;
+ }
+
/**returns a date in current language formatted to the given format string*/
- public function formatDate($date,$str)
+ public function formatDate($date,$format)
{
- $ret="";
+ $out="";
+ //parse
+ $time=new DateTime;
+ $time->setTimestamp($date+0);
+ $time->setTimeZone($this->timezone);
+ $inp=false;
+ for($i=0;$i<strlen($format);$i++){
+ if($inp){
+ //IMPORTANT NOTICE:
+ //if you change or extend any of the below please
+ //also change the corresponding code in the client
+ //class MLocalFormat method formatDateTime
+ switch($format[$i]){
+ //date format codes
+ case 'Y':
+ case 'y':
+ $out.=$time->format($format[$i]);
+ break;
+ case 'm':$out.=$time->format('n');break;
+ case 'M':$out.=$time->format('m');break;
+ case 'n':
+ $ma=$this->formatcfg->getshortmonths();
+ $out.=$ma[$time->format('n')-1];
+ break;
+ case 'N':
+ $ma=$this->formatcfg->getmonths();
+ $out.=$ma[$time->format('n')-1];
+ break;
+ case 'd':$out.=$time->format('j');break;
+ case 'D':$out.=$time->format('d');break;
+ case 'w':
+ $wd=($time->format('N')+0)%7;
+ $wa=$this->formatcfg->getshortweekdays();
+ $out.=$wa[$wd];
+ break;
+ case 'W':
+ $wd=($time->format('N')+0)%7;
+ $wa=$this->formatcfg->getweekdays();
+ $out.=$wa[$wd];
+ break;
+ //time formats
+ case 'h':$out.=$time->format('G');break;
+ case 'H':$out.=$time->format('H');break;
+ case 'a':$out.=$time->format('g');break;
+ case 'A':$out.=$time->format('h');break;
+ case 'i':$out.=$time->format('i')+0;break;
+ case 'I':$out.=$time->format('i');break;
+ case 's':$out.=$time->format('s')+0;break;
+ case 'S':$out.=$time->format('s');break;
+ case 'z':
+ $out.=floor($time->format('u')/1000);
+ break;
+ case 'Z':
+ $ms=floor($time->format('u')/1000)."";
+ while(strlen($ms)<3)$ms="0".$ms;
+ $out.=$ms;
+ break;
+ case 'p':
+ $t=$time->format('G')+0;
+ if($t>=1 && $t<=12)$out.=strtolower($this->formatcfg->getamtext());
+ else $out.=strtolower($this->formatcfg->getpmtext());
+ break;
+ case 'P':
+ $t=$time->format('G')+0;
+ if($t>=1 && $t<=12)$out.=$this->formatcfg->getamtext();
+ else $out.=$this->formatcfg->getpmtext();
+ break;
+ case 't':
+ case 'T':
+ //get diff from UTC
+ $d=floor($time->getOffset()/60);
+ //west(-) or east(+)?
+ if($d<0){$t="-";$d=-$d;}else $t="+";
+ //hours
+ $s=floor($d/60)."";
+ if(strlen($s)<2)$s="0".$s;
+ $t+=$s;
+ //T or t? make a colon?
+ if($format[$i]=='t')$t.=":";
+ //minutes
+ $s=($d%60)."";
+ if(strlen($s)<2)$s="0".$s;
+ $t.=$s;
+ //append
+ $out.=$t;
+ break;
+ case 'o':$out.=$time->format('T');break;
+ case 'O':$out.=$this->formatcfg->gettimezone();break;
+ // % sign
+ case '%':$out.="%";break;
+ //mistakes
+ default:$out.="%".$format[$i];break;
+ }
+ $inp=false;
+ }else{
+ if($format[$i]=='%')$inp=true;
+ else $out.=$format[$i];
+ }
+ }
+ //catch mistaken % at end
+ if($inp)$out.="%";
+ //return result
+ return $out;
}
/** returns date in current language, default: ISO-date */
public function getDate($date)
{
- return date(i18n("Y-m-d"), $date);
+ return $this->formatDate($date,$this->formatcfg->getdateformat());
}
/** returns date in current language, default: ISO-date */
public function getDateTime($date)
{
- return date(i18n("Y-m-d h:i a"), $date);
+ return $this->formatDate($date,$this->formatcfg->getdatetimeformat());
}
/** returns time in current language */
public function getTime($time)
{
- return date(i18n("h:i a"), $time);
+ return $this->formatDate($time,$this->formatcfg->gettimeformat());
}
/** returns price in current language */
Session::setWebSession();
//initialize TWIG
-$loader = new Twig_Loader_Filesystem(LanguageManager::singleton()->templateFolder());
+$loader = new Twig_Loader_Filesystem(LanguageManager::singleton()->templateFolders());
$twig = new Twig_Environment($loader, $twigoptions );
foreach($twigextensions as $te){
$t='Twig_Extension_'.$te;
}
}catch(Exception $ex){
error_log($ex->getMessage());
- $p=$twig->loadTemplate("error.html");
+ try{
+ $p=$twig->loadTemplate("error.html");
+ }catch(Exception $ex2){
+ $twig->setLoader(new Twig_Loader_String);
+ $p=$twig->loadTemplate("<font color=\"red\">{{ErrorText}}</font><p/><pre>\n{{ErrorTrace}}\n</pre>");
+ }
$e=$basevars;
- if($WebShowErrors)
+ if($WebShowErrors){
$e["ErrorText"]=$ex->getMessage();
- else
+ $e["ErrorTrace"]=$ex->getTraceAsString();
+ }else
$e["ErrorText"]=translate("WebSite","An error occured, contact the server admin for details.");
$page=$p->render($e);
}
--- /dev/null
+# This is the local Formatting Configuration for the German language
+# it sets new defaults for the properties that are different in German
+#
+# see ../format.cfg for syntax help
+
+# Dies ist die deutsche Formatierungs-Konfiguration.
+# siehe ../format.cfg für syntaktische Erklärungen
+
+WeekDays "Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag"
+ShortWeekDays "So Mo Di Mi Do Fr Sa"
+
+Months "Januar Februar März April Mai Juni Juli August September Oktober November Dezember"
+ShortMonths "Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez"
+
+#The format used for the time of day:
+time "%h:%I"
+
+#The format used for expressing a date:
+date "%D.%M.%Y"
+
+#The format used when full date and time display is requested,
+datetime "%D.%M.%Y %h:%I"
+
+decimaldot ","
+thousandseparator " "
+thousanddigits "3"
<body>
<h1>Error</h1>
-{{ErrorText}}
+{{ErrorText}}<p/>
+
+{# have the following only in development mode!
+It prints a full stack trace, which you probably do not want in production. #}
+<pre>
+{{ErrorTrace}}
+</pre>
<hr/>
<a href="{{script.root}}">Back to Index</a>
#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"
+WeekDays "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
+ShortWeekDays "Sun Mon Tue Wed Thu Fri Sat"
#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"
# 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"
+# start with sunday and must be exactly 7 entries long
+WeekDays "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
+ShortWeekDays "Sun Mon Tue Wed Thu Fri Sat"
#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"