Resurrect etimedate:

- Redesigned Calendar widget, many new options
- Killed a lot of code by porting to edelib::Date (timezone handling is still 
internal)
- Added syncing with time servers using ntpdate
This commit is contained in:
Vedran Ljubovic 2007-09-05 19:51:01 +00:00
parent 0c606e2676
commit 06b7079100
14 changed files with 1104 additions and 2505 deletions

View File

@ -23,3 +23,4 @@ SubInclude TOP eimage ;
SubInclude TOP datas ;
SubInclude TOP docs ;
SubInclude TOP efiler ;
SubInclude TOP etimedate ;

View File

@ -1,155 +0,0 @@
/*
* Date_Time class for FLTK
* Copyright (C) Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
* WWW: http://www.sourceforge.net/projects/ede
*
* This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
* version 2. See COPYING for details.
*
*/
#ifndef _DATE_TIME_H_
#define _DATE_TIME_H_
class DateTime;
/** \class Timezone
This class enables various manipulations of timezones needed for the DateTime class.
*/
class Timezone {
public:
/** \fn Timezone::Timezone()
Creates a variable that contains UTC (Coordinated Universal Time)
*/
TimeZone ();
/** \fn char* Timezone::place()
Returns location of current timezone e.g. Europe/Sarajevo
*/
char* place();
/** \fn void Timezone::parse(char*)
Parse given string into timezone. String can be place as returned by place() or a part of it.
*/
void parse(char*);
/** \fn int Timezone::correction(DateTime*)
Correction i.e. the number of minutes that needs to be added to UTC to get the current time zone. Because of daylight saving, this number can be different during the year - so DateTime needs to be specified. From this number a RFC822-compliant correction can be calculated - e.g. 180 means "+0300".
*/
int correction(DateTime*);
/** \fn static char** Timezone::list()
A useful function to return a list of timezone names as used by place() and parse().
*/
static char** list();
}
/** \class DateTime
DateTime
*/
class DateTime {
public:
/** \fn DateTime::DateTime()
Creates DateTime at January 1st, year 0, 00:00:00
*/
DateTime ();
/** \fn DateTime::DateTime(double)
Creates DateTime with given time_t value (as returned by time())
*/
DateTime (double);
int year();
int month();
int day();
int hour();
int minute();
int second();
bool year(int);
bool month(int);
bool day(int);
bool hour(int);
bool minute(int);
bool second(int);
static char dateInputFormat[32];
static char timeInputFormat[32];
static char dateFormat[32];
static char timeFormat[32];
static char datePartsOrder[4];
static char dateSeparator;
static char timeSeparator;
static bool time24Mode;
Fl_Date_Time (short y,short m,short d,short hour=0,short minute=0,short second=0);
Fl_Date_Time (const char * dat);
Fl_Date_Time (const Fl_Date_Time &dt);
Fl_Date_Time (const double dt=0);
static Fl_Date_Time convert (const long);
void format_date(char *str) const;
void format_time(char *str, bool ampm=true) const;
// These functions don't affect the actual system time.
// You can only alter the time for the current program.
static void Now(Fl_Date_Time dt); // Sets to current date and time
static Fl_Date_Time System(); // Gets to current system date and time
static Fl_Date_Time Now(); // Gets to current date and time
static Fl_Date_Time Date(); // Gets to current date
static Fl_Date_Time Time(); // Gets to current time
short days_in_month() const; // Number of days in month (1..31)
short day_of_week() const; // (1..7)
short day_of_year() const; // returns relative date since Jan. 1
char* day_name() const; // Character Day Of Week ('Sunday'..'Saturday')
char* month_name() const; // Character Month name
unsigned date() const; // Numeric date of date object
short day() const; // Numeric day of date object
short month() const; // Month number (1..12)
short year() const;
char* date_string() const;
char* time_string() const;
void decode_date(short *y,short *m,short *d) const;
void decode_time(short *h,short *m,short *s,short *ms) const;
operator double (void) const;
void operator = (const Fl_Date_Time& date);
void operator = (const char * dat);
Fl_Date_Time operator + (int i);
Fl_Date_Time operator - (int i);
Fl_Date_Time operator + (Fl_Date_Time& dt);
Fl_Date_Time operator - (Fl_Date_Time& dt);
Fl_Date_Time& operator += (int i);
Fl_Date_Time& operator -= (int i);
Fl_Date_Time& operator += (Fl_Date_Time& dt);
Fl_Date_Time& operator -= (Fl_Date_Time& dt);
Fl_Date_Time& operator ++ (); // Prefix increment
Fl_Date_Time& operator ++ (int); // Postfix increment
Fl_Date_Time& operator -- (); // Prefix decrement
Fl_Date_Time& operator -- (int); // Postfix decrement
protected:
double m_dateTime;
};
// Date comparison
static inline bool operator < (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 < (double)dt2 ); }
static inline bool operator <= (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 <= (double)dt2 ); }
static inline bool operator > (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 > (double)dt2 ); }
static inline bool operator >= (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 >= (double)dt2 ); }
static inline bool operator == (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 == (double)dt2 ); }
static inline bool operator != (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 != (double)dt2 ); }
#endif

View File

@ -1,471 +1,459 @@
/***************************************************************************
Fl_Calendar.cpp - description
-------------------
begin : Sun Aug 18 2002
copyright : (C) 2002 by Alexey Parshin
email : alexeyp@m7.tts-sf.com
***************************************************************************/
/*
* $Id$
*
* Application for setting system date, time and local timezone
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
// This is the Calendar widget class inspired by the Calendar originally
// developed by Alexey Parshin for SPTK and later imported into efltk.
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
//
// Ported to FLTK2 by Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
#include "EDE_Calendar.h"
// For NLS stuff
//#include "../core/fl_internal.h"
#include <string.h>
#include <stdlib.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <edelib/Nls.h>
#include <stdio.h>
#include <fltk/events.h>
#include <fltk/Rectangle.h>
#include <fltk/draw.h>
#include <fltk/events.h>
#include "../edelib2/NLS.h"
using namespace fltk;
#include <stdlib.h>
#include <string.h>
// FIXME: dont do static
static EDE_Calendar* thecalendar;
// TODO: replace this with a simple loop when operator++ is implemented in edelib::Date
long date_distance(edelib::Date da1, edelib::Date da2) {
if (da1 > da2) {
edelib::Date tmp = da2;
da2=da1;
da1=tmp;
}
int d1=da1.day(), m1=da1.month(), y1=da1.year(), d2=da2.day(), m2=da2.month(), y2=da2.year();
long result=0;
while (d1!=d2 || m1!=m2 || y1!=y2) {
result++;
d1++;
if (!da1.is_valid(y1,m1,d1)) {
d1=1;
m1++;
if (m1>12) {
m1=1;
y1++;
}
}
}
return result;
}
// Constants
static const char *weekDayLabels[7] = {
"Su","Mo","Tu","We","Th","Fr","Sa"
};
static const char *monthDayLabels[31] = {
"1","2","3","4","5","6","7","8","9","10",
"11","12","13","14","15","16","17","18","19","20",
"21","22","23","24","25","26","27","28","29","30",
"31"
};
static const char *switchLabels[4] = {
"@-1<<","@-1<","@-1>","@-1>>"
"@-1<<","@-1<","@-1>","@-1>>"
};
static const int monthChanges[4] = {
-12,-1,1,12
-12,-1,1,12
};
// TODO: read this from locale
const bool weekStartsOnMonday = false;
// Callback function for day buttons
void EDE_Calendar::cbDayButtonClicked(Widget *button, void *param) {
if (event_clicks() == 1 || event_key() == ReturnKey) {
// NOTE: this used to read:
// button->parent->dayButtonChanged...
// but it didn't work! FIXME
thecalendar->dayButtonChanged((unsigned)param);
} else {
thecalendar->dayButtonClicked((unsigned)param);
// Callback function for fwd / back buttons
void EDE_Calendar::cbSwitchButtonClicked(Fl_Widget *button, long month_change) {
EDE_Calendar* thecalendar = (EDE_Calendar*)button->parent();
edelib::Date d = thecalendar->active_date();
int year = d.year();
int month = d.month()+month_change;
int day = d.day();
// Fix month
while (month<1) { year--; month+=12; }
while (month>12) { year++; month-=12; }
// Switch to closest valid day
while (day>27 && !d.is_valid(year, month, day)) day--;
if (d.is_valid(year, month, day)) {
d.set(year, month, day);
thecalendar->active_date(d);
}
}
// Callback function for switch buttons
void EDE_Calendar::cbSwitchButtonClicked(Widget *button, void *param) {
thecalendar->switchButtonClicked((int)param);
}
// Real callback functions:
void EDE_Calendar::dayButtonClicked(unsigned cday) {
if (cday < 1 || cday > 31) return;
short year, month, day;
m_activeDate.decode_date(&year,&month,&day);
Fl_Date_Time::encode_date((double&)m_activeDate,year,month,cday);
redraw();
// do_callback(); // callback only on changing "today" date
}
void EDE_Calendar::dayButtonChanged(unsigned cday) {
if (cday < 1 || cday > 31) return;
short year, month, day;
m_todayDate.decode_date(&year,&month,&day);
m_activeDate.decode_date(&year,&month,&day);
Fl_Date_Time::encode_date((double&)m_todayDate,year,month,cday);
redraw();
do_callback();
}
void EDE_Calendar::switchButtonClicked(int monthChange) {
short year, month, day;
m_activeDate.decode_date(&year,&month,&day);
month += monthChange;
if (month < 1) {
month += 12;
year--;
}
if (month > 12) {
month -= 12;
year++;
}
// Fl_Date_Time newDate(year,month,day);
// date(newDate);
Fl_Date_Time::encode_date((double&)m_activeDate,year,month,day);
redraw();
// do_callback();
}
// This is stuff for NamedStyle - still needed?
static void revert(Style* s) {
s->color_ = GRAY75;
s->buttoncolor_ = GRAY75;
s->box_ = FLAT_BOX;
s->buttonbox_ = THIN_UP_BOX;
s->textfont_ = HELVETICA_BOLD;
}
static NamedStyle style("Calendar", revert, &EDE_Calendar::default_style);
NamedStyle* EDE_Calendar::default_style = &::style;
// Constructor
// ctor
EDE_Calendar::EDE_Calendar(int x,int y,int w,int h,const char *lbl)
: Group(2,2,w-2,h-2,lbl) {
thecalendar = this;
m_globalx = x; m_globaly = y;
style(default_style);
unsigned i;
// Header box
m_headerBox = new Group(x,y,w,32);
m_monthNameBox = new InvisibleBox(x,y,w,16);
m_monthNameBox->box(NO_BOX);
: Fl_Group(x,y,w,h,lbl) {
unsigned int i;
// Calendar contents, correct size and position is set by layout()
// Header box
m_monthNameBox = new Fl_Box(x,y,w,16);
m_monthNameBox->box(FL_NO_BOX);
// Weekday headers
for (i = 0; i < 7; i++) {
m_dayNameBoxes[i] = new Fl_Box(x+i*16,y+16,16,16);
m_dayNameBoxes[i]->box(FL_FLAT_BOX);
m_dayNameBoxes[i]->color(fl_color_average(color(), FL_GREEN, 0.8));
// get first two letters of day name
edelib::Date d;
d.set(1900,1,7+i); // 1.1.1900 was Monday
char tmp[3];
snprintf(tmp,3,"%s", d.day_name());
m_dayNameBoxes[i]->copy_label(tmp);
}
// Fillers (parts of calendar without day buttons)
for (int i=0; i<3; i++) {
m_filler[i] = new Fl_Box(x,y,16,16);
m_filler[i]->box(FL_FLAT_BOX);
m_filler[i]->color(fl_color_average(color(), FL_BLACK, 0.95)); // very mild grayish
}
// NLS stuff - FIXME this can't work because gettext needs literals inside _()
for (i=0; i<7;i++) weekDayLabels[i]=_(weekDayLabels[i]);
// Weekday headers
for (i = 0; i < 7; i++) {
m_dayNameBoxes[i] = new InvisibleBox(x+i*16,y+16,16,16,weekDayLabels[i]);
}
m_headerBox->end();
// Day buttons, correct positions are set by resize()
m_buttonBox = new Group(x,y+32,w,64);
m_buttonBox->box(FLAT_BOX);
for (i = 0; i < 31; i++) {
Button *btn = new Button(0,0,16,16,monthDayLabels[i]);
m_dayButtons[i] = btn;
btn->callback(EDE_Calendar::cbDayButtonClicked, (void *)(i+1));
}
m_buttonBox->end();
// Switch buttons, correct positions are set by resize()
for (i = 0; i < 4; i++) {
m_switchButtons[i] = new Button(x,y,16,16,switchLabels[i]);
m_switchButtons[i]->callback(EDE_Calendar::cbSwitchButtonClicked, (void *)monthChanges[i]);
m_switchButtons[i]->labeltype(SYMBOL_LABEL);
}
end();
date(Fl_Date_Time::Now());
}
/*
// New style ctor
Fl_Calendar::Fl_Calendar(const char* l,int layout_size,Align layout_al,int label_w)
: Group (l,layout_size,layout_al,label_w)
{
ctor_init(0,0,w(),h());
}*/
void EDE_Calendar::layout() {
int xx = m_globalx, yy = m_globaly; // in FLTK2 positions are absolute, not relative
int ww = w(), hh = h();
Rectangle* rect = new Rectangle(xx,yy,ww,hh);
box()->inset(*rect);
unsigned i;
// one daybox = boxh*boxw is unit of size
int boxh = hh / 10;
int boxw = ww / 7;
// rounding dimensions to a whole number of boxes
ww = boxw * 7;
hh = hh / boxh * boxh; // why not boxh * 10 ?
// center horizontally inside this space
xx = xx + (w()-ww)/2+1;
// if(xx<box()->dx()) xx=box()->dx(); //TODO: dx() is no longer available
// resize header
m_headerBox->resize(xx, yy, ww, boxh*2+2);
m_monthNameBox->resize(xx, yy, ww, boxh); // month name is actually larger
// resize column titles (Su, Mo, Tu...)
for (i=0; i < 7; i++) {
m_dayNameBoxes[i]->resize(boxw*i + xx, boxh + yy+2, boxw, boxh); // why +2 ?
}
// compute the month start date
short year, month, day;
if ((double)m_todayDate < 1) m_todayDate = Fl_Date_Time::Now();
if ((double)m_activeDate < 1) m_activeDate = m_todayDate;
m_activeDate.decode_date(&year,&month,&day);
Fl_Date_Time monthDate(year,month,1);
// create month name label
char yearstr[4];
snprintf(yearstr,4,"%d",year);
strncpy(m_headerLabel, monthDate.month_name(), 13);
strcat(m_headerLabel, ", ");
strcat(m_headerLabel, yearstr);
m_monthNameBox->label(m_headerLabel);
// resize day buttons
int topOffset = boxh*2 + yy+2;
m_buttonBox->resize(xx, topOffset, boxw*7, boxh*6); // background
int dayOffset = monthDate.day_of_week()-1;
int daysInMonth = monthDate.days_in_month();
for (i = 0; i < 31; i++) {
Button *btn = m_dayButtons[i];
btn->resize(dayOffset*boxw + xx, topOffset, boxw, boxh); // 32 = header; bh = daynameboxes
if ((int)i < daysInMonth) {
dayOffset++;
if (dayOffset > 6) {
dayOffset = 0;
topOffset += boxh;
}
btn->show();
}
else btn->hide();
}
int sby = m_buttonBox->y() + m_buttonBox->h();
for (i = 0; i < 2; i++)
m_switchButtons[i]->resize(i*boxw + xx, sby, boxw, boxh);
int x1 = ww - boxw * 2;
for (i = 2; i < 4; i++) {
m_switchButtons[i]->resize((i-2)*boxw + x1 + xx, sby, boxw, boxh);
}
//Clear layout flags
Widget::layout();
}
void EDE_Calendar::draw() {
// Note - Fl_Calendar has fixed colors because themes could make it ugly or unreadable
// TODO: Improve this!
// Color btn_color = color_average(buttoncolor(), WHITE, .4f);
//Color btn_color_hl = color_average(buttoncolor(), GRAY75, .5f);
//Color btn_color = lerp(buttoncolor(), WHITE, .4f);
Color btn_color = fltk::color(255,255,204); // light yellowish grey a la paper - don't remove fltk:: !
Color btn_color_hl = WHITE;
Color label_color = BLACK;
Color day_color = lerp(BLUE, GRAY85, .8f);
Color day_color_wknd = lerp(BLUE, WHITE, .9f); // light reddish gray
unsigned i;
short year, month, day;
m_activeDate.decode_date(&year,&month,&day);
short activeindex = day-1;
short tyear, tmonth, tday;
m_todayDate.decode_date(&tyear,&tmonth,&tday);
short todayindex = tday-1;
if (tyear != year || tmonth != month) todayindex=-1;
for (i = 0; i < 31; i++) {
Button *btn = m_dayButtons[i];
btn->box(THIN_UP_BOX);
//btn->focusbox(DOTTED_FRAME);
btn->color(btn_color);
// btn->highlight_color(btn_color_hov);
btn->labelfont(labelfont());
btn->labelcolor(label_color);
btn->labelsize(labelsize());
if((int)i==activeindex) {
btn->box(FLAT_BOX);
btn->color(btn_color_hl);
}
if((int)i==todayindex) {
//btn->box(BORDER_FRAME);
// TODO: why is this rectangle drawn behind button?
// setcolor((Color)RED);
// drawline(btn->x(),btn->y(),btn->x(),btn->y()+btn->h());
// drawline(btn->x(),btn->y()+btn->h(),btn->x()+btn->w(),btn->y()+btn->h());
// drawline(btn->x()+btn->w(),btn->y()+btn->h(),btn->x()+btn->w(),btn->y());
// drawline(btn->x()+btn->w(),btn->y(),btn->x(),btn->y());
btn->focusbox(BORDER_FRAME);
// How do I make a red frame? apparently not possible
// btn->textcolor(RED);
focus(btn);
}
}
for (i = 0; i < 4; i++) {
m_switchButtons[i]->box(FLAT_BOX);
m_switchButtons[i]->color(WHITE);
m_switchButtons[i]->labelcolor(BLACK);
m_switchButtons[i]->highlight_color(GRAY75);
m_switchButtons[i]->labelsize(labelsize());
}
for (i=0; i < 7; i++) {
m_dayNameBoxes[i]->box(buttonbox());
m_dayNameBoxes[i]->color(day_color);
m_dayNameBoxes[i]->labelcolor(label_color);
m_dayNameBoxes[i]->labelsize(labelsize());
if(i==0 || i==6)
m_dayNameBoxes[i]->color(day_color_wknd);
// m_dayNameBoxes[i]->labelcolor(RED);
}
m_monthNameBox->labelfont(textfont());
m_monthNameBox->labelsize(textsize());
m_monthNameBox->labelcolor(textcolor());
// m_buttonBox->color(darker(buttoncolor()));
m_buttonBox->color(lerp(buttoncolor(),BLACK,.67f));
Group::draw();
}
void EDE_Calendar::measure(int& ww,int& hh) const {
ww = (w() / 7) * 7;
hh = (h() / 10) * 10;
}
void EDE_Calendar::date(Fl_Date_Time dt) {
m_todayDate = dt;
m_activeDate = dt;
short year, month, day;
m_todayDate.decode_date(&year,&month,&day);
focus(m_dayButtons[day-1]);
relayout();
redraw();
}
Fl_Date_Time EDE_Calendar::date() const {
short year, month, day;
m_todayDate.decode_date(&year,&month,&day);
return Fl_Date_Time(year, month, day);
}
//------------------------------------------------------------------------------------------------------
/* Fl_Popup_Calendar - we lack Fl_Popup_Window to make this work... maybe later
static void popup_revert(Style* s)
{
s->color = GRAY75;
s->buttoncolor = GRAY75;
s->box = BORDER_BOX;
s->buttonbox = THIN_UP_BOX;
s->font = HELVETICA_BOLD;
}
static NamedStyle popup_style("Popup_Calendar", popup_revert, &Fl_Popup_Calendar::default_style);
NamedStyle* Fl_Popup_Calendar::default_style = &::popup_style;
void cb_clicked(Widget *w, void *d) {
Window *win = w->window();
if(win) {
win->set_value();
win->hide();
}
Fl::exit_modal(); //Just in case :)
}
Fl_Popup_Calendar::Fl_Popup_Calendar(Widget *dateControl)
: Fl_Popup_Window(150,150,"Calendar")
{
style(default_style);
m_dateControl = dateControl;
m_calendar = new Fl_Calendar(0,0,w(),h());
m_calendar->callback(cb_clicked);
m_calendar->box(NO_BOX);
m_calendar->copy_style(style());
end();
}
void Fl_Popup_Calendar::draw()
{
m_calendar->copy_style(style());
Fl_Popup_Window::draw();
}
void Fl_Popup_Calendar::layout() {
m_calendar->resize(box()->dx(),box()->dy(),w()-box()->dw(),h()-box()->dh());
m_calendar->layout();
Fl_Popup_Window::layout();
}
bool Fl_Popup_Calendar::popup() {
if (m_dateControl) {
int width = m_dateControl->w();
if (width < 175) width = 175;
int X=0, Y=0;
for(Widget* w = m_dateControl; w; w = w->parent()) {
X += w->x();
Y += w->y();
}
int height = 160;
m_calendar->size(width,height);
m_calendar->measure(width,height);
resize(X, Y+m_dateControl->h()-1, width+box()->dw(), height+box()->dh());
}
return Fl_Popup_Window::show_popup();
}
bool Fl_Popup_Calendar::popup(Widget *dateControl, int X, int Y, int W, int H) {
if(dateControl) {
int width = (W>0) ? W : dateControl->w();
if (width < 175) width = 175;
int height = (H>0) ? H : 175;
if (height < 175) height = 175;
for(Widget* w = m_dateControl; w; w = w->parent()) {
X += w->x();
Y += w->y();
}
resize(X, Y, width, height);
}
return Fl_Popup_Window::show_popup();
// Day buttons
for (i = 0; i < 31; i++) {
m_dayButtons[i] = new Fl_Box(0,0,16,16);
char tmp[3];
snprintf(tmp,3, "%d", (i+1));
m_dayButtons[i]->copy_label(tmp);
}
// Switch buttons
for (i = 0; i < 4; i++) {
Fl_Repeat_Button* o;
m_switchButtons[i] = o = new Fl_Repeat_Button(x,y,16,16,switchLabels[i]);
o->callback(EDE_Calendar::cbSwitchButtonClicked, (long)monthChanges[i]);
o->labelcolor(fl_darker(FL_BACKGROUND_COLOR));
o->selection_color(fl_lighter(FL_BACKGROUND_COLOR));
}
end();
reset(); // this will eventually call layout()
}
int Fl_Popup_Calendar::handle(int event) {
int rc = Fl_Popup_Window::handle(event);
// Number of rows and columns
if (rc) return rc;
#define CAL_ROWS 9
#define CAL_COLS 7
return m_calendar->handle(event);
}*/
// Calculate positions and sizes of various boxes and buttons
// NOTE: This method is costly! Avoid calling it unless calendar is actually resized
void EDE_Calendar::layout(int X, int Y, int W, int H) {
unsigned int i;
// Leave some room for edges
int x_ = X+2;
int y_ = Y+2;
int w_ = W-4;
int h_ = H-4;
// Precalculate button grid
// By doing this we try to avoid floating point math while
// having coords without holes that add up to a desired width
int bx[CAL_COLS], bw[CAL_COLS], by[CAL_ROWS], bh[CAL_ROWS];
bx[0] = x_; by[0] = y_;
for (i=1; i<CAL_COLS; i++) {
bx[i] = x_ + (w_*i)/CAL_COLS;
bw[i-1] = bx[i]-bx[i-1];
}
bw[CAL_COLS-1] = x_ + w_ - bx[CAL_COLS-1];
for (i=1; i<CAL_ROWS; i++) {
by[i] = y_ + (h_*i)/CAL_ROWS;
bh[i-1] = by[i]-by[i-1];
}
bh[CAL_ROWS-1] = y_ + h_ - by[CAL_ROWS-1];
// Title
m_monthNameBox->resize( x_,y_,w_, bh[0] );
// Labels
for (i=0; i<7; i++)
m_dayNameBoxes[i]->resize( bx[i], by[1], bw[i], bh[1] );
// Find first day of week
edelib::Date d=active_date_;
d.set(d.year(), d.month(), 1);
uint day_of_week = d.day_of_week()-1;
// First filler
if (day_of_week>0) {
int k=0;
for (i=0; i<day_of_week; i++) k += bw[i];
m_filler[0]->resize( x_, by[2], k, bh[2] );
}
// Days
int row=2;
for (i=0; i<d.days_in_month(); i++) {
m_dayButtons[i]->resize( bx[day_of_week], by[row], bw[day_of_week], bh[row] );
day_of_week++;
if (day_of_week==7) { day_of_week=0; row++; }
}
// Second filler
if (day_of_week<6) {
int k=0;
for (i=day_of_week; i<7; i++) k += bw[i];
m_filler[1]->resize( bx[day_of_week], by[row], k, bh[row] );
}
// Third filler
if (row<7)
m_filler[2]->resize( x_, by[7], w_, bh[7] );
// Switch buttons
m_switchButtons[0]->resize ( x_, by[8], bw[0], bh[8] );
m_switchButtons[1]->resize ( bx[1], by[8], bw[1], bh[8] );
m_switchButtons[2]->resize ( bx[5], by[8], bw[5], bh[8] );
m_switchButtons[3]->resize ( bx[6], by[8], bw[6], bh[8] );
}
// Overloaded resize (used to call layout)
void EDE_Calendar::resize(int X, int Y, int W, int H) {
// avoid unnecessary resizing
static int oldw=0, oldh=0;
if (W==oldw && H==oldh) return Fl_Group::resize(X,Y,W,H);
oldw=W; oldh=H;
layout(X,Y,W,H);
Fl_Widget::resize(X,Y,W,H); // avoid Fl_Group resizing because we already resized everything
}
// Set visual appearance & colors of day buttons and tooltip
void EDE_Calendar::update_calendar() {
unsigned int i;
// Find first day of week
edelib::Date d=active_date_;
d.set(d.year(), d.month(), 1);
int day_of_week = d.day_of_week()-1;
// Show/hide first filler
if (day_of_week>0)
m_filler[0]->show();
else
m_filler[0]->hide();
// Days
int row=2;
for (i=0; i<d.days_in_month(); i++) {
Fl_Box* btn = m_dayButtons[i]; // shortcut
btn->show();
// Set button color
Fl_Color daycolor = color(); // base color is the color of calendar
if (day_of_week==0) // Special color for sunday
daycolor = fl_color_average(daycolor, FL_BLUE, 0.8);
if (i==(uint)today_date_.day()-1 && d.month()==today_date_.month() && d.year()==today_date_.year())
btn->color(fl_color_average(daycolor, FL_RED, 0.5)); // today
else if (i==(uint)active_date_.day()-1)
btn->color(fl_lighter(daycolor));
else
btn->color(daycolor);
// Set downbox for active day
if (i==(uint)active_date_.day()-1)
btn->box(FL_DOWN_BOX);
else
btn->box(FL_FLAT_BOX);
day_of_week++;
if (day_of_week==7) { day_of_week=0; row++; }
}
// Hide remaining buttons
for (i=d.days_in_month(); i<31; i++)
m_dayButtons[i]->hide();
// Show/hide second filler
if (day_of_week<6)
m_filler[1]->show();
else
m_filler[1]->hide();
// Show/hide third filler
if (row<7)
m_filler[2]->show();
else
m_filler[2]->hide();
// Set title
static char title[30]; // No month name should be larger than 24 chars, even when localized
// and we can't show it anyway cause the box is too small
snprintf (title, 30, "%s, %d", d.month_name(), d.year());
m_monthNameBox->copy_label(title);
// Calculate tooltip (distance between today and active date)
static char tooltip_str[1024];
tooltip_str[0] = '\0';
if (today_date_ != active_date_) {
long dist = date_distance(today_date_, active_date_);
long weeks = dist/7;
int wdays = dist%7;
int months=0;
int mdays=0;
int years=0;
int ymonths=0;
// Find lower date, first part of tooltip
edelib::Date d1,d2;
if (today_date_ < active_date_) {
d1=today_date_;
d2=active_date_;
snprintf(tooltip_str, 1023, _("In %ld days"), dist);
} else {
d2=today_date_;
d1=active_date_;
snprintf(tooltip_str, 1023, _("%ld days ago"), dist);
}
// If necessary, calculate distance in m/d and y/m/d format
if (dist>30) {
months = d2.month() - d1.month() + (d2.year() - d1.year())*12;
mdays = d2.day() - d1.day();
if (mdays<1) {
mdays += d2.days_in_month();
months--;
}
}
if (months>11) {
years = months/12;
ymonths = months%12;
}
// Append those strings using snprintf
if (weeks) {
char* tmp = strdup(tooltip_str);
snprintf(tooltip_str, 1023, _("%s\n%ld weeks and %d days"), tmp, weeks, wdays);
free(tmp);
}
if (months) {
char* tmp = strdup(tooltip_str);
snprintf(tooltip_str, 1023, _("%s\n%d months and %d days"), tmp, months, mdays);
free(tmp);
}
if (years) {
char* tmp = strdup(tooltip_str);
snprintf(tooltip_str, 1023, _("%s\n%d years, %d months and %d days"), tmp, years, ymonths, mdays);
free(tmp);
}
}
tooltip(tooltip_str);
layout(x(),y(),w(),h()); // relayout buttons if neccessary
redraw();
}
int EDE_Calendar::handle(int e) {
// Forward events to switch buttons
for (int i=0; i<4; i++)
if (Fl::event_inside(m_switchButtons[i])) return m_switchButtons[i]->handle(e);
// Accept focus
if (e==FL_FOCUS) return 1;
if (e==FL_PUSH || e==FL_ENTER) return 1;
// Click on date to set active, doubleclick to set as today
if (e==FL_RELEASE) {
for (int i=0; i<31; i++)
if (Fl::event_inside(m_dayButtons[i])) {
edelib::Date d = active_date_;
d.set(d.year(), d.month(), i+1);
if (Fl::event_clicks() == 1)
today_date(d);
else
active_date(d);
return 1;
}
take_focus();
} else if (e==FL_KEYBOARD) {
int k=Fl::event_key();
// arrow navigation
if (k==FL_Up || k==FL_Down || k==FL_Left || k==FL_Right) {
edelib::Date ad = active_date_;
int d = ad.day();
int m = ad.month();
int y = ad.year();
if (k==FL_Up) d -= 7;
else if (k==FL_Down) d += 7;
else if (k==FL_Left) d--;
else if (k==FL_Right) d++;
if (d < 1) {
m--;
if (m<1) {
y--;
m+=12;
}
d += ad.days_in_month(y,m);
}
if (d > ad.days_in_month(y,m)) {
d -= ad.days_in_month(y,m);
m++;
if (m>12) {
y++;
m-=12;
}
}
ad.set(y,m,d);
active_date(ad);
return 1;
}
// Return to today with Home
if (k==FL_Home) {
active_date(today_date());
return 1;
}
// Set active day as today with Space
if (k==' ') {
today_date(active_date());
return 1;
}
// Allow moving focus with Tab key
if (k==FL_Tab) return Fl_Group::handle(e);
}
return Fl_Group::handle(e);
}

View File

@ -1,111 +1,103 @@
/*
* $Id: Fl_Calendar.h,v 1.7 2003/04/05 20:44:12 parshin Exp $
* $Id$
*
* Extended Fast Light Toolkit (EFLTK)
* Copyright (C) 2002-2003 by EDE-Team
* WWW: http://www.sourceforge.net/projects/ede
*
* Fast Light Toolkit (FLTK)
* Copyright (C) 1998-2003 by Bill Spitzak and others.
* WWW: http://www.fltk.org
*
* This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
* version 2. See COPYING for details.
*
* Author : Alexey Parshin
* Email : alexey@fltk.net
*
* Please report all bugs and problems to "efltk-bugs@fltk.net"
* Application for setting system date, time and local timezone
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
//
// Ported to FLTK2 by Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
// This is the Calendar widget class inspired by the Calendar originally
// developed by Alexey Parshin for SPTK and later imported into efltk.
#ifndef _EDE_CALENDAR_H_
#define _EDE_CALENDAR_H_
/*
#include <efltk/Fl.h>
#include <efltk/Fl_Popup_Window.h>
#include <efltk/Fl_Date_Time.h>
#include <efltk/Fl_Box.h>
#include <efltk/Fl_Button.h>*/
#include "Fl_Date_Time.h"
#include <fltk/InvisibleBox.h>
#include <fltk/Button.h>
#include <fltk/Group.h>
#include <fltk/Symbol.h>
/** Fl_Calendar */
class EDE_Calendar : public fltk::Group {
public:
static fltk::NamedStyle* default_style;
#include <FL/Fl_Group.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Repeat_Button.H>
/** The traditional constructor creates the calendar using the position, size, and label. */
EDE_Calendar(int x,int y,int w,int h,const char *lbl=0L);
#include <edelib/DateTime.h>
/** The new style constructor creates the calendar using the label, size, alignment, and label_width. */
// Fl_Calendar(const char* l = 0,int layout_size=30,fltk::Align layout_al=fltk::ALIGN_TOP,int label_w=100);
virtual void layout();
virtual void draw();
virtual void measure(int& w,int& h) const;
virtual void reset() { date(Fl_Date_Time::Now()); }
void date(Fl_Date_Time dt);
Fl_Date_Time date() const;
void dayButtonClicked(unsigned day);
void dayButtonChanged(unsigned day);
void switchButtonClicked(int monthChange);
#include <stdio.h>
/** EDE_Calendar */
class EDE_Calendar : public Fl_Group {
private:
static void cbDayButtonClicked(fltk::Widget *,void *);
static void cbSwitchButtonClicked(fltk::Widget *,void *);
static void cbSwitchButtonClicked(Fl_Widget *,long);
Fl_Group *m_headerBox;
Fl_Group *m_buttonBox;
Fl_Box *m_monthNameBox;
Fl_Box *m_dayNameBoxes[7];
Fl_Box *m_dayButtons[31];
Fl_Repeat_Button *m_switchButtons[4];
Fl_Box *m_filler[3];
fltk::Group *m_headerBox;
fltk::Group *m_buttonBox;
fltk::InvisibleBox *m_monthNameBox;
fltk::InvisibleBox *m_dayNameBoxes[7];
fltk::Button *m_dayButtons[31];
fltk::Button *m_switchButtons[4];
Fl_Date_Time m_todayDate;
Fl_Date_Time m_activeDate;
int m_globalx, m_globaly;
char m_headerLabel[20]; // month+year shouldn't get larger in any locale
edelib::Date today_date_;
edelib::Date active_date_;
// Update color and appearance of boxes and buttons
void update_calendar();
void ctor_init(int x,int y,int w,int h);
// Resize various boxes and buttons
void layout(int X, int Y, int W, int H);
// Debugging:
void printdate(const char* c, edelib::Date d) { fprintf(stderr, "%s: %d.%d.%d\n", c, d.day(), d.month(), d.year()); }
public:
/** The traditional constructor creates the calendar using the position, size, and label. */
EDE_Calendar(int x,int y,int w,int h,const char *lbl=0L);
/** Reset active and current date to system date */
virtual void reset() {
today_date_.set(edelib::Date::YearNow, edelib::Date::MonthNow, edelib::Date::DayNow);
edelib::Date d1 = active_date_;
active_date_.set(edelib::Date::YearNow, edelib::Date::MonthNow, edelib::Date::DayNow);
if (d1.month()!= edelib::Date::MonthNow || d1.year()!=edelib::Date::YearNow)
layout(x(),y(),w(),h());
update_calendar();
}
/** Change active date */
void active_date(const edelib::Date d) {
edelib::Date d1 = active_date_;
active_date_ = d;
// turn calendar to another page
if (d1.month()!=d.month() || d1.year()!=d.year())
layout(x(),y(),w(),h());
update_calendar();
}
const edelib::Date active_date() const { return active_date_; }
/** Change today date */
void today_date(const edelib::Date d) {
today_date_ = d;
update_calendar();
}
const edelib::Date today_date() const { return today_date_; }
// Keyboard and mouse handling
int handle(int e);
// Overload resize to call our layout()
void resize(int X, int Y, int W, int H);
// Since box colors are based on Calendar color, we need to
// overload color changing methods
void color(Fl_Color c) { Fl_Widget::color(c); update_calendar(); }
void color(Fl_Color c1, Fl_Color c2) { Fl_Widget::color(c1,c2); update_calendar(); }
Fl_Color color() { return Fl_Widget::color(); }
};
/* We lack Fl_Popup_Window to make this work... Maybe later...
class Fl_Popup_Calendar : public Fl_Popup_Window {
public:
static fltk::NamedStyle* default_style;
Fl_Popup_Calendar(fltk::Widget *dateControl=NULL);
Fl_Calendar *calendar() { return m_calendar; }
void clicked() { set_value(); }
void layout();
void draw();
int handle(int);
void date(Fl_Date_Time dt) { m_calendar->date(dt); }
Fl_Date_Time date() const { return m_calendar->date(); }
bool popup();
// Popup calendar, relative to widget
bool popup(fltk::Widget *dateControl, int X, int Y, int W=0, int H=0);
private:
friend class Fl_Calendar;
Fl_Calendar *m_calendar;
fltk::Widget *m_dateControl;
};*/
#endif

View File

@ -1,735 +0,0 @@
/***************************************************************************
Fl_Date_Time.cpp - description
-------------------
begin : Tue Dec 14 1999
copyright : (C) 1999 by Alexey Parshin
email : alexeyp@m7.tts-sf.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
//
// Ported to FLTK2 by Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
//#include <config.h>
//#include <edeconfig.h>
/*#include <efltk/Fl_Date_Time.h>
#include <efltk/Fl_Util.h>*/
#include "Fl_Date_Time.h"
// For NLS stuff
//#include "../core/fl_internal.h"
#include "../edelib2/NLS.h"
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
#ifndef _WIN32
# include <sys/time.h>
#else
# include <windows.h>
#endif
static const char *dayname[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
static const char *mname[] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
static const short _monthDays[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //Leap year
};
static const short _monthDaySums[2][12] = {
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} //Leap year
};
#define DateDelta 693594
char Fl_Date_Time::dateInputFormat[32];
char Fl_Date_Time::timeInputFormat[32];
char Fl_Date_Time::dateFormat[32];
char Fl_Date_Time::datePartsOrder[4];
char Fl_Date_Time::timeFormat[32];
bool Fl_Date_Time::time24Mode;
char Fl_Date_Time::dateSeparator;
char Fl_Date_Time::timeSeparator;
double Fl_Date_Time::dateTimeOffset;
static void upperCase(char *dest, const char *src, int dest_len) {
int i = 0;
int len = strlen(src);
if(len>dest_len) len=dest_len; //No buffer overflow.
for (; i < len; i++)
dest[i] = (char)toupper( src[i] );
dest[i] = '\0';
}
static int trimRight(char *s) {
int len = strlen(s);
while( (len--) >= 0) {
if( (unsigned char)s[len] > 32 ) {
len++;
s[len] = '\0';
break;
}
}
return len;
}
static char parseDateOrTime(char *format,char *dt) {
char separator[] = " ";
// Cut-off trailing non-digit characters
int len = strlen(dt);
char *ptr = dt + len - 1;
while (!isdigit(*ptr)) ptr--;
*(ptr+1) = 0;
// find a separator char
ptr = dt;
while (isalnum(*ptr) || *ptr == ' ') ptr++;
separator[0] = *ptr;
ptr = strtok(dt,separator);
strcpy(format,"");
const char *pattern;
while (ptr) {
int number = atoi(ptr);
switch (number) {
case 10: pattern = "HH"; // hour (12-hour mode)
Fl_Date_Time::time24Mode = false;
break;
case 22: pattern = "HH"; // hour (24-hour mode)
Fl_Date_Time::time24Mode = true;
break;
case 48: pattern = "NN"; // minute
break;
case 59: pattern = "SS"; // second
break;
case 17: pattern = "DD"; // day
strcat(Fl_Date_Time::datePartsOrder,"D");
break;
case 6: pattern = "MM"; // month
strcat(Fl_Date_Time::datePartsOrder,"M");
break;
case 2000:
case 0: pattern = "YYYY"; // year
strcat(Fl_Date_Time::datePartsOrder,"Y");
break;
default: pattern = NULL; break;
}
if (pattern) {
strcat(format,pattern);
strcat(format,separator);
}
ptr = strtok(NULL,separator);
}
len = strlen(format);
if (len)
format[len-1] = 0;
return separator[0];
}
class Fl_Date_Time_Format {
public:
Fl_Date_Time_Format();
};
static void buildDateInputFormat() {
Fl_Date_Time::dateInputFormat[0] = 0;
char separator[] = { Fl_Date_Time::dateSeparator, 0 };
for (int i = 0; i < 3; i++)
switch (Fl_Date_Time::datePartsOrder[i]) {
case 'D': strcat(Fl_Date_Time::dateInputFormat,"39\\");
strcat(Fl_Date_Time::dateInputFormat,separator);
break;
case 'M': strcat(Fl_Date_Time::dateInputFormat,"19\\");
strcat(Fl_Date_Time::dateInputFormat,separator);
break;
case 'Y': strcat(Fl_Date_Time::dateInputFormat,"2999\\");
strcat(Fl_Date_Time::dateInputFormat,separator);
break;
}
int len = strlen(Fl_Date_Time::dateInputFormat);
if (len)
Fl_Date_Time::dateInputFormat[len-2] = 0;
}
static void buildTimeInputFormat() {
if (Fl_Date_Time::time24Mode)
strcpy(Fl_Date_Time::timeInputFormat,"29\\:59");
else strcpy(Fl_Date_Time::timeInputFormat,"19\\:59T\\M");
}
Fl_Date_Time_Format::Fl_Date_Time_Format() {
char dateBuffer[32];
char timeBuffer[32];
// make a special date and time - today :)
struct tm t;
t.tm_year = 100; // since 1900, -> 2000
t.tm_mon = 5; // June (January=0)
t.tm_mday = 17;
t.tm_hour = 22;
t.tm_min = 48;
t.tm_sec = 59;
t.tm_wday = 0; // Sunday
// Build local data and time
strftime(timeBuffer,32,"%X",&t);
strftime(dateBuffer,32,"%x",&t);
// Build local date and time formats
Fl_Date_Time::datePartsOrder[0] = 0;
Fl_Date_Time::time24Mode = false; // to be determined below
Fl_Date_Time::dateSeparator = parseDateOrTime(Fl_Date_Time::dateFormat,dateBuffer);
Fl_Date_Time::timeSeparator = parseDateOrTime(Fl_Date_Time::timeFormat,timeBuffer);
if (!Fl_Date_Time::time24Mode)
strcat(Fl_Date_Time::timeFormat,"AM");
buildDateInputFormat();
buildTimeInputFormat();
}
// This is the only instance to Fl_Date_Time_Format.
static Fl_Date_Time_Format dateFormat;
bool Fl_Date_Time::is_leap_year(const short year) {
return ((year&3) == 0 && year%100 != 0 || year%400 == 0);
}
void Fl_Date_Time::encode_date(double &dt,short year,short month,short day) {
if (year == 0 && month == 0 && day == 0) {
dt = 0;
return;
}
if (month < 1 || month > 12) {
dt = 0;
return;
}
int yearKind = is_leap_year(year);
if (day < 1 || day > _monthDays[yearKind][month-1]) {
dt = 0;
return;
}
if (year <= 0 || year > 9999) {
dt = 0;
return;
}
day += _monthDaySums[yearKind][month-1];
int i = year - 1;
dt = i * 365 + i / 4 - i / 100 + i / 400 + day - DateDelta;
}
void Fl_Date_Time::encode_date(double &dt,const char *dat) {
char bdat[64];
short datePart[7], partNumber = 0;
char *ptr = NULL;
int i;
memset(datePart,0,sizeof(datePart));
upperCase(bdat, dat, sizeof(bdat));
if (strcmp(bdat,"TODAY") == 0) {
dt = Date(); // Sets the current date
return;
} else {
int len = strlen(bdat);
for(i = 0; i <= len && partNumber < 7; i++) {
char c = bdat[i];
if (c == dateSeparator || c == timeSeparator || c == ' ' || c == 0) {
if (c == timeSeparator && partNumber < 3) partNumber = 3;
if (ptr) { // end of token
bdat[i] = 0;
datePart[partNumber] = (short)atoi(ptr);
partNumber++;
ptr = NULL;
}
} else {
if (!isdigit(c)) {
dt = 0;
return;
}
if (!ptr) ptr = bdat + i;
}
}
if (partNumber < 3) { // Not enough date parts
dt = 0;
return;
}
short month=0, day=0, year=0;
for(i = 0; i < 3; i++)
switch (datePartsOrder[i]) {
case 'M': month = datePart[i]; break;
case 'D': day = datePart[i]; break;
case 'Y': year = datePart[i]; break;
}
if (year < 100) {
if (year < 35) year = short(year + 2000);
else year = short(year + 1900);
}
double dd;
encode_date(dd,year,month,day);
if (partNumber > 3) { // Time part included into string
double d;
encode_time(d,datePart[3],datePart[4],datePart[5],datePart[6]);
dd += d;
}
dt = dd;
}
}
void Fl_Date_Time::encode_time(double& dt,short h,short m,short s,short ms) {
dt = (h + ((m + (s + ms / 100.0) / 60.0) / 60.0)) / 24.0;
}
void Fl_Date_Time::encode_time(double& dt,const char *tim) {
char bdat[32];
short timePart[4] = { 0, 0, 0, 0},
partNumber = 0;
char *ptr = NULL;
bool afternoon = false;
upperCase(bdat, tim, sizeof(bdat));
if (!trimRight(bdat)) {
dt = 0;
return;
}
if (strcmp(bdat,"TIME") == 0) {
dt = Time(); // Sets the current date
return;
} else {
char *p = strstr(bdat,"AM");
if (p) {
*p = 0;
} else {
p = strstr(bdat,"PM");
if (p) {
*p = 0;
afternoon = true;
}
}
trimRight(bdat);
int len = strlen(bdat);
for (int i = 0; i <= len && partNumber < 4; i++) {
char c = bdat[i];
if (c == timeSeparator || c == ' ' || c == '.' || c == 0) {
if (ptr) { // end of token
bdat[i] = 0;
timePart[partNumber] = (short) atoi(ptr);
partNumber++;
ptr = NULL;
}
} else {
if (!isdigit(c)) {
dt = 0;
return;
}
if (!ptr) ptr = bdat + i;
}
}
if (afternoon && timePart[0] != 12)
timePart[0] = short(timePart[0] + 12);
encode_time(dt,timePart[0],timePart[1],timePart[2],timePart[3]);
}
}
const int S1 = 24 * 60 * 60; // seconds in 1 day
void Fl_Date_Time::decode_time(const double dt,short& h,short& m,short& s,short& ms) {
double t = dt - (int) dt;
int secs = int(t * S1 + 0.5);
h = short(secs / 3600);
secs = secs % 3600;
m = short(secs / 60);
secs = secs % 60;
s = short(secs);
ms = 0;
}
const int D1 = 365; // Days in 1 year
const int D4 = D1 * 4 + 1; // Days in 4 years
const int D100 = D4 * 25 - 1; // Days in 100 years
const int D400 = D100 * 4 + 1; // Days in 400 years
static void DivMod(int op1, int op2, int& div, int& mod) {
div = op1 / op2;
mod = op1 % op2;
}
void Fl_Date_Time::decode_date(const double dat, short& year, short& month, short& day) {
int Y, M, D, I;
int T = (int) dat + DateDelta;
T--;
Y = 1;
while (T >= D400) {
T -= D400;
Y += 400;
}
DivMod(T, D100, I, D);
if (I == 4) {
I--;
D += D100;
}
Y += I * 100;
DivMod(D, D4, I, D);
Y += I * 4;
DivMod(D, D1, I, D);
if (I == 4) {
I--;
D += D1;
}
Y += I;
year = Y;
//year = short (Y + 1900);
int leapYear = is_leap_year(short(year));
for (M = 0;;M++) {
I = _monthDays[leapYear][M];
if (D < I)
break;
D -= I;
}
month = short (M + 1);
day = short (D + 1);
}
//----------------------------------------------------------------
// Constructors
//----------------------------------------------------------------
Fl_Date_Time::Fl_Date_Time (short year,short month,short day,short hour,short minute,short second) {
double t;
int i;
// NLS stuff
for (i=0; i<7;i++) dayname[i]=_(dayname[i]);
for (i=0; i<12;i++) mname[i]=_(mname[i]);
encode_date(m_dateTime,year,month,day);
encode_time(t,hour,minute,second);
m_dateTime += t;
}
Fl_Date_Time::Fl_Date_Time (const char * dat) {
int i;
// NLS stuff
for (i=0; i<7;i++) dayname[i]=_(dayname[i]);
for (i=0; i<12;i++) mname[i]=_(mname[i]);
char* s1 = strdup(dat);//( Fl_String(dat).trim() );
// TODO: s1.trim()
char* s2;
if (!*dat) {
m_dateTime = 0;
return;
}
s1 = strtok(s1, " ");
char* p = strtok(NULL, " ");
if (p != NULL) {
s2 = strdup(p+1);
if (strlen(s2)>21) s2[21] = '\0';
// TODO: s2.trim()
// s1[p] = '\0'; - strtok() already did that
}
if ( strchr(s1,dateSeparator) ) {
encode_date(m_dateTime, s1);
if ( strchr(s2,timeSeparator) ) {
double dt;
encode_time(dt, s2);
m_dateTime += dt;
}
}
else encode_time(m_dateTime, s1);
}
Fl_Date_Time::Fl_Date_Time (const Fl_Date_Time &dt) {
int i;
// NLS stuff
for (i=0; i<7;i++) dayname[i]=_(dayname[i]);
for (i=0; i<12;i++) mname[i]=_(mname[i]);
m_dateTime = dt.m_dateTime;
}
Fl_Date_Time::Fl_Date_Time (const double dt) {
int i;
// NLS stuff
for (i=0; i<7;i++) dayname[i]=_(dayname[i]);
for (i=0; i<12;i++) mname[i]=_(mname[i]);
m_dateTime = dt;
}
//----------------------------------------------------------------
// Assignments
//----------------------------------------------------------------
void Fl_Date_Time::operator = (const Fl_Date_Time &dt) {
m_dateTime = dt.m_dateTime;
}
void Fl_Date_Time::operator = (const char * dat) {
encode_date(m_dateTime, dat);
}
//----------------------------------------------------------------
// Conversion operations
//----------------------------------------------------------------
// Fl_Date_Time::operator int (void) { return (int) dateTime; }
Fl_Date_Time::operator double (void) const { return m_dateTime; }
//----------------------------------------------------------------
// Date Arithmetic
//----------------------------------------------------------------
Fl_Date_Time Fl_Date_Time::operator + (int i) {
return Fl_Date_Time(m_dateTime + i);
}
Fl_Date_Time Fl_Date_Time::operator - (int i) {
return Fl_Date_Time(m_dateTime - i);
}
Fl_Date_Time Fl_Date_Time::operator + (Fl_Date_Time& dt) {
return Fl_Date_Time(m_dateTime + dt.m_dateTime);
}
Fl_Date_Time Fl_Date_Time::operator - (Fl_Date_Time& dt) {
return Fl_Date_Time(m_dateTime - dt.m_dateTime);
}
Fl_Date_Time& Fl_Date_Time::operator += (int i) {
m_dateTime += i;
return *this;
}
Fl_Date_Time& Fl_Date_Time::operator -= (int i) {
m_dateTime -= i;
return *this;
}
Fl_Date_Time& Fl_Date_Time::operator += (Fl_Date_Time& dt) {
m_dateTime += dt.m_dateTime;
return *this;
}
Fl_Date_Time& Fl_Date_Time::operator -= (Fl_Date_Time& dt) {
m_dateTime -= dt.m_dateTime;
return *this;
}
Fl_Date_Time& Fl_Date_Time::operator ++() {
m_dateTime += 1;
return *this;
}
Fl_Date_Time &Fl_Date_Time::operator ++(int) {
m_dateTime += 1;
return *this;
}
Fl_Date_Time &Fl_Date_Time::operator --() {
m_dateTime -= 1;
return *this;
}
Fl_Date_Time &Fl_Date_Time::operator --(int) {
m_dateTime -= 1;
return *this;
}
//----------------------------------------------------------------
// Format routine
//----------------------------------------------------------------
void Fl_Date_Time::format_date (char *str) const {
char *ptr = str;
short month, day, year;
if (m_dateTime == 0) {
*str = 0;
return;
}
decode_date(m_dateTime,year,month,day);
for (int i = 0; i < 3; i++) {
switch (datePartsOrder[i]) {
case 'M': sprintf(ptr,"%02i%c",month,dateSeparator);
break;
case 'D': sprintf(ptr,"%02i%c",day,dateSeparator);
break;
case 'Y': sprintf(ptr,"%04i%c",year,dateSeparator);
break;
}
ptr += strlen(ptr);
}
*(ptr-1) = 0;
}
void Fl_Date_Time::format_time (char *str,bool ampm) const {
short h,m,s,ms;
if (m_dateTime == 0) {
*str = 0;
return;
}
decode_time(m_dateTime,h,m,s,ms);
if (ampm) {
char format[] = "%02i%c%02iAM";
if (h > 11) format[10] = 'P';
sprintf(str,format,h%12,timeSeparator,m);
}
else sprintf(str,"%02i%c%02i%c%02i",h,timeSeparator,m,timeSeparator,s);
}
//----------------------------------------------------------------
// Miscellaneous Routines
//----------------------------------------------------------------
short Fl_Date_Time::day_of_year( void ) const {
Fl_Date_Time temp( 1, 1, year() );
return (short) (m_dateTime - temp.m_dateTime);
}
Fl_Date_Time Fl_Date_Time::convert(const long tt) {
struct tm *t = localtime((time_t*)&tt);
double dat,tim;
encode_date(dat,short(t->tm_year+1900),short(t->tm_mon+1),short(t->tm_mday));
encode_time(tim,short(t->tm_hour),short(t->tm_min),short(t->tm_sec),short(0));
return dat + tim;
}
#ifdef _WIN32
#define FILETIME_1970 0x019db1ded53e8000
const BYTE DWLEN = sizeof(DWORD) * 8;
/* Code ripped from some xntp implementation on http://src.openresources.com. */
long get_usec()
{
FILETIME ft;
__int64 msec;
GetSystemTimeAsFileTime(&ft);
msec = (__int64) ft.dwHighDateTime << DWLEN | ft.dwLowDateTime;
msec = (msec - FILETIME_1970) / 10;
return (long) (msec % 1000000);
}
#endif
// Get the current system time
Fl_Date_Time Fl_Date_Time::System() {
time_t tt;
time(&tt);
double datetime = convert(tt);
#ifndef _WIN32
timeval tp;
gettimeofday(&tp,0L);
double mcsec = tp.tv_usec / 1000000.0 / (3600 * 24);
#else
// This works now!
double mcsec = get_usec() / 1000000.0 / (3600 * 24);
#endif
return datetime + mcsec;
}
// Get the current system time with optional synchronization offset
Fl_Date_Time Fl_Date_Time::Now() {
return (double)Fl_Date_Time::System() + Fl_Date_Time::dateTimeOffset;
}
// Set the synchronization offset
void Fl_Date_Time::Now(Fl_Date_Time dt) {
Fl_Date_Time::dateTimeOffset = (double)dt - (double)Fl_Date_Time::System();
}
Fl_Date_Time Fl_Date_Time::Date() {
double dat = Now();
return double(int(dat));
}
Fl_Date_Time Fl_Date_Time::Time() {
double dat = Now();
return dat - int(dat);
}
short Fl_Date_Time::days_in_month() const {
short y, m, d;
decode_date(m_dateTime,y,m,d);
return _monthDays[is_leap_year(y)][m-1];
}
unsigned Fl_Date_Time::date() const {
return unsigned(m_dateTime);
}
short Fl_Date_Time::day() const {
short y, m, d;
decode_date(m_dateTime,y,m,d);
return d;
}
short Fl_Date_Time::month() const {
short y, m, d;
decode_date(m_dateTime,y,m,d);
return m;
}
short Fl_Date_Time::year() const {
short y, m, d;
decode_date(m_dateTime,y,m,d);
return y;
}
short Fl_Date_Time::day_of_week (void) const {
return short((int(m_dateTime) - 1) % 7 + 1);
}
char* Fl_Date_Time::day_name (void) const {
return strdup(dayname[day_of_week() - 1]);
}
char* Fl_Date_Time::month_name() const {
return strdup(mname[month()-1]);
}
char* Fl_Date_Time::date_string() const {
char buffer[32];
format_date(buffer);
return strdup(buffer);
}
char* Fl_Date_Time::time_string() const {
char buffer[32];
format_time(buffer,!time24Mode);
return strdup(buffer);
}
void Fl_Date_Time::decode_date(short *y,short *m,short *d) const {
decode_date(m_dateTime,*y,*m,*d);
}
void Fl_Date_Time::decode_time(short *h,short *m,short *s,short *ms) const {
decode_time(m_dateTime,*h,*m,*s,*ms);
}

View File

@ -1,120 +0,0 @@
/*
* $Id: Fl_Date_Time.h,v 1.11 2003/03/15 16:09:55 laza2000 Exp $
*
* Extended Fast Light Toolkit (EFLTK)
* Copyright (C) 2002-2003 by EDE-Team
* WWW: http://www.sourceforge.net/projects/ede
*
* Fast Light Toolkit (FLTK)
* Copyright (C) 1998-2003 by Bill Spitzak and others.
* WWW: http://www.fltk.org
*
* This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
* version 2. See COPYING for details.
*
* Author : Alexey Parshin
* Email : alexey@fltk.net
*
* Please report all bugs and problems to "efltk-bugs@fltk.net"
*
*/
//
// Ported to FLTK2 by Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
#ifndef _FL_DATE_TIME_H_
#define _FL_DATE_TIME_H_
/*#include "Fl_Export.h"
#include "Fl_String.h"*/
/** Fl_Date_Time */
class Fl_Date_Time {
public:
static char dateInputFormat[32];
static char timeInputFormat[32];
static char dateFormat[32];
static char timeFormat[32];
static char datePartsOrder[4];
static char dateSeparator;
static char timeSeparator;
static bool time24Mode;
Fl_Date_Time (short y,short m,short d,short hour=0,short minute=0,short second=0);
Fl_Date_Time (const char * dat);
Fl_Date_Time (const Fl_Date_Time &dt);
Fl_Date_Time (const double dt=0);
static Fl_Date_Time convert (const long);
void format_date(char *str) const;
void format_time(char *str, bool ampm=true) const;
// These functions don't affect the actual system time.
// You can only alter the time for the current program.
static void Now(Fl_Date_Time dt); // Sets to current date and time
static Fl_Date_Time System(); // Gets to current system date and time
static Fl_Date_Time Now(); // Gets to current date and time
static Fl_Date_Time Date(); // Gets to current date
static Fl_Date_Time Time(); // Gets to current time
short days_in_month() const; // Number of days in month (1..31)
short day_of_week() const; // (1..7)
short day_of_year() const; // returns relative date since Jan. 1
char* day_name() const; // Character Day Of Week ('Sunday'..'Saturday')
char* month_name() const; // Character Month name
unsigned date() const; // Numeric date of date object
short day() const; // Numeric day of date object
short month() const; // Month number (1..12)
short year() const;
char* date_string() const;
char* time_string() const;
void decode_date(short *y,short *m,short *d) const;
void decode_time(short *h,short *m,short *s,short *ms) const;
operator double (void) const;
void operator = (const Fl_Date_Time& date);
void operator = (const char * dat);
Fl_Date_Time operator + (int i);
Fl_Date_Time operator - (int i);
Fl_Date_Time operator + (Fl_Date_Time& dt);
Fl_Date_Time operator - (Fl_Date_Time& dt);
Fl_Date_Time& operator += (int i);
Fl_Date_Time& operator -= (int i);
Fl_Date_Time& operator += (Fl_Date_Time& dt);
Fl_Date_Time& operator -= (Fl_Date_Time& dt);
Fl_Date_Time& operator ++ (); // Prefix increment
Fl_Date_Time& operator ++ (int); // Postfix increment
Fl_Date_Time& operator -- (); // Prefix decrement
Fl_Date_Time& operator -- (int); // Postfix decrement
static void decode_date(const double dt,short& y,short& m,short& d);
static void decode_time(const double dt,short& h,short& m,short& s,short& ms);
static void encode_date(double &dt,short y=0,short m=0,short d=0);
static void encode_date(double &dt,const char *dat);
static void encode_time(double &dt,short h=0,short m=0,short s=0,short ms=0);
static void encode_time(double &dt,const char *tim);
static bool is_leap_year(const short year);
protected:
double m_dateTime;
static double dateTimeOffset; // The offset from current' system time for synchronization
// with outside system
};
// Date comparison
static inline bool operator < (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 < (double)dt2 ); }
static inline bool operator <= (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 <= (double)dt2 ); }
static inline bool operator > (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 > (double)dt2 ); }
static inline bool operator >= (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 >= (double)dt2 ); }
static inline bool operator == (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 == (double)dt2 ); }
static inline bool operator != (const Fl_Date_Time &dt1, const Fl_Date_Time &dt2) { return ( (double)dt1 != (double)dt2 ); }
#endif

111
etimedate/Fl_Time_Input.h Normal file
View File

@ -0,0 +1,111 @@
/*
* $Id$
*
* Application for setting system date, time and local timezone
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
#ifndef _FL_TIME_INPUT_H_
#define _FL_TIME_INPUT_H_
#include <FL/Fl_Input.H>
#include <string.h>
#include <stdlib.h>
#include <time.h>
class Fl_Time_Input : public Fl_Input {
int h,m,s;
// Parse time into variables h,m,s
// Return true if time is valid, else returns false
bool parse_time(const char* time) {
if (!time) return false;
h=m=s=0;
char* p = (char*)time;
while (*p != ':') {
if (*p<'0' || *p>'9') return false;
h=h*10+(*p++-48);
}
p++;
while (*p != ':') {
if (*p<'0' || *p>'9') return false;
m=m*10+(*p++-48);
}
p++;
while (*p != '\0') {
if (*p<'0' || *p>'9') return false;
s=s*10+(*p++-48);
}
if (h>23 || m>59 || s>59) return false;
return true;
}
public:
Fl_Time_Input(int x, int y, int w, int h, const char *l = 0) : Fl_Input(x,y,w,h,l) { value("00:00:00"); }
void value(const char* l) {
int p = position(), m = mark();
if (parse_time(l)) Fl_Input::value(l);
else Fl_Input::value("00:00:00");
position(p,m);
}
const char* value() { return Fl_Input::value(); }
int handle(int e) {
char* oldvalue = strdup(Fl_Input::value());
int ret = Fl_Input::handle(e);
if (!parse_time(Fl_Input::value())) Fl_Input::value(oldvalue);
free(oldvalue);
return ret;
}
int hour() { parse_time(value()); return h; }
int minute() { parse_time(value()); return m; }
int second() { parse_time(value()); return s; }
void hour(int val) {
parse_time(value());
char tmp[10];
snprintf(tmp, 10, "%02d:%02d:%02d", val, m, s);
value(tmp);
}
void minute(int val) {
parse_time(value());
char tmp[10];
snprintf(tmp, 10, "%02d:%02d:%02d", h, val, s);
value(tmp);
}
void second(int val) {
parse_time(value());
char tmp[10];
snprintf(tmp, 10, "%02d:%02d:%02d", h, m, val);
value(tmp);
}
void epoch(time_t val) {
struct tm* t = localtime(&val);
char tmp[10];
snprintf(tmp, 10, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
value(tmp);
}
time_t epoch() {
time_t ep = time(0);
struct tm* t = localtime(&ep);
t->tm_hour = hour();
t->tm_min = minute();
t->tm_sec = second();
return mktime(t);
}
};
#endif

View File

@ -10,7 +10,8 @@
SubDir TOP etimedate ;
SOURCE = etimedate.cpp TimeBox.cpp EDE_Calendar.cpp Fl_Date_Time.cpp ;
SOURCE = etimedate.cpp EDE_Calendar.cpp ;
MakeProgram etimedate : $(SOURCE) ;
ExtractStrings locale : $(SOURCE) ;
EdeProgram etimedate : $(SOURCE) ;
TranslationStrings locale : $(SOURCE) ;

View File

@ -1,22 +0,0 @@
CPPFILES = ../edelib2/Util.cpp ../edelib2/Config.cpp ../edelib2/Run.cpp ../edelib2/process.cpp ../edelib2/pty.cpp etimedate.cpp TimeBox.cpp EDE_Calendar.cpp Fl_Date_Time.cpp
TARGET = etimedate
POFILES = locale/ru.po\
locale/sr.po\
locale/sk.po\
locale/hu.po\
include ../makeinclude
install:
$(INSTALL_PROGRAM) $(TARGET) $(bindir)
$(INSTALL_LOCALE)
uninstall:
$(RM) $(bindir)/$(TARGET)
clean:
$(RM) $(TARGET)
$(RM) *.o

View File

@ -1,17 +1,14 @@
TODO with etimedate:
* calendar
- review methods and add new, for better future usability
- create new doxygen documentation
- add ability to calculate difference between selected date and today
- Add text box for direct date entry
- Make month and year display into Fl_Choice
- Display number of week (within current year) somewhere... (probably in
tooltip)
* clock
- redesign clock - use bitmaps for background and possibly hands
- add seconds to input and buttons
- use Date_Time class
- remove unnecessary methods, add new ones
- merge two boxes?
- make hands movable with mouse
* timezones
- add city coordinates (find in evolution / kde), draw current zone on map
- make map sensitive / hotspots on city coordinates
* Date_Time class
- new class

View File

@ -1,461 +0,0 @@
// TimeBox.cxx
// Class that displays a clock with ability to set time
// Part of Equinox Desktop Environment (EDE)
//
// Based on Fl_Time.cxx
// Copyright (C) 2000 Softfield Research Ltd.
//
// Changes 02/09/2001 by Martin Pekar
// Ported to FLTK2 and redesigned by Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
//
// This program is licenced under terms of the
// GNU General Public Licence version 2 or newer.
// See COPYING for details.
// TODO: Update from clock example in latest fltk2 test
// Note V.Lj.: I don't think we need all of this, some code could be
// safely removed
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <fltk/Item.h>
#include <fltk/ask.h>
#include "../edelib2/NLS.h"
#include <fltk/filename.h>
#include <fltk/events.h>
#include "etimedate.h"
#include "TimeBox.h"
// Constructor
TimeBox::TimeBox(int x, int y, int w, int h, char *l) : fltk::Group(x, y, w, h, l)
{
// Basic layout of TimeBox
// TODO: this should be part of draw() so that the widget could be resizable
int button_width; // button_height=button_width
int realx,realy,realh,realw; //realh = realw + realw/7 (buttons)
if (h >= w * 8/7) {
realx = x;
realy = y + (h-(int)(w*8/7))/2;
realw = w;
realh = (int)w * 8/7;
} else {
realx = x + (w-(int)(h*7/8))/2;
realy = y;
realw = (int)h * 7/8;
realh = h;
}
button_width = (int)(realw/7);
clock = new fltk::ClockOutput(realx, realy, realw, realw);
input_time = new fltk::Input(realx, realy+realw, realw - button_width * 4, button_width, 0);
input_time->callback(input_changed_cb, this);
input_time->when(fltk::WHEN_CHANGED);
// input_time->textsize(12);
button_decrease_hour = new fltk::Button(realx + realw - 4 * button_width, realy+realw + 2, button_width, button_width-4, "@-1<<");
button_decrease_hour->callback(button_cb, this);
button_decrease_hour->labeltype(fltk::SYMBOL_LABEL);
button_decrease_hour->box(fltk::THIN_UP_BOX);
// button_decrease_hour->labelcolor(buttoncolor());
// button_decrease_hour->highlight_color(fltk::color_average(buttoncolor(), fltk::GRAY, .5f));
button_decrease_hour->highlight_color(fltk::lerp(buttoncolor(),fltk::WHITE,.67f)); // ex. fl_lighter()
button_increase_hour = new fltk::Button(realx + realw - 3 * button_width, realy+realw + 2, button_width, button_width-4, "@-1>>");
button_increase_hour->callback(button_cb, this);
button_increase_hour->labeltype(fltk::SYMBOL_LABEL);
button_increase_hour->box(fltk::THIN_UP_BOX);
// button_increase_hour->labelcolor(buttoncolor());
// button_increase_hour->highlightcolor(fltk::color_average(buttoncolor(), fltk::GRAY, .5f));
button_increase_hour->highlight_color(fltk::lerp(buttoncolor(),fltk::WHITE,.67f)); // ex. fl_lighter()
button_decrease_minute = new fltk::Button(realx + realw - 2 * button_width, realy+realw + 2, button_width, button_width-4, "@-1<");
button_decrease_minute->callback(button_cb, this);
button_decrease_minute->labeltype(fltk::SYMBOL_LABEL);
button_decrease_minute->box(fltk::THIN_UP_BOX);
// button_decrease_minute->labelcolor(buttoncolor());
// button_decrease_minute->highlight_color(fltk::color_average(buttoncolor(), fltk::GRAY, .5f));
button_decrease_minute->highlight_color(fltk::lerp(buttoncolor(),fltk::WHITE,.67f)); // ex. fl_lighter()
button_increase_minute = new fltk::Button(realx + realw - button_width, realy+realw + 2, button_width, button_width-4, "@-1>");
button_increase_minute->callback(button_cb, this);
button_increase_minute->labeltype(fltk::SYMBOL_LABEL);
button_increase_minute->box(fltk::THIN_UP_BOX);
// button_increase_minute->labelcolor(buttoncolor());
// button_increase_minute->highlight_color(fltk::color_average(buttoncolor(), fltk::GRAY, .5f));
button_increase_minute->highlight_color(fltk::lerp(buttoncolor(),fltk::WHITE,.67f)); // ex. fl_lighter()
end();
//type(fltk::TIME_12HOUR);
// TODO: read this from current locale
type(TIMEBOX_24HOUR);
current_tv = (struct timeval*)malloc(sizeof(struct timeval)-1);
display_tv = (struct timeval*)malloc(sizeof(struct timeval)-1);
current_time();
}
// dtor
TimeBox::~TimeBox()
{
free(current_tv);
free(display_tv);
}
// Reset the clock to current system time
void TimeBox::current_time()
{
struct tm* display_time_tm;
gettimeofday(current_tv, 0);
display_tv->tv_sec = current_tv->tv_sec;
display_tv->tv_usec = current_tv->tv_usec;
display_time_tm = localtime(&current_tv->tv_sec);
if(type() == TIMEBOX_24HOUR) strftime(time_string, 19, "%2H:%2M", display_time_tm);
else strftime(time_string, 19, "%2I:%2M %p", display_time_tm);
input_time->value(time_string);
// Start the clock and display current time
clock->value(display_tv->tv_sec);
add_timeout(1.0f);
}
// Update the clock each second
int TimeBox::handle(int event)
{
switch(event) {
case fltk::TIMEOUT:
{
struct timeval t; gettimeofday(&t, 0);
clock->value(t.tv_sec);
float delay = 1.0f-float(t.tv_usec)*.000001f;
if (delay < .1f || delay > .9f) delay = 1.0f;
add_timeout(delay);
}
break;
}
return clock->handle(event); // right?
}
// This apparently has the side effect of moving the clock relatively to
// the current time, e.g
// system time TimeBox
// before 1:00 1:02
// after 1:03 1:05
// etc.
void TimeBox::refresh()
{
long different;
if (valid())
{
different = - display_tv->tv_sec + current_tv->tv_sec;
gettimeofday(current_tv, 0);
display_tv->tv_sec = current_tv->tv_sec - different;
redisplay();
}
}
// Update the text input field
void TimeBox::redisplay()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
if(type() == TIMEBOX_24HOUR) strftime(time_string, 19, "%2H:%2M", display_time_tm);
else strftime(time_string, 19, "%2I:%2M %p", display_time_tm);
input_time->value(time_string);
}
// Stop the clock and update it (move hands)
void TimeBox::move_hands()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
remove_timeout();
clock->value(display_tv->tv_sec);
}
int TimeBox::hour()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
return display_time_tm->tm_hour;
}
int TimeBox::minute()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
return display_time_tm->tm_min;
}
void TimeBox::hour(int value)
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
display_time_tm->tm_hour = value;
display_tv->tv_sec = mktime(display_time_tm);
}
void TimeBox::minute(int value)
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
if(value < 0)
{
display_time_tm->tm_min = 59;
display_time_tm->tm_hour--;
}
else if(value >= 0 && value <= 59)
{
display_time_tm->tm_min = value;
}
else if (value > 59)
{
display_time_tm->tm_min = 0;
display_time_tm->tm_hour++;
}
display_time_tm->tm_sec = 0;
display_tv->tv_sec = mktime(display_time_tm);
}
void TimeBox::settime()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv->tv_sec);
// return display_time_tm->tm_min;
time_t ct = mktime (display_time_tm);
if (stime(&ct)!=0)
fltk::alert(_("Error setting time. You are probably not superuser!"));
}
void TimeBox::value(int h, int m)
{
hour(h);
minute(m);
}
bool TimeBox::valid()
{
int h, m;
char a[5];
if(type() == TIMEBOX_12HOUR)
{
if (sscanf(input_time->value(), "%d:%d %s",&h, &m, a) == 3)
{
if (h >= 1 && h <= 12 && m >= 0 && m <= 59 && (strcasecmp(a, "am") == 0 || strcasecmp(a, "pm") == 0))
{
last_valid = true;
return true;
}
}
}
else
{
if (sscanf(input_time->value(), "%d:%d",&h, &m) == 2)
{
if (h >= 0 && h <= 23 && m >= 0 && m <= 59)
{
last_valid = true;
return true;
}
}
}
last_valid = false;
return false;
}
void TimeBox::input_changed_cb(fltk::Widget* widget, void* data)
{
TimeBox* t = (TimeBox*) data;
int h, m;
char a[5];
if (t->valid())
{
if(t->type() == TIMEBOX_12HOUR)
{
sscanf(t->input_time->value(), "%d:%d %2s",&h, &m, a);
if(strcasecmp(a, "am") == 0)
{
if(h < 12)
{
t->hour(h);
}
else
{
t->hour(0);
}
}
else
{
if(h < 12)
{
t->hour(h + 12);
}
else
{
t->hour(12);
}
}
}
else
{
sscanf(t->input_time->value(), "%d:%d",&h, &m);
t->hour(h);
}
t->minute(m);
t->move_hands();
}
t->do_callback();
}
void TimeBox::button_cb(fltk::Widget* widget, void* data)
{
TimeBox* t = (TimeBox*) data;
if(widget == t->button_decrease_hour)
{
t->hour(t->hour()-1);
}
if (widget == t->button_decrease_minute)
{
t->minute(t->minute()-1);
}
if (widget == t->button_increase_minute)
{
t->minute(t->minute()+1);
}
if (widget == t->button_increase_hour)
{
t->hour(t->hour()+1);
}
t->redisplay();
t->move_hands();
t->do_callback();
}
void TimeBox::textsize(int size)
{
input_time->textsize(size);
}
void TimeBox::labelsize(int size)
{
button_decrease_hour->labelsize(size);
button_decrease_minute->labelsize(size);
button_increase_minute->labelsize(size);
button_increase_hour->labelsize(size);
fltk::Group::labelsize(size);
}
void TimeBox::textfont(fltk::Font* font)
{
input_time->textfont(font);
}
void TimeBox::labelfont(fltk::Font* font)
{
button_decrease_hour->labelfont(font);
button_decrease_minute->labelfont(font);
button_increase_minute->labelfont(font);
button_increase_hour->labelfont(font);
fltk::Group::labelfont(font);
}
void TimeBox::textcolor(fltk::Color color)
{
input_time->textcolor(color);
}
void TimeBox::labelcolor(fltk::Color color)
{
button_decrease_hour->labelcolor(color);
button_decrease_minute->labelcolor(color);
button_increase_minute->labelcolor(color);
button_increase_hour->labelcolor(color);
fltk::Group::labelcolor(color);
}
int TimeBox::textsize()
{
return (int)input_time->textsize();
}
int TimeBox::labelsize()
{
return (int)button_decrease_hour->labelsize();
}
fltk::Font* TimeBox::labelfont()
{
return button_decrease_hour->labelfont();
}
fltk::Font* TimeBox::textfont()
{
return input_time->textfont();
}
fltk::Color TimeBox::labelcolor()
{
return button_decrease_hour->labelcolor();
}
fltk::Color TimeBox::textcolor()
{
return input_time->textcolor();
}

View File

@ -1,212 +0,0 @@
// TimeBox.h
// Class that displays a clock with ability to set time
// Part of Equinox Desktop Environment (EDE)
//
// Based on Fl_Time.h
// Copyright (C) 2000 Softfield Research Ltd.
//
// Changes 02/09/2001 by Martin Pekar
// Ported to FLTK2 and redesigned by Vedran Ljubovic <vljubovic@smartnet.ba>, 2005.
//
// This program is licenced under terms of the
// GNU General Public Licence version 2 or newer.
// See COPYING for details.
#ifndef __TIME_WIDGET_H
#define __TIME_WIDGET_H
#include "sys/time.h"
#include <fltk/Group.h>
#include <fltk/Button.h>
#include <fltk/Input.h>
#include <fltk/Clock.h>
#include "../edelib2/NLS.h"
#define TIMEBOX_24HOUR 0
#define TIMEBOX_12HOUR 1
class TimeBox : public fltk::Group {
public:
TimeBox(int x, int y, int w, int h, char *l=0);
~TimeBox();
/**
* Gets the hour.
*
* @return The hour associated with this widget.
*/
int hour();
/**
* Sets the hour.
*
* @param hour The hour associated with this widget.
*/
void hour(int value);
/**
* Gets the minute.
*
* @return The minute associated with this widget.
*/
int minute();
/**
* Sets the minute.
*
* @param minute The minute associated with this widget.
*/
void minute(int value);
// Be sure to run this after using hour and min to change the clock value.
void redisplay();
void move_hands();
/**
* Sets the minute and hour at the same time.
*
* @param minute The minute associated with this widget.
* @param hour The hour associated with this widget.
*/
void value(int h, int m);
/**
* Sets the minute and hour to the system minute and hour.
*/
void current_time();
/**
* Refreshes the widget.
*/
void refresh();
/**
* Sets the size of the label text which is used for the M+,
* M-, Y+, and Y- labels.
*
* @param size The size of the label font.
*/
void labelsize(int size);
/**
* Sets the label font which is used for the M+,
* M-, Y+, and Y- labels.
*
* @param font The label font.
*/
void labelfont(fltk::Font* font);
/**
* Sets the label color which is used for the M+,
* M-, Y+, and Y- labels.
*
* @param font The label color.
*/
void labelcolor(fltk::Color color);
/**
* Sets the size of the text which is used to display
* the set time.
*
* @param size The size of the text font.
*/
void textsize(int size);
/**
* Sets the font of the text which is used to display
* the set time.
*
* @param font The font of the text font.
*/
void textfont(fltk::Font*);
/**
* Sets the color of the text which is used to display
* the set time.
*
* @param color The color of the text font.
*/
void textcolor(fltk::Color);
/**
* Gets the size of the label text which is used for the M+,
* M-, Y+, and Y- labels.
*
* @return The size of the label font.
*/
int labelsize();
/**
* Gets the label font which is used for the M+,
* M-, Y+, and Y- labels.
*
* @return The label font.
*/
fltk::Font* labelfont();
/**
* Gets the label color which is used for the M+,
* M-, Y+, and Y- labels.
*
* @return The label color.
*/
fltk::Color labelcolor();
/**
* Gets the size of the text which is used to display
* the set time.
*
* @return The size of the text font.
*/
int textsize();
/**
* Gets the font of the text which is used to display
* the set time.
*
* @return The font of the text font.
*/
fltk::Font* textfont();
/**
* Gets the color of the text which is used to display
* the set time.
*
* @return The color of the text font.
*/
fltk::Color textcolor();
/**
* Determines if the entered time is a recognized format.
*
* @return True if it is a valid time format, otherwise false.
*/
bool valid();
int handle(int);
void settime(); //just for superuser
private:
fltk::ClockOutput *clock;
fltk::Button *button_decrease_hour;
fltk::Button *button_decrease_minute;
fltk::Input *input_time;
fltk::Button *button_increase_minute;
fltk::Button *button_increase_hour;
struct timeval *current_tv;
struct timeval *display_tv;
char time_string[20];
bool last_valid;
int look_;
static void input_changed_cb(fltk::Widget* widget, void* data);
static void button_cb(fltk::Widget* widget, void* data);
};
#endif

View File

@ -11,329 +11,528 @@
*/
#include "etimedate.h"
//#include <edeconf.h>
#include <fltk/SharedImage.h>
#include <fltk/xpmImage.h>
#include <fltk/run.h>
#include <fltk/ask.h>
#include <fltk/Item.h>
#include "../edelib2/NLS.h"
#include "../edelib2/Run.h"
#include <edelib/Nls.h>
#include <edelib/MessageBox.h>
#include <edelib/Run.h>
#include <edelib/StrUtil.h>
#include <edelib/Config.h>
#include <edelib/IconTheme.h>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_Repeat_Button.H>
#define FL_PATH_MAX 1024
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
// graphics
#include "icons/world2.xpm"
using namespace fltk;
using namespace edelib;
static Fl_Double_Window *timedateWindow=(Fl_Double_Window *)0;
EDE_Calendar *calendar=(EDE_Calendar *)0;
Fl_Time_Input *timeBox=(Fl_Time_Input*)0;
Fl_Choice *timeFormat=(Fl_Choice *)0;
Fl_Menu_Item menu_timeFormat[] = {
{_("12 hour")},
{_("24 hour")},
{0}
};
static Fl_Pixmap image_world(world2_xpm);
Fl_Choice* timeZonesList=(Fl_Choice *)0;
Fl_Button* applyButton;
Fl_Input_Choice* serverList;
Fl_Clock_Output* clk;
static Window* timedateWindow;
TimeBox* timeBox;
EDE_Calendar* calendar;
InputBrowser* timeZonesList;
// Status variables
bool time_changed, format_changed, tz_changed, date_changed;
Button* applyButton;
bool time_changed = false;
bool date_changed = false;
bool tz_changed = false;
// config file for workpanel (time format)
edelib::Config config_file;
int phour, pminute;
char* zonetab_dir = 0;
// Time servers - all in one string, so that translators can easily add new servers
const char* time_servers = _("International (pool.ntp.org)\nEurope (europe.pool.ntp.org)\nAsia (asia.pool.ntp.org)\nNorth America (north-america.pool.ntp.org)\nAustralia and Oceania (oceania.pool.ntp.org)");
// Constants
// --------------------------------------------
// timezone functions
// From efltk/filename.h
#define FL_PATH_MAX 1024
// end filename.h
// Timezone funcs
// --------------------------------------------
// wait - whether to wait for process to finish
// end Util.cpp
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
// Return string describing current timezone
void getCurrentTimeZone()
{
char szZone[100],tempstring[101];
const char* get_current_timezone() {
static char current_tz[100] = "";
char tmp[100];
FILE *f;
if(readlink("/etc/localtime", szZone, sizeof(szZone)-1)>0) {
char *tz = strstr(szZone, "/zoneinfo/") + strlen("/zoneinfo/");
if(readlink("/etc/localtime", tmp, sizeof(tmp)-1)>0) {
char *tz = strstr(tmp, "/zoneinfo/") + strlen("/zoneinfo/");
strncpy(current_tz, tz, 99);
current_tz[99]='\0';
// timeZonesList->value(tz);
timeZonesList->text(tz);
// timeZonesList->text(tz);
} else {
// some distros just copy the file instead of symlinking
// But /etc/sysconfig/clock should contain ZONE=Continent/City
if((f = fopen("/etc/sysconfig/clock", "r")) != NULL) {
while (fgets(tempstring,100,f) != NULL) {
while (fgets(tmp,99,f) != NULL) {
// last char is newline, let's strip that:
if (tempstring[strlen(tempstring)-1] == '\n')
tempstring[strlen(tempstring)-1] = '\0';
if (strstr(tempstring,"ZONE=") == tempstring) {
if (tmp[strlen(tmp)-1] == '\n')
tmp[strlen(tmp)-1] = '\0';
if (strstr(tmp,"ZONE=") == tmp) {
strncpy(current_tz, tmp+5, 99);
current_tz[99]='\0';
// timeZonesList->value(tempstring+5);
timeZonesList->text(tempstring+5);
// timeZonesList->text(tempstring+5);
}
}
} else {
// timeZonesList->value(_("Zone information not found."));
timeZonesList->text(_("Zone information not found."));
timeZonesList->add(_("Zone information not found."));
}
}
}
static char *zonetab_dir = 0;
void saveTimeZone()
{
}
/*int sort_f(const void *w1, const void *w2) {
Widget *widget1 = *(Widget**)w1;
Widget *widget2 = *(Widget**)w2;
return strcmp(widget1->label(), widget2->label());
}*/
// wstrim() - for trimming characters (used in parser)
// parts of former fl_trimleft and fl_trimright from Fl_Util.cpp
#include <ctype.h>
char* wstrim2(char *string)
{
char *start;
if(string == NULL )
return NULL;
if (*string) {
int len = strlen(string);
if (len) {
char *p = string + len;
do {
p--;
if ( !isspace(*p) ) break;
} while ( p != string );
if ( !isspace(*p) ) p++;
*p = 0;
}
}
for(start = string; *start && isspace (*start); start++);
memmove(string, start, strlen(start) + 1);
return string;
return current_tz;
}
void fillTimeZones()
{
// This funtion is very lame :)
// Fill timeZonesList widget with time zones
FILE *f;
char tempstring[101] = "Unknown";
struct stat s;
if(stat("/usr/share/zoneinfo/zone.tab",&s)==0) {
run_program("cat /usr/share/zoneinfo/zone.tab | grep -e ^[^#] | cut -f 3 |sort > /tmp/_tzone_.txt");
zonetab_dir = "/usr/share/zoneinfo/";
}
else if(stat("/usr/local/share/zoneinfo/zone.tab",&s)==0) {
run_program("cat /usr/local/share/zoneinfo/zone.tab | grep -e ^[^#] | cut -f 3 | sort > /tmp/_tzone_.txt");
zonetab_dir = "/usr/local/share/zoneinfo/";
} else {
Item *o = new Item(_("Zone information not found."));
o->textcolor(RED);
return;
}
if((f = fopen("/tmp/_tzone_.txt", "r")) != NULL)
{
while(fgets(tempstring, 100, f) != NULL)
{
Item *o = new Item();
o->copy_label(wstrim2(tempstring));
}
fclose(f);
} else {
Item *o = new Item(_("Zone information not found."));
o->textcolor(RED);
return;
}
remove("/tmp/_tzone_.txt");
void fill_timezones(const char* current) {
FILE *f;
char tempstring[101] = "";
struct stat s;
if(stat("/usr/share/zoneinfo/zone.tab",&s)==0) {
edelib::run_program("cat /usr/share/zoneinfo/zone.tab | grep -e ^[^#] | cut -f 3 |sort > /tmp/_tzone_.txt");
zonetab_dir = "/usr/share/zoneinfo/";
}
else if(stat("/usr/local/share/zoneinfo/zone.tab",&s)==0) {
edelib::run_program("cat /usr/local/share/zoneinfo/zone.tab | grep -e ^[^#] | cut -f 3 | sort > /tmp/_tzone_.txt");
zonetab_dir = "/usr/local/share/zoneinfo/";
} else {
timeZonesList->add(_("Zone information not found."));
return;
}
if((f = fopen("/tmp/_tzone_.txt", "r")) != NULL)
{
timeZonesList->clear();
while(fgets(tempstring, 100, f) != NULL)
{
timeZonesList->add(edelib::str_trim(tempstring));
}
fclose(f);
timeZonesList->value(timeZonesList->find_item(current));
} else {
timeZonesList->add(_("Zone information not found."));
}
remove("/tmp/_tzone_.txt");
// TODO: Group::current()->array().sort(sort_f);
}
// Change time zone
char* apply_timezone() {
static char cmd[FL_PATH_MAX] = "";
char tz[FL_PATH_MAX];
if(!zonetab_dir) { // this should be set by fill_timezones
// although, if there are no timezones, tz_changed should never become true
edelib::alert(_("Zone information not found."));
return 0;
}
timeZonesList->item_pathname(cmd, sizeof(cmd)-1);
snprintf(tz, sizeof(tz)-1, "%s%s", zonetab_dir, cmd);
snprintf(cmd, sizeof(cmd)-1, "rm /etc/localtime; ln -s %s /etc/localtime; ", tz);
char val[FL_PATH_MAX];
snprintf(val, sizeof(val)-1, "TZ=%s", tz);
putenv(val);
tz_changed=false;
return cmd;
}
// --------------------------------------------
// Time format
// --------------------------------------------
// Callback functions
void applyAll() {
char cmd1[FL_PATH_MAX];
char cmd2[FL_PATH_MAX];
cmd1[0]='\0'; cmd2[0]='\0';
if (tz_changed) {
if(!zonetab_dir) {
alert(_("Zone information not found."));
return;
}
char tz[FL_PATH_MAX];
// snprintf(tz, sizeof(tz)-1, "%s%s", zonetab_dir, timeZonesList->value());
snprintf(tz, sizeof(tz)-1, "%s%s", zonetab_dir, timeZonesList->text());
snprintf(cmd1, sizeof(cmd1)-1, "rm /etc/localtime; ln -s %s /etc/localtime; ", tz);
char val[FL_PATH_MAX];
snprintf(val, sizeof(val)-1, "TZ=%s", tz);
putenv(val);
// Get current time format
tz_changed=false;
int get_format() {
if (config_file.load("ede.conf")) {
char timeformatstr[5];
config_file.get("Clock", "TimeFormat", timeformatstr, 5);
if (strcmp(timeformatstr,"24") == 0)
return 1;
}
if (time_changed || date_changed) {
Fl_Date_Time date = calendar->date();
int mmonth = date.month();
int mday = date.day();
int myear = date.year();
int mhour = timeBox->hour();
int mminute = timeBox->minute();
//Default to 12 hour is there's a problem
return 0;
}
snprintf(cmd2, sizeof(cmd2)-1, "date %.2d%.2d%.2d%.2d%.2d", mmonth, mday, mhour, mminute, myear);
time_changed=false;
date_changed = false;
// Set time format
void apply_format(int format) {
if (config_file.load("ede.conf")) {
if (format == 1)
config_file.set("Clock", "TimeFormat", "24");
else
config_file.set("Clock", "TimeFormat", "12");
config_file.save("ede.conf");
}
char *cmd = (char*)malloc(FL_PATH_MAX*2);
// Now run everything as root
strcpy(cmd,cmd1);
strcat(cmd,cmd2);
run_program(cmd, true, true, false);
format_changed = false;
}
static void cb_OK(Button*, void*) {
applyAll();
exit(0);
// --------------------------------------------
// Apply
// --------------------------------------------
char* apply_date_time() {
static char cmd2[FL_PATH_MAX] = "";
edelib::Date date = calendar->today_date();
int mmonth = date.month();
int mday = date.day();
int myear = date.year();
int mhour = 0; //timeBox->hour();
int mminute = 0; //timeBox->minute();
snprintf(cmd2, sizeof(cmd2)-1, "date %.2d%.2d%.2d%.2d%.2d", mmonth, mday, mhour, mminute, (myear-2000));
time_changed=false;
date_changed=false;
return cmd2;
}
static void cb_Apply(Button*, void*) {
const char *pwd = password(_("This program requires administrator privileges.\nPlease enter your password below:"),0,"somebody");
printf ("Pwd: %s\n",pwd);
exit(0);
applyAll();
applyButton->deactivate();
// Little helper func
char* strdupcat(char* dest, char* src) {
if (!src) return dest;
if (!dest) return strdup(src);
dest = (char*)realloc(dest, strlen(dest)+strlen(src)+1);
dest = strcat(dest, src);
return dest;
}
static void cb_Close(Button*, void*) {
if (date_changed || time_changed) {
int answer = choice_alert(_("You have unsaved changes in this window!\nDo you want to close it anyway?"), 0, _("Go &Back"), _("&Discard Changes"));
if (answer != 2) return;
// Apply all changes
void apply_all() {
// Combine results into a single string so that we can run all those commands as root
char *cmd = 0;
if (format_changed) apply_format(timeFormat->value()); // don't need root for this
if (tz_changed) cmd = strdupcat(cmd, apply_timezone());
if (time_changed || date_changed) cmd = strdupcat (cmd, apply_date_time());
int ret = 0;
if (cmd) ret = edelib::run_program(cmd, /*wait=*/true , /*root=*/true );
if (ret != 0) {
edelib::MessageBox mb;
mb.set_theme_icon(MSGBOX_ICON_ERROR); // specified in edelib/MessageBox.h
mb.set_text(_("Error setting date or time."));
mb.add_button(_("&Close"));
mb.set_modal();
mb.run();
}
// Funcs should reset *_changed to false
else if (!time_changed && !format_changed && !tz_changed && !date_changed)
applyButton->deactivate();
}
// --------------------------------------------
// Synchronize
// --------------------------------------------
void synchronize(const char* server) {
char buffer[1024];
snprintf(buffer, 1024, "ntpdate %s", server);
fprintf(stderr, "run: %s\n", buffer);
long ret = edelib::run_program(buffer, /*wait=*/true, /*root=*/true);
if (ret == edelib::RUN_NOT_FOUND)
edelib::alert(_("Program <b>ntpdate</b> is required for time synchronization feature."));
else if (ret>=edelib::RUN_USER_CANCELED)
edelib::alert(_("Internal error: %d."), ret);
else if (ret != 0)
edelib::alert(_("ntpdate failed with the following return value: %d\nPlease consult ntpdate manual for details."), ret);
}
void populate_servers() {
char* tmp = strdup(time_servers);
char* server = strtok(tmp, "\n");
while (server) {
serverList->add(server);
server = strtok(NULL, "\n");
}
free(tmp);
serverList->value(0);
}
// --------------------------------------------
// Callbacks
// --------------------------------------------
static void cb_Apply(Fl_Button*, void*) {
apply_all();
}
static void cb_Close(Fl_Button*, void*) {
if (time_changed || format_changed || tz_changed || date_changed) {
edelib::MessageBox mb;
mb.set_theme_icon(MSGBOX_ICON_WARNING); // specified in edelib/MessageBox.h
mb.set_text(_("You have unsaved changes in this window!\nDo you want to close it anyway?"));
mb.add_button(_("Go &back"));
mb.add_button(_("&Discard changes"));
mb.set_modal();
if (mb.run() != 1) return;
}
exit(0);
}
static void cb_tzChanged(Widget*, void*) {
if (tz_changed) return;
tz_changed=true;
applyButton->activate();
}
static void cb_dateChanged(Widget*, void*) {
if (date_changed) return;
date_changed=true;
applyButton->activate();
}
static void cb_timeChanged(TimeBox* w, void*) {
static void cb_timeChanged(Fl_Widget*, void*) {
clk->value(timeBox->hour(),timeBox->minute(),timeBox->second());
if (time_changed) return;
time_changed=true;
applyButton->activate();
}
static void cb_timeFormatChanged(Fl_Widget*, void*) {
if (format_changed) return;
format_changed=true;
applyButton->activate();
}
static void cb_tzChanged(Fl_Widget*, void*) {
if (tz_changed) return;
tz_changed=true;
applyButton->activate();
}
static void cb_dateChanged(Fl_Widget*, void*) {
if (date_changed) return;
date_changed=true;
applyButton->activate();
}
static void cb_sync(Fl_Widget*, void*) {
char buffer[1024];
strncpy(buffer, serverList->value(), 1024);
buffer[1023]='\0';
// If part of string is in braces (), take just that
char* k1 = strchr(buffer,'(');
char* k2;
if (k1) k2 = strchr(k1, ')');
if (k1 && k2) {
int i=0;
for (char* p=k1+1; p!=k2; p++, i++)
buffer[i]=*p;
buffer[i]='\0';
}
synchronize(buffer);
}
static void cb_hour(Fl_Widget*, void*) {
int k = timeBox->hour()-1;
if (k==-1) k=23;
timeBox->hour(k);
timeBox->do_callback();
}
static void cb_hour1(Fl_Widget*, void*) {
int k = timeBox->hour()+1;
if (k==24) k=0;
timeBox->hour(k);
timeBox->do_callback();
}
static void cb_minute(Fl_Widget*, void*) {
int l = timeBox->minute()-1;
if (l==-1) {
l = 59;
int k = timeBox->hour()-1;
if (k==-1) k=23;
timeBox->hour(k);
}
timeBox->minute(l);
timeBox->do_callback();
}
static void cb_minute1(Fl_Widget*, void*) {
int l = timeBox->minute()+1;
if (l==60) {
l = 0;
int k = timeBox->hour()+1;
if (k==24) k=0;
timeBox->hour(k);
}
timeBox->minute(l);
timeBox->do_callback();
}
static void tick(void *v) {
if (time_changed) {
clk->value(clk->value()+1-3600);
} else {
clk->value(time(0));
if (timeBox) timeBox->epoch(time(0));
}
Fl::add_timeout(1.0, tick, v);
}
// --------------------------------------------
// Main window design
// --------------------------------------------
int main (int argc, char **argv) {
Window* w;
//fl_init_locale_support("etimedate", PREFIX"/share/locale");
{Window* o = timedateWindow = new Window(435, 300, _("Time and date"));
w = o;
o->begin();
{TabGroup* o = new TabGroup(10, 10, 415, 245);
o->begin();
{Group* o = new Group(0, 25, 415, 220, _("Time and date"));
o->begin();
{Group* o = new Group(10, 10, 220, 200);
o->box(DOWN_BOX);
o->color((Color)7);
o->begin();
{EDE_Calendar* o = calendar = new EDE_Calendar(10, 10, 200, 200);
//o->textfont(fonts+9); // TODO: what does this mean!?
o->color((Color)0xffffff00);
o->textcolor((Color)18);
o->labelsize(10);
o->textsize(14);
o->callback((Callback*)cb_dateChanged);
}
o->end();
}
{TimeBox* o = timeBox = new TimeBox(240, 10, 165, 200);
timeBox->callback((Callback*)cb_timeChanged);
}
int main(int argc, char **argv) {
fl_register_images();
edelib::IconTheme::init("crystalsvg");
FL_NORMAL_SIZE=12;
// Required by the new edelib::MessageBox class
edelib::themed_dialog_icons(MSGBOX_ICON_INFO, MSGBOX_ICON_WARNING, MSGBOX_ICON_QUESTION, MSGBOX_ICON_QUESTION, MSGBOX_ICON_PASSWORD);
time_changed = format_changed = tz_changed = date_changed = false;
{ timedateWindow = new Fl_Double_Window(415, 320, _("Time and date"));
{ Fl_Tabs* o = new Fl_Tabs(5, 5, 405, 270);
{ Fl_Group* o = new Fl_Group(5, 30, 405, 245, _("&Time/date"));
{ calendar = new EDE_Calendar(10, 35, 220, 202);
calendar->box(FL_DOWN_BOX);
calendar->color(FL_BACKGROUND2_COLOR);
calendar->callback(cb_dateChanged);
} // EDE_Calendar* calendar
{ clk = new Fl_Clock_Output(235, 35, 170, 177);
clk->box(FL_DOWN_BOX);
clk->color(FL_BACKGROUND2_COLOR);
tick(clk);
} // Fl_Clock* o
{ Fl_Repeat_Button* o = new Fl_Repeat_Button(235, 212, 25, 23);
o->callback(cb_hour);
o->label("@-1<<");
o->labelcolor(fl_darker(FL_BACKGROUND_COLOR));
o->selection_color(fl_lighter(FL_BACKGROUND_COLOR));
} // TimeBox* timeBox
{ Fl_Repeat_Button* o = new Fl_Repeat_Button(260, 212, 25, 23);
o->callback(cb_minute);
o->label("@-1<");
o->labelcolor(fl_darker(FL_BACKGROUND_COLOR));
o->selection_color(fl_lighter(FL_BACKGROUND_COLOR));
} // TimeBox* timeBox
{ timeBox = new Fl_Time_Input(285, 212, 70, 23);
timeBox->box(FL_DOWN_BOX);
timeBox->callback(cb_timeChanged);
timeBox->when(FL_WHEN_CHANGED);
timeBox->epoch(time(0));
} // TimeBox* timeBox
{ Fl_Repeat_Button* o = new Fl_Repeat_Button(355, 212, 25, 23);
o->callback(cb_minute1);
o->label("@-1>");
o->labelcolor(fl_darker(FL_BACKGROUND_COLOR));
o->selection_color(fl_lighter(FL_BACKGROUND_COLOR));
} // TimeBox* timeBox
{ Fl_Repeat_Button* o = new Fl_Repeat_Button(380, 212, 25, 23);
o->callback(cb_hour1);
o->label("@-1>>");
o->labelcolor(fl_darker(FL_BACKGROUND_COLOR));
o->selection_color(fl_lighter(FL_BACKGROUND_COLOR));
} // TimeBox* timeBox
{ timeFormat = new Fl_Choice(305, 240, 100, 25, _("Time format:"));
timeFormat->down_box(FL_BORDER_BOX);
timeFormat->menu(menu_timeFormat);
timeFormat->callback(cb_timeFormatChanged);
timeFormat->value(get_format());
} // Fl_Choice* timeFormat
o->end();
}
{Group* o = new Group(0, 25, 415, 220, _("Timezones"));
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 30, 405, 245, _("Time &zones"));
o->hide();
o->begin();
{Group* o = new Group(10, 10, 395, 170);
o->box(DOWN_BOX);
o->color((Color)0x7b00);
o->begin();
{InvisibleBox* o = new InvisibleBox(0, 0, 395, 170);
xpmImage* i = new xpmImage((const char**)world2_xpm);
// i->draw(Rectangle(10,5,350,160));
// i->over(Rectangle(0,0,i->w(),i->h()),*o);
o->image(i);
o->box(FLAT_BOX);
o->color((Color)0x8000);
}
{ Fl_Group* o = new Fl_Group(15, 40, 385, 190);
o->box(FL_DOWN_BOX);
o->color(FL_FOREGROUND_COLOR);
{ Fl_Box* o = new Fl_Box(25, 55, 350, 160);
o->box(FL_FLAT_BOX);
o->color(FL_FOREGROUND_COLOR);
o->image(image_world);
} // Fl_Box* o
o->end();
}
{InputBrowser* o = timeZonesList = new InputBrowser(10, 185, 395, 25); o->begin();
o->type(1); fillTimeZones();
getCurrentTimeZone();
o->end();
o->callback((Callback*)cb_tzChanged);
}
} // Fl_Group* o
{ timeZonesList = new Fl_Choice(120, 235, 280, 25, _("Time zone:"));
timeZonesList->down_box(FL_BORDER_BOX);
timeZonesList->callback(cb_tzChanged);
fill_timezones(get_current_timezone());
} // Fl_Choice* timeZonesList
o->end();
}
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 30, 405, 245, _("&Synchronize"));
o->hide();
{ Fl_Box* o = new Fl_Box(15, 55, 385, 50, _("Select the server with which you want to synhronize your system clock:"));
o->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT|FL_ALIGN_WRAP);
o->box(FL_NO_BOX);
} // Fl_Box* o
{ serverList = new Fl_Input_Choice(15, 115, 250, 25, "");
populate_servers();
} // Fl_Input_Choice* serverList
{ Fl_Button* o = new Fl_Button(55, 150, 90, 25, _("Synchronize"));
o->callback(cb_sync);
}
} // Fl_Group* o
o->end();
}
{Group* o = new Group(0, 265, 415, 33);
o->begin();
// {Button* o = new Button(154, 0, 90, 25, _("&OK"));
// o->callback((Callback*)cb_OK);
// }
{Button* o = applyButton = new Button(235, 0, 90, 25, _("&Apply"));
o->callback((Callback*)cb_Apply);
// o->tooltip(_("Set system time. ->Just root user!<-"));
o->deactivate();
}
{Button* o = new Button(335, 0, 90, 25, _("&Close"));
o->callback((Callback*)cb_Close);
}
} // Fl_Tabs* o
{ Fl_Group* o = new Fl_Group(5, 285, 405, 25);
{ applyButton = new Fl_Button(220, 285, 90, 25, _("&Apply"));
applyButton->tooltip(_("Set system time"));
applyButton->callback((Fl_Callback*)cb_Apply);
applyButton->deactivate();
} // Fl_Button* applyButton
{ Fl_Button* o = new Fl_Button(320, 285, 90, 25, _("&Close"));
o->callback((Fl_Callback*)cb_Close);
} // Fl_Button* o
o->end();
}
o->end();
}
w->show(argc, argv);
return run();
} // Fl_Group* o
timedateWindow->end();
} // Fl_Double_Window* timedateWindow
calendar->take_focus();
timedateWindow->show(argc, argv);
return Fl::run();
}

View File

@ -14,16 +14,31 @@
#ifndef etimedate_h
#define etimedate_h
#include "../edelib2/NLS.h"
#include <fltk/Window.h>
#include <fltk/Group.h>
#include <fltk/Button.h>
#include <fltk/TabGroup.h>
#include <fltk/InvisibleBox.h>
#include <fltk/InputBrowser.h>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Clock.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Input_Choice.H>
#include "EDE_Calendar.h"
//#include <fltk/Clock.h>
#include "TimeBox.h"
#include "Fl_Time_Input.h"
//#define Fl_Time_Input Fl_Input
extern EDE_Calendar *calendar;
extern Fl_Time_Input *timeBox;
extern Fl_Choice *timeFormat;
extern Fl_Choice *timeZonesList;
extern Fl_Menu_Item menu_timeFormat[];
extern Fl_Button *applyButton;
extern Fl_Input_Choice* serverList;
extern Fl_Clock_Output* clk;
#endif