Dasher depends on glib, and newish glib comes with gio, so use gio's gvfs
[dasher.git] / Src / Gtk2 / dasher_editor.cpp
blob95107feed75bd3d68c21a459a345d80f5918cdf1
1 // dasher_editor.cpp
2 //
3 // Copyright (c) 2008 The Dasher Team
4 //
5 // This file is part of Dasher.
6 //
7 // Dasher is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
12 // Dasher is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with Dasher; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "config.h"
23 #include <glib/gi18n.h>
24 #include <gtk/gtk.h>
26 #include "dasher_action_keyboard.h"
27 #ifdef WITH_MAEMO
28 #include "dasher_action_keyboard_maemo.h"
29 #else
30 #include "dasher_action_script.h"
31 #endif
32 #ifdef GNOME_SPEECH
33 #include "dasher_action_speech.h"
34 #endif
35 #include "dasher_editor.h"
36 #include "dasher_external_buffer.h"
37 #include "dasher_internal_buffer.h"
38 #include "dasher_lock_dialogue.h"
39 #include "dasher_main.h"
40 //#include "game_mode_helper.h"
42 #define ACTION_STATE_SHOW 1
43 #define ACTION_STATE_CONTROL 2
44 #define ACTION_STATE_AUTO 4
46 typedef struct _EditorAction EditorAction;
48 struct _EditorAction {
49 DasherAction *pAction;
50 EditorAction *pNext;
51 EditorAction *pPrevious;
52 gint iControlID;
53 gint iID; // TODO: does this need to be separate from iControlID?
54 gboolean bShow;
55 gboolean bControl;
56 gboolean bAuto;
57 gint iNSub;
60 typedef struct _DasherEditorPrivate DasherEditorPrivate;
62 struct _DasherEditorPrivate {
63 DasherMain *pDasherMain;
64 GtkTextView *pTextView;
65 GtkTextBuffer *pBuffer;
66 GtkVBox *pActionPane;
67 GtkClipboard *pTextClipboard;
68 GtkClipboard *pPrimarySelection;
69 EditorAction *pActionRing;
70 EditorAction *pActionIter;
71 gboolean bActionIterStarted;
72 gint iNextActionID;
73 IDasherBufferSet *pBufferSet;
74 IDasherBufferSet *pExternalBuffer;
75 IDasherBufferSet *pInternalBuffer;
76 // GameModeHelper *pGameModeHelper;
77 GtkTextMark *pNewMark;
78 DasherAppSettings *pAppSettings;
79 gchar *szFilename;
80 gboolean bFileModified; // TODO: Make this work properly, export to main for quit etc
83 #define DASHER_EDITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), TYPE_DASHER_EDITOR, DasherEditorPrivate))
85 /* Signals */
86 enum {
87 FILENAME_CHANGED,
88 BUFFER_CHANGED,
89 CONTEXT_CHANGED,
90 SIGNAL_NUM
93 static guint dasher_editor_signals[SIGNAL_NUM];
95 /* TODO: Use appropriate macros here */
96 /* G-object boilerplate code */
97 // static void dasher_editor_class_init(DasherEditorClass *pClass);
98 // static void dasher_editor_init(DasherEditor *pEditor);
100 G_DEFINE_TYPE(DasherEditor, dasher_editor, GTK_TYPE_VBOX);
102 static void dasher_editor_finalize(GObject *pObject);
104 static void
105 dasher_editor_class_init(DasherEditorClass *pClass) {
106 g_type_class_add_private(pClass, sizeof(DasherEditorPrivate));
108 GObjectClass *pObjectClass = (GObjectClass *) pClass;
109 pObjectClass->finalize = dasher_editor_finalize;
111 /* Setup signals */
112 dasher_editor_signals[FILENAME_CHANGED] = g_signal_new("filename-changed", G_TYPE_FROM_CLASS(pClass),
113 static_cast < GSignalFlags > (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
114 G_STRUCT_OFFSET(DasherEditorClass, filename_changed),
115 NULL, NULL, g_cclosure_marshal_VOID__VOID,
116 G_TYPE_NONE, 0);
118 dasher_editor_signals[BUFFER_CHANGED] = g_signal_new("buffer-changed", G_TYPE_FROM_CLASS(pClass),
119 static_cast < GSignalFlags > (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
120 G_STRUCT_OFFSET(DasherEditorClass, buffer_changed),
121 NULL, NULL, g_cclosure_marshal_VOID__VOID,
122 G_TYPE_NONE, 0);
124 dasher_editor_signals[CONTEXT_CHANGED] = g_signal_new("context-changed", G_TYPE_FROM_CLASS(pClass),
125 static_cast < GSignalFlags > (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
126 G_STRUCT_OFFSET(DasherEditorClass, context_changed),
127 NULL, NULL, g_cclosure_marshal_VOID__VOID,
128 G_TYPE_NONE, 0);
130 pClass->initialise = NULL;
131 pClass->command = NULL;
132 pClass->action_button = NULL;
133 pClass->actions_start = NULL;
134 pClass->actions_more = NULL;
135 pClass->actions_get_next = NULL;
136 pClass->action_set_show = NULL;
137 pClass->action_set_control = NULL;
138 pClass->action_set_auto = NULL;
139 pClass->get_all_text = NULL;
140 pClass->get_new_text = NULL;
141 pClass->output = NULL;
142 pClass->delete_text = NULL;
143 pClass->start_compose = NULL;
144 pClass->end_compose = NULL;
145 pClass->get_context = NULL;
146 pClass->get_offset = NULL;
147 pClass->handle_parameter_change = NULL;
148 pClass->handle_stop = NULL;
149 pClass->handle_start = NULL;
150 pClass->handle_control = NULL;
151 pClass->grab_focus = NULL;
152 pClass->file_changed = NULL;
153 pClass->get_filename = NULL;
155 pClass->filename_changed = NULL;
156 pClass->buffer_changed = NULL;
157 pClass->context_changed = NULL;
160 static void
161 dasher_editor_init(DasherEditor *pDasherControl) {
162 DasherEditorPrivate *pPrivate = DASHER_EDITOR_GET_PRIVATE(pDasherControl);
164 pPrivate->pBufferSet = NULL;
165 pPrivate->pInternalBuffer = NULL;
166 pPrivate->pExternalBuffer = NULL;
167 pPrivate->szFilename = NULL;
168 pPrivate->pTextClipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
169 pPrivate->pPrimarySelection = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
170 pPrivate->pActionRing = NULL;
171 pPrivate->iNextActionID = 0;
172 // pPrivate->pGameModeHelper = NULL;
173 pPrivate->bFileModified = FALSE;
176 static void
177 dasher_editor_finalize(GObject *pObject) {
178 g_debug("Finalising DasherEditor");
180 DasherEditorPrivate *pPrivate = DASHER_EDITOR_GET_PRIVATE(pObject);
182 EditorAction *pCurrentAction = pPrivate->pActionRing;
184 if(pCurrentAction) {
185 bool bStarted = false;
187 while(!bStarted || (pCurrentAction != pPrivate->pActionRing)) {
188 bStarted = true;
189 dasher_action_deactivate(pCurrentAction->pAction);
190 g_object_unref(G_OBJECT(pCurrentAction->pAction));
191 pCurrentAction = pCurrentAction->pNext;
195 if(pPrivate->pBufferSet)
196 g_object_unref(G_OBJECT(pPrivate->pBufferSet));
198 if(pPrivate->szFilename)
199 g_free(pPrivate->szFilename);
202 void
203 dasher_editor_initialise(DasherEditor *pSelf, DasherAppSettings *pAppSettings, DasherMain *pDasherMain, GladeXML *pGladeXML, const gchar *szFullPath) {
204 if(DASHER_EDITOR_GET_CLASS(pSelf)->initialise)
205 DASHER_EDITOR_GET_CLASS(pSelf)->initialise(pSelf, pAppSettings, pDasherMain, pGladeXML, szFullPath);
208 void
209 dasher_editor_handle_stop(DasherEditor *pSelf) {
210 if(DASHER_EDITOR_GET_CLASS(pSelf)->handle_stop)
211 DASHER_EDITOR_GET_CLASS(pSelf)->handle_stop(pSelf);
214 void
215 dasher_editor_handle_start(DasherEditor *pSelf) {
216 if(DASHER_EDITOR_GET_CLASS(pSelf)->handle_start)
217 DASHER_EDITOR_GET_CLASS(pSelf)->handle_start(pSelf);
220 /* TODO: This is obsolete - sort this out when commands are reconsidered */
221 void
222 dasher_editor_handle_control(DasherEditor *pSelf, int iNodeID) {
223 if(DASHER_EDITOR_GET_CLASS(pSelf)->handle_control)
224 DASHER_EDITOR_GET_CLASS(pSelf)->handle_control(pSelf, iNodeID);
227 void
228 dasher_editor_action_button(DasherEditor *pSelf, DasherAction *pAction) {
229 if(DASHER_EDITOR_GET_CLASS(pSelf)->action_button)
230 DASHER_EDITOR_GET_CLASS(pSelf)->action_button(pSelf, pAction);
233 void
234 dasher_editor_actions_start(DasherEditor *pSelf) {
235 if(DASHER_EDITOR_GET_CLASS(pSelf)->actions_start)
236 DASHER_EDITOR_GET_CLASS(pSelf)->actions_start(pSelf);
239 bool
240 dasher_editor_actions_more(DasherEditor *pSelf) {
241 if(DASHER_EDITOR_GET_CLASS(pSelf)->actions_more)
242 return DASHER_EDITOR_GET_CLASS(pSelf)->actions_more(pSelf);
243 else
244 return false;
247 void
248 dasher_editor_actions_get_next(DasherEditor *pSelf, const gchar **szName, gint *iID, gboolean *bShow, gboolean *bControl, gboolean *bAuto) {
249 if(DASHER_EDITOR_GET_CLASS(pSelf)->actions_get_next)
250 DASHER_EDITOR_GET_CLASS(pSelf)->actions_get_next(pSelf, szName, iID, bShow, bControl, bAuto);
253 void
254 dasher_editor_action_set_show(DasherEditor *pSelf, int iActionID, bool bValue) {
255 if(DASHER_EDITOR_GET_CLASS(pSelf)->action_set_show)
256 DASHER_EDITOR_GET_CLASS(pSelf)->action_set_show(pSelf, iActionID, bValue);
259 void
260 dasher_editor_action_set_control(DasherEditor *pSelf, int iActionID, bool bValue) {
261 if(DASHER_EDITOR_GET_CLASS(pSelf)->action_set_control)
262 DASHER_EDITOR_GET_CLASS(pSelf)->action_set_control(pSelf, iActionID, bValue);
265 void
266 dasher_editor_action_set_auto(DasherEditor *pSelf, int iActionID, bool bValue) {
267 if(DASHER_EDITOR_GET_CLASS(pSelf)->action_set_auto)
268 DASHER_EDITOR_GET_CLASS(pSelf)->action_set_auto(pSelf, iActionID, bValue);
271 void
272 dasher_editor_grab_focus(DasherEditor *pSelf) {
273 if(DASHER_EDITOR_GET_CLASS(pSelf)->grab_focus)
274 DASHER_EDITOR_GET_CLASS(pSelf)->grab_focus(pSelf);
277 void
278 dasher_editor_output(DasherEditor *pSelf, const gchar *szText, int iOffset) {
279 if(DASHER_EDITOR_GET_CLASS(pSelf)->output)
280 DASHER_EDITOR_GET_CLASS(pSelf)->output(pSelf, szText, iOffset);
283 void
284 dasher_editor_delete(DasherEditor *pSelf, int iLength, int iOffset) {
285 if(DASHER_EDITOR_GET_CLASS(pSelf)->delete_text)
286 DASHER_EDITOR_GET_CLASS(pSelf)->delete_text(pSelf, iLength, iOffset);
289 void
290 dasher_editor_start_compose(DasherEditor *pSelf) {
291 if(DASHER_EDITOR_GET_CLASS(pSelf)->start_compose)
292 DASHER_EDITOR_GET_CLASS(pSelf)->start_compose(pSelf);
295 void
296 dasher_editor_end_compose(DasherEditor *pSelf, bool bKeep) {
297 if(DASHER_EDITOR_GET_CLASS(pSelf)->end_compose)
298 DASHER_EDITOR_GET_CLASS(pSelf)->end_compose(pSelf, bKeep);
302 const gchar *
303 dasher_editor_get_context(DasherEditor *pSelf, int iOffset, int iLength) {
304 if(DASHER_EDITOR_GET_CLASS(pSelf)->get_context)
305 return DASHER_EDITOR_GET_CLASS(pSelf)->get_context(pSelf, iOffset, iLength);
306 else
307 return NULL;
310 gint
311 dasher_editor_get_offset(DasherEditor *pSelf) {
312 if(DASHER_EDITOR_GET_CLASS(pSelf)->get_offset)
313 return DASHER_EDITOR_GET_CLASS(pSelf)->get_offset(pSelf);
314 else
315 return 0;
318 gboolean
319 dasher_editor_command(DasherEditor *pSelf, const gchar *szCommand) {
320 if(DASHER_EDITOR_GET_CLASS(pSelf)->command)
321 return DASHER_EDITOR_GET_CLASS(pSelf)->command(pSelf, szCommand);
322 else
323 return false;
326 gboolean
327 dasher_editor_file_changed(DasherEditor *pSelf) {
328 if(DASHER_EDITOR_GET_CLASS(pSelf)->file_changed)
329 return DASHER_EDITOR_GET_CLASS(pSelf)->file_changed(pSelf);
330 else
331 return false;
334 const gchar *
335 dasher_editor_get_filename(DasherEditor *pSelf) {
336 if(DASHER_EDITOR_GET_CLASS(pSelf)->get_filename)
337 return DASHER_EDITOR_GET_CLASS(pSelf)->get_filename(pSelf);
338 else
339 return NULL;
342 const gchar *
343 dasher_editor_get_all_text(DasherEditor *pSelf) {
344 if(DASHER_EDITOR_GET_CLASS(pSelf)->get_all_text)
345 return DASHER_EDITOR_GET_CLASS(pSelf)->get_all_text(pSelf);
346 else
347 return NULL;
350 const gchar *
351 dasher_editor_get_new_text(DasherEditor *pSelf) {
352 if(DASHER_EDITOR_GET_CLASS(pSelf)->get_new_text)
353 return DASHER_EDITOR_GET_CLASS(pSelf)->get_new_text(pSelf);
354 else
355 return NULL;
358 void
359 dasher_editor_handle_parameter_change(DasherEditor *pSelf, gint iParameter) {
360 if(DASHER_EDITOR_GET_CLASS(pSelf)->handle_parameter_change)
361 DASHER_EDITOR_GET_CLASS(pSelf)->handle_parameter_change(pSelf, iParameter);