/** * return the path of the selected transaction * according line_in_transaction * * \param line_in_transaction * * \return a newly allocated GtkTreePath * */ GtkTreePath *transaction_list_select_get_path ( gint line_in_transaction ) { CustomRecord *record; GtkTreePath *path; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, NULL ); record = custom_list -> selected_row; if (!record) return NULL; /* if not child, go to the first row */ if (!record -> mother_row) record = record -> transaction_records[line_in_transaction]; /* if something is wrong in line_in_transaction, it's possible we are not * on the same transaction */ if (! record || record -> transaction_pointer != custom_list -> selected_row -> transaction_pointer) return NULL; path = gtk_tree_path_new (); if (record -> mother_row) /* it's a child, need to get the path of the mother */ gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); return path; }
/** * unselect the current selection of the custom list * * \param * * \return * */ void transaction_list_select_unselect (void) { CustomRecord *record = NULL; GtkTreePath *path; GtkTreeIter iter; gint i; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_if_fail ( custom_list != NULL ); g_return_if_fail ( custom_list -> selected_row != NULL ); iter.stamp = custom_list->stamp; /* get the selected row */ record = custom_list -> selected_row; if (record) { /* si l'opération n'est pas visible on sort */ if ( ( record -> mother_row && record -> mother_row -> filtered_pos == -1 ) || record -> filtered_pos == -1 ) { custom_list -> selected_row = NULL; return; } /* get the path of the row */ path = gtk_tree_path_new (); if (record -> mother_row) /* it's a child, need to get the path of the mother */ gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); for (i=0 ; i < custom_list -> nb_rows_by_transaction ; i++) { record -> row_bg = record -> row_bg_save; record -> row_bg_save = NULL; /* inform the world that the row has changed */ iter.user_data = record; gtk_tree_model_row_changed(GTK_TREE_MODEL(custom_list), path, &iter); /* if the selection was a child, we stop now, only 1 line */ if (record -> mother_row) break; /* go to the next row of the transaction */ record = custom_list -> visibles_rows [record -> filtered_pos + 1]; gtk_tree_path_next (path); } gtk_tree_path_free (path); } custom_list -> selected_row = NULL; }
/** * select the transaction by the record * static function * * \param record the CustomRecord to select * * \return TRUE ok, FALSE problem * */ static gboolean transaction_list_select_record ( CustomRecord *record ) { GtkTreePath *path; GtkTreeIter iter; gint i; gint selected_transaction; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); g_return_val_if_fail ( record != NULL, FALSE ); /* get the transaction number */ selected_transaction = gsb_data_transaction_get_transaction_number (record -> transaction_pointer); /* record is the first row of the transaction to select */ custom_list -> selected_row = record; /* get the path of the row we want to select */ path = gtk_tree_path_new (); if ( record -> mother_row ) /* it's a child, need to get the path of the mother */ gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); /* colorize the record */ for (i=0 ; i < custom_list -> nb_rows_by_transaction ; i++) { record -> row_bg_save = record -> row_bg; record -> row_bg = gsb_rgba_get_couleur ( "couleur_selection" ); /* inform the world that the row has changed */ iter.user_data = record; gtk_tree_model_row_changed(GTK_TREE_MODEL(custom_list), path, &iter); /* if the selection was a child, we stop now, only 1 line */ if (record -> mother_row) break; /* go to the next row of the transaction */ record = custom_list -> visibles_rows [record -> filtered_pos + 1]; gtk_tree_path_next (path); } /** update account and other stuff */ gsb_transactions_list_selection_changed (selected_transaction); return TRUE; }
/** * return the selected transaction * * \param * * \return the transaction_number or -1 (white line) if problem * */ gint transaction_list_select_get ( void ) { CustomRecord *record; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); record = custom_list -> selected_row; if (!record) return -1; return gsb_data_transaction_get_transaction_number (record -> transaction_pointer); }
/** * draw the background of all the rows of the transaction * * \param cr cairo context * \param record record to draw * \param color_bg TRUE to colorize, FALSE to let blank * \param line_position position where drawing the line * * \return * */ static void print_transactions_list_draw_background ( CustomRecord *record, gboolean color_bg, gint line_position ) { if (!gsb_data_print_config_get_draw_background ()) return; if (record -> what_is_line == IS_ARCHIVE) { GdkColor *color; color = gsb_color_get_couleur ( "archive_background_color" ); cairo_rectangle ( cr, 0, line_position, page_width, size_row + 2*gsb_data_print_config_get_draw_lines ( ) ); cairo_set_source_rgb ( cr, (gdouble) color -> red/65535, (gdouble) color -> green/65535, (gdouble) color -> blue/65535 ); } else { CustomList *custom_list = transaction_model_get_model ( ); GdkColor *color; if ( color_bg ) color = gsb_color_get_couleur_with_indice ( "couleur_fond", 0 ); else color = gsb_color_get_couleur_with_indice ( "couleur_fond", 1 ); cairo_rectangle (cr, 0, line_position, page_width, custom_list -> nb_rows_by_transaction * size_row + 2*gsb_data_print_config_get_draw_lines ( ) ); cairo_set_source_rgb (cr, (gdouble) color -> red/65535, (gdouble) color -> green/65535, (gdouble) color -> blue/65535 ); } cairo_fill ( cr ); cairo_set_source_rgb ( cr, 0.0, 0.0, 0.0 ); }
/** * find the number of archives and of transactions, according to the user conf * so if archives are not wanted, the value filled in number_of_archives will be always 0. * * \param number_of_archives a pointer of gint to fill with the number of archives * \param number_of_transactions a pointer to gint to fill with the number of transactions to show * * \return FALSE; * */ gboolean print_transactions_list_get_visibles_lines ( gint *number_of_archives, gint *number_of_transactions ) { gint i; CustomList *custom_list; gint archives_nb = 0; gint transactions_nb = 0; custom_list = transaction_model_get_model (); for (i=0 ; i<custom_list -> num_visibles_rows ; i++) { CustomRecord *record; record = custom_list -> visibles_rows[i]; switch (record -> what_is_line) { case IS_ARCHIVE: if (gsb_data_print_config_get_draw_archives ()) archives_nb++; break; case IS_TRANSACTION: if ( gsb_data_print_config_get_draw_interval_dates () && draw_initial_date && draw_final_date ) { /* we want an interval, so check the transaction */ gint transaction_number; const GDate *date; transaction_number = gsb_data_transaction_get_transaction_number (record -> transaction_pointer); if (gsb_data_print_config_get_draw_dates_are_value_dates ()) { date = gsb_data_transaction_get_value_date (transaction_number); /* if no value date, get the date */ if (!date) date = gsb_data_transaction_get_date (transaction_number); } else date = gsb_data_transaction_get_date (transaction_number); if (date && g_date_compare (date, draw_initial_date) >= 0 && g_date_compare (date, draw_final_date) <= 0) transactions_nb++; } else transactions_nb++; break; } } /* before returning the value, transactions_nb is in fact the number of lines of visibles transactions, * so need to divide by the number of lines for 1 transaction, and remove the white line if necessary */ if ( gsb_data_print_config_get_draw_interval_dates () && draw_initial_date && draw_final_date ) transactions_nb = ( transactions_nb ) / custom_list -> nb_rows_by_transaction; else transactions_nb = (transactions_nb - custom_list -> nb_rows_by_transaction) / custom_list -> nb_rows_by_transaction; *number_of_archives = archives_nb; *number_of_transactions = transactions_nb; return FALSE; }
/** * print the page * * \param operation GtkPrintOperation * \param context GtkPrintContext * \param page page to print * \param null * * \return FALSE * */ gboolean print_transactions_list_draw_page ( GtkPrintOperation *operation, GtkPrintContext *context, gint page, gpointer null ) { CustomList *custom_list; gboolean color_bg = TRUE; gint line_position = 0; gint transactions_to_draw; devel_debug_int (page); /* draw the title */ if (!page) line_position = print_transactions_list_draw_title (context, line_position); /* draw the columns titles */ if (gsb_data_print_config_get_draw_columns_name ()) line_position = print_transactions_list_draw_columns_title (context, line_position); /* draw the transactions lines */ custom_list = transaction_model_get_model (); if (page) transactions_to_draw = transactions_per_page; else transactions_to_draw = transactions_in_first_page; if (transactions_to_draw > (total_transactions_to_print - total_transactions_printed)) transactions_to_draw = total_transactions_to_print - total_transactions_printed; while (transactions_to_draw) { gint i; CustomRecord *record = NULL; /* begin a transaction : fill the line before the transaction */ line_position = print_transactions_list_draw_line (line_position); /* print the transaction */ for (i=0 ; i<custom_list -> nb_rows_by_transaction ; i++) { record = custom_list -> visibles_rows[current_row_to_print]; /* if it's an archive, check we want it */ if (record -> what_is_line == IS_ARCHIVE && !gsb_data_print_config_get_draw_archives ()) { /* go to the next row but come back to the first line of transaction */ current_row_to_print++; i--; continue; } /* if we use the dates, it's here */ if (gsb_data_print_config_get_draw_interval_dates () && draw_initial_date && draw_final_date && record -> what_is_line == IS_TRANSACTION) { /* we want an interval, so check the transaction */ gint transaction_number; const GDate *date = NULL; transaction_number = gsb_data_transaction_get_transaction_number (record -> transaction_pointer); if (gsb_data_print_config_get_draw_dates_are_value_dates ()) date = gsb_data_transaction_get_value_date (transaction_number); /* if no value date, get the date */ if (!date) date = gsb_data_transaction_get_date (transaction_number); if (g_date_compare (date, draw_initial_date) < 0 || g_date_compare (date, draw_final_date) > 0) { /* the transaction is not into the dates, go to the next transaction */ current_row_to_print = current_row_to_print + custom_list -> nb_rows_by_transaction; i--; continue; } } /* begin the transaction, fill the background */ if (!i) print_transactions_list_draw_background (record, color_bg, line_position ); /* draw the last column */ print_transactions_list_draw_column (page_width, line_position); line_position = print_transactions_list_draw_row (context, record, line_position); current_row_to_print++; /* an archive is 1 line */ if (record -> what_is_line == IS_ARCHIVE) break; } /* we are on the last record of the transaction or archive, * decrease the number of transactions to draw */ if (record -> what_is_line == IS_TRANSACTION) { transactions_to_draw--; total_transactions_printed++; } /* add a space between 2 transactions */ line_position++; color_bg = !color_bg; } /* draw the last line */ print_transactions_list_draw_line (line_position); return FALSE; }
/** * Function called first when try to print the transaction list * initialize the variables and calculate the number of pages * * \param operation GtkPrintOperation * \param context GtkPrintContext * \param null * * \return FALSE * */ gboolean print_transactions_list_begin ( GtkPrintOperation *operation, GtkPrintContext *context, gpointer null ) { CustomList *custom_list; gint size_transaction; gint size_title = 0; gint size_archive = 0; gdouble transactions_per_page_double; gint nb_pages; gint number_of_archives = 0; devel_debug (NULL); /* we need to calculate the number of pages */ cr = gtk_print_context_get_cairo_context (context); custom_list = transaction_model_get_model (); /* get the size of the title */ if (gsb_data_print_config_get_draw_title () && title_string && strlen (title_string)) size_title = pango_font_description_get_size (gsb_data_print_config_get_font_title ())/PANGO_SCALE; /* we need the number of archives and of transactions to print * number_of_archives will be set to 0 if no draw archives */ print_transactions_list_get_visibles_lines (&number_of_archives, &total_transactions_to_print ); /* xxx mk_include 2 fois de suite modifie qd même des fichiers */ /* get the size of a complete transaction and an archive */ size_row = pango_font_description_get_size (gsb_data_print_config_get_font_transactions ())/PANGO_SCALE; size_transaction = size_row * custom_list -> nb_rows_by_transaction + 2*gsb_data_print_config_get_draw_lines (); size_archive = size_row + 2*gsb_data_print_config_get_draw_lines (); /* the heigh of a page decrease of 1 line if we use the columns titles */ page_height = gtk_print_context_get_height (context) - gsb_data_print_config_get_draw_columns_name ()*size_transaction; /* how much transactions we can show in a page : */ transactions_per_page_double = page_height / size_transaction; if (!size_title && !gsb_data_print_config_get_draw_archives ()) { /* simple way : no archives and no title */ nb_pages = ceil ( total_transactions_to_print / transactions_per_page_double ); transactions_in_first_page = floor (transactions_per_page_double); } else { /* there are title or archives, it's more complex because it will have less transactions * on the first page */ gint first_page_height = page_height - size_title - size_archive*number_of_archives; transactions_in_first_page = floor (first_page_height / size_transaction); nb_pages = 1 + ceil ( (total_transactions_to_print - transactions_in_first_page)/ transactions_per_page_double ); } /* set the number of page */ gtk_print_operation_set_n_pages ( GTK_PRINT_OPERATION (operation), nb_pages ); /* save the nb of transactions per page */ transactions_per_page = floor (transactions_per_page_double); /* calculate the size and position of the columns */ page_width = gtk_print_context_get_width (context); print_transactions_list_calculate_columns (page_width); total_transactions_printed = 0; current_row_to_print = 0; return FALSE; }
/** * set the selection on the given transaction * * \param transaction_number the transaction to select * * \return FALSE if not possible (not visible), TRUE if ok * */ gboolean transaction_list_select ( gint transaction_number ) { CustomRecord *record = NULL; gboolean return_value; GtkTreePath *path; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); /* fixes bug 1875 */ if (custom_list->num_visibles_rows == 0) return FALSE; /* if the selection didn't change, do nothing */ if ( gsb_data_transaction_get_transaction_number (custom_list -> selected_row) == transaction_number ) return FALSE; /* first, we un-select the last transaction */ if (custom_list -> selected_row) transaction_list_select_unselect (); /* if we want the white line, this will increase a little the speed */ if (transaction_number == -1) { record = custom_list -> visibles_rows [custom_list -> num_visibles_rows - custom_list -> nb_rows_by_transaction]; if (gsb_data_transaction_get_transaction_number (record -> transaction_pointer) != -1) record = NULL; } if (!record) { GtkTreeIter iter; if (!transaction_model_get_transaction_iter ( &iter, transaction_number, 0 )) return FALSE; record = iter.user_data; } /* si l'opération n'est pas visible on la rend visible */ if ( ( record -> mother_row && record -> mother_row -> filtered_pos == -1 ) || record -> filtered_pos == -1 ) { gint account_number; account_number = gsb_data_transaction_get_account_number ( transaction_number ); gsb_data_account_set_r ( account_number, TRUE ); gsb_menu_update_view_menu ( account_number ); mise_a_jour_affichage_r ( TRUE ); } return_value = transaction_list_select_record (record); /* if we are on a child, open the expander if necessary */ path = gtk_tree_path_new (); if (record -> mother_row) { gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_view_expand_row ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, FALSE ); } else gtk_tree_path_append_index (path, record -> filtered_pos); /* move the tree view to the selection */ gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, NULL, FALSE, 0.0, 0.0 ); gtk_tree_path_free (path); return return_value; }
/** * move down the selection * this doesn't change the selection in the account, only on the model, * so need to update the account * * \param into_children if TRUE and the current selection has children and is opened, * the selection goes on the first child of that transaction * else it goes directly on the next mother * * \return TRUE : done, FALSE : no change * */ gboolean transaction_list_select_down ( gboolean into_children ) { CustomRecord *record; GtkTreePath *end_path_list; GtkTreePath *path; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); /* the only way to forbid the move is if we are on the white line */ record = custom_list -> selected_row; if (!record) /* there is no selection, should not happen * to avoid to block grisbi, set on the white line */ return transaction_list_select (-1); /* the way is different between the selected transaction is a child or a mother */ if (record -> mother_row) { /* we are on a child, go to the next child or to the next mother */ if (record -> pos == (record -> mother_row -> number_of_children - 1)) /* go to the next mother */ record = custom_list -> visibles_rows[record -> mother_row -> filtered_pos + 1]; else /* go to the next child */ record = record -> mother_row -> children_rows[record -> pos + 1]; } else { /* we are on a mother, go into the first child or the next mother */ /* if we are on the white line, go away */ if (gsb_data_transaction_get_transaction_number (record -> transaction_pointer) == -1) return FALSE; /* if we are on a split, and it is opened, and into_children i set, go * to the first child */ if (record -> number_of_children && into_children) { path = gtk_tree_path_new (); /* set the path on the mother row which have the expander */ gtk_tree_path_append_index (path, record -> children_rows[0] -> mother_row -> filtered_pos); } else path = NULL; if (path && gtk_tree_view_row_expanded (GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path)) { /* go to the first child */ record = record -> children_rows[0]; gtk_tree_path_free (path); } else /* go to the next transaction mother */ record = custom_list -> visibles_rows[record -> filtered_pos + custom_list -> nb_rows_by_transaction]; } /* now can remove the selection and select the new one */ transaction_list_select_unselect (); transaction_list_select_record (record); /* move the tree view to the selection, we need to check the visible range and * all that stuff because gtk_tree_view_scroll_to_cell set the rows at the upper of the tree view * instead of keeping them at the bottom, when transaction goes down beside the bottom of the tree view */ if ( gtk_tree_view_get_visible_range ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), NULL, &end_path_list )) { path = gtk_tree_path_new (); if (record -> mother_row) { gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); } else /* check with the last visible line of the transaction */ gtk_tree_path_append_index (path, record -> transaction_records[custom_list -> nb_rows_by_transaction - 1] -> filtered_pos); if (gtk_tree_path_compare (end_path_list, path) == -1) /* the last line of the transaction is above the last visible row */ gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, NULL, TRUE, 1.0, 0.0 ); gtk_tree_path_free (path); gtk_tree_path_free (end_path_list); } return TRUE; }
/** * move up the selection * this doesn't change the selection in the account, only on the model, * so need to update the account * * \param into_children if TRUE and the previous transaction is a split and is opened, * the selection goes on the last child of the previous transactions, * else it goes directly on the mother * * \return TRUE : done, FALSE : no change * */ gboolean transaction_list_select_up ( gboolean into_children ) { CustomRecord *record; GtkTreePath *path; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); record = custom_list -> selected_row; if (!record) /* there is no selection, should not happen * to avoid to block grisbi, set on the white line */ return transaction_list_select (-1); /* check if first record */ if (record -> filtered_pos == 0 && !record -> mother_row) return FALSE; /* go to previous record */ if (record -> mother_row) { /* the current selection is a child, go up or on the mother */ if (record -> pos == 0) /* we are on the first child, go to the mother */ record = record -> mother_row -> transaction_records[0]; else /* go to the prev child */ record = record -> mother_row -> children_rows[record -> pos - 1]; } else { /* the current selection is a mother, we go on the prev mother or the prev child */ record = custom_list -> visibles_rows[record -> filtered_pos -1]; /* if the upper row is an archive, do nothin */ if (record -> what_is_line == IS_ARCHIVE) return FALSE; /* if the record is a mother, the expander is opened and into_children is TRUE, * go to the last child */ path = gtk_tree_path_new (); gtk_tree_path_append_index (path, record -> filtered_pos); if (record -> number_of_children && into_children && gtk_tree_view_row_expanded (GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path)) record = record -> children_rows[record -> number_of_children - 1]; else /* we want the mother, set record on the first row */ record = record -> transaction_records[0]; gtk_tree_path_free (path); } /* now can remove the selection and select the new one */ transaction_list_select_unselect (); transaction_list_select_record (record); /* move the tree view to the selection */ path = gtk_tree_path_new (); if (record -> mother_row) gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, NULL, FALSE, 0.0, 0.0 ); gtk_tree_path_free (path); return TRUE; }