/*
elmo - ELectronic Mail Operator
Copyright (C) 2002 bazyl
Copyright (C) 2003 rzyjontko
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; version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
----------------------------------------------------------------------
This module creates special window with date and time.
It's also using special structure to show elmo's work like downloading or
sending mails.
*/
/****************************************************************************
* IMPLEMENTATION HEADERS
****************************************************************************/
#include <stdarg.h>
#include <time.h>
#include <unistd.h>
#include "clock.h"
#include "ecurses.h"
#include "ask.h"
#include "color.h"
#include "interface.h"
#include "cmd.h"
#include "xmalloc.h"
#include "str.h"
/****************************************************************************
* IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
****************************************************************************/
struct job_list {
struct job_list *next;
str_t *desc;
int max;
int old;
int cur;
int index;
};
/****************************************************************************
* IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE DATA
****************************************************************************/
/* Clock window. */
static WINDOW *clock_win = NULL;
/* Color of the text displayed in the clock window. */
static chtype text_color;
/* Format string that controls, how is the time displayed. */
static char *clock_fmt = " %H:%M %a, %e %b ";
/* List of jobs to be displayed with progresses. */
static struct job_list *job_list = NULL;
/* This is used to disable clock. */
static int pause_me = 0;
/****************************************************************************
* INTERFACE DATA
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTIONS
****************************************************************************/
static void
draw_job (struct job_list *job, int y)
{
int height, width;
int cnt;
getmaxyx (clock_win, height, width);
if (y + 1 >= height)
return;
window_mvaddnstr (clock_win, y, 0, job->desc->str, width);
cnt = job->cur * width / job->max;
width -= cnt;
wmove (clock_win, y + 1, 0);
while (cnt--)
window_addch (clock_win, '#');
while (width--)
window_addch (clock_win, ' ');
}
static void
draw_jobs (struct job_list *list, int y)
{
if (list == NULL)
return;
draw_job (list, y);
draw_jobs (list->next, y + 2);
}
static void
display_jobs (void)
{
int height, width;
int i;
if (pause_me)
return;
getmaxyx (clock_win, height, width);
for (i = 1; i < height; i++){
wmove (clock_win, i, 0);
wclrtoeol (clock_win);
}
draw_jobs (job_list, 1);
}
static void
display_time (void)
{
static char buf[50];
static time_t oldtime = 0;
time_t curtime;
struct tm *tm;
int width, nothing;
cmd_state_t state = cmd_state_get (0);
if (state == CMD_READ_MAIL || state == CMD_HELP
|| state == CMD_ATTACH || state == CMD_SENDER
|| state == CMD_ABOOK_ADD)
return;
curtime = time (NULL);
if (curtime == oldtime)
return;
tm = localtime (& curtime);
oldtime = curtime;
getmaxyx (clock_win, nothing, width);
strftime (buf, sizeof (buf) - 1, clock_fmt, tm);
width -= window_mvaddnstr (clock_win, 0, 0, buf, width);
while (width--){
window_addch (clock_win, ' ');
}
}
static void
clock_hook (int nothing)
{
display_time ();
wnoutrefresh (clock_win);
}
static void
destroy_list (struct job_list *list)
{
if (list == NULL)
return;
destroy_list (list->next);
xfree (list);
}
static struct job_list *
list_find_index (struct job_list *list, int index)
{
if (list == NULL)
return NULL;
if (list->index == index)
return list;
return list_find_index (list->next, index);
}
static struct job_list *
list_remove_index (struct job_list *list, int index)
{
struct job_list *next;
if (list == NULL)
return NULL;
if (list->index == index){
next = list->next;
if (list->desc)
str_destroy (list->desc);
xfree (list);
return next;
}
list->next = list_remove_index (list->next, index);
return list;
}
/* This file is generated by interface.pl script from interface.desc,
and inc.in. */
static WINDOW *interface_init (void);
#include "clock.inc"
/****************************************************************************
* INTERFACE FUNCTIONS
****************************************************************************/
void
clock_init (void)
{
clock_win = interface_init ();
cmd_add_timeout_handler (clock_hook);
}
void
clock_free_resources (void)
{
destroy_list (job_list);
}
void
clock_pause (void)
{
pause_me = 1;
}
void
clock_resume (void)
{
pause_me = 0;
}
int
progress_setup (int max, const char *desc, ...)
{
va_list ap;
struct job_list *list;
if (max < 1)
return -1;
list = xmalloc (sizeof (struct job_list));
list->max = max;
list->old = 0;
list->cur = 0;
list->index = (job_list) ? job_list->index + 1 : 0;
list->next = job_list;
list->desc = str_create ();
va_start (ap, desc);
str_vsprintf (list->desc, desc, ap);
va_end (ap);
job_list = list;
display_jobs ();
wnoutrefresh (clock_win);
doupdate ();
return list->index;
}
void
progress_advance (int index, int count)
{
struct job_list *list = list_find_index (job_list, index);
if (list == NULL)
return;
list->cur += count;
if (list->cur > list->max)
list->cur = list->max;
display_jobs ();
wnoutrefresh (clock_win);
doupdate ();
}
void
progress_close (int index)
{
job_list = list_remove_index (job_list, index);
display_jobs ();
wnoutrefresh (clock_win);
doupdate ();
}
void
progress_change_desc (int index, const char *desc, ...)
{
va_list ap;
struct job_list *list = list_find_index (job_list, index);
if (list == NULL)
return;
if (list->desc)
str_clear (list->desc);
else
list->desc = str_create ();
va_start (ap, desc);
str_vsprintf (list->desc, desc, ap);
va_end (ap);
display_jobs ();
wnoutrefresh (clock_win);
doupdate ();
}
/****************************************************************************
* INTERFACE CLASS BODIES
****************************************************************************/
/****************************************************************************
*
* END MODULE clock.c
*
****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1