2021-01-13 12:59:15 +01:00
|
|
|
Up: [Readme.md](../Readme.md), Prev: [Section 6](sec6.md), Next: [Section 8](sec8.md)
|
2021-01-11 03:15:04 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
# Widgets (3)
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
## Open signal
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
### G\_APPLICATION\_HANDLES\_OPEN flag
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The GtkTextView, GtkTextBuffer and GtkScrolledWindow widgets have given us a minimum editor
|
|
|
|
in the previous section.
|
|
|
|
We will now add a function to read a file and rework the program into a file viewer.
|
|
|
|
There are many ways to implement the function and
|
|
|
|
because this is a tutorial for beginners, we'll take the easiest one.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
When the program starts, we will give the filename to open as an argument.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
$ ./a.out filename
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
It will open the file and insert its contents into the GtkTextBuffer.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
To do this, we need to know how GtkApplication (or GApplication) recognizes arguments.
|
|
|
|
This is described in the [GIO API Reference, Application](https://docs.gtk.org/gio/class.Application.html).
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
When GtkApplication is created, a flag (with the type GApplicationFlags) is provided as an argument.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-01-25 13:20:15 +01:00
|
|
|
~~~C
|
2021-06-15 04:24:42 +02:00
|
|
|
GtkApplication *
|
|
|
|
gtk_application_new (const gchar *application_id, GApplicationFlags flags);
|
2021-01-25 13:20:15 +01:00
|
|
|
~~~
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-07-17 17:00:20 +02:00
|
|
|
This tutorial explains only two flags, `G_APPLICATION_FLAGS_NONE` and `G_APPLICATION_HANDLES_OPEN`.
|
2022-03-04 15:38:31 +01:00
|
|
|
If you want to handle command line arguments, the `G_APPLICATION_HANDLES_COMMAND_LINE` flag is what you need.
|
|
|
|
How to use the new application method is described in [GIO API Reference, g\_application\_run](https://docs.gtk.org/gio/method.Application.run.html),
|
|
|
|
and the flag is described in the [GIO API Reference, ApplicationFlags](https://docs.gtk.org/gio/flags.ApplicationFlags.html).
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
~~~
|
|
|
|
GApplicationFlags' Members
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
G_APPLICATION_FLAGS_NONE Default. (No argument allowed)
|
|
|
|
... ... ...
|
|
|
|
G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance).
|
|
|
|
... ... ...
|
|
|
|
~~~
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
There are ten flags in total, but we only need two of them so far.
|
|
|
|
We've already used `G_APPLICATION_FLAGS_NONE`, as
|
|
|
|
it is the simplest option, and no arguments are allowed.
|
|
|
|
If you provide arguments when running the application, an error will occur.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The flag `G_APPLICATION_HANDLES_OPEN` is the second simplest option.
|
2021-06-15 04:24:42 +02:00
|
|
|
It allows arguments but only files.
|
2022-03-04 15:38:31 +01:00
|
|
|
The application assumes all the arguments are filenames and we will use this flag when creating
|
|
|
|
our GtkApplication.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-01-25 10:35:49 +01:00
|
|
|
~~~C
|
2021-06-15 04:24:42 +02:00
|
|
|
app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
|
|
|
|
~~~
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
### open signal
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
Now, when the application starts, two signals can be emitted.
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
- activate signal --- This signal is emitted when there's no argument.
|
|
|
|
- open signal --- This signal is emitted when there is at least one argument.
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The handler of the "open" signal is defined as follows.
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
~~~C
|
|
|
|
void user_function (GApplication *application,
|
|
|
|
gpointer files,
|
|
|
|
gint n_files,
|
|
|
|
gchar *hint,
|
|
|
|
gpointer user_data)
|
|
|
|
~~~
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
The parameters are:
|
2021-01-25 10:35:49 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
- `application` --- the application (usually GtkApplication)
|
|
|
|
- `files` --- an array of GFiles. [array length=n\_files] [element-type GFile]
|
|
|
|
- `n_files` --- the number of the elements of `files`
|
|
|
|
- `hint` --- a hint provided by the calling instance (usually it can be ignored)
|
|
|
|
- `user_data` --- user data set when the signal handler was connected.
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
How to read a specified file (GFile) will be described next.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
|
|
|
## Making a file viewer
|
|
|
|
|
|
|
|
### What is a file viewer?
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
A file viewer is a program that displays the text file that is given as an argument.
|
|
|
|
Our file viewer will work as follows.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
- When arguments are given, it treats the first argument as a filename and opens it.
|
|
|
|
- If opening the file succeeds, it reads the contents of the file and inserts it to GtkTextBuffer and then shows the window.
|
|
|
|
- If it fails to open the file, it will show an error message and quit.
|
|
|
|
- If there's no argument, it will shows an error message and quit.
|
|
|
|
- If there are two or more arguments, the second one and any others are ignored.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The program which does this is shown below.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-01-25 13:20:15 +01:00
|
|
|
~~~C
|
2021-06-15 04:24:42 +02:00
|
|
|
1 #include <gtk/gtk.h>
|
|
|
|
2
|
|
|
|
3 static void
|
|
|
|
4 app_activate (GApplication *app, gpointer user_data) {
|
|
|
|
5 g_print ("You need a filename argument.\n");
|
|
|
|
6 }
|
|
|
|
7
|
|
|
|
8 static void
|
|
|
|
9 app_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) {
|
|
|
|
10 GtkWidget *win;
|
|
|
|
11 GtkWidget *scr;
|
|
|
|
12 GtkWidget *tv;
|
|
|
|
13 GtkTextBuffer *tb;
|
|
|
|
14 char *contents;
|
|
|
|
15 gsize length;
|
|
|
|
16 char *filename;
|
|
|
|
17
|
|
|
|
18 win = gtk_application_window_new (GTK_APPLICATION (app));
|
|
|
|
19 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
|
|
|
20
|
|
|
|
21 scr = gtk_scrolled_window_new ();
|
|
|
|
22 gtk_window_set_child (GTK_WINDOW (win), scr);
|
|
|
|
23
|
|
|
|
24 tv = gtk_text_view_new ();
|
|
|
|
25 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
|
|
|
26 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
|
|
|
|
27 gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE);
|
|
|
|
28 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv);
|
|
|
|
29
|
|
|
|
30 if (g_file_load_contents (files[0], NULL, &contents, &length, NULL, NULL)) {
|
|
|
|
31 gtk_text_buffer_set_text (tb, contents, length);
|
|
|
|
32 g_free (contents);
|
|
|
|
33 if ((filename = g_file_get_basename (files[0])) != NULL) {
|
|
|
|
34 gtk_window_set_title (GTK_WINDOW (win), filename);
|
|
|
|
35 g_free (filename);
|
|
|
|
36 }
|
|
|
|
37 gtk_widget_show (win);
|
|
|
|
38 } else {
|
|
|
|
39 if ((filename = g_file_get_path (files[0])) != NULL) {
|
|
|
|
40 g_print ("No such file: %s.\n", filename);
|
|
|
|
41 g_free (filename);
|
|
|
|
42 }
|
|
|
|
43 gtk_window_destroy (GTK_WINDOW (win));
|
|
|
|
44 }
|
|
|
|
45 }
|
|
|
|
46
|
|
|
|
47 int
|
|
|
|
48 main (int argc, char **argv) {
|
|
|
|
49 GtkApplication *app;
|
|
|
|
50 int stat;
|
|
|
|
51
|
|
|
|
52 app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
|
|
|
|
53 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
|
|
|
54 g_signal_connect (app, "open", G_CALLBACK (app_open), NULL);
|
2022-03-04 15:38:31 +01:00
|
|
|
55 stat = g_application_run (G_APPLICATION (app), argc, argv);
|
2021-06-15 04:24:42 +02:00
|
|
|
56 g_object_unref (app);
|
|
|
|
57 return stat;
|
|
|
|
58 }
|
2021-01-25 13:20:15 +01:00
|
|
|
~~~
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
Save it as `tfv3.c`.
|
|
|
|
Then compile and run it.
|
|
|
|
|
|
|
|
$ comp tfv3
|
|
|
|
$ ./a.out tfv3.c
|
|
|
|
|
|
|
|
![File viewer](../image/screenshot_tfv3.png)
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
Let's explain how the program `tfv3.c` works.
|
|
|
|
First, the function `main` has only two changes from the previous version.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
- `G_APPLICATION_FLAGS_NONE` is replaced by `G_APPLICATION_HANDLES_OPEN`; and
|
2021-06-15 04:24:42 +02:00
|
|
|
- `g_signal_connect (app, "open", G_CALLBACK (on_open), NULL)` is added.
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
Next, the handler `app_activate` is added and is very simple.
|
|
|
|
It just outputs the error message and
|
|
|
|
the application quits immediately because no window is created.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The main functionality is the in the handler `app_open`. It
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
- Creates GtkApplicationWindow, GtkScrolledWindow, GtkTextView and GtkTextBuffer and connects them together;
|
|
|
|
- Sets wrap mode to `GTK_WRAP_WORD_CHAR` in GtktextView;
|
|
|
|
- Sets GtkTextView to non-editable because the program isn't an editor but only a viewer;
|
|
|
|
- Reads the file and inserts the text into GtkTextBuffer (this will be explained in detail later); and
|
|
|
|
- If the file is not opened then outputs an error message and destroys the window. This makes the application quit.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The following is the important file reading part of the program and is shown again below.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-01-25 10:35:49 +01:00
|
|
|
~~~C
|
2021-06-15 04:24:42 +02:00
|
|
|
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_print ("No such file: %s.\n", filename);
|
|
|
|
g_free (filename);
|
|
|
|
}
|
|
|
|
gtk_window_destroy (GTK_WINDOW (win));
|
|
|
|
}
|
2021-01-25 10:35:49 +01:00
|
|
|
~~~
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The function `g_file_load_contents` loads the file contents into a buffer,
|
|
|
|
which is automatically allocated and sets `contents` to point that buffer.
|
|
|
|
The length of the buffer is set to `length`.
|
|
|
|
It returns `TRUE` if the file's contents are successfully loaded and `FALSE` if an error occurs.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
If this function succeeds, it inserts the contents into GtkTextBuffer,
|
|
|
|
frees the 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, causing the program to quit.
|
2021-06-15 04:24:42 +02:00
|
|
|
|
|
|
|
## GtkNotebook
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
GtkNotebook is a container widget that uses tabs and contains multiple children.
|
|
|
|
The child that is displayed depends on which tab has been selected.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-06-15 04:24:42 +02:00
|
|
|
![GtkNotebook](../image/screenshot_gtk_notebook.png)
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
Looking at the screenshots above,
|
|
|
|
the left one is the window at the startup.
|
|
|
|
It shows the file `pr1.c` and the filename is in the left tab.
|
|
|
|
After clicking on the right tab, the contents of the file `tfv1.c` are shown instead.
|
|
|
|
This is shown in the right screenshot.
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
The GtkNotebook widget is inserted as a child of GtkApplicationWindow and contains a GtkScrolledWindow
|
|
|
|
for each file that is being displayed.
|
|
|
|
The code to do this is given in `tfv4.c` and is:
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2021-01-25 10:35:49 +01:00
|
|
|
~~~C
|
2021-06-15 04:24:42 +02:00
|
|
|
1 #include <gtk/gtk.h>
|
|
|
|
2
|
|
|
|
3 static void
|
|
|
|
4 app_activate (GApplication *app, gpointer user_data) {
|
|
|
|
5 g_print ("You need a filename argument.\n");
|
|
|
|
6 }
|
|
|
|
7
|
|
|
|
8 static void
|
|
|
|
9 app_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) {
|
|
|
|
10 GtkWidget *win;
|
|
|
|
11 GtkWidget *nb;
|
|
|
|
12 GtkWidget *lab;
|
|
|
|
13 GtkNotebookPage *nbp;
|
|
|
|
14 GtkWidget *scr;
|
|
|
|
15 GtkWidget *tv;
|
|
|
|
16 GtkTextBuffer *tb;
|
|
|
|
17 char *contents;
|
|
|
|
18 gsize length;
|
|
|
|
19 char *filename;
|
|
|
|
20 int i;
|
|
|
|
21
|
|
|
|
22 win = gtk_application_window_new (GTK_APPLICATION (app));
|
|
|
|
23 gtk_window_set_title (GTK_WINDOW (win), "file viewer");
|
|
|
|
24 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
|
|
|
25 gtk_window_maximize (GTK_WINDOW (win));
|
|
|
|
26
|
|
|
|
27 nb = gtk_notebook_new ();
|
|
|
|
28 gtk_window_set_child (GTK_WINDOW (win), nb);
|
|
|
|
29
|
|
|
|
30 for (i = 0; i < n_files; i++) {
|
|
|
|
31 if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) {
|
|
|
|
32 scr = gtk_scrolled_window_new ();
|
|
|
|
33 tv = gtk_text_view_new ();
|
|
|
|
34 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
|
|
|
35 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
|
|
|
|
36 gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE);
|
|
|
|
37 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv);
|
|
|
|
38
|
|
|
|
39 gtk_text_buffer_set_text (tb, contents, length);
|
|
|
|
40 g_free (contents);
|
|
|
|
41 if ((filename = g_file_get_basename (files[i])) != NULL) {
|
|
|
|
42 lab = gtk_label_new (filename);
|
|
|
|
43 g_free (filename);
|
|
|
|
44 } else
|
|
|
|
45 lab = gtk_label_new ("");
|
|
|
|
46 gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab);
|
|
|
|
47 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr);
|
|
|
|
48 g_object_set (nbp, "tab-expand", TRUE, NULL);
|
|
|
|
49 } else if ((filename = g_file_get_path (files[i])) != NULL) {
|
|
|
|
50 g_print ("No such file: %s.\n", filename);
|
|
|
|
51 g_free (filename);
|
|
|
|
52 } else
|
|
|
|
53 g_print ("No valid file is given\n");
|
|
|
|
54 }
|
|
|
|
55 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0)
|
|
|
|
56 gtk_widget_show (win);
|
|
|
|
57 else
|
|
|
|
58 gtk_window_destroy (GTK_WINDOW (win));
|
|
|
|
59 }
|
|
|
|
60
|
|
|
|
61 int
|
|
|
|
62 main (int argc, char **argv) {
|
|
|
|
63 GtkApplication *app;
|
|
|
|
64 int stat;
|
|
|
|
65
|
|
|
|
66 app = gtk_application_new ("com.github.ToshioCP.tfv4", G_APPLICATION_HANDLES_OPEN);
|
|
|
|
67 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
|
|
|
68 g_signal_connect (app, "open", G_CALLBACK (app_open), NULL);
|
2022-03-04 15:38:31 +01:00
|
|
|
69 stat = g_application_run (G_APPLICATION (app), argc, argv);
|
2021-06-15 04:24:42 +02:00
|
|
|
70 g_object_unref (app);
|
|
|
|
71 return stat;
|
|
|
|
72 }
|
|
|
|
~~~
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
Most of the changes are in the function `app_open`.
|
2021-06-15 04:24:42 +02:00
|
|
|
The numbers at the left of the following items are line numbers in the source code.
|
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
- 11-13: Variables `nb`, `lab` and `nbp` are defined and will point to a new GtkNotebook, GtkLabel and GtkNotebookPage widget respectively.
|
2021-06-15 04:24:42 +02:00
|
|
|
- 23: The window's title is set to "file viewer".
|
|
|
|
- 25: The size of the window is set to maximum because a big window is appropriate for file viewers.
|
|
|
|
- 27-28 GtkNotebook is created and inserted to the GtkApplicationWindow as a child.
|
2022-03-04 15:38:31 +01:00
|
|
|
- 30-59 For-loop. Each loop corresponds to a filename argument, and `files[i]` is GFile object containing the i-th argument.
|
|
|
|
- 32-37 GtkScrollledWindow, GtkTextView are created and GtkTextBuffer found from the new GtkTextView.
|
2021-06-15 04:24:42 +02:00
|
|
|
GtkTextView is connected to GtkScrolledWindow as a child.
|
2022-03-04 15:38:31 +01:00
|
|
|
Each file gets their own copy of these widgets, so they are created inside the for-loop.
|
2021-06-15 04:24:42 +02:00
|
|
|
- 39-40 inserts the contents of the file into GtkTextBuffer and frees the memory pointed by `contents`.
|
2022-03-04 15:38:31 +01:00
|
|
|
- 41-43: Gets the filename and creates GtkLabel with the filename and then frees `filename`.
|
2021-06-15 04:24:42 +02:00
|
|
|
- 44-45: If `filename` is NULL, creates GtkLabel with the empty string.
|
2022-03-04 15:38:31 +01:00
|
|
|
- 46: Appends GtkScrolledWindow as a page, with the tab GtkLabel, to GtkNotebook.
|
|
|
|
At this time a GtkNoteBookPage widget is created automatically.
|
2021-06-15 04:24:42 +02:00
|
|
|
The GtkScrolledWindow widget is connected to the GtkNotebookPage.
|
|
|
|
Therefore, the structure is like this:
|
|
|
|
|
|
|
|
~~~
|
|
|
|
GtkNotebook -- GtkNotebookPage -- GtkScrolledWindow
|
2021-01-25 10:35:49 +01:00
|
|
|
~~~
|
2021-01-13 05:29:35 +01:00
|
|
|
|
2022-03-04 15:38:31 +01:00
|
|
|
- 47: Gets GtkNotebookPage widget and sets `nbp` to point to this GtkNotebookPage.
|
|
|
|
- 48: GtkNotebookPage has a property set called "tab-expand".
|
2021-06-15 04:24:42 +02:00
|
|
|
If it is set to TRUE then the tab expands horizontally as long as possible.
|
|
|
|
If it is FALSE, then the width of the tab is determined by the size of the label.
|
2022-03-04 15:38:31 +01:00
|
|
|
`g_object_set` is a general function to set properties in objects.
|
2021-08-12 07:04:22 +02:00
|
|
|
See [GObject API Reference, g\_object\_set](https://docs.gtk.org/gobject/method.Object.set.html).
|
2022-03-04 15:38:31 +01:00
|
|
|
- 49-51: If the file cannot be read, "No such file" message is displayed and the `filename` buffer is freed.
|
|
|
|
- 52-53: If `filename` is NULL, the "No valid file is given" message is outputted.
|
2021-06-15 04:24:42 +02:00
|
|
|
- 55-58: If at least one file was read, then the number of GtkNotebookPage is greater than zero.
|
|
|
|
If it's true, it shows the window.
|
2022-03-04 15:38:31 +01:00
|
|
|
If it's false, it destroys the window, which causes the program to quit.
|
2021-01-11 03:15:04 +01:00
|
|
|
|
2021-01-13 12:59:15 +01:00
|
|
|
Up: [Readme.md](../Readme.md), Prev: [Section 6](sec6.md), Next: [Section 8](sec8.md)
|