331 lines
7.6 KiB
C
331 lines
7.6 KiB
C
/*
|
|
* L3afpad - GTK+ based simple text editor
|
|
* Copyright (C) 2004-2005 Tarot Osuji
|
|
*
|
|
* 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
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include <glib/gprintf.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "l3afpad.h"
|
|
|
|
gboolean check_file_writable(gchar *filename)
|
|
{
|
|
FILE *fp;
|
|
|
|
if ((fp = fopen(filename, "a")) != NULL) {
|
|
fclose(fp);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
gchar *get_file_basename(gchar *filename, gboolean bracket)
|
|
{
|
|
gchar *basename = NULL;
|
|
gchar *tmp;
|
|
gboolean exist_flag;
|
|
|
|
if (filename) {
|
|
tmp = g_path_get_basename(
|
|
g_filename_to_utf8(filename, -1, NULL, NULL, NULL));
|
|
exist_flag = g_file_test(
|
|
g_filename_to_utf8(filename, -1, NULL, NULL, NULL),
|
|
G_FILE_TEST_EXISTS);
|
|
} else {
|
|
tmp = g_strdup(_("Untitled"));
|
|
exist_flag = FALSE;
|
|
}
|
|
|
|
if (bracket) {
|
|
if (!exist_flag) {
|
|
GString *string = g_string_new(tmp);
|
|
g_string_prepend(string, "(");
|
|
g_string_append(string, ")");
|
|
basename = g_strdup(string->str);
|
|
g_string_free(string, TRUE);
|
|
} else if (!check_file_writable(filename)) {
|
|
GString *string = g_string_new(tmp);
|
|
g_string_prepend(string, "<");
|
|
g_string_append(string, ">");
|
|
basename = g_strdup(string->str);
|
|
g_string_free(string, TRUE);
|
|
}
|
|
}
|
|
|
|
if (!basename)
|
|
basename = g_strdup(tmp);
|
|
g_free(tmp);
|
|
|
|
return basename;
|
|
}
|
|
|
|
gchar *parse_file_uri(gchar *uri)
|
|
{
|
|
gchar *filename;
|
|
// gchar **strs;
|
|
|
|
if (g_strstr_len(uri, 5, "file:"))
|
|
filename = g_filename_from_uri(uri, NULL, NULL);
|
|
else {
|
|
if (g_path_is_absolute(uri))
|
|
filename = g_strdup(uri);
|
|
else
|
|
filename = g_build_filename(g_get_current_dir(), uri, NULL);
|
|
}
|
|
/* if (strstr(filename, " ")) {
|
|
strs = g_strsplit(filename, " ", -1);
|
|
g_free(filename);
|
|
filename = g_strjoinv("\\ ", strs);
|
|
g_strfreev(strs);
|
|
}
|
|
*/
|
|
return filename;
|
|
}
|
|
|
|
gint file_open_real(GtkWidget *view, FileInfo *fi)
|
|
{
|
|
gchar *contents;
|
|
gsize length;
|
|
GError *err = NULL;
|
|
const gchar *charset;
|
|
gchar *str = NULL;
|
|
GtkTextIter iter;
|
|
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
|
|
|
|
if (!g_file_get_contents(fi->filename, &contents, &length, &err)) {
|
|
if (g_file_test(fi->filename, G_FILE_TEST_EXISTS)) {
|
|
run_dialog_message(gtk_widget_get_toplevel(view),
|
|
GTK_MESSAGE_ERROR, err->message);
|
|
g_error_free(err);
|
|
return -1;
|
|
}
|
|
g_error_free(err);
|
|
err = NULL;
|
|
contents = g_strdup("");
|
|
}
|
|
|
|
fi->lineend = detect_line_ending(contents);
|
|
if (fi->lineend != LF)
|
|
convert_line_ending_to_lf(contents);
|
|
|
|
if (fi->charset)
|
|
charset = fi->charset;
|
|
else {
|
|
charset = detect_charset(contents);
|
|
if (charset == NULL)
|
|
charset = get_default_charset();
|
|
}
|
|
|
|
if (length)
|
|
do {
|
|
if (err) {
|
|
charset = "ISO-8859-1";
|
|
g_error_free(err);
|
|
err = NULL;
|
|
}
|
|
str = g_convert(contents, -1, "UTF-8", charset, NULL, NULL, &err);
|
|
} while (err);
|
|
else
|
|
str = g_strdup("");
|
|
g_free(contents);
|
|
|
|
if (charset != fi->charset) {
|
|
g_free(fi->charset);
|
|
fi->charset = g_strdup(charset);
|
|
if (fi->charset_flag)
|
|
fi->charset_flag = FALSE;
|
|
}
|
|
|
|
// undo_disconnect_signal(textbuffer);
|
|
// undo_block_signal(buffer);
|
|
force_block_cb_modified_changed(view);
|
|
|
|
gtk_text_buffer_set_text(buffer, "", 0);
|
|
gtk_text_buffer_get_start_iter(buffer, &iter);
|
|
gtk_text_buffer_insert(buffer, &iter, str, strlen(str));
|
|
gtk_text_buffer_get_start_iter(buffer, &iter);
|
|
gtk_text_buffer_place_cursor(buffer, &iter);
|
|
gtk_text_buffer_set_modified(buffer, FALSE);
|
|
gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(view), &iter, 0, FALSE, 0, 0);
|
|
g_free(str);
|
|
|
|
force_unblock_cb_modified_changed(view);
|
|
menu_sensitivity_from_modified_flag(FALSE);
|
|
// undo_unblock_signal(buffer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
gint file_save_real(GtkWidget *view, FileInfo *fi)
|
|
{
|
|
FILE *fp;
|
|
GtkTextIter start, end;
|
|
gchar *str, *cstr;
|
|
gsize rbytes, wbytes;
|
|
GError *err = NULL;
|
|
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
|
|
|
|
gtk_text_buffer_get_start_iter(buffer, &start);
|
|
gtk_text_buffer_get_end_iter(buffer, &end);
|
|
str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
|
|
|
|
switch (fi->lineend) {
|
|
case CR:
|
|
convert_line_ending(&str, CR);
|
|
break;
|
|
case CR+LF:
|
|
convert_line_ending(&str, CR+LF);
|
|
}
|
|
|
|
if (!fi->charset)
|
|
fi->charset = g_strdup(get_default_charset());
|
|
cstr = g_convert(str, -1, fi->charset, "UTF-8", &rbytes, &wbytes, &err);
|
|
g_free(str);
|
|
if (err) {
|
|
switch (err->code) {
|
|
case G_CONVERT_ERROR_ILLEGAL_SEQUENCE:
|
|
run_dialog_message(gtk_widget_get_toplevel(view),
|
|
GTK_MESSAGE_ERROR, _("Can't convert codeset to '%s'"), fi->charset);
|
|
break;
|
|
default:
|
|
run_dialog_message(gtk_widget_get_toplevel(view),
|
|
GTK_MESSAGE_ERROR, err->message);
|
|
}
|
|
g_error_free(err);
|
|
return -1;
|
|
}
|
|
|
|
fp = fopen(fi->filename, "w");
|
|
if (!fp) {
|
|
run_dialog_message(gtk_widget_get_toplevel(view),
|
|
GTK_MESSAGE_ERROR, _("Can't open file to write"));
|
|
return -1;
|
|
}
|
|
if (fwrite(cstr, 1, wbytes, fp) != wbytes) {
|
|
run_dialog_message(gtk_widget_get_toplevel(view),
|
|
GTK_MESSAGE_ERROR, _("Can't write file"));
|
|
return -1;
|
|
}
|
|
|
|
gtk_text_buffer_set_modified(buffer, FALSE);
|
|
fclose(fp);
|
|
g_free(cstr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if ENABLE_STATISTICS
|
|
void text_stats(gchar * text, gint * wc, gint * lc);
|
|
gint skipDelim(gchar ** pos);
|
|
gboolean isDelim(gchar);
|
|
|
|
gchar * file_stats(GtkWidget *view, FileInfo *fi)
|
|
{
|
|
GtkTextIter start;
|
|
GtkTextIter end;
|
|
GtkTextIter textStart;
|
|
GtkTextIter textEnd;
|
|
gchar * str;
|
|
gchar * text;
|
|
gint totalLines = 0;
|
|
gint totalChars = 0;
|
|
gint totalWords = 0;
|
|
gint charCount = 0;
|
|
gint wordCount = 0;
|
|
gint lineCount = 0;
|
|
gchar * toret = g_malloc( 8192 );
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
|
|
gboolean hasSelection = gtk_text_buffer_get_selection_bounds( buffer, &start, &end );
|
|
|
|
if ( !hasSelection ) {
|
|
gtk_text_buffer_get_start_iter(buffer, &start);
|
|
gtk_text_buffer_get_start_iter(buffer, &end);
|
|
}
|
|
|
|
gtk_text_buffer_get_start_iter(buffer, &textStart);
|
|
gtk_text_buffer_get_end_iter(buffer, &textEnd);
|
|
|
|
str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
|
|
text = gtk_text_buffer_get_text(buffer, &textStart, &textEnd, FALSE);
|
|
|
|
totalChars = gtk_text_buffer_get_char_count( buffer );
|
|
charCount = strlen( str );
|
|
|
|
text_stats( str, &wordCount, &lineCount );
|
|
text_stats( text, &totalWords, &totalLines );
|
|
|
|
g_sprintf(
|
|
toret,
|
|
_("<u>Totals count</u>\nChars: %7d Words: %6d Lines: %5d\n\n"
|
|
"<u>Selection</u>\nChars: %7d Words: %6d Lines: %5d\n"),
|
|
totalChars,
|
|
totalWords,
|
|
totalLines,
|
|
charCount,
|
|
wordCount,
|
|
lineCount
|
|
);
|
|
|
|
return toret;
|
|
}
|
|
|
|
const gchar * DelimChars = " ,.;:\t\n-_?¿()!¡'/&%$#\"\\|{}[]+*";
|
|
|
|
void text_stats(gchar * text, gint * wc, gint * lc)
|
|
{
|
|
gchar * pos = text;
|
|
*wc = 0;
|
|
*lc = 1;
|
|
|
|
*lc += skipDelim( &pos );
|
|
while( *pos != 0 ) {
|
|
++(*wc);
|
|
while( *pos != 0
|
|
&& !isDelim( *pos ) )
|
|
{
|
|
++pos;
|
|
}
|
|
|
|
*lc += skipDelim( &pos );
|
|
}
|
|
}
|
|
|
|
gint skipDelim(gchar ** pos)
|
|
{
|
|
gint lc = 0;
|
|
|
|
while( **pos != 0
|
|
&& isDelim( **pos ) )
|
|
{
|
|
if ( **pos == '\n' ) {
|
|
++lc;
|
|
}
|
|
++( *pos );
|
|
}
|
|
|
|
return lc;
|
|
}
|
|
|
|
inline
|
|
gboolean isDelim(gchar ch)
|
|
{
|
|
return ( strchr( DelimChars, ch ) != NULL );
|
|
}
|
|
#endif
|