mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2024-11-16 19:50:35 +01:00
22 KiB
22 KiB
Up: Readme.md, Prev: Section 14, Next: Section 16
tfe5 source files
How to compile and execute tfe text editor.
First, source files are shown in the later subsections. How to download them is written at the end of the previous section.
The following is the instruction of compilation and execution.
- You need meson and ninja.
- Set necessary environment variables.
If you have installed gtk4 under the instruction in Section 2, type
. env.sh
to set the environment variables. - change your current directory to
src/tfe5
directory. - type
meson _build
for configuration. - type
ninja -C _build
for compilation. Then the applicationtfe
is build under the_build
directory. - type
_build/tfe
to execute it.
Then the window appears.
There are four buttons, New
, Open
, Save
and Close
.
- Click on
Open
button, then a FileChooserDialog appears. Choose a file in the list and click onOpen
button. Then the file is read and a new Notebook Page appears. - Edit the file and click on
Save
button, then the text is saved to the original file. - Click
Close
, then the Notebook Page disappears. - Click
Close
again, then theUntitled
Notebook Page disappears and at the same time the application quits.
This is a very simple editor. It is a good practice for you to add more features.
meson.build
1 project('tfe', 'c')
2
3 gtkdep = dependency('gtk4')
4
5 gnome=import('gnome')
6 resources = gnome.compile_resources('resources','tfe.gresource.xml')
7
8 sourcefiles=files('tfeapplication.c', 'tfenotebook.c', '../tfetextview/tfetextview.c')
9
10 executable('tfe', sourcefiles, resources, dependencies: gtkdep)
tfe.gresource.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <gresources>
3 <gresource prefix="/com/github/ToshioCP/tfe">
4 <file>tfe.ui</file>
5 </gresource>
6 </gresources>
tfe.ui
1 <interface>
2 <object class="GtkApplicationWindow" id="win">
3 <property name="title">file editor</property>
4 <property name="default-width">600</property>
5 <property name="default-height">400</property>
6 <child>
7 <object class="GtkBox" id="boxv">
8 <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
9 <child>
10 <object class="GtkBox" id="boxh">
11 <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
12 <child>
13 <object class="GtkLabel" id="dmy1">
14 <property name="width-chars">10</property>
15 </object>
16 </child>
17 <child>
18 <object class="GtkButton" id="btnn">
19 <property name="label">_New</property>
20 <property name="use-underline">TRUE</property>
21 </object>
22 </child>
23 <child>
24 <object class="GtkButton" id="btno">
25 <property name="label">_Open</property>
26 <property name="use-underline">TRUE</property>
27 </object>
28 </child>
29 <child>
30 <object class="GtkLabel" id="dmy2">
31 <property name="hexpand">TRUE</property>
32 </object>
33 </child>
34 <child>
35 <object class="GtkButton" id="btns">
36 <property name="label">_Save</property>
37 <property name="use-underline">TRUE</property>
38 </object>
39 </child>
40 <child>
41 <object class="GtkButton" id="btnc">
42 <property name="label">_Close</property>
43 <property name="use-underline">TRUE</property>
44 </object>
45 </child>
46 <child>
47 <object class="GtkLabel" id="dmy3">
48 <property name="width-chars">10</property>
49 </object>
50 </child>
51 </object>
52 </child>
53 <child>
54 <object class="GtkNotebook" id="nb">
55 <property name="scrollable">TRUE</property>
56 <property name="hexpand">TRUE</property>
57 <property name="vexpand">TRUE</property>
58 </object>
59 </child>
60 </object>
61 </child>
62 </object>
63 </interface>
64
tfe.h
1 #include <gtk/gtk.h>
2
3 #include "../tfetextview/tfetextview.h"
4 #include "tfenotebook.h"
tfeapplication.c
1 #include "tfe.h"
2
3 static void
4 open_clicked (GtkWidget *btno, GtkNotebook *nb) {
5 notebook_page_open (nb);
6 }
7
8 static void
9 new_clicked (GtkWidget *btnn, GtkNotebook *nb) {
10 notebook_page_new (nb);
11 }
12
13 static void
14 save_clicked (GtkWidget *btns, GtkNotebook *nb) {
15 notebook_page_save (nb);
16 }
17
18 static void
19 close_clicked (GtkWidget *btnc, GtkNotebook *nb) {
20 GtkWidget *win;
21 GtkWidget *boxv;
22 gint i;
23
24 if (gtk_notebook_get_n_pages (nb) == 1) {
25 boxv = gtk_widget_get_parent (GTK_WIDGET (nb));
26 win = gtk_widget_get_parent (boxv);
27 gtk_window_destroy (GTK_WINDOW (win));
28 } else {
29 i = gtk_notebook_get_current_page (nb);
30 gtk_notebook_remove_page (GTK_NOTEBOOK (nb), i);
31 }
32 }
33
34 static void
35 tfe_activate (GApplication *application) {
36 GtkApplication *app = GTK_APPLICATION (application);
37 GtkWidget *win;
38 GtkWidget *boxv;
39 GtkNotebook *nb;
40
41 win = GTK_WIDGET (gtk_application_get_active_window (app));
42 boxv = gtk_window_get_child (GTK_WINDOW (win));
43 nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv));
44
45 notebook_page_new (nb);
46 gtk_widget_show (GTK_WIDGET (win));
47 }
48
49 static void
50 tfe_open (GApplication *application, GFile ** files, gint n_files, const gchar *hint) {
51 GtkApplication *app = GTK_APPLICATION (application);
52 GtkWidget *win;
53 GtkWidget *boxv;
54 GtkNotebook *nb;
55 int i;
56
57 win = GTK_WIDGET (gtk_application_get_active_window (app));
58 boxv = gtk_window_get_child (GTK_WINDOW (win));
59 nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv));
60
61 for (i = 0; i < n_files; i++)
62 notebook_page_new_with_file (nb, files[i]);
63 if (gtk_notebook_get_n_pages (nb) == 0)
64 notebook_page_new (nb);
65 gtk_widget_show (win);
66 }
67
68
69 static void
70 tfe_startup (GApplication *application) {
71 GtkApplication *app = GTK_APPLICATION (application);
72 GtkApplicationWindow *win;
73 GtkNotebook *nb;
74 GtkBuilder *build;
75 GtkButton *btno;
76 GtkButton *btnn;
77 GtkButton *btns;
78 GtkButton *btnc;
79
80 build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe/tfe.ui");
81 win = GTK_APPLICATION_WINDOW (gtk_builder_get_object (build, "win"));
82 nb = GTK_NOTEBOOK (gtk_builder_get_object (build, "nb"));
83 gtk_window_set_application (GTK_WINDOW (win), app);
84 btno = GTK_BUTTON (gtk_builder_get_object (build, "btno"));
85 btnn = GTK_BUTTON (gtk_builder_get_object (build, "btnn"));
86 btns = GTK_BUTTON (gtk_builder_get_object (build, "btns"));
87 btnc = GTK_BUTTON (gtk_builder_get_object (build, "btnc"));
88 g_signal_connect (btno, "clicked", G_CALLBACK (open_clicked), nb);
89 g_signal_connect (btnn, "clicked", G_CALLBACK (new_clicked), nb);
90 g_signal_connect (btns, "clicked", G_CALLBACK (save_clicked), nb);
91 g_signal_connect (btnc, "clicked", G_CALLBACK (close_clicked), nb);
92 g_object_unref(build);
93
94 GdkDisplay *display;
95
96 display = gtk_widget_get_display (GTK_WIDGET (win));
97 GtkCssProvider *provider = gtk_css_provider_new ();
98 gtk_css_provider_load_from_data (provider, "textview {padding: 10px; font-family: monospace; font-size: 12pt;}", -1);
99 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
100 }
101
102 int
103 main (int argc, char **argv) {
104 GtkApplication *app;
105 int stat;
106
107 app = gtk_application_new ("com.github.ToshioCP.tfe", G_APPLICATION_HANDLES_OPEN);
108
109 g_signal_connect (app, "startup", G_CALLBACK (tfe_startup), NULL);
110 g_signal_connect (app, "activate", G_CALLBACK (tfe_activate), NULL);
111 g_signal_connect (app, "open", G_CALLBACK (tfe_open), NULL);
112
113 stat =g_application_run (G_APPLICATION (app), argc, argv);
114 g_object_unref (app);
115 return stat;
116 }
117
tfenotebook.h
1 void
2 notebook_page_save(GtkNotebook *nb);
3
4 void
5 notebook_page_open (GtkNotebook *nb);
6
7 void
8 notebook_page_new_with_file (GtkNotebook *nb, GFile *file);
9
10 void
11 notebook_page_new (GtkNotebook *nb);
12
tfenotebook.c
1 #include "tfe.h"
2
3 /* The returned string should be freed with g_free() when no longer needed. */
4 static gchar*
5 get_untitled () {
6 static int c = -1;
7 if (++c == 0)
8 return g_strdup_printf("Untitled");
9 else
10 return g_strdup_printf ("Untitled%u", c);
11 }
12
13 static void
14 file_changed (TfeTextView *tv, GtkNotebook *nb) {
15 GFile *file;
16 char *filename;
17 GtkWidget *scr;
18 GtkWidget *label;
19
20 file = tfe_text_view_get_file (tv);
21 scr = gtk_widget_get_parent (GTK_WIDGET (tv));
22 if (G_IS_FILE (file))
23 filename = g_file_get_basename (file);
24 else
25 filename = get_untitled ();
26 label = gtk_label_new (filename);
27 gtk_notebook_set_tab_label (nb, scr, label);
28 g_object_unref (file);
29 g_free (filename);
30 }
31
32 /* Save the contents in the current page */
33 void
34 notebook_page_save(GtkNotebook *nb) {
35 gint i;
36 GtkWidget *scr;
37 GtkWidget *tv;
38
39 i = gtk_notebook_get_current_page (nb);
40 scr = gtk_notebook_get_nth_page (nb, i);
41 tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr));
42 tfe_text_view_save (TFE_TEXT_VIEW (tv));
43 }
44
45 static void
46 notebook_page_build (GtkNotebook *nb, GtkWidget *tv, char *filename) {
47 GtkWidget *scr;
48 GtkNotebookPage *nbp;
49 GtkWidget *lab;
50 gint i;
51 scr = gtk_scrolled_window_new ();
52
53 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
54 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv);
55 lab = gtk_label_new (filename);
56 i = gtk_notebook_append_page (nb, scr, lab);
57 nbp = gtk_notebook_get_page (nb, scr);
58 g_object_set (nbp, "tab-expand", TRUE, NULL);
59 gtk_notebook_set_current_page (nb, i);
60 g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb);
61 }
62
63 static void
64 open_response (TfeTextView *tv, gint response, GtkNotebook *nb) {
65 GFile *file;
66 char *filename;
67
68 if (response != TFE_OPEN_RESPONSE_SUCCESS) {
69 g_object_ref_sink (tv);
70 g_object_unref (tv);
71 }else if (! G_IS_FILE (file = tfe_text_view_get_file (tv))) {
72 g_object_ref_sink (tv);
73 g_object_unref (tv);
74 }else {
75 filename = g_file_get_basename (file);
76 g_object_unref (file);
77 notebook_page_build (nb, GTK_WIDGET (tv), filename);
78 }
79 }
80
81 void
82 notebook_page_open (GtkNotebook *nb) {
83 g_return_if_fail(GTK_IS_NOTEBOOK (nb));
84
85 GtkWidget *tv;
86
87 tv = tfe_text_view_new ();
88 g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb);
89 tfe_text_view_open (TFE_TEXT_VIEW (tv), gtk_widget_get_ancestor (GTK_WIDGET (nb), GTK_TYPE_WINDOW));
90 }
91
92 void
93 notebook_page_new_with_file (GtkNotebook *nb, GFile *file) {
94 g_return_if_fail(GTK_IS_NOTEBOOK (nb));
95 g_return_if_fail(G_IS_FILE (file));
96
97 GtkWidget *tv;
98 char *filename;
99
100 if ((tv = tfe_text_view_new_with_file (file)) == NULL)
101 return; /* read error */
102 filename = g_file_get_basename (file);
103 notebook_page_build (nb, tv, filename);
104 }
105
106 void
107 notebook_page_new (GtkNotebook *nb) {
108 g_return_if_fail(GTK_IS_NOTEBOOK (nb));
109
110 GtkWidget *tv;
111 char *filename;
112
113 tv = tfe_text_view_new ();
114 filename = get_untitled ();
115 notebook_page_build (nb, tv, filename);
116 }
117
tfetextview.h
1 #ifndef __TFE_TEXT_VIEW_H__
2 #define __TFE_TEXT_VIEW_H__
3
4 #include <gtk/gtk.h>
5
6 #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type ()
7 G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView)
8
9 /* "open-response" signal response */
10 enum TfeTextViewOpenResponseType
11 {
12 TFE_OPEN_RESPONSE_SUCCESS,
13 TFE_OPEN_RESPONSE_CANCEL,
14 TFE_OPEN_RESPONSE_ERROR
15 };
16
17 GFile *
18 tfe_text_view_get_file (TfeTextView *tv);
19
20 void
21 tfe_text_view_open (TfeTextView *tv, GtkWidget *win);
22
23 void
24 tfe_text_view_save (TfeTextView *tv);
25
26 void
27 tfe_text_view_saveas (TfeTextView *tv);
28
29 GtkWidget *
30 tfe_text_view_new_with_file (GFile *file);
31
32 GtkWidget *
33 tfe_text_view_new (void);
34
35 #endif /* __TFE_TEXT_VIEW_H__ */
tfetextview.c
1 #include <string.h>
2 #include "tfetextview.h"
3
4 struct _TfeTextView
5 {
6 GtkTextView parent;
7 GFile *file;
8 };
9
10 G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW);
11
12 enum {
13 CHANGE_FILE,
14 OPEN_RESPONSE,
15 NUMBER_OF_SIGNALS
16 };
17
18 static guint tfe_text_view_signals[NUMBER_OF_SIGNALS];
19
20 static void
21 tfe_text_view_dispose (GObject *gobject) {
22 TfeTextView *tv = TFE_TEXT_VIEW (gobject);
23
24 if (G_IS_FILE (tv->file))
25 g_clear_object (&tv->file);
26
27 G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject);
28 }
29
30 static void
31 tfe_text_view_init (TfeTextView *tv) {
32 tv->file = NULL;
33 }
34
35 static void
36 tfe_text_view_class_init (TfeTextViewClass *class) {
37 GObjectClass *object_class = G_OBJECT_CLASS (class);
38
39 object_class->dispose = tfe_text_view_dispose;
40 tfe_text_view_signals[CHANGE_FILE] = g_signal_newv ("change-file",
41 G_TYPE_FROM_CLASS (class),
42 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
43 NULL /* closure */,
44 NULL /* accumulator */,
45 NULL /* accumulator data */,
46 NULL /* C marshaller */,
47 G_TYPE_NONE /* return_type */,
48 0 /* n_params */,
49 NULL /* param_types */);
50 GType param_types[] = {G_TYPE_INT};
51 tfe_text_view_signals[OPEN_RESPONSE] = g_signal_newv ("open-response",
52 G_TYPE_FROM_CLASS (class),
53 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
54 NULL /* closure */,
55 NULL /* accumulator */,
56 NULL /* accumulator data */,
57 NULL /* C marshaller */,
58 G_TYPE_NONE /* return_type */,
59 1 /* n_params */,
60 param_types);
61 }
62
63 GFile *
64 tfe_text_view_get_file (TfeTextView *tv) {
65 g_return_val_if_fail (TFE_IS_TEXT_VIEW (tv), NULL);
66
67 return g_file_dup (tv->file);
68 }
69
70 static void
71 open_dialog_response(GtkWidget *dialog, gint response, TfeTextView *tv) {
72 GtkTextBuffer *tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
73 GFile *file;
74 char *contents;
75 gsize length;
76 GtkWidget *message_dialog;
77 GError *err = NULL;
78
79 if (response != GTK_RESPONSE_ACCEPT)
80 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL);
81 else if (! G_IS_FILE (file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog))))
82 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR);
83 else if (! g_file_load_contents (file, NULL, &contents, &length, NULL, &err)) { /* read error */
84 if (G_IS_FILE (file))
85 g_object_unref (file);
86 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_MODAL,
87 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
88 "%s.\n", err->message);
89 g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
90 gtk_widget_show (message_dialog);
91 g_error_free (err);
92 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR);
93 } else {
94 gtk_text_buffer_set_text (tb, contents, length);
95 g_free (contents);
96 if (G_IS_FILE (tv->file))
97 g_object_unref (tv->file);
98 tv->file = file;
99 gtk_text_buffer_set_modified (tb, FALSE);
100 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS);
101 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
102 }
103 gtk_window_destroy (GTK_WINDOW (dialog));
104 }
105
106 void
107 tfe_text_view_open (TfeTextView *tv, GtkWidget *win) {
108 g_return_if_fail (TFE_IS_TEXT_VIEW (tv));
109 g_return_if_fail (GTK_IS_WINDOW (win));
110
111 GtkWidget *dialog;
112
113 dialog = gtk_file_chooser_dialog_new ("Open file", GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_OPEN,
114 "Cancel", GTK_RESPONSE_CANCEL,
115 "Open", GTK_RESPONSE_ACCEPT,
116 NULL);
117 g_signal_connect (dialog, "response", G_CALLBACK (open_dialog_response), tv);
118 gtk_widget_show (dialog);
119 }
120
121 static void
122 saveas_dialog_response (GtkWidget *dialog, gint response, TfeTextView *tv) {
123 GtkTextBuffer *tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
124 GFile *file;
125
126 if (response == GTK_RESPONSE_ACCEPT) {
127 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
128 if (G_IS_FILE(file)) {
129 if (G_IS_FILE (tv->file))
130 g_object_unref (tv->file);
131 tv->file = file;
132 gtk_text_buffer_set_modified (tb, TRUE);
133 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
134 tfe_text_view_save (TFE_TEXT_VIEW (tv));
135 }
136 }
137 gtk_window_destroy (GTK_WINDOW (dialog));
138 }
139
140 void
141 tfe_text_view_save (TfeTextView *tv) {
142 g_return_if_fail (TFE_IS_TEXT_VIEW (tv));
143
144 GtkTextBuffer *tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
145 GtkTextIter start_iter;
146 GtkTextIter end_iter;
147 gchar *contents;
148 GtkWidget *message_dialog;
149 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW);
150 GError *err = NULL;
151
152 if (! gtk_text_buffer_get_modified (tb))
153 return; /* no need to save it */
154 else if (tv->file == NULL)
155 tfe_text_view_saveas (tv);
156 else {
157 gtk_text_buffer_get_bounds (tb, &start_iter, &end_iter);
158 contents = gtk_text_buffer_get_text (tb, &start_iter, &end_iter, FALSE);
159 if (g_file_replace_contents (tv->file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, &err))
160 gtk_text_buffer_set_modified (tb, FALSE);
161 else {
162 /* It is possible that tv->file is broken or you don't have permission to write. */
163 /* It is a good idea to set tv->file to NULL. */
164 if (G_IS_FILE (tv->file))
165 g_object_unref (tv->file);
166 tv->file =NULL;
167 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
168 message_dialog = gtk_message_dialog_new (GTK_WINDOW (win), GTK_DIALOG_MODAL,
169 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
170 "%s.\n", err->message);
171 g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
172 gtk_widget_show (message_dialog);
173 g_error_free (err);
174 }
175 }
176 }
177
178 void
179 tfe_text_view_saveas (TfeTextView *tv) {
180 g_return_if_fail (TFE_IS_TEXT_VIEW (tv));
181
182 GtkWidget *dialog;
183 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW);
184
185 dialog = gtk_file_chooser_dialog_new ("Save file", GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_SAVE,
186 "Cancel", GTK_RESPONSE_CANCEL,
187 "Save", GTK_RESPONSE_ACCEPT,
188 NULL);
189 g_signal_connect (dialog, "response", G_CALLBACK (saveas_dialog_response), tv);
190 gtk_widget_show (dialog);
191 }
192
193 GtkWidget *
194 tfe_text_view_new_with_file (GFile *file) {
195 g_return_val_if_fail (G_IS_FILE (file), NULL);
196
197 GtkWidget *tv;
198 GtkTextBuffer *tb;
199 char *contents;
200 gsize length;
201
202 if (! g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) /* read error */
203 return NULL;
204
205 tv = tfe_text_view_new();
206 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
207 gtk_text_buffer_set_text (tb, contents, length);
208 g_free (contents);
209 TFE_TEXT_VIEW (tv)->file = g_file_dup (file);
210 return tv;
211 }
212
213 GtkWidget *
214 tfe_text_view_new (void) {
215 return GTK_WIDGET (g_object_new (TFE_TYPE_TEXT_VIEW, NULL));
216 }
217
Total number of lines, words and characters
$ LANG=C wc tfe5/meson.build tfe5/tfeapplication.c tfe5/tfe.gresource.xml tfe5/tfe.h tfe5/tfenotebook.c tfe5/tfenotebook.h tfetextview/tfetextview.c tfetextview/tfetextview.h tfe5/tfe.ui
10 17 294 tfe5/meson.build
117 348 3576 tfe5/tfeapplication.c
6 9 153 tfe5/tfe.gresource.xml
4 6 87 tfe5/tfe.h
117 325 3064 tfe5/tfenotebook.c
12 17 196 tfe5/tfenotebook.h
217 637 7725 tfetextview/tfetextview.c
35 60 701 tfetextview/tfetextview.h
64 105 2266 tfe5/tfe.ui
582 1524 18062 total
Up: Readme.md, Prev: Section 14, Next: Section 16