mousepad-window.c 223 KB
Newer Older
Nick Schermer's avatar
Nick Schermer committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA  02111-1307  USA
 */

17
#include <mousepad/mousepad-private.h>
18
#include <mousepad/mousepad-settings.h>
Nick Schermer's avatar
Nick Schermer committed
19
#include <mousepad/mousepad-application.h>
Nick Schermer's avatar
Nick Schermer committed
20
#include <mousepad/mousepad-marshal.h>
21
#include <mousepad/mousepad-document.h>
22
#include <mousepad/mousepad-dialogs.h>
Nick Schermer's avatar
Nick Schermer committed
23
24
#include <mousepad/mousepad-replace-dialog.h>
#include <mousepad/mousepad-encoding-dialog.h>
25
26
#include <mousepad/mousepad-search-bar.h>
#include <mousepad/mousepad-statusbar.h>
Nick Schermer's avatar
Nick Schermer committed
27
#include <mousepad/mousepad-print.h>
Nick Schermer's avatar
Nick Schermer committed
28
#include <mousepad/mousepad-window.h>
Gaël Bonithon's avatar
Gaël Bonithon committed
29
#include <mousepad/mousepad-util.h>
30
#include <mousepad/mousepad-history.h>
Nick Schermer's avatar
Nick Schermer committed
31
32
33



34
35
36
37
#define PADDING                   2
#define PASTE_HISTORY_MENU_LENGTH 30
#define MIN_FONT_SIZE             6
#define MAX_FONT_SIZE             72
38

39
40
41
42
#define MENUBAR        MOUSEPAD_SETTING_MENUBAR_VISIBLE
#define STATUSBAR      MOUSEPAD_SETTING_STATUSBAR_VISIBLE
#define TOOLBAR        MOUSEPAD_SETTING_TOOLBAR_VISIBLE
#define NOTEBOOK_GROUP "Mousepad"
Nick Schermer's avatar
Nick Schermer committed
43

44
45


Gaël Bonithon's avatar
Gaël Bonithon committed
46
47
48
49
50
51
enum
{
  PROP_SEARCH_WIDGET_VISIBLE=1,
  N_PROPERTIES
};

52
53
54
enum
{
  NEW_WINDOW,
Gaël Bonithon's avatar
Gaël Bonithon committed
55
  SEARCH_COMPLETED,
56
  LAST_SIGNAL
57
58
};

59
60
61
62
63
64
65
enum
{
  AUTO = 0,
  NO,
  YES
};

66
67


68
69
70
71
72
73
74
75
76
/* GObject virtual functions */
static void              mousepad_window_set_property                 (GObject                  *object,
                                                                       guint                     prop_id,
                                                                       const GValue             *value,
                                                                       GParamSpec               *pspec);
static void              mousepad_window_get_property                 (GObject                  *object,
                                                                       guint                     prop_id,
                                                                       GValue                   *value,
                                                                       GParamSpec               *pspec);
77
static void              mousepad_window_dispose                      (GObject                  *object);
78
79
80
81
82
83
84
85
86
87
88
89
static void              mousepad_window_finalize                     (GObject                  *object);

/* GtkWindow virtual functions or property change handlers */
static gboolean          mousepad_window_close_request                (GtkWindow                *window);
static void              mousepad_window_fullscreened                 (MousepadWindow           *window);
static void              mousepad_window_save_geometry                (GtkWindow                *window);

/* event handlers */
static gboolean          mousepad_window_scroll                       (GtkEventControllerScroll *scroll,
                                                                       double                    dx,
                                                                       double                    dy,
                                                                       MousepadWindow           *window);
90
91

/* statusbar tooltips */
92
93
94
95
static void              mousepad_window_menu_set_tooltips            (MousepadWindow           *window,
                                                                       GtkWidget                *menu,
                                                                       GMenuModel               *model,
                                                                       gint                     *offset);
96
97
/* TODO Menubar */
#if 0
98
99
100
101
static void              mousepad_window_menu_item_selected           (GtkWidget                *menu_item,
                                                                       MousepadWindow           *window);
static void              mousepad_window_menu_item_deselected         (GtkWidget                *menu_item,
                                                                       MousepadWindow           *window);
102
#endif
103
104
105
106
107
108
109
110
static void              mousepad_window_toolbar_item_enter           (GtkEventControllerMotion *controller,
                                                                       double                    x,
                                                                       double                    y,
                                                                       MousepadWindow           *window);
static void              mousepad_window_toolbar_item_leave           (GtkEventControllerMotion *controller,
                                                                       double                    x,
                                                                       double                    y,
                                                                       MousepadWindow           *window);
111

112
/* window functions */
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
static gboolean          mousepad_window_open_file                    (MousepadWindow           *window,
                                                                       GFile                    *file,
                                                                       MousepadEncoding          encoding,
                                                                       gint                      line,
                                                                       gint                      column,
                                                                       gboolean                  must_exist);
static gboolean          mousepad_window_close_document               (MousepadWindow           *window,
                                                                       MousepadDocument         *document);
static void              mousepad_window_button_close_tab             (MousepadDocument         *document,
                                                                       MousepadWindow           *window);
static void              mousepad_window_set_title                    (MousepadWindow           *window);
static void              mousepad_window_update_bar_visibility        (MousepadWindow           *window,
                                                                       const gchar              *key);
static void              mousepad_window_update_tabs_visibility       (MousepadWindow           *window,
                                                                       gchar                    *key,
                                                                       GSettings                *settings);
129
130

/* notebook signals */
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
static void              mousepad_window_notebook_switch_page         (GtkNotebook              *notebook,
                                                                       GtkWidget                *page,
                                                                       guint                     page_num,
                                                                       MousepadWindow           *window);
static void              mousepad_window_notebook_added               (GtkNotebook              *notebook,
                                                                       GtkWidget                *page,
                                                                       guint                     page_num,
                                                                       MousepadWindow           *window);
static void              mousepad_window_notebook_removed             (GtkNotebook              *notebook,
                                                                       GtkWidget                *page,
                                                                       guint                     page_num,
                                                                       MousepadWindow           *window);
static GtkNotebook      *mousepad_window_notebook_create_window       (GtkNotebook              *notebook,
                                                                       GtkWidget                *page,
                                                                       MousepadWindow           *window);
static void              mousepad_window_notebook_button_pressed      (GtkGestureClick          *gesture_click,
                                                                       int                       n_press,
                                                                       double                    x,
                                                                       double                    y,
                                                                       MousepadWindow           *window);
static void              mousepad_window_notebook_button_released     (GtkGestureClick          *gesture_click,
                                                                       int                       n_press,
                                                                       double                    x,
                                                                       double                    y,
                                                                       MousepadWindow           *window);
156

157
/* document signals */
158
159
160
161
162
static void              mousepad_window_textview_menu_popup          (GtkGestureClick          *gesture,
                                                                       int                       n_press,
                                                                       double                    x,
                                                                       double                    y,
                                                                       MousepadWindow           *window);
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
static void              mousepad_window_externally_modified          (MousepadFile             *file,
                                                                       MousepadWindow           *window);
static void              mousepad_window_location_changed             (MousepadFile             *file,
                                                                       GFile                    *location,
                                                                       MousepadWindow           *window);
static void              mousepad_window_readonly_changed             (MousepadFile             *file,
                                                                       gboolean                  readonly,
                                                                       MousepadWindow           *window);
static void              mousepad_window_modified_changed             (GtkTextBuffer            *buffer,
                                                                       MousepadWindow           *window);
static void              mousepad_window_enable_edit_actions          (GObject                  *object,
                                                                       GParamSpec               *pspec,
                                                                       MousepadWindow           *window);
static void              mousepad_window_cursor_changed               (MousepadDocument         *document,
                                                                       gint                      line,
                                                                       gint                      column,
                                                                       gint                      selection,
                                                                       MousepadWindow           *window);
static void              mousepad_window_encoding_changed             (MousepadDocument         *document,
                                                                       MousepadEncoding          encoding,
                                                                       MousepadWindow           *window);
static void              mousepad_window_language_changed             (MousepadDocument         *document,
                                                                       GtkSourceLanguage        *language,
                                                                       MousepadWindow           *window);
static void              mousepad_window_overwrite_changed            (MousepadDocument         *document,
                                                                       gboolean                  overwrite,
                                                                       MousepadWindow           *window);
static void              mousepad_window_can_undo                     (GtkTextBuffer            *buffer,
                                                                       GParamSpec               *unused,
                                                                       MousepadWindow           *window);
static void              mousepad_window_can_redo                     (GtkTextBuffer            *buffer,
                                                                       GParamSpec               *unused,
                                                                       MousepadWindow           *window);
196

197
/* menu functions */
198
199
200
201
202
203
204
205
206
207
208
209
210
211
static void              mousepad_window_menu_templates               (GSimpleAction            *action,
                                                                       GVariant                 *state,
                                                                       gpointer                  data);
static void              mousepad_window_menu_tab_sizes_update        (MousepadWindow           *window);
static void              mousepad_window_update_menu_item             (MousepadWindow           *window,
                                                                       const gchar              *menu_id,
                                                                       gint                      index,
                                                                       gpointer                  data);
static void              mousepad_window_update_gomenu                (GSimpleAction            *action,
                                                                       GVariant                 *state,
                                                                       gpointer                  data);
static void              mousepad_window_recent_menu                  (GSimpleAction            *action,
                                                                       GVariant                 *state,
                                                                       gpointer                  data);
212

213
/* dnd */
214
215
216
217
static gboolean          mousepad_window_drag_data_received           (GtkDropTarget            *target,
                                                                       GValue                   *value,
                                                                       double                    x,
                                                                       double                    y,
218
                                                                       MousepadWindow           *window);
219

220
/* find and replace */
221
222
223
224
225
226
227
228
229
230
static void              mousepad_window_search                       (MousepadWindow           *window,
                                                                       MousepadSearchFlags       flags,
                                                                       const gchar              *string,
                                                                       const gchar              *replacement);
static void              mousepad_window_search_completed             (MousepadDocument         *document,
                                                                       gint                      n_matches_doc,
                                                                       const gchar              *string,
                                                                       MousepadSearchFlags       flags,
                                                                       MousepadWindow           *window);
static void              mousepad_window_hide_search_bar              (MousepadWindow           *window);
231

232
/* history clipboard functions */
233
static void              mousepad_window_paste_history_add            (MousepadWindow           *window);
234
235
/* TODO Paste History */
#if 0
236
237
238
239
240
static void              mousepad_window_paste_history_activate       (GtkMenuItem              *item,
                                                                       MousepadWindow           *window);
static GtkWidget        *mousepad_window_paste_history_menu_item      (const gchar              *text,
                                                                       const gchar              *mnemonic);
static GtkWidget        *mousepad_window_paste_history_menu           (MousepadWindow           *window);
241
#endif
242

243
/* actions */
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
static void              mousepad_window_action_new                   (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_new_window            (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_new_from_template     (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_open                  (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_open_recent           (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_clear_recent          (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_save                  (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_save_as               (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_save_all              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_reload                (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_print                 (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_detach                (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_close                 (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_close_window          (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_undo                  (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_redo                  (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_cut                   (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_copy                  (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_paste                 (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_paste_history         (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_paste_column          (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_delete_selection      (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_delete_line           (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_select_all            (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_lowercase             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_uppercase             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_titlecase             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_opposite_case         (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_tabs_to_spaces        (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_spaces_to_tabs        (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_strip_trailing_spaces (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_transpose             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_move_line_up          (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_move_line_down        (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_move_word_left        (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_move_word_right       (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_duplicate             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_increase_indent       (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_decrease_indent       (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_find                  (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_find_next             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_find_previous         (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_replace               (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_go_to_position        (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_select_font           (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_increase_font_size    (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_decrease_font_size    (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_reset_font_size       (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_bar_activate          (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_textview              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_menubar_state         (GSimpleAction            *action,
                                                                       GVariant                 *state,
                                                                       gpointer                  data);
static void              mousepad_window_action_fullscreen            (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_line_ending           (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_tab_size              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_language              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_write_bom             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_viewer_mode           (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_prev_tab              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_next_tab              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_go_to_tab             (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_contents              (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
static void              mousepad_window_action_about                 (GSimpleAction            *action,
                                                                       GVariant                 *value,
                                                                       gpointer                  data);
Nick Schermer's avatar
Nick Schermer committed
430
431
432
433
434



struct _MousepadWindowClass
{
435
  GtkApplicationWindowClass __parent__;
Nick Schermer's avatar
Nick Schermer committed
436
437
438
439
};

struct _MousepadWindow
{
440
  GtkApplicationWindow __parent__;
Nick Schermer's avatar
Nick Schermer committed
441

442
  /* the current and previous active documents */
443
  MousepadDocument    *active, *previous;
444

445
  /* main window widgets */
446
447
448
449
450
  GtkWidget           *box, *menubar_box, *menubar, *toolbar_box, *toolbar, *notebook,
                      *search_bar_box, *search_bar, *statusbar, *replace_dialog;

  /* context menus */
  GtkWidget           *textview_menu, *tab_menu, *languages_menu;
451
452

  /* menubar related */
Gaël Bonithon's avatar
Gaël Bonithon committed
453
  const gchar         *gtkmenu_key, *offset_key;
Gaël Bonithon's avatar
Gaël Bonithon committed
454
  gboolean             old_style_menu;
Gaël Bonithon's avatar
Gaël Bonithon committed
455
456
457

  /* search widgets related */
  gboolean             search_widget_visible;
458
459
460

  /* event handling */
  GtkEventController  *controller_click, *controller_key, *controller_scroll;
Nick Schermer's avatar
Nick Schermer committed
461
462
463
464
};



465
466
467
468
469
470
471
/* menubar actions */
static const GActionEntry action_entries[] =
{
  /* to make menu items insensitive, when needed */
  { "insensitive", NULL, NULL, NULL, NULL },

  /* additional action for the "Textview" menu to show the menubar when hidden */
472
  { "textview.menubar", mousepad_window_action_textview, NULL, "false", NULL },
473

474
  /* increase/decrease font size from keyboard/mouse */
475
476
477
  { "font-size-increase", mousepad_window_action_increase_font_size, NULL, NULL, NULL },
  { "font-size-decrease", mousepad_window_action_decrease_font_size, NULL, NULL, NULL },
  { "font-size-reset", mousepad_window_action_reset_font_size, NULL, NULL, NULL },
478

479
480
481
482
483
484
485
486
487
488
489
  /* "File" menu */
  { "file.new", mousepad_window_action_new, NULL, NULL, NULL },
  { "file.new-window", mousepad_window_action_new_window, NULL, NULL, NULL },
  { "file.new-from-template", NULL, NULL, "false", mousepad_window_menu_templates },
    { "file.new-from-template.new", mousepad_window_action_new_from_template, "s", NULL, NULL },

  { "file.open", mousepad_window_action_open, NULL, NULL, NULL },
  { "file.open-recent", NULL, NULL, "false", mousepad_window_recent_menu },
    { "file.open-recent.new", mousepad_window_action_open_recent, "s", NULL, NULL },
    { "file.open-recent.clear-history", mousepad_window_action_clear_recent, NULL, NULL, NULL },

Gaël Bonithon's avatar
Gaël Bonithon committed
490
491
  { "file.save", mousepad_window_action_save, NULL, "0", NULL },
  { "file.save-as", mousepad_window_action_save_as, NULL, "0", NULL },
492
  { "file.save-all", mousepad_window_action_save_all, NULL, NULL, NULL },
Gaël Bonithon's avatar
Gaël Bonithon committed
493
  { "file.reload", mousepad_window_action_reload, NULL, NULL, NULL },
494
495
496
497
498
499

  { "file.print", mousepad_window_action_print, NULL, NULL, NULL },

  { "file.detach-tab", mousepad_window_action_detach, NULL, NULL, NULL },

  { "file.close-tab", mousepad_window_action_close, NULL, NULL, NULL },
500
  { "file.close-window", mousepad_window_action_close_window, NULL, "0", NULL },
501
502
503
504
505
506
507
508
509
510
511

  /* "Edit" menu */
  { "edit.undo", mousepad_window_action_undo, NULL, NULL, NULL },
  { "edit.redo", mousepad_window_action_redo, NULL, NULL, NULL },

  { "edit.cut", mousepad_window_action_cut, NULL, NULL, NULL },
  { "edit.copy", mousepad_window_action_copy, NULL, NULL, NULL },
  { "edit.paste", mousepad_window_action_paste, NULL, NULL, NULL },
  /* "Paste Special" submenu */
    { "edit.paste-special.paste-from-history", mousepad_window_action_paste_history, NULL, NULL, NULL },
    { "edit.paste-special.paste-as-column", mousepad_window_action_paste_column, NULL, NULL, NULL },
Gaël Bonithon's avatar
Gaël Bonithon committed
512
513
  { "edit.delete-selection", mousepad_window_action_delete_selection, NULL, NULL, NULL },
  { "edit.delete-line", mousepad_window_action_delete_line, NULL, NULL, NULL },
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528

  { "edit.select-all", mousepad_window_action_select_all, NULL, NULL, NULL },

  /* "Convert" submenu */
    { "edit.convert.to-lowercase", mousepad_window_action_lowercase, NULL, NULL, NULL },
    { "edit.convert.to-uppercase", mousepad_window_action_uppercase, NULL, NULL, NULL },
    { "edit.convert.to-title-case", mousepad_window_action_titlecase, NULL, NULL, NULL },
    { "edit.convert.to-opposite-case", mousepad_window_action_opposite_case, NULL, NULL, NULL },

    { "edit.convert.tabs-to-spaces", mousepad_window_action_tabs_to_spaces, NULL, NULL, NULL },
    { "edit.convert.spaces-to-tabs", mousepad_window_action_spaces_to_tabs, NULL, NULL, NULL },

    { "edit.convert.strip-trailing-spaces", mousepad_window_action_strip_trailing_spaces, NULL, NULL, NULL },

    { "edit.convert.transpose", mousepad_window_action_transpose, NULL, NULL, NULL },
Gaël Bonithon's avatar
Gaël Bonithon committed
529
530
531
532
533
  /* "Move" submenu */
    { "edit.move.line-up", mousepad_window_action_move_line_up, NULL, NULL, NULL },
    { "edit.move.line-down", mousepad_window_action_move_line_down, NULL, NULL, NULL },
    { "edit.move.word-left", mousepad_window_action_move_word_left, NULL, NULL, NULL },
    { "edit.move.word-right", mousepad_window_action_move_word_right, NULL, NULL, NULL },
534
535
536
537
538
539
540
541
542
543
544
545
546
547
  { "edit.duplicate-line-selection", mousepad_window_action_duplicate, NULL, NULL, NULL },
  { "edit.increase-indent", mousepad_window_action_increase_indent, NULL, NULL, NULL },
  { "edit.decrease-indent", mousepad_window_action_decrease_indent, NULL, NULL, NULL },

  /* "Search" menu */
  { "search.find", mousepad_window_action_find, NULL, NULL, NULL },
  { "search.find-next", mousepad_window_action_find_next, NULL, NULL, NULL },
  { "search.find-previous", mousepad_window_action_find_previous, NULL, NULL, NULL },
  { "search.find-and-replace", mousepad_window_action_replace, NULL, NULL, NULL },

  { "search.go-to", mousepad_window_action_go_to_position, NULL, NULL, NULL },

  /* "View" menu */
  { "view.select-font", mousepad_window_action_select_font, NULL, NULL, NULL },
548
549
550
  { MENUBAR, mousepad_window_action_bar_activate, NULL, "false", mousepad_window_action_menubar_state },
  { TOOLBAR, mousepad_window_action_bar_activate, NULL, "false", NULL },
  { STATUSBAR, mousepad_window_action_bar_activate, NULL, "false", NULL },
551

552
  { "view.fullscreen", mousepad_window_action_fullscreen, NULL, "false", NULL },
553
554
555

  /* "Document" menu */
  { "document", NULL, NULL, "false", mousepad_window_update_gomenu },
556
557
  /* "Tab Size" submenu */
    { "document.tab.tab-size", mousepad_window_action_tab_size, "i", "2", NULL },
558

559
  /* "Filetype" submenu */
560
    { "document.filetype", mousepad_window_action_language, "s", "'" MOUSEPAD_LANGUAGE_NONE "'", NULL },
561
562
  /* "Line Ending" submenu */
    { "document.line-ending", mousepad_window_action_line_ending, "i", "0", NULL },
563

564
  { "document.write-unicode-bom", mousepad_window_action_write_bom, NULL, "false", NULL },
Gaël Bonithon's avatar
Gaël Bonithon committed
565
  { "document.viewer-mode", mousepad_window_action_viewer_mode, NULL, "false", NULL },
566

567
568
  { "document.previous-tab", mousepad_window_action_prev_tab, NULL, NULL, NULL },
  { "document.next-tab", mousepad_window_action_next_tab, NULL, NULL, NULL },
569

570
  { "document.go-to-tab", mousepad_window_action_go_to_tab, "i", "0", NULL },
571
572
573
574

  /* "Help" menu */
  { "help.contents", mousepad_window_action_contents, NULL, NULL, NULL },
  { "help.about", mousepad_window_action_about, NULL, NULL, NULL }
575
576
};

577
578


579
/* global variables */
Nick Schermer's avatar
Nick Schermer committed
580
581
582
583
static guint   window_signals[LAST_SIGNAL];
static gint    lock_menu_updates = 0;
static GSList *clipboard_history = NULL;
static guint   clipboard_history_ref_count = 0;
584
static GFile  *last_save_location = NULL;
585
static guint   last_save_location_ref_count = 0;
586

Nick Schermer's avatar
Nick Schermer committed
587
588


589
G_DEFINE_TYPE (MousepadWindow, mousepad_window, GTK_TYPE_APPLICATION_WINDOW)
Nick Schermer's avatar
Nick Schermer committed
590
591
592



Nick Schermer's avatar
Nick Schermer committed
593
GtkWidget *
594
mousepad_window_new (MousepadApplication *application)
Nick Schermer's avatar
Nick Schermer committed
595
{
596
  return g_object_new (MOUSEPAD_TYPE_WINDOW, "application", GTK_APPLICATION (application), NULL);
Nick Schermer's avatar
Nick Schermer committed
597
598
599
600
601
602
603
}



static void
mousepad_window_class_init (MousepadWindowClass *klass)
{
604
605
  GObjectClass   *gobject_class = G_OBJECT_CLASS (klass);
  GtkWindowClass *gtkwindow_class = GTK_WINDOW_CLASS (klass);
Nick Schermer's avatar
Nick Schermer committed
606

Gaël Bonithon's avatar
Gaël Bonithon committed
607
608
  gobject_class->set_property = mousepad_window_set_property;
  gobject_class->get_property = mousepad_window_get_property;
609
  gobject_class->dispose = mousepad_window_dispose;
Nick Schermer's avatar
Nick Schermer committed
610
611
  gobject_class->finalize = mousepad_window_finalize;

612
  gtkwindow_class->close_request = mousepad_window_close_request;
613
614

  window_signals[NEW_WINDOW] =
615
    g_signal_new (I_("new-window"), G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST,
616
                  0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
Gaël Bonithon's avatar
Gaël Bonithon committed
617
618

  window_signals[SEARCH_COMPLETED] =
619
620
621
    g_signal_new (I_("search-completed"), G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST,
                  0, NULL, NULL, _mousepad_marshal_VOID__INT_STRING_FLAGS,
                  G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_STRING, MOUSEPAD_TYPE_SEARCH_FLAGS);
Gaël Bonithon's avatar
Gaël Bonithon committed
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640

  g_object_class_install_property (gobject_class, PROP_SEARCH_WIDGET_VISIBLE,
    g_param_spec_boolean ("search-widget-visible", "SearchWidgetVisible",
                          "At least one search widget is visible or not",
                          FALSE, G_PARAM_READWRITE));
}



static void
mousepad_window_set_property (GObject      *object,
                              guint         prop_id,
                              const GValue *value,
                              GParamSpec   *pspec)
{
  MousepadWindow *window = MOUSEPAD_WINDOW (object);

  switch (prop_id)
    {
641
642
643
644
645
646
      case PROP_SEARCH_WIDGET_VISIBLE:
        window->search_widget_visible = g_value_get_boolean (value);
        break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
Gaël Bonithon's avatar
Gaël Bonithon committed
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
    }
}



static void
mousepad_window_get_property (GObject    *object,
                              guint       prop_id,
                              GValue     *value,
                              GParamSpec *pspec)
{
  MousepadWindow *window = MOUSEPAD_WINDOW (object);

  switch (prop_id)
    {
662
663
664
665
666
667
      case PROP_SEARCH_WIDGET_VISIBLE:
        g_value_set_boolean (value, window->search_widget_visible);
        break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
Gaël Bonithon's avatar
Gaël Bonithon committed
668
669
670
671
672
    }
}



673
674
675
676
677
678
679
680
681
682
683
684
685
686
static void
mousepad_window_dispose (GObject *object)
{
  MousepadWindow *window = MOUSEPAD_WINDOW (object);

  gtk_widget_unparent (window->textview_menu);
  gtk_widget_unparent (window->tab_menu);
  gtk_widget_unparent (window->languages_menu);

  G_OBJECT_CLASS (mousepad_window_parent_class)->dispose (object);
}



Gaël Bonithon's avatar
Gaël Bonithon committed
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
static void
mousepad_window_finalize (GObject *object)
{
  /* decrease history clipboard ref count */
  clipboard_history_ref_count--;

  /* decrease last save location ref count */
  last_save_location_ref_count--;

  /* free clipboard history if needed */
  if (clipboard_history_ref_count == 0 && clipboard_history != NULL)
    g_slist_free_full (clipboard_history, g_free);

  /* free last save location if needed */
  if (last_save_location_ref_count == 0 && last_save_location != NULL)
    {
703
      g_object_unref (last_save_location);
Gaël Bonithon's avatar
Gaël Bonithon committed
704
705
706
      last_save_location = NULL;
    }

707
  G_OBJECT_CLASS (mousepad_window_parent_class)->finalize (object);
Nick Schermer's avatar
Nick Schermer committed
708
709
710
}


711

712
static void
713
mousepad_window_restore_geometry (MousepadWindow *window)
714
715
{
  /* first restore size */
716
717
718
719
  if (MOUSEPAD_SETTING_GET_BOOLEAN (REMEMBER_SIZE))
    gtk_window_set_default_size (GTK_WINDOW (window),
                                 MOUSEPAD_SETTING_GET_UINT (WINDOW_WIDTH),
                                 MOUSEPAD_SETTING_GET_UINT (WINDOW_HEIGHT));
720

721
722
/* TODO: see mousepad_window_save_geometry() */
#if 0
723
  /* then restore position */
724
725
726
727
728
  if (MOUSEPAD_SETTING_GET_BOOLEAN (REMEMBER_POSITION))
    gtk_window_move (GTK_WINDOW (window),
                     MOUSEPAD_SETTING_GET_UINT (WINDOW_LEFT),
                     MOUSEPAD_SETTING_GET_UINT (WINDOW_TOP));
#endif
729
730

  /* finally restore window state */
731
  if (MOUSEPAD_SETTING_GET_BOOLEAN (REMEMBER_STATE))
732
733
    {
      /* first restore if it was maximized */
734
      if (MOUSEPAD_SETTING_GET_BOOLEAN (WINDOW_MAXIMIZED))
735
736
        gtk_window_maximize (GTK_WINDOW (window));

737
      /* then restore if it was fullscreen and update action state accordingly */
738
      if (MOUSEPAD_SETTING_GET_BOOLEAN (WINDOW_FULLSCREEN))
739
        g_action_group_activate_action (G_ACTION_GROUP (window), "view.fullscreen", NULL);
740
741
742
743
744
    }
}



745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
static void
mousepad_window_action_statusbar_overwrite (MousepadWindow *window,
                                            gboolean        overwrite)
{
  g_return_if_fail (MOUSEPAD_IS_WINDOW (window));
  g_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active));

  /* set the new overwrite mode */
  mousepad_document_set_overwrite (window->active, overwrite);
}



static void
mousepad_window_create_statusbar (MousepadWindow *window)
{
  /* setup a new statusbar */
  window->statusbar = mousepad_statusbar_new ();

  /* update the statusbar visibility and related actions state */
  mousepad_window_update_bar_visibility (window, STATUSBAR);

  /* pack the statusbar into the window UI */
  gtk_box_append (GTK_BOX (window->box), window->statusbar);

  /* overwrite toggle signal */
  g_signal_connect_swapped (window->statusbar, "enable-overwrite",
                            G_CALLBACK (mousepad_window_action_statusbar_overwrite), window);

  /* connect to some signals to keep in sync */
  MOUSEPAD_SETTING_CONNECT_OBJECT (STATUSBAR_VISIBLE, mousepad_window_update_bar_visibility,
                                   window, G_CONNECT_SWAPPED);

  MOUSEPAD_SETTING_CONNECT_OBJECT (STATUSBAR_VISIBLE_FULLSCREEN,
                                   mousepad_window_update_bar_visibility,
                                   window, G_CONNECT_SWAPPED);
}



static void
mousepad_window_update_toolbar_properties (MousepadWindow *window,
                                           gchar          *key,
                                           GSettings      *settings)
{
790
791
/* TODO Toolbar */
#if 0
792
793
794
795
796
797
798
799
  GtkToolbarStyle style;
  GtkIconSize     size;

  style = MOUSEPAD_SETTING_GET_ENUM (TOOLBAR_STYLE);
  size = MOUSEPAD_SETTING_GET_ENUM (TOOLBAR_ICON_SIZE);

  gtk_toolbar_set_style (GTK_TOOLBAR (window->toolbar), style);
  gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->toolbar), size);
800
#endif
801
802
803
804
}



805
static void
806
807
808
809
mousepad_window_update_toolbar_item (GMenuModel  *model,
                                     gint         position,
                                     gint         removed,
                                     gint         added,
810
                                     GtkWidget   *item)
811
{
812
  GtkApplication *application;
813
814
  GtkWidget      *window;
  GVariant       *value;
Gaël Bonithon's avatar
Gaël Bonithon committed
815

816
817
818
819
820
  /* don't update the toolbar item properties for the non active application windows */
  if ((window = gtk_widget_get_ancestor (GTK_WIDGET (item), MOUSEPAD_TYPE_WINDOW))
      && (application = gtk_window_get_application (GTK_WINDOW (window)))
      && (GTK_WINDOW (window) != gtk_application_get_active_window (application)))
    return;
821

822
823
824
  /* update the toolbar item properties only when the corresponding menu item is added,
   * that is at the end of its own update (see also the comment above the toolbar in
   * mousepad/resources/gtk/menus.ui) */
Gaël Bonithon's avatar
Gaël Bonithon committed
825
  if (added && position == GPOINTER_TO_INT (mousepad_object_get_data (item, "index")))
826
827
828
829
    {
      /* every menu item should have at least a label, so we can suppose it exists */
      value = g_menu_model_get_item_attribute_value (model, position, "label",
                                                     G_VARIANT_TYPE_STRING);
830
      gtk_button_set_label (GTK_BUTTON (item), g_variant_get_string (value, NULL));
831
832
833
834
835
836
837
      g_variant_unref (value);

      /* all the following item attributes should normally be filled to build a toolbar item,
       * but strictly speaking, it is not necessary */
      if ((value = g_menu_model_get_item_attribute_value (model, position, "icon",
                                                          G_VARIANT_TYPE_STRING)))
        {
838
          gtk_button_set_icon_name (GTK_BUTTON (item), g_variant_get_string (value, NULL));
839
840
          g_variant_unref (value);
        }
841

842
843
844
      if ((value = g_menu_model_get_item_attribute_value (model, position, "tooltip",
                                                          G_VARIANT_TYPE_STRING)))
        {
845
          gtk_widget_set_tooltip_text (item, g_variant_get_string (value, NULL));
846
847
          g_variant_unref (value);
        }
Gaël Bonithon's avatar
Gaël Bonithon committed
848

849
850
851
852
853
854
855
856
      if ((value = g_menu_model_get_item_attribute_value (model, position, "action",
                                                          G_VARIANT_TYPE_STRING)))
        {
          gtk_actionable_set_action_name (GTK_ACTIONABLE (item),
                                          g_variant_get_string (value, NULL));
          g_variant_unref (value);
        }
    }
857
858
859
860
}



Nick Schermer's avatar
Nick Schermer committed
861
static void
862
mousepad_window_toolbar_insert (MousepadWindow *window,
863
864
865
                                GtkWidget      *toolbar,
                                GMenuModel     *model,
                                gint            index)
Nick Schermer's avatar
Nick Schermer committed
866
{
867
  GtkEventController *controller;
868
  GtkWidget          *item;
869
  gchar              *tooltip;
Nick Schermer's avatar
Nick Schermer committed
870

871
  /* create an empty toolbar item */
872
  item = gtk_button_new ();
873
874

  /* initialize the toolbar item properties from the menu item attributes */
Gaël Bonithon's avatar
Gaël Bonithon committed
875
  mousepad_object_set_data (item, "index", GINT_TO_POINTER (index));
876
  mousepad_window_update_toolbar_item (model, index, 0, 1, item);
877
  gtk_button_set_use_underline (GTK_BUTTON (item), TRUE);
Nick Schermer's avatar
Nick Schermer committed
878

879
880
881
  /* a kind of binding between the menu item attributes and the toolbar item properties */
  g_signal_connect_object (model, "items-changed",
                           G_CALLBACK (mousepad_window_update_toolbar_item), item, 0);
882

883
  /* connect to signals to show the tooltip in the status bar */
884
  tooltip = g_strdup (gtk_widget_get_tooltip_text (GTK_WIDGET (item)));
885
886
887
888
889
890
  controller = gtk_event_controller_motion_new ();
  mousepad_object_set_data_full (controller, "tooltip", tooltip, g_free);
  g_signal_connect (controller, "enter",
                    G_CALLBACK (mousepad_window_toolbar_item_enter), window);
  g_signal_connect (controller, "leave",
                    G_CALLBACK (mousepad_window_toolbar_item_leave), window);
891
  gtk_widget_add_controller (item, controller);
892

893
  /* append the item to the end of the toolbar */
894
  gtk_box_append (GTK_BOX (toolbar), item);
895
}
896

897

Nick Schermer's avatar
Nick Schermer committed
898

899
900
901
static GtkWidget *
mousepad_window_toolbar_new_from_model (MousepadWindow *window,
                                        GMenuModel     *model)
902
{
903
904
905
  GtkWidget  *toolbar, *item = NULL;
  GMenuModel *section;
  gint        m, n, n_items;
906
907

  /* create the toolbar and set the main properties */
908
909
910
911
912
  toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_widget_add_css_class (toolbar, "toolbar");

/* TODO Toolbar */
#if 0
913
914
  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
  gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR);
915
#endif
916
917

  /* insert items */
918
919
920
921
922
923
924
925
926
  for (m = 0; m < g_menu_model_get_n_items (model); m++)
    {
      /* section GMenuItem */
      if ((section = g_menu_model_get_item_link (model, m, G_MENU_LINK_SECTION))
          && (n_items = g_menu_model_get_n_items (section)))
        {
          /* append a toolbar separator when needed */
          if (m > 0)
            {
927
928
              item = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
              gtk_box_append (GTK_BOX (toolbar), item);
929
930
931
932
933
934
935
936
937
938
            }

          /* walk through the section */
          for (n = 0; n < n_items; n++)
            mousepad_window_toolbar_insert (window, toolbar, section, n);
        }
      /* real GMenuItem */
      else
        mousepad_window_toolbar_insert (window, toolbar, model, m);
    }
939

940
941
942
  /* align the last item (fullscreen) on the right */
  gtk_widget_set_halign (gtk_widget_get_last_child (toolbar), GTK_ALIGN_END);
  gtk_widget_set_hexpand (gtk_widget_get_last_child (toolbar), TRUE);
Matthew Brush's avatar
Matthew Brush committed
943

944
945
  return toolbar;
}
Matthew Brush's avatar
Matthew Brush committed
946

947
948
949
950
951
952
953
954
955
956
957
958
959


static void
mousepad_window_post_init (MousepadWindow *window)
{
  GtkApplication *application;
  GMenuModel     *model;
  gchar          *gtkmenu_key, *offset_key;
  gint            window_id;

  /* disconnect this handler */
  mousepad_disconnect_by_func (window, mousepad_window_post_init, NULL);

960
961
962
  /* setup CSD titlebar */
  mousepad_util_set_titlebar (GTK_WINDOW (window));

963
964
965
966
967
968
969
970
971
972
973
974
  /* set the unique menu and offset keys for this window */
  window_id = gtk_application_window_get_id (GTK_APPLICATION_WINDOW (window));
  gtkmenu_key = g_strdup_printf ("gtkmenu-%d", window_id);
  offset_key = g_strdup_printf ("offset-%d", window_id);
  window->gtkmenu_key = g_intern_string (gtkmenu_key);
  window->offset_key = g_intern_string (offset_key);
  g_free (gtkmenu_key);
  g_free (offset_key);

  /* create text view menu and set tooltips (must be done before setting the menubar visibility) */
  application = gtk_window_get_application (GTK_WINDOW (window));
  model = G_MENU_MODEL (gtk_application_get_menu_by_id (application, "textview-menu"));
975
976
  window->textview_menu = gtk_popover_menu_new_from_model_full (model, GTK_POPOVER_MENU_NESTED);
  gtk_widget_set_parent (window->textview_menu, GTK_WIDGET (window));
977
978
979
980
  mousepad_window_menu_set_tooltips (window, window->textview_menu, model, NULL);

  /* create tab menu and set tooltips */
  model = G_MENU_MODEL (gtk_application_get_menu_by_id (application, "tab-menu"));
981
982
  window->tab_menu = gtk_popover_menu_new_from_model_full (model, GTK_POPOVER_MENU_NESTED);
  gtk_widget_set_parent (window->tab_menu, window->notebook);
983
984
985
986
  mousepad_window_menu_set_tooltips (window, window->tab_menu, model, NULL);

  /* create languages menu and set tooltips */
  model = G_MENU_MODEL (gtk_application_get_menu_by_id (application, "document.filetype"));
987
  window->languages_menu = gtk_popover_menu_new_from_model_full (model, GTK_POPOVER_MENU_NESTED);
988
989
990
991
992
993
994
995
996
997
998
  mousepad_window_menu_set_tooltips (window, window->languages_menu, model, NULL);

  /* hide the default menubar */
  gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), FALSE);

  /*
   * Outsource the creation of the menubar from
   * gtk/gtk/gtkapplicationwindow.c:gtk_application_window_update_menubar(), to make the menubar
   * a window attribute, and be able to access its items to show their tooltips in the statusbar.
   */
  model = gtk_application_get_menubar (application);
999
  window->menubar = gtk_popover_menu_bar_new_from_model (model);
1000