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 // TODO: The following global variable makes control mode editing work
26 // - this needs to be sorted out properly.
27 static gboolean g_bSend
= true;
29 struct _DasherMainPrivate
{
30 // The glade XML file - TODO: this shouldn't be kept after interface has been loaded
33 // Child objects owned here
34 DasherAppSettings
*pAppSettings
;
35 DasherPreferencesDialogue
*pPreferencesDialogue
;
36 DasherEditor
*pEditor
;
38 CKeyboardHelper
*pKeyboardHelper
;
40 // Various widgets which need to be cached:
41 GtkWidget
*pBufferView
;
43 GtkWidget
*pMainWindow
;
46 GtkWidget
*pAlphabetCombo
;
47 GtkWidget
*pStatusControl
;
48 GtkWidget
*pDasherWidget
;
50 GtkListStore
*pAlphabetList
;
51 GtkAccelGroup
*pAccel
;
52 gulong iAlphabetComboHandler
;
54 // Widgets used for maemo
56 DasherMaemoHelper
*pMaemoHelper
;
57 #ifdef WITH_MAEMOFULLSCREEN
58 HildonProgram
*pProgram
;
59 HildonWindow
*pHWindow
;
63 // Properties of the main window
66 bool bWidgetsInitialised
;
69 typedef struct _DasherMainPrivate DasherMainPrivate
;
71 // TODO: Make sure this is actually used
72 #define DASHER_MAIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), TYPE_DASHER_MAIN, DasherMainPrivate))
79 static guint dasher_main_signals
[SIGNAL_NUM
] = { 0 };
81 /* Automatic command hookups */
83 typedef struct _DasherMenuCommand DasherMenuCommand
;
85 struct _DasherMenuCommand
{
87 const gchar
*szWidgetName
;
88 const gchar
*szCommand
;
91 static DasherMenuCommand MenuCommands
[] = {
93 {NULL
, "menu_command_new", "new"},
94 {NULL
, "menu_command_open", "open"},
95 {NULL
, "menu_command_save", "save"},
96 {NULL
, "menu_command_saveas", "saveas"},
97 {NULL
, "menu_command_append", "append"},
98 {NULL
, "menu_command_import", "import"},
99 {NULL
, "menu_command_quit", "quit"},
100 {NULL
, "menu_command_cut", "cut"},
101 {NULL
, "menu_command_copy", "copy"},
102 {NULL
, "menu_command_copyall", "copyall"},
103 {NULL
, "menu_command_paste", "paste"},
104 {NULL
, "menu_command_preferences", "preferences"},
105 {NULL
, "menu_command_tutorial", "tutorial"},
106 {NULL
, "menu_command_help", "help"},
107 {NULL
, "menu_command_about", "about"},
110 {NULL
, "tb_command_new", "new"},
111 {NULL
, "tb_command_open", "open"},
112 {NULL
, "tb_command_save", "save"},
113 {NULL
, "tb_command_saveas", "saveas"},
114 {NULL
, "tb_command_cut", "cut"},
115 {NULL
, "tb_command_copy", "copy"},
116 {NULL
, "tb_command_paste", "paste"}
119 G_DEFINE_TYPE(DasherMain
, dasher_main
, G_TYPE_OBJECT
);
121 static void dasher_main_finalize(GObject
*pObject
);
123 /* Private member functions */
124 static void dasher_main_setup_window_state(DasherMain
*pSelf
);
125 static void dasher_main_setup_window_style(DasherMain
*pSelf
);
126 static void dasher_main_setup_internal_layout(DasherMain
*pSelf
);
127 static void dasher_main_refresh_font(DasherMain
*pSelf
);
128 static void dasher_main_set_filename(DasherMain
*pSelf
);
130 /* ... Table based menu/toolbar commands */
131 static void dasher_main_connect_menus(DasherMain
*pSelf
);
132 static void dasher_main_menu_command(DasherMain
*pSelf
, GtkWidget
*pWidget
);
134 static void dasher_main_command_import(DasherMain
*pSelf
);
135 static void dasher_main_command_quit(DasherMain
*pSelf
);
136 static void dasher_main_command_preferences(DasherMain
*pSelf
);
137 static void dasher_main_command_preferences_alphabet(DasherMain
*pSelf
);
138 static void dasher_main_command_tutorial(DasherMain
*pSelf
);
139 static void dasher_main_command_help(DasherMain
*pSelf
);
140 static void dasher_main_command_about(DasherMain
*pself
);
142 static gboolean
dasher_main_speed_changed(DasherMain
*pSelf
);
143 static void dasher_main_alphabet_combo_changed(DasherMain
*pSelf
);
144 // TODO: populate speed slider
145 static void dasher_main_populate_alphabet_combo(DasherMain
*pSelf
);
147 /* TODO: order these in file */
148 static void dasher_main_load_interface(DasherMain
*pSelf
);
149 static void dasher_main_create_preferences(DasherMain
*pSelf
);
150 static void dasher_main_handle_parameter_change(DasherMain
*pSelf
, int iParameter
);
151 static void dasher_main_load_state(DasherMain
*pSelf
);
152 static void dasher_main_save_state(DasherMain
*pSelf
);
153 static void dasher_main_setup_window(DasherMain
*pSelf
);
154 static void dasher_main_populate_controls(DasherMain
*pSelf
);
155 static void dasher_main_connect_control(DasherMain
*pSelf
);
156 static gboolean
dasher_main_command(DasherMain
*pSelf
, const gchar
*szCommand
);
157 static gint
dasher_main_lookup_key(DasherMain
*pSelf
, guint iKeyVal
);
159 /* TODO: Various functions which haven't yet been rationalised */
160 gboolean
grab_focus();
162 // TODO: Sort out callbacks - 1 rename, 2 check return values
164 /* Callback functions */
165 extern "C" GtkWidget
*create_dasher_control(gchar
*szName
, gchar
*szString1
, gchar
*szString2
, gint iInt1
, gint iInt2
);
166 extern "C" GtkWidget
*create_dasher_editor(gchar
*szName
, gchar
*szString1
, gchar
*szString2
, gint iInt1
, gint iInt2
);
168 /* ... Message handling from main window widgets */
169 extern "C" gboolean
dasher_main_cb_menu_command(GtkWidget
*pWidget
, gpointer pUserData
);
170 extern "C" gboolean
speed_changed(GtkWidget
*pWidget
, gpointer user_data
);
171 extern "C" void alphabet_combo_changed(GtkWidget
*pWidget
, gpointer pUserData
);
172 extern "C" void dasher_main_cb_filename_changed(DasherEditor
*pEditor
, gpointer pUserData
);
173 extern "C" void dasher_main_cb_buffer_changed(DasherEditor
*pEditor
, gpointer pUserData
);
174 extern "C" void dasher_main_cb_context_changed(DasherEditor
*pEditor
, gpointer pUserData
);
175 extern "C" gboolean
dasher_main_cb_window_close(GtkWidget
*pWidget
, gpointer pUserData
);
176 extern "C" void parameter_notification(GtkDasherControl
*pDasherControl
, gint iParameter
, gpointer data
);
178 /* ... Focus management and event forwarding */
179 extern "C" bool focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
);
180 extern "C" bool edit_focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
);
181 extern "C" gboolean
take_real_focus(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer user_data
);
183 extern "C" gboolean
edit_key_press(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
);
184 extern "C" gboolean
edit_key_release(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
);
186 /* ... Temporary test/debug functions */
187 extern "C" gboolean
test_focus_handler(GtkWidget
*pWidget
, GtkDirectionType iDirection
, gpointer
*pUserData
);
189 extern "C" void handle_context_request(GtkDasherControl
* pDasherControl
, gint iOffset
, gint iLength
, gpointer data
);
190 extern "C" void handle_control_event(GtkDasherControl
*pDasherControl
, gint iEvent
, gpointer data
);
191 extern "C" void handle_start_event(GtkDasherControl
*pDasherControl
, gpointer data
);
192 extern "C" gint
dasher_main_key_snooper(GtkWidget
*pWidget
, GdkEventKey
*pEvent
, gpointer pUserData
);
194 /* Boilerplate code */
196 dasher_main_class_init(DasherMainClass
*pClass
) {
197 g_type_class_add_private(pClass
, sizeof(DasherMainPrivate
));
199 dasher_main_signals
[REALIZED
] = g_signal_new("realized", G_TYPE_FROM_CLASS(pClass
),
200 (GSignalFlags
)(G_SIGNAL_RUN_FIRST
| G_SIGNAL_ACTION
),
201 G_STRUCT_OFFSET(DasherMainClass
, realized
),
202 NULL
, NULL
, g_cclosure_marshal_VOID__VOID
,
205 GObjectClass
*pObjectClass
= (GObjectClass
*)pClass
;
206 pObjectClass
->finalize
= dasher_main_finalize
;
210 dasher_main_init(DasherMain
*pDasherMain
) {
211 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
213 /* TODO: define log domain */
214 g_debug("Initialising DasherMain");
216 pPrivate
->pAppSettings
= NULL
;
217 pPrivate
->pEditor
= NULL
;
218 pPrivate
->pPreferencesDialogue
= NULL
;
220 pPrivate
->pKeyboardHelper
= new CKeyboardHelper(NULL
);
222 pPrivate
->bWidgetsInitialised
= false;
226 dasher_main_finalize(GObject
*pObject
) {
227 /* TODO: Need a general overview of class finalisation */
228 g_debug("Finalizing DasherMain");
230 DasherMain
*pDasherMain
= DASHER_MAIN(pObject
);
231 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
233 dasher_main_save_state(pDasherMain
);
235 /* TODO: Does unref really do the right thing - check the whole ref counting situation */
236 if(pPrivate
->pEditor
)
237 g_object_unref(pPrivate
->pEditor
);
239 if(pPrivate
->pPreferencesDialogue
)
240 g_object_unref(pPrivate
->pPreferencesDialogue
);
242 if(pPrivate
->pAppSettings
)
243 g_object_unref(pPrivate
->pAppSettings
);
245 gtk_widget_destroy(pPrivate
->pMainWindow
);
247 /* TDO: Do we need to take down anything else? */
252 dasher_main_new(int *argc
, char ***argv
, SCommandLine
*pCommandLine
) {
254 return g_pDasherMain
;
256 DasherMain
*pDasherMain
= (DasherMain
*)(g_object_new(dasher_main_get_type(), NULL
));
257 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
259 /* Create the app settings object */
260 pPrivate
->pAppSettings
= dasher_app_settings_new(*argc
, *argv
);
262 /* Load the user interface from the glade file */
263 if(pCommandLine
&& pCommandLine
->szAppStyle
) {
264 if(!strcmp(pCommandLine
->szAppStyle
, "traditional")) {
265 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 0);
267 else if(!strcmp(pCommandLine
->szAppStyle
, "compose")) {
268 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 1);
270 else if(!strcmp(pCommandLine
->szAppStyle
, "direct")) {
271 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 2);
273 else if(!strcmp(pCommandLine
->szAppStyle
, "fullscreen")) {
274 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 3);
277 g_error("Application style %s is not supported", pCommandLine
->szAppStyle
);
281 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_STYLE
, 0);
284 dasher_main_load_interface(pDasherMain
);
286 dasher_app_settings_set_widget(pPrivate
->pAppSettings
, GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
));
287 dasher_editor_initialise(pPrivate
->pEditor
, pPrivate
->pAppSettings
, pDasherMain
, pPrivate
->pGladeXML
, NULL
);
290 dasher_main_setup_window(pDasherMain
);
292 /* Create the editor */
293 gchar
*szFullPath
= NULL
;
296 if(pCommandLine
->szFilename
) {
297 if(!g_path_is_absolute(pCommandLine
->szFilename
)) {
299 cwd
= (char *)malloc(1024 * sizeof(char));
301 szFullPath
= g_build_path("/", cwd
, pCommandLine
->szFilename
, NULL
);
304 szFullPath
= g_strdup(pCommandLine
->szFilename
);
310 // pPrivate->pEditor = GTK_EDITOR(
313 // dasher_editor_initialise(pPrivate->pAppSettings, pDasherMain, pPrivate->pGladeXML, szFullPath);
317 g_signal_connect(pPrivate
->pEditor
, "filename_changed", G_CALLBACK(dasher_main_cb_filename_changed
), pDasherMain
);
318 g_signal_connect(pPrivate
->pEditor
, "buffer_changed", G_CALLBACK(dasher_main_cb_buffer_changed
), pDasherMain
);
319 g_signal_connect(pPrivate
->pEditor
, "context_changed", G_CALLBACK(dasher_main_cb_context_changed
), pDasherMain
);
321 /* Create the preferences window */
322 dasher_main_create_preferences(pDasherMain
);
324 /* Create the lock dialogue (to be removed in future versions) */
326 dasher_lock_dialogue_new(pPrivate
->pGladeXML
, GTK_WINDOW(pPrivate
->pMainWindow
));
328 dasher_lock_dialogue_new(pPrivate
->pGladeXML
, 0);
331 /* Set up various bits and pieces */
332 dasher_main_set_filename(pDasherMain
);
333 dasher_main_populate_controls(pDasherMain
);
334 dasher_main_connect_control(pDasherMain
);
336 gtk_key_snooper_install(dasher_main_key_snooper
, pDasherMain
);
338 /* Cache a file-wide static pointer to the singleton class */
339 g_pDasherMain
= pDasherMain
;
345 /* Load the window interface from the glade file, and do various initialisation bits and pieces */
347 dasher_main_load_interface(DasherMain
*pSelf
) {
348 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
350 const char *szGladeFilename
= NULL
;
353 szGladeFilename
= PROGDATA
"/dashergpe.glade";
355 #ifdef WITH_MAEMOFULLSCREEN
356 // szGladeFilename = "/var/lib/install" PROGDATA "/dashermaemofullscreen.glade";
357 szGladeFilename
= PROGDATA
"/dashermaemofullscreen.glade";
359 //szGladeFilename = "/var/lib/install" PROGDATA "/dashermaemo.glade";
360 szGladeFilename
= PROGDATA
"/dashermaemo.glade";
363 switch(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
)) {
365 szGladeFilename
= PROGDATA
"/dasher.traditional.glade";
368 szGladeFilename
= PROGDATA
"/dasher.compose.glade";
371 szGladeFilename
= PROGDATA
"/dasher.direct.glade";
374 szGladeFilename
= PROGDATA
"/dasher.fullscreen.glade";
377 g_error("Inconsistent application style specified.");
381 if(!szGladeFilename
) {
382 g_error("Failure to determine glade filename");
385 pPrivate
->pGladeXML
= glade_xml_new(szGladeFilename
, NULL
, NULL
);
387 if (!pPrivate
->pGladeXML
) {
388 g_error("Can't find Glade file: %s. Dasher is unlikely to be correctly installed.", szGladeFilename
);
391 glade_xml_signal_autoconnect(pPrivate
->pGladeXML
);
393 // Save the details of some of the widgets for later
394 // pPrivate->pActionPane = glade_xml_get_widget(pPrivate->pGladeXML, "vbox39");
395 pPrivate
->pBufferView
= glade_xml_get_widget(pPrivate
->pGladeXML
, "the_text_view");
396 pPrivate
->pDivider
= glade_xml_get_widget(pPrivate
->pGladeXML
, "main_divider");
397 // pPrivate->pEditPane = glade_xml_get_widget(pPrivate->pGladeXML, "vbox40");
398 pPrivate
->pMainWindow
= glade_xml_get_widget(pPrivate
->pGladeXML
, "window");
399 pPrivate
->pToolbar
= glade_xml_get_widget(pPrivate
->pGladeXML
, "toolbar");
400 // pPrivate->pMenuBar = glade_xml_get_widget(pPrivate->pGladeXML, "dasher_menu_bar");
401 pPrivate
->pDasherWidget
= glade_xml_get_widget(pPrivate
->pGladeXML
, "DasherControl");
404 pPrivate
->pSpeedBox
= glade_xml_get_widget(pPrivate
->pGladeXML
, "spinbutton1");
405 pPrivate
->pAlphabetCombo
= glade_xml_get_widget(pPrivate
->pGladeXML
, "combobox1");
406 pPrivate
->pStatusControl
= glade_xml_get_widget(pPrivate
->pGladeXML
, "hbox8");
408 pPrivate
->pAlphabetList
= gtk_list_store_new(1, G_TYPE_STRING
);
409 gtk_combo_box_set_model(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
),
410 GTK_TREE_MODEL(pPrivate
->pAlphabetList
));
412 GtkCellRenderer
*pRenderer
;
413 pRenderer
= gtk_cell_renderer_text_new();
414 #if GTK_CHECK_VERSION(2,6,0)
415 g_object_set(G_OBJECT(pRenderer
), "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
417 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(pPrivate
->pAlphabetCombo
), pRenderer
, true);
418 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(pPrivate
->pAlphabetCombo
), pRenderer
, "text", 0, NULL
);
421 // gtk_widget_add_events(pPrivate->pDragHandle, GDK_POINTER_MOTION_MASK);
424 #ifdef WITH_MAEMOFULLSCREEN
425 // TODO: This is horrible - no need to get it from the glade file if we're not going to use it
427 pPrivate
->pProgram
= HILDON_PROGRAM(hildon_program_get_instance());
428 // hildon_app_set_title(pPrivate->pApp, "Dasher");
430 pPrivate
->pHWindow
= HILDON_WINDOW(hildon_window_new());
431 hildon_program_add_window(pPrivate
->pProgram
, pPrivate
->pHWindow
);
433 gtk_widget_reparent(pPrivate
->pInnerFrame
, GTK_WIDGET(pPrivate
->pHWindow
));
434 // gtk_paned_set_position(GTK_PANED(window), 100);
438 GtkWidget
*file_menu
;
439 GtkWidget
*file_menu_item
;
440 GtkWidget
*options_menu
;
441 GtkWidget
*options_menu_item
;
442 GtkWidget
*help_menu
;
443 GtkWidget
*help_menu_item
;
446 // main_menu = hildon_appview_get_menu(appview);
448 main_menu
= GTK_MENU(gtk_menu_new());
449 file_menu
= glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem4_menu");
450 options_menu
= glade_xml_get_widget(pPrivate
->pGladeXML
, "options1_menu");
451 help_menu
= glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem7_menu");
452 file_menu_item
= gtk_menu_item_new_with_label ("File");
453 options_menu_item
= gtk_menu_item_new_with_label ("Options");
454 help_menu_item
= gtk_menu_item_new_with_label ("Help");
456 g_object_ref(file_menu
);
457 g_object_ref(options_menu
);
458 g_object_ref(help_menu
);
460 gtk_menu_item_remove_submenu(GTK_MENU_ITEM(glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem4")));
461 gtk_menu_item_remove_submenu(GTK_MENU_ITEM(glade_xml_get_widget(pPrivate
->pGladeXML
, "options1")));
462 gtk_menu_item_remove_submenu(GTK_MENU_ITEM(glade_xml_get_widget(pPrivate
->pGladeXML
, "menuitem7")));
464 gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menu_item
),file_menu
);
465 gtk_menu_item_set_submenu(GTK_MENU_ITEM(options_menu_item
),options_menu
);
466 gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_menu_item
),help_menu
);
467 gtk_menu_append(main_menu
, file_menu_item
);
468 gtk_menu_append(main_menu
, options_menu_item
);
469 gtk_menu_append(main_menu
, help_menu_item
);
471 g_object_unref(file_menu
);
472 g_object_unref(options_menu
);
473 g_object_unref(help_menu
);
475 hildon_program_set_common_menu(pPrivate
->pProgram
, main_menu
);
477 gtk_widget_show_all( GTK_WIDGET( main_menu
) );
480 // GtkWidget *toolbar;
481 // toolbar = glade_xml_get_widget(pPrivate->pGladeXML, "toolbar");
482 // g_print("Got %p\n",toolbar);
483 // gtk_widget_reparent (toolbar, appview->vbox);
485 gtk_widget_show_all(GTK_WIDGET(pPrivate
->pHWindow
));
487 gtk_widget_destroy(pPrivate
->pMainWindow
);
488 pPrivate
->pMainWindow
= GTK_WIDGET(pPrivate
->pHWindow
);
490 g_signal_connect(G_OBJECT(pPrivate
->pHWindow
), "delete_event", G_CALLBACK(ask_save_before_exit
), NULL
);
492 #endif // Maemo fullscreen
495 // pPrivate->bHidden = false;
496 // pPrivate->bGrabbed = false;
498 // pPrivate->iPosition = 100; // FIXME - make this persistant
500 // TODO: Specify callbacks in glade file
501 // TODO: Rationalise focus
502 g_signal_connect(G_OBJECT(pPrivate
->pBufferView
), "button-release-event", G_CALLBACK(take_real_focus
), NULL
);
503 g_signal_connect(G_OBJECT(pPrivate
->pBufferView
), "key-press-event", G_CALLBACK(edit_key_press
), NULL
);
504 g_signal_connect(G_OBJECT(pPrivate
->pBufferView
), "key-release-event", G_CALLBACK(edit_key_release
), NULL
);
506 pPrivate
->iAlphabetComboHandler
= g_signal_connect(G_OBJECT(pPrivate
->pAlphabetCombo
), "changed", G_CALLBACK(alphabet_combo_changed
), NULL
);
508 // dasher_main_build_context_menu(pSelf);
510 // Create a Maemo helper if necessary
511 #if defined WITH_MAEMO && !defined WITH_MAEMOFULLSCREEN
512 pPrivate
->pMaemoHelper
= dasher_maemo_helper_new(GTK_WINDOW(pPrivate
->pMainWindow
));
515 // Set up any non-registry-dependent options
517 gtk_window_set_decorated(GTK_WINDOW(pPrivate
->pMainWindow
), false);
520 dasher_main_connect_menus(pSelf
);
523 pPrivate
->pEditor
= DASHER_EDITOR(glade_xml_get_widget(pPrivate
->pGladeXML
, "DasherEditor"));
525 pPrivate
->bWidgetsInitialised
= true;
529 dasher_main_create_preferences(DasherMain
*pSelf
) {
530 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
531 pPrivate
->pPreferencesDialogue
= dasher_preferences_dialogue_new(pPrivate
->pGladeXML
, pPrivate
->pEditor
, pPrivate
->pAppSettings
, GTK_WINDOW(pPrivate
->pMainWindow
));
535 // dasher_main_get_editor(DasherMain *pSelf) {
536 // DasherMainPrivate *pPrivate = DASHER_MAIN_GET_PRIVATE(pSelf);
537 // return pPrivate->pEditor;
541 dasher_main_handle_parameter_change(DasherMain
*pSelf
, int iParameter
) {
542 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
544 switch( iParameter
) {
545 case APP_BP_SHOW_TOOLBAR
:
546 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, APP_BP_SHOW_TOOLBAR
))
547 gtk_widget_show(pPrivate
->pToolbar
);
549 gtk_widget_hide(pPrivate
->pToolbar
);
551 case BP_SHOW_SLIDER
: // TODO: Shouldn't be a core parmeter
552 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, BP_SHOW_SLIDER
))
553 gtk_widget_show(pPrivate
->pStatusControl
);
555 gtk_widget_hide(pPrivate
->pStatusControl
);
557 case APP_SP_EDIT_FONT
:
558 // TODO: Editor should handle this directly
559 dasher_main_refresh_font(pSelf
);
563 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pPrivate
->pSpeedBox
), dasher_app_settings_get_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
) / 100.0);
567 dasher_main_populate_alphabet_combo(pSelf
);
569 case BP_GLOBAL_KEYBOARD
:
570 dasher_main_setup_window(pSelf
);
572 #if defined WITH_MAEMO && !defined WITH_MAEMOFULLSCREEN
573 case APP_LP_MAEMO_SIZE
: {
574 g_message("Maemo size");
576 bool bVisible
= GTK_WIDGET_VISIBLE(pPrivate
->pMainWindow
);
577 gtk_widget_hide(pPrivate
->pMainWindow
);
578 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_MAEMO_SIZE
) == 0) {
580 gtk_window_get_size(GTK_WINDOW(pPrivate
->pMainWindow
), &iWidth
, NULL
);
581 gtk_widget_set_size_request(pPrivate
->pMainWindow
, -1, 150);
582 gtk_window_resize(GTK_WINDOW(pPrivate
->pMainWindow
), iWidth
, 150);
583 gtk_widget_set_size_request(pPrivate
->pDasherWidget
, 175, -1);
587 gtk_window_get_size(GTK_WINDOW(pPrivate
->pMainWindow
), &iWidth
, NULL
);
588 gtk_widget_set_size_request(pPrivate
->pMainWindow
, -1, 250);
589 gtk_window_resize(GTK_WINDOW(pPrivate
->pMainWindow
), iWidth
, 250);
590 gtk_widget_set_size_request(pPrivate
->pDasherWidget
, 280, -1);
593 gtk_widget_show(pPrivate
->pMainWindow
);
599 // TODO: Pass into editor?
600 dasher_preferences_dialogue_handle_parameter_change(pPrivate
->pPreferencesDialogue
, iParameter
);
604 dasher_main_load_state(DasherMain
*pSelf
) {
605 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
611 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
) != 1) {
612 iEditHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_EDIT_HEIGHT
);
613 iWindowWidth
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH
);
614 iWindowHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT
);
617 iEditHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_EDIT_WIDTH
);
618 iWindowWidth
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH_H
);
619 iWindowHeight
= dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT_H
);
623 gtk_window_resize(GTK_WINDOW(pPrivate
->pMainWindow
), iWindowWidth
, iWindowHeight
);
626 gtk_paned_set_position(GTK_PANED(pPrivate
->pDivider
), iEditHeight
);
628 pPrivate
->iWidth
= iWindowWidth
;
629 pPrivate
->iHeight
= iWindowHeight
;
631 // pPrivate->iPosition = dasher_app_settings_get_long(pPrivate->pAppSettings, APP_LP_DOCK_POSITION);
635 dasher_main_save_state(DasherMain
*pSelf
) {
636 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
638 if(!pPrivate
->bWidgetsInitialised
)
645 gtk_window_get_size(GTK_WINDOW(pPrivate
->pMainWindow
), &iWindowWidth
, &iWindowHeight
);
646 iEditHeight
= gtk_paned_get_position(GTK_PANED(pPrivate
->pDivider
));
648 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
) != 1) {
649 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_EDIT_HEIGHT
, iEditHeight
);
650 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH
, iWindowWidth
);
651 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT
, iWindowHeight
);
654 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_EDIT_WIDTH
, iEditHeight
);
655 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_WIDTH_H
, iWindowWidth
);
656 dasher_app_settings_set_long(pPrivate
->pAppSettings
, APP_LP_SCREEN_HEIGHT_H
, iWindowHeight
);
659 // dasher_app_settings_set_long(pPrivate->pAppSettings, APP_LP_DOCK_POSITION, pPrivate->iPosition);
663 dasher_main_show(DasherMain
*pSelf
) {
664 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
665 gtk_widget_show(pPrivate
->pMainWindow
);
669 dasher_main_setup_window(DasherMain
*pSelf
) {
670 dasher_main_setup_window_style(pSelf
);
671 dasher_main_setup_window_state(pSelf
);
672 dasher_main_setup_internal_layout(pSelf
);
674 // DasherMainPrivate *pPrivate = (DasherMainPrivate *)(pSelf->private_data);
676 // if(dasher_app_settings_get_bool(pPrivate->pAppSettings, BP_GLOBAL_KEYBOARD))
677 // gdk_window_add_filter(0, keyboard_filter_cb, 0);
679 // gdk_window_remove_filter(0, keyboard_filter_cb, 0);
683 dasher_main_populate_controls(DasherMain
*pSelf
) {
684 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
686 // Populate the alphabet chooser
687 dasher_main_populate_alphabet_combo(pSelf
);
689 // Set the value of the speed spinner
690 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pPrivate
->pSpeedBox
),
691 dasher_app_settings_get_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
) / 100.0);
695 dasher_main_connect_control(DasherMain
*pSelf
) {
696 /* TODO: This is very much temporary - we need to think of a better
697 way of presenting application commands in a unified way */
699 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
701 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
702 Dasher::CControlManager::CTL_USER
,
705 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
706 Dasher::CControlManager::CTL_USER
,
707 Dasher::CControlManager::CTL_ROOT
, -2);
710 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
711 Dasher::CControlManager::CTL_USER
+ 1,
714 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
715 Dasher::CControlManager::CTL_USER
+ 2,
718 gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
719 Dasher::CControlManager::CTL_USER
+ 3,
722 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
723 Dasher::CControlManager::CTL_USER
+ 1,
724 Dasher::CControlManager::CTL_USER
, -2);
726 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
728 Dasher::CControlManager::CTL_USER
+ 1, -2);
730 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
731 Dasher::CControlManager::CTL_USER
+ 2,
732 Dasher::CControlManager::CTL_USER
, -2);
734 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
736 Dasher::CControlManager::CTL_USER
+ 2, -2);
738 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
739 Dasher::CControlManager::CTL_USER
+ 3,
740 Dasher::CControlManager::CTL_USER
, -2);
742 gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
744 Dasher::CControlManager::CTL_USER
+ 3, -2);
751 dasher_main_command(DasherMain
*pSelf
, const gchar
*szCommand
) {
752 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
754 if(!strcmp(szCommand
, "import")) {
755 dasher_main_command_import(pSelf
);
759 if(!strcmp(szCommand
, "quit")) {
760 dasher_main_command_quit(pSelf
);
764 if(!strcmp(szCommand
, "preferences")) {
765 dasher_main_command_preferences(pSelf
);
769 if(!strcmp(szCommand
, "preferences_alphabet")) {
770 dasher_main_command_preferences_alphabet(pSelf
);
774 if(!strcmp(szCommand
, "tutorial")) {
775 dasher_main_command_tutorial(pSelf
);
779 if(!strcmp(szCommand
, "help")) {
780 dasher_main_command_help(pSelf
);
784 if(!strcmp(szCommand
, "about")) {
785 dasher_main_command_about(pSelf
);
789 if(pPrivate
->pEditor
)
790 return dasher_editor_command(pPrivate
->pEditor
, szCommand
);
795 /* Private methods */
797 /* Window state is basically size and position */
799 dasher_main_setup_window_state(DasherMain
*pSelf
) {
800 dasher_main_load_state(pSelf
);
802 // TODO: Setup positioning here - need to think up a policy on this
806 /* Setup the window style - this is defined to be window manager hints and the like */
808 dasher_main_setup_window_style(DasherMain
*pSelf
) {
809 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
811 switch(dasher_app_settings_get_long(pPrivate
->pAppSettings
, APP_LP_STYLE
)) {
819 // Direct mode - set always on top
820 gtk_window_set_keep_above(GTK_WINDOW(pPrivate
->pMainWindow
), true);
823 gtk_window_set_accept_focus(GTK_WINDOW(pPrivate
->pMainWindow
), false);
826 // Fullscreen mode - set fullscreen
827 gtk_window_fullscreen(GTK_WINDOW(pPrivate
->pMainWindow
));
830 g_error("Inconsistent application style specified.");
834 /* Internal layout is the visibility of various widgets */
836 dasher_main_setup_internal_layout(DasherMain
*pSelf
) {
837 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
839 if(pPrivate
->pToolbar
) {
840 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, APP_BP_SHOW_TOOLBAR
))
841 gtk_widget_show(pPrivate
->pToolbar
);
843 gtk_widget_hide(pPrivate
->pToolbar
);
846 if(pPrivate
->pStatusControl
) {
847 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, BP_SHOW_SLIDER
))
848 gtk_widget_show(pPrivate
->pStatusControl
);
850 gtk_widget_hide(pPrivate
->pStatusControl
);
853 dasher_main_refresh_font(pSelf
);
857 dasher_main_refresh_font(DasherMain
*pSelf
) {
858 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
860 dasher_editor_handle_font(pPrivate
->pEditor
,
861 dasher_app_settings_get_string(pPrivate
->pAppSettings
, APP_SP_EDIT_FONT
));
864 // TODO: Fold into setup controls?
866 dasher_main_set_filename(DasherMain
*pSelf
) {
867 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
869 const gchar
*szFilename
= dasher_editor_get_filename(pPrivate
->pEditor
);
871 if(szFilename
== 0) {
872 gtk_window_set_title(GTK_WINDOW(pPrivate
->pMainWindow
), "Dasher");
875 // TODO: Prepend 'Dasher - ' to filename?
876 gtk_window_set_title(GTK_WINDOW(pPrivate
->pMainWindow
), szFilename
);
881 dasher_main_connect_menus(DasherMain
*pSelf
) {
882 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
884 int iNumItems
= sizeof(MenuCommands
) / sizeof(DasherMenuCommand
);
886 for(int i(0); i
< iNumItems
; ++i
) {
889 pWidget
= glade_xml_get_widget(pPrivate
->pGladeXML
, MenuCommands
[i
].szWidgetName
);
891 MenuCommands
[i
].pWidget
= pWidget
;
893 // TODO: Check that these are the right signals to connect to
895 if(GTK_IS_MENU_ITEM(pWidget
))
896 g_signal_connect(G_OBJECT(pWidget
), "activate", G_CALLBACK(dasher_main_cb_menu_command
), pSelf
);
898 g_signal_connect(G_OBJECT(pWidget
), "clicked", G_CALLBACK(dasher_main_cb_menu_command
), pSelf
);
903 dasher_main_menu_command(DasherMain
*pSelf
, GtkWidget
*pWidget
) {
904 int iNumItems
= sizeof(MenuCommands
) / sizeof(DasherMenuCommand
);
906 for(int i(0); i
< iNumItems
; ++i
) {
907 if(MenuCommands
[i
].pWidget
== pWidget
) {
908 dasher_main_command(pSelf
, MenuCommands
[i
].szCommand
);
915 dasher_main_command_import(DasherMain
*pSelf
) {
916 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
918 GtkWidget
*pFileSel
= gtk_file_chooser_dialog_new(_("Select File"),
919 GTK_WINDOW(pPrivate
->pMainWindow
),
920 GTK_FILE_CHOOSER_ACTION_OPEN
,
921 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
922 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
926 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(pFileSel
), FALSE
);
929 if(gtk_dialog_run(GTK_DIALOG(pFileSel
)) == GTK_RESPONSE_ACCEPT
) {
932 gchar
*szFilename
= gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(pFileSel
));
934 gchar
*szFilename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSel
));
937 gtk_dasher_control_train(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), szFilename
);
942 gtk_widget_destroy(pFileSel
);
945 static void dasher_main_command_quit(DasherMain
*pSelf
) {
946 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
948 GtkWidget
*pDialogue
= NULL
;
950 if(dasher_editor_file_changed(pPrivate
->pEditor
)) {
951 const gchar
*szFilename
= dasher_editor_get_filename(pPrivate
->pEditor
);
954 pDialogue
= gtk_message_dialog_new(GTK_WINDOW(pPrivate
->pMainWindow
), GTK_DIALOG_MODAL
,
955 GTK_MESSAGE_QUESTION
, GTK_BUTTONS_NONE
,
956 _("Do you want to save your changes to %s?\n\nYour changes will be lost if you don't save them."),
960 pDialogue
= gtk_message_dialog_new(GTK_WINDOW(pPrivate
->pMainWindow
), GTK_DIALOG_MODAL
,
961 GTK_MESSAGE_QUESTION
, GTK_BUTTONS_NONE
,
962 _("Do you want to save your changes?\n\nYour changes will be lost if you don't save them."));
965 gtk_dialog_add_buttons(GTK_DIALOG(pDialogue
),
966 _("Don't save"), GTK_RESPONSE_REJECT
,
967 _("Don't quit"), GTK_RESPONSE_CANCEL
,
968 _("Save and quit"), GTK_RESPONSE_ACCEPT
,
971 switch (gtk_dialog_run(GTK_DIALOG(pDialogue
))) {
972 case GTK_RESPONSE_REJECT
:
973 // write_to_file(); // FIXME - REIMPLEMENT
976 case GTK_RESPONSE_CANCEL
:
977 gtk_widget_destroy(GTK_WIDGET(pDialogue
));
979 case GTK_RESPONSE_ACCEPT
:
980 gtk_widget_destroy(GTK_WIDGET(pDialogue
));
981 // write_to_file(); // FIXME - REIMPLEMENT
982 // save_file_and_quit(NULL, NULL);
986 // It should be noted that write_to_file merely saves the new text to the training
987 // file rather than saving it to a file of the user's choice
989 // FIXME - REIMPLEMENT
998 dasher_main_command_preferences(DasherMain
*pSelf
) {
999 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1000 dasher_preferences_dialogue_show(pPrivate
->pPreferencesDialogue
, 0);
1004 dasher_main_command_preferences_alphabet(DasherMain
*pSelf
) {
1005 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1006 dasher_preferences_dialogue_show(pPrivate
->pPreferencesDialogue
, 1);
1010 dasher_main_command_tutorial(DasherMain
*pSelf
) {
1011 // TODO: Implement this
1015 dasher_main_command_help(DasherMain
*pSelf
) {
1016 // TODO: Need to disable the menu if gnome libs aren't present (or get rid of without gnome option)
1018 gnome_help_display_desktop(NULL
, "dasher", "dasher", NULL
, NULL
);
1023 dasher_main_command_about(DasherMain
*pSelf
) {
1024 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1026 #if (defined GNOME_LIBS) || (GTK_CHECK_VERSION(2,6,0))
1028 // In alphabetical order
1029 const gchar
*authors
[] = {
1049 // Yeah, should really do some Gnome documentation for it...
1050 const gchar
*documenters
[] = {
1057 #if GTK_CHECK_VERSION(2,6,0)
1058 gtk_show_about_dialog(GTK_WINDOW(pPrivate
->pMainWindow
),
1060 "comments", _("Dasher is a predictive text entry application"),
1061 "copyright", "Copyright \xC2\xA9 1998-2007 The Dasher Project",
1062 "documenters", documenters
,
1063 "license", "GPL 2+",
1064 "logo-icon-name", "dasher",
1065 "translator-credits", _("translator-credits"),
1067 "website", "http://www.dasher.org.uk/",
1068 "wrap-license", true,
1071 gchar
*translator_credits
= _("translator-credits");
1073 GtkWidget
*about
= gnome_about_new (_("Dasher"),
1075 "Copyright The Dasher Project\n",
1076 _("Dasher is a predictive text entry application"),
1077 (const char **)authors
,
1078 (const char **)documenters
,
1079 strcmp (translator_credits
, "translator-credits") != 0 ? (const char *)translator_credits
: NULL
,
1082 gtk_window_set_transient_for (GTK_WINDOW(about
), GTK_WINDOW(pPrivate
->pMainWindow
));
1083 // g_signal_connect (G_OBJECT (about), "destory", G_CALLBACK (gtk_widget_destroyed), &about);
1084 gtk_widget_show(about
);
1089 // EAT UGLY ABOUT BOX, PHILISTINE
1090 GtkWidget
*label
, *button
;
1093 GtkWidget
*about
= gtk_dialog_new();
1095 gtk_dialog_set_has_separator(GTK_DIALOG(about
), FALSE
);
1096 gtk_window_set_title(GTK_WINDOW(about
), "About Dasher");
1098 tmp
= g_strdup_printf("Dasher Version %s ", VERSION
);
1099 label
= gtk_label_new(tmp
);
1100 gtk_widget_show(label
);
1101 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), label
, FALSE
, FALSE
, 0);
1103 label
= gtk_label_new("http://www.dasher.org.uk/");
1104 gtk_widget_show(label
);
1105 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), label
, FALSE
, FALSE
, 0);
1107 label
= gtk_label_new("Copyright The Dasher Project");
1108 gtk_widget_show(label
);
1109 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), label
, TRUE
, TRUE
, 0);
1111 button
= gtk_button_new_from_stock(GTK_STOCK_OK
);
1112 gtk_widget_show(button
);
1113 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about
)->vbox
), button
, FALSE
, FALSE
, 0);
1114 g_signal_connect_swapped(G_OBJECT(button
), "clicked", G_CALLBACK(gtk_widget_destroy
), G_OBJECT(about
));
1116 gtk_widget_show(about
);
1121 dasher_main_speed_changed(DasherMain
*pSelf
) {
1122 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1124 int iNewValue( static_cast<int>(round(gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(pPrivate
->pSpeedBox
)) * 100)));
1126 if(dasher_app_settings_get_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
) != iNewValue
)
1127 dasher_app_settings_set_long(pPrivate
->pAppSettings
, LP_MAX_BITRATE
, iNewValue
);
1133 dasher_main_alphabet_combo_changed(DasherMain
*pSelf
) {
1134 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1138 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
), &sIter
);
1140 const char *szSelected
;
1141 gtk_tree_model_get(GTK_TREE_MODEL(pPrivate
->pAlphabetList
), &sIter
, 0, &szSelected
, -1);
1143 if(!strcmp("More Alphabets...", szSelected
)) {
1144 gtk_combo_box_set_active(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
), 0);
1145 // dasher_preferences_dialogue_show(pPrivate->pPreferencesDialogue);
1146 dasher_main_command(pSelf
, "preferences_alphabet");
1149 dasher_app_settings_set_string(pPrivate
->pAppSettings
, SP_ALPHABET_ID
, szSelected
);
1153 dasher_main_populate_alphabet_combo(DasherMain
*pSelf
) {
1155 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1157 // Disconnect the event handler temporarily, otherwise this will
1158 // trigger alphabet changes
1160 g_signal_handler_block(pPrivate
->pAlphabetCombo
, pPrivate
->iAlphabetComboHandler
);
1162 gtk_list_store_clear(pPrivate
->pAlphabetList
);
1166 const char *szValue
;
1168 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_ID
);
1170 if(strlen(szValue
) > 0) {
1171 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1172 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1173 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(pPrivate
->pAlphabetCombo
), &sIter
);
1176 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_1
);
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_2
);
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 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_3
);
1189 if(strlen(szValue
) > 0) {
1190 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1191 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1194 szValue
= dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_ALPHABET_4
);
1195 if(strlen(szValue
) > 0) {
1196 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1197 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, szValue
, -1);
1200 gtk_list_store_append(pPrivate
->pAlphabetList
, &sIter
);
1201 gtk_list_store_set(pPrivate
->pAlphabetList
, &sIter
, 0, "More Alphabets...", -1);
1203 g_signal_handler_unblock(pPrivate
->pAlphabetCombo
, pPrivate
->iAlphabetComboHandler
);
1209 dasher_main_lookup_key(DasherMain
*pSelf
, guint iKeyVal
) {
1210 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1212 if(pPrivate
->pKeyboardHelper
)
1213 return pPrivate
->pKeyboardHelper
->ConvertKeycode(iKeyVal
);
1222 // TODO: reimplement (text view member of class)
1223 // gtk_widget_grab_focus(the_text_view);
1224 // g_bForwardKeyboard = true;
1230 extern "C" GtkWidget
*
1231 create_dasher_control(gchar
*szName
, gchar
*szString1
, gchar
*szString2
, gint iInt1
, gint iInt2
) {
1232 GtkWidget
*pDasherControl
= gtk_dasher_control_new();
1235 // TODO: Do this in glade file?
1236 gtk_widget_set_size_request(pDasherControl
, 175, -1);
1239 return pDasherControl
;
1242 extern "C" GtkWidget
*
1243 create_dasher_editor(gchar
*szName
, gchar
*szString1
, gchar
*szString2
, gint iInt1
, gint iInt2
) {
1244 return GTK_WIDGET(dasher_editor_new());
1248 dasher_main_cb_menu_command(GtkWidget
*pWidget
, gpointer pUserData
) {
1249 dasher_main_menu_command((DasherMain
*)pUserData
, pWidget
);
1251 return FALSE
; // TODO: Scheck semantics of return value
1255 speed_changed(GtkWidget
*pWidget
, gpointer user_data
) {
1257 return dasher_main_speed_changed(g_pDasherMain
);
1259 // TODO: Check callback return functions
1264 alphabet_combo_changed(GtkWidget
*pWidget
, gpointer pUserData
) {
1266 dasher_main_alphabet_combo_changed(g_pDasherMain
);
1270 dasher_main_cb_filename_changed(DasherEditor
*pEditor
, gpointer pUserData
) {
1271 dasher_main_set_filename(DASHER_MAIN(pUserData
));
1275 dasher_main_cb_buffer_changed(DasherEditor
*pEditor
, gpointer pUserData
) {
1276 DasherMain
*pDasherMain
= DASHER_MAIN(pUserData
);
1277 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
1279 gtk_dasher_control_set_buffer(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), dasher_editor_get_offset(pPrivate
->pEditor
));
1283 dasher_main_cb_context_changed(DasherEditor
*pEditor
, gpointer pUserData
) {
1287 DasherMain
*pDasherMain
= DASHER_MAIN(pUserData
);
1288 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pDasherMain
);
1290 gtk_dasher_control_set_offset(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), dasher_editor_get_offset(pPrivate
->pEditor
));
1294 dasher_main_cb_window_close(GtkWidget
*pWidget
, gpointer pUserData
) {
1295 dasher_main_command(g_pDasherMain
, "quit");
1297 /* Returning true stops further propagation */
1302 parameter_notification(GtkDasherControl
*pDasherControl
, gint iParameter
, gpointer data
) {
1304 dasher_main_handle_parameter_change(g_pDasherMain
, iParameter
);
1307 // TODO: Not really sure what happens here - need to sort out focus behaviour in general
1309 focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
) {
1310 return grab_focus();
1314 edit_focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
) {
1319 take_real_focus(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer user_data
) {
1320 // g_bForwardKeyboard = false;
1325 edit_key_press(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
) {
1326 // TODO: Reimplement
1328 // if(g_bForwardKeyboard) {
1329 // gboolean *returnType;
1330 // g_signal_emit_by_name(GTK_OBJECT(pPrivate->pDasherWidget), "key_press_event", event, &returnType);
1337 // TODO: Check callback return functions
1342 edit_key_release(GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
) {
1343 // TODO: reimplement
1345 // if(g_bForwardKeyboard) {
1346 // gboolean *returnType;
1347 // g_signal_emit_by_name(GTK_OBJECT(pPrivate->pDasherWidget), "key_release_event", event, &returnType);
1354 // TODO: Check callback return functions
1359 test_focus_handler(GtkWidget
*pWidget
, GtkDirectionType iDirection
, gpointer
*pUserData
) {
1364 handle_context_request(GtkDasherControl
* pDasherControl
, gint iOffset
, gint iLength
, gpointer data
) {
1368 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(g_pDasherMain
);
1370 if(!pPrivate
->pEditor
|| !pPrivate
->pDasherWidget
)
1373 gtk_dasher_control_set_context(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), dasher_editor_get_context(pPrivate
->pEditor
, iOffset
, iLength
));
1377 handle_control_event(GtkDasherControl
*pDasherControl
, gint iEvent
, gpointer data
) {
1381 /* TODO: replace this with something a little more sensible */
1384 case Dasher::CControlManager::CTL_USER
+ 1:
1385 dasher_main_command(g_pDasherMain
, "speakall");
1387 case Dasher::CControlManager::CTL_USER
+ 2:
1388 dasher_main_command(g_pDasherMain
, "speaklast");
1390 case Dasher::CControlManager::CTL_USER
+ 3:
1391 dasher_main_command(g_pDasherMain
, "speakrepeat");
1398 // TODO: This is a horrible hack here to make the release work!
1402 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(g_pDasherMain
);
1403 dasher_editor_handle_control(pPrivate
->pEditor
, iEvent
);
1405 gtk_dasher_control_set_control_offset(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
),
1406 dasher_editor_get_offset(pPrivate
->pEditor
));
1414 handle_start_event(GtkDasherControl
*pDasherControl
, gpointer data
) {
1418 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(g_pDasherMain
);
1420 dasher_editor_grab_focus(pPrivate
->pEditor
);
1424 // TODO: Make this only work for children of the main window
1426 dasher_main_key_snooper(GtkWidget
*pWidget
, GdkEventKey
*pEvent
, gpointer pUserData
) {
1427 DasherMain
*pSelf
= DASHER_MAIN(pUserData
);
1429 gint iButton
= dasher_main_lookup_key(pSelf
, pEvent
->keyval
);
1432 DasherMainPrivate
*pPrivate
= DASHER_MAIN_GET_PRIVATE(pSelf
);
1434 if(gdk_window_get_toplevel(pEvent
->window
) == pPrivate
->pMainWindow
->window
) {
1435 if(pPrivate
->pDasherWidget
) {
1436 if(pEvent
->type
== GDK_KEY_PRESS
)
1437 gtk_dasher_control_external_key_down(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), iButton
);
1439 gtk_dasher_control_external_key_up(GTK_DASHER_CONTROL(pPrivate
->pDasherWidget
), iButton
);