5 #include <glade/glade.h>
6 #include <glib/gi18n.h>
8 #ifdef WITH_MAEMOFULLSCREEN
9 #include <hildon-widgets/hildon-program.h>
11 #include <libgnome/libgnome.h>
13 #include "GtkDasherControl.h"
14 #include "KeyboardHelper.h"
15 #include "Preferences.h"
16 #include "dasher_lock_dialogue.h"
18 #include "dasher_maemo_helper.h"
20 #include "dasher_main.h"
22 /* Static instance of singleton, USE SPARINGLY */
23 static DasherMain
*g_pDasherMain
= NULL
;
25 struct _DasherMainPrivate
{
26 // The glade XML file - TODO: this shouldn't be kept after interface has been loaded
29 // Child objects owned here
30 DasherAppSettings
*pAppSettings
;
31 DasherPreferencesDialogue
*pPreferencesDialogue
;
32 DasherEditor
*pEditor
;
34 CKeyboardHelper
*pKeyboardHelper
;
36 // Various widgets which need to be cached:
37 GtkWidget
*pBufferView
;
39 GtkWidget
*pMainWindow
;
42 GtkWidget
*pAlphabetCombo
;
43 GtkWidget
*pStatusControl
;
44 GtkWidget
*pDasherWidget
;
46 GtkListStore
*pAlphabetList
;
47 GtkAccelGroup
*pAccel
;
48 gulong iAlphabetComboHandler
;
50 // Widgets used for maemo
52 DasherMaemoHelper
*pMaemoHelper
;
53 #ifdef WITH_MAEMOFULLSCREEN
54 HildonProgram
*pProgram
;
55 HildonWindow
*pHWindow
;
59 // Properties of the main window
62 bool bWidgetsInitialised
;
65 typedef struct _DasherMainPrivate DasherMainPrivate
;
67 // TODO: Make sure this is actually used
68 #define DASHER_MAIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), TYPE_DASHER_MAIN, DasherMainPrivate))
75 static guint dasher_main_signals
[SIGNAL_NUM
] = { 0 };
77 /* Automatic command hookups */
79 typedef struct _DasherMenuCommand DasherMenuCommand
;
81 struct _DasherMenuCommand
{
83 const gchar
*szWidgetName
;
84 const gchar
*szCommand
;
87 static DasherMenuCommand MenuCommands
[] = {
89 {NULL
, "menu_command_new", "new"},
90 {NULL
, "menu_command_open", "open"},
91 {NULL
, "menu_command_save", "save"},
92 {NULL
, "menu_command_saveas", "saveas"},
93 {NULL
, "menu_command_append", "append"},
94 {NULL
, "menu_command_import", "import"},
95 {NULL
, "menu_command_quit", "quit"},
96 {NULL
, "menu_command_cut", "cut"},
97 {NULL
, "menu_command_copy", "copy"},
98 {NULL
, "menu_command_copyall", "copyall"},
99 {NULL
, "menu_command_paste", "paste"},
100 {NULL
, "menu_command_preferences", "preferences"},
101 {NULL
, "menu_command_tutorial", "tutorial"},
102 {NULL
, "menu_command_help", "help"},
103 {NULL
, "menu_command_about", "about"},
106 {NULL
, "tb_command_new", "new"},
107 {NULL
, "tb_command_open", "open"},
108 {NULL
, "tb_command_save", "save"},
109 {NULL
, "tb_command_saveas", "saveas"},
110 {NULL
, "tb_command_cut", "cut"},
111 {NULL
, "tb_command_copy", "copy"},
112 {NULL
, "tb_command_paste", "paste"}
115 G_DEFINE_TYPE(DasherMain
, dasher_main
, G_TYPE_OBJECT
);
117 static void dasher_main_finalize(GObject
*pObject
);
119 /* Private member functions */
120 static void dasher_main_setup_window_state(DasherMain
*pSelf
);
121 static void dasher_main_setup_window_style(DasherMain
*pSelf
);
122 static void dasher_main_setup_internal_layout(DasherMain
*pSelf
);
123 static void dasher_main_refresh_font(DasherMain
*pSelf
);
124 static void dasher_main_set_filename(DasherMain
*pSelf
);
126 /* ... Table based menu/toolbar commands */
127 static void dasher_main_connect_menus(DasherMain
*pSelf
);
128 static void dasher_main_menu_command(DasherMain
*pSelf
, GtkWidget
*pWidget
);
130 static void dasher_main_command_import(DasherMain
*pSelf
);
131 static void dasher_main_command_quit(DasherMain
*pSelf
);
132 static void dasher_main_command_preferences(DasherMain
*pSelf
);
133 static void dasher_main_command_preferences_alphabet(DasherMain
*pSelf
);
134 static void dasher_main_command_tutorial(DasherMain
*pSelf
);
135 static void dasher_main_command_help(DasherMain
*pSelf
);
136 static void dasher_main_command_about(DasherMain
*pself
);
138 static gboolean
dasher_main_speed_changed(DasherMain
*pSelf
);
139 static void dasher_main_alphabet_combo_changed(DasherMain
*pSelf
);
140 // TODO: populate speed slider
141 static void dasher_main_populate_alphabet_combo(DasherMain
*pSelf
);
143 /* TODO: order these in file */
144 static void dasher_main_load_interface(DasherMain
*pSelf
);
145 static void dasher_main_create_preferences(DasherMain
*pSelf
);
146 static void dasher_main_handle_parameter_change(DasherMain
*pSelf
, int iParameter
);
147 static void dasher_main_load_state(DasherMain
*pSelf
);
148 static void dasher_main_save_state(DasherMain
*pSelf
);
149 static void dasher_main_setup_window(DasherMain
*pSelf
);
150 static void dasher_main_populate_controls(DasherMain
*pSelf
);
151 static void dasher_main_connect_control(DasherMain
*pSelf
);
152 static gboolean
dasher_main_command(DasherMain
*pSelf
, const gchar
*szCommand
);
153 static gint
dasher_main_lookup_key(DasherMain
*pSelf
, guint iKeyVal
);
155 /* TODO: Various functions which haven't yet been rationalised */
156 gboolean
grab_focus();
158 // TODO: Sort out callbacks - 1 rename, 2 check return values
160 /* Callback functions */
161 extern "C" GtkWidget
*create_dasher_control(gchar
*szName
, gchar
*szString1
, gchar
*szString2
, gint iInt1
, gint iInt2
);
163 /* ... Message handling from main window widgets */
164 extern "C" gboolean
dasher_main_cb_menu_command(GtkWidget
*pWidget
, gpointer pUserData
);
165 extern "C" gboolean
speed_changed(GtkWidget
*pWidget
, gpointer user_data
);
166 extern "C" void alphabet_combo_changed(GtkWidget
*pWidget
, gpointer pUserData
);
167 extern "C" void dasher_main_cb_filename_changed(DasherEditor
*pEditor
, gpointer pUserData
);
168 extern "C" void dasher_main_cb_buffer_changed(DasherEditor
*pEditor
, gpointer pUserData
);
169 extern "C" void dasher_main_cb_context_changed(DasherEditor
*pEditor
, gpointer pUserData
);
170 extern "C" gboolean
dasher_main_cb_window_close(GtkWidget
*pWidget
, gpointer pUserData
);
171 extern "C" void parameter_notification(GtkDasherControl
*pDasherControl
, gint iParameter
, gpointer data
);
173 /* ... Focus management and event forwarding */
174 extern "C" bool focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
);
175 extern "C" bool edit_focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
);
176 extern "C" gboolean
take_real_focus(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer user_data
);
178 extern "C" gboolean
edit_key_press(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
);
179 extern "C" gboolean
edit_key_release(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
);
181 /* ... Temporary test/debug functions */
182 extern "C" gboolean
test_focus_handler(GtkWidget
*pWidget
, GtkDirectionType iDirection
, gpointer
*pUserData
);
184 extern "C" void handle_context_request(GtkDasherControl
* pDasherControl
, gint iOffset
, gint iLength
, gpointer data
);
185 extern "C" void handle_control_event(GtkDasherControl
*pDasherControl
, gint iEvent
, gpointer data
);
186 extern "C" void handle_start_event(GtkDasherControl
*pDasherControl
, gpointer data
);
187 extern "C" gint
dasher_main_key_snooper(GtkWidget
*pWidget
, GdkEventKey
*pEvent
, gpointer pUserData
);
189 /* Boilerplate code */
191 dasher_main_class_init(DasherMainClass
*pClass
) {
192 g_type_class_add_private(pClass
, sizeof(DasherMainPrivate
));
194 dasher_main_signals
[REALIZED
] = g_signal_new("realized", G_TYPE_FROM_CLASS(pClass
),
195 (GSignalFlags
)(G_SIGNAL_RUN_FIRST
| G_SIGNAL_ACTION
),
196 G_STRUCT_OFFSET(DasherMainClass
, realized
),
197 NULL
, NULL
, g_cclosure_marshal_VOID__VOID
,
200 GObjectClass
*pObjectClass
= (GObjectClass
*)pClass
;
201 pObjectClass
->finalize
= dasher_main_finalize
;
205 dasher_main_init(DasherMain
*pDasherMain
) {
206 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
208 /* TODO: define log domain */
209 g_debug("Initialising DasherMain");
211 pPrivate
->pAppSettings
= NULL
;
212 pPrivate
->pEditor
= NULL
;
213 pPrivate
->pPreferencesDialogue
= NULL
;
215 pPrivate
->pKeyboardHelper
= new CKeyboardHelper(NULL
);
217 pPrivate
->bWidgetsInitialised
= false;
221 dasher_main_finalize(GObject
*pObject
) {
222 /* TODO: Need a general overview of class finalisation */
223 g_debug("Finalizing DasherMain");
225 DasherMain
*pDasherMain
= DASHER_MAIN(pObject
);
226 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
228 dasher_main_save_state(pDasherMain
);
230 /* TODO: Does unref really do the right thing - check the whole ref counting situation */
231 if(pPrivate
->pEditor
)
232 g_object_unref(pPrivate
->pEditor
);
234 if(pPrivate
->pPreferencesDialogue
)
235 g_object_unref(pPrivate
->pPreferencesDialogue
);
237 if(pPrivate
->pAppSettings
)
238 g_object_unref(pPrivate
->pAppSettings
);
240 gtk_widget_destroy(pPrivate
->pMainWindow
);
242 /* TDO: Do we need to take down anything else? */
247 dasher_main_new(int *argc
, char ***argv
, SCommandLine
*pCommandLine
) {
249 return g_pDasherMain
;
251 DasherMain
*pDasherMain
= (DasherMain
*)(g_object_new(dasher_main_get_type(), NULL
));
252 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
254 /* Create the app settings object */
255 pPrivate
->pAppSettings
= dasher_app_settings_new(*argc
, *argv
);
257 /* Load the user interface from the glade file */
258 if(pCommandLine
&& pCommandLine
->szAppStyle
) {
259 if(!strcmp(pCommandLine
->szAppStyle
, "traditional")) {
260 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 0);
262 else if(!strcmp(pCommandLine
->szAppStyle
, "compose")) {
263 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 1);
265 else if(!strcmp(pCommandLine
->szAppStyle
, "direct")) {
266 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 2);
268 else if(!strcmp(pCommandLine
->szAppStyle
, "fullscreen")) {
269 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 3);
272 g_error("Application style %s is not supported", pCommandLine
->szAppStyle
);
276 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 0);
279 dasher_main_load_interface(pDasherMain
);
281 dasher_app_settings_set_widget(pPrivate
->pAppSettings
, GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
));
282 dasher_main_setup_window(pDasherMain
);
284 /* Create the editor */
285 gchar
*szFullPath
= NULL
;
288 if(pCommandLine
->szFilename
) {
289 if(!g_path_is_absolute(pCommandLine
->szFilename
)) {
291 cwd
= (char *)malloc(1024 * sizeof(char));
293 szFullPath
= g_build_path("/", cwd
, pCommandLine
->szFilename
, NULL
);
296 szFullPath
= g_strdup(pCommandLine
->szFilename
);
301 pPrivate
->pEditor
= dasher_editor_new(pPrivate
->pAppSettings
, pDasherMain
, pPrivate
->pGladeXML
, szFullPath
);
305 g_signal_connect(pPrivate
->pEditor
, "filename_changed", G_CALLBACK(dasher_main_cb_filename_changed
), pDasherMain
);
306 g_signal_connect(pPrivate
->pEditor
, "buffer_changed", G_CALLBACK(dasher_main_cb_buffer_changed
), pDasherMain
);
307 g_signal_connect(pPrivate
->pEditor
, "context_changed", G_CALLBACK(dasher_main_cb_context_changed
), pDasherMain
);
309 /* Create the preferences window */
310 dasher_main_create_preferences(pDasherMain
);
312 /* Create the lock dialogue (to be removed in future versions) */
314 dasher_lock_dialogue_new(pPrivate
->pGladeXML
, GTK_WINDOW(pPrivate
->pMainWindow
));
316 dasher_lock_dialogue_new(pPrivate
->pGladeXML
, 0);
319 /* Set up various bits and pieces */
320 dasher_main_set_filename(pDasherMain
);
321 dasher_main_populate_controls(pDasherMain
);
322 dasher_main_connect_control(pDasherMain
);
324 gtk_key_snooper_install(dasher_main_key_snooper
, pDasherMain
);
326 /* Cache a file-wide static pointer to the singleton class */
327 g_pDasherMain
= pDasherMain
;
333 /* Load the window interface from the glade file, and do various initialisation bits and pieces */
335 dasher_main_load_interface(DasherMain
*pSelf
) {
336 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
338 const char *szGladeFilename
= NULL
;
341 szGladeFilename
= PROGDATA
"/dashergpe.glade";
343 #ifdef WITH_MAEMOFULLSCREEN
344 // szGladeFilename = "/var/lib/install" PROGDATA "/dashermaemofullscreen.glade";
345 szGladeFilename
= PROGDATA
"/dashermaemofullscreen.glade";
347 //szGladeFilename = "/var/lib/install" PROGDATA "/dashermaemo.glade";
348 szGladeFilename
= PROGDATA
"/dashermaemo.glade";
351 switch(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
)) {
353 szGladeFilename
= PROGDATA
"/dasher.traditional.glade";
356 szGladeFilename
= PROGDATA
"/dasher.compose.glade";
359 szGladeFilename
= PROGDATA
"/dasher.direct.glade";
362 szGladeFilename
= PROGDATA
"/dasher.fullscreen.glade";
365 g_error("Inconsistent application style specified.");
369 if(!szGladeFilename
) {
370 g_error("Failure to determine glade filename");
373 pPrivate
->pGladeXML
= glade_xml_new(szGladeFilename
, NULL
, NULL
);
375 if (!pPrivate
->pGladeXML
) {
376 g_error("Can't find Glade file: %s. Dasher is unlikely to be correctly installed.", szGladeFilename
);
379 glade_xml_signal_autoconnect(pPrivate
->pGladeXML
);
381 // Save the details of some of the widgets for later
382 // pPrivate->pActionPane = glade_xml_get_widget(pPrivate->pGladeXML, "vbox39");
383 pPrivate
->pBufferView
= glade_xml_get_widget(pPrivate
->pGladeXML
, "the_text_view");
384 pPrivate
->pDivider
= glade_xml_get_widget(pPrivate
->pGladeXML
, "main_divider");
385 // pPrivate->pEditPane = glade_xml_get_widget(pPrivate->pGladeXML, "vbox40");
386 pPrivate
->pMainWindow
= glade_xml_get_widget(pPrivate
->pGladeXML
, "window");
387 pPrivate
->pToolbar
= glade_xml_get_widget(pPrivate
->pGladeXML
, "toolbar");
388 // pPrivate->pMenuBar = glade_xml_get_widget(pPrivate->pGladeXML, "dasher_menu_bar");
389 pPrivate
->pDasherWidget
= glade_xml_get_widget(pPrivate
->pGladeXML
, "DasherControl");
392 pPrivate
->pSpeedBox
= glade_xml_get_widget(pPrivate
->pGladeXML
, "spinbutton1");
393 pPrivate
->pAlphabetCombo
= glade_xml_get_widget(pPrivate
->pGladeXML
, "combobox1");
394 pPrivate
->pStatusControl
= glade_xml_get_widget(pPrivate
->pGladeXML
, "hbox8");
396 pPrivate
->pAlphabetList
= gtk_list_store_new(1, G_TYPE_STRING
);
397 gtk_combo_box_set_model(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
),
398 GTK_TREE_MODEL(pPrivate
->pAlphabetList
));
400 GtkCellRenderer
*pRenderer
;
401 pRenderer
= gtk_cell_renderer_text_new();
402 #if GTK_CHECK_VERSION(2,6,0)
403 g_object_set(G_OBJECT(pRenderer
), "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
405 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(pPrivate
->pAlphabetCombo
), pRenderer
, true);
406 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(pPrivate
->pAlphabetCombo
), pRenderer
, "text", 0, NULL
);
409 // gtk_widget_add_events(pPrivate->pDragHandle, GDK_POINTER_MOTION_MASK);
412 #ifdef WITH_MAEMOFULLSCREEN
413 // TODO: This is horrible - no need to get it from the glade file if we're not going to use it
415 pPrivate
->pProgram
= HILDON_PROGRAM(hildon_program_get_instance());
416 // hildon_app_set_title(pPrivate->pApp, "Dasher");
418 pPrivate
->pHWindow
= HILDON_WINDOW(hildon_window_new());
419 hildon_program_add_window(pPrivate
->pProgram
, pPrivate
->pHWindow
);
421 gtk_widget_reparent(pPrivate
->pInnerFrame
, GTK_WIDGET(pPrivate
->pHWindow
));
422 // gtk_paned_set_position(GTK_PANED(window), 100);
426 GtkWidget
*file_menu
;
427 GtkWidget
*file_menu_item
;
428 GtkWidget
*options_menu
;
429 GtkWidget
*options_menu_item
;
430 GtkWidget
*help_menu
;
431 GtkWidget
*help_menu_item
;
434 // main_menu = hildon_appview_get_menu(appview);
436 main_menu
= GTK_MENU(gtk_menu_new());
437 file_menu
= glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem4_menu");
438 options_menu
= glade_xml_get_widget(pPrivate
->pGladeXML
, "options1_menu");
439 help_menu
= glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem7_menu");
440 file_menu_item
= gtk_menu_item_new_with_label ("File");
441 options_menu_item
= gtk_menu_item_new_with_label ("Options");
442 help_menu_item
= gtk_menu_item_new_with_label ("Help");
444 g_object_ref(file_menu
);
445 g_object_ref(options_menu
);
446 g_object_ref(help_menu
);
448 gtk_menu_item_remove_submenu(GTK_MENU_ITEM(glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem4")));
449 gtk_menu_item_remove_submenu(GTK_MENU_ITEM(glade_xml_get_widget(pPrivate
->pGladeXML
, "options1")));
450 gtk_menu_item_remove_submenu(GTK_MENU_ITEM(glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem7")));
452 gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menu_item
),file_menu
);
453 gtk_menu_item_set_submenu(GTK_MENU_ITEM(options_menu_item
),options_menu
);
454 gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_menu_item
),help_menu
);
455 gtk_menu_append(main_menu
, file_menu_item
);
456 gtk_menu_append(main_menu
, options_menu_item
);
457 gtk_menu_append(main_menu
, help_menu_item
);
459 g_object_unref(file_menu
);
460 g_object_unref(options_menu
);
461 g_object_unref(help_menu
);
463 hildon_program_set_common_menu(pPrivate
->pProgram
, main_menu
);
465 gtk_widget_show_all( GTK_WIDGET( main_menu
) );
468 // GtkWidget *toolbar;
469 // toolbar = glade_xml_get_widget(pPrivate->pGladeXML, "toolbar");
470 // g_print("Got %p\n",toolbar);
471 // gtk_widget_reparent (toolbar, appview->vbox);
473 gtk_widget_show_all(GTK_WIDGET(pPrivate
->pHWindow
));
475 gtk_widget_destroy(pPrivate
->pMainWindow
);
476 pPrivate
->pMainWindow
= GTK_WIDGET(pPrivate
->pHWindow
);
478 g_signal_connect(G_OBJECT(pPrivate
->pHWindow
), "delete_event", G_CALLBACK(ask_save_before_exit
), NULL
);
480 #endif // Maemo fullscreen
483 // pPrivate->bHidden = false;
484 // pPrivate->bGrabbed = false;
486 // pPrivate->iPosition = 100; // FIXME - make this persistant
488 // TODO: Specify callbacks in glade file
489 // TODO: Rationalise focus
490 g_signal_connect(G_OBJECT(pPrivate
->pBufferView
), "button-release-event", G_CALLBACK(take_real_focus
), NULL
);
491 g_signal_connect(G_OBJECT(pPrivate
->pBufferView
), "key-press-event", G_CALLBACK(edit_key_press
), NULL
);
492 g_signal_connect(G_OBJECT(pPrivate
->pBufferView
), "key-release-event", G_CALLBACK(edit_key_release
), NULL
);
494 pPrivate
->iAlphabetComboHandler
= g_signal_connect(G_OBJECT(pPrivate
->pAlphabetCombo
), "changed", G_CALLBACK(alphabet_combo_changed
), NULL
);
496 // dasher_main_build_context_menu(pSelf);
498 // Create a Maemo helper if necessary
499 #if defined WITH_MAEMO && !defined WITH_MAEMOFULLSCREEN
500 pPrivate
->pMaemoHelper
= dasher_maemo_helper_new(GTK_WINDOW(pPrivate
->pMainWindow
));
503 // Set up any non-registry-dependent options
505 gtk_window_set_decorated(GTK_WINDOW(pPrivate
->pMainWindow
), false);
508 dasher_main_connect_menus(pSelf
);
510 pPrivate
->bWidgetsInitialised
= true;
514 dasher_main_create_preferences(DasherMain
*pSelf
) {
515 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
516 pPrivate
->pPreferencesDialogue
= dasher_preferences_dialogue_new(pPrivate
->pGladeXML
, pPrivate
->pEditor
, pPrivate
->pAppSettings
, GTK_WINDOW(pPrivate
->pMainWindow
));
520 // dasher_main_get_editor(DasherMain *pSelf) {
521 // DasherMainPrivate *pPrivate = DASHER_MAIN_GET_PRIVATE(pSelf);
522 // return pPrivate->pEditor;
526 dasher_main_handle_parameter_change(DasherMain
*pSelf
, int iParameter
) {
527 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
529 switch( iParameter
) {
530 case APP_BP_SHOW_TOOLBAR
:
531 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, APP_BP_SHOW_TOOLBAR
))
532 gtk_widget_show(pPrivate
->pToolbar
);
534 gtk_widget_hide(pPrivate
->pToolbar
);
536 case BP_SHOW_SLIDER
: // TODO: Shouldn't be a core parmeter
537 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, BP_SHOW_SLIDER
))
538 gtk_widget_show(pPrivate
->pStatusControl
);
540 gtk_widget_hide(pPrivate
->pStatusControl
);
542 case APP_SP_EDIT_FONT
:
543 dasher_main_refresh_font(pSelf
);
547 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pPrivate
->pSpeedBox
), dasher_app_settings_get_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
) / 100.0);
551 dasher_main_populate_alphabet_combo(pSelf
);
553 case BP_GLOBAL_KEYBOARD
:
554 dasher_main_setup_window(pSelf
);
556 #if defined WITH_MAEMO && !defined WITH_MAEMOFULLSCREEN
557 case APP_LP_MAEMO_SIZE
: {
558 g_message("Maemo size");
560 bool bVisible
= GTK_WIDGET_VISIBLE(pPrivate
->pMainWindow
);
561 gtk_widget_hide(pPrivate
->pMainWindow
);
562 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_MAEMO_SIZE
) == 0) {
564 gtk_window_get_size(GTK_WINDOW(pPrivate
->pMainWindow
), &iWidth
, NULL
);
565 gtk_widget_set_size_request(pPrivate
->pMainWindow
, -1, 150);
566 gtk_window_resize(GTK_WINDOW(pPrivate
->pMainWindow
), iWidth
, 150);
567 gtk_widget_set_size_request(pPrivate
->pDasherWidget
, 175, -1);
571 gtk_window_get_size(GTK_WINDOW(pPrivate
->pMainWindow
), &iWidth
, NULL
);
572 gtk_widget_set_size_request(pPrivate
->pMainWindow
, -1, 250);
573 gtk_window_resize(GTK_WINDOW(pPrivate
->pMainWindow
), iWidth
, 250);
574 gtk_widget_set_size_request(pPrivate
->pDasherWidget
, 280, -1);
577 gtk_widget_show(pPrivate
->pMainWindow
);
583 // TODO: Pass into editor?
584 dasher_preferences_dialogue_handle_parameter_change(pPrivate
->pPreferencesDialogue
, iParameter
);
588 dasher_main_load_state(DasherMain
*pSelf
) {
589 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
595 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
) != 1) {
596 iEditHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_EDIT_HEIGHT
);
597 iWindowWidth
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH
);
598 iWindowHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT
);
601 iEditHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_EDIT_WIDTH
);
602 iWindowWidth
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH_H
);
603 iWindowHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT_H
);
607 gtk_window_resize(GTK_WINDOW(pPrivate
->pMainWindow
), iWindowWidth
, iWindowHeight
);
610 gtk_paned_set_position(GTK_PANED(pPrivate
->pDivider
), iEditHeight
);
612 pPrivate
->iWidth
= iWindowWidth
;
613 pPrivate
->iHeight
= iWindowHeight
;
615 // pPrivate->iPosition = dasher_app_settings_get_long(pPrivate->pAppSettings, APP_LP_DOCK_POSITION);
619 dasher_main_save_state(DasherMain
*pSelf
) {
620 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
622 if(!pPrivate
->bWidgetsInitialised
)
629 gtk_window_get_size(GTK_WINDOW(pPrivate
->pMainWindow
), &iWindowWidth
, &iWindowHeight
);
630 iEditHeight
= gtk_paned_get_position(GTK_PANED(pPrivate
->pDivider
));
632 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
) != 1) {
633 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_EDIT_HEIGHT
, iEditHeight
);
634 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH
, iWindowWidth
);
635 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT
, iWindowHeight
);
638 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_EDIT_WIDTH
, iEditHeight
);
639 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH_H
, iWindowWidth
);
640 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT_H
, iWindowHeight
);
643 // dasher_app_settings_set_long(pPrivate->pAppSettings, APP_LP_DOCK_POSITION, pPrivate->iPosition);
647 dasher_main_show(DasherMain
*pSelf
) {
648 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
649 gtk_widget_show(pPrivate
->pMainWindow
);
653 dasher_main_setup_window(DasherMain
*pSelf
) {
654 dasher_main_setup_window_style(pSelf
);
655 dasher_main_setup_window_state(pSelf
);
656 dasher_main_setup_internal_layout(pSelf
);
658 // DasherMainPrivate *pPrivate = (DasherMainPrivate *)(pSelf->private_data);
660 // if(dasher_app_settings_get_bool(pPrivate->pAppSettings, BP_GLOBAL_KEYBOARD))
661 // gdk_window_add_filter(0, keyboard_filter_cb, 0);
663 // gdk_window_remove_filter(0, keyboard_filter_cb, 0);
667 dasher_main_populate_controls(DasherMain
*pSelf
) {
668 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
670 // Populate the alphabet chooser
671 dasher_main_populate_alphabet_combo(pSelf
);
673 // Set the value of the speed spinner
674 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pPrivate
->pSpeedBox
),
675 dasher_app_settings_get_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
) / 100.0);
679 dasher_main_connect_control(DasherMain
*pSelf
) {
680 /* TODO: This is very much temporary - we need to think of a better
681 way of presenting application commands in a unified way */
683 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
685 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
686 Dasher::CControlManager::CTL_USER
,
689 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
690 Dasher::CControlManager::CTL_USER
,
691 Dasher::CControlManager::CTL_ROOT
, -2);
694 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
695 Dasher::CControlManager::CTL_USER
+ 1,
698 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
699 Dasher::CControlManager::CTL_USER
+ 2,
702 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
703 Dasher::CControlManager::CTL_USER
+ 3,
706 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
707 Dasher::CControlManager::CTL_USER
+ 1,
708 Dasher::CControlManager::CTL_USER
, -2);
710 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
712 Dasher::CControlManager::CTL_USER
+ 1, -2);
714 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
715 Dasher::CControlManager::CTL_USER
+ 2,
716 Dasher::CControlManager::CTL_USER
, -2);
718 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
720 Dasher::CControlManager::CTL_USER
+ 2, -2);
722 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
723 Dasher::CControlManager::CTL_USER
+ 3,
724 Dasher::CControlManager::CTL_USER
, -2);
726 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
728 Dasher::CControlManager::CTL_USER
+ 3, -2);
735 dasher_main_command(DasherMain
*pSelf
, const gchar
*szCommand
) {
736 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
738 if(!strcmp(szCommand
, "import")) {
739 dasher_main_command_import(pSelf
);
743 if(!strcmp(szCommand
, "quit")) {
744 dasher_main_command_quit(pSelf
);
748 if(!strcmp(szCommand
, "preferences")) {
749 dasher_main_command_preferences(pSelf
);
753 if(!strcmp(szCommand
, "preferences_alphabet")) {
754 dasher_main_command_preferences_alphabet(pSelf
);
758 if(!strcmp(szCommand
, "tutorial")) {
759 dasher_main_command_tutorial(pSelf
);
763 if(!strcmp(szCommand
, "help")) {
764 dasher_main_command_help(pSelf
);
768 if(!strcmp(szCommand
, "about")) {
769 dasher_main_command_about(pSelf
);
773 if(pPrivate
->pEditor
)
774 return dasher_editor_command(pPrivate
->pEditor
, szCommand
);
779 /* Private methods */
781 /* Window state is basically size and position */
783 dasher_main_setup_window_state(DasherMain
*pSelf
) {
784 dasher_main_load_state(pSelf
);
786 // TODO: Setup positioning here - need to think up a policy on this
790 /* Setup the window style - this is defined to be window manager hints and the like */
792 dasher_main_setup_window_style(DasherMain
*pSelf
) {
793 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
795 switch(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
)) {
803 // Direct mode - set always on top
804 gtk_window_set_keep_above(GTK_WINDOW(pPrivate
->pMainWindow
), true);
807 gtk_window_set_accept_focus(GTK_WINDOW(pPrivate
->pMainWindow
), false);
810 // Fullscreen mode - set fullscreen
811 gtk_window_fullscreen(GTK_WINDOW(pPrivate
->pMainWindow
));
814 g_error("Inconsistent application style specified.");
818 /* Internal layout is the visibility of various widgets */
820 dasher_main_setup_internal_layout(DasherMain
*pSelf
) {
821 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
823 if(pPrivate
->pToolbar
) {
824 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, APP_BP_SHOW_TOOLBAR
))
825 gtk_widget_show(pPrivate
->pToolbar
);
827 gtk_widget_hide(pPrivate
->pToolbar
);
830 if(pPrivate
->pStatusControl
) {
831 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, BP_SHOW_SLIDER
))
832 gtk_widget_show(pPrivate
->pStatusControl
);
834 gtk_widget_hide(pPrivate
->pStatusControl
);
837 dasher_main_refresh_font(pSelf
);
841 dasher_main_refresh_font(DasherMain
*pSelf
) {
842 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
844 const gchar
*szFontName
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, APP_SP_EDIT_FONT
);
845 PangoFontDescription
*pFD
= pango_font_description_from_string(szFontName
);
847 if(strcmp(szFontName
, "")) {
848 gtk_widget_modify_font(pPrivate
->pBufferView
, pFD
);
852 // TODO: Fold into setup controls?
854 dasher_main_set_filename(DasherMain
*pSelf
) {
855 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
857 const gchar
*szFilename
= dasher_editor_get_filename(pPrivate
->pEditor
);
859 if(szFilename
== 0) {
860 gtk_window_set_title(GTK_WINDOW(pPrivate
->pMainWindow
), "Dasher");
863 // TODO: Prepend 'Dasher - ' to filename?
864 gtk_window_set_title(GTK_WINDOW(pPrivate
->pMainWindow
), szFilename
);
869 dasher_main_connect_menus(DasherMain
*pSelf
) {
870 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
872 int iNumItems
= sizeof(MenuCommands
) / sizeof(DasherMenuCommand
);
874 for(int i(0); i
< iNumItems
; ++i
) {
877 pWidget
= glade_xml_get_widget(pPrivate
->pGladeXML
, MenuCommands
[i
].szWidgetName
);
879 MenuCommands
[i
].pWidget
= pWidget
;
881 // TODO: Check that these are the right signals to connect to
883 if(GTK_IS_MENU_ITEM(pWidget
))
884 g_signal_connect(G_OBJECT(pWidget
), "activate", G_CALLBACK(dasher_main_cb_menu_command
), pSelf
);
886 g_signal_connect(G_OBJECT(pWidget
), "clicked", G_CALLBACK(dasher_main_cb_menu_command
), pSelf
);
891 dasher_main_menu_command(DasherMain
*pSelf
, GtkWidget
*pWidget
) {
892 int iNumItems
= sizeof(MenuCommands
) / sizeof(DasherMenuCommand
);
894 for(int i(0); i
< iNumItems
; ++i
) {
895 if(MenuCommands
[i
].pWidget
== pWidget
) {
896 dasher_main_command(pSelf
, MenuCommands
[i
].szCommand
);
903 dasher_main_command_import(DasherMain
*pSelf
) {
904 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
906 GtkWidget
*pFileSel
= gtk_file_chooser_dialog_new(_("Select File"),
907 GTK_WINDOW(pPrivate
->pMainWindow
),
908 GTK_FILE_CHOOSER_ACTION_OPEN
,
909 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
910 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
914 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(pFileSel
), FALSE
);
917 if(gtk_dialog_run(GTK_DIALOG(pFileSel
)) == GTK_RESPONSE_ACCEPT
) {
920 gchar
*szFilename
= gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(pFileSel
));
922 gchar
*szFilename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSel
));
925 gtk_dasher_control_train(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), szFilename
);
930 gtk_widget_destroy(pFileSel
);
933 static void dasher_main_command_quit(DasherMain
*pSelf
) {
934 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
936 GtkWidget
*pDialogue
= NULL
;
938 if(dasher_editor_file_changed(pPrivate
->pEditor
)) {
939 const gchar
*szFilename
= dasher_editor_get_filename(pPrivate
->pEditor
);
942 pDialogue
= gtk_message_dialog_new(GTK_WINDOW(pPrivate
->pMainWindow
), GTK_DIALOG_MODAL
,
943 GTK_MESSAGE_QUESTION
, GTK_BUTTONS_NONE
,
944 _("Do you want to save your changes to %s?\n\nYour changes will be lost if you don't save them."),
948 pDialogue
= gtk_message_dialog_new(GTK_WINDOW(pPrivate
->pMainWindow
), GTK_DIALOG_MODAL
,
949 GTK_MESSAGE_QUESTION
, GTK_BUTTONS_NONE
,
950 _("Do you want to save your changes?\n\nYour changes will be lost if you don't save them."));
953 gtk_dialog_add_buttons(GTK_DIALOG(pDialogue
),
954 _("Don't save"), GTK_RESPONSE_REJECT
,
955 _("Don't quit"), GTK_RESPONSE_CANCEL
,
956 _("Save and quit"), GTK_RESPONSE_ACCEPT
,
959 switch (gtk_dialog_run(GTK_DIALOG(pDialogue
))) {
960 case GTK_RESPONSE_REJECT
:
961 // write_to_file(); // FIXME - REIMPLEMENT
964 case GTK_RESPONSE_CANCEL
:
965 gtk_widget_destroy(GTK_WIDGET(pDialogue
));
967 case GTK_RESPONSE_ACCEPT
:
968 gtk_widget_destroy(GTK_WIDGET(pDialogue
));
969 // write_to_file(); // FIXME - REIMPLEMENT
970 // save_file_and_quit(NULL, NULL);
974 // It should be noted that write_to_file merely saves the new text to the training
975 // file rather than saving it to a file of the user's choice
977 // FIXME - REIMPLEMENT
986 dasher_main_command_preferences(DasherMain
*pSelf
) {
987 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
988 dasher_preferences_dialogue_show(pPrivate
->pPreferencesDialogue
, 0);
992 dasher_main_command_preferences_alphabet(DasherMain
*pSelf
) {
993 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
994 dasher_preferences_dialogue_show(pPrivate
->pPreferencesDialogue
, 1);
998 dasher_main_command_tutorial(DasherMain
*pSelf
) {
999 // TODO: Implement this
1003 dasher_main_command_help(DasherMain
*pSelf
) {
1004 // TODO: Need to disable the menu if gnome libs aren't present (or get rid of without gnome option)
1006 gnome_help_display_desktop(NULL
, "dasher", "dasher", NULL
, NULL
);
1011 dasher_main_command_about(DasherMain
*pSelf
) {
1012 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1014 #if (defined GNOME_LIBS) || (GTK_CHECK_VERSION(2,6,0))
1016 // In alphabetical order
1017 const gchar
*authors
[] = {
1037 // Yeah, should really do some Gnome documentation for it...
1038 const gchar
*documenters
[] = {
1045 #if GTK_CHECK_VERSION(2,6,0)
1046 gtk_show_about_dialog(GTK_WINDOW(pPrivate
->pMainWindow
),
1048 "comments", _("Dasher is a predictive text entry application"),
1049 "copyright", "Copyright \xC2\xA9 1998-2007 The Dasher Project",
1050 "documenters", documenters
,
1051 "license", "GPL 2+",
1052 "logo-icon-name", "dasher",
1053 "translator-credits", _("translator-credits"),
1055 "website", "http://www.dasher.org.uk/",
1056 "wrap-license", true,
1059 gchar
*translator_credits
= _("translator-credits");
1061 GtkWidget
*about
= gnome_about_new (_("Dasher"),
1063 "Copyright The Dasher Project\n",
1064 _("Dasher is a predictive text entry application"),
1065 (const char **)authors
,
1066 (const char **)documenters
,
1067 strcmp (translator_credits
, "translator-credits") != 0 ? (const char *)translator_credits
: NULL
,
1070 gtk_window_set_transient_for (GTK_WINDOW(about
), GTK_WINDOW(pPrivate
->pMainWindow
));
1071 // g_signal_connect (G_OBJECT (about), "destory", G_CALLBACK (gtk_widget_destroyed), &about);
1072 gtk_widget_show(about
);
1077 // EAT UGLY ABOUT BOX, PHILISTINE
1078 GtkWidget
*label
, *button
;
1081 GtkWidget
*about
= gtk_dialog_new();
1083 gtk_dialog_set_has_separator(GTK_DIALOG(about
), FALSE
);
1084 gtk_window_set_title(GTK_WINDOW(about
), "About Dasher");
1086 tmp
= g_strdup_printf("Dasher Version %s ", VERSION
);
1087 label
= gtk_label_new(tmp
);
1088 gtk_widget_show(label
);
1089 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), label
, FALSE
, FALSE
, 0);
1091 label
= gtk_label_new("http://www.dasher.org.uk/");
1092 gtk_widget_show(label
);
1093 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), label
, FALSE
, FALSE
, 0);
1095 label
= gtk_label_new("Copyright The Dasher Project");
1096 gtk_widget_show(label
);
1097 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), label
, TRUE
, TRUE
, 0);
1099 button
= gtk_button_new_from_stock(GTK_STOCK_OK
);
1100 gtk_widget_show(button
);
1101 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), button
, FALSE
, FALSE
, 0);
1102 g_signal_connect_swapped(G_OBJECT(button
), "clicked", G_CALLBACK(gtk_widget_destroy
), G_OBJECT(about
));
1104 gtk_widget_show(about
);
1109 dasher_main_speed_changed(DasherMain
*pSelf
) {
1110 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1112 int iNewValue( static_cast<int>(round(gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(pPrivate
->pSpeedBox
)) * 100)));
1114 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
) != iNewValue
)
1115 dasher_app_settings_set_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
, iNewValue
);
1121 dasher_main_alphabet_combo_changed(DasherMain
*pSelf
) {
1122 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1126 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
), &sIter
);
1128 const char *szSelected
;
1129 gtk_tree_model_get(GTK_TREE_MODEL(pPrivate
->pAlphabetList
), &sIter
, 0, &szSelected
, -1);
1131 if(!strcmp("More Alphabets...", szSelected
)) {
1132 gtk_combo_box_set_active(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
), 0);
1133 // dasher_preferences_dialogue_show(pPrivate->pPreferencesDialogue);
1134 dasher_main_command(pSelf
, "preferences_alphabet");
1137 dasher_app_settings_set_string(pPrivate
->pAppSettings
, SP_ALPHABET_ID
, szSelected
);
1141 dasher_main_populate_alphabet_combo(DasherMain
*pSelf
) {
1143 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1145 // Disconnect the event handler temporarily, otherwise this will
1146 // trigger alphabet changes
1148 g_signal_handler_block(pPrivate
->pAlphabetCombo
, pPrivate
->iAlphabetComboHandler
);
1150 gtk_list_store_clear(pPrivate
->pAlphabetList
);
1154 const char *szValue
;
1156 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_ID
);
1158 if(strlen(szValue
) > 0) {
1159 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1160 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1161 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
), &sIter
);
1164 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_1
);
1165 if(strlen(szValue
) > 0) {
1166 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1167 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1170 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_2
);
1171 if(strlen(szValue
) > 0) {
1172 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1173 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1176 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_3
);
1177 if(strlen(szValue
) > 0) {
1178 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1179 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1182 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_4
);
1183 if(strlen(szValue
) > 0) {
1184 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1185 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1188 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1189 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, "More Alphabets...", -1);
1191 g_signal_handler_unblock(pPrivate
->pAlphabetCombo
, pPrivate
->iAlphabetComboHandler
);
1197 dasher_main_lookup_key(DasherMain
*pSelf
, guint iKeyVal
) {
1198 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1200 if(pPrivate
->pKeyboardHelper
)
1201 return pPrivate
->pKeyboardHelper
->ConvertKeycode(iKeyVal
);
1210 // TODO: reimplement (text view member of class)
1211 // gtk_widget_grab_focus(the_text_view);
1212 // g_bForwardKeyboard = true;
1218 extern "C" GtkWidget
*
1219 create_dasher_control(gchar
*szName
, gchar
*szString1
, gchar
*szString2
, gint iInt1
, gint iInt2
) {
1220 GtkWidget
*pDasherControl
= gtk_dasher_control_new();
1223 // TODO: Do this in glade file?
1224 gtk_widget_set_size_request(pDasherControl
, 175, -1);
1227 return pDasherControl
;
1231 dasher_main_cb_menu_command(GtkWidget
*pWidget
, gpointer pUserData
) {
1232 dasher_main_menu_command((DasherMain
*)pUserData
, pWidget
);
1234 return FALSE
; // TODO: Scheck semantics of return value
1238 speed_changed(GtkWidget
*pWidget
, gpointer user_data
) {
1240 return dasher_main_speed_changed(g_pDasherMain
);
1242 // TODO: Check callback return functions
1247 alphabet_combo_changed(GtkWidget
*pWidget
, gpointer pUserData
) {
1249 dasher_main_alphabet_combo_changed(g_pDasherMain
);
1253 dasher_main_cb_filename_changed(DasherEditor
*pEditor
, gpointer pUserData
) {
1254 dasher_main_set_filename(DASHER_MAIN(pUserData
));
1258 dasher_main_cb_buffer_changed(DasherEditor
*pEditor
, gpointer pUserData
) {
1259 DasherMain
*pDasherMain
= DASHER_MAIN(pUserData
);
1260 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
1262 gtk_dasher_control_set_buffer(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), dasher_editor_get_offset(pPrivate
->pEditor
));
1266 dasher_main_cb_context_changed(DasherEditor
*pEditor
, gpointer pUserData
) {
1267 DasherMain
*pDasherMain
= DASHER_MAIN(pUserData
);
1268 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
1270 gtk_dasher_control_set_offset(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), dasher_editor_get_offset(pPrivate
->pEditor
));
1274 dasher_main_cb_window_close(GtkWidget
*pWidget
, gpointer pUserData
) {
1275 dasher_main_command(g_pDasherMain
, "quit");
1277 /* Returning true stops further propagation */
1282 parameter_notification(GtkDasherControl
*pDasherControl
, gint iParameter
, gpointer data
) {
1284 dasher_main_handle_parameter_change(g_pDasherMain
, iParameter
);
1287 // TODO: Not really sure what happens here - need to sort out focus behaviour in general
1289 focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
) {
1290 return grab_focus();
1294 edit_focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
) {
1299 take_real_focus(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer user_data
) {
1300 // g_bForwardKeyboard = false;
1305 edit_key_press(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
) {
1306 // TODO: Reimplement
1308 // if(g_bForwardKeyboard) {
1309 // gboolean *returnType;
1310 // g_signal_emit_by_name(GTK_OBJECT(pPrivate->pDasherWidget), "key_press_event", event, &returnType);
1317 // TODO: Check callback return functions
1322 edit_key_release(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
) {
1323 // TODO: reimplement
1325 // if(g_bForwardKeyboard) {
1326 // gboolean *returnType;
1327 // g_signal_emit_by_name(GTK_OBJECT(pPrivate->pDasherWidget), "key_release_event", event, &returnType);
1334 // TODO: Check callback return functions
1339 test_focus_handler(GtkWidget
*pWidget
, GtkDirectionType iDirection
, gpointer
*pUserData
) {
1344 handle_context_request(GtkDasherControl
* pDasherControl
, gint iOffset
, gint iLength
, gpointer data
) {
1348 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(g_pDasherMain
);
1350 if(!pPrivate
->pEditor
|| !pPrivate
->pDasherWidget
)
1353 gtk_dasher_control_set_context(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), dasher_editor_get_context(pPrivate
->pEditor
, iOffset
, iLength
));
1357 handle_control_event(GtkDasherControl
*pDasherControl
, gint iEvent
, gpointer data
) {
1361 /* TODO: replace this with something a little more sensible */
1364 case Dasher::CControlManager::CTL_USER
+ 1:
1365 dasher_main_command(g_pDasherMain
, "speakall");
1367 case Dasher::CControlManager::CTL_USER
+ 2:
1368 dasher_main_command(g_pDasherMain
, "speaklast");
1370 case Dasher::CControlManager::CTL_USER
+ 3:
1371 dasher_main_command(g_pDasherMain
, "speakrepeat");
1379 handle_start_event(GtkDasherControl
*pDasherControl
, gpointer data
) {
1383 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(g_pDasherMain
);
1385 dasher_editor_grab_focus(pPrivate
->pEditor
);
1389 // TODO: Make this only work for children of the main window
1391 dasher_main_key_snooper(GtkWidget
*pWidget
, GdkEventKey
*pEvent
, gpointer pUserData
) {
1392 DasherMain
*pSelf
= DASHER_MAIN(pUserData
);
1394 gint iButton
= dasher_main_lookup_key(pSelf
, pEvent
->keyval
);
1397 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1399 if(gdk_window_get_toplevel(pEvent
->window
) == pPrivate
->pMainWindow
->window
) {
1400 if(pPrivate
->pDasherWidget
) {
1401 if(pEvent
->type
== GDK_KEY_PRESS
)
1402 gtk_dasher_control_external_key_down(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), iButton
);
1404 gtk_dasher_control_external_key_up(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), iButton
);