diff --git a/.gitignore b/.gitignore index 9e57c93..0472bd1 100755 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ src/tfe5/hello.txt src/tfe6/_build src/tfe7/_build src/menu/a.out +src/menu3/_build src/color/_build src/turtle/_build src/temp diff --git a/Readme.md b/Readme.md index 391dee8..d2e813d 100644 --- a/Readme.md +++ b/Readme.md @@ -9,7 +9,7 @@ The table of contents are shown at the end of this abstract. - Section 24 to 27 describes list model and list view (GtkListView, GtkGridView and GtkColumnView). It also describes GtkExpression. -Please refer to [Gtk API reference](https://developer.gnome.org/gtk4/stable/index.html) +Please refer to [Gtk reference manual](https://developer.gnome.org/gtk4/stable/index.html) and [Gnome Developer Center](https://developer.gnome.org/) for further topics. This tutorial is under development and unstable. diff --git a/gfm/sec12.md b/gfm/sec12.md index 96a7102..696b118 100644 --- a/gfm/sec12.md +++ b/gfm/sec12.md @@ -91,7 +91,7 @@ Signals are registered in the class initialization function. The signal "change-file" has no default handler (object method handler). You usually don't need to set a default handler. If you need it, use `g_signal_new_class_handler` function. -See [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-new-class-handler) for further information. +See [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-new-class-handler) for further information. - The return value of `g_signal_new` is the signal id. The type of signal id is guint, which is the same as unsigned int. It is used in the function `g_signal_emit`. @@ -101,7 +101,7 @@ This signal has a parameter. "open-response" signal has one parameter. - 25: The type of the parameter. `G_TYPE_INT` is a type of integer. -Such fundamental types are described in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html). +Such fundamental types are described in [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html). The handlers are declared as follows. diff --git a/gfm/sec13.md b/gfm/sec13.md index 203bea7..0bb4275 100644 --- a/gfm/sec13.md +++ b/gfm/sec13.md @@ -115,7 +115,7 @@ Each function is defined as follows. Just returns the value from the function `g_object_new` but casts it to the pointer to GtkWidget. Initialization is done in `tfe_text_view_init` which is called in the process of `g_object_new` function. - 1-21: `tfe_text_view_new_with_file` function. -- 3: `g_return_val_if_fail` is described in [Glib API reference](https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail). +- 3: `g_return_val_if_fail` is described in [Glib reference manual](https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail). It tests whether the argument `file` is a pointer to GFile. If it's true, then the program goes on to the next line. If it's false, then it returns NULL (the second argument) immediately. @@ -438,7 +438,7 @@ The important thing is to duplicate `tv->file`. Otherwise, if the caller frees the GFile object, `tv->file` is no more guaranteed to point the GFile. Another reason to use `g_file_dup` is that GFile isn't thread-safe. If you use GFile in the different thread, the duplication is necessary. -See [Gio API reference](https://developer.gnome.org/gio/stable/GFile.html#g-file-dup). +See [Gio reference manual](https://developer.gnome.org/gio/stable/GFile.html#g-file-dup). ## The API document and source file of tfetextview.c diff --git a/gfm/sec14.md b/gfm/sec14.md index 384ce29..242f865 100644 --- a/gfm/sec14.md +++ b/gfm/sec14.md @@ -199,7 +199,7 @@ On the other hand, when an instance of GObject (not GInitiallyUnowned) is create And the instance has a normal reference count instead of floating reference. If you use `g_object_unref` to an instance that has a floating reference, you need to convert the floating reference to a normal reference in advance. -See [GObject API reference manual](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#gobject-The-Base-Object-Type.description) for further information. +See [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#gobject-The-Base-Object-Type.description) for further information. ## notebook\_page\_close diff --git a/gfm/sec15.md b/gfm/sec15.md index e97f577..accd1c7 100644 --- a/gfm/sec15.md +++ b/gfm/sec15.md @@ -124,7 +124,7 @@ textview {color: yellow; ...} ~~~ Class, ID and some other things can be applied to the selector like Web CSS. -Refer [Gtk4 API reference](https://developer.gnome.org/gtk4/stable/theming.html) for further information. +Refer [Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/theming.html) for further information. In line 30, the CSS is a string. diff --git a/gfm/sec17.md b/gfm/sec17.md index 65ffcc5..c4171ff 100644 --- a/gfm/sec17.md +++ b/gfm/sec17.md @@ -195,7 +195,7 @@ Therefore, `act_quit` has a name "quit" and no parameter. - 17: Adds the action to GtkApplication `app`. GtkApplication implements an interface GActionMap and GActionGroup. GtkApplication (GActionMap) can have a group of actions and the actions are added with the function `g_action_map_add_action`. -This function is described in [GMenuModel section in GIO API reference](https://developer.gnome.org/gio/stable/GActionMap.html#g-action-map-add-action). +This function is described in [GMenuModel section in GIO reference manual](https://developer.gnome.org/gio/stable/GActionMap.html#g-action-map-add-action). - 18: Connects "activate" signal of the action and the handler `quit_activated`. - 20-23: Creates GMenu and GMenuItem instances. `menubar` and `menu` are GMenu. diff --git a/gfm/sec19.md b/gfm/sec19.md index cdec84d..2c1abba 100644 --- a/gfm/sec19.md +++ b/gfm/sec19.md @@ -216,7 +216,7 @@ g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, The code above does: - Builds the "quit" action -- Connects the action and the "activate" signal handler `quit_activate` +- Connects the action and the "activate" signal handler `quit_activated` - Adds the action to the action map `app`. The same goes for the other actions. @@ -234,7 +234,7 @@ The code above does: - Builds a "fullscreen" action and "color" action. - Connects the "fullscreen" action and the "change-state" signal handler `fullscreen_changed` - Its initial state is set to FALSE. -- Connects the "color" action and the "activate" signal handler `color_activate` +- Connects the "color" action and the "activate" signal handler `color_activated` - Its parameter type is string and the initial value is "red". - Adds the actions to the action map `win`. @@ -297,7 +297,7 @@ The C source code of `menu3` and `meson.build` is as follows. 52 } 53 54 static void - 55 on_activate (GApplication *app, gpointer user_data) { + 55 app_activate (GApplication *app, gpointer user_data) { 56 GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); 57 58 const GActionEntry win_entries[] = { @@ -322,7 +322,7 @@ The C source code of `menu3` and `meson.build` is as follows. 77 } 78 79 static void - 80 on_startup (GApplication *app, gpointer user_data) { + 80 app_startup (GApplication *app, gpointer user_data) { 81 GtkBuilder *builder = gtk_builder_new_from_resource ("/com/github/ToshioCP/menu3/menu3.ui"); 82 GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); 83 @@ -335,20 +335,22 @@ The C source code of `menu3` and `meson.build` is as follows. 90 g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, G_N_ELEMENTS (app_entries), app); 91 } 92 - 93 int - 94 main (int argc, char **argv) { - 95 GtkApplication *app; - 96 int stat; - 97 - 98 app = gtk_application_new ("com.github.ToshioCP.menu3", G_APPLICATION_FLAGS_NONE); - 99 g_signal_connect (app, "startup", G_CALLBACK (on_startup), NULL); -100 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); -101 -102 stat =g_application_run (G_APPLICATION (app), argc, argv); -103 g_object_unref (app); -104 return stat; -105 } -106 + 93 #define APPLICATION_ID "com.github.ToshioCP.menu3" + 94 + 95 int + 96 main (int argc, char **argv) { + 97 GtkApplication *app; + 98 int stat; + 99 +100 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE); +101 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL); +102 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL); +103 +104 stat =g_application_run (G_APPLICATION (app), argc, argv); +105 g_object_unref (app); +106 return stat; +107 } +108 ~~~ meson.build diff --git a/gfm/sec2.md b/gfm/sec2.md index 7ec88fb..76bcc57 100644 --- a/gfm/sec2.md +++ b/gfm/sec2.md @@ -53,7 +53,7 @@ I installed Gtk4 under the directory `$HOME/local`. This is a private user area. If you want to install it in the system area, `/opt/gtk4` is one of good choices. -[Gtk4 API Reference](https://developer.gnome.org/gtk4/stable/gtk-building.html) gives an installation example to `/opt/gtk4`. +[Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/gtk-building.html) gives an installation example to `/opt/gtk4`. Don't install it to `/usr/local` which is the default. It is used by Ubuntu applications, which are not build on Gtk4. diff --git a/gfm/sec20.md b/gfm/sec20.md index 7f1f536..573995f 100644 --- a/gfm/sec20.md +++ b/gfm/sec20.md @@ -3,7 +3,7 @@ Up: [Readme.md](../Readme.md), Prev: [Section 19](sec19.md), Next: [Section 21] # GtkMenuButton, accelerators, font, pango and gsettings Traditional menu structure is fine. -However, Buttons or menu items we often use are not so many. +However, buttons or menu items we often use are not so many. Some mightn't be clicked at all. Therefore, it's a good idea to put some frequently used buttons on the toolbar and put the rest of the less frequently used operations into the menu. Such menu are often connected to GtkMenuButton. @@ -89,11 +89,11 @@ Menus are described in `menu.ui` file. There are four items, "New", "Saveas", "Preference" and "Quit". -- New menu creates a new empty page. -- Saveas menu saves the current page as a new filename. -- Preference menu sets preference items. +- "New" menu creates a new empty page. +- "Saveas" menu saves the current page as a new filename. +- "Preference" menu sets preference items. This version of `tfe` has only font preference. -- Quit menu quits the application. +- "Quit" menu quits the application. These four menus are not used so often. That's why they are put to the menu behind the menu button. @@ -183,7 +183,7 @@ You can define more than one accelerator keys and the list must ends with NULL ( If you want to do so, the array length needs to be three or more. The parser recognizes "\o", "\\F2", "\minus" and so on. If you want to use symbol key like "\-", use "\minus" instead. -Such relation between lower case and symbol (its character code) is specified in [`gdkkeysyms.h`](https://gitlab.gnome.org/GNOME/gtk/-/blob/master/gdk/gdkkeysyms.h) in the gtk4 source code. +Such relation between lower case and symbol (its character code) is specified in [`gdkkeysyms.h`](https://gitlab.gnome.org/GNOME/gtk/-/blob/master/gdk/gdkkeysyms.h) in the Gtk4 source code. ## Saveas handler @@ -221,9 +221,10 @@ In `tfeapplication.c`, saveas handler just call `notebook_page_saveas`. ~~~C 1 static void -2 saveas_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { -3 notebook_page_saveas (GTK_NOTEBOOK (nb)); -4 } +2 saveas_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { +3 GtkNotebook *nb = GTK_NOTEBOOK (user_data); +4 notebook_page_saveas (nb); +5 } ~~~ ## Preference and alert dialog @@ -266,16 +267,17 @@ Preference dialog xml definition is added to `tfe.ui`. ~~~ - Preference dialog is an independent dialog. -It is not a descendant widget of the top GtkApplicationwindow `win`. -Therefore, There's no child tag of the dialog object. -- There are four properties of the dialog specified. +It is not a descendant widget of the top-level GtkApplicationwindow `win`. +Therefore, There's no child tag that surrounds the dialog object. +- There are four properties of the dialog. GtkDialog is a child object (not child widget) of GtkWindow, so it inherits all the properties from GtkWindow. Title, resizable, modal and transient-for properties are inherited from GtkWindow. Transient-for specifies a temporary parent window, which the dialog's location is based on. - internal-child attribute is used in the child tag above. GtkDialog has a GtkBox child widget. -Its id is "content_area" in `gtkdialog.ui`, which is the ui file of GtkDialog in gtk4 source files. -This box is provided to users to add content widgets in it. +Its id is "content_area" in `gtkdialog.ui`, which is the ui file of GtkDialog. +(It is in the Gtk4 source files.) +This box is provided for users to add content widgets in it. The tag `` is put at the top of the contents. Then you need to specify an object tag and define its class as GtkBox and its id as content_area. This object is defined in `gtkdialog.ui` but you need to define it again in the child tag. @@ -365,7 +367,7 @@ tfe_startup (GApplication *application) { } ~~~ -The function `tfe_application_quit` destroys top level windows and quits the application. +The function `tfe_application_quit` destroys top-level windows and quits the application. It first disconnects the handlers from the signal "close-request". ### Alert dialog @@ -447,8 +449,8 @@ An alert message will be inserted by the program later. There are two child tags which have "action" type. They are button objects located in the action area. Action-widgets tag describes the actions of the buttons. -Btn\_cancel button emits response signal with cancel response (GTK_RESPONSE_CANCEL) if it is clicked on. -Btn\_accept button emits response signal with accept response (GTK_RESPONSE_ACCEPT) if it is clicked on. +`btn_cancel` button emits response signal with cancel response (`GTK_RESPONSE_CANCEL`) if it is clicked on. +`btn_accept` button emits response signal with accept response (`GTK_RESPONSE_ACCEPT`) if it is clicked on. The response signal is connected to `alert_response_cb` handler. The alert dialog keeps alive while the application lives. @@ -478,8 +480,9 @@ close_cb (GtkNotebook *nb) { ... ... static void -close_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - close_cb (GTK_NOTEBOOK (nb)); +close_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + close_cb (nb); } ... ... @@ -499,15 +502,16 @@ alert_response_cb (GtkDialog *alert, int response_id, gpointer user_data) { } static void -quit_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { +quit_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (nb), GTK_TYPE_WINDOW); is_quit = true; - if (has_saved_all (GTK_NOTEBOOK (nb))) + if (has_saved_all (nb)) tfe_application_quit (GTK_WINDOW (win)); else { gtk_label_set_text (lb_alert, "Contents aren't saved yet.\nAre you sure to quit?"); - gtk_button_set_label (close_btn_close, "Quit"); + gtk_button_set_label (btn_accept, "Quit"); gtk_widget_show (GTK_WIDGET (alert)); } } @@ -535,20 +539,24 @@ When user clicks on the close button, `close_cb` handler is invoked. The handler sets `is_quit` to false. The function `has_saved` returns true if the current page has been saved. If it is true, it calls `notebook_page_close` to close the current page. -Otherwise, it sets the text in the label and button, then shows the alert dialog. +Otherwise, it sets the message of the dialog and the label of the button, then shows the alert dialog. The response signal of the dialog is connected to the handler `alert_response_cb`. It hides the dialog first. -Then check the response\_id. -If it is `GTK_RESPONSE_ACCEPT`, which means user clicked on the close button, then closes the current page. +Then checks the `response_id`. +If it is `GTK_RESPONSE_ACCEPT`, which means user clicked on the close button, then it closes the current page. +Otherwise it does nothing. When user press "Ctrl-q" or clicked on the quit menu, then `quit_activated` handler is invoked. The handler sets `is_quit` to true. The function `has_saved_all` returns true if all the pages have been saved. If it is true, it calls `tfe_application_quit` to quit the application. -Otherwise, it sets the text in the label and button, then shows the alert dialog. +Otherwise, it sets the message of the dialog and the label of the button, then shows the alert dialog. -Now `alert_response_cb` works similar but it calls `tfe_application_quit`instead of `notebook_page_close`. +If the user clicked on the buttons on the alert dialog, `alert_resoponse_cb` is invoked. +It hides the dialog and checks the `response_id`. +If it is `GTK_RESPONSE_ACCEPT`, which means user clicked on the quit button, then it calls `tfe_application_quit` to quit the application. +Otherwise it does nothing. The static variables `alert`, `lb_alert` and `btn_accept` are set in the startup handler. And the signal "close-request" and `dialog_close_cb` handler are connected. @@ -592,10 +600,12 @@ And the signal "close-request" and `dialog_close_cb` handler are connected. - 1-14: `has_saved` function. - 10: The function `gtk_text_buffer_get_modified` returns true if the content of the buffer has been modified since the modified flag had set false. -The flag is set to false when the buffer is generated. -It is reset to false when it is replaced with a new contents from a file or it is saved to a file. +The flag is set to false when: + - the buffer is created. + - the contents of the buffer is replaced + - the contents of the buffer is saved to a file. - 11-13: This function returns true if the contents of the current page has been saved and no modification has been made. -If it returns false, then the user tries to close the current page without saving the modified contents. +It returns false, if the current page has been modified and hasn't been saved. - 16-33: `has_saved_all` function. This function is similar to `has_saved` function. It returns true if all the pages have been saved. @@ -655,10 +665,11 @@ When a page is built, connect "change-file" and "modified-changed" signals to `f 34 filename = gtk_notebook_get_tab_label_text (GTK_NOTEBOOK (nb), scr); 35 text = g_strdup_printf ("*%s", filename); 36 label = gtk_label_new (text); -37 gtk_notebook_set_tab_label (GTK_NOTEBOOK (nb), scr, label); -38 } else -39 file_changed_cb (tv); -40 } +37 g_free (text); +38 gtk_notebook_set_tab_label (GTK_NOTEBOOK (nb), scr, label); +39 } else +40 file_changed_cb (tv); +41 } ~~~ - 1-20: `file_changed_cb` handler. @@ -667,12 +678,12 @@ That is, there's no page corresponds to `tv`. Then, it isn't necessary to change the name of the tab because no tab exists. - 13-15: If `file` is GFile, then it gets the filename and unrefs `file`. - 16-17: Otherwise, `file` is probably NULL and it assigns "Untitled" related name to `filename` -- 18-19: Generates GtkLabel with `filename` and sets the tab of the page with the GtkLabel. -- 22-40: `modified_changed_cb` handler. +- 18-19: Creates GtkLabel with `filename` and sets the tab of the page with the GtkLabel. +- 22-41: `modified_changed_cb` handler. - 31-32: If `tv` isn't a descendant of `nb`, then nothing needs to be done. - 33-35: If the content is modified, then it gets the text of the tab and adds asterisk at the beginning of the text. -- 36-37: Sets the tab with the asterisk prepended text. -- 38-39: Otherwise the modified bit is off. +- 36-38: Sets the tab with the asterisk prepended text. +- 39-40: Otherwise the modified bit is off. It is because content is saved. It calls `file_changed_cb` and resets the filename, that means it leaves out the asterisk. @@ -735,7 +746,7 @@ A new file `css.c` is made for functions related to CSS. 1 #include "tfe.h" 2 3 void - 4 set_css_for_display (GtkWindow *win, char *css) { + 4 set_css_for_display (GtkWindow *win, const char *css) { 5 GdkDisplay *display; 6 7 display = gtk_widget_get_display (GTK_WIDGET (win)); @@ -751,78 +762,79 @@ A new file `css.c` is made for functions related to CSS. 17 textview_css = g_strdup_printf ("textview {padding: 10px; font-family: \"%s\"; font-style: %s; font-weight: %s; font-size: %dpt;}", 18 fontfamily, fontstyle, fontweight, fontsize); 19 set_css_for_display (win, textview_css); -20 } -21 -22 void -23 set_font_for_display_with_pango_font_desc (GtkWindow *win, PangoFontDescription *pango_font_desc) { -24 int pango_style; -25 int pango_weight; -26 const char *family; -27 const char *style; -28 const char *weight; -29 int fontsize; -30 -31 family = pango_font_description_get_family (pango_font_desc); -32 pango_style = pango_font_description_get_style (pango_font_desc); -33 switch (pango_style) { -34 case PANGO_STYLE_NORMAL: -35 style = "normal"; -36 break; -37 case PANGO_STYLE_ITALIC: -38 style = "italic"; -39 break; -40 case PANGO_STYLE_OBLIQUE: -41 style = "oblique"; -42 break; -43 default: -44 style = "normal"; -45 break; -46 } -47 pango_weight = pango_font_description_get_weight (pango_font_desc); -48 switch (pango_weight) { -49 case PANGO_WEIGHT_THIN: -50 weight = "100"; -51 break; -52 case PANGO_WEIGHT_ULTRALIGHT: -53 weight = "200"; -54 break; -55 case PANGO_WEIGHT_LIGHT: -56 weight = "300"; -57 break; -58 case PANGO_WEIGHT_SEMILIGHT: -59 weight = "350"; -60 break; -61 case PANGO_WEIGHT_BOOK: -62 weight = "380"; -63 break; -64 case PANGO_WEIGHT_NORMAL: -65 weight = "400"; /* or "normal" */ -66 break; -67 case PANGO_WEIGHT_MEDIUM: -68 weight = "500"; -69 break; -70 case PANGO_WEIGHT_SEMIBOLD: -71 weight = "600"; -72 break; -73 case PANGO_WEIGHT_BOLD: -74 weight = "700"; /* or "bold" */ -75 break; -76 case PANGO_WEIGHT_ULTRABOLD: -77 weight = "800"; -78 break; -79 case PANGO_WEIGHT_HEAVY: -80 weight = "900"; -81 break; -82 case PANGO_WEIGHT_ULTRAHEAVY: -83 weight = "900"; /* In PangoWeight definition, the weight is 1000. But CSS allows the weight below 900. */ -84 break; -85 default: -86 weight = "normal"; -87 break; -88 } -89 fontsize = pango_font_description_get_size (pango_font_desc) / PANGO_SCALE; -90 set_font_for_display (win, family, style, weight, fontsize); -91 } +20 g_free (textview_css); +21 } +22 +23 void +24 set_font_for_display_with_pango_font_desc (GtkWindow *win, PangoFontDescription *pango_font_desc) { +25 PangoStyle pango_style; +26 PangoWeight pango_weight; +27 const char *family; +28 const char *style; +29 const char *weight; +30 int fontsize; +31 +32 family = pango_font_description_get_family (pango_font_desc); +33 pango_style = pango_font_description_get_style (pango_font_desc); +34 switch (pango_style) { +35 case PANGO_STYLE_NORMAL: +36 style = "normal"; +37 break; +38 case PANGO_STYLE_ITALIC: +39 style = "italic"; +40 break; +41 case PANGO_STYLE_OBLIQUE: +42 style = "oblique"; +43 break; +44 default: +45 style = "normal"; +46 break; +47 } +48 pango_weight = pango_font_description_get_weight (pango_font_desc); +49 switch (pango_weight) { +50 case PANGO_WEIGHT_THIN: +51 weight = "100"; +52 break; +53 case PANGO_WEIGHT_ULTRALIGHT: +54 weight = "200"; +55 break; +56 case PANGO_WEIGHT_LIGHT: +57 weight = "300"; +58 break; +59 case PANGO_WEIGHT_SEMILIGHT: +60 weight = "350"; +61 break; +62 case PANGO_WEIGHT_BOOK: +63 weight = "380"; +64 break; +65 case PANGO_WEIGHT_NORMAL: +66 weight = "400"; /* or "normal" */ +67 break; +68 case PANGO_WEIGHT_MEDIUM: +69 weight = "500"; +70 break; +71 case PANGO_WEIGHT_SEMIBOLD: +72 weight = "600"; +73 break; +74 case PANGO_WEIGHT_BOLD: +75 weight = "700"; /* or "bold" */ +76 break; +77 case PANGO_WEIGHT_ULTRABOLD: +78 weight = "800"; +79 break; +80 case PANGO_WEIGHT_HEAVY: +81 weight = "900"; +82 break; +83 case PANGO_WEIGHT_ULTRAHEAVY: +84 weight = "900"; /* In PangoWeight definition, the weight is 1000. But CSS allows the weight below 900. */ +85 break; +86 default: +87 weight = "normal"; +88 break; +89 } +90 fontsize = pango_font_description_get_size (pango_font_desc) / PANGO_SCALE; +91 set_font_for_display (win, family, style, weight, fontsize); +92 } ~~~ - 3-11: `set_css_for_display`. @@ -841,22 +853,24 @@ Bold is 700. - font-size specifies the size of a font. Small, medium, large and 12pt are font-size. - 17: Makes CSS text. -The function `g_strdup_printf` generates a new string with printf-like formatting. -- 22-91: `set_font_for_display_with_pango_font_desc`. +The function `g_strdup_printf` creates a new string with printf-like formatting. +- 23-92: `set_font_for_display_with_pango_font_desc`. This function takes out font-family, font-style, font-weight and font-size from the PangoFontDescription object and calls `set_font`for_display`. -- 31: Gets the font-family of `pango_font_desc`. -- 32-46: Gets the font-style of `pango_font_desc`. +- 32: Gets the font-family of `pango_font_desc`. +- 33-47: Gets the font-style of `pango_font_desc`. The functions `pango_font_description_get_style` returns an enumerated value. -- 47-88: Gets the font-weight of `pango_font_desc`. +- 48-89: Gets the font-weight of `pango_font_desc`. The function `pango_font_description_get_weight` returns an enumerated value. They corresponds to the numbers from 100 to 900. -- 89: Gets the font-size of `pango_font_desc`. +- 90: Gets the font-size of `pango_font_desc`. The function `pango_font_description_get_size` returns the size of a font. The unit of this size is (1/PANGO\_SCALE)pt. If the font size is 10pt, the function returns 10*PANGO\_SCALE. PANGO\_SCALE is defined as 1024. Therefore, 10*PANGO\_SCALE is 10240. -- 90: calls `set_font_for_display` to set CSS for the GdkDisplay. +- 91: calls `set_font_for_display` to set CSS for the GdkDisplay. + +For further information, see [Pango reference manual](https://developer.gnome.org/pango/1.46/). ## GSettings @@ -920,12 +934,13 @@ It is [GVariant format string](https://developer.gnome.org/glib/stable/gvariant- Other common types are: - "b": gboolean - "i": gint32. - - "d": double -Further information is in the website `GVariant format string` above. + - "d": double. + +Further information is in [Glib reference manual](https://developer.gnome.org/glib/stable/gvariant-format-strings.html). ### gsettings -First, let's try `gsetting` application. +First, let's try `gsettings` application. It is a configuration tool for GSettings. ~~~ @@ -1005,7 +1020,7 @@ Then, change the mode to advanced and quit. ![gnome-calculator advanced mode](../image/gnome_calculator_advanced.png) -Run gsettongs and check whether the value of `button-mode` changes. +Run gsettings and check whether the value of `button-mode` changes. ~~~ $ gsettings list-recursively org.gnome.calculator @@ -1018,13 +1033,13 @@ org.gnome.calculator button-mode 'advanced' ~~~ -Now we know that Gnome Calculator used gsettings and it sets `button-mode` key to "advanced" which is the current mode. +Now we know that Gnome Calculator used gsettings and it has set `button-mode` key to "advanced". The value remains even the calculator quits. So when the calculator is run again, it will appear as an advanced mode calculator. ### glib-compile-schemas -GSettings schemas are specified with XML format. +GSettings schemas are specified with an XML format. The XML schema files must have the filename extension `.gschema.xml`. The following is the XML schema file for the application `tfe`. @@ -1059,7 +1074,7 @@ They are optional, but it is recommended to add them in the XML file. The XML file is compiled by glib-compile-schemas. When compiling, `glib-compile-schemas` compiles all the XML files which have ".gschema.xml" file extension in the directory given as an argument. It converts the XML file into a binary file `gschemas.compiled`. -Suppose the XML file above is under `tfe6`directory. +Suppose the XML file above is under `tfe6` directory. ~~~ $ glib-compile-schemas tfe6 @@ -1076,7 +1091,7 @@ This is because GSettings object searches `GSETTINGS_SCHEMA_DIR` for `gschemas.c GSettings object looks for this file by the following process. -- It searches `glib-2.0/schemas` subdirectories of all the directories specified in the environment cariable `XDG_DATA_DIRS`. +- It searches `glib-2.0/schemas` subdirectories of all the directories specified in the environment variable `XDG_DATA_DIRS`. Most common directory is `/usr/share/glib-2.0/schemas`. - If `GSETTINGS_SCHEMA_DIR` environment variable is defined, it searches all the directories specified in the variable. `GSETTINGS_SCHEMA_DIR` can specify multiple directories delimited by colon (:). @@ -1085,7 +1100,7 @@ In the directories above, all the `.gschema.xml` files are stored. Therefore, when you install your application, follow the instruction below to install your schemas. 1. Make `.gschema.xml` file. -2. Copy it to one of the directories above. For example, `/usr/share/glib-2.0/schemas`. +2. Copy it to one of the directories above. For example, `/usr/local/share/glib-2.0/schemas`. 3. Run `glib-compile-schemas` on the directory above. ### Meson.build @@ -1146,18 +1161,21 @@ Then the two values will be always the same. If one value changes then the other will automatically change. You need to make an effort to understand GSettings concept, but coding is very simple. -Just generate a GSettings object and bind it to a property of an object. +Just create a GSettings object and bind it to a property of an object. ## Installation -It is a good idea to install your application in `$HOME/local/bin` directory if you have installed gtk4 under the instruction in Section 2. +It is a good idea to install your application in `$HOME/local/bin` directory if you have installed Gtk4 from the source (See Section 2). Then you need to put `--prefix=$HOME/local` option to meson like this. ~~~ $ meson --prefix=$HOME/local _build ~~~ -Modify `meson.build` abd add install option and set it true in executable function. +If you've installed Gtk4 from the distribution package, `--prefix` option isn't necessary. +You just install `tfe` to the default bin directory like `/usr/local/bin`. + +Modify `meson.build` and add install option and set it true in executable function. ~~~meson executable('tfe', sourcefiles, resources, dependencies: gtkdep, export_dynamic: true, install: true) @@ -1182,10 +1200,10 @@ install_data('com.github.ToshioCP.tfe.gschema.xml', install_dir: schema_dir) The default value of the option 'prefix' is "/usr/local", but it is "\$HOME/local" because we have run meson with prefix option. The default value of the option 'datadir' is "share". The operator '/' connects the strings with '/' separator. -So, `$HOME/local/share/glib-2.0/schemas` is assigned to the varable `schema_dir`. +So, `$HOME/local/share/glib-2.0/schemas` is assigned to the variable `schema_dir`. - install_data: This function installs the data to the install directory. -Meson can runs a post compile script. +Meson can run a post compile script. ~~~meson meson.add_install_script('glib-compile-schemas', schema_dir) diff --git a/gfm/sec25.md b/gfm/sec25.md index 1102f5e..e84a8f1 100644 --- a/gfm/sec25.md +++ b/gfm/sec25.md @@ -3,7 +3,7 @@ Up: [Readme.md](../Readme.md), Prev: [Section 24](sec24.md), Next: [Section 26] # GtkListView Gtk4 has added new list objects GtkListView, GtkGridView and GtkColumnView. -The new feature is described in the sections "GListModel support" and "List-based widgets" at the top of [the third chapter of the API reference](https://developer.gnome.org/gtk4/stable/gtkobjects.html). +The new feature is described in the sections "GListModel support" and "List-based widgets" at the top of [the third chapter of Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/gtkobjects.html). Gtk4 has other means to implement lists. They are GtkListBox and GtkTreeView which are took over from Gtk3. @@ -59,7 +59,7 @@ There are functions to add items to the list or remove items from the list. - `gtk_string_list_remove` removes an item from the list - `gtk_string_list_get_string` gets a string in the list -See [API document](https://developer.gnome.org/gtk4/stable/GtkStringList.html) for the further information. +See [Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/GtkStringList.html) for the further information. I'll explain the other list objects later. @@ -409,7 +409,7 @@ Therefore, "gchararray" is "an array of char type", which is the same as string It is used to get the type of GValue object. GValue is a generic value and it can contain various type of values. For example, the type can be gboolean, gchar (char), gint (int), gfloat (float), gdouble (double), gchararray (char *) and so on. -For the further information, refer to GFileAttribute and GFileInfo section in [GIO API reference](https://developer.gnome.org/gio/stable/). +For the further information, refer to GFileAttribute and GFileInfo section in [GIO reference manual](https://developer.gnome.org/gio/stable/). - closure tag has type attribute and function attribute. Function attribute specifies a function name and type attribute specifies the type of the return value of the function. The contents of closure tag (it is between \ and\) is parameters of the function. diff --git a/gfm/sec27.md b/gfm/sec27.md index 9d5ccbf..17bd34d 100644 --- a/gfm/sec27.md +++ b/gfm/sec27.md @@ -278,7 +278,7 @@ So, the change of the text in `entry` reflects "label" in `label2` immediately. Closure expression calls closure when it is evaluated. A closure is a generic representation of a callback (a pointer to a function). -For information about closure, see [GObject API reference](https://developer.gnome.org/gobject/stable/chapter-signal.html#closure). +For information about closure, see [GObject reference manual](https://developer.gnome.org/gobject/stable/chapter-signal.html#closure). A closure expression is created with `gtk_cclosure_expression_new` function. ~~~C diff --git a/gfm/sec3.md b/gfm/sec3.md index cd2b5d8..96523f2 100644 --- a/gfm/sec3.md +++ b/gfm/sec3.md @@ -139,12 +139,12 @@ The function `g_signal_connect` has four arguments. 3. A handler function (also called callback), which needs to be casted by `G_CALLBACK`. 4. Data to pass to the handler. If no data is necessary, NULL should be given. -You can find the description of each signal in API reference. -For example, "activate" signal is in GApplication section in [GIO API reference](https://developer.gnome.org/gio/stable/GApplication.html#GApplication-activate). +You can find the description of each signal in the API reference manual. +For example, "activate" signal is in GApplication section in [GIO reference manual](https://developer.gnome.org/gio/stable/GApplication.html#GApplication-activate). The handler function is described in it. -In addition, `g_signal_connect` is described in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). -API reference is very important. +In addition, `g_signal_connect` is described in [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). +API reference manual is very important. You should see and understand it to write Gtk applications. They are located in ['GNOME Developer Center'](https://developer.gnome.org/). diff --git a/gfm/sec4.md b/gfm/sec4.md index 33eebe1..c8a5f7e 100644 --- a/gfm/sec4.md +++ b/gfm/sec4.md @@ -223,7 +223,7 @@ The change is: - The fourth argument of `g_signal_connect` is changed from `NULL` to `win`. Most important is the fourth argument of `g_signal_connect`. -It is described as "data to pass to handler" in the definition of `g_signal_connect` in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). +It is described as "data to pass to handler" in the definition of `g_signal_connect` in [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). Therefore, `win` which is a pointer to GtkApplicationWindow is passed to the handler as a second parameter `user_data`. Then, the handler cast it to a pointer to GtkWindow and call `gtk_window_destroy` to destroy the top-level window. Then, the application quits. diff --git a/gfm/sec6.md b/gfm/sec6.md index 893b812..6e21f64 100644 --- a/gfm/sec6.md +++ b/gfm/sec6.md @@ -191,7 +191,7 @@ The string literal "Hello" has 6 bytes because the string has '\0' at the end it `s` is assigned the top address of the memory. `g_free` returns the memory to the heap area. -`g_strdup` is described in [GLib API reference](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strdup). +`g_strdup` is described in [GLib reference manual](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strdup). The following is extracted from the reference. > The returned string should be freed with `g_free()` when no longer needed. diff --git a/gfm/sec7.md b/gfm/sec7.md index 8ec79fd..a8908ca 100644 --- a/gfm/sec7.md +++ b/gfm/sec7.md @@ -18,7 +18,7 @@ When the program starts, we give a filename as an argument. Then it opens the file and inserts its contents into the GtkTextBuffer. At the beginning of the implementation, we need to know how GtkApplication (or GApplication) recognizes arguments. -It is described in the [GIO API reference](https://developer.gnome.org/gio/stable/GApplication.html#GApplication.description). +It is described in the [GIO reference manual](https://developer.gnome.org/gio/stable/GApplication.html#GApplication.description). When GtkApplication is created, a flag (its type is GApplicationFlags) is given as an argument. @@ -27,7 +27,7 @@ GtkApplication * gtk_application_new (const gchar *application_id, GApplicationFlags flags); ~~~ -This flag is described in the [GApplication section](https://developer.gnome.org/gio/stable/GApplication.html#GApplicationFlags) in GIO API reference. +This flag is described in the [GApplication section](https://developer.gnome.org/gio/stable/GApplication.html#GApplicationFlags) in GIO reference manual. ~~~ GApplicationFlags' Members @@ -334,7 +334,7 @@ Therefore, the structure is like this: 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. `g_object_set` is a general function to set properties in any objects. -See [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-set). +See [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-set). - 49-51: If it fails to read the file, "No such file" message is outputted. Frees `filename`. - 52-53: If `filename` is NULL, "No valid file is given" message is outputted. diff --git a/gfm/sec8.md b/gfm/sec8.md index 4a34229..0b4747b 100644 --- a/gfm/sec8.md +++ b/gfm/sec8.md @@ -97,7 +97,7 @@ tfe_text_view_new (void) { If you are curious about the background theory of this program, It's very good for you. Because knowing the theory is very important for you to program GTK applications. -Look at [GObject API reference](https://developer.gnome.org/gobject/stable/). +Look at [GObject reference manual](https://developer.gnome.org/gobject/stable/). All you need is described in it. Or, refer to [GObject tutorial](https://github.com/ToshioCP/Gobject-tutorial). However, it's a tough journey especially for beginners. diff --git a/src/abstract.src.md b/src/abstract.src.md index 6c6c778..6183521 100644 --- a/src/abstract.src.md +++ b/src/abstract.src.md @@ -7,7 +7,7 @@ The table of contents are shown at the end of this abstract. - Section 24 to 27 describes list model and list view (GtkListView, GtkGridView and GtkColumnView). It also describes GtkExpression. -Please refer to [Gtk API reference](https://developer.gnome.org/gtk4/stable/index.html) +Please refer to [Gtk reference manual](https://developer.gnome.org/gtk4/stable/index.html) and [Gnome Developer Center](https://developer.gnome.org/) for further topics. This tutorial is under development and unstable. diff --git a/src/menu/menu2.c b/src/menu/menu2.c index 9a95891..6fe6d90 100644 --- a/src/menu/menu2.c +++ b/src/menu/menu2.c @@ -90,12 +90,14 @@ app_activate (GApplication *app, gpointer user_data) { gtk_window_present (GTK_WINDOW (win)); } +#define APPLICATION_ID "com.github.ToshioCP.menu2" + int main (int argc, char **argv) { GtkApplication *app; int stat; - app = gtk_application_new ("com.github.ToshioCP.menu2", G_APPLICATION_FLAGS_NONE); + app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE); g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL); stat =g_application_run (G_APPLICATION (app), argc, argv); diff --git a/src/menu/menu2_int16.c b/src/menu/menu2_int16.c index c3142f4..4994b0b 100644 --- a/src/menu/menu2_int16.c +++ b/src/menu/menu2_int16.c @@ -92,12 +92,14 @@ app_activate (GApplication *app, gpointer user_data) { gtk_window_present (GTK_WINDOW (win)); } +#define APPLICATION_ID "com.github.ToshioCP.menu2" + int main (int argc, char **argv) { GtkApplication *app; int stat; - app = gtk_application_new ("com.github.ToshioCP.menu2", G_APPLICATION_FLAGS_NONE); + app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE); g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL); stat =g_application_run (G_APPLICATION (app), argc, argv); diff --git a/src/menu3/menu3.c b/src/menu3/menu3.c index 7c82763..507a2fd 100644 --- a/src/menu3/menu3.c +++ b/src/menu3/menu3.c @@ -52,7 +52,7 @@ quit_activated (GSimpleAction *action, GVariant *parameter, gpointer app) } static void -on_activate (GApplication *app, gpointer user_data) { +app_activate (GApplication *app, gpointer user_data) { GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); const GActionEntry win_entries[] = { @@ -77,7 +77,7 @@ on_activate (GApplication *app, gpointer user_data) { } static void -on_startup (GApplication *app, gpointer user_data) { +app_startup (GApplication *app, gpointer user_data) { GtkBuilder *builder = gtk_builder_new_from_resource ("/com/github/ToshioCP/menu3/menu3.ui"); GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); @@ -90,14 +90,16 @@ on_startup (GApplication *app, gpointer user_data) { g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, G_N_ELEMENTS (app_entries), app); } +#define APPLICATION_ID "com.github.ToshioCP.menu3" + int main (int argc, char **argv) { GtkApplication *app; int stat; - app = gtk_application_new ("com.github.ToshioCP.menu3", G_APPLICATION_FLAGS_NONE); - g_signal_connect (app, "startup", G_CALLBACK (on_startup), NULL); - g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL); + g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL); stat =g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); diff --git a/src/sec12.src.md b/src/sec12.src.md index daf99b5..10c9d1e 100644 --- a/src/sec12.src.md +++ b/src/sec12.src.md @@ -63,7 +63,7 @@ tfetextview/tfetextview.c tfe_text_view_class_init The signal "change-file" has no default handler (object method handler). You usually don't need to set a default handler. If you need it, use `g_signal_new_class_handler` function. -See [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-new-class-handler) for further information. +See [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-new-class-handler) for further information. - The return value of `g_signal_new` is the signal id. The type of signal id is guint, which is the same as unsigned int. It is used in the function `g_signal_emit`. @@ -73,7 +73,7 @@ This signal has a parameter. "open-response" signal has one parameter. - 25: The type of the parameter. `G_TYPE_INT` is a type of integer. -Such fundamental types are described in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html). +Such fundamental types are described in [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html). The handlers are declared as follows. diff --git a/src/sec13.src.md b/src/sec13.src.md index 69e0ef5..16676fe 100644 --- a/src/sec13.src.md +++ b/src/sec13.src.md @@ -51,7 +51,7 @@ tfetextview/tfetextview.c tfe_text_view_new_with_file tfe_text_view_new Just returns the value from the function `g_object_new` but casts it to the pointer to GtkWidget. Initialization is done in `tfe_text_view_init` which is called in the process of `g_object_new` function. - 1-21: `tfe_text_view_new_with_file` function. -- 3: `g_return_val_if_fail` is described in [Glib API reference](https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail). +- 3: `g_return_val_if_fail` is described in [Glib reference manual](https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail). It tests whether the argument `file` is a pointer to GFile. If it's true, then the program goes on to the next line. If it's false, then it returns NULL (the second argument) immediately. @@ -239,7 +239,7 @@ The important thing is to duplicate `tv->file`. Otherwise, if the caller frees the GFile object, `tv->file` is no more guaranteed to point the GFile. Another reason to use `g_file_dup` is that GFile isn't thread-safe. If you use GFile in the different thread, the duplication is necessary. -See [Gio API reference](https://developer.gnome.org/gio/stable/GFile.html#g-file-dup). +See [Gio reference manual](https://developer.gnome.org/gio/stable/GFile.html#g-file-dup). ## The API document and source file of tfetextview.c diff --git a/src/sec14.src.md b/src/sec14.src.md index abe828c..f9bdc69 100644 --- a/src/sec14.src.md +++ b/src/sec14.src.md @@ -109,7 +109,7 @@ On the other hand, when an instance of GObject (not GInitiallyUnowned) is create And the instance has a normal reference count instead of floating reference. If you use `g_object_unref` to an instance that has a floating reference, you need to convert the floating reference to a normal reference in advance. -See [GObject API reference manual](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#gobject-The-Base-Object-Type.description) for further information. +See [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#gobject-The-Base-Object-Type.description) for further information. ## notebook\_page\_close diff --git a/src/sec15.src.md b/src/sec15.src.md index ff6b1f0..1868249 100644 --- a/src/sec15.src.md +++ b/src/sec15.src.md @@ -121,7 +121,7 @@ textview {color: yellow; ...} ~~~ Class, ID and some other things can be applied to the selector like Web CSS. -Refer [Gtk4 API reference](https://developer.gnome.org/gtk4/stable/theming.html) for further information. +Refer [Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/theming.html) for further information. In line 30, the CSS is a string. diff --git a/src/sec17.src.md b/src/sec17.src.md index 03a1c96..3d1ce4d 100644 --- a/src/sec17.src.md +++ b/src/sec17.src.md @@ -144,7 +144,7 @@ Therefore, `act_quit` has a name "quit" and no parameter. - 17: Adds the action to GtkApplication `app`. GtkApplication implements an interface GActionMap and GActionGroup. GtkApplication (GActionMap) can have a group of actions and the actions are added with the function `g_action_map_add_action`. -This function is described in [GMenuModel section in GIO API reference](https://developer.gnome.org/gio/stable/GActionMap.html#g-action-map-add-action). +This function is described in [GMenuModel section in GIO reference manual](https://developer.gnome.org/gio/stable/GActionMap.html#g-action-map-add-action). - 18: Connects "activate" signal of the action and the handler `quit_activated`. - 20-23: Creates GMenu and GMenuItem instances. `menubar` and `menu` are GMenu. diff --git a/src/sec19.src.md b/src/sec19.src.md index b58f999..ef64fd6 100644 --- a/src/sec19.src.md +++ b/src/sec19.src.md @@ -138,7 +138,7 @@ g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, The code above does: - Builds the "quit" action -- Connects the action and the "activate" signal handler `quit_activate` +- Connects the action and the "activate" signal handler `quit_activated` - Adds the action to the action map `app`. The same goes for the other actions. @@ -156,7 +156,7 @@ The code above does: - Builds a "fullscreen" action and "color" action. - Connects the "fullscreen" action and the "change-state" signal handler `fullscreen_changed` - Its initial state is set to FALSE. -- Connects the "color" action and the "activate" signal handler `color_activate` +- Connects the "color" action and the "activate" signal handler `color_activated` - Its parameter type is string and the initial value is "red". - Adds the actions to the action map `win`. diff --git a/src/sec2.src.md b/src/sec2.src.md index 62ddfb5..c444dbc 100644 --- a/src/sec2.src.md +++ b/src/sec2.src.md @@ -51,7 +51,7 @@ I installed Gtk4 under the directory `$HOME/local`. This is a private user area. If you want to install it in the system area, `/opt/gtk4` is one of good choices. -[Gtk4 API Reference](https://developer.gnome.org/gtk4/stable/gtk-building.html) gives an installation example to `/opt/gtk4`. +[Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/gtk-building.html) gives an installation example to `/opt/gtk4`. Don't install it to `/usr/local` which is the default. It is used by Ubuntu applications, which are not build on Gtk4. diff --git a/src/sec20.src.md b/src/sec20.src.md index ae7180b..872da84 100644 --- a/src/sec20.src.md +++ b/src/sec20.src.md @@ -1,7 +1,7 @@ # GtkMenuButton, accelerators, font, pango and gsettings Traditional menu structure is fine. -However, Buttons or menu items we often use are not so many. +However, buttons or menu items we often use are not so many. Some mightn't be clicked at all. Therefore, it's a good idea to put some frequently used buttons on the toolbar and put the rest of the less frequently used operations into the menu. Such menu are often connected to GtkMenuButton. @@ -61,11 +61,11 @@ tfe6/menu.ui There are four items, "New", "Saveas", "Preference" and "Quit". -- New menu creates a new empty page. -- Saveas menu saves the current page as a new filename. -- Preference menu sets preference items. +- "New" menu creates a new empty page. +- "Saveas" menu saves the current page as a new filename. +- "Preference" menu sets preference items. This version of `tfe` has only font preference. -- Quit menu quits the application. +- "Quit" menu quits the application. These four menus are not used so often. That's why they are put to the menu behind the menu button. @@ -155,7 +155,7 @@ You can define more than one accelerator keys and the list must ends with NULL ( If you want to do so, the array length needs to be three or more. The parser recognizes "\o", "\\F2", "\minus" and so on. If you want to use symbol key like "\-", use "\minus" instead. -Such relation between lower case and symbol (its character code) is specified in [`gdkkeysyms.h`](https://gitlab.gnome.org/GNOME/gtk/-/blob/master/gdk/gdkkeysyms.h) in the gtk4 source code. +Such relation between lower case and symbol (its character code) is specified in [`gdkkeysyms.h`](https://gitlab.gnome.org/GNOME/gtk/-/blob/master/gdk/gdkkeysyms.h) in the Gtk4 source code. ## Saveas handler @@ -215,16 +215,17 @@ Preference dialog xml definition is added to `tfe.ui`. ~~~ - Preference dialog is an independent dialog. -It is not a descendant widget of the top GtkApplicationwindow `win`. -Therefore, There's no child tag of the dialog object. -- There are four properties of the dialog specified. +It is not a descendant widget of the top-level GtkApplicationwindow `win`. +Therefore, There's no child tag that surrounds the dialog object. +- There are four properties of the dialog. GtkDialog is a child object (not child widget) of GtkWindow, so it inherits all the properties from GtkWindow. Title, resizable, modal and transient-for properties are inherited from GtkWindow. Transient-for specifies a temporary parent window, which the dialog's location is based on. - internal-child attribute is used in the child tag above. GtkDialog has a GtkBox child widget. -Its id is "content_area" in `gtkdialog.ui`, which is the ui file of GtkDialog in gtk4 source files. -This box is provided to users to add content widgets in it. +Its id is "content_area" in `gtkdialog.ui`, which is the ui file of GtkDialog. +(It is in the Gtk4 source files.) +This box is provided for users to add content widgets in it. The tag `` is put at the top of the contents. Then you need to specify an object tag and define its class as GtkBox and its id as content_area. This object is defined in `gtkdialog.ui` but you need to define it again in the child tag. @@ -314,7 +315,7 @@ tfe_startup (GApplication *application) { } ~~~ -The function `tfe_application_quit` destroys top level windows and quits the application. +The function `tfe_application_quit` destroys top-level windows and quits the application. It first disconnects the handlers from the signal "close-request". ### Alert dialog @@ -396,8 +397,8 @@ An alert message will be inserted by the program later. There are two child tags which have "action" type. They are button objects located in the action area. Action-widgets tag describes the actions of the buttons. -Btn\_cancel button emits response signal with cancel response (GTK_RESPONSE_CANCEL) if it is clicked on. -Btn\_accept button emits response signal with accept response (GTK_RESPONSE_ACCEPT) if it is clicked on. +`btn_cancel` button emits response signal with cancel response (`GTK_RESPONSE_CANCEL`) if it is clicked on. +`btn_accept` button emits response signal with accept response (`GTK_RESPONSE_ACCEPT`) if it is clicked on. The response signal is connected to `alert_response_cb` handler. The alert dialog keeps alive while the application lives. @@ -427,8 +428,9 @@ close_cb (GtkNotebook *nb) { ... ... static void -close_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - close_cb (GTK_NOTEBOOK (nb)); +close_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + close_cb (nb); } ... ... @@ -448,15 +450,16 @@ alert_response_cb (GtkDialog *alert, int response_id, gpointer user_data) { } static void -quit_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { +quit_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (nb), GTK_TYPE_WINDOW); is_quit = true; - if (has_saved_all (GTK_NOTEBOOK (nb))) + if (has_saved_all (nb)) tfe_application_quit (GTK_WINDOW (win)); else { gtk_label_set_text (lb_alert, "Contents aren't saved yet.\nAre you sure to quit?"); - gtk_button_set_label (close_btn_close, "Quit"); + gtk_button_set_label (btn_accept, "Quit"); gtk_widget_show (GTK_WIDGET (alert)); } } @@ -484,20 +487,24 @@ When user clicks on the close button, `close_cb` handler is invoked. The handler sets `is_quit` to false. The function `has_saved` returns true if the current page has been saved. If it is true, it calls `notebook_page_close` to close the current page. -Otherwise, it sets the text in the label and button, then shows the alert dialog. +Otherwise, it sets the message of the dialog and the label of the button, then shows the alert dialog. The response signal of the dialog is connected to the handler `alert_response_cb`. It hides the dialog first. -Then check the response\_id. -If it is `GTK_RESPONSE_ACCEPT`, which means user clicked on the close button, then closes the current page. +Then checks the `response_id`. +If it is `GTK_RESPONSE_ACCEPT`, which means user clicked on the close button, then it closes the current page. +Otherwise it does nothing. When user press "Ctrl-q" or clicked on the quit menu, then `quit_activated` handler is invoked. The handler sets `is_quit` to true. The function `has_saved_all` returns true if all the pages have been saved. If it is true, it calls `tfe_application_quit` to quit the application. -Otherwise, it sets the text in the label and button, then shows the alert dialog. +Otherwise, it sets the message of the dialog and the label of the button, then shows the alert dialog. -Now `alert_response_cb` works similar but it calls `tfe_application_quit`instead of `notebook_page_close`. +If the user clicked on the buttons on the alert dialog, `alert_resoponse_cb` is invoked. +It hides the dialog and checks the `response_id`. +If it is `GTK_RESPONSE_ACCEPT`, which means user clicked on the quit button, then it calls `tfe_application_quit` to quit the application. +Otherwise it does nothing. The static variables `alert`, `lb_alert` and `btn_accept` are set in the startup handler. And the signal "close-request" and `dialog_close_cb` handler are connected. @@ -508,10 +515,12 @@ tfe6/tfenotebook.c has_saved has_saved_all - 1-14: `has_saved` function. - 10: The function `gtk_text_buffer_get_modified` returns true if the content of the buffer has been modified since the modified flag had set false. -The flag is set to false when the buffer is generated. -It is reset to false when it is replaced with a new contents from a file or it is saved to a file. +The flag is set to false when: + - the buffer is created. + - the contents of the buffer is replaced + - the contents of the buffer is saved to a file. - 11-13: This function returns true if the contents of the current page has been saved and no modification has been made. -If it returns false, then the user tries to close the current page without saving the modified contents. +It returns false, if the current page has been modified and hasn't been saved. - 16-33: `has_saved_all` function. This function is similar to `has_saved` function. It returns true if all the pages have been saved. @@ -544,12 +553,12 @@ That is, there's no page corresponds to `tv`. Then, it isn't necessary to change the name of the tab because no tab exists. - 13-15: If `file` is GFile, then it gets the filename and unrefs `file`. - 16-17: Otherwise, `file` is probably NULL and it assigns "Untitled" related name to `filename` -- 18-19: Generates GtkLabel with `filename` and sets the tab of the page with the GtkLabel. -- 22-40: `modified_changed_cb` handler. +- 18-19: Creates GtkLabel with `filename` and sets the tab of the page with the GtkLabel. +- 22-41: `modified_changed_cb` handler. - 31-32: If `tv` isn't a descendant of `nb`, then nothing needs to be done. - 33-35: If the content is modified, then it gets the text of the tab and adds asterisk at the beginning of the text. -- 36-37: Sets the tab with the asterisk prepended text. -- 38-39: Otherwise the modified bit is off. +- 36-38: Sets the tab with the asterisk prepended text. +- 39-40: Otherwise the modified bit is off. It is because content is saved. It calls `file_changed_cb` and resets the filename, that means it leaves out the asterisk. @@ -628,22 +637,24 @@ Bold is 700. - font-size specifies the size of a font. Small, medium, large and 12pt are font-size. - 17: Makes CSS text. -The function `g_strdup_printf` generates a new string with printf-like formatting. -- 22-91: `set_font_for_display_with_pango_font_desc`. +The function `g_strdup_printf` creates a new string with printf-like formatting. +- 23-92: `set_font_for_display_with_pango_font_desc`. This function takes out font-family, font-style, font-weight and font-size from the PangoFontDescription object and calls `set_font`for_display`. -- 31: Gets the font-family of `pango_font_desc`. -- 32-46: Gets the font-style of `pango_font_desc`. +- 32: Gets the font-family of `pango_font_desc`. +- 33-47: Gets the font-style of `pango_font_desc`. The functions `pango_font_description_get_style` returns an enumerated value. -- 47-88: Gets the font-weight of `pango_font_desc`. +- 48-89: Gets the font-weight of `pango_font_desc`. The function `pango_font_description_get_weight` returns an enumerated value. They corresponds to the numbers from 100 to 900. -- 89: Gets the font-size of `pango_font_desc`. +- 90: Gets the font-size of `pango_font_desc`. The function `pango_font_description_get_size` returns the size of a font. The unit of this size is (1/PANGO\_SCALE)pt. If the font size is 10pt, the function returns 10*PANGO\_SCALE. PANGO\_SCALE is defined as 1024. Therefore, 10*PANGO\_SCALE is 10240. -- 90: calls `set_font_for_display` to set CSS for the GdkDisplay. +- 91: calls `set_font_for_display` to set CSS for the GdkDisplay. + +For further information, see [Pango reference manual](https://developer.gnome.org/pango/1.46/). ## GSettings @@ -698,12 +709,13 @@ It is [GVariant format string](https://developer.gnome.org/glib/stable/gvariant- Other common types are: - "b": gboolean - "i": gint32. - - "d": double -Further information is in the website `GVariant format string` above. + - "d": double. + +Further information is in [Glib reference manual](https://developer.gnome.org/glib/stable/gvariant-format-strings.html). ### gsettings -First, let's try `gsetting` application. +First, let's try `gsettings` application. It is a configuration tool for GSettings. ~~~ @@ -783,7 +795,7 @@ Then, change the mode to advanced and quit. ![gnome-calculator advanced mode](../image/gnome_calculator_advanced.png){width=10.74cm height=7.14cm} -Run gsettongs and check whether the value of `button-mode` changes. +Run gsettings and check whether the value of `button-mode` changes. ~~~ $ gsettings list-recursively org.gnome.calculator @@ -796,13 +808,13 @@ org.gnome.calculator button-mode 'advanced' ~~~ -Now we know that Gnome Calculator used gsettings and it sets `button-mode` key to "advanced" which is the current mode. +Now we know that Gnome Calculator used gsettings and it has set `button-mode` key to "advanced". The value remains even the calculator quits. So when the calculator is run again, it will appear as an advanced mode calculator. ### glib-compile-schemas -GSettings schemas are specified with XML format. +GSettings schemas are specified with an XML format. The XML schema files must have the filename extension `.gschema.xml`. The following is the XML schema file for the application `tfe`. @@ -828,7 +840,7 @@ They are optional, but it is recommended to add them in the XML file. The XML file is compiled by glib-compile-schemas. When compiling, `glib-compile-schemas` compiles all the XML files which have ".gschema.xml" file extension in the directory given as an argument. It converts the XML file into a binary file `gschemas.compiled`. -Suppose the XML file above is under `tfe6`directory. +Suppose the XML file above is under `tfe6` directory. ~~~ $ glib-compile-schemas tfe6 @@ -845,7 +857,7 @@ This is because GSettings object searches `GSETTINGS_SCHEMA_DIR` for `gschemas.c GSettings object looks for this file by the following process. -- It searches `glib-2.0/schemas` subdirectories of all the directories specified in the environment cariable `XDG_DATA_DIRS`. +- It searches `glib-2.0/schemas` subdirectories of all the directories specified in the environment variable `XDG_DATA_DIRS`. Most common directory is `/usr/share/glib-2.0/schemas`. - If `GSETTINGS_SCHEMA_DIR` environment variable is defined, it searches all the directories specified in the variable. `GSETTINGS_SCHEMA_DIR` can specify multiple directories delimited by colon (:). @@ -854,7 +866,7 @@ In the directories above, all the `.gschema.xml` files are stored. Therefore, when you install your application, follow the instruction below to install your schemas. 1. Make `.gschema.xml` file. -2. Copy it to one of the directories above. For example, `/usr/share/glib-2.0/schemas`. +2. Copy it to one of the directories above. For example, `/usr/local/share/glib-2.0/schemas`. 3. Run `glib-compile-schemas` on the directory above. ### Meson.build @@ -919,18 +931,21 @@ Then the two values will be always the same. If one value changes then the other will automatically change. You need to make an effort to understand GSettings concept, but coding is very simple. -Just generate a GSettings object and bind it to a property of an object. +Just create a GSettings object and bind it to a property of an object. ## Installation -It is a good idea to install your application in `$HOME/local/bin` directory if you have installed gtk4 under the instruction in Section 2. +It is a good idea to install your application in `$HOME/local/bin` directory if you have installed Gtk4 from the source (See Section 2). Then you need to put `--prefix=$HOME/local` option to meson like this. ~~~ $ meson --prefix=$HOME/local _build ~~~ -Modify `meson.build` abd add install option and set it true in executable function. +If you've installed Gtk4 from the distribution package, `--prefix` option isn't necessary. +You just install `tfe` to the default bin directory like `/usr/local/bin`. + +Modify `meson.build` and add install option and set it true in executable function. @@@if gfm ~~~meson @@ -963,10 +978,10 @@ install_data('com.github.ToshioCP.tfe.gschema.xml', install_dir: schema_dir) The default value of the option 'prefix' is "/usr/local", but it is "\$HOME/local" because we have run meson with prefix option. The default value of the option 'datadir' is "share". The operator '/' connects the strings with '/' separator. -So, `$HOME/local/share/glib-2.0/schemas` is assigned to the varable `schema_dir`. +So, `$HOME/local/share/glib-2.0/schemas` is assigned to the variable `schema_dir`. - install_data: This function installs the data to the install directory. -Meson can runs a post compile script. +Meson can run a post compile script. @@@if gfm ~~~meson diff --git a/src/sec25.src.md b/src/sec25.src.md index b93b89a..4f995cc 100644 --- a/src/sec25.src.md +++ b/src/sec25.src.md @@ -1,7 +1,7 @@ # GtkListView Gtk4 has added new list objects GtkListView, GtkGridView and GtkColumnView. -The new feature is described in the sections "GListModel support" and "List-based widgets" at the top of [the third chapter of the API reference](https://developer.gnome.org/gtk4/stable/gtkobjects.html). +The new feature is described in the sections "GListModel support" and "List-based widgets" at the top of [the third chapter of Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/gtkobjects.html). Gtk4 has other means to implement lists. They are GtkListBox and GtkTreeView which are took over from Gtk3. @@ -65,7 +65,7 @@ There are functions to add items to the list or remove items from the list. - `gtk_string_list_remove` removes an item from the list - `gtk_string_list_get_string` gets a string in the list -See [API document](https://developer.gnome.org/gtk4/stable/GtkStringList.html) for the further information. +See [Gtk4 reference manual](https://developer.gnome.org/gtk4/stable/GtkStringList.html) for the further information. I'll explain the other list objects later. @@ -288,7 +288,7 @@ Therefore, "gchararray" is "an array of char type", which is the same as string It is used to get the type of GValue object. GValue is a generic value and it can contain various type of values. For example, the type can be gboolean, gchar (char), gint (int), gfloat (float), gdouble (double), gchararray (char *) and so on. -For the further information, refer to GFileAttribute and GFileInfo section in [GIO API reference](https://developer.gnome.org/gio/stable/). +For the further information, refer to GFileAttribute and GFileInfo section in [GIO reference manual](https://developer.gnome.org/gio/stable/). - closure tag has type attribute and function attribute. Function attribute specifies a function name and type attribute specifies the type of the return value of the function. The contents of closure tag (it is between \ and\) is parameters of the function. diff --git a/src/sec27.src.md b/src/sec27.src.md index e89fced..f4fc6ae 100644 --- a/src/sec27.src.md +++ b/src/sec27.src.md @@ -136,7 +136,7 @@ So, the change of the text in `entry` reflects "label" in `label2` immediately. Closure expression calls closure when it is evaluated. A closure is a generic representation of a callback (a pointer to a function). -For information about closure, see [GObject API reference](https://developer.gnome.org/gobject/stable/chapter-signal.html#closure). +For information about closure, see [GObject reference manual](https://developer.gnome.org/gobject/stable/chapter-signal.html#closure). A closure expression is created with `gtk_cclosure_expression_new` function. ~~~C diff --git a/src/sec3.src.md b/src/sec3.src.md index f390a3a..833668f 100644 --- a/src/sec3.src.md +++ b/src/sec3.src.md @@ -107,12 +107,12 @@ The function `g_signal_connect` has four arguments. 3. A handler function (also called callback), which needs to be casted by `G_CALLBACK`. 4. Data to pass to the handler. If no data is necessary, NULL should be given. -You can find the description of each signal in API reference. -For example, "activate" signal is in GApplication section in [GIO API reference](https://developer.gnome.org/gio/stable/GApplication.html#GApplication-activate). +You can find the description of each signal in the API reference manual. +For example, "activate" signal is in GApplication section in [GIO reference manual](https://developer.gnome.org/gio/stable/GApplication.html#GApplication-activate). The handler function is described in it. -In addition, `g_signal_connect` is described in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). -API reference is very important. +In addition, `g_signal_connect` is described in [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). +API reference manual is very important. You should see and understand it to write Gtk applications. They are located in ['GNOME Developer Center'](https://developer.gnome.org/). diff --git a/src/sec4.src.md b/src/sec4.src.md index 23d9e9e..36f66e2 100644 --- a/src/sec4.src.md +++ b/src/sec4.src.md @@ -101,7 +101,7 @@ The change is: - The fourth argument of `g_signal_connect` is changed from `NULL` to `win`. Most important is the fourth argument of `g_signal_connect`. -It is described as "data to pass to handler" in the definition of `g_signal_connect` in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). +It is described as "data to pass to handler" in the definition of `g_signal_connect` in [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect). Therefore, `win` which is a pointer to GtkApplicationWindow is passed to the handler as a second parameter `user_data`. Then, the handler cast it to a pointer to GtkWindow and call `gtk_window_destroy` to destroy the top-level window. Then, the application quits. diff --git a/src/sec6.src.md b/src/sec6.src.md index 36e8a99..9290754 100644 --- a/src/sec6.src.md +++ b/src/sec6.src.md @@ -189,7 +189,7 @@ The string literal "Hello" has 6 bytes because the string has '\0' at the end it `s` is assigned the top address of the memory. `g_free` returns the memory to the heap area. -`g_strdup` is described in [GLib API reference](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strdup). +`g_strdup` is described in [GLib reference manual](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strdup). The following is extracted from the reference. > The returned string should be freed with `g_free()` when no longer needed. diff --git a/src/sec7.src.md b/src/sec7.src.md index 51ce5ef..c48cf66 100644 --- a/src/sec7.src.md +++ b/src/sec7.src.md @@ -16,7 +16,7 @@ When the program starts, we give a filename as an argument. Then it opens the file and inserts its contents into the GtkTextBuffer. At the beginning of the implementation, we need to know how GtkApplication (or GApplication) recognizes arguments. -It is described in the [GIO API reference](https://developer.gnome.org/gio/stable/GApplication.html#GApplication.description). +It is described in the [GIO reference manual](https://developer.gnome.org/gio/stable/GApplication.html#GApplication.description). When GtkApplication is created, a flag (its type is GApplicationFlags) is given as an argument. @@ -25,7 +25,7 @@ GtkApplication * gtk_application_new (const gchar *application_id, GApplicationFlags flags); ~~~ -This flag is described in the [GApplication section](https://developer.gnome.org/gio/stable/GApplication.html#GApplicationFlags) in GIO API reference. +This flag is described in the [GApplication section](https://developer.gnome.org/gio/stable/GApplication.html#GApplicationFlags) in GIO reference manual. ~~~ GApplicationFlags' Members @@ -202,7 +202,7 @@ Therefore, the structure is like this: 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. `g_object_set` is a general function to set properties in any objects. -See [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-set). +See [GObject reference manual](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-set). - 49-51: If it fails to read the file, "No such file" message is outputted. Frees `filename`. - 52-53: If `filename` is NULL, "No valid file is given" message is outputted. diff --git a/src/sec8.src.md b/src/sec8.src.md index 559de9f..4e4b9f9 100644 --- a/src/sec8.src.md +++ b/src/sec8.src.md @@ -95,7 +95,7 @@ tfe_text_view_new (void) { If you are curious about the background theory of this program, It's very good for you. Because knowing the theory is very important for you to program GTK applications. -Look at [GObject API reference](https://developer.gnome.org/gobject/stable/). +Look at [GObject reference manual](https://developer.gnome.org/gobject/stable/). All you need is described in it. Or, refer to [GObject tutorial](https://github.com/ToshioCP/Gobject-tutorial). However, it's a tough journey especially for beginners. diff --git a/src/tfe6/css.c b/src/tfe6/css.c index 864b570..2244c4e 100644 --- a/src/tfe6/css.c +++ b/src/tfe6/css.c @@ -1,7 +1,7 @@ #include "tfe.h" void -set_css_for_display (GtkWindow *win, char *css) { +set_css_for_display (GtkWindow *win, const char *css) { GdkDisplay *display; display = gtk_widget_get_display (GTK_WIDGET (win)); @@ -17,12 +17,13 @@ set_font_for_display (GtkWindow *win, const char *fontfamily, const char *fontst textview_css = g_strdup_printf ("textview {padding: 10px; font-family: \"%s\"; font-style: %s; font-weight: %s; font-size: %dpt;}", fontfamily, fontstyle, fontweight, fontsize); set_css_for_display (win, textview_css); + g_free (textview_css); } void set_font_for_display_with_pango_font_desc (GtkWindow *win, PangoFontDescription *pango_font_desc) { - int pango_style; - int pango_weight; + PangoStyle pango_style; + PangoWeight pango_weight; const char *family; const char *style; const char *weight; diff --git a/src/tfe6/tfeapplication.c b/src/tfe6/tfeapplication.c index dcd612d..dd1a4de 100644 --- a/src/tfe6/tfeapplication.c +++ b/src/tfe6/tfeapplication.c @@ -36,28 +36,33 @@ close_cb (GtkNotebook *nb) { /* ----- menu or accelerator => action => handlers ----- */ static void -open_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - open_cb (GTK_NOTEBOOK (nb)); +open_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + open_cb (nb); } static void -save_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - save_cb (GTK_NOTEBOOK (nb)); +save_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + save_cb (nb); } static void -close_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - close_cb (GTK_NOTEBOOK (nb)); +close_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + close_cb (nb); } static void -new_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - notebook_page_new (GTK_NOTEBOOK (nb)); +new_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + notebook_page_new (nb); } static void -saveas_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { - notebook_page_saveas (GTK_NOTEBOOK (nb)); +saveas_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); + notebook_page_saveas (nb); } static gboolean @@ -76,7 +81,7 @@ font_set_cb (GtkFontButton *fontbtn, gpointer user_data) { } static void -pref_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { +pref_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { gtk_widget_show (GTK_WIDGET (pref)); } @@ -95,11 +100,12 @@ alert_response_cb (GtkDialog *alert, int response_id, gpointer user_data) { } static void -quit_activated (GSimpleAction *action, GVariant *parameter, gpointer nb) { +quit_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { + GtkNotebook *nb = GTK_NOTEBOOK (user_data); GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (nb), GTK_TYPE_WINDOW); is_quit = true; - if (has_saved_all (GTK_NOTEBOOK (nb))) + if (has_saved_all (nb)) tfe_application_quit (GTK_WINDOW (win)); else { gtk_label_set_text (lb_alert, "Contents aren't saved yet.\nAre you sure to quit?"); diff --git a/src/tfe6/tfenotebook.c b/src/tfe6/tfenotebook.c index ff40960..4744e1a 100644 --- a/src/tfe6/tfenotebook.c +++ b/src/tfe6/tfenotebook.c @@ -58,6 +58,7 @@ modified_changed_cb (GtkTextBuffer *tb, gpointer user_data) { filename = gtk_notebook_get_tab_label_text (GTK_NOTEBOOK (nb), scr); text = g_strdup_printf ("*%s", filename); label = gtk_label_new (text); + g_free (text); gtk_notebook_set_tab_label (GTK_NOTEBOOK (nb), scr, label); } else file_changed_cb (tv);