/********************************************************************\
 * gnc_stock_split_dialog                                           *
 *   opens up a window to record a stock split                      *
 *                                                                  *
 * Args:   parent  - the parent ofthis window                       *
 *         initial - the initial account to use                     *
 * Return: nothing                                                  *
\********************************************************************/
void
gnc_stock_split_dialog (GtkWidget *parent, Account * initial)
{
    StockSplitInfo *info;
    gint component_id;

    info = g_new0 (StockSplitInfo, 1);

    info->acct = NULL;

    gnc_stock_split_assistant_create (info);

    component_id = gnc_register_gui_component (ASSISTANT_STOCK_SPLIT_CM_CLASS,
                   refresh_handler, close_handler,
                   info);

    gnc_gui_component_watch_entity_type (component_id,
                                         GNC_ID_ACCOUNT,
                                         QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);

    if (fill_account_list (info, initial) == 0)
    {
        gnc_warning_dialog (parent, "%s", _("You don't have any stock accounts with balances!"));
        gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
        return;
    }

    gtk_widget_show_all (info->window);

    gnc_window_adjust_for_screen (GTK_WINDOW(info->window));
}
Esempio n. 2
0
static void
gnc_price_cell_leave (BasicCell *_cell)
{
    gint error_position = -1;
    PriceCell *cell = (PriceCell *) _cell;

    error_position = gnc_price_cell_parse (cell, TRUE);
    if (error_position != -1)
    {
        gnc_warning_dialog(NULL, _("An error occurred while processing %s."),
                           cell->cell.value);
    }

}
Esempio n. 3
0
gboolean
gnc_account_separator_validate_cb (GtkEntry *entry, GdkEvent *event, GtkWidget *dialog)
{
    gchar *separator;
    gchar *conflict_msg = gnc_account_separator_is_valid (gtk_entry_get_text (entry), &separator);

    /* Check if the new separator clashes with existing account names */

    if (conflict_msg)
    {
        gnc_warning_dialog(dialog, "%s", conflict_msg);
        g_free ( conflict_msg );
    }
    g_free (separator);
    return FALSE;
}
static void
remove_clicked (CommoditiesDialog *cd)
{
    GNCPriceDB *pdb;
    GList *prices;
    gboolean can_delete;
    gnc_commodity *commodity;
    GtkWidget *dialog;
    const gchar *message, *warning;
    gint response;

    commodity = gnc_tree_view_commodity_get_selected_commodity (cd->commodity_tree);
    if (commodity == NULL)
        return;

    AccountList_t accounts = gnc_account_get_descendants (gnc_book_get_root_account(cd->book));
    can_delete = TRUE;

    for (AccountList_t::const_iterator node = accounts.begin(); 
            node != accounts.end(); node++)
    {
        Account *account = *node;

        if (commodity == xaccAccountGetCommodity (account))
        {
            can_delete = FALSE;
            break;
        }
    }

    /* FIXME check for transaction references */

    if (!can_delete)
    {
        const char *message = _("That commodity is currently used by "
                                "at least one of your accounts. You may "
                                "not delete it.");

        gnc_warning_dialog (cd->dialog, "%s", message);
        return;
    }

    pdb = gnc_pricedb_get_db (cd->book);
    prices = gnc_pricedb_get_prices(pdb, commodity, NULL);
    if (prices)
    {
        message = _("This commodity has price quotes. Are "
                    "you sure you want to delete the selected "
                    "commodity and its price quotes?");
        warning = "delete_commodity2";
    }
    else
    {
        message = _("Are you sure you want to delete the "
                    "selected commodity?");
        warning = "delete_commodity";
    }

    dialog = gtk_message_dialog_new(GTK_WINDOW(cd->dialog),
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
                                    GTK_MESSAGE_QUESTION,
                                    GTK_BUTTONS_NONE,
                                    "%s", _("Delete commodity?"));
    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
            "%s", message);
    gtk_dialog_add_buttons(GTK_DIALOG(dialog),
                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                           GTK_STOCK_DELETE, GTK_RESPONSE_OK,
                           (gchar *)NULL);
    response = gnc_dialog_run(GTK_DIALOG(dialog), warning);
    gtk_widget_destroy(dialog);

    if (response == GTK_RESPONSE_OK)
    {
        gnc_commodity_table *ct;

        ct = gnc_commodity_table_get_table (cd->book);
        for (GList *node = prices; node; node = node->next)
            gnc_pricedb_remove_price(pdb, node->data);

        gnc_commodity_table_remove (ct, commodity);
        gnc_commodity_destroy (commodity);
        commodity = NULL;
    }

    gnc_price_list_destroy(prices);
    gnc_gui_refresh_all ();
}
Esempio n. 5
0
static PaymentWindow *
new_payment_window (GncOwner *owner, QofBook *book, GncInvoice *invoice)
{
    PaymentWindow *pw;
    GtkBuilder *builder;
    GtkWidget *box, *label, *credit_box, *debit_box;
    GtkTreeSelection *selection;
    GtkTreeViewColumn *column;
    GtkCellRenderer *renderer;
    char * cm_class = (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER ?
                       DIALOG_PAYMENT_CUSTOMER_CM_CLASS :
                       DIALOG_PAYMENT_VENDOR_CM_CLASS);

    /*
     * Find an existing payment window.  If found, bring it to
     * the front.  If we have an actual owner, then set it in
     * the window.
     */

    pw = gnc_find_first_gui_component (cm_class, find_handler, NULL);
    if (pw)
    {
        if (gncOwnerIsValid(owner))
            gnc_payment_set_owner (pw, owner);

        // Reset the setting about the pre-existing TXN
        pw->pre_existing_txn = NULL;

        gtk_window_present (GTK_WINDOW(pw->dialog));
        return(pw);
    }

    /* Ok, we need a new window */

    pw = g_new0 (PaymentWindow, 1);
    pw->book = book;
    gncOwnerCopy (owner, &(pw->owner));

    /* Compute the post-to account types */
    pw->acct_types = gncOwnerGetAccountTypesList (owner);

    if (gncOwnerIsValid(owner))
        pw->acct_commodities = gncOwnerGetCommoditiesList (owner);

    /* Open and read the Glade File */
    builder = gtk_builder_new();
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "docs_list_hor_adj");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "docs_list_vert_adj");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "docs_list_model");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "post_combo_model");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "Payment Dialog");
    pw->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "Payment Dialog"));

    /* Grab the widgets and build the dialog */
    pw->payment_warning = GTK_WIDGET (gtk_builder_get_object (builder, "payment_warning"));
    pw->ok_button = GTK_WIDGET (gtk_builder_get_object (builder, "okbutton"));
    pw->num_entry = GTK_WIDGET (gtk_builder_get_object (builder, "num_entry"));
    pw->memo_entry = GTK_WIDGET (gtk_builder_get_object (builder, "memo_entry"));
    pw->post_combo = GTK_WIDGET (gtk_builder_get_object (builder, "post_combo"));
    gtk_combo_box_set_entry_text_column( GTK_COMBO_BOX( pw->post_combo ), 0 );
    gnc_cbwe_require_list_item(GTK_COMBO_BOX(pw->post_combo));

    label = GTK_WIDGET (gtk_builder_get_object (builder, "owner_label"));
    box = GTK_WIDGET (gtk_builder_get_object (builder, "owner_box"));
    pw->owner_choice = gnc_owner_select_create (label, box, book, owner);

    /* Some terminology:
     * Invoices are paid, credit notes are refunded.
     * A customer payment is a credit action, paying a vendor is debit
     *
     * So depending on the owner the payment amount should be considered
     * credit (customer) or debit (vendor/employee) and refunds should be
     * considered debit (customer) or credit (vendor/employee).
     * For visual consistency, the dialog box will always show a payment and
     * a refund field. Internally they are treated as credit or debit depending
     * on the owner type.
     */
    if (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER)
    {
        debit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_refund_box"));
        credit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_payment_box"));
    }
    else
    {
        debit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_payment_box"));
        credit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_refund_box"));
    }

    pw->amount_debit_edit = gnc_amount_edit_new ();
    gtk_box_pack_start (GTK_BOX (debit_box), pw->amount_debit_edit, TRUE, TRUE, 0);
    gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_debit_edit),
                                           TRUE);
    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_debit_edit), gnc_numeric_zero());
    g_signal_connect(G_OBJECT(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(pw->amount_debit_edit))),
                     "focus-out-event",
                     G_CALLBACK(gnc_payment_leave_amount_cb), pw);

    pw->amount_credit_edit = gnc_amount_edit_new ();
    gtk_box_pack_start (GTK_BOX (credit_box), pw->amount_credit_edit, TRUE, TRUE, 0);
    gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_credit_edit),
                                           TRUE);
    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_credit_edit), gnc_numeric_zero());
    g_signal_connect(G_OBJECT(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(pw->amount_credit_edit))),
                     "focus-out-event",
                     G_CALLBACK(gnc_payment_leave_amount_cb), pw);

    box = GTK_WIDGET (gtk_builder_get_object (builder, "date_box"));
    pw->date_edit = gnc_date_edit_new (time(NULL), FALSE, FALSE);
    gtk_box_pack_start (GTK_BOX (box), pw->date_edit, TRUE, TRUE, 0);

    pw->docs_list_tree_view = GTK_WIDGET (gtk_builder_get_object (builder, "docs_list_tree_view"));
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->docs_list_tree_view));
    gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);

    /* Configure date column */
    renderer = gtk_cell_renderer_text_new ();
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 0);
    gtk_tree_view_column_pack_start (column, renderer, TRUE);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "31-12-2013");
    gtk_tree_view_column_set_cell_data_func (column, renderer,
                                             (GtkTreeCellDataFunc) print_date,
                                             NULL, NULL);

    /* Configure document number column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 1);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "INV2013-016");

    /* Configure document type column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 2);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, _("Credit Note"));

    /* Configure debit column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 3);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "11,999.00");

    /* Configure credit column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 4);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "11,999.00");

    gtk_tree_sortable_set_sort_column_id (
        GTK_TREE_SORTABLE (gtk_tree_view_get_model (GTK_TREE_VIEW (pw->docs_list_tree_view))),
        0, GTK_SORT_ASCENDING);


    box = GTK_WIDGET (gtk_builder_get_object (builder, "acct_window"));
    pw->acct_tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
    gtk_container_add (GTK_CONTAINER (box), pw->acct_tree);
    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(pw->acct_tree), FALSE);
    gnc_payment_set_account_types (GNC_TREE_VIEW_ACCOUNT (pw->acct_tree));

    /* Set the dialog for the 'new' owner.
     * Note that this also sets the post account tree. */
    gnc_payment_dialog_owner_changed(pw);

    /* Set the dialog for the 'new' invoice */
    pw->invoice = invoice;
    if (invoice)
    {
        Account *postacct = gncInvoiceGetPostedAcc (invoice);
        if (postacct)
        {
            gchar *acct_string = gnc_account_get_full_name (postacct);
            gnc_cbwe_set_by_string(GTK_COMBO_BOX(pw->post_combo), acct_string);
            gnc_payment_dialog_post_to_changed_cb (pw->post_combo, pw);
            g_free(acct_string);
        }
    }

    /* Setup signals */
    gtk_builder_connect_signals_full( builder,
                                      gnc_builder_connect_full_func,
                                      pw);

    g_signal_connect (G_OBJECT (pw->owner_choice), "changed",
                      G_CALLBACK (gnc_payment_dialog_owner_changed_cb), pw);

    g_signal_connect (G_OBJECT (pw->acct_tree), "row-activated",
                      G_CALLBACK (gnc_payment_acct_tree_row_activated_cb), pw);

    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->acct_tree));
    g_signal_connect (G_OBJECT (selection), "changed",
                      G_CALLBACK (gnc_payment_dialog_xfer_acct_changed_cb), pw);


    /* Register with the component manager */
    pw->component_id =
        gnc_register_gui_component (cm_class,
                                    gnc_payment_window_refresh_handler,
                                    gnc_payment_window_close_handler,
                                    pw);

    /* Watch for any new or changed accounts */
    gnc_gui_component_watch_entity_type (pw->component_id,
                                         GNC_ID_ACCOUNT,
                                         QOF_EVENT_CREATE | QOF_EVENT_MODIFY |
                                         QOF_EVENT_DESTROY);

    /* Show it all */
    gtk_widget_show_all (pw->dialog);
    g_object_unref(G_OBJECT(builder));

    // The customer choice widget should have keyboard focus
    if (GNC_IS_GENERAL_SEARCH(pw->owner_choice))
    {
        gnc_general_search_grab_focus(GNC_GENERAL_SEARCH(pw->owner_choice));
    }

    /* Reflect if the payment could complete now */
    gnc_payment_window_check_payment (pw);

    /* Warn the user if they have no valid post-to accounts */
    {
        const gchar *text;
        const char *acct_type;

        text = gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (GTK_COMBO_BOX(pw->post_combo)))));

        if (!text || g_strcmp0 (text, "") == 0)
        {

            /* The code below assumes there will only be one account type.
             * Let's assert this to protect from potential future changes. */
            g_assert (g_list_length (pw->acct_types) == 1);
            acct_type = xaccAccountGetTypeStr(GPOINTER_TO_INT(pw->acct_types->data));
            gnc_warning_dialog(pw->dialog,
                               _("You have no valid \"Post To\" accounts. "
                                 "Please create an account of type \"%s\" "
                                 "before you continue to process this payment. "
                                 "Perhaps you want to create an Invoice or "
                                 "Bill first?"),
                               acct_type);
        }
    }

    return pw;
}
Esempio n. 6
0
/*  This routine checks to see if GnuCash's gconf schemas are visible
 *  to the user.  The schemas typically should be visible, as rpm and
 *  deb installs will put the schemas in the default system location.
 *  For things like network installs or developers, this function will
 *  present a warning dialog that asks the user whether to setup
 *  gconf, continue without the schemas, or quit.  If the user chooses
 *  to set up the schemas, this function will invoke an assistant to
 *  walk the user through making the schemas visible.
 */
void
assistant_gconf_install_check_schemas (void)
{
    GtkBuilder *builder;
    GtkWidget *dialog;
    gboolean done = FALSE;
    gint response;

    if (gnc_gconf_schemas_found())
    {
        gnc_gconf_unset_dir(GCONF_WARNINGS_TEMP, NULL);
        return;
    }

#ifdef G_OS_WIN32
    {
        /* automatically update the search path on windows */
        GError *error = NULL;
        if (!assistant_gconf_update_path (&error))
        {
            gnc_error_dialog (NULL, error->message);
            g_error_free (error);
            exit(42);
        }
        else
        {
            if (!g_spawn_command_line_sync("gconftool-2 --shutdown", NULL, NULL,
                                           NULL, &error))
            {
                gnc_warning_dialog(NULL, error->message);
                g_error_free(error);
            }
            return;
        }
    }
#endif /* G_OS_WIN32 */

    builder = gtk_builder_new();
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "GConf Query");

    if (!builder)
    {
        gnc_error_dialog(NULL, "The glade UI files were not found. Your installation is incomplete and cannot be run.");
        exit(-1); /* quit immediately */
    }
    g_assert(builder);
    dialog = GTK_WIDGET(gtk_builder_get_object (builder, "GConf Query"));
    g_assert(dialog);
    do
    {
        response = gtk_dialog_run(GTK_DIALOG(dialog));

        switch (response)
        {
        case GTK_RESPONSE_CANCEL:
        default:
            exit(42);
            /* never returns */

        case GTK_RESPONSE_NO:
            /* User wants to run without setting up gconf */
            done = TRUE;
            break;

        case GTK_RESPONSE_ACCEPT:
            gtk_widget_hide(dialog);
            gnc_gnome_install_gconf_schemas();
            done = TRUE;
            break;

        case GTK_RESPONSE_HELP:
            gnc_gnome_help(HF_HELP, HL_GCONF);
            break;
        }
    }
    while (!done);

    g_object_unref(G_OBJECT(builder));
    gtk_widget_destroy(dialog);
}
Esempio n. 7
0
/** This function build and presents the assistant that presents the user
 *  with the two methods of making the gconf schemas visible, and
 *  learns whether gnucash should do the work or the user will do the
 *  work.  This function then blocks in a call to gtk_main(), while
 *  all of the work happens in callback functions.  Once the dialog is
 *  finished, this function kills off any existing gconf daemon so
 *  that the changes will be noticed upon daemon restart.
 */
static GtkWidget *
gnc_gnome_install_gconf_schemas (void)
{
    gconf_data *data;
    GtkBuilder *builder;
    GtkWidget *dialog;
    GError *error = NULL;


    data = g_new0 (gconf_data, 1);
    builder = gtk_builder_new();
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer1");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer2");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer3");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer4");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer5");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer6");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer7");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "textbuffer8");
    gnc_builder_add_from_file (builder, "assistant-gconf-setup.glade", "GConf Setup Assistant");

    dialog = GTK_WIDGET(gtk_builder_get_object (builder, "GConf Setup Assistant"));
    data->dialog = dialog;

    /* Set the colors for the assistant */
    gnc_assistant_set_colors (GTK_ASSISTANT (data->dialog));

    /* Enable buttons on all pages. */
    gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
                                     GTK_WIDGET(gtk_builder_get_object(builder, "start_page")),
                                     TRUE);
    gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
                                     GTK_WIDGET(gtk_builder_get_object(builder, "choose_page")),
                                     TRUE);
    gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
                                     GTK_WIDGET(gtk_builder_get_object(builder, "update_page")),
                                     TRUE);
    gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
                                     GTK_WIDGET(gtk_builder_get_object(builder, "step_page")),
                                     TRUE);
    gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
                                     GTK_WIDGET(gtk_builder_get_object(builder, "install_page")),
                                     TRUE);
    gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
                                     GTK_WIDGET(gtk_builder_get_object(builder, "finish_page")),
                                     TRUE);

    /* Choose page */
    data->update_path = GTK_WIDGET(gtk_builder_get_object (builder, "update_path"));

    /* Update page */
    data->program1 = GTK_WIDGET(gtk_builder_get_object (builder, "program1"));
    data->user1 = GTK_WIDGET(gtk_builder_get_object (builder, "user1"));
    data->update_text = GTK_WIDGET(gtk_builder_get_object (builder, "update_text"));

    /* Install page */
    data->program2 = GTK_WIDGET(gtk_builder_get_object (builder, "program2"));
    data->user2 = GTK_WIDGET(gtk_builder_get_object (builder, "user2"));
    data->install_text = GTK_WIDGET(gtk_builder_get_object (builder, "install_text"));

    /* Finish page  */
    data->finish_page = GTK_WIDGET(gtk_builder_get_object (builder, "finish_page"));

    gtk_builder_connect_signals(builder, data);
    g_object_unref(G_OBJECT(builder));

    gtk_widget_show_all(dialog);

    /* This won't return until the dialog is finished */
    gtk_main();

    /* Destroy the Assistant dialog */
    gtk_widget_destroy(GTK_WIDGET(data->dialog));

    /* Kill the backend daemon. When it restarts it will find our changes */
    if (!g_spawn_command_line_sync("gconftool-2 --shutdown", NULL, NULL,
                                   NULL, &error))
    {
        gnc_warning_dialog(NULL, "%s", error->message);
        g_error_free(error);
    }

    return dialog;
}