Revision: 1270 http://svn.sourceforge.net/geany/?rev=1270&view=rev Author: eht16 Date: 2007-02-12 10:42:15 -0800 (Mon, 12 Feb 2007)
Log Message: ----------- Ensure the VTE visual settings are applied when switching to VTE when the Message Window is hidden. Fixed several issues while opening files and improved code. Improved the auto scrolling of documents and fixed a bug when opening files remotely.
Modified Paths: -------------- branches/geany-0.10.1/NEWS branches/geany-0.10.1/src/callbacks.c branches/geany-0.10.1/src/dialogs.c branches/geany-0.10.1/src/document.c branches/geany-0.10.1/src/document.h branches/geany-0.10.1/src/encodings.c branches/geany-0.10.1/src/encodings.h branches/geany-0.10.1/src/keybindings.c branches/geany-0.10.1/src/keyfile.c branches/geany-0.10.1/src/sci_cb.c branches/geany-0.10.1/src/sciwrappers.c branches/geany-0.10.1/src/sciwrappers.h branches/geany-0.10.1/src/socket.c branches/geany-0.10.1/src/ui_utils.c branches/geany-0.10.1/src/utils.c branches/geany-0.10.1/src/utils.h branches/geany-0.10.1/tagmanager/latex.c
Modified: branches/geany-0.10.1/NEWS =================================================================== --- branches/geany-0.10.1/NEWS 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/NEWS 2007-02-12 18:42:15 UTC (rev 1270) @@ -22,8 +22,12 @@ * Change default keybinding for Close All to Ctrl-Shift-W. * Allow Make for files with no extension - prevent Build when the output filename would be the same as the source file. + * Ensure the VTE visual settings are applied when switching to VTE + when the Message Window is hidden. + * Fixed several issues while opening files and improved code. + * Improved the auto scrolling of documents and fixed a bug when + opening files remotely.
- Internationalisation: * New translations: fi (thanks to Harri Koskinen). * Updated translations: de, es.
Modified: branches/geany-0.10.1/src/callbacks.c =================================================================== --- branches/geany-0.10.1/src/callbacks.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/callbacks.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -2002,10 +2002,10 @@ line = sci_get_current_line(doc_list[idx].sci, old_pos); ind_pos = sci_get_line_indent_position(doc_list[idx].sci, line);
- sci_set_current_position(doc_list[idx].sci, ind_pos); + sci_set_current_position(doc_list[idx].sci, ind_pos, TRUE); sci_cmd(doc_list[idx].sci, SCI_TAB); sci_set_current_position(doc_list[idx].sci, - (old_pos > ind_pos) ? old_pos + 1 : old_pos); + (old_pos > ind_pos) ? old_pos + 1 : old_pos, TRUE); } }
@@ -2031,10 +2031,10 @@
if (ind_pos == sci_get_position_from_line(doc_list[idx].sci, line)) return; - sci_set_current_position(doc_list[idx].sci, ind_pos); + sci_set_current_position(doc_list[idx].sci, ind_pos, TRUE); sci_cmd(doc_list[idx].sci, SCI_BACKTAB); sci_set_current_position(doc_list[idx].sci, - (old_pos >= ind_pos) ? old_pos - 1 : old_pos); + (old_pos >= ind_pos) ? old_pos - 1 : old_pos, TRUE); } }
Modified: branches/geany-0.10.1/src/dialogs.c =================================================================== --- branches/geany-0.10.1/src/dialogs.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/dialogs.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -1016,8 +1016,9 @@ gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
enctext = g_strdup_printf("%s %s", - doc_list[idx].encoding, - (utils_is_unicode_charset(doc_list[idx].encoding)) ? ((doc_list[idx].has_bom) ? _("(with BOM)") : _("(without BOM)")) : ""); + doc_list[idx].encoding, + (encodings_is_unicode_charset(doc_list[idx].encoding)) ? + ((doc_list[idx].has_bom) ? _("(with BOM)") : _("(without BOM)")) : "");
label = gtk_label_new(enctext); g_free(enctext);
Modified: branches/geany-0.10.1/src/document.c =================================================================== --- branches/geany-0.10.1/src/document.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/document.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * document.c - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -207,6 +208,7 @@ new_doc->sci = NULL; new_doc->undo_actions = NULL; new_doc->redo_actions = NULL; + new_doc->scroll_percent = -1.0F; }
@@ -348,6 +350,7 @@ doc_list[idx].encoding = NULL; doc_list[idx].has_bom = FALSE; doc_list[idx].tm_file = NULL; + doc_list[idx].scroll_percent = -1.0F; document_undo_clear(idx); if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) == 0) { @@ -421,113 +424,236 @@ }
+typedef struct +{ + gchar *data; // null-terminated file data + gsize len; // string length of data + gchar *enc; + gboolean bom; + time_t mtime; // modification time, read by stat::st_mtime + gboolean readonly; +} FileData; + + // reload file with specified encoding static gboolean -handle_forced_encoding(gchar **data, gsize *size, const gchar *forced_enc, gchar **enc, - gboolean *bom) +handle_forced_encoding(FileData *filedata, const gchar *forced_enc) { + GeanyEncodingIndex enc_idx; + if (utils_str_equal(forced_enc, "UTF-8")) { - if (! g_utf8_validate(*data, *size, NULL)) + if (! g_utf8_validate(filedata->data, filedata->len, NULL)) { return FALSE; } - else - { - *bom = utils_str_equal(utils_scan_unicode_bom(*data), "UTF-8"); - *enc = g_strdup(forced_enc); - } } else { gchar *converted_text = encodings_convert_to_utf8_from_charset( - *data, *size, forced_enc, FALSE); + filedata->data, filedata->len, forced_enc, FALSE); if (converted_text == NULL) { return FALSE; } else { - g_free(*data); - *data = (void*)converted_text; - *size = strlen(converted_text); - *bom = utils_str_equal(utils_scan_unicode_bom(*data), "UTF-8"); - *enc = g_strdup(forced_enc); + g_free(filedata->data); + filedata->data = converted_text; + filedata->len = strlen(converted_text); } } + enc_idx = encodings_scan_unicode_bom(filedata->data, filedata->len, NULL); + filedata->bom = (enc_idx == GEANY_ENCODING_UTF_8); + filedata->enc = g_strdup(forced_enc); return TRUE; }
+// detect encoding and convert to UTF-8 if necessary static gboolean -handle_encoding(gchar **data, gsize *size, gchar **enc, gboolean *bom) +handle_encoding(FileData *filedata) { - if (*size > 0) - { // the usual way to detect encoding and convert to UTF-8 - if (*size >= 4) + g_return_val_if_fail(filedata->enc == NULL, FALSE); + g_return_val_if_fail(filedata->bom == FALSE, FALSE); + + if (filedata->len == 0) + { + // we have no data so assume UTF-8 + filedata->enc = g_strdup("UTF-8"); + } + else + { + // first check for a BOM + GeanyEncodingIndex enc_idx = + encodings_scan_unicode_bom(filedata->data, filedata->len, NULL); + + if (enc_idx != GEANY_ENCODING_NONE) { - *enc = utils_scan_unicode_bom(*data); - } - if (*enc != NULL) - { - *bom = TRUE; - if ((*enc)[4] != '8') // the BOM indicated something else than UTF-8 + filedata->enc = g_strdup(encodings[enc_idx].charset); + filedata->bom = TRUE; + + if (enc_idx != GEANY_ENCODING_UTF_8) // the BOM indicated something else than UTF-8 { gchar *converted_text = encodings_convert_to_utf8_from_charset( - *data, *size, *enc, FALSE); - if (converted_text == NULL) + filedata->data, filedata->len, filedata->enc, FALSE); + if (converted_text != NULL) { - g_free(*enc); - *enc = NULL; - *bom = FALSE; + g_free(filedata->data); + filedata->data = converted_text; + filedata->len = strlen(converted_text); } else { - g_free(*data); - *data = (void*)converted_text; - *size = strlen(converted_text); + // there was a problem converting data from BOM encoding type + g_free(filedata->enc); + filedata->enc = NULL; + filedata->bom = FALSE; } } } - // this if is important, else doesn't work because enc can be altered in the above block - if (*enc == NULL) + + if (filedata->enc == NULL) // either there was no BOM or the BOM encoding failed { - if (g_utf8_validate(*data, *size, NULL)) + // try UTF-8 first + if (g_utf8_validate(filedata->data, filedata->len, NULL)) { - *enc = g_strdup("UTF-8"); + filedata->enc = g_strdup("UTF-8"); } else { - gchar *converted_text = encodings_convert_to_utf8(*data, *size, enc); + // detect the encoding + gchar *converted_text = encodings_convert_to_utf8(filedata->data, + filedata->len, &filedata->enc);
if (converted_text == NULL) { return FALSE; } - else - { - g_free(*data); - *data = (void*)converted_text; - *size = strlen(converted_text); - } + g_free(filedata->data); + filedata->data = converted_text; + filedata->len = strlen(converted_text); } } } - else + return TRUE; +} + + +static void +handle_bom(FileData *filedata) +{ + guint bom_len; + + encodings_scan_unicode_bom(filedata->data, filedata->len, &bom_len); + g_return_if_fail(bom_len != 0); + + filedata->len -= bom_len; + // overwrite the BOM with the remainder of the file contents, plus the NULL terminator. + g_memmove(filedata->data, filedata->data + bom_len, filedata->len + 1); + filedata->data = g_realloc(filedata->data, filedata->len + 1); +} + + +/* loads textfile data, verifies and converts to forced_enc or UTF-8. Also handles BOM. */ +static gboolean load_text_file(const gchar *locale_filename, const gchar *utf8_filename, + FileData *filedata, const gchar *forced_enc) +{ + GError *err = NULL; + struct stat st; + + filedata->data = NULL; + filedata->len = 0; + filedata->enc = NULL; + filedata->bom = FALSE; + filedata->readonly = FALSE; + + if (stat(locale_filename, &st) != 0) { - *enc = g_strdup("UTF-8"); + msgwin_status_add(_("Could not open file %s (%s)"), utf8_filename, g_strerror(errno)); + return FALSE; } + + filedata->mtime = st.st_mtime; + +#ifdef G_OS_WIN32 + if (! g_file_get_contents(utf8_filename, &filedata->data, NULL, &err)) +#else + if (! g_file_get_contents(locale_filename, &filedata->data, NULL, &err)) +#endif + { + msgwin_status_add(err->message); + g_error_free(err); + return FALSE; + } + + // use strlen to check for null chars + filedata->len = strlen(filedata->data); + + /* check whether the size of the loaded data is equal to the size of the file in the filesystem */ + if (filedata->len != (gsize) st.st_size) + { + gchar *warn_msg = _("The file "%s" could not be opened properly and has been truncated. " + "This can occur if the file contains a NULL byte. " + "Be aware that saving it can cause data loss.\nThe file was set to read-only."); + + if (app->main_window_realized) + dialogs_show_msgbox(GTK_MESSAGE_WARNING, warn_msg, utf8_filename); + + msgwin_status_add(warn_msg, utf8_filename); + + // set the file to read-only mode because saving it is probably dangerous + filedata->readonly = TRUE; + } + + /* Determine character encoding and convert to UTF-8 */ + if (forced_enc != NULL) + { + // the encoding should be ignored(requested by user), so open the file "as it is" + if (utils_str_equal(forced_enc, encodings[GEANY_ENCODING_NONE].charset)) + { + filedata->bom = FALSE; + filedata->enc = g_strdup(encodings[GEANY_ENCODING_NONE].charset); + } + else if (! handle_forced_encoding(filedata, forced_enc)) + { + msgwin_status_add(_("The file "%s" is not valid %s."), utf8_filename, forced_enc); + utils_beep(); + g_free(filedata->data); + return FALSE; + } + } + else if (! handle_encoding(filedata)) + { + msgwin_status_add( + _("The file "%s" does not look like a text file or the file encoding is not supported."), + utf8_filename); + utils_beep(); + g_free(filedata->data); + return FALSE; + } + + if (filedata->bom) + handle_bom(filedata); return TRUE; }
-static void -handle_bom(gchar **data) +/* Sets the cursor position on opening a file. First it sets the line when cl_options.goto_line + * is set, otherwise it sets the line when pos is greater than zero. */ +static void set_cursor_position(gint idx, gint pos) { - gchar *data_without_bom; - data_without_bom = g_strdup(*data + 3); - g_free(*data); - *data = data_without_bom; + if (cl_options.goto_line >= 0) + { // goto line which was specified on command line and then undefine the line + sci_goto_line(doc_list[idx].sci, cl_options.goto_line - 1, TRUE); + doc_list[idx].scroll_percent = 0.5F; + cl_options.goto_line = -1; + } + else if (pos > 0) + { + sci_set_current_position(doc_list[idx].sci, pos, FALSE); + doc_list[idx].scroll_percent = 0.5F; + } }
@@ -541,16 +667,11 @@ const gchar *forced_enc) { gint editor_mode; - gsize size; gboolean reload = (idx == -1) ? FALSE : TRUE; - struct stat st; - gboolean bom = FALSE; - gchar *enc = NULL; gchar *utf8_filename = NULL; gchar *locale_filename = NULL; - GError *err = NULL; - gchar *data = NULL; filetype *use_ft; + FileData filedata;
//struct timeval tv, tv1; //struct timezone tz; @@ -585,120 +706,52 @@ g_free(utf8_filename); g_free(locale_filename); utils_check_disk_status(idx, TRUE); // force a file changed check + set_cursor_position(idx, pos); return idx; } }
- if (stat(locale_filename, &st) != 0) + if (! load_text_file(locale_filename, utf8_filename, &filedata, forced_enc)) { - msgwin_status_add(_("Could not open file %s (%s)"), utf8_filename, g_strerror(errno)); g_free(utf8_filename); g_free(locale_filename); return -1; }
-#ifdef G_OS_WIN32 - if (! g_file_get_contents(utf8_filename, &data, NULL, &err)) -#else - if (! g_file_get_contents(locale_filename, &data, NULL, &err)) -#endif - { - msgwin_status_add(err->message); - g_error_free(err); - g_free(utf8_filename); - g_free(locale_filename); - return -1; - } - - /* check whether the size of the loaded data is equal to the size of the file in the filesystem */ - //size = strlen(data); - size = strlen(data); - if (size != (gsize) st.st_size) - { - gchar *warn_msg = _("The file "%s" could not opened properly and probably was truncated. " - "Be aware that saving it can cause data loss.\nThe file was set to read-only."); - - if (app->main_window_realized) - dialogs_show_msgbox(GTK_MESSAGE_WARNING, warn_msg, utf8_filename); - - msgwin_status_add(warn_msg, utf8_filename); - - // set the file to read-only mode because saving it is probably dangerous - readonly = TRUE; - } - - /* Determine character encoding and convert to UTF-8 */ - if (forced_enc != NULL) - { - // the encoding should be ignored(requested by user), so open the file "as it is" - if (utils_str_equal(forced_enc, encodings[GEANY_ENCODING_NONE].charset)) - { - bom = FALSE; - enc = g_strdup(encodings[GEANY_ENCODING_NONE].charset); - } - else if (! handle_forced_encoding(&data, &size, forced_enc, &enc, &bom)) - { - msgwin_status_add(_("The file "%s" is not valid %s."), utf8_filename, forced_enc); - utils_beep(); - g_free(data); - g_free(utf8_filename); - g_free(locale_filename); - return -1; - } - } - else if (! handle_encoding(&data, &size, &enc, &bom)) - { - msgwin_status_add( - _("The file "%s" does not look like a text file or the file encoding is not supported."), - utf8_filename); - utils_beep(); - g_free(data); - g_free(utf8_filename); - g_free(locale_filename); - return -1; - } - - if (bom) handle_bom(&data); - if (! reload) idx = document_create_new_sci(utf8_filename); - if (idx == -1) return -1; // really should not happen + g_return_val_if_fail(idx != -1, -1); // really should not happen
- // set editor mode and add the text to the ScintillaObject 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); + // add the text to the ScintillaObject + sci_set_text(doc_list[idx].sci, filedata.data); // NULL terminated data + + // detect & set line endings + editor_mode = utils_get_line_endings(filedata.data, filedata.len); sci_set_eol_mode(doc_list[idx].sci, editor_mode); - sci_set_line_numbers(doc_list[idx].sci, app->show_linenumber_margin, 0); + g_free(filedata.data);
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].mtime = filedata.mtime; // get the modification time from file and keep it doc_list[idx].changed = FALSE; g_free(doc_list[idx].encoding); // if reloading, free old encoding - doc_list[idx].encoding = enc; - doc_list[idx].has_bom = bom; + doc_list[idx].encoding = filedata.enc; + doc_list[idx].has_bom = filedata.bom; store_saved_encoding(idx); // store the opened encoding for undo/redo
- if (cl_options.goto_line >= 0) - { // goto line which was specified on command line and then undefine the line - sci_goto_line(doc_list[idx].sci, cl_options.goto_line - 1, TRUE); - sci_scroll_to_line(doc_list[idx].sci, -1, 0.5); - cl_options.goto_line = -1; - } - else if (pos >= 0) - { - sci_goto_pos(doc_list[idx].sci, pos, FALSE); - if (reload) - sci_scroll_to_line(doc_list[idx].sci, -1, 0.5); - } + doc_list[idx].readonly = readonly || filedata.readonly; + sci_set_readonly(doc_list[idx].sci, doc_list[idx].readonly);
+ // update line number margin width + sci_set_line_numbers(doc_list[idx].sci, app->show_linenumber_margin, 0); + + // set the cursor position according to pos, cl_options.goto_line and cl_options.goto_column + set_cursor_position(idx, pos); + if (! reload) { - doc_list[idx].readonly = readonly; - sci_set_readonly(doc_list[idx].sci, readonly); - // "the" SCI signal (connect after initial setup(i.e. adding text)) g_signal_connect((GtkWidget*) doc_list[idx].sci, "sci-notify", G_CALLBACK(on_editor_notification), GINT_TO_POINTER(idx)); @@ -716,9 +769,7 @@ document_set_text_changed(idx); // also updates tab state ui_document_show_hide(idx); // update the document menu
- g_free(data);
- // finally add current file to recent files menu, but not the files from the last session if (! app->opening_session_files) ui_add_recent_file(utf8_filename);
@@ -840,7 +891,7 @@ sci_convert_eols(doc_list[idx].sci, sci_get_eol_mode(doc_list[idx].sci));
len = sci_get_length(doc_list[idx].sci) + 1; - if (doc_list[idx].has_bom && utils_is_unicode_charset(doc_list[idx].encoding)) + if (doc_list[idx].has_bom && encodings_is_unicode_charset(doc_list[idx].encoding)) { data = (gchar*) g_malloc(len + 3); // 3 chars for BOM data[0] = 0xef; @@ -979,7 +1030,7 @@ { sci_set_selection_start(doc_list[idx].sci, ttf.chrgText.cpMin); sci_set_selection_end(doc_list[idx].sci, ttf.chrgText.cpMax); - sci_scroll_to_line(doc_list[idx].sci, -1, 0.3); + doc_list[idx].scroll_percent = 0.3F; } else { @@ -1027,7 +1078,7 @@ if (search_pos != -1) { if (scroll) - sci_scroll_to_line(doc_list[idx].sci, -1, 0.3); + doc_list[idx].scroll_percent = 0.3F; } else { @@ -1611,7 +1662,7 @@
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)); + encodings_is_unicode_charset(doc_list[idx].encoding)); }
Modified: branches/geany-0.10.1/src/document.h =================================================================== --- branches/geany-0.10.1/src/document.h 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/document.h 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * document.h - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,6 +64,7 @@ gboolean changed; gboolean line_breaking; gboolean use_auto_indention; + gfloat scroll_percent; // % to scroll view by on paint, if positive. time_t last_check; // to remember the last disk check time_t mtime; GTrashStack *undo_actions;
Modified: branches/geany-0.10.1/src/encodings.c =================================================================== --- branches/geany-0.10.1/src/encodings.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/encodings.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * encodings.c - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,12 +40,12 @@
-#define fill(v, w, x, y, z) \ - encodings[x].idx = x; \ - encodings[x].order = v; \ - encodings[x].group = w; \ - encodings[x].charset = y; \ - encodings[x].name = z; +#define fill(Order, Group, Idx, Charset, Name) \ + encodings[Idx].idx = Idx; \ + encodings[Idx].order = Order; \ + encodings[Idx].group = Group; \ + encodings[Idx].charset = Charset; \ + encodings[Idx].name = Name;
static void init_encodings(void) { @@ -377,3 +378,71 @@
return NULL; } + + +/* If there's a BOM, return a corresponding GEANY_ENCODING_UTF_* index, + * otherwise GEANY_ENCODING_NONE. + * */ +GeanyEncodingIndex encodings_scan_unicode_bom(const gchar *string, gsize len, guint *bom_len) +{ + if (len >= 3) + { + if (bom_len) + *bom_len = 3; + + if ((guchar)string[0] == 0xef && (guchar)string[1] == 0xbb && + (guchar)string[2] == 0xbf) + { + return GEANY_ENCODING_UTF_8; + } + } + if (len >= 4) + { + if (bom_len) + *bom_len = 4; + + if ((guchar)string[0] == 0x00 && (guchar)string[1] == 0x00 && + (guchar)string[2] == 0xfe && (guchar)string[3] == 0xff) + { + return GEANY_ENCODING_UTF_32BE; // Big endian + } + if ((guchar)string[0] == 0xff && (guchar)string[1] == 0xfe && + (guchar)string[2] == 0x00 && (guchar)string[3] == 0x00) + { + return GEANY_ENCODING_UTF_32LE; // Little endian + } + if ((string[0] == 0x2b && string[1] == 0x2f && string[2] == 0x76) && + (string[3] == 0x38 || string[3] == 0x39 || string[3] == 0x2b || string[3] == 0x2f)) + { + return GEANY_ENCODING_UTF_7; + } + } + if (len >= 2) + { + if (bom_len) + *bom_len = 2; + + if ((guchar)string[0]==0xfe && (guchar)string[1] == 0xff) + { + return GEANY_ENCODING_UTF_16BE; // Big endian + } + if ((guchar)string[0] == 0xff && (guchar)string[1] == 0xfe) + { + return GEANY_ENCODING_UTF_16LE; // Little endian + } + } + if (bom_len) + *bom_len = 0; + return GEANY_ENCODING_NONE; +} + + +gboolean encodings_is_unicode_charset(const gchar *string) +{ + if (string != NULL && (strncmp(string, "UTF", 3) == 0 || strncmp(string, "UCS", 3) == 0)) + { + return TRUE; + } + return FALSE; +} +
Modified: branches/geany-0.10.1/src/encodings.h =================================================================== --- branches/geany-0.10.1/src/encodings.h 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/encodings.h 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * encodings.h - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,7 +75,9 @@ gchar *encodings_convert_to_utf8_from_charset(const gchar *buffer, gsize size, const gchar *charset, gboolean fast);
+gboolean encodings_is_unicode_charset(const gchar *string);
+ /* * The original versions of the following tables are taken from profterm * @@ -152,7 +155,7 @@ GEANY_ENCODING_WINDOWS_1256, GEANY_ENCODING_WINDOWS_1257, GEANY_ENCODING_WINDOWS_1258, - + GEANY_ENCODING_NONE,
GEANY_ENCODINGS_MAX @@ -161,4 +164,7 @@
GeanyEncoding encodings[GEANY_ENCODINGS_MAX];
+ +GeanyEncodingIndex encodings_scan_unicode_bom(const gchar *string, gsize len, guint *bom_len); + #endif
Modified: branches/geany-0.10.1/src/keybindings.c =================================================================== --- branches/geany-0.10.1/src/keybindings.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/keybindings.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -689,12 +689,16 @@ static void cb_func_switch_scribble(G_GNUC_UNUSED guint key_id) { gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_SCRATCH); + msgwin_show_hide(TRUE); gtk_widget_grab_focus(lookup_widget(app->window, "textview_scribble")); }
static void cb_func_switch_vte(G_GNUC_UNUSED guint key_id) { #ifdef HAVE_VTE + msgwin_show_hide(TRUE); + /* the msgwin must be visible before we switch to the VTE page so that + * the font settings are applied on realization */ gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_VTE); gtk_widget_grab_focus(vc->vte); msgwin_show_hide(TRUE); @@ -749,7 +753,7 @@ if (new_pos != -1) { sci_goto_pos(doc_list[idx].sci, new_pos, TRUE); // set the cursor at the brace - sci_scroll_to_line(doc_list[idx].sci, -1, 0.5); + doc_list[idx].scroll_percent = 0.5F; } }
Modified: branches/geany-0.10.1/src/keyfile.c =================================================================== --- branches/geany-0.10.1/src/keyfile.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/keyfile.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * keyfile.c - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -581,21 +582,6 @@ gtk_paned_set_position(GTK_PANED(lookup_widget(app->window, "vpaned1")), vpan_position); }
- // now the scintilla widget pages may need scrolling in view - if (app->pref_main_load_session) - { - gint idx; - guint tabnum = 0; - - while (tabnum < (guint) gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook))) - { - idx = document_get_n_idx(tabnum); - if (idx < 0) break; - sci_scroll_to_line(doc_list[idx].sci, -1, 0.5F); - tabnum++; - } - } - // set fullscreen after initial draw so that returning to normal view is the right size. // fullscreen mode is disabled by default, so act only if it is true if (app->fullscreen)
Modified: branches/geany-0.10.1/src/sci_cb.c =================================================================== --- branches/geany-0.10.1/src/sci_cb.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/sci_cb.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -53,6 +53,7 @@ static void get_indent(ScintillaObject *sci, gint pos, gboolean use_this_line); static void auto_multiline(ScintillaObject *sci, gint pos); static gboolean is_comment(gint lexer, gint style); +static void scroll_to_line(ScintillaObject *sci, gint line, gfloat percent_of_view);
// calls the edit popup menu in the editor @@ -159,6 +160,15 @@
ui_update_statusbar(idx, pos);
+ /* Visible lines are only laid out accurately once [SCN_UPDATEUI] is sent, + * so we need to only call sci_scroll_to_line here, because the document + * may have line wrapping and folding enabled. + * http://scintilla.sourceforge.net/ScintillaDoc.html#LineWrapping */ + if (doc_list[idx].scroll_percent > 0.0F) + { + scroll_to_line(sci, -1, doc_list[idx].scroll_percent); + doc_list[idx].scroll_percent = -1.0F; // disable further scrolling + } #if 0 /// experimental code for inverting selections { @@ -378,7 +388,7 @@ { sci_add_text(sci, "}"); } - sci_set_current_position(sci, pos); + sci_set_current_position(sci, pos, TRUE); }
@@ -1509,7 +1519,7 @@ else if (count_uncommented > 0) { gint eol_len = (sci_get_eol_mode(doc_list[idx].sci) == SC_EOL_CRLF) ? 2 : 1; - sci_set_current_position(doc_list[idx].sci, sel_start - co_len - eol_len); + sci_set_current_position(doc_list[idx].sci, sel_start - co_len - eol_len, TRUE); } }
@@ -1915,3 +1925,28 @@ return -1; } } + + +/* Scroll the view to make line appear at percent_of_view. + * line can be -1 to use the current position. */ +static void scroll_to_line(ScintillaObject *sci, gint line, gfloat percent_of_view) +{ + gint vis1, los, delta; + GtkWidget *wid = GTK_WIDGET(sci); + + if (! wid->window || ! gdk_window_is_viewable(wid->window)) + return; // prevent gdk_window_scroll warning + + if (line == -1) + line = sci_get_current_line(sci, -1); + + // sci 'visible line' != doc line number because of folding and line wrapping + /* calling SCI_VISIBLEFROMDOCLINE for line is more accurate than calling + * SCI_DOCLINEFROMVISIBLE for vis1. */ + line = SSM(sci, SCI_VISIBLEFROMDOCLINE, line, 0); + vis1 = SSM(sci, SCI_GETFIRSTVISIBLELINE, 0, 0); + los = SSM(sci, SCI_LINESONSCREEN, 0, 0); + delta = (line - vis1) - los * percent_of_view; + sci_scroll_lines(sci, delta); + //sci_scroll_caret(sci); // ensure visible (maybe not needed now) +}
Modified: branches/geany-0.10.1/src/sciwrappers.c =================================================================== --- branches/geany-0.10.1/src/sciwrappers.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/sciwrappers.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * sciwrappers.c - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -379,9 +380,15 @@ }
-void sci_set_current_position(ScintillaObject* sci, gint position ) +void sci_set_current_position(ScintillaObject* sci, gint position, gboolean scroll_to_caret) { - SSM(sci, SCI_GOTOPOS, position, 0); + if (scroll_to_caret) + SSM(sci, SCI_GOTOPOS, position, 0); + else + { + SSM(sci, SCI_SETCURRENTPOS, position, 0); + SSM(sci, SCI_SETANCHOR, position, 0); // to avoid creation of a selection + } }
@@ -672,26 +679,6 @@ }
-/* Scroll the view to make line appear at percent_of_view. - * line can be -1 to use the current position. */ -void sci_scroll_to_line(ScintillaObject *sci, gint line, gfloat percent_of_view) -{ - gint vis1, los, delta; - - if (GTK_WIDGET(sci)->allocation.height <= 1) return; // prevent gdk_window_scroll warning - if (line == -1) - line = sci_get_current_line(sci, -1); - - // sci 'visible line' != file line number - vis1 = SSM(sci, SCI_GETFIRSTVISIBLELINE, 0, 0); - vis1 = SSM(sci, SCI_DOCLINEFROMVISIBLE, vis1, 0); - los = SSM(sci, SCI_LINESONSCREEN, 0, 0); - delta = (line - vis1) - los * percent_of_view; - sci_scroll_lines(sci, delta); - sci_scroll_caret(sci); //ensure visible, in case of excessive folding/wrapping -} - - gint sci_search_next(ScintillaObject *sci, gint flags, const gchar *text) { return SSM(sci, SCI_SEARCHNEXT, flags, (sptr_t) text );
Modified: branches/geany-0.10.1/src/sciwrappers.h =================================================================== --- branches/geany-0.10.1/src/sciwrappers.h 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/sciwrappers.h 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * sciwrappers.h - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * Copyright 2005-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -68,7 +69,7 @@ gint sci_get_line_from_position (ScintillaObject* sci, gint position); gint sci_get_position_from_line (ScintillaObject* sci, gint line ); gint sci_get_current_position (ScintillaObject* sci); -void sci_set_current_position (ScintillaObject* sci, gint position); +void sci_set_current_position (ScintillaObject* sci, gint position, gboolean scroll_to_caret); void sci_set_current_line (ScintillaObject* sci, gint line);
void sci_cut (ScintillaObject* sci); @@ -124,7 +125,6 @@ void sci_set_anchor (ScintillaObject * sci, gint pos); void sci_scroll_caret (ScintillaObject * sci); void sci_scroll_lines (ScintillaObject * sci, gint lines); -void sci_scroll_to_line (ScintillaObject * sci, gint line, gfloat percent_of_view); gint sci_search_next (ScintillaObject * sci, gint flags, const gchar *text); gint sci_search_prev (ScintillaObject * sci, gint flags, const gchar *text); gint sci_find_text (ScintillaObject * sci, gint flags, struct TextToFind *ttf);
Modified: branches/geany-0.10.1/src/socket.c =================================================================== --- branches/geany-0.10.1/src/socket.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/socket.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -1,7 +1,8 @@ /* * socket.h - this file is part of Geany, a fast and lightweight IDE * - * Copyright 2006 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Enrico Tröger enrico.troeger@uvena.de + * Copyright 2006-2007 Nick Treleaven nick.treleaven@btinternet.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,12 +37,14 @@ # include <winsock2.h> # include <ws2tcpip.h> #endif +#include <stdlib.h> #include <unistd.h> #include <fcntl.h>
#include "main.h" #include "socket.h" #include "document.h" +#include "support.h"
@@ -75,6 +78,46 @@
+void send_open_command(gint sock, gint argc, gchar **argv) +{ + gint i; + gchar *filename; + + g_return_if_fail(argc > 1); + geany_debug("using running instance of Geany"); + + if (cl_options.goto_line >= 0) + { + gchar *line = g_strdup_printf("%d\n", cl_options.goto_line); + socket_fd_write_all(sock, "line\n", 5); + socket_fd_write_all(sock, line, strlen(line)); + socket_fd_write_all(sock, ".\n", 2); + g_free(line); + } + + socket_fd_write_all(sock, "open\n", 5); + + for(i = 1; i < argc && argv[i] != NULL; i++) + { + filename = get_argv_filename(argv[i]); + + if (filename != NULL && + g_file_test(filename, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) + { + socket_fd_write_all(sock, filename, strlen(filename)); + socket_fd_write_all(sock, "\n", 1); + } + else + { + g_printerr(_("Could not find file '%s'."), filename); + g_printerr("\n"); // keep translation from open_cl_files() in main.c. + } + g_free(filename); + } + socket_fd_write_all(sock, ".\n", 2); +} + + /* (Unix domain) socket support to replace the old FIFO code * (taken from Sylpheed, thanks) */ gint socket_init(gint argc, gchar **argv) @@ -118,25 +161,7 @@ // remote command mode, here we have another running instance and want to use it if (argc > 1) { - gint i; - gchar *filename; - - geany_debug("using running instance of Geany"); - - socket_fd_write_all(sock, "open\n", 5); - - for(i = 1; i < argc && argv[i] != NULL; i++) - { - filename = get_argv_filename(argv[i]); - - if (filename != NULL) - { - socket_fd_write_all(sock, filename, strlen(filename)); - socket_fd_write_all(sock, "\n", 1); - g_free(filename); - } - } - socket_fd_write_all(sock, ".\n", 2); + send_open_command(sock, argc, argv); }
socket_fd_close(sock); @@ -349,24 +374,34 @@ sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len);
// first get the command - if (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && strncmp(buf, "open", 4) == 0) + while (socket_fd_gets(sock, buf, sizeof(buf)) != -1) { - geany_debug("remote command: open"); - while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') + if (strncmp(buf, "open", 4) == 0) { - g_strstrip(buf); // remove \n char + while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') + { + g_strstrip(buf); // remove \n char
- if (g_file_test(buf, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) - document_open_file(-1, buf, 0, FALSE, NULL, NULL); - else - geany_debug("got data from socket, but it does not look like a filename"); - } - gtk_window_deiconify(GTK_WINDOW(app->window)); + if (g_file_test(buf, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) + document_open_file(-1, buf, 0, FALSE, NULL, NULL); + else + geany_debug("got data from socket, but it does not look like a filename"); + } + gtk_window_deiconify(GTK_WINDOW(app->window)); #ifdef G_OS_WIN32 - gtk_window_present(GTK_WINDOW(app->window)); + gtk_window_present(GTK_WINDOW(app->window)); #endif + } + else if (strncmp(buf, "line", 4) == 0) + { + while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') + { + g_strstrip(buf); // remove \n char + // on any error we get 0 which should be save enough as fallback + cl_options.goto_line = atoi(buf); + } + } } - socket_fd_close(sock);
return TRUE;
Modified: branches/geany-0.10.1/src/ui_utils.c =================================================================== --- branches/geany-0.10.1/src/ui_utils.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/ui_utils.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -120,7 +120,7 @@ (doc_list[idx].readonly) ? ", read only" : "", cur_tag, (doc_list[idx].encoding) ? doc_list[idx].encoding : _("unknown"), - (utils_is_unicode_charset(doc_list[idx].encoding)) ? ((doc_list[idx].has_bom) ? _("(with BOM)") : _("(without BOM)")) : "", + (encodings_is_unicode_charset(doc_list[idx].encoding)) ? ((doc_list[idx].has_bom) ? _("(with BOM)") : _("(without BOM)")) : "", (doc_list[idx].file_type) ? doc_list[idx].file_type->title : _("unknown")); set_statusbar(text, TRUE); // can be overridden by status messages g_free(text); @@ -706,7 +706,7 @@ TRUE);
gtk_widget_set_sensitive(lookup_widget(app->window, "menu_write_unicode_bom1"), - utils_is_unicode_charset(doc_list[idx].encoding)); + encodings_is_unicode_charset(doc_list[idx].encoding));
encodings_select_radio_item(doc_list[idx].encoding); filetypes_select_radio_item(doc_list[idx].file_type);
Modified: branches/geany-0.10.1/src/utils.c =================================================================== --- branches/geany-0.10.1/src/utils.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/utils.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -235,7 +235,7 @@ sci_set_marker_at_line(doc_list[idx].sci, line, TRUE, 0);
sci_goto_line(doc_list[idx].sci, line, TRUE); - sci_scroll_to_line(doc_list[idx].sci, -1, 0.25); + doc_list[idx].scroll_percent = 0.25F;
// finally switch to the page page_num = gtk_notebook_page_num(GTK_NOTEBOOK(app->notebook), GTK_WIDGET(doc_list[idx].sci)); @@ -1371,50 +1371,6 @@ }
-gchar *utils_scan_unicode_bom(const gchar *string) -{ - if ((unsigned char)string[0] == 0xef && (unsigned char)string[1] == 0xbb && - (unsigned char)string[2] == 0xbf) - { - return g_strdup("UTF-8"); - } - else if ((unsigned char)string[0] == 0x00 && (unsigned char)string[1] == 0x00 && - (unsigned char)string[2] == 0xfe && (unsigned char)string[3] == 0xff) - { - return g_strdup("UTF-32BE"); // Big endian - } - else if ((unsigned char)string[0] == 0xff && (unsigned char)string[1] == 0xfe && - (unsigned char)string[2] == 0x00 && (unsigned char)string[3] == 0x00) - { - return g_strdup("UTF-32LE"); // Little endian - } - else if ((unsigned char)string[0]==0xfe && (unsigned char)string[1] == 0xff) - { - return g_strdup("UTF-16BE"); // Big endian - } - else if ((unsigned char)string[0] == 0xff && (unsigned char)string[1] == 0xfe) - { - return g_strdup("UTF-16LE"); // Little endian - } - else if ((string[0] == 0x2b && string[1] == 0x2f && string[2] == 0x76) && - (string[3] == 0x38 || string[3] == 0x39 || string[3] == 0x2b || string[3] == 0x2f)) - { - return g_strdup("UTF-7"); - } - return NULL; -} - - -gboolean utils_is_unicode_charset(const gchar *string) -{ - if (string != NULL && (strncmp(string, "UTF", 3) == 0 || strncmp(string, "UCS", 3) == 0)) - { - return TRUE; - } - return FALSE; -} - - /* Wraps a string in place, replacing a space with a newline character. * wrapstart is the minimum position to start wrapping or -1 for default */ gboolean utils_wrap_string(gchar *string, gint wrapstart)
Modified: branches/geany-0.10.1/src/utils.h =================================================================== --- branches/geany-0.10.1/src/utils.h 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/src/utils.h 2007-02-12 18:42:15 UTC (rev 1270) @@ -136,10 +136,6 @@ * Replaces \, \r, \n, \t and \uXXX by their real counterparts */ gboolean utils_str_replace_escape(gchar *string);
-gchar *utils_scan_unicode_bom(const gchar *string); - -gboolean utils_is_unicode_charset(const gchar *string); - /* Wraps a string in place, replacing a space with a newline character. * wrapstart is the minimum position to start wrapping or -1 for default */ gboolean utils_wrap_string(gchar *string, gint wrapstart);
Modified: branches/geany-0.10.1/tagmanager/latex.c =================================================================== --- branches/geany-0.10.1/tagmanager/latex.c 2007-02-12 17:21:57 UTC (rev 1269) +++ branches/geany-0.10.1/tagmanager/latex.c 2007-02-12 18:42:15 UTC (rev 1270) @@ -54,18 +54,22 @@ * FUNCTION DEFINITIONS */
-static int getWord(const char * ref, const char **pointer) +static int getWord(const char * ref, const char **ptr) { - const char * p = *pointer; + const char *p = *ptr;
- while ((*ref != '\0') && (*p != '\0') && (*ref == *p)) - ref++, p++; + while ((*ref != '\0') && (*p != '\0') && (*ref == *p)) + ref++, p++;
- if (*ref) - return FALSE;
- *pointer = p; - return TRUE; + if (*ref) + return FALSE; + + if (*p == '*') // to allow something like \section*{foobar} + p++; + + *ptr = p; + return TRUE; }
static void createTag(int flags, TeXKind kind, const char * l) @@ -92,7 +96,8 @@ ++l; } while ((*l != '\0') && (*l != '}')); vStringTerminate(name); - makeSimpleTag(name, TeXKinds, kind); + if (name->buffer[0] != '}') + makeSimpleTag(name, TeXKinds, kind); } else if (isalpha((int) *l) || *l == '@') { @@ -127,7 +132,7 @@ for (; *cp != '\0'; cp++) { if (*cp == '%') - break; + break; if (*cp == '\') { cp++;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.