summaryrefslogtreecommitdiff
path: root/src/day.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/day.c')
-rwxr-xr-xsrc/day.c362
1 files changed, 362 insertions, 0 deletions
diff --git a/src/day.c b/src/day.c
new file mode 100755
index 0000000..8fd7981
--- /dev/null
+++ b/src/day.c
@@ -0,0 +1,362 @@
+/* $calcurse: day.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
+
+/*
+ * Calcurse - text-based organizer
+ * Copyright (c) 2004-2006 Frederic Culot
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Send your feedback or comments to : calcurse@culot.org
+ * Calcurse home page : http://culot.org/calcurse
+ *
+ */
+
+#include <ncurses.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <time.h>
+
+#include "i18n.h"
+#include "utils.h"
+#include "apoint.h"
+#include "event.h"
+#include "recur.h"
+#include "day.h"
+#include "vars.h"
+
+static struct day_item_s *day_items_ptr;
+static struct day_saved_item_s *day_saved_item = NULL;
+
+/*
+ * Store all of the items to be displayed for the selected day.
+ * Items are of four types: recursive events, normal events,
+ * recursive appointments and normal appointments.
+ * The items are stored in the linked list pointed by *day_items_ptr
+ * and the length of the new pad to write is returned.
+ * The number of events and appointments in the current day are also updated.
+ */
+int day_store_items(long date, int *pnb_events, int *pnb_apoints)
+{
+ int pad_length;
+ int nb_events, nb_recur_events;
+ int nb_apoints, nb_recur_apoints;
+
+ pad_length = nb_events = nb_apoints = 0;
+ nb_recur_events = nb_recur_apoints = 0;
+
+ if (day_items_ptr != 0)
+ day_free_list();
+ nb_recur_events = day_store_recur_events(date);
+ nb_events = day_store_events(date);
+ *pnb_events = nb_events;
+ nb_recur_apoints = day_store_recur_apoints(date);
+ nb_apoints = day_store_apoints(date);
+ *pnb_apoints = nb_apoints;
+ pad_length = nb_recur_events + nb_events + 1 +
+ 3*(nb_recur_apoints + nb_apoints);
+ *pnb_apoints += nb_recur_apoints;
+ *pnb_events += nb_recur_events;
+
+ return pad_length;
+}
+
+/* Free the current day linked list containing the events and appointments. */
+void day_free_list(void)
+{
+ struct day_item_s *p, *q;
+
+ for (p = day_items_ptr; p != 0; p = q) {
+ q = p->next;
+ free(p->mesg);
+ free(p);
+ }
+ day_items_ptr = NULL;
+}
+
+/*
+ * Store the recurrent events for the selected day in structure pointed
+ * by day_items_ptr. This is done by copying the recurrent events
+ * from the general structure pointed by recur_elist to the structure
+ * dedicated to the selected day.
+ * Returns the number of recurrent events for the selected day.
+ */
+int day_store_recur_events(long date)
+{
+ struct recur_event_s *j;
+ struct day_item_s *ptr;
+ int e_nb = 0;
+
+ for (j = recur_elist; j != 0; j = j->next) {
+ if (recur_item_inday(j->day, j->rpt->type, j->rpt->freq,
+ j->rpt->until, date)) {
+ e_nb++;
+ ptr = day_add_event(RECUR_EVNT, j->mesg, j->day, j->id);
+ }
+ }
+
+ return e_nb;
+}
+
+/*
+ * Store the events for the selected day in structure pointed
+ * by day_items_ptr. This is done by copying the events
+ * from the general structure pointed by eventlist to the structure
+ * dedicated to the selected day.
+ * Returns the number of events for the selected day.
+ */
+int day_store_events(long date)
+{
+ struct event_s *j;
+ struct day_item_s *ptr;
+ int e_nb = 0;
+
+ for (j = eventlist; j != 0; j = j->next) {
+ if (event_inday(j, date)) {
+ e_nb++;
+ ptr = day_add_event(EVNT, j->mesg, j->day, j->id);
+ }
+ }
+
+ return e_nb;
+}
+
+/*
+ * Store the recurrent apoints for the selected day in structure pointed
+ * by day_items_ptr. This is done by copying the appointments
+ * from the general structure pointed by recur_alist to the structure
+ * dedicated to the selected day.
+ * Returns the number of recurrent appointments for the selected day.
+ */
+int day_store_recur_apoints(long date)
+{
+ struct recur_apoint_s *j;
+ struct day_item_s *ptr;
+ int a_nb = 0;
+
+ for (j = recur_alist; j != 0; j = j->next) {
+ if (recur_item_inday(j->start, j->rpt->type, j->rpt->freq,
+ j->rpt->until, date)) {
+ a_nb++;
+ ptr = day_add_apoint(RECUR_APPT, j->mesg, j->start, j->dur);
+ }
+ }
+
+ return a_nb;
+}
+
+/*
+ * Store the apoints for the selected day in structure pointed
+ * by day_items_ptr. This is done by copying the appointments
+ * from the general structure pointed by apointlist to the structure
+ * dedicated to the selected day.
+ * Returns the number of appointments for the selected day.
+ */
+int day_store_apoints(long date)
+{
+ struct apoint_s *j;
+ struct day_item_s *ptr;
+ int a_nb = 0;
+
+ for (j = apointlist; j != 0; j = j->next) {
+ if (apoint_inday(j, date)) {
+ a_nb++;
+ ptr = day_add_apoint(APPT, j->mesg, j->start, j->dur);
+ }
+ }
+
+ return a_nb;
+}
+
+/* Add an event in the current day list */
+struct day_item_s *day_add_event(int type, char *mesg, long day, int id)
+{
+ struct day_item_s *o, **i;
+ o = (struct day_item_s *) malloc(sizeof(struct day_item_s));
+ o->mesg = (char *) malloc(strlen(mesg) + 1);
+ strcpy(o->mesg, mesg);
+ o->type = type;
+ o->appt_dur = 0;
+ o->start = day;
+ o->evnt_id = id;
+ i = &day_items_ptr;
+ for (;;) {
+ if (*i == 0 || (*i)->start > day) {
+ o->next = *i;
+ *i = o;
+ break;
+ }
+ i = &(*i)->next;
+ }
+ return o;
+}
+
+/* Add an appointment in the current day list. */
+struct day_item_s *day_add_apoint(int type, char *mesg, long start, long dur)
+{
+ struct day_item_s *o, **i;
+ o = (struct day_item_s *) malloc(sizeof(struct day_item_s));
+ o->mesg = (char *) malloc(strlen(mesg) + 1);
+ strcpy(o->mesg, mesg);
+ o->start = start;
+ o->appt_dur = dur;
+ o->type = type;
+ o->evnt_id = 0;
+ i = &day_items_ptr;
+ for (;;) {
+ if (*i == 0 || (*i)->start > start) {
+ o->next = *i;
+ *i = o;
+ break;
+ }
+ i = &(*i)->next;
+ }
+ return o;
+}
+
+/*
+ * Write the appointments and events for the selected day in a pad.
+ * An horizontal line is drawn between events and appointments, and the
+ * item selected by user is highlighted. This item is also saved inside
+ * structure (pointed by day_saved_item), to be later displayed in a
+ * popup window if requested.
+ */
+void day_write_pad(long date, int width, int length, int incolor, int colr)
+{
+ struct day_item_s *p;
+ int line, item_number, max_pos;
+ const int x_pos = 0;
+ bool draw_line = true;
+
+ line = item_number = 0;
+ max_pos = length;
+
+ /* Initialize the structure used to store highlited item. */
+ if (day_saved_item == NULL) {
+ day_saved_item = (struct day_saved_item_s *)
+ malloc(sizeof(struct day_saved_item_s));
+ day_saved_item->mesg = (char *) malloc(1);
+ }
+
+ for (p = day_items_ptr; p != 0; p = p->next) {
+
+ /* First print the events for current day. */
+ if (p->type < RECUR_APPT) {
+ item_number++;
+ if (item_number - incolor == 0) {
+ day_saved_item->type = p->type;
+ day_saved_item->mesg = (char *)
+ realloc(day_saved_item->mesg,
+ strlen(p->mesg) + 1);
+ day_saved_item->mesg = p->mesg;
+ }
+ display_item(apad->ptrwin, item_number - incolor, p->mesg,
+ width - 4, line, x_pos);
+ line++;
+ } else {
+ /* Draw a line between events and appointments. */
+ if (line > 0 && draw_line){
+ wmove(apad->ptrwin, line, x_pos);
+ whline(apad->ptrwin, 0, width);
+ draw_line = false;
+ }
+
+ /* Last print the appointments for current day. */
+ item_number++;
+ if (item_number - incolor == 0) {
+ day_saved_item->type = p->type;
+ day_saved_item->mesg = (char *)
+ realloc(day_saved_item->mesg,
+ strlen(p->mesg) + 1);
+ day_saved_item->mesg = p->mesg;
+ apoint_sec2str(day_item_s2apoint_s(p),
+ p->type, date,
+ day_saved_item->start,
+ day_saved_item->end);
+ }
+ display_item_date(apad->ptrwin, item_number - incolor,
+ day_item_s2apoint_s(p), p->type, date,
+ line + 1, x_pos);
+ display_item(apad->ptrwin, item_number - incolor, p->mesg,
+ width - 6, line + 2, x_pos + 2);
+ line = line + 3;
+ }
+ }
+}
+
+/* Returns a structure of type apoint_s given a structure of type day_item_s */
+struct apoint_s *day_item_s2apoint_s(struct day_item_s *p)
+{
+ struct apoint_s *a;
+
+ a = (struct apoint_s *) malloc(sizeof(struct apoint_s));
+ a->mesg = (char *) malloc(strlen(p->mesg) + 1);
+ a->start = p->start;
+ a->dur = p->appt_dur;
+ a->mesg = p->mesg;
+ return a;
+}
+
+/* Display an item inside a popup window. */
+void day_popup_item(void)
+{
+ char *error =
+ _("FATAL ERROR in day_popup_item: unknown item type\n");
+
+ if (day_saved_item->type == EVNT || day_saved_item->type == RECUR_EVNT)
+ item_in_popup(NULL, NULL, day_saved_item->mesg, _("Event :"));
+ else if (day_saved_item->type == APPT ||
+ day_saved_item->type == RECUR_APPT)
+ item_in_popup(day_saved_item->start, day_saved_item->end,
+ day_saved_item->mesg, _("Appointment :"));
+ else { /* NOT REACHED */
+ fputs(error, stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+/*
+ * Need to know if there is an item for the current selected day inside
+ * calendar. This is used to put the correct colors inside calendar panel.
+ */
+ int day_check_if_item(int year, int month, int day) {
+ struct recur_event_s *re;
+ struct recur_apoint_s *ra;
+ struct event_s *e;
+ struct apoint_s *a;
+ const long date = date2sec(year, month, day, 0, 0);
+
+ for (re = recur_elist; re != 0; re = re->next)
+ if (recur_item_inday(re->day, re->rpt->type, re->rpt->freq,
+ re->rpt->until, date))
+ return 1;
+
+ for (ra = recur_alist; ra != 0; ra = ra->next)
+ if (recur_item_inday(ra->start, ra->rpt->type, ra->rpt->freq,
+ ra->rpt->until, date))
+ return 1;
+
+ for (e = eventlist; e != 0; e = e->next)
+ if (event_inday(e, date))
+ return 1;
+
+ for (a = apointlist; a != 0; a = a->next)
+ if (apoint_inday(a, date))
+ return 1;
+
+ return 0;
+}