#pragma implementation #include #include #include #include #include #include #include #include "../framework/framework.h" #include "agenda.h" #include "agenda.m" #include #include using namespace std; static const char *calendar_getfontlarge() { return guiid_setfont (20,GFONT_ID_MODERN,GFONT_STYLE_DEFAULT,GFONT_WEIGHT_BOLD,false); } static const char *calendar_getfontmedium() { return guiid_setfont (12,GFONT_ID_MODERN,GFONT_STYLE_DEFAULT,GFONT_WEIGHT_BOLD,false); } #define _TLMP_agenda_drawmonth struct _F_agenda_drawmonth{ #define _F_agenda_drawmonth_title(nom) void nom title(DIALOG &dia, int year, int month, const char *mname) virtual _F_agenda_drawmonth_title( )=0; #define _F_agenda_drawmonth_cell(nom) void nom cell(DIALOG &dia, int day, int weekday, int x, int y, const char *tasks, bool focus) virtual _F_agenda_drawmonth_cell( )=0; }; static time_t agenda_mktime (int year, int month, int day) { struct tm t; memset (&t,0,sizeof(t)); t.tm_year = year-1900; t.tm_mon = month-1; t.tm_mday = day; t.tm_isdst = 0; return mktime (&t); } static void agenda_infomonth (int year, int month, int &nbday, int &first) { time_t ti = agenda_mktime (year,month,1); // Compute next month int nextmonth = month+1; int nextyear = year; if (nextmonth == 13){ nextmonth = 1; nextyear++; } time_t nextti = agenda_mktime (nextyear,nextmonth,1); nbday = (nextti-ti)/(24*60*60); struct tm *t = gmtime (&ti); first = t->tm_wday; } PUBLIC CALENDAR_CTX::CALENDAR_CTX() { goto_today(); } PUBLIC CALENDAR_CTX::CALENDAR_CTX(CALENDAR_CTX &c) { set (c); } PUBLIC void CALENDAR_CTX::set (CALENDAR_CTX &c) { year = c.year; month = c.month; day = c.day; team.setfrom (c.team); } PUBLIC void CALENDAR_CTX::goto_today() { time_t ti = time(NULL); struct tm *t = localtime (&ti); year = t->tm_year + 1900; month = t->tm_mon + 1; day = t->tm_mday; } PUBLIC void CALENDAR_CTX::add (int days, int months, int years) { year += years; month += months; while (month > 12){ year++; month-=12; } while (month < 1){ year--; month+=12; } day += days; while (day < 1){ month--; int nbday,first; agenda_infomonth (year,month,nbday,first); day = nbday + day; } while (1){ int nbday,first; agenda_infomonth (year,month,nbday,first); if (day <= nbday) break; month++; day -= nbday; } } PUBLIC void CALENDAR_CTX::setday(int _day) { day = _day; } PUBLIC void CALENDAR_CTX::setmonth(int _month) { month = _month; } PUBLIC void CALENDAR_CTX::setteam(const char *s) { team.setfrom (s); } PUBLIC int CALENDAR_CTX::getyear() const { return year; } PUBLIC int CALENDAR_CTX::getmonth() const { return month; } PUBLIC int CALENDAR_CTX::getday() const { return day; } PUBLIC const char *CALENDAR_CTX::getteam() const { return team.get(); } /* Return the weekday (0,6) of the selected date */ PUBLIC int CALENDAR_CTX::getweekday() const { time_t ti = agenda_mktime (year,month,day); struct tm *t = gmtime (&ti); return t->tm_wday; } PUBLIC void CALENDAR_CTX::sendmessage() { dialog_sendmessage (changeday); } PUBLIC void CALENDAR_CTX::forceredraw() { dialog_sendmessage (redraw); } /* Return true if the selected date was changed or a redraw command was sent (because some preferences were changed) */ PUBLIC bool CALENDAR_CTX::is_change() { return dialog_testmessage(changeday) || must_redraw(); } /* Return true if a redraw is needed */ PUBLIC bool CALENDAR_CTX::must_redraw() { return dialog_testmessage(redraw); } PUBLIC void CALENDAR_CTX::waitfor (DIALOG &dia) { dia.waitfor (changeday); dia.waitfor (redraw); } static void agenda_drawmonth( _F_agenda_drawmonth &c, int year, int month, int focusday, const char *team, DIALOG &dia, int width, // Width and height of one cell int height, int head) // Height of the head { int nbday,first; agenda_infomonth (year,month,nbday,first); int total_width = 7*width+1; int total_height = 6*height + head + 1; static const char *tbmonth[]={ MSG_U(I_JANUARY,"January"), MSG_U(I_FEBRUARY,"February"), MSG_U(I_MARCH,"March"), MSG_U(I_APRIL,"April"), MSG_U(I_MAY,"May"), MSG_U(I_JUNE,"June"), MSG_U(I_JULY,"July"), MSG_U(I_AUGUST,"August"), MSG_U(I_SEPTEMBER,"September"), MSG_U(I_OCTOBER,"October"), MSG_U(I_NOVEMBER,"November"), MSG_U(I_DECEMBER,"December"), }; c.title (dia,year,month,tbmonth[month-1]); dia.gui_passthrough (P_Form,"f $w=%d h=%d",total_width,total_height); const char *bwhite = guiid_setbrush ("white"); const char *pwhite = guiid_setpen ("white"); const char *fwhite = guiid_setfont (head==20 ? 12 : 6,GFONT_ID_DEFAULT,GFONT_STYLE_DEFAULT,GFONT_WEIGHT_DEFAULT,false); const char *dcwhite = guiid_setdc (fwhite,pwhite,bwhite); dia.gui_passthrough (P_Clear,"$dc=%s",dcwhite); { const char *blue = guiid_setbrush ("blue"); const char *dc = guiid_setdc (NULL,NULL,blue); dia.gui_passthrough (P_Fillrect,"0 0 %d %d $dc=%s",total_width,head,dc); } for (int i=0; i<7; i++){ static const char *tb[]={ MSG_U(I_SUNDAY,"Sun"), MSG_U(I_MONDAY,"Mon"), MSG_U(I_TUESDAY,"Tue"), MSG_U(I_WEDNESDAY,"Wed"), MSG_U(I_THURSDAY,"Thu"), MSG_U(I_FRIDAY,"Fri"), MSG_U(I_SATURDAY,"Sat") }; dia.gui_passthrough (P_Drawtext,"%d %d %s $dc=%s" ,i*width+width/4,head/3,tb[i],dcwhite); } // Draw vertical separators for (int i=0; i<8; i++){ int x = i*width; dia.gui_passthrough (P_Drawline,"%d %d %d %d",x,head,x,total_height); } dia.gui_passthrough (P_Drawline,"%d %d %d %d",0,0,total_width,0); dia.gui_passthrough (P_Drawline,"%d %d %d %d",0,head,total_width,head); int day = -first; for (int i=0; i<6; i++){ int y = i*height+head; dia.gui_passthrough (P_Drawline,"%d %d %d %d",0,y,total_width,y); for (int j=0; j<7; j++){ if (day >= 0 && day < nbday){ int x = j*width; int mday = day+1; char line[10]; tasks_getshort (year,month,mday,team,line); c.cell (dia,mday,j,x,y,line,mday==focusday); } day++; } } dia.gui_passthrough (P_Drawline,"0 %d %d %d",total_height-1,total_width,total_height-1); dia.gui_end(); } #define _TLMP_agenda_editmonth struct _F_agenda_editmonth{ #define _F_agenda_editmonth_select(nom) void nom select(int day, int button, CALENDAR_CTX &ctx, bool &must_redraw) virtual _F_agenda_editmonth_select( )=0; #define _F_agenda_editmonth_change(nom) void nom change(CALENDAR_CTX &ctx) virtual _F_agenda_editmonth_change( ); }; void _F_agenda_editmonth::change(CALENDAR_CTX &){} /* Map a click in a calendar to a day of the month. Return -1 if this was an empty slot. */ static int agenda_map2day ( int year, int month, int cellwidth, int cellheight, int headsize, int &button) { int ret = -1; UISTATE st; diajava_lastmousestate(st); int cx = st.x/cellwidth; int cy = (st.y-headsize)/cellheight; button = 1; if (st.middleb) button = 2; if (st.rightb) button = 3; int nbday,first; agenda_infomonth (year,month,nbday,first); int day = cy * 7 + cx - first; if (day >= 0 && day < nbday){ ret = day + 1; } return ret; } /* Draw a red rectangle outline */ static void agenda_redrect (DIALOG &dia, int x, int y, int w, int h) { const char *pred = guiid_setpen ("red"); const char *dcred = guiid_setdc (NULL,pred,NULL); dia.gui_passthrough (P_Drawrect,"%d %d %d %d $dc=%s",x+1,y+1 ,x+w-1,y+h-1,dcred); } /* Draw a filled yellow rectangle */ static void agenda_yellowrect (DIALOG &dia, int x, int y, int w, int h) { const char *yellow = guiid_setbrush ("yellow"); const char *dc = guiid_setdc (NULL,NULL,yellow); dia.gui_passthrough (P_Fillrect,"%d %d %d %d $dc=%s",x,y,w,h,dc); } static void agenda_editmonth( _F_agenda_editmonth &c, CALENDAR_CTX &ctx, FRAMEWORK_INFO &info) { glocal PRIVATE_MESSAGE click; glocal PRIVATE_MESSAGE leftmonth,leftyear; glocal PRIVATE_MESSAGE rightmonth,rightyear; DIALOG dia; info.msgs.waitfor (dia); int nof = 0; ctx.waitfor (dia); while (1){ if (dia.getnb()==0){ (ctx.getyear(),ctx.getmonth(),ctx.getday() ,ctx.getteam(),dia,20,20,10); const char *font = calendar_getfontmedium(); const char *black = guiid_setbrush ("black"); const char *dc = guiid_setdc (font,NULL,black); dia.gui_passthrough (P_Form,"top $w=140 h=20"); dia.gui_passthrough (P_Fillpolygon,"3 8 13 3 13 13 $dc=%s",dc); dia.new_inputgrid (3,3,10,10,1,1,glocal.leftmonth); dia.gui_passthrough (P_Drawtext,"15 3 %s $dc=%s",mname,dc); dia.gui_passthrough (P_Fillpolygon,"65 3 75 8 65 13 $dc=%s",dc); dia.new_inputgrid (65,3,10,10,1,1,glocal.rightmonth); dia.gui_passthrough (P_Fillpolygon,"80 8 90 3 90 13"); dia.new_inputgrid (80,3,10,10,1,1,glocal.leftyear); dia.gui_passthrough (P_Drawtext,"95 3 %04d $dc=%s",year,dc); dia.gui_passthrough (P_Fillpolygon,"127 3 137 8 127 13"); dia.new_inputgrid (127,3,10,10,1,1,glocal.rightyear); dia.gui_end(); dia.newline(); if (day == 1){ dia.new_inputgrid (0,0,20,20,7,6,glocal.click); } const char *font = guiid_setfont (10,GFONT_ID_DEFAULT,GFONT_STYLE_DEFAULT ,(tasks[0] != '\0' ? GFONT_WEIGHT_BOLD : GFONT_WEIGHT_DEFAULT) ,false); const char *dc = guiid_setdc (font,NULL,NULL); if (focus) agenda_redrect (dia,x,y,20,20); dia.gui_passthrough (P_Drawtext,"%d %d %d $dc=%s",x+2,y+2,day,dc); // Without the following instruction, the program core dump // Very weird. Compiler bug ? //int a = 2; } MENU_STATUS code = dia.edit ("","",help_nil,nof,0); if (code == MENU_MESSAGE){ if (info.c->must_end(info.msgs)){ break; }else if (ctx.is_change()){ dia.remove_all(); c.change(ctx); }else if (dialog_testmessage(glocal.click)){ int button; int day = agenda_map2day (ctx.getyear(),ctx.getmonth(),20,20,10,button); if (day != -1){ bool must_redraw = false; c.select (day,button,ctx,must_redraw); if (must_redraw) dia.remove_all(); } }else{ if (dialog_testmessage(glocal.leftmonth)){ ctx.add (0,-1,0); }else if (dialog_testmessage(glocal.rightmonth)){ ctx.add (0,1,0); }else if (dialog_testmessage(glocal.leftyear)){ ctx.add (0,0,-1); }else if (dialog_testmessage(glocal.rightyear)){ ctx.add (0,0,1); } ctx.sendmessage(); dia.remove_all(); c.change(ctx); } } } } /* Return -1 if the framework must end */ static int agenda_editday ( CALENDAR_CTX &ctx, FRAMEWORK_INFO &info, DIALOG_TYPE type) { int ret = 0; DIALOG_RECORDS dia; dia.settype (type); dia.newf_head ("",MSG_U(H_ONEDAY,"Hour\tTasks")); SSTRING tb[48]; tasks_getday (ctx.getyear(),ctx.getmonth(),ctx.getday(),ctx.getteam() ,tb); for (int i=0; i<48; i++){ char tmp[10],tmp2[40]; sprintf (tmp,"%02d:%02d",i/2,(i&1)?30:0); sprintf (tmp2,"%-39s",tb[i].get()); dia.new_menuitem (tmp,tmp2); } info.msgs.waitfor (dia); int nof = 16; string title = string_f("%04d/%02d/%02d",ctx.getyear(),ctx.getmonth(),ctx.getday()); while (1){ MENU_STATUS code = dia.editmenu (title.c_str(),"",help_nil,nof,0); if (code == MENU_QUIT || code == MENU_ESCAPE){ break; }else if (code == MENU_MESSAGE){ if (info.c->must_end(info.msgs)){ ret = -1; break; } } } return ret; } static bool agenda_daypopup( CALENDAR_CTX &ctx, FRAMEWORK_INFO &info, int month, int day, int button) { bool ret = false; CALENDAR_CTX nctx(ctx); nctx.setmonth (month); nctx.setday (day); if (button == 1){ if (agenda_editday (nctx,info,DIATYPE_POPUP)==-1){ ret = true; } }else{ DIALOG_MENUPOPUP pop; pop.new_menuitem ("",MSG_U(M_JUMPTO,"Jump to")); pop.new_menuitem ("",MSG_U(M_EDITDAY,"Edit this day")); int nof; if (pop.editmenu("","",help_nil,nof,0)==MENU_OK){ if (nof == 0){ ctx.set (nctx); ctx.sendmessage(); }else if (nof == 1){ if (agenda_editday (nctx,info,DIATYPE_POPUP)==-1){ ret = true; } } } } return ret; } static void agenda_byday(CALENDAR_CTX &ctx, FRAMEWORK_INFO &info) { glocal CALENDAR_CTX *ctx = &ctx; glocal FRAMEWORK_INFO *info = &info; (info); layout_area1(true); // We can display several days at once layout_area2(false); layout_newline(); layout_area3(false); layout_dispolast (GUI_H_LEFT,2,GUI_V_CENTER,1); // Task list for a day agenda_editday (*glocal.ctx,info,DIATYPE_STD); // Calendar glocal _F_FRAMEWORK *frame = this; (*glocal.ctx,info); if (button == 1){ ctx.setday (day); glocal.frame->newdocument(); }else if (button == 3){ agenda_daypopup(ctx,*glocal.info,ctx.getmonth(),day,button); must_redraw = true; } frame.newdocument(); frame.loop(); } static void agenda_editweek ( CALENDAR_CTX &ctx, FRAMEWORK_INFO &info, int firstday, int lastday) { DIALOG dia; info.msgs.waitfor(dia); ctx.waitfor (dia); PRIVATE_MESSAGE click[7]; const char *bwhite = guiid_setbrush ("white"); const char *dc = guiid_setdc (NULL,NULL,bwhite); CALENDAR_CTX tbctx[7]; int nof = 0; while (1){ if (dia.getnb()==0){ int weekday = ctx.getweekday(); for (int i=firstday; i<=lastday; i++){ static const char *tbday[]={ MSG_U(I_DAYSUNDAY,"Sunday"), MSG_U(I_DAYMONDAY,"Monday"), MSG_U(I_DAYTUESDAY,"Tuesday"), MSG_U(I_DAYWEDNESDAY,"Wednesday"), MSG_U(I_DAYTHURSDAY,"Thursday"), MSG_U(I_DAYFRIDAY,"Friday"), MSG_U(I_DAYSATURDAY,"Saturday") }; CALENDAR_CTX *cx = tbctx + i; cx->set (ctx); cx->add (i-weekday,0,0); dia.gui_passthrough (P_Form,"f%d $w=101 h=76",i); dia.gui_passthrough (P_Clear,"$dc=%s",dc); dia.gui_passthrough (P_Drawrect,"0 0 100 75"); dia.gui_passthrough (P_Drawtext,"3 3 %s",tbday[i]); dia.gui_passthrough (P_Drawtext,"85 3 %02d",tbctx[i].getday()); SSTRINGS tb; tasks_gettitles (cx->getyear(),cx->getmonth(),cx->getday() ,cx->getteam(),tb); for (int j=0; j<5 && jget(),tmp)); } dia.new_inputgrid (0,0,100,75,1,1,click[i]); dia.gui_end(); } } MENU_STATUS code = dia.edit("","",help_nil,nof,0); if (code == MENU_MESSAGE){ if (info.c->must_end(info.msgs)){ break; }else if (ctx.is_change()){ dia.remove_all(); }else if (ctx.must_redraw()){ dia.remove_all(); }else{ for (int i=firstday; i<=lastday; i++){ if (dialog_testmessage(click[i])){ agenda_editday (tbctx[i],info,DIATYPE_POPUP); break; } } } } } } static void agenda_byweek(CALENDAR_CTX &ctx, FRAMEWORK_INFO &info) { glocal CALENDAR_CTX weekctx; glocal CALENDAR_CTX *ctx = &ctx; glocal.weekctx.set (ctx); (info); layout_area1(false); layout_dispolast (GUI_H_LEFT,2,GUI_V_CENTER,1); layout_newline(); layout_area2(false); layout_area3(false); // First sunday,monday,tuesday agenda_editweek (glocal.weekctx,info,0,3); // wednesday,thursday agenda_editweek (glocal.weekctx,info,4,6); // Calendar (*glocal.ctx,info); // We select a different week glocal.weekctx.setday (day); glocal.weekctx.sendmessage(); glocal.weekctx.set (ctx); glocal.weekctx.sendmessage(); frame.loop(); } static void agenda_bymonth(CALENDAR_CTX &ctx, FRAMEWORK_INFO &info) { glocal PRIVATE_MESSAGE click; glocal int w = 70; glocal int h = 40; DIALOG dia; info.msgs.waitfor (dia); ctx.waitfor (dia); int nof = 0; while (1){ if (dia.getnb()==0){ (ctx.getyear(),ctx.getmonth(),ctx.getday() ,ctx.getteam(),dia,glocal.w,glocal.h,20); const char *font = calendar_getfontlarge(); const char *dc = guiid_setdc (font,NULL,NULL); dia.gui_passthrough (P_Label,"\"%s %04d\" $dc=%s" ,mname,year,dc); dia.gui_dispolast (GUI_H_CENTER,1,GUI_V_CENTER,1); dia.newline(); if (day == 1){ dia.new_inputgrid (0,0,glocal.w,glocal.h,7,6,glocal.click); } if (focus) agenda_redrect (dia,x,y,glocal.w,glocal.h); dia.gui_passthrough (P_Drawtext,"%d %d %d",x+3,y+3,day); if (tasks[0] != '\0'){ char tmp[1000]; dia.gui_passthrough (P_Drawtext,"%d %d %s",x+3,y+20 ,diagui_quote(tasks,tmp)); } } MENU_STATUS code = dia.edit ("","",help_nil,nof,0); if (code == MENU_MESSAGE){ if (info.c->must_end(info.msgs)){ break; }else if (ctx.is_change()){ dia.remove_all(); }else if (dialog_testmessage(glocal.click)){ int button; int day = agenda_map2day (ctx.getyear(),ctx.getmonth(),glocal.w,glocal.h,20,button); if (day != -1){ if (agenda_daypopup(ctx,info,ctx.getmonth(),day,button)){ break; } dia.remove_all(); } } } } } static void agenda_byyear(CALENDAR_CTX &ctx, FRAMEWORK_INFO &info) { glocal PRIVATE_MESSAGE *click; DIALOG dia; ctx.waitfor (dia); dia.set_formparms ("vtrigger=300"); info.msgs.waitfor (dia); int nof = 0; int year = ctx.getyear(); PRIVATE_MESSAGE clicks[13]; bool done = false; while (!done){ if (dia.getnb()==0){ year = ctx.getyear(); { const char *font = calendar_getfontlarge(); const char *dc = guiid_setdc (font,NULL,NULL); dia.gui_label ("%04d $dc=%s",ctx.getyear(),dc); dia.gui_dispolast (GUI_H_CENTER,3,GUI_V_CENTER,1); dia.newline(); } for (int i=1; i<=12; i++){ glocal.click = clicks+i; if (i != 1 && (i%3)==1) dia.newline(); dia.gui_passthrough (P_Form,"f%d",i); (year,i ,i==ctx.getmonth() ? ctx.getday() : -1 ,ctx.getteam(),dia,20,20,10); dia.gui_label(mname); dia.gui_dispolast (GUI_H_CENTER,1,GUI_V_CENTER,1); dia.newline(); if (day == 1){ dia.new_inputgrid (0,0,20,20,7,6,*glocal.click); } if (tasks[0] != '\0'){ agenda_yellowrect (dia,x,y,20,20); } if (focus) agenda_redrect (dia,x,y,20,20); dia.gui_passthrough (P_Drawtext,"%d %d %d",x+2,y+2,day); dia.gui_end(); } } MENU_STATUS code = dia.edit ("","",help_nil,nof,0); if (code == MENU_MESSAGE){ if (info.c->must_end(info.msgs)){ break; }else if (ctx.is_change()){ if (year != ctx.getyear()){ dia.remove_all(); } }else{ for (int i=1; i<=12; i++){ if (dialog_testmessage(clicks[i])){ int button; int day = agenda_map2day (ctx.getyear(),i,20,20,10,button); if (day != -1){ done = agenda_daypopup(ctx,info,i,day,button); } break; } } } } } } static void agenda_mainwindow(); static void agenda_mainwindow() { glocal PRIVATE_MESSAGE msg; glocal CALENDAR_CTX ctx; (MSG_U(T_AGENDA,"Agenda 1.0"),glocal.msg); layout_book(); layout_page (MSG_U(I_BYDAY,"By day")); layout_area1(false); layout_end(); layout_page (MSG_U(I_BYWEEK,"By week")); layout_area2(false); layout_end(); layout_page (MSG_U(I_BYMONTH,"By month")); layout_area3(false); layout_end(); layout_page (MSG_U(I_BYYEAR,"By year")); layout_area4(false); layout_end(); layout_end(); ("agenda",TLMPWORK_VERSION,TLMPWORK_RELEASE); printf (MSG_U(I_ABOUT,"Experimental TLMP agenda\n")); printf ("Jacques Gélinas jack@solucorp.qc.ca\n"); setgpl(); printf ("http://www.solucorp.qc.ca/tlmp\n"); topmenu (MSG_U(M_FILE,"File")); menuentry (1,MSG_U(M_NEWWINDOW,"New window")); menuentry (2,MSG_U(M_SAVE,"Save")); menuentry (2,MSG_U(M_SAVEAS,"Save as")); menuentry (99,MSG_U(M_QUIT,"Quit")); endmenu(); topmenu (MSG_U(M_VIEW,"View")); menuentry (801,MSG_U(M_PERSONAL,"Personal agenda")); menuentry (802,MSG_U(M_TEAM,"Team agenda")); menuentry (803,MSG_U(M_DEFTEAM,"Define a team")); endmenu(); topmenu (MSG_U(M_OPTIONS,"Options")); menuentry (901,MSG_U(M_PREFER,"Preferences")); endmenu(); helpmenu(); endmenu(); if (id == 1){ agenda_mainwindow(); }else if (id == 99){ end(); }else if (id == 801){ glocal.ctx.setteam(""); glocal.ctx.forceredraw(); }else if (id == 802){ team_select (glocal.ctx); }else if (id == 803){ team_define (); }else if (id == 901){ pref_edit(); } newbutton (1,MSG_U(B_BEFORE,"Before"),MSG_R(B_BEFORE),MSG_U(I_BEFORE,"Select yesterday")); newbutton (2,MSG_U(B_TODAY,"Today"),MSG_R(B_TODAY),MSG_U(I_TODAY,"Select today")); newbutton (3,MSG_U(B_NEXT,"After"),MSG_R(B_NEXT),MSG_U(I_NEXT,"Select tomorrow")); if (id == 1){ glocal.ctx.add(0,-1,0); }else if (id == 2){ glocal.ctx.goto_today(); }else if (id == 3){ glocal.ctx.add (0,1,0); } glocal.ctx.sendmessage(); agenda_byday(glocal.ctx,info); agenda_byweek(glocal.ctx,info); agenda_bymonth(glocal.ctx,info); agenda_byyear(glocal.ctx,info); frame.loop(); } int main (int argc, char *argv[]) { uithread_init (50); int ret = (argc, argv,"tlmpwork"); xconf_error(msg); char buf[1000]; snprintf (buf,sizeof(buf)-1,MSG_U(N_USAGE,"agenda version %d.%d\n\nUsage: tledit fichier") ,TLMPWORK_VERSION,TLMPWORK_RELEASE); xconf_notice (buf); usage(); return -1; agenda_mainwindow(); return 0; return ret; }