Widgets (3)

Open signal

G_APPLICATION_HANDLES_OPEN flag

We made a very simple editor in the previous section with GtkTextView, GtkTextBuffer and GtkScrolledWindow. We will add file-reading ability to the program and improve it to a file viewer.

The easiest way to give a filename is to use a command line argument.

$ ./a.out filename

The program will open the file and insert its contents into the GtkTextBuffer.

To do this, we need to know how GtkApplication (or GApplication) recognizes arguments. This is described in the GIO API Reference – Application.

When GtkApplication is created, a flag (GApplicationFlags) is given as an argument.

GtkApplication *
gtk_application_new (const gchar *application_id, GApplicationFlags flags);

This tutorial explains only two flags, G_APPLICATION_DEFAULT_FLAGS and G_APPLICATION_HANDLES_OPEN. (G_APPLICATION_FLAGS_NONE was used instead of G_APPLICATION_DEFAULT_FLAGS before GIO version2.73.3 (GLib 2.73.3 5/Aug/2022). Some GTK 4 applications still use G_APPLICATION_FLAGS_NONE. But now it is deprecated and G_APPLICATION_DEFAULT_FLAGS is recommended.) If you want to handle command line arguments, the G_APPLICATION_HANDLES_COMMAND_LINE flag is what you need.

For further information, see GIO API Reference – ApplicationFlags and GIO API Reference – g_application_run.

We’ve already used G_APPLICATION_DEFAULT_FLAGS, as it is the simplest option, and no command line arguments are allowed. If you give arguments, an error will occur.

The flag G_APPLICATION_HANDLES_OPEN is the second simplest option. It allows arguments but only files. The application assumes all the arguments are filenames.

app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);

open signal

When G_APPLICATION_HANDLES_OPEN flag is given to the application, two signals are available.

The handler of the “open” signal is defined as follows.

void
open (
  GApplication* self,
  gpointer files,
  gint n_files,
  gchar* hint,
  gpointer user_data
)

The parameters are:

Making a file viewer

What is a file viewer?

A file viewer is a program that displays text files. Our file viewer will work as follows.

The program is shown below.

@@@include tfv/tfv3.c @@@

Save it as tfv3.c. Then compile and run it.

$ comp tfv3
$ ./a.out tfv3.c
File viewer

The function main has only two changes from the previous version.

When the flag G_APPLICATION_HANDLES_OPEN is given to gtk_application_new function, the application behaves like this:

The handler app_activate becomes very simple. It just outputs the error message and return to the caller. Then the application quits immediately because no window is created.

The main work is done in the handler app_open.

The following is the file reading part of the program again.

if (g_file_load_contents (files[0], NULL, &contents, &length, NULL, NULL)) {
  gtk_text_buffer_set_text (tb, contents, length);
  g_free (contents);
  if ((filename = g_file_get_basename (files[0])) != NULL) {
    gtk_window_set_title (GTK_WINDOW (win), filename);
    g_free (filename);
  }
  gtk_widget_show (win);
} else {
  if ((filename = g_file_get_path (files[0])) != NULL) {
    g_printerr ("No such file: %s.\n", filename);
    g_free (filename);
  } else
    g_printerr ("File can't be opened.\n");
  gtk_window_destroy (GTK_WINDOW (win));
}

The function g_file_load_contents loads the file contents into a temporary buffer, which is automatically allocated and sets contents to point the buffer. The length of the buffer is assigned to length. It returns TRUE if the file’s contents are successfully loaded or FALSE if an error occurs. If you want to know the details about g_file_load_contents, see g file load contents.

If it has successfully read the file, it inserts the contents into GtkTextBuffer, frees the temporary buffer pointed by contents, sets the title of the window, frees the memories pointed by filename and then shows the window. If it fails, it outputs an error message and destroys the window and finally make the program quit.

GtkNotebook

GtkNotebook is a container widget that contains multiple widgets with tabs. It shows only one child at a time. Another child will be shown when its tab is clicked.

GtkNotebook

The left image is the window at the startup. The file pr1.c is shown and its filename is in the left tab. After clicking on the right tab, the contents of the file tfv1.c is shown. The right image is the screenshot.

The following is tfv4.c. It has GtkNoteBook widget. It is inserted as a child of GtkApplicationWindow and contains multiple GtkScrolledWindow.

@@@include tfv/tfv4.c @@@

Most of the changes are in the function app_open. The numbers at the left of the following items are line numbers in the source code.