Logo Search packages:      
Sourcecode: pal version File versions  Download package

add.c

/* pal
 *
 * Copyright (C) 2004, Scott Kuhl
 *
 * 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
 *
 */

#include <stdio.h>
#include <readline/readline.h>

#include "main.h"
#include "output.h"
#include "event.h"
#include "rl.h"


/* This only works when 'number' is between 1 and 10 inclusive */
void pal_add_suffix(gint number, gchar* suffix, gint buf_size)
{
    number = number % 10;
    switch(number)
    {
      case 1:  snprintf(suffix, buf_size, "%s", _("1st")); return;
      case 2:  snprintf(suffix, buf_size, "%s", _("2nd")); return;
      case 3:  snprintf(suffix, buf_size, "%s", _("3rd")); return;
      case 4:  snprintf(suffix, buf_size, "%s", _("4th")); return;
      case 5:  snprintf(suffix, buf_size, "%s", _("5th")); return;
      case 6:  snprintf(suffix, buf_size, "%s", _("6th")); return;
      case 7:  snprintf(suffix, buf_size, "%s", _("7th")); return;
      case 8:  snprintf(suffix, buf_size, "%s", _("8th")); return;
      case 9:  snprintf(suffix, buf_size, "%s", _("9th")); return;
      case 10: snprintf(suffix, buf_size, "%s", _("10th")); return;

      default: *suffix = '\0'; return;
    }

}

gchar* pal_add_get_range()
{
    g_print("\n");
    pal_output_fg(BRIGHT, GREEN, "> ");
    g_print(_("Does this event have starting and ending dates? "));

    if(pal_rl_get_y_n(_("[y/n]: ")))
    {
      GDate* d1 = NULL;
      GDate* d2 = NULL;
      gchar buf[1024];
      gchar* s;
      gboolean bad_range = FALSE;

      do
      {
          /* set back to null for loop to work properly */
          d1 = NULL;
          d2 = NULL;

          bad_range = FALSE;

          while(d1 == NULL)
          {
            s = pal_rl_get_line(_("Start date: "));
            d1 = get_query_date(s, FALSE);
            g_free(s);
          }

          while(d2 == NULL)
          {
            s = pal_rl_get_line(_("End date: "));
            d2 = get_query_date(s, FALSE);
            g_free(s);
          }

          if(g_date_days_between(d1,d2) < 1)
          {
            pal_output_error(_("ERROR: The end date is the same as or before the start date.\n"));
            d1 = NULL;
            d2 = NULL;
            bad_range = TRUE;
            continue;
          }

          g_date_strftime(buf, 1024, "%a %e %b %Y", d1);
          g_print("%s%s\n", _("Start date: "), buf);
          g_date_strftime(buf, 1024, "%a %e %b %Y", d2);
          g_print("%s%s\n", _("End date: "), buf);

          snprintf(buf, 1024, "%s ", _("Accept? [y/n]:"));

      } while(bad_range || !pal_rl_get_y_n(buf));

      s = g_strconcat(":", get_key(d1), ":", get_key(d2), NULL);
      g_date_free(d1);
      g_date_free(d2);
      return s;

    }
    else return g_strdup("");

}


/* reuturned string should be freed */
gchar* pal_add_get_recur(GDate* date)
{
    gchar* key;
    gchar* s;

    g_print("\n");
    pal_output_fg(BRIGHT, GREEN, "> ");
    g_print(_("Is the event recurring? "));

    key = get_key(date);

    if(pal_rl_get_y_n(_("[y/n]: ")))
    {
      gchar* selection;
      gchar buf[128];
      gchar buf2[128];
      gchar suffix[16];
      gboolean last_weekday = FALSE;

      pal_output_fg(BRIGHT, GREEN, "> ");
      g_print(_("Select how often this event occurs\n"));

      pal_output_attr(BRIGHT, " 1 ");
      g_print(_("- Daily\n"));

      pal_output_attr(BRIGHT, " 2 ");
      g_date_strftime(buf, 128, "%A", date);
      g_print(_("- Weekly: Every %s\n"), buf);

      pal_output_attr(BRIGHT, " 3 ");
      g_print(_("- Monthly: Day %d of every month\n"),
            g_date_get_day(date));

      pal_output_attr(BRIGHT, " 4 ");
      pal_add_suffix(get_nth_day(date), suffix, 16);
      g_date_strftime(buf, 128, "%A", date);
      g_print(_("- Monthly: The %s %s of every month\n"),
            suffix, buf);

      pal_output_attr(BRIGHT, " 5 ");
      g_date_strftime(buf, 128, "%B", date);
      g_print(_("- Annually: %d %s\n"),
            g_date_get_day(date), buf);

      pal_output_attr(BRIGHT, " 6 ");
      pal_add_suffix(get_nth_day(date), suffix, 16);
      g_date_strftime(buf, 128, "%A", date);
      g_date_strftime(buf2, 128, "%B", date);
      g_print(_("- Annually: The %s %s of every %s\n"),
            suffix, buf, buf2);


      if(last_weekday_of_month(date))
      {
          last_weekday = TRUE;

          pal_output_attr(BRIGHT, " 7 ");
          g_date_strftime(buf, 128, "%A", date);
          g_print(_("- Monthly: The last %s of every month\n"), buf);

          pal_output_attr(BRIGHT, " 8 ");
          g_date_strftime(buf, 128, "%A", date);
          g_date_strftime(buf2, 128, "%B", date);
          g_print(_("- Annually: The last %s in %s\n"), buf, buf2);
      }

      g_print("\n");

      do
      {
          if(last_weekday)
            selection = pal_rl_get_line(_("Select type [1--8]: "));
          else
            selection = pal_rl_get_line(_("Select type [1--6]: "));


          if(g_ascii_strcasecmp(selection, "1") == 0)
          {
            snprintf(key, 9, "DAILY");
            break;
          }
          else if(g_ascii_strcasecmp(selection, "2") == 0)
          {
            switch(g_date_get_weekday(date))
            {
                case 1: snprintf(key, 9, "MON"); break;
                case 2: snprintf(key, 9, "TUE"); break;
                case 3: snprintf(key, 9, "WED"); break;
                case 4: snprintf(key, 9, "THU"); break;
                case 5: snprintf(key, 9, "FRI"); break;
                case 6: snprintf(key, 9, "SAT"); break;
                case 7: snprintf(key, 9, "SUN"); break;
                default: key = NULL; /* impossible...i think */
            }
            break;
          }
          else if(g_ascii_strcasecmp(selection, "3") == 0)
          {
            key[0] = '0';
            key[1] = '0';
            key[2] = '0';
            key[3] = '0';
            key[4] = '0';
            key[5] = '0';
            break;
          }
          else if(g_ascii_strcasecmp(selection, "4") == 0)
          {
            int weekday = g_date_get_weekday(date);
            int n = get_nth_day(date);

            /* convert weekday to friendly weekday
               from: 1(mon) -> 7(sun)
               to:   1(sun) -> 7(sat) */
            if(weekday == 7)
                weekday = 1;
            else
                weekday++;

            snprintf(key, 9, "*00%01d%01d", n, weekday);
            break;


          }

          else if(g_ascii_strcasecmp(selection, "5") == 0)
          {
            key[0] = '0';
            key[1] = '0';
            key[2] = '0';
            key[3] = '0';
            break;
          }
          else if(g_ascii_strcasecmp(selection, "6") == 0)
          {
            int weekday = g_date_get_weekday(date);
            int month = g_date_get_month(date);
            int n = get_nth_day(date);

            /* convert weekday to friendly weekday
               from: 1(mon) -> 7(sun)
               to:   1(sun) -> 7(sat) */
            if(weekday == 7)
                weekday = 1;
            else
                weekday++;

            snprintf(key, 9, "*%02d%01d%01d", month, n, weekday);
            break;
          }
          else if(g_ascii_strcasecmp(selection, "7") == 0 && last_weekday)
          {
            int weekday = g_date_get_weekday(date);

            /* convert weekday to friendly weekday
               from: 1(mon) -> 7(sun)
               to:   1(sun) -> 7(sat) */
            if(weekday == 7)
                weekday = 1;
            else
                weekday++;

            snprintf(key, 9, "*00L%01d", weekday);
            break;
          }

          else if(g_ascii_strcasecmp(selection, "8") == 0 && last_weekday)
          {
            int weekday = g_date_get_weekday(date);
            int month = g_date_get_month(date);

            /* convert weekday to friendly weekday
               from: 1(mon) -> 7(sun)
               to:   1(sun) -> 7(sat) */
            if(weekday == 7)
                weekday = 1;
            else
                weekday++;

            snprintf(key, 9, "*%02dL%01d", month, weekday);
            break;
          }

      }while(1);


      s = g_strconcat(key, pal_add_get_range(), NULL);
      return s;


    }
    else
      return get_key(date);
}





gchar* pal_add_get_desc()
{
    char* desc = NULL;

    g_print("\n");
    pal_output_fg(BRIGHT, GREEN, "> ");
    g_print(_("What is the description of this event?\n"));

    do{
      if(desc != NULL)
      {
          pal_rl_default_text = desc;
          rl_pre_input_hook = (rl_hook_func_t*) pal_rl_default_text_fn;
      }

      desc = pal_rl_get_line(_("Description: "));
      rl_pre_input_hook = NULL;
    }
    while(!pal_rl_get_y_n(_("Is this description correct? [y/n]: ")));

    return desc;
}


/* prompts for a file name */
gchar* pal_add_get_file()
{
    char* filename;
    gboolean prompt_again = FALSE;

    pal_output_fg(BRIGHT, GREEN, "> ");
    g_print(_("Calendar file (usually ending with \".pal\") to add event to:\n"));

    /* get the filename */
    do
    {
      prompt_again = FALSE;
      pal_rl_default_text = g_strconcat(g_get_home_dir(), "/.pal/", NULL);
      rl_pre_input_hook = (rl_hook_func_t*) pal_rl_default_text_fn;
      filename = pal_rl_get_line("Filename: ");
      rl_pre_input_hook = NULL;
      g_free(pal_rl_default_text);

      /* replace ~/ or ~ with home dir  */
      if(*filename == '~')
      {
          char* tmp;
          char* tmp_orig;

          tmp = g_strconcat(filename, NULL);
          tmp_orig = tmp;

          g_free(filename);
          tmp++;
          if(*tmp == '/')
            tmp++;
          filename = g_strconcat(g_get_home_dir(), "/", tmp, NULL);
          g_free(tmp_orig);
      }

      /* check if file exists */
      if(g_file_test(filename, G_FILE_TEST_EXISTS))
      {
          /* make sure it aint a directory */
          if(g_file_test(filename, G_FILE_TEST_IS_DIR))
          {
            pal_output_error(_("ERROR: %s is a directory.\n"), filename);
            prompt_again = TRUE;
          }
      }
      else
      {
          /* ask to create the file if it doesn't exist */
          pal_output_error(_("WARNING: %s does not exist.\n"), filename);

          if(!pal_rl_get_y_n(_("Create? [y/n]: ")))
             prompt_again = TRUE;
          else
          {
            /* create the file */
            FILE*  file = fopen(filename, "w");
            if(file == NULL)
            {
                pal_output_error(_("ERROR: Can't create %s.\n"), filename);
                prompt_again = TRUE;
            }
            else
            {
                gchar *markers;
                gchar *event_type;
                gchar *top_line;

                g_print("\n");
                pal_output_fg(BRIGHT, GREEN, "> ");
                g_print(_("Information for %s:\n"), filename);
                do
                  markers = pal_rl_get_line(_("2 character marker for calendar: "));
                while(g_utf8_strlen(markers, -1) != 2 || markers[0] == '#');

                event_type = pal_rl_get_line(_("Calendar title: "));

                top_line = g_strconcat(markers, " ", event_type, "\n", NULL);

                g_print("\n");
                pal_output_fg(BRIGHT, RED, "> ");
                g_print("%s\n", _("If you want events in this new calendar file to appear when you run pal,\n  you need to manually update ~/.pal/pal.conf"));

                fputs(top_line, file);

                g_free(top_line);
                g_free(event_type);
                g_free(markers);

                fclose(file);
            }
          }

      }

      if(prompt_again)
          g_free(filename);

    }while (prompt_again);

    return filename;
}

void pal_add_write_file(gchar* filename, gchar* key, gchar* desc)
{
    FILE *file = NULL;
    gchar* write_line = NULL;
    gboolean no_newline = FALSE;

    /* check for newline at end of file */
    do
    {
      file = fopen(filename, "r");
      if(file == NULL)
      {
          pal_output_error(_("ERROR: Can't read from file %s.\n"), filename);
          if(!pal_rl_get_y_n(_("Try again? [y/n]: ")))
            return;
      }
    } while(file == NULL);

    fseek(file, -1, SEEK_END);
    if(fgetc(file)!= '\n')
      no_newline = TRUE;
    fclose(file);

    /* write the new event out to that file */
    do
    {
      file = fopen(filename, "a");
      if(file == NULL)
      {
          pal_output_error(_("ERROR: Can't write to file %s.\n"), filename);
          if(!pal_rl_get_y_n(_("Try again? [y/n]: ")))
            return;
      }
    } while(file == NULL);

    /* put a newline at end of file if one isn't there already */
    if(no_newline)
      fputc('\n', file);

    write_line = g_strconcat(key, " ", desc, "\n", NULL);
    fputs(write_line, file);
    g_print("\n");
    pal_output_fg(BRIGHT, GREEN, ">>> ");
    g_print(_("Wrote new event \"%s %s\" to %s.\n"), key, desc, filename);
    g_free(write_line);
    fclose(file);

}


/* Gets a date from the user, then asks if the event is recurring.
 * This function might return "TODO". */
gchar* pal_add_get_date_recur()
{
    gchar* key;
    pal_output_fg(BRIGHT, GREEN, "> ");
    pal_output_wrap(_("Use \"TODO\" to make an event that always occurs on the current date.  If the event is recurring, select one of the days the event occurs on."),2,2);

    key = pal_rl_get_date();
    g_print("\n");

    if(g_ascii_strcasecmp(key, "TODO") == 0)
      return key;
    else
      return pal_add_get_recur(get_date(key));
}


void pal_add_event()
{
    gchar* filename;
    gchar* description;
    gchar* key;

    pal_output_fg(BRIGHT, GREEN, "* * * ");
    pal_output_attr(BRIGHT, _("Add an event"));
    pal_output_fg(BRIGHT, GREEN, " * * *\n");

    rl_completion_entry_function = rl_filename_completion_function;

    filename = pal_add_get_file();
    g_print("\n");

    /* no more completion necessary */
    rl_completion_entry_function = (rl_compentry_func_t*) pal_rl_no_match;

    key = pal_add_get_date_recur();

    description = pal_add_get_desc();

    if(!is_valid_key(key))
    {
      pal_output_error("INTERNAL ERROR: Please report this error message along with\n");
      pal_output_error("                the input that generated it.\n");
      pal_output_error("INVALID KEY: %s\n", key);

    }
    else
      pal_add_write_file(filename, key, description);

    g_free(filename);
    g_free(description);
    g_free(key);

    pal_main_reload();

}



Generated by  Doxygen 1.6.0   Back to index