static void gdcs_generic_update_recurrences(GncDenseCalStore *trans, GDate *start, GList *recurrences) { int i; GDate date, next; date = *start; /* go one day before what's in the box so we can get the correct start * date. */ g_date_subtract_days(&date, 1); recurrenceListNextInstance(recurrences, &date, &next); i = 0; while ((i < trans->num_marks) && g_date_valid(&next) /* Do checking against end restriction. */ && ((trans->end_type == NEVER_END) || (trans->end_type == END_ON_DATE && g_date_compare(&next, &trans->end_date) <= 0) || (trans->end_type == END_AFTER_N_OCCS && i < trans->n_occurrences))) { *trans->cal_marks[i++] = next; date = next; recurrenceListNextInstance(recurrences, &date, &next); } trans->num_real_marks = i; /* cstim: Previously this was i-1 but that's just plain wrong for * occurrences which are coming to an end, because then i contains * the number of (rest) occurrences exactly! Subtracting one means * we will miss the last one. */ g_signal_emit_by_name(trans, "update", GUINT_TO_POINTER(1)); }
/** * Update start date... right now we always base this off the transaction * start date, but ideally we want to respect what the user has in the field, * somehow. **/ static void sxftd_freq_combo_changed( GtkWidget *w, gpointer user_data ) { SXFromTransInfo *sxfti = (SXFromTransInfo*)user_data; GDate date, nextDate; time_t tmp_tt; struct tm *tmpTm; GList *schedule = NULL; tmp_tt = xaccTransGetDate( sxfti->trans ); g_date_set_time_t( &date, tmp_tt ); g_date_clear(&nextDate, 1); sxftd_update_schedule(sxfti, &date, &schedule); recurrenceListNextInstance(schedule, &date, &nextDate); tmpTm = g_new0( struct tm, 1 ); g_date_to_struct_tm( &nextDate, tmpTm ); tmp_tt = mktime( tmpTm ); g_free( tmpTm ); gnc_date_edit_set_time( sxfti->startDateGDE, tmp_tt ); recurrenceListFree(&schedule); sxftd_update_example_cal( sxfti ); }
void ap_assistant_finish (GtkAssistant *assistant, gpointer user_data) { AcctPeriodInfo *info = user_data; GtkTextBuffer * buffer; GtkTextIter startiter, enditer; gint len; const char *btitle; char *bnotes; Timespec closing_date; ENTER("info=%p", info); btitle = gtk_entry_get_text (GTK_ENTRY(info->book_title)); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(info->book_notes)); len = gtk_text_buffer_get_char_count (buffer); gtk_text_buffer_get_iter_at_offset(buffer, &startiter, 0); gtk_text_buffer_get_iter_at_offset(buffer, &enditer, len); bnotes = gtk_text_buffer_get_text(buffer, &startiter, &enditer , 0); PINFO("Book title is - %s\n", btitle); timespecFromTime64 (&closing_date, gnc_time64_get_day_end_gdate (&info->closing_date)); g_free(bnotes); /* Report the status back to the user. */ info->close_status = 0; /* XXX fixme success or failure? */ /* Find the next closing date ... */ info->prev_closing_date = info->closing_date; recurrenceListNextInstance (info->period, &info->prev_closing_date, &info->closing_date); /* FIXME Test for valid closing date, not sure why it won't be!!! */ if (g_date_valid(&info->closing_date) == TRUE) { /* If the next closing date is in the future, then we are done. */ if (gnc_time (NULL) > gnc_time64_get_day_end_gdate (&info->closing_date)) { /* Load up the GUI for the next closing period. */ gnc_frequency_setup_recurrence (info->period_menu, NULL, &info->closing_date); /* Jump back to the Close Book page. */ gtk_assistant_set_current_page (GTK_ASSISTANT(info->window), 1); } } }
static void prepare_remarks (AcctPeriodInfo *info) { int nperiods; GDate period_begin, period_end, date_now; const char *remarks_text; char * str; ENTER ("info=%p", info); /* Pull info from widget, push into freq spec */ //gnc_frequency_save_state (info->period_menu, info->period, &info->closing_date); recurrenceListFree(&info->period); gnc_frequency_save_to_recurrence(info->period_menu, &info->period, &info->closing_date); /* Count the number of periods that would be generated. */ g_date_clear (&period_begin, 1); g_date_clear (&period_end, 1); g_date_clear (&date_now, 1); nperiods = 0; period_end = info->closing_date; g_date_set_time_t (&date_now, time(NULL)); while (0 > g_date_compare(&period_end, &date_now )) { nperiods ++; PINFO ("period=%d end date=%d/%d/%d", nperiods, g_date_get_month(&period_end), g_date_get_day(&period_end), g_date_get_year(&period_end)); period_begin = period_end; recurrenceListNextInstance(info->period, &period_begin, &period_end); } /* Display the results */ remarks_text = _("The earliest transaction date found in this book is %s. " "Based on the selection made above, this book will be split " "into %d books. Click on 'Forward' to start closing the " "earliest book."); str = g_strdup_printf (remarks_text, info->earliest_str, nperiods); gtk_label_set_text (info->period_remarks, str); g_free (str); }
GDate xaccSchedXactionGetNextInstance (const SchedXaction *sx, SXTmpStateData *tsd) { GDate prev_occur, next_occur; g_date_clear( &prev_occur, 1 ); if ( tsd != NULL ) prev_occur = tsd->last_date; /* If prev_occur is in the "cleared" state and sx->start_date isn't, then * we're at the beginning. We want to pretend prev_occur is the day before * the start_date in case the start_date is today so that the SX will fire * today. If start_date isn't valid either then the SX will fire anyway, no * harm done. */ if (! g_date_valid( &prev_occur ) && g_date_valid(&sx->start_date)) { /* We must be at the beginning. */ prev_occur = sx->start_date; g_date_subtract_days( &prev_occur, 1 ); } recurrenceListNextInstance(sx->schedule, &prev_occur, &next_occur); if ( xaccSchedXactionHasEndDate( sx ) ) { const GDate *end_date = xaccSchedXactionGetEndDate( sx ); if ( g_date_compare( &next_occur, end_date ) > 0 ) { g_date_clear( &next_occur, 1 ); } } else if ( xaccSchedXactionHasOccurDef( sx ) ) { if ((tsd && tsd->num_occur_rem == 0) || (!tsd && sx->num_occurances_remain == 0 )) { g_date_clear( &next_occur, 1 ); } } return next_occur; }
/** * Update start date... right now we always base this off the transaction * start date, but ideally we want to respect what the user has in the field, * somehow. **/ static void sxftd_freq_combo_changed( GtkWidget *w, gpointer user_data ) { SXFromTransInfo *sxfti = (SXFromTransInfo*)user_data; GDate date, nextDate; time64 tmp_tt; GList *schedule = NULL; tmp_tt = xaccTransGetDate( sxfti->trans ); gnc_gdate_set_time64 (&date, tmp_tt); g_date_clear(&nextDate, 1); sxftd_update_schedule(sxfti, &date, &schedule); recurrenceListNextInstance(schedule, &date, &nextDate); tmp_tt = gnc_time64_get_day_start_gdate (&nextDate); gnc_date_edit_set_time( sxfti->startDateGDE, tmp_tt ); recurrenceListFree(&schedule); sxftd_update_example_cal( sxfti ); }
/** * Update the example calendar; make sure to take into account the end * specification. **/ static void sxftd_update_example_cal( SXFromTransInfo *sxfti ) { struct tm *tmpTm; time64 tmp_tt; GDate date, startDate, nextDate; GList *schedule = NULL; getEndTuple get; get = sxftd_get_end_info( sxfti ); tmp_tt = gnc_date_edit_get_date( sxfti->startDateGDE ); gnc_gdate_set_time64 (&date, tmp_tt); sxftd_update_schedule(sxfti, &date, &schedule); /* go one day before what's in the box so we can get the correct start * date. */ startDate = date; g_date_subtract_days(&date, 1); g_date_clear(&nextDate, 1); recurrenceListNextInstance(schedule, &date, &nextDate); { gchar *name; /* get the name */ name = NULL; name = gtk_editable_get_chars(GTK_EDITABLE(sxfti->name), 0, -1); gnc_dense_cal_store_update_name(sxfti->dense_cal_model, name); g_free(name); } { gchar *schedule_desc; schedule_desc = recurrenceListToCompactString(schedule); gnc_dense_cal_store_update_info(sxfti->dense_cal_model, schedule_desc); g_free(schedule_desc); } /* Set End date sensitivity */ gtk_widget_set_sensitive( GTK_WIDGET(sxfti->endDateGDE), (get.type == END_ON_DATE) ); gtk_widget_set_sensitive( GTK_WIDGET(sxfti->n_occurences), (get.type == END_AFTER_N_OCCS) ); /* Use the day preceding the start date for the store to find the correct real start date */ switch (get.type) { case NEVER_END: gnc_dense_cal_store_update_recurrences_no_end(sxfti->dense_cal_model, &date, schedule); break; case END_ON_DATE: gnc_dense_cal_store_update_recurrences_date_end(sxfti->dense_cal_model, &date, schedule, &get.end_date); break; case END_AFTER_N_OCCS: gnc_dense_cal_store_update_recurrences_count_end(sxfti->dense_cal_model, &date, schedule, get.n_occurrences); break; default: g_warning("unknown get.type [%d]\n", get.type); break; } gnc_dense_cal_set_month( sxfti->example_cal, g_date_get_month( &startDate ) ); gnc_dense_cal_set_year( sxfti->example_cal, g_date_get_year( &startDate ) ); recurrenceListFree(&schedule); }
static gint sxftd_init( SXFromTransInfo *sxfti ) { GtkWidget *w; const char *transName; gint pos; GList *schedule = NULL; time64 start_tt; struct tm *tmpTm; GDate date, nextDate; if ( ! sxfti->sx ) { return -1; } if ( ! sxfti->trans ) { return -2; } if ( xaccTransIsOpen( sxfti->trans ) ) { return SXFTD_ERRNO_OPEN_XACTION; } /* Setup Widgets */ { sxfti->ne_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "never_end_button")); sxfti->ed_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "end_on_date_button")); sxfti->oc_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "n_occurrences_button")); sxfti->n_occurences = GTK_ENTRY(gtk_builder_get_object(sxfti->builder, "n_occurrences_entry")); } /* Get the name from the transaction, try that as the initial SX name. */ transName = xaccTransGetDescription( sxfti->trans ); xaccSchedXactionSetName( sxfti->sx, transName ); sxfti->name = GTK_ENTRY(gtk_builder_get_object(sxfti->builder, "name_entry" )); pos = 0; gtk_editable_insert_text( GTK_EDITABLE(sxfti->name), transName, (strlen(transName) * sizeof(char)), &pos ); sxfti_attach_callbacks(sxfti); /* Setup the example calendar and related data structures. */ { int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31; w = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "ex_cal_frame" )); sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks); sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model))); g_object_ref_sink(sxfti->example_cal); g_assert(sxfti->example_cal); gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS ); gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL ); gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) ); } /* Setup the start and end dates as GNCDateEdits */ { GtkWidget *paramTable = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "param_table" )); sxfti->startDateGDE = GNC_DATE_EDIT( gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE)); gtk_table_attach( GTK_TABLE(paramTable), GTK_WIDGET( sxfti->startDateGDE ), 1, 2, 2, 3, (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0 ); g_signal_connect( sxfti->startDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } { GtkWidget *endDateBox = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "end_date_hbox" )); sxfti->endDateGDE = GNC_DATE_EDIT( gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE)); gtk_box_pack_start( GTK_BOX( endDateBox ), GTK_WIDGET( sxfti->endDateGDE ), TRUE, TRUE, 0 ); g_signal_connect( sxfti->endDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } /* Setup the initial start date for user display/confirmation */ /* compute good initial date. */ start_tt = xaccTransGetDate( sxfti->trans ); gnc_gdate_set_time64( &date, start_tt ); sxfti->freq_combo = GTK_COMBO_BOX(gtk_builder_get_object(sxfti->builder, "freq_combo_box")); gtk_combo_box_set_active(GTK_COMBO_BOX(sxfti->freq_combo), 0); g_signal_connect( sxfti->freq_combo, "changed", G_CALLBACK(sxftd_freq_combo_changed), sxfti ); sxftd_update_schedule( sxfti, &date, &schedule); recurrenceListNextInstance(schedule, &date, &nextDate); recurrenceListFree(&schedule); start_tt = gnc_time64_get_day_start_gdate (&nextDate); gnc_date_edit_set_time( sxfti->startDateGDE, start_tt ); g_signal_connect( G_OBJECT(sxfti->name), "destroy", G_CALLBACK(sxftd_destroy), sxfti ); sxftd_update_example_cal( sxfti ); return 0; }
void ap_assistant_menu_prepare (GtkAssistant *assistant, gpointer user_data) { int nperiods; GDate period_begin, period_end, date_now; char * str; AcctPeriodInfo *info = user_data; ENTER ("info=%p", info); /* Pull info from widget, push into freq spec */ //gnc_frequency_save_state (info->period_menu, info->period, &info->closing_date); recurrenceListFree(&info->period); gnc_frequency_save_to_recurrence(info->period_menu, &info->period, &info->closing_date); /* Count the number of periods that would be generated. */ g_date_clear (&period_begin, 1); g_date_clear (&period_end, 1); g_date_clear (&date_now, 1); nperiods = 0; period_end = info->closing_date; gnc_gdate_set_time64 (&date_now, gnc_time (NULL)); while (0 > g_date_compare(&period_end, &date_now )) { nperiods ++; PINFO ("Period = %d and End date is %d/%d/%d", nperiods, g_date_get_month(&period_end), g_date_get_day(&period_end), g_date_get_year(&period_end)); period_begin = period_end; recurrenceListNextInstance(info->period, &period_begin, &period_end); /* FIXME Check for valid period_end, not sure why it won't be!!! */ if (g_date_valid (&period_end) != TRUE) break; } /* Find the date of the earliest transaction in the current book. * Note that this could have changed since last time, since * we may have closed books since last time. */ info->earliest = get_earliest_in_book (gnc_get_current_book()); info->earliest_str = qof_print_date(info->earliest); PINFO ("Date of earliest transaction is %" G_GINT64_FORMAT " %s", info->earliest, gnc_ctime (&info->earliest)); /* Display the results */ str = g_strdup_printf ( /* Translators: %s is a date string. %d is the number of books * that will be created. This is a ngettext(3) message (but * only for the %d part). */ ngettext("The earliest transaction date found in this book is %s. " "Based on the selection made above, this book will be split " "into %d book.", "The earliest transaction date found in this book is %s. " "Based on the selection made above, this book will be split " "into %d books.", nperiods), info->earliest_str, nperiods); gtk_label_set_text (GTK_LABEL(info->period_remarks), str); g_free (str); }
static gboolean ap_close_period (GnomeDruidPage *druidpage, GtkWidget *druid, gpointer user_data) { AcctPeriodInfo *info = user_data; QofBook *closed_book = NULL, *current_book; const char *btitle; char *bnotes; Timespec closing_date; KvpFrame *book_frame; gboolean really_do_close_books = FALSE; ENTER("info=%p", info); current_book = gnc_get_current_book (); btitle = gtk_entry_get_text (info->book_title); bnotes = xxxgtk_textview_get_text (info->book_notes); PINFO("book title=%s\n", btitle); timespecFromTime_t (&closing_date, gnc_timet_get_day_end_gdate (&info->closing_date)); #define REALLY_DO_CLOSE_BOOKS #ifdef REALLY_DO_CLOSE_BOOKS really_do_close_books = TRUE; #endif /* REALLY_DO_CLOSE_BOOKS */ if (really_do_close_books) { /* Close the books ! */ qof_event_suspend (); gnc_suspend_gui_refresh (); scrub_all(); closed_book = gnc_book_close_period (current_book, closing_date, NULL, btitle); book_frame = qof_book_get_slots(closed_book); kvp_frame_set_str (book_frame, "/book/title", btitle); kvp_frame_set_str (book_frame, "/book/notes", bnotes); qof_session_add_book (gnc_get_current_session(), closed_book); /* We must save now; if we don't, and the user bails without saving, * then opening account balances will be incorrect, and this can only * lead to unhappiness. */ gnc_file_save (); gnc_resume_gui_refresh (); qof_event_resume (); gnc_gui_refresh_all (); /* resume above should have been enough ??? */ } g_free(bnotes); /* Report the status back to the user. */ info->close_status = 0; /* XXX fixme success or failure? */ /* Find the next closing date ... */ info->prev_closing_date = info->closing_date; recurrenceListNextInstance(info->period, &info->prev_closing_date, &info->closing_date); /* If the next closing date is in the future, then we are done. */ if (time(NULL) < gnc_timet_get_day_end_gdate (&info->closing_date)) { return FALSE; } /* Load up the GUI for the next closing period. */ gnc_frequency_setup_recurrence(info->period_menu, NULL, &info->closing_date); show_book_details (info); return TRUE; }
/** * Update the example calendar; make sure to take into account the end * specification. **/ static void sxftd_update_example_cal( SXFromTransInfo *sxfti ) { struct tm *tmpTm; time_t tmp_tt; GDate date, startDate, nextDate; GList *schedule = NULL; getEndTuple get; get = sxftd_get_end_info( sxfti ); tmp_tt = gnc_date_edit_get_date( sxfti->startDateGDE ); tmpTm = g_new0( struct tm, 1 ); *tmpTm = *localtime( &tmp_tt ); g_date_clear(&date, 1); g_date_set_day( &date, tmpTm->tm_mday ); g_date_set_month( &date, tmpTm->tm_mon + 1 ); g_date_set_year( &date, tmpTm->tm_year + 1900 ); g_free( tmpTm ); sxftd_update_schedule(sxfti, &date, &schedule); /* go one day before what's in the box so we can get the correct start * date. */ startDate = date; g_date_subtract_days(&date, 1); g_date_clear(&nextDate, 1); recurrenceListNextInstance(schedule, &date, &nextDate); { GtkWidget *w; gchar *name; /* get the name */ w = glade_xml_get_widget(sxfti->gxml, SXFTD_NAME_ENTRY); name = gtk_editable_get_chars(GTK_EDITABLE(w), 0, -1); gnc_dense_cal_store_update_name(sxfti->dense_cal_model, name); g_free(name); } { gchar *schedule_desc; schedule_desc = recurrenceListToCompactString(schedule); gnc_dense_cal_store_update_info(sxfti->dense_cal_model, schedule_desc); g_free(schedule_desc); } switch (get.type) { case NEVER_END: gnc_dense_cal_store_update_recurrences_no_end(sxfti->dense_cal_model, &startDate, schedule); break; case END_ON_DATE: gnc_dense_cal_store_update_recurrences_date_end(sxfti->dense_cal_model, &startDate, schedule, &get.end_date); break; case END_AFTER_N_OCCS: gnc_dense_cal_store_update_recurrences_count_end(sxfti->dense_cal_model, &startDate, schedule, get.n_occurrences); break; default: g_warning("unknown get.type [%d]\n", get.type); break; } gnc_dense_cal_set_month( sxfti->example_cal, g_date_get_month( &startDate ) ); gnc_dense_cal_set_year( sxfti->example_cal, g_date_get_year( &startDate ) ); recurrenceListFree(&schedule); }
static gint sxftd_init( SXFromTransInfo *sxfti ) { GtkWidget *w; const char *transName; gint pos; GList *schedule = NULL; time_t start_tt; struct tm *tmpTm; GDate date, nextDate; if ( ! sxfti->sx ) { return -1; } if ( ! sxfti->trans ) { return -2; } if ( xaccTransIsOpen( sxfti->trans ) ) { return SXFTD_ERRNO_OPEN_XACTION; } sxfti_attach_callbacks(sxfti); /* Setup the example calendar and related data structures. */ { int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31; w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME )); sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks); sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model))); g_object_ref_sink(sxfti->example_cal); g_assert(sxfti->example_cal); gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS ); gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL ); gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) ); } /* Setup the start and end dates as GNCDateEdits */ { GtkWidget *paramTable = glade_xml_get_widget( sxfti->gxml, SXFTD_PARAM_TABLE ); sxfti->startDateGDE = GNC_DATE_EDIT( gnc_date_edit_new( time( NULL ), FALSE, FALSE ) ); gtk_table_attach( GTK_TABLE(paramTable), GTK_WIDGET( sxfti->startDateGDE ), 1, 2, 2, 3, (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0 ); g_signal_connect( sxfti->startDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } { GtkWidget *endDateBox = glade_xml_get_widget( sxfti->gxml, SXFTD_END_DATE_BOX ); sxfti->endDateGDE = GNC_DATE_EDIT( gnc_date_edit_new( time( NULL ), FALSE, FALSE ) ); gtk_box_pack_start( GTK_BOX( endDateBox ), GTK_WIDGET( sxfti->endDateGDE ), FALSE, TRUE, 0 ); g_signal_connect( sxfti->endDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } /* Get the name from the transaction, try that as the initial SX name. */ transName = xaccTransGetDescription( sxfti->trans ); xaccSchedXactionSetName( sxfti->sx, transName ); /* Setup the initial start date for user display/confirmation */ /* compute good initial date. */ start_tt = xaccTransGetDate( sxfti->trans ); g_date_set_time_t( &date, start_tt ); w = glade_xml_get_widget(sxfti->gxml, SXFTD_FREQ_COMBO_BOX); gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0); g_signal_connect( w, "changed", G_CALLBACK(sxftd_freq_combo_changed), sxfti ); sxftd_update_schedule( sxfti, &date, &schedule); recurrenceListNextInstance(schedule, &date, &nextDate); recurrenceListFree(&schedule); tmpTm = g_new0( struct tm, 1 ); g_date_to_struct_tm( &nextDate, tmpTm ); start_tt = mktime( tmpTm ); g_free( tmpTm ); gnc_date_edit_set_time( sxfti->startDateGDE, start_tt ); w = glade_xml_get_widget( sxfti->gxml, SXFTD_NAME_ENTRY ); pos = 0; gtk_editable_insert_text( GTK_EDITABLE(w), transName, (strlen(transName) * sizeof(char)), &pos ); g_signal_connect( GTK_OBJECT(w), "destroy", G_CALLBACK(sxftd_destroy), sxfti ); sxftd_update_example_cal( sxfti ); return 0; }