#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include "gm-support.h" #include "debug.h" #include "gm-pixbuf.h" //#include "if_main.h" #define URL_REGEXP "(((mailto|news|telnet|nttp|file|http|sftp|ftp|https|dav|callto)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.@:]+[^]''\\.}>\\) ,\\/\\\"\\!]+(:[0-9]*)?(/|/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"\\!])?" static regex_t url_regexp; gchar * gm_fix_decimal_point(gchar *line, int len) { int i; struct lconv *l = localeconv(); for (i = 0; i < len; i++) { if (line[i] == '.') { line[i] = l->decimal_point[0]; } } return line; } gchar * gm_fix_decimal_point_rev(gchar *line, int len) { int i; struct lconv *l = localeconv(); for (i = 0; i < len; i++) { if (line[i] == l->decimal_point[0]) { line[i] = '.'; } } return line; } gchar * gm_ansi_strip(gchar * s) { int i, j = 0; for (i = 0; s[i] != '\0'; i++) { // Escape sequence, advance to character after 'm' if (s[i] == '\x1B') { while (s[i] != '\0' && s[i] != 'm') { i++; } } else if (s[i] != '\x07') { s[j] = s[i]; j++; } } s[j] = '\0'; return s; } int garray_length(gchar **s) { int i = 0; while (s[i] != NULL) { i++; } return i; } void g_list_free_simple(GList *s) { GList *tmp; for (tmp = s; tmp; tmp = tmp->next) { g_free(tmp->data); } g_list_free(s); } gchar * g_list_find_simple(GList *s, gchar *f) { GList *tmp; for (tmp = s; tmp; tmp = tmp->next) { if (strcmp(tmp->data, f) == 0) { return tmp->data; } } return NULL; } void gm_dialog(gchar * message, GtkMessageType messagebox_type, GtkWindow * parent) { GtkWidget *dlg; if (parent == NULL) { //parent = GTK_WINDOW(if_main_get_widget("wndMain")); } dlg = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, messagebox_type, GTK_BUTTONS_OK, message, NULL); gtk_dialog_run(GTK_DIALOG(dlg)); gtk_widget_destroy(dlg); } void gm_error_dialog(gchar * message, GtkWindow * parent) { gm_dialog(message, GTK_MESSAGE_ERROR, parent); } void gm_warning_dialog(gchar * message, GtkWindow * parent) { gm_dialog(message, GTK_MESSAGE_WARNING, parent); } void gm_info_dialog(gchar * message, GtkWindow * parent) { gm_dialog(message, GTK_MESSAGE_INFO, parent); } void gm_question_dialog(gchar * message, GtkWindow * parent) { gm_dialog(message, GTK_MESSAGE_QUESTION, parent); } void gm_do_events() { while (gtk_events_pending()) { gtk_main_iteration(); } } gchar * gm_str_escape(gchar * line) { gchar *newLine; int i, j = 0; if (strlen(line) == 0) { return g_strdup(""); } if (strstr(line, "\"") || strstr(line, "\\")) { newLine = g_new(gchar, (strlen(line) * 2) + 1); for (i = 0; i < (int)strlen(line); i++) { if (line[i] == '"' || line[i] == '\\') { newLine[j] = '\\'; j++; } newLine[j] = line[i]; j++; } newLine[j] = '\0'; return newLine; } else { return g_strdup(line); } } void gm_directory_remove_all(const gchar * path, gboolean remove_self) { GDir *cDir; gchar *name; gchar *newPath; if (g_file_test(path, G_FILE_TEST_IS_DIR)) { // Iterate through the files and do the right thingie if ((cDir = g_dir_open(path, 0, NULL))) { while ((name = (gchar *) (g_dir_read_name(cDir))) != NULL) { newPath = g_strconcat(path, "/", name, NULL); gm_directory_remove_all(newPath, TRUE); g_free(newPath); } g_dir_close(cDir); } } if (remove_self) { // Its a file, or just empty! MUST...BE...REMOVEEEED! remove(path); } } gint gm_url_regex_match(const gchar *msg, int len, GArray *start, GArray *end) { static gboolean inited = FALSE; regmatch_t matches[1]; gint ret = 0, num_matches = 0, offset = 0; gchar *tmp; gint s; if (!inited) { memset (&url_regexp, 0, sizeof (regex_t)); regcomp (&url_regexp, URL_REGEXP, REG_EXTENDED); inited = TRUE; } tmp = g_strndup(msg, len); while (!ret) { ret = regexec(&url_regexp, (char *)(tmp + offset), 1, matches, 0); if (ret == 0) { if (matches[0].rm_so > matches[0].rm_eo) { break; } num_matches++; s = matches[0].rm_so + offset; offset = matches[0].rm_eo + offset; g_array_append_val(start, s); g_array_append_val(end, offset); } } g_free(tmp); return num_matches; } void gm_open_url (const gchar *url) { if (!url || strlen (url) == 0) { return; } /* gnome_url_show doesn't work when there's no protocol, so we might * need to add one. */ if (strstr (url, "://") == NULL) { gchar *tmp; tmp = g_strconcat ("http://", url, NULL); gnome_url_show(tmp, NULL); g_free (tmp); return; } gnome_url_show (url, NULL); } void gm_fetch_handle_free(GmFetchHandle *g) { GList *tmp; g_free(g->cur_file_name); for (tmp = g->source_uri; tmp; tmp = tmp->next) { gnome_vfs_uri_unref((GnomeVFSURI*)(tmp->data)); } g_list_free(g->source_uri); for (tmp = g->dest_uri; tmp; tmp = tmp->next) { gnome_vfs_uri_unref((GnomeVFSURI*)(tmp->data)); } g_list_free(g->dest_uri); g_free(g); } GmFetchHandle * gm_fetch_handle_create(GFunc cb, gpointer user_data) { GmFetchHandle *g = g_new0(GmFetchHandle, 1); g->cb = cb; g->user_data = user_data; g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; g->cur_phase = -1; g->prev_phase = -1; g->cur_file = -1; g->prev_file = -1; g->source_uri = NULL; g->dest_uri = NULL; g->cur_file_name = NULL; g->files_total = 0; g->done = FALSE; g->aborted = FALSE; return g; } gint gm_fetch_progress(GnomeVFSAsyncHandle *handle, GnomeVFSXferProgressInfo *info, GmFetchHandle *g) { gchar *name; const gchar *err; g->cur_phase = info->phase; g->cur_file = info->file_index; g->files_total = info->files_total; g->bytes_total = info->bytes_total; g->file_size = info->file_size; g->bytes_copied = info->bytes_copied; g->total_bytes_copied = info->total_bytes_copied; g->status = info->status; if (g->aborted) { g->cb(g, g->user_data); gm_fetch_handle_free(g); return FALSE; } if (info->target_name != NULL) { if (g->cur_file_name && strcmp(g->cur_file_name, info->target_name) != 0) { g->cur_phase = GNOME_VFS_XFER_PHASE_FILECOMPLETED; g->cb(g, g->user_data); g->cur_phase = info->phase; g_free(g->cur_file_name); g->cur_file_name = NULL; } if (!g->cur_file_name) { g->cur_file_name = g_strdup(info->target_name); } } if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE) { name = gnome_vfs_get_local_path_from_uri(info->target_name); debug_msg(1, "gnoemoe_fetch_progress: asking for overwriting %s: yes", name); g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE; return GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE; } else if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR) { name = gnome_vfs_get_local_path_from_uri(info->target_name); err = gnome_vfs_result_to_string(info->vfs_status); gdk_threads_enter(); debug_msg(1, "gnoemoe_fetch_progress: error for %s: %s", name, err); g->cb(g, g->user_data); gdk_threads_leave(); g_free(g->cur_file_name); g->cur_file_name = NULL; g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR; g_free(name); return GNOME_VFS_XFER_ERROR_ACTION_SKIP; } if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { if (g->cur_file_name != NULL) { g->cur_phase = GNOME_VFS_XFER_PHASE_FILECOMPLETED; g->cb(g, g->user_data); g->cur_phase = info->phase; } g->done = TRUE; g->cb(g, g->user_data); gm_fetch_handle_free(g); return TRUE; } g->prev_status = info->status; return TRUE; } gint gm_fetch_interact(GnomeVFSXferProgressInfo *info, gpointer user_data) { return 1; } GmFetchHandle * gm_fetch(const GList *source, const GList *dest, GFunc cb, gpointer user_data) { GmFetchHandle *g = gm_fetch_handle_create(cb, user_data); gchar *uri; for (; source; source = source->next) { uri = (gchar *)(source->data); g->source_uri = g_list_append(g->source_uri, gnome_vfs_uri_new(uri)); } for (; dest; dest = dest->next) { uri = (gchar *)(dest->data); g->dest_uri = g_list_append(g->dest_uri, gnome_vfs_uri_new(uri)); } gnome_vfs_async_xfer(&(g->handle), g->source_uri, g->dest_uri, GNOME_VFS_XFER_DEFAULT|GNOME_VFS_XFER_RECURSIVE, GNOME_VFS_XFER_ERROR_MODE_QUERY, GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, GNOME_VFS_PRIORITY_DEFAULT, (GnomeVFSAsyncXferProgressCallback)gm_fetch_progress, g, gm_fetch_interact, g); return g; } gboolean gm_is_end_scrolled(GtkScrolledWindow *wnd, guint charHeight) { GtkAdjustment *ad = gtk_scrolled_window_get_vadjustment(wnd); return ((ad->page_size + ad->value) >= ad->upper - (double)charHeight); } void gm_scroll_end(GtkTextView *view, gboolean needs) { GtkTextBuffer *buf; GtkTextMark *mark; GtkTextIter iter; if (!needs) { return; } buf = gtk_text_view_get_buffer(view); mark = gtk_text_buffer_get_mark(buf, "end-of-buffer"); if (mark == NULL) { gtk_text_buffer_get_end_iter(buf, &iter); mark = gtk_text_buffer_create_mark(buf, "end-of-buffer", &iter, FALSE); } gtk_text_view_scroll_to_mark(view, mark, 0.0, TRUE, 1.0, 1.0); } #define MAX_BUF 1024 GString * gm_read_file(const gchar *fname, gboolean readall, OpenLogProgress func, gpointer user_data) { FILE *f; gchar line[MAX_BUF], *tmp; GString *str = NULL; long bytes_read = 0, bytes_total = 0; if (!fname) { return NULL; } f = fopen(fname, "r"); if (f) { fseek(f, 0, SEEK_END); bytes_total = ftell(f); rewind(f); str = g_string_new(""); while (fgets((char *) &line, MAX_BUF, f) != NULL) { bytes_read += strlen((char *)&line); tmp = NULL; if (g_utf8_validate(line, -1, NULL)) { if (readall) { str = g_string_append(str, line); } tmp = g_strdup(line); } else { tmp = g_locale_to_utf8(line, -1, NULL, NULL, NULL); if (!tmp) { tmp = g_convert(line, -1, "UTF-8", "ISO-8859-15", NULL, NULL, NULL); } if (!tmp) { tmp = g_convert(line, -1, "UTF-8", "ISO-8859-15", NULL, NULL, NULL); } if (readall) { str = g_string_append(str, tmp); } } if (func != NULL) { func(bytes_read, bytes_total, tmp, user_data); } else { g_free(tmp); } } fclose(f); return str; } else { debug_msg(1, "support_read_file: file (%s) could not be read: %s", fname, strerror(errno)); return NULL; } } GtkWidget * gm_create_tab_label(const gchar *icon, const gchar *caption, gboolean has_exit, GmLabelInfo *info) { /* First create the gbox (size 3) which will contain an icon, a label and a exit button if has_exit is true */ GtkWidget *hboxTabLabel; gint h, w; hboxTabLabel = gtk_hbox_new(FALSE, 3); gtk_widget_show(hboxTabLabel); info->image_icon = gtk_image_new_from_pixbuf( gm_pixbuf_get_at_size(icon, 16, 16)); gtk_widget_set_size_request(info->image_icon, 16, 16); gtk_widget_show(info->image_icon); gtk_box_pack_start(GTK_BOX(hboxTabLabel), info->image_icon, TRUE, TRUE, 0); info->label_name = gtk_label_new(caption); gtk_widget_show(info->label_name); gtk_box_pack_start(GTK_BOX(hboxTabLabel), info->label_name, FALSE, FALSE, 0); if (has_exit) { info->button_exit = gtk_button_new(); gtk_widget_show(info->button_exit); gtk_box_pack_end(GTK_BOX(hboxTabLabel), info->button_exit , FALSE, FALSE, 0); gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &w, &h); gtk_widget_set_size_request(info->button_exit , w + 2, h + 2); gtk_button_set_relief(GTK_BUTTON(info->button_exit ), GTK_RELIEF_NONE); gtk_button_set_focus_on_click(GTK_BUTTON(info->button_exit), FALSE); info->image_exit = gtk_image_new_from_stock("gtk-close", GTK_ICON_SIZE_MENU); gtk_widget_show(info->image_exit); gtk_container_add(GTK_CONTAINER(info->button_exit), info->image_exit); } return hboxTabLabel; } void gm_widget_destroy_data(GtkWidget *caller, GtkWidget *destroyer) { if (GTK_IS_WIDGET(destroyer)) { gtk_widget_destroy(destroyer); } } const gchar * gm_default_charset() { const gchar *loc = NULL; g_get_charset(&loc); if (loc == NULL || strlen(loc) == 0) { loc = "ISO-8859-15"; } return loc; }