/**
 * callback called by the button to launch the automatic association
 * between transactions and reconcile
 *
 * \param button
 * \param assistant
 *
 * \return FALSE
 * */
static gboolean gsb_assistant_reconcile_config_lauch_auto_asso ( GtkWidget *button,
                        GtkWidget *assistant )
{
    GSList *tmp_list;

    /* we will use the list already created */
    tmp_list = list_association;
    while (tmp_list)
    {
	struct association_transaction_reconcile *association;

	association = tmp_list -> data;

	gsb_data_transaction_set_reconcile_number ( association -> transaction_number,
						    association -> reconcile_number );
	tmp_list = tmp_list -> next;
    }

    transactions_to_link = transactions_to_link - g_slist_length (list_association);
    g_slist_free (list_association);
    list_association = NULL;

    /* now there is 2 way :
     * either transactions_to_link is 0, we go directly to the succes page
     * either it's not null, and the user should create more reconciliations */
    if (transactions_to_link)
    {
	gchar *string;

	/* update the labels */
	string = g_strdup_printf (_("Still %d transactions to link with a reconciliation."),
				  transactions_to_link);
	gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_2),
			     string);
	g_free (string);
	gtk_misc_set_alignment ( GTK_MISC (label_transactions_to_link_2),
				 0, 0.5 );

	gtk_label_set_text ( GTK_LABEL (label_possible_association),
			     _("There is no transaction that Grisbi can link.\n"
			       "Check if you created all the necesssary reconciliations."));
	gtk_widget_set_sensitive ( button_run_association,
				   FALSE );
    }
    else
    {
	/* go to the success page */
	gsb_assistant_set_next ( assistant,
				 RECONCILE_ASSISTANT_AUTOMATICALLY_ASSOCIATE,
				 RECONCILE_ASSISTANT_SUCCESS );
	gsb_assistant_next_page (assistant);
    }
    return FALSE;
}
/**
 * callback called when there is a change in the menu
 * change the next page to show according to the menu
 *
 * \param button
 * \param assistant
 *
 * \return FALSE
 * */
static gboolean gsb_assistant_reconcile_config_page_menu_toggled ( GtkWidget *button,
                        GtkWidget *assistant )
{
    gint new_next_page;

    new_next_page = GPOINTER_TO_INT ( g_object_get_data (G_OBJECT (button),
							 "next_page"));
    gsb_assistant_set_next ( assistant,
			     RECONCILE_ASSISTANT_MENU,
			     new_next_page );

    return FALSE;
}
Beispiel #3
0
/**
 * Add a page to the Grisbi assistant.
 *
 * \param assistant		Grisbi assistant to add a page to.
 * \param widget		Widget containing the new page to insert.
 * \param position		Number of the page to insert.  Page 0 is
 *				reserved to the explanation label.
 * \param prev			Page to display when the "Previous" button is
 *				clicked.
 * \param next			Page to display when the "Next" button is clicked.
 * \param enter_callback	A callback to connect to the "switch-page" callback
 *				of the Grisbi assistant notebook. (the callback should
 *				be : gboolean callback ( GtkWidget *assistant, gint new_page ) )
 */
void gsb_assistant_add_page ( GtkWidget * assistant, GtkWidget * widget, gint position,
			      gint prev, gint next, GCallback enter_callback )
{
    GtkWidget * notebook;
    gchar *tmpstr;

    notebook = g_object_get_data ( G_OBJECT(assistant), "notebook" );
    gtk_notebook_insert_page ( GTK_NOTEBOOK(notebook), widget, gtk_label_new(NULL), position );

    gsb_assistant_set_prev ( assistant, position, prev );
    gsb_assistant_set_next ( assistant, position, next );
    tmpstr = g_strdup_printf ( "enter%d", position );
    g_object_set_data ( G_OBJECT(assistant), tmpstr,
			enter_callback );
    g_free (tmpstr);

    gtk_widget_show_all ( widget );
}
Beispiel #4
0
/**
 * Create and initialize a new grisbi assistant.  It is basically
 * composed of a GtkDialog with a notebook that is switched from page
 * to page when user click on dialog buttons.
 *
 * \param title			Title of the assistant.
 * \param explanation		Short text to display in the first
 *				page of the assistant.
 * \param image_filename	Icon to display in the title. (if NULL, use grisbi.png, default logo)
 * \param enter_callback	A callback to connect to the "switch-page" callback when go to the first page
 *				of the Grisbi assistant notebook. (the callback should
 *				be : gboolean callback ( GtkWidget *assistant, gint new_page ) )
 *
 */
GtkWidget * gsb_assistant_new ( const gchar * title, const gchar * explanation,
                        gchar * image_filename,
                        GCallback enter_callback )
{
    GtkWidget * assistant, *notebook, *hbox, *label, *image, *view, *eb;
    GtkWidget * button_cancel, * button_prev, * button_next;
    GtkWidget *button_select;
    GtkStyle * style;
    GtkTextBuffer * buffer;
    gchar *tmpstr;
    gint width = 140;

    assistant = gtk_dialog_new_with_buttons ( title,
                        GTK_WINDOW ( run.window ),
                        GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
                        NULL );

    gtk_window_set_default_size ( GTK_WINDOW ( assistant ), 800, 500 );
    gtk_window_set_position ( GTK_WINDOW ( assistant ), GTK_WIN_POS_CENTER_ON_PARENT );
    gtk_window_set_resizable ( GTK_WINDOW ( assistant ), TRUE );
    g_object_set_data ( G_OBJECT ( run.window ), "assistant", assistant );

    button_select = gtk_toggle_button_new_with_label ( _("Select all") );
    gtk_widget_set_size_request ( button_select, width, -1 );
    gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( assistant )->action_area ),
                        button_select, FALSE, FALSE, 0 );
    g_object_set_data ( G_OBJECT(assistant), "button_select", button_select );

    button_cancel = gtk_dialog_add_button ( GTK_DIALOG(assistant),
                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL );
    gtk_widget_set_size_request ( button_cancel, width, -1 );
    g_object_set_data ( G_OBJECT(assistant), "button_cancel", button_cancel );

    button_prev = gtk_dialog_add_button ( GTK_DIALOG(assistant),
                        GTK_STOCK_GO_BACK, GTK_RESPONSE_NO );
    gtk_widget_set_size_request ( button_prev, width, -1 );
    g_object_set_data ( G_OBJECT(assistant), "button_prev", button_prev );
    gtk_widget_set_sensitive ( button_prev, FALSE );

    button_next = gtk_dialog_add_button ( GTK_DIALOG(assistant),
                        GTK_STOCK_GO_FORWARD, GTK_RESPONSE_YES );
    gtk_widget_set_size_request ( button_next, width, -1 );
    g_object_set_data ( G_OBJECT(assistant), "button_next", button_next );

    eb = gtk_event_box_new ();
    style = gtk_widget_get_style ( eb );
    gtk_widget_modify_bg ( eb, 0, &(style -> bg[GTK_STATE_ACTIVE]) );

    hbox = gtk_hbox_new ( FALSE, 12 );
    gtk_container_add ( GTK_CONTAINER(eb), hbox );
    gtk_container_set_border_width ( GTK_CONTAINER(hbox), 12 );

    label = gtk_label_new ( NULL );
    tmpstr = g_markup_printf_escaped (
                        "<b><span size=\"x-large\">%s</span></b>", title );
    gtk_label_set_markup ( GTK_LABEL(label), tmpstr );
    g_free ( tmpstr );
    gtk_box_pack_start ( GTK_BOX(hbox), label, TRUE, TRUE, 0 );

    if (!image_filename)
        image_filename = "grisbi.png";

    tmpstr = g_build_filename ( gsb_dirs_get_pixmaps_dir ( ), image_filename, NULL);
    image = gtk_image_new_from_file ( tmpstr );
    g_free ( tmpstr );
    gtk_box_pack_start ( GTK_BOX(hbox), image, FALSE, FALSE, 0 );

    gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG(assistant) -> vbox ), eb, FALSE, FALSE, 0 );

    notebook = gtk_notebook_new ();
    gtk_notebook_set_show_tabs ( GTK_NOTEBOOK(notebook), FALSE );
    gtk_notebook_set_show_border ( GTK_NOTEBOOK(notebook), FALSE );
    gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG(assistant) -> vbox ), notebook, TRUE, TRUE, 0 );

    view = gtk_text_view_new ();
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
    tmpstr = g_strconcat ( "\n", explanation, "\n", NULL );
    gtk_text_buffer_set_text (buffer, tmpstr, -1);
    g_free ( tmpstr );
    gtk_text_view_set_editable ( GTK_TEXT_VIEW(view), FALSE );
    gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW(view), FALSE );
    gtk_text_view_set_left_margin ( GTK_TEXT_VIEW(view), 12 );
    gtk_text_view_set_right_margin ( GTK_TEXT_VIEW(view), 12 );

    /* Create some handy fonts. */
    gtk_text_buffer_create_tag ( buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL );
    gtk_text_buffer_create_tag ( buffer, "x-large", "scale", PANGO_SCALE_X_LARGE, NULL );
    gtk_text_buffer_create_tag ( buffer, "indented", "left-margin", 24, NULL );

    gtk_notebook_append_page ( GTK_NOTEBOOK(notebook), view, gtk_label_new(NULL) );

    g_signal_connect_after ( notebook, "switch-page",
                        G_CALLBACK ( gsb_assistant_change_page ), assistant );

    gsb_assistant_set_next ( assistant, 0, 1 );
    g_object_set_data ( G_OBJECT(assistant), "notebook", notebook );
    /* need to set (gchar *) because title is const gchar, the good way should be my_strdup,
     * but we don't touch/free title later so it should be ok... */
    g_object_set_data ( G_OBJECT(assistant), "title", (gchar *) title );
    g_object_set_data ( G_OBJECT(assistant), "enter0", enter_callback );

    return assistant;
}
/**
 * callback called by the button to launch the automatic association
 * between transactions and reconcile
 *
 * \param button
 * \param assistant
 *
 * \return FALSE
 * */
static gboolean gsb_assistant_reconcile_config_lauch_manu_asso ( GtkWidget *button,
                        GtkWidget *assistant )
{
    GList *tmp_list;
    GtkTreeIter iter;
    GtkTreeModel *model;
    GtkTreeSelection *selection;
    GList *path_list;
    gint account_number = -1;
    GtkWidget *dialog;
    GtkWidget *label;
    GtkWidget *scrolled_window;
    GtkWidget *dialog_tree_view;
    GtkListStore *dialog_store;
    gint return_value;
    gint i;
    enum dialog_column {
	DIALOG_NAME = 0,
	DIALOG_INIT_DATE,
	DIALOG_FINAL_DATE,
	DIALOG_RECONCILE_NUMBER,
	DIALOG_NB_COL
    };
    gint selected_reconcile_number;
    gint transaction_number;

    /* get the selection */
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_transactions_to_link));

    /* get the selected transactions */
    path_list = gtk_tree_selection_get_selected_rows ( GTK_TREE_SELECTION (selection),
						       &model );
    if (!path_list)
	return FALSE;

    /* ok, we have a selection, before continuing,
     * we check that all the transactions are on the same account */
    tmp_list = path_list;
    while (tmp_list)
    {
	GtkTreePath *path;

	path = tmp_list -> data;

	if (gtk_tree_model_get_iter ( GTK_TREE_MODEL (model),
				      &iter,
				      path ))
	{
	    gtk_tree_model_get ( GTK_TREE_MODEL (model),
				 &iter,
				 TRANSACTION_NUMBER, &transaction_number,
				 -1 );
	    if (account_number == -1)
		account_number = gsb_data_transaction_get_account_number (transaction_number);
	    else
	    {
		if (gsb_data_transaction_get_account_number (transaction_number) != account_number)
		{
		    dialogue_error (_("All the selected transactions have to belong to the same account !"));
		    /* erase the path_list */
		    g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
		    g_list_free (path_list);
		    return FALSE;
		}
	    }
	}
	tmp_list = tmp_list -> next;
    }

    if (account_number == -1)
    {
	/* erase the path_list */
	g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
	g_list_free (path_list);
	return FALSE;
    }

    /* ok, all the transactions belong to the same account, we can
     * show a dialog to select the reconcile */
    dialog = gtk_dialog_new_with_buttons ( _("Selection of a reconciliation"),
					   GTK_WINDOW ( assistant ),
					   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
					   "gtk-cancel", GTK_RESPONSE_CANCEL,
					   "gtk-ok", GTK_RESPONSE_OK,
					   NULL );

    gtk_window_set_default_size ( GTK_WINDOW ( dialog ), 770, 412 );
    gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
    gtk_window_set_resizable ( GTK_WINDOW ( dialog ), TRUE );
    gtk_container_set_border_width ( GTK_CONTAINER ( dialog ), 12 );

    label = gtk_label_new ( _("Select the reconciliation to associate to the selected transactions: ") );
    gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 );
    gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ),
			 label,
			 FALSE, FALSE,
			 10 );

    /* make the list */
    scrolled_window = gtk_scrolled_window_new (FALSE, FALSE);
    gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scrolled_window),
				     GTK_POLICY_AUTOMATIC,
				     GTK_POLICY_AUTOMATIC );
    gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ),
			 scrolled_window,
			 TRUE, TRUE,
			 0 );

    dialog_store = gtk_list_store_new ( DIALOG_NB_COL,
					G_TYPE_STRING,
					G_TYPE_STRING,
					G_TYPE_STRING,
					G_TYPE_INT );
    dialog_tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog_store));
    g_object_unref (G_OBJECT(dialog_store));
    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (dialog_tree_view), TRUE);
    gtk_container_add ( GTK_CONTAINER (scrolled_window),
			dialog_tree_view );

    /* set the columns */
    for (i=DIALOG_NAME ; i<DIALOG_RECONCILE_NUMBER ; i++)
    {
	GtkTreeViewColumn *column;
	GtkCellRenderer *cell;
	gchar *titles[] = {
	    _("Reconciliation reference"), _("Initial date"), _("Final date")
	};
	gfloat alignment[] = {
	    COLUMN_LEFT, COLUMN_CENTER, COLUMN_CENTER
	};

	cell = gtk_cell_renderer_text_new ();
	g_object_set ( G_OBJECT (cell),
		       "xalign", alignment[i],
		       NULL );
	column = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_sizing ( column,
					  GTK_TREE_VIEW_COLUMN_AUTOSIZE );
	gtk_tree_view_column_set_alignment ( column,
					     alignment[i] );
	gtk_tree_view_column_pack_start ( column, cell, TRUE );
	gtk_tree_view_column_set_title ( column, titles[i] );
	gtk_tree_view_column_set_attributes (column, cell,
					     "text", i,
					     NULL);
	gtk_tree_view_column_set_expand ( column, TRUE );
	gtk_tree_view_column_set_resizable ( column,
					     TRUE );
	gtk_tree_view_append_column ( GTK_TREE_VIEW(dialog_tree_view), column);
    }

    /* fill the tree view */
    tmp_list = gsb_data_reconcile_get_reconcile_list ();
    while (tmp_list)
    {
	gint reconcile_number;

	reconcile_number = gsb_data_reconcile_get_no_reconcile (tmp_list -> data);

	if (gsb_data_reconcile_get_account (reconcile_number) == account_number)
	{
	    gchar *init_date_str;
	    gchar *final_date_str;

	    init_date_str = gsb_format_gdate (gsb_data_reconcile_get_init_date (reconcile_number));
	    final_date_str = gsb_format_gdate (gsb_data_reconcile_get_final_date (reconcile_number));

	    gtk_list_store_append ( GTK_LIST_STORE (dialog_store),
				    &iter );
	    gtk_list_store_set ( GTK_LIST_STORE (dialog_store),
				 &iter,
				 DIALOG_NAME, gsb_data_reconcile_get_name (reconcile_number),
				 DIALOG_INIT_DATE, init_date_str,
				 DIALOG_FINAL_DATE, final_date_str,
				 DIALOG_RECONCILE_NUMBER, reconcile_number,
				 -1 );
	    g_free (init_date_str);
	    g_free (final_date_str);
	}
	tmp_list = tmp_list -> next;
    }

    gtk_widget_show_all (dialog);

    /* launch the dialog */
    return_value = gtk_dialog_run (GTK_DIALOG (dialog));

    if (return_value != GTK_RESPONSE_OK)
    {
	gtk_widget_destroy (dialog);
	return FALSE;
    }

    /* we get the selected reconcile */
    if (!gtk_tree_selection_get_selected ( gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog_tree_view)),
					   NULL,
					   &iter ))
    {
	dialogue_warning (_("No selection found, the transactions are not modified."));
	gtk_widget_destroy (dialog);
	return FALSE;
    }

    gtk_tree_model_get ( GTK_TREE_MODEL (dialog_store),
			 &iter,
			 DIALOG_RECONCILE_NUMBER, &selected_reconcile_number,
			 -1 );
    /* ok we have the reconcile number, we can destroy the dialog */
    gtk_widget_destroy (dialog);

    /* and now, fill the selected transactions with that reconcile number */
    tmp_list = g_list_last (path_list);
    while (tmp_list)
    {
	GtkTreePath *path;

	path = tmp_list -> data;

	if (gtk_tree_model_get_iter ( GTK_TREE_MODEL (model),
				      &iter,
				      path ))
	{
	    gtk_tree_model_get ( GTK_TREE_MODEL (model),
				 &iter,
				 TRANSACTION_NUMBER, &transaction_number,
				 -1 );
	    gtk_list_store_remove ( GTK_LIST_STORE (model),
				    &iter );
	    gsb_data_transaction_set_reconcile_number ( transaction_number,
							selected_reconcile_number );
	    transactions_to_link--;
	}
	tmp_list = tmp_list -> prev;
    }

    /* erase the path_list */
    g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
    g_list_free (path_list);

    /* now there is 2 way :
     * either transactions_to_link is 0, we go directly to the succes page
     * either it's not null, and the user should create more reconciles */
    if (transactions_to_link)
    {
	gchar *string;

	/* update the labels */
	string = g_strdup_printf (_("Still %d transactions to link with a reconciliation."),
				  transactions_to_link);
	gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_1),
			     string);
	gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_3),
			     string);
	g_free (string);
	gtk_widget_grab_focus (treeview_transactions_to_link);
    }
    else
    {
	/* go to the success page */
	gsb_assistant_set_next ( assistant,
				 RECONCILE_ASSISTANT_MANUALLY_ASSOCIATE,
				 RECONCILE_ASSISTANT_SUCCESS );
	gsb_assistant_next_page (assistant);
    }
    return FALSE;
}