5 #include <glib/gi18n.h>
12 #include "dasher_action_keyboard_maemo.h"
14 #include "dasher_action_keyboard.h"
18 #include "dasher_action_script.h"
22 #include "dasher_action_speech.h"
25 #include "dasher_editor_internal.h"
26 #include "dasher_external_buffer.h"
27 #include "dasher_internal_buffer.h"
28 #include "dasher_lock_dialogue.h"
29 #include "dasher_main.h"
30 //#include "game_mode_helper.h"
32 // TODO: Maybe reimplement something along the lines of the following, which used to be in edit.cc
35 // GtkTextIter oBufferEnd;
36 // GtkTextIter oBufferStart;
37 // gtk_text_buffer_get_bounds( the_text_buffer, &oBufferStart, &oBufferEnd);
38 // gtk_text_buffer_create_mark(the_text_buffer, "new_start", &oBufferEnd, true);
41 // const gchar *get_new_text() {
42 // GtkTextIter oNewStart;
43 // GtkTextIter oNewEnd;
44 // GtkTextIter oDummy;
46 // gtk_text_buffer_get_bounds( the_text_buffer, &oDummy, &oNewEnd);
47 // gtk_text_buffer_get_iter_at_mark( the_text_buffer, &oNewStart, gtk_text_buffer_get_mark(the_text_buffer, "new_start"));
49 // return gtk_text_buffer_get_text( the_text_buffer, &oNewStart, &oNewEnd, false );
55 #define ACTION_STATE_SHOW 1
56 #define ACTION_STATE_CONTROL 2
57 #define ACTION_STATE_AUTO 4
59 typedef struct _EditorAction EditorAction
;
61 struct _EditorAction
{
62 DasherAction
*pAction
;
64 EditorAction
*pPrevious
;
66 gint iID
; // TODO: does this need to be separate from iControlID?
73 typedef struct _DasherEditorInternalPrivate DasherEditorInternalPrivate
;
75 struct _DasherEditorInternalPrivate
{
76 DasherMain
*pDasherMain
;
77 GtkTextView
*pTextView
;
78 GtkTextBuffer
*pBuffer
;
80 GtkClipboard
*pTextClipboard
;
81 GtkClipboard
*pPrimarySelection
;
83 GtkLabel
*pGameInfoLabel
;
84 EditorAction
*pActionRing
;
85 EditorAction
*pActionIter
;
86 gboolean bActionIterStarted
;
88 IDasherBufferSet
*pBufferSet
;
89 IDasherBufferSet
*pExternalBuffer
;
90 // GameModeHelper *pGameModeHelper;
91 GtkTextMark
*pNewMark
;
92 DasherAppSettings
*pAppSettings
;
94 gboolean bFileModified
; // TODO: Make this work properly, export to main for quit etc
97 #define DASHER_EDITOR_INTERNAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), TYPE_DASHER_EDITOR_INTERNAL, DasherEditorInternalPrivate))
107 //static guint dasher_editor_internal_signals[SIGNAL_NUM];
109 static DasherEditorInternal
*g_pEditor
;
111 G_DEFINE_TYPE(DasherEditorInternal
, dasher_editor_internal
, TYPE_DASHER_EDITOR
);
113 static void dasher_editor_internal_finalize(GObject
*pObject
);
116 static void dasher_editor_internal_handle_font(DasherEditor
*pSelf
, const gchar
*szFont
);
118 gboolean
dasher_editor_internal_command(DasherEditor
*pSelf
, const gchar
*szCommand
);
119 void dasher_editor_internal_initialise(DasherEditor
*pSelf
, DasherAppSettings
*pAppSettings
, DasherMain
*pDasherMain
, GladeXML
*pGladeXML
, const gchar
*szFullPath
);
121 /* Private methods */
122 static void dasher_editor_internal_select_all(DasherEditor
*pSelf
);
123 static void dasher_editor_internal_setup_actions(DasherEditor
*pSelf
);
124 static void dasher_editor_internal_add_action(DasherEditor
*pSelf
, DasherAction
*pNewAction
);
125 static EditorAction
*dasher_editor_internal_get_action_by_id(DasherEditor
*pSelf
, int iID
);
126 static void dasher_editor_internal_rebuild_action_pane(DasherEditor
*pSelf
);
127 //static void dasher_editor_internal_display_message(DasherEditor *pSelf, DasherMessageInfo *pMessageInfo);
128 static void dasher_editor_internal_check_activity(DasherEditor
*pSelf
, EditorAction
*pAction
);
129 static void dasher_editor_internal_action_save_state(DasherEditor
*pSelf
, EditorAction
*pAction
);
131 static void dasher_editor_internal_command_new(DasherEditor
*pSelf
);
132 static void dasher_editor_internal_command_open(DasherEditor
*pSelf
);
133 static void dasher_editor_internal_command_save(DasherEditor
*pSelf
, gboolean bPrompt
, gboolean bAppend
);
136 static void dasher_editor_internal_gvfs_print_error(DasherEditor
*pSelf
, GError
*error
, const char *myfilename
);
137 static GFileOutputStream
*append_or_replace_file(GFile
*file
, bool append
, GError
**error
);
138 static gboolean
dasher_editor_internal_gvfs_open_file(DasherEditor
*pSelf
, const char *filename
, gchar
** buffer
, gsize
*size
);
139 static gboolean
dasher_editor_internal_gvfs_save_file(DasherEditor
*pSelf
, const char *filename
, gchar
* buffer
, gsize length
, bool append
);
141 static gboolean
dasher_editor_internal_unix_vfs_open_file(DasherEditor
*pSelf
, const char *filename
, gchar
** buffer
, gsize
*size
);
142 static gboolean
dasher_editor_internal_unix_vfs_save_file(DasherEditor
*pSelf
, const char *filename
, gchar
* buffer
, gsize length
, bool append
);
145 static void dasher_editor_internal_set_filename(DasherEditor
*pSelf
, const gchar
*szFilename
);
147 // TODO: Should these be public?
148 static void dasher_editor_internal_convert(DasherEditor
*pSelf
);
149 static void dasher_editor_internal_protect(DasherEditor
*pSelf
);
151 static void dasher_editor_internal_new_buffer(DasherEditor
*pSelf
, const gchar
*szFilename
);
153 static void dasher_editor_internal_generate_filename(DasherEditor
*pSelf
);
154 static void dasher_editor_internal_open(DasherEditor
*pSelf
, const gchar
*szFilename
);
155 static bool dasher_editor_internal_save_as(DasherEditor
*pSelf
, const gchar
*szFilename
, bool bAppend
);
156 static void dasher_editor_internal_create_buffer(DasherEditor
*pSelf
);
157 static void dasher_editor_internal_clear(DasherEditor
*pSelf
, gboolean bStore
);
158 static void dasher_editor_internal_clipboard(DasherEditor
*pSelf
, clipboard_action act
);
160 /* To be obsoleted by movement to GTK buffers */
161 void dasher_editor_internal_output(DasherEditor
*pSelf
, const gchar
*szText
, int iOffset
);
162 void dasher_editor_internal_delete(DasherEditor
*pSelf
, int iLength
, int iOffset
);
163 const gchar
*dasher_editor_internal_get_context(DasherEditor
*pSelf
, int iOffset
, int iLength
);
164 gint
dasher_editor_internal_get_offset(DasherEditor
*pSelf
);
166 /* Events proagated from main */
167 void dasher_editor_internal_handle_stop(DasherEditor
*pSelf
);
168 void dasher_editor_internal_handle_start(DasherEditor
*pSelf
);
169 void dasher_editor_internal_handle_control(DasherEditor
*pSelf
, int iNodeID
);
171 /* Action related methods - TODO: a lot of this should be moved to dasher_main (eg action on stop etc) - that way we get a better level of abstraction, and can incorporate commands from otehr modules too. Actions should only be externally visible as a list of string commands*/
172 void dasher_editor_internal_action_button(DasherEditor
*pSelf
, DasherAction
*pAction
);
173 void dasher_editor_internal_actions_start(DasherEditor
*pSelf
);
174 bool dasher_editor_internal_actions_more(DasherEditor
*pSelf
);
175 void dasher_editor_internal_actions_get_next(DasherEditor
*pSelf
, const gchar
**szName
, gint
*iID
, gboolean
*bShow
, gboolean
*bControl
, gboolean
*bAuto
);
176 void dasher_editor_internal_action_set_show(DasherEditor
*pSelf
, int iActionID
, bool bValue
);
177 void dasher_editor_internal_action_set_control(DasherEditor
*pSelf
, int iActionID
, bool bValue
);
178 void dasher_editor_internal_action_set_auto(DasherEditor
*pSelf
, int iActionID
, bool bValue
);
180 void dasher_editor_internal_grab_focus(DasherEditor
*pSelf
);
182 /* TODO: Tutorial editor should be a separate class */
183 //void dasher_editor_internal_start_tutorial(DasherEditor *pSelf);
185 /* Todo: possibly tidy up the need to have this public (quit in dasher_main possibly too connected) */
186 gboolean
dasher_editor_internal_file_changed(DasherEditor
*pSelf
);
187 const gchar
*dasher_editor_internal_get_filename(DasherEditor
*pSelf
);
189 const gchar
*dasher_editor_internal_get_all_text(DasherEditor
*pSelf
);
190 const gchar
*dasher_editor_internal_get_new_text(DasherEditor
*pSelf
);
192 static void dasher_editor_internal_handle_parameter_change(DasherEditor
*pSelf
, gint iParameter
);
195 // Private methods not in class
196 extern "C" void delete_children_callback(GtkWidget
*pWidget
, gpointer pUserData
);
197 extern "C" void main_window_realized(DasherMain
*pMain
, gpointer pUserData
);
198 extern "C" void action_button_callback(GtkWidget
*pWidget
, gpointer pUserData
);
199 extern "C" void context_changed_handler(GObject
*pSource
, gpointer pUserData
);
200 extern "C" void buffer_changed_handler(GObject
*pSource
, gpointer pUserData
);
201 extern "C" void handle_stop_event(GtkDasherControl
*pDasherControl
, gpointer data
);
202 extern "C" void on_message(GtkDasherControl
*pDasherControl
, gpointer pMessageInfo
, gpointer pUserData
);
203 extern "C" void on_command(GtkDasherControl
*pDasherControl
, gchar
*szCommand
, gpointer pUserData
);
204 extern "C" void handle_request_settings(GtkDasherControl
* pDasherControl
, gpointer data
);
205 extern "C" void gtk2_edit_delete_callback(GtkDasherControl
*pDasherControl
, const gchar
*szText
, int iOffset
, gpointer user_data
);
206 extern "C" void gtk2_edit_output_callback(GtkDasherControl
*pDasherControl
, const gchar
*szText
, int iOffset
, gpointer user_data
);
207 extern "C" void convert_cb(GtkDasherControl
*pDasherControl
, gpointer pUserData
);
208 extern "C" void protect_cb(GtkDasherControl
*pDasherControl
, gpointer pUserData
);
211 dasher_editor_internal_class_init(DasherEditorInternalClass
*pClass
) {
212 g_type_class_add_private(pClass
, sizeof(DasherEditorInternalPrivate
));
214 GObjectClass
*pObjectClass
= (GObjectClass
*) pClass
;
215 pObjectClass
->finalize
= dasher_editor_internal_finalize
;
217 DasherEditorClass
*pParentClass
= (DasherEditorClass
*)pClass
;
219 pParentClass
->initialise
= dasher_editor_internal_initialise
;
220 pParentClass
->command
= dasher_editor_internal_command
;
221 pParentClass
->output
= dasher_editor_internal_output
;
222 pParentClass
->delete_text
= dasher_editor_internal_delete
;
223 pParentClass
->get_context
= dasher_editor_internal_get_context
;
224 pParentClass
->get_offset
= dasher_editor_internal_get_offset
;
225 pParentClass
->handle_stop
= dasher_editor_internal_handle_stop
;
226 pParentClass
->handle_start
= dasher_editor_internal_handle_start
;
227 pParentClass
->handle_control
= dasher_editor_internal_handle_control
;
228 pParentClass
->action_button
= dasher_editor_internal_action_button
;
229 pParentClass
->actions_start
= dasher_editor_internal_actions_start
;
230 pParentClass
->actions_more
= dasher_editor_internal_actions_more
;
231 pParentClass
->actions_get_next
= dasher_editor_internal_actions_get_next
;
232 pParentClass
->action_set_show
= dasher_editor_internal_action_set_show
;
233 pParentClass
->action_set_control
= dasher_editor_internal_action_set_control
;
234 pParentClass
->action_set_auto
= dasher_editor_internal_action_set_auto
;
235 pParentClass
->grab_focus
= dasher_editor_internal_grab_focus
;
236 pParentClass
->file_changed
= dasher_editor_internal_file_changed
;
237 pParentClass
->get_filename
= dasher_editor_internal_get_filename
;
238 pParentClass
->get_all_text
= dasher_editor_internal_get_all_text
;
239 pParentClass
->get_new_text
= dasher_editor_internal_get_new_text
;
240 pParentClass
->handle_parameter_change
= dasher_editor_internal_handle_parameter_change
;
244 dasher_editor_internal_init(DasherEditorInternal
*pDasherControl
) {
245 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pDasherControl
);
247 pPrivate
->pBufferSet
= NULL
;
248 pPrivate
->pExternalBuffer
= NULL
;
249 pPrivate
->szFilename
= NULL
;
250 pPrivate
->pTextClipboard
= gtk_clipboard_get(GDK_SELECTION_CLIPBOARD
);
251 pPrivate
->pPrimarySelection
= gtk_clipboard_get(GDK_SELECTION_PRIMARY
);
252 pPrivate
->pActionRing
= NULL
;
253 pPrivate
->iNextActionID
= 0;
254 // pPrivate->pGameModeHelper = NULL;
255 pPrivate
->bFileModified
= FALSE
;
259 dasher_editor_internal_finalize(GObject
*pObject
) {
260 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pObject
);
262 EditorAction
*pCurrentAction
= pPrivate
->pActionRing
;
265 bool bStarted
= false;
267 while(!bStarted
|| (pCurrentAction
!= pPrivate
->pActionRing
)) {
269 dasher_action_deactivate(pCurrentAction
->pAction
);
270 g_object_unref(G_OBJECT(pCurrentAction
->pAction
));
271 pCurrentAction
= pCurrentAction
->pNext
;
275 if(pPrivate
->pBufferSet
)
276 g_object_unref(G_OBJECT(pPrivate
->pBufferSet
));
278 if(pPrivate
->szFilename
)
279 g_free(pPrivate
->szFilename
);
283 DasherEditorInternal
*
284 dasher_editor_internal_new() {
285 DasherEditorInternal
*pDasherEditor
;
286 pDasherEditor
= (DasherEditorInternal
*)(g_object_new(dasher_editor_internal_get_type(), NULL
));
288 g_pEditor
= pDasherEditor
;
290 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pDasherEditor
);
292 GtkWidget
*pScrolledWindow
= gtk_scrolled_window_new(NULL
, NULL
);
294 GtkWidget
*pTextView
= gtk_text_view_new();
295 gtk_widget_grab_focus(pTextView
);
298 pPrivate
->pTextView
= GTK_TEXT_VIEW(pTextView
);
300 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(pTextView
),
303 gtk_container_add(GTK_CONTAINER(pScrolledWindow
), pTextView
);
305 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pScrolledWindow
),
306 GTK_POLICY_AUTOMATIC
,
307 GTK_POLICY_AUTOMATIC
);
309 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pScrolledWindow
),
312 gtk_box_pack_start(GTK_BOX(&(pDasherEditor
->parent
.box
)), pScrolledWindow
, true, true, 0);
315 gtk_widget_show_all(GTK_WIDGET(&(pDasherEditor
->parent
.box
)));
317 return pDasherEditor
;
321 dasher_editor_internal_initialise(DasherEditor
*pSelf
, DasherAppSettings
*pAppSettings
, DasherMain
*pDasherMain
, GladeXML
*pGladeXML
, const gchar
*szFullPath
) {
323 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
325 pPrivate
->pAppSettings
= pAppSettings
;
326 pPrivate
->pDasherMain
= pDasherMain
;
328 dasher_editor_internal_handle_font(pSelf
,
329 dasher_app_settings_get_string(pPrivate
->pAppSettings
,
332 GtkVBox
*pActionPane
= GTK_VBOX(glade_xml_get_widget(pGladeXML
, "vbox39"));
333 pPrivate
->pBuffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(pPrivate
->pTextView
));
335 gtk_widget_show_all(GTK_WIDGET(pPrivate
->pTextView
));
337 GtkTextIter oStartIter
;
338 gtk_text_buffer_get_start_iter(pPrivate
->pBuffer
, &oStartIter
);
339 pPrivate
->pNewMark
= gtk_text_buffer_create_mark(pPrivate
->pBuffer
, NULL
, &oStartIter
, TRUE
);
341 pPrivate
->pActionPane
= pActionPane
;
343 // TODO: is this still needed?
344 dasher_editor_internal_create_buffer(pSelf
);
346 dasher_editor_internal_setup_actions(pSelf
);
348 // TODO: see note in command_new method
350 dasher_editor_internal_open(pSelf
, szFullPath
);
352 dasher_editor_internal_generate_filename(pSelf
);
353 dasher_editor_internal_clear(pSelf
, false);
356 // pPrivate->pGameModeHelper = GAME_MODE_HELPER(game_mode_helper_new(pGladeXML, (void*)pSelf));
360 dasher_editor_internal_clipboard(DasherEditor
*pSelf
, clipboard_action act
) {
361 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
363 GtkTextIter
*start
= new GtkTextIter
;
364 GtkTextIter
*end
= new GtkTextIter
;
366 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), start
, 0);
367 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), end
, -1);
369 gchar
*the_text
= gtk_text_buffer_get_text(pPrivate
->pBuffer
, start
, end
, TRUE
);
373 gtk_text_buffer_cut_clipboard(pPrivate
->pBuffer
, pPrivate
->pTextClipboard
, TRUE
);
376 gtk_text_buffer_copy_clipboard(pPrivate
->pBuffer
, pPrivate
->pTextClipboard
);
378 case CLIPBOARD_PASTE
:
379 gtk_text_buffer_paste_clipboard(pPrivate
->pBuffer
, pPrivate
->pTextClipboard
, NULL
, TRUE
);
381 case CLIPBOARD_COPYALL
:
382 gtk_clipboard_set_text(pPrivate
->pTextClipboard
, the_text
, strlen(the_text
));
383 gtk_clipboard_set_text(pPrivate
->pPrimarySelection
, the_text
, strlen(the_text
));
386 case CLIPBOARD_SELECTALL
:
387 dasher_editor_internal_select_all(pSelf
);
389 case CLIPBOARD_CLEAR
:
390 gtk_text_buffer_set_text(pPrivate
->pBuffer
, "", 0);
399 void dasher_editor_internal_cleartext(DasherEditorInternal
*pSelf
)
401 dasher_editor_internal_clear((DasherEditor
*)pSelf
, true);
406 dasher_editor_internal_handle_stop(DasherEditor
*pSelf
) {
407 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
409 // See if anything is set to auto:
410 EditorAction
*pCurrentAction
= pPrivate
->pActionRing
;
413 bool bStarted
= false;
415 while(!bStarted
|| (pCurrentAction
!= pPrivate
->pActionRing
)) {
417 if(pCurrentAction
->bAuto
)
418 dasher_action_execute(pCurrentAction
->pAction
, DASHER_EDITOR(pSelf
), -1);
419 pCurrentAction
= pCurrentAction
->pNext
;
425 dasher_editor_internal_handle_start(DasherEditor
*pSelf
) {
426 // The edit box keeps track of where we started
428 // TODO: This should be filtered through the buffer, rather than directly to the edit box
432 /* TODO: This is obsolete - sort this out when commands are reconsidered */
434 dasher_editor_internal_handle_control(DasherEditor
*pSelf
, int iNodeID
) {
435 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
437 if(iNodeID
== Dasher::CControlManager::CTL_USER
+ 1)
438 dasher_editor_internal_clear(pSelf
, false); // Clear node is a special case (it shouldn't be)
440 EditorAction
*pCurrentAction
= pPrivate
->pActionRing
;
441 bool bStarted
= false;
443 while(!bStarted
|| (pCurrentAction
!= pPrivate
->pActionRing
)) {
445 if((iNodeID
>= pCurrentAction
->iControlID
) && (iNodeID
<= pCurrentAction
->iControlID
+ pCurrentAction
->iNSub
)) {
446 dasher_action_execute(pCurrentAction
->pAction
, DASHER_EDITOR(pSelf
), iNodeID
- pCurrentAction
->iControlID
- 1);
447 // dasher_editor_internal_clear(pSelf, true);
449 pCurrentAction
= pCurrentAction
->pNext
;
454 // TODO: Think about changing signals so we don't need to do this translation
463 static struct SControlMap sMap
[] = {
464 {Dasher::CControlManager::CTL_MOVE_FORWARD_CHAR
, EDIT_FORWARDS
, EDIT_CHAR
, false},
465 {Dasher::CControlManager::CTL_MOVE_FORWARD_WORD
, EDIT_FORWARDS
, EDIT_WORD
, false},
466 {Dasher::CControlManager::CTL_MOVE_FORWARD_LINE
, EDIT_FORWARDS
, EDIT_LINE
, false},
467 {Dasher::CControlManager::CTL_MOVE_FORWARD_FILE
, EDIT_FORWARDS
, EDIT_FILE
, false},
468 {Dasher::CControlManager::CTL_MOVE_BACKWARD_CHAR
, EDIT_BACKWARDS
, EDIT_CHAR
, false},
469 {Dasher::CControlManager::CTL_MOVE_BACKWARD_WORD
, EDIT_BACKWARDS
, EDIT_WORD
, false},
470 {Dasher::CControlManager::CTL_MOVE_BACKWARD_LINE
, EDIT_BACKWARDS
, EDIT_LINE
, false},
471 {Dasher::CControlManager::CTL_MOVE_BACKWARD_FILE
, EDIT_BACKWARDS
, EDIT_FILE
, false},
472 {Dasher::CControlManager::CTL_DELETE_FORWARD_CHAR
, EDIT_FORWARDS
, EDIT_CHAR
, true},
473 {Dasher::CControlManager::CTL_DELETE_FORWARD_WORD
, EDIT_FORWARDS
, EDIT_WORD
, true},
474 {Dasher::CControlManager::CTL_DELETE_FORWARD_LINE
, EDIT_FORWARDS
, EDIT_LINE
, true},
475 {Dasher::CControlManager::CTL_DELETE_FORWARD_FILE
, EDIT_FORWARDS
, EDIT_FILE
, true},
476 {Dasher::CControlManager::CTL_DELETE_BACKWARD_CHAR
, EDIT_BACKWARDS
, EDIT_CHAR
, true},
477 {Dasher::CControlManager::CTL_DELETE_BACKWARD_WORD
, EDIT_BACKWARDS
, EDIT_WORD
, true},
478 {Dasher::CControlManager::CTL_DELETE_BACKWARD_LINE
, EDIT_BACKWARDS
, EDIT_LINE
, true},
479 {Dasher::CControlManager::CTL_DELETE_BACKWARD_FILE
, EDIT_BACKWARDS
, EDIT_FILE
, true}
482 if(pPrivate
->pBufferSet
) {
483 for(unsigned int i(0); i
< sizeof(sMap
)/sizeof(struct SControlMap
); ++i
) {
484 if(sMap
[i
].iEvent
== iNodeID
) {
486 idasher_buffer_set_edit_delete(pPrivate
->pBufferSet
, sMap
[i
].iDir
, sMap
[i
].iDist
);
488 idasher_buffer_set_edit_move(pPrivate
->pBufferSet
, sMap
[i
].iDir
, sMap
[i
].iDist
);
496 dasher_editor_internal_action_button(DasherEditor
*pSelf
, DasherAction
*pAction
) {
498 dasher_action_execute(pAction
, DASHER_EDITOR(pSelf
), -1);
499 dasher_editor_internal_clear(pSelf
, true);
501 else { // Clear button
502 dasher_editor_internal_clear(pSelf
, false);
507 dasher_editor_internal_clear(DasherEditor
*pSelf
, gboolean bStore
) {
508 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
510 if(IS_DASHER_INTERNAL_BUFFER(pPrivate
->pBufferSet
))
511 dasher_internal_buffer_clear(DASHER_INTERNAL_BUFFER(pPrivate
->pBufferSet
));
516 dasher_editor_internal_actions_start(DasherEditor
*pSelf
) {
517 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
519 pPrivate
->bActionIterStarted
= false;
520 pPrivate
->pActionIter
= pPrivate
->pActionRing
;
524 dasher_editor_internal_actions_more(DasherEditor
*pSelf
) {
525 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
527 return(!pPrivate
->bActionIterStarted
|| (pPrivate
->pActionIter
!= pPrivate
->pActionRing
));
531 dasher_editor_internal_actions_get_next(DasherEditor
*pSelf
, const gchar
**szName
, gint
*iID
, gboolean
*bShow
, gboolean
*bControl
, gboolean
*bAuto
) {
532 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
534 *szName
= dasher_action_get_name(pPrivate
->pActionIter
->pAction
);
535 *iID
= pPrivate
->pActionIter
->iID
;
536 *bShow
= pPrivate
->pActionIter
->bShow
;
537 *bControl
= pPrivate
->pActionIter
->bControl
;
538 *bAuto
= pPrivate
->pActionIter
->bAuto
;
540 pPrivate
->pActionIter
= pPrivate
->pActionIter
->pNext
;
541 pPrivate
->bActionIterStarted
= true;
545 dasher_editor_internal_action_set_show(DasherEditor
*pSelf
, int iActionID
, bool bValue
) {
546 EditorAction
*pAction
;
547 pAction
= dasher_editor_internal_get_action_by_id(pSelf
, iActionID
);
550 pAction
->bShow
= bValue
;
551 dasher_editor_internal_check_activity(pSelf
, pAction
);
552 dasher_editor_internal_rebuild_action_pane(pSelf
);
554 dasher_editor_internal_action_save_state(pSelf
, pAction
);
559 dasher_editor_internal_action_set_control(DasherEditor
*pSelf
, int iActionID
, bool bValue
) {
560 // TODO: Need to actually change behaviour in resonse to these calls
564 // EditorAction *pAction;
565 // pAction = dasher_editor_internal_get_action_by_id(pSelf, iActionID);
568 // pAction->bControl = bValue;
569 // dasher_editor_internal_check_activity(pSelf, pAction);
571 // gtk_dasher_control_connect_node(GTK_DASHER_CONTROL(pDasherWidget), pAction->iControlID, Dasher::CControlManager::CTL_USER, -2);
573 // gtk_dasher_control_disconnect_node(GTK_DASHER_CONTROL(pDasherWidget), pAction->iControlID, Dasher::CControlManager::CTL_USER);
575 // dasher_editor_internal_action_save_state(pSelf, pAction);
580 dasher_editor_internal_action_set_auto(DasherEditor
*pSelf
, int iActionID
, bool bValue
) {
581 EditorAction
*pAction
;
582 pAction
= dasher_editor_internal_get_action_by_id(pSelf
, iActionID
);
585 pAction
->bAuto
= bValue
;
586 dasher_editor_internal_check_activity(pSelf
, pAction
);
588 dasher_editor_internal_action_save_state(pSelf
, pAction
);
593 dasher_editor_internal_grab_focus(DasherEditor
*pSelf
) {
594 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
596 if(pPrivate
->pTextView
)
597 gtk_widget_grab_focus(GTK_WIDGET(pPrivate
->pTextView
));
602 dasher_editor_internal_create_buffer(DasherEditor
*pSelf
) {
603 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
605 /* Make an external buffer anyway, for keyboard command */
606 /* TODO: Review this */
607 if(!(pPrivate
->pExternalBuffer
))
608 pPrivate
->pExternalBuffer
= IDASHER_BUFFER_SET(dasher_external_buffer_new());
610 if(!(pPrivate
->pBufferSet
))
611 pPrivate
->pBufferSet
= IDASHER_BUFFER_SET(dasher_internal_buffer_new(pPrivate
->pTextView
));
614 g_signal_connect(G_OBJECT(pPrivate
->pBufferSet
), "offset_changed", G_CALLBACK(context_changed_handler
), pSelf
);
615 g_signal_connect(G_OBJECT(pPrivate
->pBufferSet
), "buffer_changed", G_CALLBACK(buffer_changed_handler
), pSelf
);
619 dasher_editor_internal_output(DasherEditor
*pSelf
, const gchar
*szText
, int iOffset
) {
620 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
622 // TODO: tidy this up, actionlookup by name, more flexible
623 // definition of space
625 if(!strcmp(szText
, " ")) {
626 gboolean bActionIterStarted
= false;
627 EditorAction
*pActionIter
= pPrivate
->pActionRing
;
629 while((pActionIter
!= pPrivate
->pActionRing
) || !bActionIterStarted
) {
630 bActionIterStarted
= true;
632 if(!strcmp(dasher_action_get_name(pActionIter
->pAction
), "Speak")) {
633 dasher_action_preview(pActionIter
->pAction
, DASHER_EDITOR(pSelf
));
636 pActionIter
= pActionIter
->pNext
;
640 if(pPrivate
->pBufferSet
)
641 idasher_buffer_set_insert(pPrivate
->pBufferSet
, szText
, iOffset
);
643 // if(pPrivate->pGameModeHelper)
644 // game_mode_helper_output(pPrivate->pGameModeHelper, szText);
646 pPrivate
->bFileModified
= TRUE
;
650 dasher_editor_internal_delete(DasherEditor
*pSelf
, int iLength
, int iOffset
) {
651 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
653 if(pPrivate
->pBufferSet
)
654 idasher_buffer_set_delete(pPrivate
->pBufferSet
, iLength
, iOffset
);
656 // if(pPrivate->pGameModeHelper)
657 // game_mode_helper_delete(pPrivate->pGameModeHelper, iLength);
659 pPrivate
->bFileModified
= TRUE
;
663 dasher_editor_internal_get_context(DasherEditor
*pSelf
, int iOffset
, int iLength
) {
664 // TODO: Check where this function is used
665 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
667 const gchar
*szContext
;
669 if(pPrivate
->pBufferSet
)
670 szContext
= idasher_buffer_set_get_context(pPrivate
->pBufferSet
, iOffset
, iLength
);
675 // if(szContext && (strlen(szContext) > 0))
676 // gtk_dasher_control_set_context( GTK_DASHER_CONTROL(pDasherWidget), szContext );
681 dasher_editor_internal_get_offset(DasherEditor
*pSelf
) {
682 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
683 return idasher_buffer_set_get_offset(pPrivate
->pBufferSet
);
687 dasher_editor_internal_generate_filename(DasherEditor
*pSelf
) {
688 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
690 gchar
*szNewFilename
= NULL
;
692 if( dasher_app_settings_get_bool(pPrivate
->pAppSettings
, APP_BP_TIME_STAMP
)) {
693 // Build a filename based on the current time and date
701 t_struct
= localtime(&ctime
);
704 snprintf(tbuffer
, 200, "dasher-%04d%02d%02d-%02d%02d.txt", (t_struct
->tm_year
+ 1900), (t_struct
->tm_mon
+ 1), t_struct
->tm_mday
, t_struct
->tm_hour
, t_struct
->tm_min
);
706 szNewFilename
= g_build_path("/", cwd
, tbuffer
, NULL
);
709 dasher_editor_internal_set_filename(pSelf
, szNewFilename
);
711 g_free(szNewFilename
);
715 dasher_editor_internal_open(DasherEditor
*pSelf
, const gchar
*szFilename
) {
716 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
722 if(!dasher_editor_internal_gvfs_open_file(pSelf
, szFilename
, &buffer
, &size
)) {
726 if(!dasher_editor_internal_unix_vfs_open_file(pSelf
, szFilename
, &buffer
, &size
)) {
731 // FIXME - REIMPLEMENT (shouldn't happen through core)
735 // Don't attempt to insert new text if the file is empty as it makes
737 if(!g_utf8_validate(buffer
, size
, NULL
)) { // PRLW: size as gssize = signed int
738 // It's not UTF8, so we do the best we can...
740 // If there are zero bytes in the file then we have a problem -
741 // for now, just assert that we can't load these files.
742 for(gsize i
= 0; i
< size
; ++i
)
744 // GtkWidget *pErrorBox = gtk_message_dialog_new(GTK_WINDOW(window),
746 // GTK_MESSAGE_ERROR,
748 // "Could not open the file \"%s\". Please note that Dasher cannot load files containing binary data, which may be the cause of this error.\n",
750 GtkWidget
*pErrorBox
= gtk_message_dialog_new(NULL
,
754 "Could not open the file \"%s\". Please note that Dasher cannot load files containing binary data, which may be the cause of this error.\n",
756 gtk_dialog_run(GTK_DIALOG(pErrorBox
));
757 gtk_widget_destroy(pErrorBox
);
761 pPrivate
->bFileModified
= TRUE
;
764 gchar
*buffer2
= g_strdup(g_locale_to_utf8(buffer
, size
, NULL
, &iNewSize
, NULL
));
766 // TODO: This function probably needs more thought
768 // const gchar *pEnd;
769 //gboolean bValid = g_utf8_validate(buffer2, -1, &pEnd);
775 gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), buffer
, size
);
776 gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(pPrivate
->pTextView
), gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(pPrivate
->pBuffer
)));
779 dasher_editor_internal_set_filename(pSelf
, szFilename
);
783 dasher_editor_internal_save_as(DasherEditor
*pSelf
, const gchar
*szFilename
, bool bAppend
) {
784 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
786 unsigned long long length
;
787 gchar
*inbuffer
, *outbuffer
= NULL
;
788 // gsize bytes_read, bytes_written;
790 // GError *error = NULL;
791 GtkTextIter
*start
, *end
;
794 start
= new GtkTextIter
;
795 end
= new GtkTextIter
;
797 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), start
, 0);
798 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), end
, -1);
800 inbuffer
= gtk_text_iter_get_slice(start
, end
);
802 // g_message("String %s", inbuffer);
804 //length = gtk_text_iter_get_offset(end) - gtk_text_iter_get_offset(start);
805 //length = gtk_text_buffer_get_byte_count(GTK_TEXT_BUFFER(the_text_buffer));
807 // I'm pretty certain that this is null terminated, but not 100%
808 length
= strlen(inbuffer
);
810 // g_message("Length is %d", length);
812 outbuffer
= (char *)malloc((length
+ 1) * sizeof(gchar
));
813 memcpy((void *)outbuffer
, (void *)inbuffer
, length
* sizeof(gchar
));
814 outbuffer
[length
] = 0;
816 inbuffer
= outbuffer
;
819 // switch (fileencoding) {
820 // case Dasher::Opts::UserDefault:
821 // case Dasher::Opts::AlphabetDefault:
822 // //FIXME - need to call GetAlphabetType and do appropriate stuff regarding
823 // //the character set. Arguably we should always be saving in either UTF-8 or
824 // //the user's locale (which may, of course, be UTF-8) because otherwise
825 // //we're going to read in rubbish, and we shouldn't be encouraging weird
826 // //codepage madness any further
828 // //FIXME - error handling
829 // outbuffer = g_locale_from_utf8(inbuffer, -1, &bytes_read, &bytes_written, &error);
830 // if(outbuffer == NULL) {
831 // // We can't represent the text in the current locale, so fall back to
833 // outbuffer = inbuffer;
834 // bytes_written = length;
836 // case Dasher::Opts::UTF8:
837 // outbuffer = inbuffer;
838 // bytes_written = length;
840 // // Does /anyone/ want to save text files in UTF16?
841 // // (in any case, my opinions regarding encouragement of data formats with
842 // // endianness damage are almost certainly unprintable)
844 // case Dasher::Opts::UTF16LE:
845 // cd = g_iconv_open("UTF16LE", "UTF8");
846 // outbuffer = g_convert_with_iconv(inbuffer, -1, cd, &bytes_read, &bytes_written, &error);
848 // case Dasher::Opts::UTF16BE:
849 // cd = g_iconv_open("UTF16BE", "UTF8");
850 // outbuffer = g_convert_with_iconv(inbuffer, -1, cd, &bytes_read, &bytes_written, &error);
853 outbuffer
= inbuffer
;
854 bytes_written
= length
;
858 if(!dasher_editor_internal_gvfs_save_file(pSelf
, szFilename
, outbuffer
, bytes_written
, bAppend
)) {
862 if(!dasher_editor_internal_unix_vfs_save_file(pSelf
, szFilename
, outbuffer
, bytes_written
, bAppend
)) {
867 pPrivate
->bFileModified
= FALSE
;
869 dasher_editor_internal_set_filename(pSelf
, szFilename
);
875 // dasher_editor_internal_start_tutorial(DasherEditor *pSelf) {
876 // DasherEditorInternalPrivate *pPrivate = (DasherEditorInternalPrivate *)(pSelf->private_data);
878 // // TODO: reimplement
879 // // pPrivate->pGameModeHelper = GAME_MODE_HELPER(game_mode_helper_new(GTK_DASHER_CONTROL(pDasherWidget)));
883 dasher_editor_internal_command(DasherEditor
*pSelf
, const gchar
*szCommand
) {
884 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
886 if(!strcmp(szCommand
, "new")) { //select_new_file
887 dasher_editor_internal_command_new(pSelf
);
891 if(!strcmp(szCommand
, "open")) { //select open file
892 dasher_editor_internal_command_open(pSelf
);
896 if(!strcmp(szCommand
, "save")) { //save_file
897 dasher_editor_internal_command_save(pSelf
, FALSE
, FALSE
);
901 if(!strcmp(szCommand
, "saveas")) { // select_save_file_as
902 dasher_editor_internal_command_save(pSelf
, TRUE
, FALSE
);
906 if(!strcmp(szCommand
, "append")) { // select_append_file
907 dasher_editor_internal_command_save(pSelf
, TRUE
, TRUE
);
911 if(!strcmp(szCommand
, "cut")) { // clipboard_cut
912 dasher_editor_internal_clipboard(pSelf
, CLIPBOARD_CUT
);
916 if(!strcmp(szCommand
, "copy")) { // clipboard_copy
917 dasher_editor_internal_clipboard(pSelf
, CLIPBOARD_COPY
);
921 if(!strcmp(szCommand
, "copyall")) { // clipboard_copyall
922 dasher_editor_internal_clipboard(pSelf
, CLIPBOARD_COPYALL
);
926 if(!strcmp(szCommand
, "paste")) { // clipboard_paste
927 dasher_editor_internal_clipboard(pSelf
, CLIPBOARD_PASTE
);
931 // TODO: This isn't actually accessible from anywhere
932 if(!strcmp(szCommand
, "selectall")) { // clipboard_paste
933 dasher_editor_internal_clipboard(pSelf
, CLIPBOARD_SELECTALL
);
937 /* TODO: We need a rethink here */
938 const gchar
*szForwardCommand
= NULL
;
939 gint iSubCommand
= 0;
941 if(!strcmp(szCommand
, "speakall")) {
942 szForwardCommand
= "Speak";
945 else if(!strcmp(szCommand
, "speaklast")) {
946 szForwardCommand
= "Speak";
949 else if(!strcmp(szCommand
, "speakrepeat")) {
950 szForwardCommand
= "Speak";
954 if(szForwardCommand
) {
955 gboolean bActionIterStarted
= false;
956 EditorAction
*pActionIter
= pPrivate
->pActionRing
;
958 while((pActionIter
!= pPrivate
->pActionRing
) || !bActionIterStarted
) {
959 bActionIterStarted
= true;
961 if(!strcmp(dasher_action_get_name(pActionIter
->pAction
), szForwardCommand
)) {
962 dasher_action_execute(pActionIter
->pAction
, DASHER_EDITOR(pSelf
), iSubCommand
);
966 pActionIter
= pActionIter
->pNext
;
976 dasher_editor_internal_handle_font(DasherEditor
*pSelf
, const gchar
*szFont
) {
977 if(strcmp(szFont
, "")) {
978 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
980 PangoFontDescription
*pFD
= pango_font_description_from_string(szFont
);
981 gtk_widget_modify_font(GTK_WIDGET(pPrivate
->pTextView
), pFD
);
987 dasher_editor_internal_file_changed(DasherEditor
*pSelf
) {
988 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
989 return pPrivate
->bFileModified
;
993 dasher_editor_internal_get_filename(DasherEditor
*pSelf
) {
994 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
996 return pPrivate
->szFilename
;
999 // TODO: We shouldn't need to know about the buffer here - make this a method of the buffer set
1001 dasher_editor_internal_get_all_text(DasherEditor
*pSelf
) {
1002 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1007 gtk_text_buffer_get_start_iter(pPrivate
->pBuffer
, &oStart
);
1008 gtk_text_buffer_get_end_iter(pPrivate
->pBuffer
, &oEnd
);
1010 pPrivate
->pNewMark
= gtk_text_buffer_create_mark(pPrivate
->pBuffer
, NULL
, &oEnd
, TRUE
);
1012 return gtk_text_buffer_get_text(pPrivate
->pBuffer
, &oStart
, &oEnd
, false );
1016 dasher_editor_internal_get_new_text(DasherEditor
*pSelf
) {
1017 // TODO: Implement this properly
1018 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1023 gtk_text_buffer_get_end_iter(pPrivate
->pBuffer
, &oEnd
);
1024 gtk_text_buffer_get_iter_at_mark(pPrivate
->pBuffer
, &oStart
, pPrivate
->pNewMark
);
1026 const gchar
*szRetVal
= gtk_text_buffer_get_text(pPrivate
->pBuffer
, &oStart
, &oEnd
, false );
1028 pPrivate
->pNewMark
= gtk_text_buffer_create_mark(pPrivate
->pBuffer
, NULL
, &oEnd
, TRUE
);
1034 /* Private methods */
1036 dasher_editor_internal_select_all(DasherEditor
*pSelf
) {
1037 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1038 GtkTextIter
*start
, *end
;
1040 start
= new GtkTextIter
;
1041 end
= new GtkTextIter
;
1043 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), start
, 0);
1044 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(pPrivate
->pBuffer
), end
, -1);
1046 GtkTextMark
*selection
= gtk_text_buffer_get_mark(pPrivate
->pBuffer
, "selection_bound");
1047 GtkTextMark
*cursor
= gtk_text_buffer_get_mark(pPrivate
->pBuffer
, "insert");
1049 gtk_text_buffer_move_mark(pPrivate
->pBuffer
, selection
, start
);
1050 gtk_text_buffer_move_mark(pPrivate
->pBuffer
, cursor
, end
);
1057 dasher_editor_internal_setup_actions(DasherEditor
*pSelf
) {
1058 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1060 // TODO: Activate and deactivate methods for actions
1061 // TODO: Clear shouldn't be a special case (include support for false in clear method)
1064 dasher_editor_internal_add_action(pSelf
, DASHER_ACTION(dasher_action_speech_new()));
1067 dasher_editor_internal_add_action(pSelf
, DASHER_ACTION(dasher_action_keyboard_new(pPrivate
->pExternalBuffer
)));
1070 dasher_editor_internal_add_action(pSelf
, DASHER_ACTION(dasher_action_keyboard_maemo_new()));
1072 // dasher_editor_internal_add_action(pSelf, DASHER_ACTION(dasher_action_copy_new(pSelf)));
1075 G_CONST_RETURN gchar
*szFilename
;
1078 gchar
*szUserScriptDir
= new gchar
[strlen(dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_USER_LOC
))+9];
1079 strcpy(szUserScriptDir
, dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_USER_LOC
));
1080 strcat(szUserScriptDir
, "scripts/");
1082 pDirectory
= g_dir_open(szUserScriptDir
, 0, NULL
);
1085 while((szFilename
= g_dir_read_name(pDirectory
))) {
1086 dasher_editor_internal_add_action(pSelf
, DASHER_ACTION(dasher_action_script_new(szUserScriptDir
, szFilename
)));
1089 g_dir_close(pDirectory
);
1092 delete[] szUserScriptDir
;
1094 gchar
*szSystemScriptDir
= new gchar
[strlen(dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_SYSTEM_LOC
))+9];
1095 strcpy(szSystemScriptDir
, dasher_app_settings_get_string(pPrivate
->pAppSettings
, SP_SYSTEM_LOC
));
1096 strcat(szSystemScriptDir
, "scripts/");
1098 pDirectory
= g_dir_open(szSystemScriptDir
, 0, NULL
);
1101 while((szFilename
= g_dir_read_name(pDirectory
))) {
1102 dasher_editor_internal_add_action(pSelf
, DASHER_ACTION(dasher_action_script_new(szSystemScriptDir
, szFilename
)));
1105 g_dir_close(pDirectory
);
1108 delete[] szSystemScriptDir
;
1111 // TODO: Reimplement
1113 // // TODO: This doesn't get re-called if the preferences change
1115 // gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER, "Actions", -1 );
1116 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER, Dasher::CControlManager::CTL_ROOT, -2);
1117 // int iControlOffset(1);
1119 // gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER + iControlOffset, "Clear", -1 );
1120 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER + iControlOffset, Dasher::CControlManager::CTL_USER, -2);
1121 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), -1, Dasher::CControlManager::CTL_USER + iControlOffset, -2);
1122 // ++iControlOffset;
1124 // EditorAction *pCurrentAction = pPrivate->pActionRing;
1125 // bool bStarted = false;
1127 // while(!bStarted || (pCurrentAction != pPrivate->pActionRing)) {
1130 // if(pCurrentAction->bControl) {
1131 // gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER + iControlOffset, dasher_action_get_name(pCurrentAction->pAction), -1 );
1132 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER + iControlOffset, Dasher::CControlManager::CTL_USER, -2);
1134 // int iNSub(dasher_action_get_sub_count(pCurrentAction->pAction));
1137 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), -1, Dasher::CControlManager::CTL_USER + iControlOffset, -2);
1140 // for(int i(0); i < iNSub; ++i) {
1141 // gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER + iControlOffset + i + 1, dasher_action_get_sub_name(pCurrentAction->pAction, i), -1 );
1142 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), Dasher::CControlManager::CTL_USER + iControlOffset + i + 1, Dasher::CControlManager::CTL_USER + iControlOffset, -2);
1143 // gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pDasherWidget), -1, Dasher::CControlManager::CTL_USER + iControlOffset + i + 1, -2);
1147 // pCurrentAction->iControlID = Dasher::CControlManager::CTL_USER + iControlOffset;
1148 // pCurrentAction->iNSub = iNSub;
1149 // iControlOffset += iNSub + 1;
1152 // pCurrentAction = pCurrentAction->pNext;
1155 #ifndef WITH_MAEMOFULLSCREEN
1156 // dasher_editor_internal_rebuild_action_pane(pSelf);
1161 dasher_editor_internal_add_action(DasherEditor
*pSelf
, DasherAction
*pNewAction
) {
1162 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1164 EditorAction
*pNewEditorAction
= new EditorAction
;
1165 pNewEditorAction
->pAction
= pNewAction
;
1166 pNewEditorAction
->iID
= pPrivate
->iNextActionID
;
1167 ++pPrivate
->iNextActionID
;
1169 gchar szRegistryName
[256];
1170 strncpy(szRegistryName
, "Action_", 256);
1171 strncat(szRegistryName
, dasher_action_get_name(pNewEditorAction
->pAction
), 255 - strlen(szRegistryName
));
1173 for(unsigned int i(0); i
< strlen(szRegistryName
); ++i
)
1174 if(szRegistryName
[i
] == ' ')
1175 szRegistryName
[i
] = '_';
1179 if(!dasher_app_settings_get_free_long(pPrivate
->pAppSettings
, szRegistryName
, iState
)) {
1180 if(!strcmp(dasher_action_get_name(pNewEditorAction
->pAction
), "Speak"))
1183 iState
= ACTION_STATE_SHOW
| ACTION_STATE_CONTROL
;
1185 dasher_app_settings_set_free_long(pPrivate
->pAppSettings
, szRegistryName
, iState
);
1188 pNewEditorAction
->bShow
= iState
& ACTION_STATE_SHOW
;
1189 pNewEditorAction
->bControl
= iState
& ACTION_STATE_CONTROL
;
1190 pNewEditorAction
->bAuto
= iState
& ACTION_STATE_AUTO
;
1192 dasher_editor_internal_check_activity(pSelf
, pNewEditorAction
);
1194 if(pPrivate
->pActionRing
) {
1195 pNewEditorAction
->pNext
= pPrivate
->pActionRing
;
1196 pNewEditorAction
->pPrevious
= pPrivate
->pActionRing
->pPrevious
;
1197 pPrivate
->pActionRing
->pPrevious
->pNext
= pNewEditorAction
;
1198 pPrivate
->pActionRing
->pPrevious
= pNewEditorAction
;
1201 pNewEditorAction
->pNext
= pNewEditorAction
;
1202 pNewEditorAction
->pPrevious
= pNewEditorAction
;
1205 pPrivate
->pActionRing
= pNewEditorAction
;
1207 // TODO: Reimplement
1208 // if(iState & ACTION_STATE_SHOW)
1209 // gtk_dasher_control_add_action_button(GTK_DASHER_CONTROL(pDasherWidget), dasher_action_get_name(pNewEditorAction->pAction));
1212 static EditorAction
*
1213 dasher_editor_internal_get_action_by_id(DasherEditor
*pSelf
, int iID
){
1214 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1216 EditorAction
*pCurrentAction
= pPrivate
->pActionRing
;
1217 bool bStarted
= false;
1219 while(!bStarted
|| (pCurrentAction
!= pPrivate
->pActionRing
)) {
1221 if(pCurrentAction
->iID
== iID
)
1222 return pCurrentAction
;
1223 pCurrentAction
= pCurrentAction
->pNext
;
1230 dasher_editor_internal_rebuild_action_pane(DasherEditor
*pSelf
) {
1231 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1233 // Delete any existing widgets
1234 gtk_container_foreach(GTK_CONTAINER(pPrivate
->pActionPane
), delete_children_callback
, 0);
1236 // Add the cancel button
1237 GtkButton
*pNewButton
= GTK_BUTTON(gtk_button_new_with_label("Clear"));
1238 gtk_widget_show(GTK_WIDGET(pNewButton
));
1240 void **pUserData
= new void *[2];
1241 pUserData
[0] = (void *)pSelf
;
1244 g_signal_connect(G_OBJECT(pNewButton
), "clicked", G_CALLBACK(action_button_callback
), pUserData
);
1246 // For Maemo we want the packing to expand
1247 gtk_box_pack_start(GTK_BOX(pPrivate
->pActionPane
), GTK_WIDGET(pNewButton
), true, true, 0);
1249 gtk_box_pack_start(GTK_BOX(pPrivate
->pActionPane
), GTK_WIDGET(pNewButton
), false, false, 0);
1253 EditorAction
*pCurrentAction
= pPrivate
->pActionRing
;
1254 bool bStarted
= false;
1256 while(!bStarted
|| (pCurrentAction
!= pPrivate
->pActionRing
)) {
1258 if(pCurrentAction
->bShow
) {
1259 GtkButton
*pNewButton
= GTK_BUTTON(gtk_button_new_with_label(dasher_action_get_name(pCurrentAction
->pAction
)));
1260 gtk_widget_show(GTK_WIDGET(pNewButton
));
1262 pUserData
= new void *[2];
1263 pUserData
[0] = (void *)pSelf
;
1264 pUserData
[1] = (void *)(pCurrentAction
->pAction
);
1266 g_signal_connect(G_OBJECT(pNewButton
), "clicked", G_CALLBACK(action_button_callback
), pUserData
);
1268 // For Maemo we want the packing to expand
1269 gtk_box_pack_start(GTK_BOX(pPrivate
->pActionPane
), GTK_WIDGET(pNewButton
), true, true, 0);
1271 gtk_box_pack_start(GTK_BOX(pPrivate
->pActionPane
), GTK_WIDGET(pNewButton
), false, false, 0);
1274 pCurrentAction
= pCurrentAction
->pNext
;
1278 // TODO: This shouldn't be a part of the editor
1280 //dasher_editor_internal_display_message(DasherEditor *pSelf, DasherMessageInfo *pMessageInfo) {
1281 // GtkMessageDialog *pDialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new(0, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, pMessageInfo->szMessage));
1282 // gtk_dialog_run(GTK_DIALOG(pDialog));
1283 // gtk_widget_destroy(GTK_WIDGET(pDialog));
1287 dasher_editor_internal_check_activity(DasherEditor
*pSelf
, EditorAction
*pAction
) {
1288 gboolean
bNeedActive(pAction
->bShow
|| pAction
->bControl
|| pAction
->bAuto
);
1289 gboolean
bActive(dasher_action_get_active(pAction
->pAction
));
1291 if(bNeedActive
&& !bActive
)
1292 dasher_action_activate(pAction
->pAction
);
1293 else if(!bNeedActive
&& bActive
)
1294 dasher_action_deactivate(pAction
->pAction
);
1298 dasher_editor_internal_action_save_state(DasherEditor
*pSelf
, EditorAction
*pAction
) {
1299 gchar szRegistryName
[256];
1300 strncpy(szRegistryName
, "Action_", 256);
1301 strncat(szRegistryName
, dasher_action_get_name(pAction
->pAction
), 255 - strlen(szRegistryName
));
1303 for(unsigned int i(0); i
< strlen(szRegistryName
); ++i
)
1304 if(szRegistryName
[i
] == ' ')
1305 szRegistryName
[i
] = '_';
1310 iState
+= ACTION_STATE_SHOW
;
1312 if(pAction
->bControl
)
1313 iState
+= ACTION_STATE_CONTROL
;
1316 iState
+= ACTION_STATE_AUTO
;
1318 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1319 dasher_app_settings_set_free_long(pPrivate
->pAppSettings
, szRegistryName
, iState
);
1323 dasher_editor_internal_command_new(DasherEditor
*pSelf
) {
1324 dasher_editor_internal_new_buffer(pSelf
, NULL
);
1328 dasher_editor_internal_command_open(DasherEditor
*pSelf
) {
1329 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1331 GtkWidget
*pTopLevel
= gtk_widget_get_toplevel(GTK_WIDGET(pPrivate
->pTextView
));
1332 GtkWidget
*filesel
= gtk_file_chooser_dialog_new(_("Select File"),
1333 GTK_WINDOW(pTopLevel
),
1334 GTK_FILE_CHOOSER_ACTION_OPEN
,
1336 GTK_RESPONSE_ACCEPT
,
1338 GTK_RESPONSE_CANCEL
, NULL
);
1341 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(filesel
), FALSE
);
1344 if(gtk_dialog_run(GTK_DIALOG(filesel
)) == GTK_RESPONSE_ACCEPT
) {
1346 char *filename
= gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(filesel
));
1348 char *filename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filesel
));
1350 dasher_editor_internal_new_buffer(pSelf
, filename
);
1354 gtk_widget_destroy(filesel
);
1358 dasher_editor_internal_command_save(DasherEditor
*pSelf
, gboolean bPrompt
, gboolean bAppend
) {
1359 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1361 gchar
*szFilename
= NULL
;
1363 // Hmm... this makes no sense - surely this always evaluates to true?
1364 if(bPrompt
|| !szFilename
) {
1365 GtkWidget
*pTopLevel
= gtk_widget_get_toplevel(GTK_WIDGET(pPrivate
->pTextView
));
1366 GtkWidget
*filesel
= gtk_file_chooser_dialog_new(_("Select File"),
1367 GTK_WINDOW(pTopLevel
),
1368 GTK_FILE_CHOOSER_ACTION_SAVE
,
1370 GTK_RESPONSE_ACCEPT
,
1372 GTK_RESPONSE_CANCEL
, NULL
);
1375 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(filesel
), FALSE
);
1378 if(gtk_dialog_run(GTK_DIALOG(filesel
)) == GTK_RESPONSE_ACCEPT
) {
1380 szFilename
= gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(filesel
));
1382 szFilename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filesel
));
1386 gtk_widget_destroy(filesel
);
1390 gtk_widget_destroy(filesel
);
1393 szFilename
= g_strdup(pPrivate
->szFilename
);
1396 dasher_editor_internal_save_as(pSelf
, szFilename
, bAppend
);
1402 dasher_editor_internal_gvfs_print_error(DasherEditor
*pSelf
, GError
*error
, const char *myfilename
) {
1403 // Turns a GVFS error into English
1404 GtkWidget
*error_dialog
;
1405 // error_dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Could not open the file \"%s\"\n%s\n", myfilename, gnome_vfs_result_to_string(*result));
1406 error_dialog
= gtk_message_dialog_new(NULL
, GTK_DIALOG_MODAL
, GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
, "Could not open the file \"%s\"\n%s\n", myfilename
, error
->message
);
1407 gtk_dialog_set_default_response(GTK_DIALOG(error_dialog
), GTK_RESPONSE_OK
);
1408 gtk_window_set_resizable(GTK_WINDOW(error_dialog
), FALSE
);
1409 gtk_dialog_run(GTK_DIALOG(error_dialog
));
1410 gtk_widget_destroy(error_dialog
);
1415 dasher_editor_internal_gvfs_open_file(DasherEditor
*pSelf
, const char *uri
, gchar
**buffer
, gsize
*size
)
1418 GFileInputStream
*read_handle
;
1423 file
= g_file_new_for_uri (uri
);
1425 read_handle
= g_file_read (file
, NULL
, &error
);
1427 /* If URI didn't work, try path */
1428 if (read_handle
== NULL
)
1429 { // PRLW: g_object_unref isn't actually stipulated by g_file_new_for_uri
1430 g_object_unref (file
);
1431 file
= g_file_new_for_path (uri
);
1432 read_handle
= g_file_read (file
, NULL
, &error
);
1435 if (read_handle
== NULL
)
1437 dasher_editor_internal_gvfs_print_error (pSelf
, error
, uri
);
1438 g_object_unref (file
);
1442 info
= g_file_query_info (file
, G_FILE_ATTRIBUTE_STANDARD_SIZE
,
1443 G_FILE_QUERY_INFO_NONE
, NULL
, &error
);
1447 dasher_editor_internal_gvfs_print_error (pSelf
, error
, uri
);
1448 g_input_stream_close (G_INPUT_STREAM(read_handle
), NULL
, &error
);
1449 g_object_unref (read_handle
);
1450 g_object_unref (file
);
1454 // XXX PRLW: cases info > max(size) as max(size) < max(uint64),
1455 // and bytes_read < size aren't handled.
1456 *size
= g_file_info_get_attribute_uint64(info
,G_FILE_ATTRIBUTE_STANDARD_SIZE
);
1457 *buffer
= (gchar
*) g_malloc (*size
);
1458 bytes_read
= g_input_stream_read (G_INPUT_STREAM(read_handle
), *buffer
,
1459 *size
, NULL
, &error
);
1461 if (bytes_read
== -1)
1463 dasher_editor_internal_gvfs_print_error (pSelf
, error
, uri
);
1464 g_input_stream_close (G_INPUT_STREAM(read_handle
), NULL
, &error
);
1465 g_object_unref (read_handle
);
1466 g_object_unref (info
);
1467 g_object_unref (file
);
1471 g_input_stream_close (G_INPUT_STREAM(read_handle
), NULL
, NULL
);
1472 g_object_unref (read_handle
);
1473 g_object_unref (info
);
1474 g_object_unref (file
);
1478 static GFileOutputStream
*append_or_replace_file(GFile
*file
, bool append
, GError
**error
)
1480 GFileOutputStream
*write_handle
;
1482 write_handle
= g_file_append_to (file
, G_FILE_CREATE_NONE
, NULL
, error
);
1484 write_handle
= g_file_replace (file
, NULL
, FALSE
, G_FILE_CREATE_NONE
,
1487 return write_handle
;
1491 dasher_editor_internal_gvfs_save_file(DasherEditor
*pSelf
, const char *uri
, gchar
*buffer
, gsize length
, bool append
)
1494 GFileOutputStream
*write_handle
;
1496 gssize bytes_written
;
1498 file
= g_file_new_for_uri (uri
);
1500 write_handle
= append_or_replace_file (file
, append
, &error
);
1502 /* If URI didn't work, try path */
1503 if (write_handle
== NULL
)
1505 g_object_unref (file
);
1506 file
= g_file_new_for_path (uri
);
1507 write_handle
= append_or_replace_file (file
, append
, &error
);
1510 if (write_handle
== NULL
)
1512 dasher_editor_internal_gvfs_print_error (pSelf
, error
, uri
);
1513 g_object_unref (file
);
1519 if (!g_seekable_seek(G_SEEKABLE(write_handle
),0,G_SEEK_END
, NULL
, &error
))
1521 dasher_editor_internal_gvfs_print_error (pSelf
, error
, uri
);
1522 g_object_unref (write_handle
);
1523 g_object_unref (file
);
1528 bytes_written
= g_output_stream_write (G_OUTPUT_STREAM(write_handle
), buffer
,
1529 length
, NULL
, &error
);
1530 // XXX PRLW: case bytes_written < length not handled.
1531 if (bytes_written
== -1)
1533 dasher_editor_internal_gvfs_print_error (pSelf
, error
, uri
);
1534 g_output_stream_close (G_OUTPUT_STREAM(write_handle
), NULL
, NULL
);
1535 g_object_unref (write_handle
);
1536 g_object_unref (file
);
1540 g_output_stream_close (G_OUTPUT_STREAM(write_handle
), NULL
, NULL
);
1541 g_object_unref (write_handle
);
1542 g_object_unref (file
);
1546 #else /* not HAVE_GIO */
1549 dasher_editor_internal_unix_vfs_open_file(DasherEditor
*pSelf
, const char *myfilename
, gchar
**buffer
, gsize
*size
) {
1550 GtkWidget
*error_dialog
;
1552 struct stat file_stat
;
1555 stat(myfilename
, &file_stat
);
1556 fp
= fopen(myfilename
, "r");
1558 if(fp
== NULL
|| S_ISDIR(file_stat
.st_mode
)) {
1559 // error_dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Could not open the file \"%s\".\n", myfilename);
1560 error_dialog
= gtk_message_dialog_new(NULL
, GTK_DIALOG_MODAL
, GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
, "Could not open the file \"%s\".\n", myfilename
);
1561 gtk_dialog_set_default_response(GTK_DIALOG(error_dialog
), GTK_RESPONSE_OK
);
1562 gtk_window_set_resizable(GTK_WINDOW(error_dialog
), FALSE
);
1563 gtk_dialog_run(GTK_DIALOG(error_dialog
));
1564 gtk_widget_destroy(error_dialog
);
1568 *size
= file_stat
.st_size
; // PRLW: is off_t = uint64_t, size is size_t, MD
1569 *buffer
= (gchar
*) g_malloc(*size
);
1570 fread(*buffer
, *size
, 1, fp
);
1576 dasher_editor_internal_unix_vfs_save_file(DasherEditor
*pSelf
, const char *myfilename
, gchar
*buffer
, gsize length
, bool append
) {
1578 GtkWidget
*error_dialog
;
1582 if(append
== true) {
1583 fp
= fopen(myfilename
, "a");
1590 fp
= fopen(myfilename
, "w");
1597 // error_dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Could not save the file \"%s\".\n", myfilename);
1598 error_dialog
= gtk_message_dialog_new(NULL
, GTK_DIALOG_MODAL
, GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
, "Could not save the file \"%s\".\n", myfilename
);
1599 gtk_dialog_set_default_response(GTK_DIALOG(error_dialog
), GTK_RESPONSE_OK
);
1600 gtk_window_set_resizable(GTK_WINDOW(error_dialog
), FALSE
);
1601 gtk_dialog_run(GTK_DIALOG(error_dialog
));
1602 gtk_widget_destroy(error_dialog
);
1606 fwrite(buffer
, 1, length
, fp
);
1613 dasher_editor_internal_set_filename(DasherEditor
*pSelf
, const gchar
*szFilename
) {
1614 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1616 if(pPrivate
->szFilename
)
1617 g_free((void *)pPrivate
->szFilename
);
1620 pPrivate
->szFilename
= g_strdup(szFilename
);
1622 pPrivate
->szFilename
= NULL
;
1624 g_signal_emit_by_name(G_OBJECT(pSelf
), "filename_changed", G_OBJECT(pSelf
), NULL
, NULL
);
1628 dasher_editor_internal_convert(DasherEditor
*pSelf
) {
1629 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1631 if(pPrivate
->pBufferSet
)
1632 idasher_buffer_set_edit_convert(pPrivate
->pBufferSet
);
1636 dasher_editor_internal_protect(DasherEditor
*pSelf
) {
1637 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1639 if(pPrivate
->pBufferSet
)
1640 idasher_buffer_set_edit_protect(pPrivate
->pBufferSet
);
1644 dasher_editor_internal_new_buffer(DasherEditor
*pSelf
, const gchar
*szFilename
) {
1645 /* TODO: eventually rewrite this without references to external functions */
1648 dasher_editor_internal_open(pSelf
, szFilename
);
1651 dasher_editor_internal_generate_filename(pSelf
);
1652 dasher_editor_internal_clear(pSelf
, false);
1655 // g_signal_emit_by_name(G_OBJECT(pSelf), "buffer_changed", G_OBJECT(pSelf), NULL, NULL);
1659 dasher_editor_internal_handle_parameter_change(DasherEditor
*pSelf
, gint iParameter
) {
1660 DasherEditorInternalPrivate
*pPrivate
= DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf
);
1662 switch(iParameter
) {
1663 case APP_SP_EDIT_FONT
:
1664 dasher_editor_internal_handle_font(pSelf
,
1665 dasher_app_settings_get_string(pPrivate
->pAppSettings
, APP_SP_EDIT_FONT
));
1670 /* Callback Functions */
1673 delete_children_callback(GtkWidget
*pWidget
, gpointer pUserData
) {
1674 gtk_widget_destroy(pWidget
);
1678 main_window_realized(DasherMain
*pMain
, gpointer pUserData
) {
1682 action_button_callback(GtkWidget
*pWidget
, gpointer pUserData
) {
1683 void **pPointers((void **)pUserData
);
1684 dasher_editor_internal_action_button((DasherEditor
*)pPointers
[0], (DasherAction
*)pPointers
[1]);
1688 context_changed_handler(GObject
*pSource
, gpointer pUserData
) {
1689 DasherEditorInternal
*pSelf
= DASHER_EDITOR_INTERNAL(pUserData
);
1691 // TODO: plumb signal back into control
1692 g_signal_emit_by_name(G_OBJECT(pSelf
), "context_changed", G_OBJECT(pSelf
), NULL
, NULL
);
1697 buffer_changed_handler(GObject
*pSource
, gpointer pUserData
) {
1698 DasherEditorInternal
*pSelf
= DASHER_EDITOR_INTERNAL(pUserData
);
1700 // TODO: plumb signal back into control
1701 g_signal_emit_by_name(G_OBJECT(pSelf
), "buffer_changed", G_OBJECT(pSelf
), NULL
, NULL
);