SF.net SVN: geany: [878] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Tue Oct 10 16:02:51 UTC 2006
Revision: 878
http://svn.sourceforge.net/geany/?rev=878&view=rev
Author: eht16
Date: 2006-10-10 09:02:41 -0700 (Tue, 10 Oct 2006)
Log Message:
-----------
Finished new Undo system. Now some more actions can be undone and also redone.
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/callbacks.c
trunk/src/document.c
trunk/src/document.h
trunk/src/sci_cb.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-10-10 14:27:58 UTC (rev 877)
+++ trunk/ChangeLog 2006-10-10 16:02:41 UTC (rev 878)
@@ -1,6 +1,13 @@
2006-10-10 Enrico Tröger <enrico.troeger at uvena.de>
* src/document.c: Connect only once to the "sci-notify" signal.
+ * scintilla/CellBuffer.cxx, scintilla/Document.cxx,
+ scintilla/include/Scintilla.h:
+ Applied patch from Armel Asselin (thanks). It adds SC_START_ACTION
+ notification which is required for Geany's new Undo system.
+ * src/document.c, src/sci_cb.c, src/callbacks.c:
+ Finished new Undo system. Now some more actions can be undone and
+ also redone.
2006-10-09 Nick Treleaven <nick.treleaven at btinternet.com>
Modified: trunk/src/callbacks.c
===================================================================
--- trunk/src/callbacks.c 2006-10-10 14:27:58 UTC (rev 877)
+++ trunk/src/callbacks.c 2006-10-10 16:02:41 UTC (rev 878)
@@ -2432,15 +2432,12 @@
gint idx = document_get_cur_idx();
guint i = GPOINTER_TO_INT(user_data);
- if (app->ignore_callback || idx < 0 || encodings[i].charset == NULL ||
+ if (app->ignore_callback || ! DOC_IDX_VALID(idx) || encodings[i].charset == NULL ||
utils_strcmp(encodings[i].charset, doc_list[idx].encoding)) return;
- // old charset string will be freed with the undo buffer
- document_undo_add(idx, UNDO_ENCODING, doc_list[idx].encoding);
- doc_list[idx].encoding = g_strdup(encodings[i].charset);
- ui_update_statusbar(idx, -1);
- gtk_widget_set_sensitive(lookup_widget(app->window, "menu_write_unicode_bom1"),
- utils_is_unicode_charset(doc_list[idx].encoding));
+ document_undo_add(idx, UNDO_ENCODING, g_strdup(doc_list[idx].encoding));
+
+ document_set_encoding(idx, encodings[i].charset);
}
@@ -2492,9 +2489,10 @@
if (idx == -1 || ! doc_list[idx].is_valid) return;
+ document_undo_add(idx, UNDO_BOM, GINT_TO_POINTER(doc_list[idx].has_bom));
+
doc_list[idx].has_bom = ! doc_list[idx].has_bom;
- document_undo_add(idx, UNDO_BOM, GINT_TO_POINTER(! doc_list[idx].has_bom));
ui_update_statusbar(idx, -1);
}
}
Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c 2006-10-10 14:27:58 UTC (rev 877)
+++ trunk/src/document.c 2006-10-10 16:02:41 UTC (rev 878)
@@ -68,7 +68,11 @@
document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text,
gint flags, gint start, gint end, gboolean escaped_chars);
+static void document_undo_clear(gint idx);
+static void document_redo_add(gint idx, guint type, gpointer data);
+
+
/* returns the index of the notebook page which has the given filename
* is_tm_filename is needed when passing TagManager filenames because they are
* dereferenced, and would not match the link filename. */
@@ -362,7 +366,6 @@
doc_list[idx].has_bom = FALSE;
doc_list[idx].tm_file = NULL;
document_undo_clear(idx);
- document_redo_clear(idx);
if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) == 0)
{
ui_update_tag_list(-1, FALSE);
@@ -388,10 +391,19 @@
g_assert(idx != -1);
+ sci_set_undo_collection(doc_list[idx].sci, FALSE); // avoid creation of an undo action
sci_clear_all(doc_list[idx].sci);
sci_set_text(doc_list[idx].sci, template);
g_free(template);
+#ifdef G_OS_WIN32
+ sci_set_eol_mode(doc_list[idx].sci, SC_EOL_CRLF);
+#else
+ sci_set_eol_mode(doc_list[idx].sci, SC_EOL_LF);
+#endif
+ sci_set_undo_collection(doc_list[idx].sci, TRUE);
+ sci_empty_undo_buffer(doc_list[idx].sci);
+
doc_list[idx].encoding = g_strdup(encodings[app->pref_editor_default_encoding].charset);
//document_set_filetype(idx, (ft == NULL) ? filetypes[GEANY_FILETYPES_ALL] : ft);
document_set_filetype(idx, ft); // also clears taglist
@@ -402,13 +414,8 @@
doc_list[idx].changed = FALSE;
document_set_text_changed(idx);
ui_document_show_hide(idx); //update the document menu
-#ifdef G_OS_WIN32
- sci_set_eol_mode(doc_list[idx].sci, SC_EOL_CRLF);
-#else
- sci_set_eol_mode(doc_list[idx].sci, SC_EOL_LF);
-#endif
+
sci_set_line_numbers(doc_list[idx].sci, app->show_linenumber_margin, 0);
- sci_empty_undo_buffer(doc_list[idx].sci);
sci_goto_pos(doc_list[idx].sci, 0, TRUE);
// "the" SCI signal (connect after initial setup(i.e. adding text))
@@ -637,15 +644,17 @@
if (idx == -1) return -1; // really should not happen
// set editor mode and add the text to the ScintillaObject
- sci_set_text(doc_list[idx].sci, data); // NULL terminated data; avoids modifying sci
+ sci_set_undo_collection(doc_list[idx].sci, FALSE); // avoid creation of an undo action
+ sci_empty_undo_buffer(doc_list[idx].sci);
+ sci_set_text(doc_list[idx].sci, data); // NULL terminated data
+
editor_mode = utils_get_line_endings(data, size);
sci_set_eol_mode(doc_list[idx].sci, editor_mode);
+ sci_set_line_numbers(doc_list[idx].sci, app->show_linenumber_margin, 0);
- sci_set_line_numbers(doc_list[idx].sci, app->show_linenumber_margin, 0);
- sci_set_savepoint(doc_list[idx].sci);
- sci_empty_undo_buffer(doc_list[idx].sci);
- // get the modification time from file and keep it
- doc_list[idx].mtime = st.st_mtime;
+ sci_set_undo_collection(doc_list[idx].sci, TRUE);
+
+ doc_list[idx].mtime = st.st_mtime; // get the modification time from file and keep it
doc_list[idx].changed = FALSE;
doc_list[idx].file_name = g_strdup(utf8_filename);
doc_list[idx].encoding = enc;
@@ -676,6 +685,7 @@
else
{ // reloading
document_update_tag_list(idx, TRUE);
+ document_undo_clear(idx);
}
document_set_text_changed(idx);
@@ -1494,11 +1504,26 @@
}
}
+
+void document_set_encoding(gint idx, const gchar *new_encoding)
+{
+ if (! DOC_IDX_VALID(idx) || new_encoding == NULL ||
+ utils_strcmp(new_encoding, doc_list[idx].encoding)) return;
+
+ g_free(doc_list[idx].encoding);
+ doc_list[idx].encoding = g_strdup(new_encoding);
+
+ ui_update_statusbar(idx, -1);
+ gtk_widget_set_sensitive(lookup_widget(app->window, "menu_write_unicode_bom1"),
+ utils_is_unicode_charset(doc_list[idx].encoding));
+}
+
+
/* own Undo / Redo implementation to be able to undo / redo changes
* to the encoding or the Unicode BOM (which are Scintilla independet).
* All Scintilla events are stored in the undo / redo buffer and are passed through. */
-/* Clears the Undo buffer (to be called after saving a file or when closing the document) */
+/* Clears the Undo and Redo buffer (to be called when reloading or closing the document) */
void document_undo_clear(gint idx)
{
undo_action *a;
@@ -1519,17 +1544,6 @@
}
doc_list[idx].undo_actions = NULL;
- doc_list[idx].changed = FALSE;
- if (! app->quitting) document_set_text_changed(idx);
-}
-
-
-/* Clears the Redo buffer (to be called after saving a file or when closing the document) */
-void document_redo_clear(gint idx)
-{
-/*
- undo_action *a;
-
while (g_trash_stack_height(&doc_list[idx].redo_actions) > 0)
{
a = g_trash_stack_pop(&doc_list[idx].redo_actions);
@@ -1548,7 +1562,9 @@
doc_list[idx].changed = FALSE;
if (! app->quitting) document_set_text_changed(idx);
-*/
+
+ //geany_debug("%s: new undo stack height: %d, new redo stack height: %d", __func__,
+ //g_trash_stack_height(&doc_list[idx].undo_actions), g_trash_stack_height(&doc_list[idx].redo_actions));
}
@@ -1556,7 +1572,7 @@
{
undo_action *action;
- if (idx == -1 || ! doc_list[idx].is_valid) return;
+ if (! DOC_IDX_VALID(idx)) return;
action = g_new0(undo_action, 1);
action->type = type;
@@ -1568,19 +1584,15 @@
document_set_text_changed(idx);
ui_update_popup_reundo_items(idx);
- {
- geany_debug("%s: new stack height: %d, added type: %d", __func__,
- g_trash_stack_height(&doc_list[idx].undo_actions), action->type);
- }
+ //geany_debug("%s: new stack height: %d, added type: %d", __func__,
+ //g_trash_stack_height(&doc_list[idx].undo_actions), action->type);
}
gboolean document_can_undo(gint idx)
{
- return sci_can_undo(doc_list[idx].sci);
+ if (! DOC_IDX_VALID(idx)) return FALSE;
- if (idx == -1 || ! doc_list[idx].is_valid) return FALSE;
-
if (g_trash_stack_height(&doc_list[idx].undo_actions) > 0 || sci_can_undo(doc_list[idx].sci))
return TRUE;
else
@@ -1588,31 +1600,96 @@
}
+void document_undo(gint idx)
+{
+ undo_action *action;
+
+ if (! DOC_IDX_VALID(idx)) return;
+
+ action = g_trash_stack_pop(&doc_list[idx].undo_actions);
+
+ if (action == NULL)
+ {
+ // fallback, should not be necessary
+ geany_debug("%s: fallback used", __func__);
+ sci_undo(doc_list[idx].sci);
+ }
+ else
+ {
+ switch (action->type)
+ {
+ case UNDO_SCINTILLA:
+ {
+ document_redo_add(idx, UNDO_SCINTILLA, NULL);
+
+ sci_undo(doc_list[idx].sci);
+ break;
+ }
+ case UNDO_BOM:
+ {
+ document_redo_add(idx, UNDO_BOM, GINT_TO_POINTER(doc_list[idx].has_bom));
+
+ doc_list[idx].has_bom = GPOINTER_TO_INT(action->data);
+ ui_update_statusbar(idx, -1);
+ ui_document_show_hide(idx);
+ break;
+ }
+ case UNDO_ENCODING:
+ {
+ // use the "old" encoding
+ document_redo_add(idx, UNDO_ENCODING, g_strdup(doc_list[idx].encoding));
+
+ document_set_encoding(idx, (const gchar*)action->data);
+
+ app->ignore_callback = TRUE;
+ encodings_select_radio_item((const gchar*)action->data);
+ app->ignore_callback = FALSE;
+
+ g_free(action->data);
+ break;
+ }
+ default: break;
+ }
+ }
+ g_free(action); // free the action which was taken from the stack
+
+ if (g_trash_stack_height(&doc_list[idx].undo_actions) == 0)
+ {
+ doc_list[idx].changed = FALSE;
+ document_set_text_changed(idx);
+ }
+ else
+ doc_list[idx].changed = TRUE;
+
+ ui_update_popup_reundo_items(idx);
+ //geany_debug("%s: new stack height: %d", __func__, g_trash_stack_height(&doc_list[idx].undo_actions));
+}
+
+
gboolean document_can_redo(gint idx)
{
- if (idx == -1 || ! doc_list[idx].is_valid) return FALSE;
+ if (! DOC_IDX_VALID(idx)) return FALSE;
- return sci_can_redo(doc_list[idx].sci);
+ if (g_trash_stack_height(&doc_list[idx].redo_actions) > 0 || sci_can_redo(doc_list[idx].sci))
+ return TRUE;
+ else
+ return FALSE;
}
-void document_undo(gint idx)
+void document_redo(gint idx)
{
undo_action *action;
-#if 1
- sci_undo(doc_list[idx].sci);
- return;
-#endif
+ if (! DOC_IDX_VALID(idx)) return;
- if (idx == -1 || ! doc_list[idx].is_valid) return;
+ action = g_trash_stack_pop(&doc_list[idx].redo_actions);
- action = g_trash_stack_pop(&doc_list[idx].undo_actions);
-
if (action == NULL)
{
// fallback, should not be necessary
- sci_undo(doc_list[idx].sci);
+ geany_debug("%s: fallback used", __func__);
+ sci_redo(doc_list[idx].sci);
}
else
{
@@ -1620,13 +1697,15 @@
{
case UNDO_SCINTILLA:
{
- geany_debug("undo: Scintilla");
- sci_undo(doc_list[idx].sci);
+ document_undo_add(idx, UNDO_SCINTILLA, NULL);
+
+ sci_redo(doc_list[idx].sci);
break;
}
case UNDO_BOM:
{
- geany_debug("undo: BOM");
+ document_undo_add(idx, UNDO_BOM, GINT_TO_POINTER(doc_list[idx].has_bom));
+
doc_list[idx].has_bom = GPOINTER_TO_INT(action->data);
ui_update_statusbar(idx, -1);
ui_document_show_hide(idx);
@@ -1634,28 +1713,46 @@
}
case UNDO_ENCODING:
{
- geany_debug("undo: Encoding");
- doc_list[idx].encoding = (gchar*) action->data;
- ui_update_statusbar(idx, -1);
- encodings_select_radio_item(doc_list[idx].encoding);
- gtk_widget_set_sensitive(lookup_widget(app->window, "menu_write_unicode_bom1"),
- utils_is_unicode_charset(doc_list[idx].encoding));
+ document_undo_add(idx, UNDO_ENCODING, g_strdup(doc_list[idx].encoding));
+
+ document_set_encoding(idx, (const gchar*)action->data);
+
+ app->ignore_callback = TRUE;
+ encodings_select_radio_item((const gchar*)action->data);
+ app->ignore_callback = FALSE;
+
+ g_free(action->data);
break;
}
default: break;
}
}
+ g_free(action); // free the action which was taken from the stack
- if (g_trash_stack_height(&doc_list[idx].undo_actions) == 0) doc_list[idx].changed = FALSE;
ui_update_popup_reundo_items(idx);
- geany_debug("%s: new stack height: %d", __func__, g_trash_stack_height(&doc_list[idx].undo_actions));
+ //geany_debug("%s: new stack height: %d", __func__, g_trash_stack_height(&doc_list[idx].redo_actions));
}
-void document_redo(gint idx)
+static void document_redo_add(gint idx, guint type, gpointer data)
{
- if (idx == -1 || ! doc_list[idx].is_valid) return;
+ undo_action *action;
- sci_redo(doc_list[idx].sci);
+ if (! DOC_IDX_VALID(idx)) return;
+
+ action = g_new0(undo_action, 1);
+ action->type = type;
+ action->data = data;
+
+ g_trash_stack_push(&doc_list[idx].redo_actions, action);
+
+ doc_list[idx].changed = TRUE;
+ document_set_text_changed(idx);
+ ui_update_popup_reundo_items(idx);
+
+ //geany_debug("%s: new stack height: %d, added type: %d", __func__,
+ //g_trash_stack_height(&doc_list[idx].redo_actions), action->type);
}
+
+
Modified: trunk/src/document.h
===================================================================
--- trunk/src/document.h 2006-10-10 14:27:58 UTC (rev 877)
+++ trunk/src/document.h 2006-10-10 16:02:41 UTC (rev 878)
@@ -175,11 +175,14 @@
void document_ensure_final_newline(gint idx);
+void document_set_encoding(gint idx, const gchar *new_encoding);
/* own Undo / Redo implementation to be able to undo / redo changes
* to the encoding or the Unicode BOM (which are Scintilla independet).
* All Scintilla events are stored in the undo / redo buffer and are passed through. */
+
+// available UNDO actions, UNDO_SCINTILLA is a pseudo action to trigger Scintilla's undo management
enum
{
UNDO_SCINTILLA = 0,
@@ -188,11 +191,13 @@
UNDO_ACTIONS_MAX
};
+// an undo action, also used for redo actions
typedef struct
{
- GTrashStack *next;
- guint type; // to identify the action
- gpointer *data; // the old value (before the change)
+ GTrashStack *next; // pointer to the next stack element(required for the GTrashStack)
+ guint type; // to identify the action
+ gpointer *data; // the old value (before the change), in case of a redo action it contains
+ // the new value
} undo_action;
gboolean document_can_undo(gint idx);
@@ -205,8 +210,4 @@
void document_undo_add(gint idx, guint type, gpointer data);
-void document_undo_clear(gint idx);
-
-void document_redo_clear(gint idx);
-
#endif
Modified: trunk/src/sci_cb.c
===================================================================
--- trunk/src/sci_cb.c 2006-10-10 14:27:58 UTC (rev 877)
+++ trunk/src/sci_cb.c 2006-10-10 16:02:41 UTC (rev 878)
@@ -153,26 +153,16 @@
#endif
break;
}
- case 2023:
+ case SCN_MODIFIED:
{
- geany_debug("Undo notification");
- break;
- }
-/* case SCN_KEY:
- {
- //geany_debug("key notification triggered with %c", nt->ch);
- break;
- }
- case SCN_MODIFIED:
- {
- if (nt->modificationType & SC_MOD_INSERTTEXT ||
- nt->modificationType & SC_MOD_DELETETEXT)
+ if (nt->modificationType & SC_START_ACTION && ! app->ignore_callback)
{
+ // get notified about undo changes
document_undo_add(idx, UNDO_SCINTILLA, NULL);
}
break;
}
-*/ case SCN_CHARADDED:
+ case SCN_CHARADDED:
{
gint pos = sci_get_current_position(sci);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list