Holger
Holger

Reputation: 1000

Using GCancellable with the GtkAlertDialog

For testing purposes, I wrote a small program calling a GtkAlertDialog and showing the results of the user selection.

I noticed the topic of GCancellable.

Despite studying the documentation, I did not succeed in finding a meaningful use for it. Here is the corresponding programme section:

#include"g-cancellable.h"

void presst(GObject* quelle, GAsyncResult* res, gpointer user_data)
{
      GtkAlertDialog *dialog = GTK_ALERT_DIALOG(quelle);
      GError *err = NULL;
      int button = gtk_alert_dialog_choose_finish (dialog, res, &err);

     if (err) 
     {
                g_print("An error occured!\n");
                g_print("Error Message: %s\n", err->message);
                g_free(err);
                return;
     }

     if (button == 1) 
        g_print("Cancel\n");
     if (button == 0)
        g_print("O.k.\n");
      
    g_object_unref(dialog);  // GtkAlertDialog dispose.
}

void clicked (GtkWidget *button, gpointer user_data)
{
    GtkWidget* box =gtk_widget_get_parent(button);
    GtkWidget* window = gtk_widget_get_parent(box);

    GCancellable *cancel = G_CANCELLABLE(user_data);

    GtkAlertDialog* alert_dialog = gtk_alert_dialog_new (
                                  "DANGER!\nA mistake\n");

   const char* buttons[] = {"O.k.","Cancel",NULL};

   gtk_alert_dialog_set_buttons(alert_dialog,buttons);
   // Esc - Button 
   gtk_alert_dialog_set_cancel_button (alert_dialog,1);
   // Enter - Button
   gtk_alert_dialog_set_default_button(alert_dialog,0);

   // Dialog 
   gtk_alert_dialog_choose (alert_dialog,
                   GTK_WINDOW(window),  
                   G_CANCELLABLE(cancel),  // Which function ??
                   (GAsyncReadyCallback)presst,  
                   NULL);
}

void activate (GtkApplication *app, gpointer data)
{
  GtkWidget *window;

  window =gtk_application_window_new(app);
  gtk_widget_set_size_request(window,50,50);
 
  GCancellable*  cancel = g_cancellable_new ();

  GtkWidget *button = gtk_button_new_with_label("Click me");
  g_signal_connect(button,"clicked",G_CALLBACK(clicked),cancel);
  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10);
  gtk_box_append(GTK_BOX(box),button);
  gtk_window_set_child(GTK_WINDOW(window),box);

  gtk_widget_set_visible(window,TRUE);
}

Can anyone help me here?

Upvotes: 1

Views: 51

Answers (1)

Holger
Holger

Reputation: 1000

GCancellable is an object that is intended to stop a process. 4 steps in principle are necessary for this:

Step 1 Create GCancellable-Object:

GCancellable*  cancel = g_cancellable_new ();

Step 2 Connect the GCancellable-Object to a process:

 // Dialog 
  gtk_alert_dialog_choose (alert_dialog,
                   GTK_WINDOW(window),  
                   G_CANCELLABLE(cancel),  // connecting to gcancellable
                  (GAsyncReadyCallback)user_action, // for user reaction 
                   cancel);
}

Step 3 Connect the signal emitting from GCancellable

g_cancellable_connect(cancel,
                        G_CALLBACK(gecancelld), // unused 
                        GINT_TO_POINTER(timer),
                        (GDestroyNotify) timer_destroy_func); // destroy timer
                                                       // if GCancellable is
                                                       // unref 

Step 4 set GCancellable to cancelled, to cancel the process.

    g_cancellable_cancel(cancel);
    g_object_unref(cancel);  // GCancellable dispose  

In connection with GtkAlertDialog, this can now be used as follows:

#include"g-cancellable.h"

// if timeout
gboolean time_out(gpointer user_data)
{
    GCancellable *cancel = G_CANCELLABLE(user_data);
    g_cancellable_cancel(cancel);
    g_object_unref(cancel);
    return TRUE;
}

// for user interaction
void user_action(GObject* quelle, GAsyncResult* res, gpointer user_data)
{
      GtkAlertDialog *dialog = GTK_ALERT_DIALOG(quelle);
      GError *err = NULL;
      int button = gtk_alert_dialog_choose_finish (dialog, res, &err);

     if (err) 
     {
                g_print("An error occured!\n");
                g_print("Error Message: %s\n", err->message);
                g_free(err);
                g_object_unref(dialog);
                return;
     }

     if (button == 1) 
        g_print("Cancel\n");
     if (button == 0)
        g_print("O.k.\n");
      
    GCancellable *cancel = G_CANCELLABLE(user_data);
    g_cancellable_cancel(cancel);
    g_object_unref(cancel);  // GCancellable dispose  
    g_object_unref(dialog);  // GtkAlertDialog dispose.
}

void timer_destroy_func(gpointer data)
{
    guint timer = GPOINTER_TO_INT(data);
    g_source_remove(timer);
}

void gecancelld()
{
    // unused
};

void dialog_called (GtkWidget *button, gpointer user_data)
{
  GtkWidget* box =gtk_widget_get_parent(button);
  GtkWidget* window = gtk_widget_get_parent(box);
  // create Object GCancellable
  GCancellable*  cancel = g_cancellable_new ();
 
  guint timer = g_timeout_add(10000, G_SOURCE_FUNC(time_out), (gpointer)cancel);

  g_cancellable_connect(cancel,
                        G_CALLBACK(gecancelld), // unused 
                        GINT_TO_POINTER(timer),
                        (GDestroyNotify) timer_destroy_func); // destroy timer
                                  // if GCancellable is
                                  // unref 
  GtkAlertDialog* alert_dialog = gtk_alert_dialog_new (
                                  "DANGER!\nA mistake\n");

  const char* buttons[] = {"O.k.","Cancel",NULL};

  gtk_alert_dialog_set_buttons(alert_dialog,buttons);
  // Esc - Button 
  gtk_alert_dialog_set_cancel_button (alert_dialog,1);
  // Enter - Button
  gtk_alert_dialog_set_default_button(alert_dialog,0);
  // Dialog 
  gtk_alert_dialog_choose (alert_dialog,
                   GTK_WINDOW(window),  
                   G_CANCELLABLE(cancel),  // connecting to gcancellable
                   (GAsyncReadyCallback)user_action, // for user reaction 
                   cancel);
}

void activate (GtkApplication *app, gpointer data)
{
  GtkWidget *window;

  window =gtk_application_window_new(app);
  gtk_widget_set_size_request(window,50,50);

  GtkWidget *button = gtk_button_new_with_label("Click me");
  g_signal_connect(button,"clicked",G_CALLBACK(dialog_called),NULL);
  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10);
  gtk_box_append(GTK_BOX(box),button);
  gtk_window_set_child(GTK_WINDOW(window),box);

  gtk_widget_set_visible(window,TRUE);
}

The program section shows a GtkAlertDialog, which, if the user does not react, is closed again after a timeout. At the same time, an error message is issued, which can then be used in the program.

Enjoy testing and programming.

Upvotes: 0

Related Questions