831
/* reload file with specified encoding */
833
handle_forced_encoding(FileData *filedata, const gchar *forced_enc)
835
GeanyEncodingIndex enc_idx;
837
if (utils_str_equal(forced_enc, "UTF-8"))
839
if (! g_utf8_validate(filedata->data, filedata->len, NULL))
846
gchar *converted_text = encodings_convert_to_utf8_from_charset(
847
filedata->data, filedata->size, forced_enc, FALSE);
848
if (converted_text == NULL)
854
g_free(filedata->data);
855
filedata->data = converted_text;
856
filedata->len = strlen(converted_text);
859
enc_idx = encodings_scan_unicode_bom(filedata->data, filedata->size, NULL);
860
filedata->bom = (enc_idx == GEANY_ENCODING_UTF_8);
861
filedata->enc = g_strdup(forced_enc);
866
/* detect encoding and convert to UTF-8 if necessary */
868
handle_encoding(FileData *filedata, GeanyEncodingIndex enc_idx)
870
g_return_val_if_fail(filedata->enc == NULL, FALSE);
871
g_return_val_if_fail(filedata->bom == FALSE, FALSE);
873
if (filedata->size == 0)
875
/* we have no data so assume UTF-8, filedata->len can be 0 even we have an empty
876
* e.g. UTF32 file with a BOM(so size is 4, len is 0) */
877
filedata->enc = g_strdup("UTF-8");
881
/* first check for a BOM */
882
if (enc_idx != GEANY_ENCODING_NONE)
884
filedata->enc = g_strdup(encodings[enc_idx].charset);
885
filedata->bom = TRUE;
887
if (enc_idx != GEANY_ENCODING_UTF_8) /* the BOM indicated something else than UTF-8 */
889
gchar *converted_text = encodings_convert_to_utf8_from_charset(
890
filedata->data, filedata->size, filedata->enc, FALSE);
891
if (converted_text != NULL)
893
g_free(filedata->data);
894
filedata->data = converted_text;
895
filedata->len = strlen(converted_text);
899
/* there was a problem converting data from BOM encoding type */
900
g_free(filedata->enc);
901
filedata->enc = NULL;
902
filedata->bom = FALSE;
907
if (filedata->enc == NULL) /* either there was no BOM or the BOM encoding failed */
909
/* try UTF-8 first */
910
if ((filedata->size == filedata->len) &&
911
g_utf8_validate(filedata->data, filedata->len, NULL))
913
filedata->enc = g_strdup("UTF-8");
917
/* detect the encoding */
918
gchar *converted_text = encodings_convert_to_utf8(filedata->data,
919
filedata->size, &filedata->enc);
921
if (converted_text == NULL)
925
g_free(filedata->data);
926
filedata->data = converted_text;
927
filedata->len = strlen(converted_text);
936
handle_bom(FileData *filedata)
940
encodings_scan_unicode_bom(filedata->data, filedata->size, &bom_len);
941
g_return_if_fail(bom_len != 0);
943
/* use filedata->len here because the contents are already converted into UTF-8 */
944
filedata->len -= bom_len;
945
/* overwrite the BOM with the remainder of the file contents, plus the NULL terminator. */
946
g_memmove(filedata->data, filedata->data + bom_len, filedata->len + 1);
947
filedata->data = g_realloc(filedata->data, filedata->len + 1);
951
825
/* loads textfile data, verifies and converts to forced_enc or UTF-8. Also handles BOM. */
952
826
static gboolean load_text_file(const gchar *locale_filename, const gchar *display_filename,
953
827
FileData *filedata, const gchar *forced_enc)
955
829
GError *err = NULL;
957
GeanyEncodingIndex tmp_enc_idx;
959
832
filedata->data = NULL;
960
833
filedata->len = 0;
981
/* use strlen to check for null chars */
982
filedata->size = (gsize) st.st_size;
983
filedata->len = strlen(filedata->data);
985
/* temporarily retrieve the encoding idx based on the BOM to suppress the following warning
986
* if we have a BOM */
987
tmp_enc_idx = encodings_scan_unicode_bom(filedata->data, filedata->size, NULL);
989
/* check whether the size of the loaded data is equal to the size of the file in the
990
* filesystem file size may be 0 to allow opening files in /proc/ which have typically a
991
* file size of 0 bytes */
992
if (filedata->len != filedata->size && filedata->size != 0 && (
993
tmp_enc_idx == GEANY_ENCODING_UTF_8 || /* tmp_enc_idx can be UTF-7/8/16/32, UCS and None */
994
tmp_enc_idx == GEANY_ENCODING_UTF_7)) /* filter UTF-7/8 where no NULL bytes are allowed */
854
filedata->len = (gsize) st.st_size;
855
if (! encodings_convert_to_utf8_auto(&filedata->data, &filedata->len, forced_enc,
856
&filedata->enc, &filedata->bom, &filedata->readonly))
860
ui_set_statusbar(TRUE, _("The file \"%s\" is not valid %s."),
861
display_filename, forced_enc);
865
ui_set_statusbar(TRUE,
866
_("The file \"%s\" does not look like a text file or the file encoding is not supported."),
869
g_free(filedata->data);
873
if (filedata->readonly)
996
875
const gchar *warn_msg = _(
997
876
"The file \"%s\" could not be opened properly and has been truncated. " \
1002
881
dialogs_show_msgbox(GTK_MESSAGE_WARNING, warn_msg, display_filename);
1004
883
ui_set_statusbar(TRUE, warn_msg, display_filename);
1006
/* set the file to read-only mode because saving it is probably dangerous */
1007
filedata->readonly = TRUE;
1010
/* Determine character encoding and convert to UTF-8 */
1011
if (forced_enc != NULL)
1013
/* the encoding should be ignored(requested by user), so open the file "as it is" */
1014
if (utils_str_equal(forced_enc, encodings[GEANY_ENCODING_NONE].charset))
1016
filedata->bom = FALSE;
1017
filedata->enc = g_strdup(encodings[GEANY_ENCODING_NONE].charset);
1019
else if (! handle_forced_encoding(filedata, forced_enc))
1021
/* For translators: the second wildcard is an encoding name, e.g.
1022
* The file \"test.txt\" is not valid UTF-8. */
1023
ui_set_statusbar(TRUE, _("The file \"%s\" is not valid %s."),
1024
display_filename, forced_enc);
1026
g_free(filedata->data);
1030
else if (! handle_encoding(filedata, tmp_enc_idx))
1032
ui_set_statusbar(TRUE,
1033
_("The file \"%s\" does not look like a text file or the file encoding is not supported."),
1036
g_free(filedata->data);
1041
handle_bom(filedata);
1109
/* Detect the indent type based on counting the leading indent characters for each line. */
1110
static GeanyIndentType detect_indent_type(GeanyEditor *editor)
953
/* Detect the indent type based on counting the leading indent characters for each line.
954
* Returns whether detection succeeded, and the detected type in *type_ upon success */
955
gboolean document_detect_indent_type(GeanyDocument *doc, GeanyIndentType *type_)
1112
const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor);
957
GeanyEditor *editor = doc->editor;
1113
958
ScintillaObject *sci = editor->sci;
1114
guint line, line_count;
959
gint line, line_count;
1115
960
gsize tabs = 0, spaces = 0;
1117
962
if (detect_tabs_and_spaces(editor))
1118
return GEANY_INDENT_TYPE_BOTH;
964
*type_ = GEANY_INDENT_TYPE_BOTH;
1120
968
line_count = sci_get_line_count(sci);
1121
969
for (line = 0; line < line_count; line++)
1131
979
c = sci_get_char_at(sci, pos);
1137
/* check for at least 2 spaces */
1138
if (sci_get_char_at(sci, pos + 1) == ' ')
982
/* check for at least 2 spaces */
983
else if (c == ' ' && sci_get_char_at(sci, pos + 1) == ' ')
1142
986
if (spaces == 0 && tabs == 0)
1143
return iprefs->type;
1145
989
/* the factors may need to be tweaked */
1146
990
if (spaces > tabs * 4)
1147
return GEANY_INDENT_TYPE_SPACES;
991
*type_ = GEANY_INDENT_TYPE_SPACES;
1148
992
else if (tabs > spaces * 4)
1149
return GEANY_INDENT_TYPE_TABS;
993
*type_ = GEANY_INDENT_TYPE_TABS;
1151
return GEANY_INDENT_TYPE_BOTH;
995
*type_ = GEANY_INDENT_TYPE_BOTH;
1001
/* Detect the indent width based on counting the leading indent characters for each line.
1002
* Returns whether detection succeeded, and the detected width in *width_ upon success */
1003
static gboolean detect_indent_width(GeanyEditor *editor, GeanyIndentType type, gint *width_)
1005
const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor);
1006
ScintillaObject *sci = editor->sci;
1007
gint line, line_count;
1008
gint widths[7] = { 0 }; /* width can be from 2 to 8 */
1009
gint count, width, i;
1011
/* can't easily detect the supposed width of a tab, guess the default is OK */
1012
if (type == GEANY_INDENT_TYPE_TABS)
1015
/* force 8 at detection time for tab & spaces -- anyway we don't use tabs at this point */
1016
sci_set_tab_width(sci, 8);
1018
line_count = sci_get_line_count(sci);
1019
for (line = 0; line < line_count; line++)
1021
width = sci_get_line_indentation(sci, line);
1022
/* most code will have indent total <= 24, otherwise it's more likely to be
1023
* alignment than indentation */
1026
/* < 2 is no indentation */
1030
for (i = G_N_ELEMENTS(widths) - 1; i >= 0; i--)
1032
if ((width % (i + 2)) == 0)
1037
width = iprefs->width;
1038
for (i = G_N_ELEMENTS(widths) - 1; i >= 0; i--)
1040
/* give large indents higher weight not to be fooled by spurious indents */
1041
if (widths[i] >= count * 1.5)
1056
/* same as detect_indent_width() but uses editor's indent type */
1057
gboolean document_detect_indent_width(GeanyDocument *doc, gint *width_)
1059
return detect_indent_width(doc->editor, doc->editor->indent_type, width_);
1157
1065
const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(NULL);
1158
1066
GeanyIndentType type = iprefs->type;
1160
switch (doc->file_type->id)
1162
case GEANY_FILETYPES_MAKE:
1163
/* force using tabs for indentation for Makefiles */
1164
editor_set_indent(doc->editor, GEANY_INDENT_TYPE_TABS, iprefs->width);
1166
case GEANY_FILETYPES_F77:
1167
/* force using spaces for indentation for Fortran 77 */
1168
editor_set_indent(doc->editor, GEANY_INDENT_TYPE_SPACES, iprefs->width);
1173
if (iprefs->detect_type)
1175
type = detect_indent_type(doc->editor);
1067
gint width = iprefs->width;
1069
if (iprefs->detect_type && document_detect_indent_type(doc, &type))
1177
1071
if (type != iprefs->type)
1179
1073
const gchar *name = NULL;
1196
1090
DOC_FILENAME(doc));
1199
editor_set_indent(doc->editor, type, iprefs->width);
1204
static gboolean auto_update_tag_list(gpointer data)
1206
GeanyDocument *doc = data;
1208
if (! doc || ! doc->is_valid || doc->tm_file == NULL)
1211
if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != GTK_WIDGET(doc->editor->sci))
1214
if (update_tags_from_buffer(doc))
1215
sidebar_update_tag_list(doc, TRUE);
1093
else if (doc->file_type->indent_type > -1)
1094
type = doc->file_type->indent_type;
1096
if (iprefs->detect_width && detect_indent_width(doc->editor, type, &width))
1098
if (width != iprefs->width)
1100
ui_set_statusbar(TRUE, _("Setting indentation width to %d for %s."), width,
1104
else if (doc->file_type->indent_width > -1)
1105
width = doc->file_type->indent_width;
1107
editor_set_indent(doc->editor, type, width);
1222
1111
/* To open a new file, set doc to NULL; filename should be locale encoded.
1356
1245
if (! main_status.opening_session_files)
1357
1246
ui_add_recent_file(utf8_filename);
1250
g_signal_emit_by_name(geany_object, "document-reload", doc);
1251
ui_set_statusbar(TRUE, _("File %s reloaded."), display_filename);
1360
1255
g_signal_emit_by_name(geany_object, "document-open", doc);
1363
ui_set_statusbar(TRUE, _("File %s reloaded."), display_filename);
1365
1256
/* For translators: this is the status window message for opening a file. %d is the number
1366
1257
* of the newly opened file, %s indicates whether the file is opened read-only
1367
1258
* (it is replaced with the string ", read-only"). */
1368
1259
msgwin_status_add(_("File %s opened(%d%s)."),
1369
1260
display_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)),
1370
1261
(readonly) ? _(", read-only") : "");
1373
1265
g_free(display_filename);
1374
1266
g_free(utf8_filename);
1375
1267
g_free(locale_filename);
1377
/* TODO This could be used to automatically update the symbol list,
1378
* based on a configurable interval */
1379
/*g_timeout_add(10000, auto_update_tag_list, doc);*/
1381
1269
/* set the cursor position according to pos, cl_options.goto_line and cl_options.goto_column */
1382
1270
pos = set_cursor_position(doc->editor, pos);
1383
1271
/* now bring the file in front */
1393
1281
/* Takes a new line separated list of filename URIs and opens each file.
1394
* length is the length of the string or -1 if it should be detected */
1395
void document_open_file_list(const gchar *data, gssize length)
1282
* length is the length of the string */
1283
void document_open_file_list(const gchar *data, gsize length)
1398
1286
gchar *filename;
1401
1289
g_return_if_fail(data != NULL);
1404
length = strlen(data);
1406
switch (utils_get_line_endings(data, length))
1408
case SC_EOL_CR: list = g_strsplit(data, "\r", 0); break;
1409
case SC_EOL_CRLF: list = g_strsplit(data, "\r\n", 0); break;
1410
case SC_EOL_LF: list = g_strsplit(data, "\n", 0); break;
1411
default: list = g_strsplit(data, "\n", 0);
1416
if (list[i] == NULL)
1291
list = g_strsplit(data, utils_get_eol_char(utils_get_line_endings(data, length)), 0);
1293
for (i = 0; list[i] != NULL; i++)
1418
1295
filename = g_filename_from_uri(list[i], NULL, NULL);
1419
1296
if (G_UNLIKELY(filename == NULL))
1715
1592
GError *error = NULL;
1717
if (! file_prefs.use_safe_file_saving)
1594
if (file_prefs.use_safe_file_saving)
1596
/* Use old GLib API for safe saving (GVFS-safe, but alters ownership and permissons).
1597
* This is the only option that handles disk space exhaustion. */
1598
if (g_file_set_contents(locale_filename, data, len, &error))
1599
geany_debug("Wrote %s with g_file_set_contents().", locale_filename);
1601
else if (file_prefs.use_gio_unsafe_file_saving)
1722
/* Use GIO API to save file (GVFS-safe) */
1605
/* Use GIO API to save file (GVFS-safe)
1606
* It is best in most GVFS setups but don't seem to work correctly on some more complex
1607
* setups (saving from some VM to their host, over some SMB shares, etc.) */
1723
1608
fp = g_file_new_for_path(locale_filename);
1724
1609
g_file_replace_contents(fp, data, len, NULL, file_prefs.gio_unsafe_save_backup,
1725
1610
G_FILE_CREATE_NONE, NULL, NULL, &error);
1726
1611
g_object_unref(fp);
1729
1616
int save_errno;
1730
1617
gchar *display_name = g_filename_display_name(locale_filename);
1968
1847
/* special search function, used from the find entry in the toolbar
1969
1848
* return TRUE if text was found otherwise FALSE
1970
1849
* return also TRUE if text is empty */
1971
gboolean document_search_bar_find(GeanyDocument *doc, const gchar *text, gint flags, gboolean inc)
1850
gboolean document_search_bar_find(GeanyDocument *doc, const gchar *text, gint flags, gboolean inc,
1973
1853
gint start_pos, search_pos;
1974
1854
struct Sci_TextToFind ttf;
1981
start_pos = (inc) ? sci_get_selection_start(doc->editor->sci) :
1861
start_pos = (inc || backwards) ? sci_get_selection_start(doc->editor->sci) :
1982
1862
sci_get_selection_end(doc->editor->sci); /* equal if no selection */
1984
/* search cursor to end */
1864
/* search cursor to end or start */
1985
1865
ttf.chrg.cpMin = start_pos;
1986
ttf.chrg.cpMax = sci_get_length(doc->editor->sci);
1866
ttf.chrg.cpMax = backwards ? 0 : sci_get_length(doc->editor->sci);
1987
1867
ttf.lpstrText = (gchar *)text;
1988
1868
search_pos = sci_find_text(doc->editor->sci, flags, &ttf);
1990
/* if no match, search start to cursor */
1870
/* if no match, search start (or end) to cursor */
1991
1871
if (search_pos == -1)
1994
ttf.chrg.cpMax = start_pos + strlen(text);
1875
ttf.chrg.cpMin = sci_get_length(doc->editor->sci);
1876
ttf.chrg.cpMax = start_pos;
1881
ttf.chrg.cpMax = start_pos + strlen(text);
1995
1883
search_pos = sci_find_text(doc->editor->sci, flags, &ttf);
2031
1919
/* General search function, used from the find dialog.
2032
1920
* Returns -1 on failure or the start position of the matching text.
2033
* Will skip past any selection, ignoring it. */
2034
gint document_find_text(GeanyDocument *doc, const gchar *text, gint flags, gboolean search_backwards,
2035
gboolean scroll, GtkWidget *parent)
1921
* Will skip past any selection, ignoring it.
1923
* @param text Text to find.
1924
* @param original_text Text as it was entered by user, or @c NULL to use @c text
1926
gint document_find_text(GeanyDocument *doc, const gchar *text, const gchar *original_text,
1927
gint flags, gboolean search_backwards, gboolean scroll, GtkWidget *parent)
2037
1929
gint selection_end, selection_start, search_pos;
2084
1979
/* we searched only part of the document, so ask whether to wraparound. */
2085
1980
if (search_prefs.suppress_dialogs ||
2086
1981
dialogs_show_question_full(parent, GTK_STOCK_FIND, GTK_STOCK_CANCEL,
2087
_("Wrap search and find again?"), _("\"%s\" was not found."), text))
1982
_("Wrap search and find again?"), _("\"%s\" was not found."), original_text))
2091
1986
sci_set_current_position(doc->editor->sci, (search_backwards) ? sci_len : 0, FALSE);
2092
ret = document_find_text(doc, text, flags, search_backwards, scroll, parent);
1987
ret = document_find_text(doc, text, original_text, flags, search_backwards, scroll, parent);
2094
1989
{ /* return to original cursor position if not found */
2095
1990
sci_set_current_position(doc->editor->sci, selection_start, FALSE);
2104
1999
/* Replaces the selection if it matches, otherwise just finds the next match.
2105
* Returns: start of replaced text, or -1 if no replacement was made */
2106
gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text,
2107
gint flags, gboolean search_backwards)
2000
* Returns: start of replaced text, or -1 if no replacement was made
2002
* @param find_text Text to find.
2003
* @param original_find_text Text to find as it was entered by user, or @c NULL to use @c find_text
2005
gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gchar *original_find_text,
2006
const gchar *replace_text, gint flags, gboolean search_backwards)
2109
2008
gint selection_end, selection_start, search_pos;
2117
2016
if (flags & SCFIND_REGEXP)
2118
2017
search_backwards = FALSE;
2019
if (!original_find_text)
2020
original_find_text = find_text;
2120
2022
selection_start = sci_get_selection_start(doc->editor->sci);
2121
2023
selection_end = sci_get_selection_end(doc->editor->sci);
2122
2024
if (selection_end == selection_start)
2124
2026
/* no selection so just find the next match */
2125
document_find_text(doc, find_text, flags, search_backwards, TRUE, NULL);
2027
document_find_text(doc, find_text, original_find_text, flags, search_backwards, TRUE, NULL);
2128
2030
/* there's a selection so go to the start before finding to search through it
2133
2035
sci_goto_pos(doc->editor->sci, selection_start, TRUE);
2135
search_pos = document_find_text(doc, find_text, flags, search_backwards, TRUE, NULL);
2037
search_pos = document_find_text(doc, find_text, original_find_text, flags, search_backwards, TRUE, NULL);
2136
2038
/* return if the original selected text did not match (at the start of the selection) */
2137
2039
if (search_pos != selection_start)
2159
static void show_replace_summary(GeanyDocument *doc, gint count, const gchar *find_text,
2160
const gchar *replace_text, gboolean escaped_chars)
2061
static void show_replace_summary(GeanyDocument *doc, gint count, const gchar *original_find_text,
2062
const gchar *original_replace_text)
2162
gchar *escaped_find_text, *escaped_replace_text, *filename;
2164
2066
if (count == 0)
2166
ui_set_statusbar(FALSE, _("No matches found for \"%s\"."), find_text);
2068
ui_set_statusbar(FALSE, _("No matches found for \"%s\"."), original_find_text);
2170
2072
filename = g_path_get_basename(DOC_FILENAME(doc));
2173
{ /* escape special characters for showing */
2174
escaped_find_text = g_strescape(find_text, NULL);
2175
escaped_replace_text = g_strescape(replace_text, NULL);
2176
ui_set_statusbar(TRUE, ngettext(
2177
"%s: replaced %d occurrence of \"%s\" with \"%s\".",
2178
"%s: replaced %d occurrences of \"%s\" with \"%s\".",
2179
count), filename, count, escaped_find_text, escaped_replace_text);
2180
g_free(escaped_find_text);
2181
g_free(escaped_replace_text);
2185
ui_set_statusbar(TRUE, ngettext(
2186
"%s: replaced %d occurrence of \"%s\" with \"%s\".",
2187
"%s: replaced %d occurrences of \"%s\" with \"%s\".",
2188
count), filename, count, find_text, replace_text);
2073
ui_set_statusbar(TRUE, ngettext(
2074
"%s: replaced %d occurrence of \"%s\" with \"%s\".",
2075
"%s: replaced %d occurrences of \"%s\" with \"%s\".",
2076
count), filename, count, original_find_text, original_replace_text);
2190
2077
g_free(filename);
2238
2125
void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text,
2239
gint flags, gboolean escaped_chars)
2126
const gchar *original_find_text, const gchar *original_replace_text, gint flags)
2241
2128
gint selection_end, selection_start, selection_mode, selected_lines, last_line = 0;
2242
2129
gint max_column = 0, count = 0;
2333
2220
else /* no replacements */
2336
show_replace_summary(doc, count, find_text, replace_text, escaped_chars);
2223
show_replace_summary(doc, count, original_find_text, original_replace_text);
2340
2227
/* returns number of replacements made. */
2341
2228
gint document_replace_all(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text,
2342
gint flags, gboolean escaped_chars)
2229
const gchar *original_find_text, const gchar *original_replace_text, gint flags)
2344
2231
gint len, count;
2345
2232
g_return_val_if_fail(doc != NULL && find_text != NULL && replace_text != NULL, FALSE);
2351
2238
count = document_replace_range(
2352
2239
doc, find_text, replace_text, flags, 0, len, TRUE, NULL);
2354
show_replace_summary(doc, count, find_text, replace_text, escaped_chars);
2241
show_replace_summary(doc, count, original_find_text, original_replace_text);
2317
static gboolean on_document_update_tag_list_idle(gpointer data)
2319
GeanyDocument *doc = data;
2321
if (! DOC_VALID(doc))
2324
if (! main_status.quitting)
2325
document_update_tag_list(doc, TRUE);
2327
doc->priv->tag_list_update_source = 0;
2332
void document_update_tag_list_in_idle(GeanyDocument *doc)
2334
if (editor_prefs.autocompletion_update_freq <= 0 || ! filetype_has_tags(doc->file_type))
2337
if (doc->priv->tag_list_update_source != 0)
2338
g_source_remove(doc->priv->tag_list_update_source);
2339
doc->priv->tag_list_update_source = g_timeout_add_full(G_PRIORITY_LOW,
2340
editor_prefs.autocompletion_update_freq, on_document_update_tag_list_idle, doc, NULL);
2430
2344
/* Caches the list of project typenames, as a space separated GString.
2431
2345
* Returns: TRUE if typenames have changed.
2432
2346
* (*types) is set to the list of typenames, or NULL if there are none. */
2586
2500
if (ft_changed)
2502
const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(NULL);
2504
/* assume that if previous filetype was none and the settings are the default ones, this
2505
* is the first time the filetype is carefully set, so we should apply indent settings */
2506
if (old_ft && old_ft->id == GEANY_FILETYPES_NONE &&
2507
doc->editor->indent_type == iprefs->type &&
2508
doc->editor->indent_width == iprefs->width)
2510
document_apply_indent_settings(doc);
2511
ui_document_show_hide(doc);
2588
2514
sidebar_openfiles_update(doc); /* to update the icon */
2589
2515
g_signal_emit_by_name(geany_object, "document-filetype-set", doc, old_ft);
3038
/** Compares documents by their display names.
3039
* This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort().
3040
* @note 'Display name' means the base name of the document's filename.
3042
* @param a @c GeanyDocument**.
3043
* @param b @c GeanyDocument**.
3044
* @warning The arguments take the address of each document pointer.
3045
* @return Negative value if a < b; zero if a = b; positive value if a > b.
3049
gint document_compare_by_display_name(gconstpointer a, gconstpointer b)
3051
GeanyDocument *doc_a = *((GeanyDocument**) a);
3052
GeanyDocument *doc_b = *((GeanyDocument**) b);
3053
gchar *base_name_a, *base_name_b;
3056
base_name_a = g_path_get_basename(DOC_FILENAME(doc_a));
3057
base_name_b = g_path_get_basename(DOC_FILENAME(doc_b));
3059
result = strcmp(base_name_a, base_name_b);
3061
g_free(base_name_a);
3062
g_free(base_name_b);
3068
/** Compares documents by their tab order.
3069
* This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort().
3071
* @param a @c GeanyDocument**.
3072
* @param b @c GeanyDocument**.
3073
* @warning The arguments take the address of each document pointer.
3074
* @return Negative value if a < b; zero if a = b; positive value if a > b.
3076
* @since 0.21 (GEANY_API_VERSION 209)
3078
gint document_compare_by_tab_order(gconstpointer a, gconstpointer b)
3080
GeanyDocument *doc_a = *((GeanyDocument**) a);
3081
GeanyDocument *doc_b = *((GeanyDocument**) b);
3082
gint notebook_position_doc_a;
3083
gint notebook_position_doc_b;
3085
notebook_position_doc_a = document_get_notebook_page(doc_a);
3086
notebook_position_doc_b = document_get_notebook_page(doc_b);
3088
if (notebook_position_doc_a < notebook_position_doc_b)
3090
if (notebook_position_doc_a > notebook_position_doc_b)
3097
/** Compares documents by their tab order, in reverse order.
3098
* This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort().
3100
* @param a @c GeanyDocument**.
3101
* @param b @c GeanyDocument**.
3102
* @warning The arguments take the address of each document pointer.
3103
* @return Negative value if a < b; zero if a = b; positive value if a > b.
3105
* @since 0.21 (GEANY_API_VERSION 209)
3107
gint document_compare_by_tab_order_reverse(gconstpointer a, gconstpointer b)
3109
GeanyDocument *doc_a = *((GeanyDocument**) a);
3110
GeanyDocument *doc_b = *((GeanyDocument**) b);
3111
gint notebook_position_doc_a;
3112
gint notebook_position_doc_b;
3114
notebook_position_doc_a = document_get_notebook_page(doc_a);
3115
notebook_position_doc_b = document_get_notebook_page(doc_b);
3117
if (notebook_position_doc_a < notebook_position_doc_b)
3119
if (notebook_position_doc_a > notebook_position_doc_b)
3126
void document_grab_focus(GeanyDocument *doc)
3128
g_return_if_fail(doc != NULL);
3130
gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci));