1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Naba Kumar <naba@gnome.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * SECTION:anjuta-utils
24 * @short_description: Utility functions
26 * @stability: Unstable
27 * @include: libanjuta/anjuta-utils.h
40 #include <sys/types.h>
41 #include <sys/fcntl.h>
42 #include <sys/termios.h>
52 #include <dbus/dbus-glib.h>
53 #include <glib/gi18n.h>
55 #include <glib/gstdio.h>
58 #include <gconf/gconf-client.h>
60 #include <libanjuta/anjuta-utils.h>
61 #include <libanjuta/anjuta-debug.h>
63 #define FILE_BUFFER_SIZE 1024
66 anjuta_util_from_file_to_file (GInputStream
*istream
,
67 GOutputStream
*ostream
)
71 gchar buffer
[FILE_BUFFER_SIZE
];
73 while (bytes
!= 0 && bytes
!= -1)
75 bytes
= g_input_stream_read (istream
, buffer
,
81 g_output_stream_write (ostream
, buffer
,
90 g_warning ("%s", error
->message
);
95 if (!g_output_stream_close (ostream
, NULL
, &error
))
97 g_warning ("%s", error
->message
);
101 if (!g_input_stream_close (istream
, NULL
, &error
))
103 g_warning ("%s", error
->message
);
104 g_error_free (error
);
109 * anjuta_util_copy_file:
110 * @src: the file where copy
111 * @dest: the path to copy the @src
112 * @show_error: TRUE to show a dialog error
114 * Copies @src to @dest and shows a dialog error in case is needed.
116 * Returns: TRUE if there was an error copying the file.
119 anjuta_util_copy_file (const gchar
* src
, const gchar
* dest
, gboolean show_error
)
121 GFile
*src_file
, *dest_file
;
122 GFileInputStream
*istream
;
123 GFileOutputStream
*ostream
;
124 GError
*error
= NULL
;
125 gboolean toret
= FALSE
;
127 src_file
= g_file_new_for_path (src
);
128 dest_file
= g_file_new_for_path (dest
);
130 istream
= g_file_read (src_file
, NULL
, &error
);
134 ostream
= g_file_create (dest_file
, G_FILE_CREATE_NONE
,
139 anjuta_util_from_file_to_file (G_INPUT_STREAM (istream
), G_OUTPUT_STREAM (ostream
));
144 anjuta_util_dialog_error_system (NULL
, error
->code
,
147 g_warning ("%s", error
->message
);
152 g_object_unref (src_file
);
153 g_object_unref (dest_file
);
159 anjuta_util_color_from_string (const gchar
* val
, guint16
* r
, guint16
* g
, guint16
* b
)
162 if (gdk_color_parse(val
, &color
))
171 anjuta_util_string_from_color (guint16 r
, guint16 g
, guint16 b
)
173 return g_strdup_printf("#%02x%02x%02x", r
>> 8, g
>> 8, b
>> 8);
177 anjuta_util_button_new_with_stock_image (const gchar
* text
,
178 const gchar
* stock_id
)
188 button
= gtk_button_new ();
190 child
= gtk_bin_get_child (GTK_BIN (button
));
192 gtk_container_remove (GTK_CONTAINER (button
), child
);
194 if (gtk_stock_lookup (stock_id
, &item
))
196 label
= gtk_label_new_with_mnemonic (text
);
198 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), GTK_WIDGET (button
));
200 image
= gtk_image_new_from_stock (stock_id
, GTK_ICON_SIZE_BUTTON
);
201 hbox
= gtk_hbox_new (FALSE
, 2);
203 align
= gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
205 gtk_box_pack_start (GTK_BOX (hbox
), image
, FALSE
, FALSE
, 0);
206 gtk_box_pack_end (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
208 gtk_container_add (GTK_CONTAINER (button
), align
);
209 gtk_container_add (GTK_CONTAINER (align
), hbox
);
210 gtk_widget_show_all (align
);
215 label
= gtk_label_new_with_mnemonic (text
);
216 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), GTK_WIDGET (button
));
218 gtk_misc_set_alignment (GTK_MISC (label
), 0.5, 0.5);
220 gtk_widget_show (label
);
221 gtk_container_add (GTK_CONTAINER (button
), label
);
227 anjuta_util_dialog_add_button (GtkDialog
*dialog
, const gchar
* text
,
228 const gchar
* stock_id
, gint response_id
)
232 g_return_val_if_fail (GTK_IS_DIALOG (dialog
), NULL
);
233 g_return_val_if_fail (text
!= NULL
, NULL
);
234 g_return_val_if_fail (stock_id
!= NULL
, NULL
);
236 button
= anjuta_util_button_new_with_stock_image (text
, stock_id
);
237 g_return_val_if_fail (button
!= NULL
, NULL
);
239 gtk_widget_set_can_default (button
, TRUE
);
241 gtk_widget_show (button
);
243 gtk_dialog_add_action_widget (dialog
, button
, response_id
);
249 anjuta_util_dialog_error (GtkWindow
*parent
, const gchar
*mesg
, ...)
254 GtkWindow
*real_parent
;
256 va_start (args
, mesg
);
257 message
= g_strdup_vprintf (mesg
, args
);
260 if (parent
&& GTK_IS_WINDOW (parent
))
262 real_parent
= parent
;
269 // Dialog to be HIG compliant
270 dialog
= gtk_message_dialog_new (real_parent
,
271 GTK_DIALOG_DESTROY_WITH_PARENT
,
273 GTK_BUTTONS_CLOSE
, "%s", message
);
274 g_signal_connect (G_OBJECT (dialog
), "response",
275 G_CALLBACK (gtk_widget_destroy
), NULL
);
276 gtk_widget_show (dialog
);
281 anjuta_util_dialog_warning (GtkWindow
*parent
, const gchar
* mesg
, ...)
286 GtkWindow
*real_parent
;
288 va_start (args
, mesg
);
289 message
= g_strdup_vprintf (mesg
, args
);
292 if (parent
&& GTK_IS_WINDOW (parent
))
294 real_parent
= parent
;
301 // Dialog to be HIG compliant
302 dialog
= gtk_message_dialog_new (real_parent
,
303 GTK_DIALOG_DESTROY_WITH_PARENT
,
305 GTK_BUTTONS_CLOSE
, "%s", message
);
306 g_signal_connect (G_OBJECT (dialog
), "response",
307 G_CALLBACK (gtk_widget_destroy
), NULL
);
308 gtk_widget_show (dialog
);
313 anjuta_util_dialog_info (GtkWindow
*parent
, const gchar
* mesg
, ...)
318 GtkWindow
*real_parent
;
320 va_start (args
, mesg
);
321 message
= g_strdup_vprintf (mesg
, args
);
324 if (parent
&& GTK_IS_WINDOW (parent
))
326 real_parent
= parent
;
332 // Dialog to be HIG compliant
333 dialog
= gtk_message_dialog_new (real_parent
,
334 GTK_DIALOG_DESTROY_WITH_PARENT
,
336 GTK_BUTTONS_CLOSE
, "%s", message
);
337 g_signal_connect (G_OBJECT (dialog
), "response",
338 G_CALLBACK (gtk_widget_destroy
), NULL
);
339 gtk_widget_show (dialog
);
344 anjuta_util_dialog_error_system (GtkWindow
* parent
, gint errnum
,
345 const gchar
* mesg
, ... )
351 GtkWindow
*real_parent
;
353 va_start (args
, mesg
);
354 message
= g_strdup_vprintf (mesg
, args
);
358 /* Avoid space in translated string */
359 tot_mesg
= g_strconcat (message
, "\n", _("System:"), " ",
360 g_strerror(errnum
), NULL
);
365 if (parent
&& GTK_IS_WINDOW (parent
))
367 real_parent
= parent
;
373 // Dialog to be HIG compliant
374 dialog
= gtk_message_dialog_new (real_parent
,
375 GTK_DIALOG_DESTROY_WITH_PARENT
,
377 GTK_BUTTONS_CLOSE
, "%s", tot_mesg
);
378 g_signal_connect (G_OBJECT (dialog
), "response",
379 G_CALLBACK (gtk_widget_destroy
), NULL
);
380 gtk_widget_show (dialog
);
385 anjuta_util_dialog_boolean_question (GtkWindow
*parent
, const gchar
*mesg
, ...)
391 GtkWindow
*real_parent
;
393 va_start (args
, mesg
);
394 message
= g_strdup_vprintf (mesg
, args
);
397 if (parent
&& GTK_IS_WINDOW (parent
))
399 real_parent
= parent
;
406 dialog
= gtk_message_dialog_new (real_parent
,
407 GTK_DIALOG_DESTROY_WITH_PARENT
,
408 GTK_MESSAGE_QUESTION
,
409 GTK_BUTTONS_YES_NO
, "%s", message
);
411 ret
= gtk_dialog_run (GTK_DIALOG (dialog
));
412 gtk_widget_destroy (dialog
);
415 return (ret
== GTK_RESPONSE_YES
);
419 anjuta_util_dialog_input (GtkWindow
*parent
, const gchar
*prompt
,
420 const gchar
*default_value
, gchar
**return_value
)
422 GtkWidget
*dialog
, *label
, *frame
, *entry
, *dialog_vbox
, *vbox
;
425 GtkWindow
*real_parent
;
427 if (parent
&& GTK_IS_WINDOW (parent
))
429 real_parent
= parent
;
436 dialog
= gtk_dialog_new_with_buttons (prompt
, real_parent
,
437 GTK_DIALOG_DESTROY_WITH_PARENT
,
438 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
439 GTK_STOCK_OK
, GTK_RESPONSE_OK
,
441 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_OK
);
442 dialog_vbox
= gtk_dialog_get_content_area (GTK_DIALOG (dialog
));
443 gtk_window_set_default_size (GTK_WINDOW (dialog
), 400, -1);
444 gtk_widget_show (dialog_vbox
);
446 markup
= g_strconcat ("<b>", prompt
, "</b>", NULL
);
447 label
= gtk_label_new (NULL
);
448 gtk_label_set_markup (GTK_LABEL (label
), markup
);
449 gtk_widget_show (label
);
452 frame
= gtk_frame_new (NULL
);
453 gtk_frame_set_label_widget (GTK_FRAME (frame
), label
);
454 gtk_frame_set_shadow_type (GTK_FRAME (frame
), GTK_SHADOW_NONE
);
455 gtk_container_set_border_width (GTK_CONTAINER (frame
), 10);
456 gtk_widget_show (frame
);
457 gtk_box_pack_start (GTK_BOX (dialog_vbox
), frame
, FALSE
, FALSE
, 0);
459 vbox
= gtk_vbox_new (FALSE
, 0);
460 gtk_widget_show (vbox
);
461 gtk_container_set_border_width (GTK_CONTAINER (vbox
), 10);
462 gtk_container_add (GTK_CONTAINER (frame
), vbox
);
464 entry
= gtk_entry_new ();
465 gtk_widget_show (entry
);
466 gtk_entry_set_activates_default (GTK_ENTRY (entry
), TRUE
);
467 gtk_box_pack_start (GTK_BOX (vbox
), entry
, FALSE
, FALSE
, 0);
469 gtk_entry_set_text (GTK_ENTRY (entry
), default_value
);
471 res
= gtk_dialog_run (GTK_DIALOG (dialog
));
473 if (gtk_entry_get_text (GTK_ENTRY (entry
)) &&
474 strlen (gtk_entry_get_text (GTK_ENTRY (entry
))) > 0)
476 *return_value
= g_strdup (gtk_entry_get_text (GTK_ENTRY (entry
)));
480 *return_value
= NULL
;
482 gtk_widget_destroy (dialog
);
483 return (res
== GTK_RESPONSE_OK
);
487 on_install_files_done (DBusGProxy
*proxy
, DBusGProxyCall
*call_id
,
490 GError
*error
= NULL
;
491 dbus_g_proxy_end_call (proxy
, call_id
, &error
, G_TYPE_INVALID
);
495 Only dbus error is handled. Rest of the errors are from packagekit
496 which have already been notified to user by packagekit.
498 if (error
->domain
== DBUS_GERROR
)
500 const gchar
*error_message
= NULL
;
502 /* Service error which implies packagekit is missing */
503 if (error
->code
== DBUS_GERROR_SERVICE_UNKNOWN
)
505 error_message
= _("You do not seem to have PackageKit installed. PackageKit is required for installing missing packages. Please install \"packagekit-gnome\" package from your distribution, or install the missing packages manually.");
507 /* General dbus error implies failure to call dbus method */
508 else if (error
->code
!= DBUS_GERROR_REMOTE_EXCEPTION
&&
509 error
->code
!= DBUS_GERROR_NO_REPLY
)
511 error_message
= error
->message
;
514 anjuta_util_dialog_error (NULL
,
515 _("Installation failed: %s"),
518 g_error_free (error
);
523 anjuta_util_install_files (const gchar
* const names
)
525 DBusGConnection
* connection
;
533 connection
= dbus_g_bus_get (DBUS_BUS_SESSION
, NULL
);
537 proxy
= dbus_g_proxy_new_for_name (connection
,
538 "org.freedesktop.PackageKit",
539 "/org/freedesktop/PackageKit",
540 "org.freedesktop.PackageKit.Modify");
544 pkgv
= g_strsplit (names
, ", ", 0);
545 dbus_g_proxy_begin_call (proxy
, "InstallProvideFiles",
546 on_install_files_done
, NULL
, NULL
,
550 G_TYPE_INVALID
, G_TYPE_INVALID
);
556 anjuta_util_package_is_installed (const gchar
* package
, gboolean show
)
558 gboolean installed
= FALSE
;
563 if ((pid
= fork()) == 0)
564 execlp ("pkg-config", "pkg-config", "--exists", package
, NULL
);
566 waitpid (pid
, &status
, 0);
567 exit_status
= WEXITSTATUS (status
);
568 installed
= (exit_status
== 0) ? TRUE
: FALSE
;
574 anjuta_util_dialog_error (NULL
,
575 _("The \"%s\" package is not installed.\n"
576 "Please install it."), package
);
583 anjuta_util_prog_is_installed (const gchar
* prog
, gboolean show
)
585 gchar
* prog_path
= g_find_program_in_path (prog
);
593 anjuta_util_dialog_error (NULL
, _("The \"%s\" utility is not installed.\n"
594 "Please install it."), prog
);
600 anjuta_util_get_a_tmp_file (void)
602 static gint count
= 0;
606 tmpdir
= g_get_tmp_dir ();
608 g_strdup_printf ("%s/anjuta_%d.%d", tmpdir
, count
++, getpid ());
612 /* GList of strings operations */
614 anjuta_util_glist_from_string (const gchar
*string
)
616 gchar
*str
, *temp
, buff
[256];
618 gchar
*word_start
, *word_end
;
623 temp
= g_strdup (string
);
633 /* Remove leading spaces */
634 while (isspace (*str
) && *str
!= '\0')
639 /* Find start and end of word */
641 while (!isspace (*str
) && *str
!= '\0')
645 /* Copy the word into the buffer */
646 for (ptr
= word_start
, i
= 0; ptr
< word_end
; ptr
++, i
++)
650 list
= g_list_append (list
, g_strdup (buff
));
659 /* Prefix the strings */
661 anjuta_util_glist_strings_prefix (GList
* list
, const gchar
*prefix
)
666 g_return_if_fail (prefix
!= NULL
);
671 node
->data
= g_strconcat (prefix
, tmp
, NULL
);
672 if (tmp
) g_free (tmp
);
673 node
= g_list_next (node
);
677 /* Suffix the strings */
679 anjuta_util_glist_strings_sufix (GList
* list
, const gchar
*sufix
)
684 g_return_if_fail (sufix
!= NULL
);
689 node
->data
= g_strconcat (tmp
, sufix
, NULL
);
690 if (tmp
) g_free (tmp
);
691 node
= g_list_next (node
);
695 /* Duplicate list of strings */
697 anjuta_util_glist_strings_dup (GList
* list
)
707 new_list
= g_list_append (new_list
, g_strdup(node
->data
));
709 new_list
= g_list_append (new_list
, NULL
);
710 node
= g_list_next (node
);
715 /* Join list of strings using the given delimiter */
717 anjuta_util_glist_strings_join (GList
* list
, gchar
*delimiter
)
720 gboolean first
= TRUE
;
723 joined
= g_string_new (NULL
);
730 g_string_append (joined
, delimiter
);
733 g_string_append (joined
, node
->data
);
735 node
= g_list_next (node
);
738 return g_string_free (joined
, FALSE
);
740 g_string_free (joined
, TRUE
);
745 anjuta_util_get_real_path (const gchar
*path
)
751 gchar buf
[PATH_MAX
+1];
753 result
= realpath (path
, buf
);
756 *(buf
+ PATH_MAX
) = '\0'; /* ensure a terminator */
757 return g_strdup (buf
);
761 /* the string returned by realpath should be cleaned with
762 free(), not g_free() */
763 buf
= realpath (path
, NULL
);
766 result
= g_strdup (buf
);
776 * anjuta_util_get_current_dir:
778 * Get current working directory, unlike g_get_current_dir, keeps symbolic links
781 * Returns: The current working directory.
784 anjuta_util_get_current_dir (void)
788 pwd
= g_getenv ("PWD");
791 return g_strdup (pwd
);
795 return g_get_current_dir ();
800 is_valid_scheme_character (char c
)
802 return g_ascii_isalnum (c
) || c
== '+' || c
== '-' || c
== '.';
805 /* Following RFC 2396, valid schemes are built like:
806 * scheme = alpha *( alpha | digit | "+" | "-" | "." )
809 has_valid_scheme (const char *uri
)
815 if (!g_ascii_isalpha (*p
))
820 } while (is_valid_scheme_character (*p
));
826 * anjuta_util_file_new_for_commandline_arg:
828 * @arg: URI or relative or absolute file path
830 * Create a new file corresponding to arg, unlike g_file_new_for_commandline_arg,
831 * keeps symbolic links in path name.
833 * Returns: A new GFile object
836 anjuta_util_file_new_for_commandline_arg (const gchar
*arg
)
842 g_return_val_if_fail (arg
!= NULL
, NULL
);
844 if (g_path_is_absolute (arg
))
845 return g_file_new_for_path (arg
);
847 if (has_valid_scheme (arg
))
848 return g_file_new_for_uri (arg
);
850 current_dir
= anjuta_util_get_current_dir ();
851 filename
= g_build_filename (current_dir
, arg
, NULL
);
852 g_free (current_dir
);
854 file
= g_file_new_for_path (filename
);
861 /* Dedup a list of paths - duplicates are removed from the tail.
862 ** Useful for deduping Recent Files and Recent Projects */
864 anjuta_util_glist_path_dedup(GList
*list
)
866 GList
*nlist
= NULL
, *tmp
, *tmp1
;
869 for (tmp
= list
; tmp
; tmp
= g_list_next(tmp
))
871 path
= anjuta_util_get_real_path ((const gchar
*) tmp
->data
);
874 if (stat (path
, &s
) != 0)
880 for (tmp1
= nlist
; tmp1
; tmp1
= g_list_next(tmp1
))
882 if (0 == strcmp((const char *) tmp1
->data
, path
))
890 nlist
= g_list_prepend(nlist
, path
);
894 anjuta_util_glist_strings_free(list
);
895 nlist
= g_list_reverse(nlist
);
900 sort_node (gchar
* a
, gchar
*b
)
902 if ( !a
&& !b
) return 0;
903 else if (!a
) return -1;
904 else if (!b
) return 1;
905 return strcmp (a
, b
);
908 /* Sort the list alphabatically */
910 anjuta_util_glist_strings_sort (GList
* list
)
912 return g_list_sort(list
, (GCompareFunc
)sort_node
);
915 /* Free the strings and GList */
917 anjuta_util_glist_strings_free (GList
* list
)
925 node
= g_list_next (node
);
931 anjuta_util_type_from_string (AnjutaUtilStringMap
*map
, const char *str
)
935 while (-1 != map
[i
].type
)
937 if (0 == strcmp(map
[i
].name
, str
))
945 anjuta_util_string_from_type (AnjutaUtilStringMap
*map
, int type
)
948 while (-1 != map
[i
].type
)
950 if (map
[i
].type
== type
)
958 anjuta_util_glist_from_map (AnjutaUtilStringMap
*map
)
960 GList
*out_list
= NULL
;
962 while (-1 != map
[i
].type
)
964 out_list
= g_list_append(out_list
, map
[i
].name
);
972 anjuta_util_update_string_list (GList
*p_list
, const gchar
*p_str
, gint length
)
978 for (i
= 0; i
< g_list_length (p_list
); i
++)
980 str
= (gchar
*) g_list_nth_data (p_list
, i
);
983 if (strcmp (p_str
, str
) == 0)
985 p_list
= g_list_remove (p_list
, str
);
986 p_list
= g_list_prepend (p_list
, str
);
990 p_list
= g_list_prepend (p_list
, g_strdup (p_str
));
991 while (g_list_length (p_list
) > length
)
993 str
= g_list_nth_data (p_list
, g_list_length (p_list
) - 1);
994 p_list
= g_list_remove (p_list
, str
);
1001 anjuta_util_create_dir (const gchar
* path
)
1003 GFile
*dir
= g_file_new_for_path (path
);
1007 if (g_file_query_exists (dir
, NULL
))
1009 GFileInfo
*info
= g_file_query_info (dir
,
1010 G_FILE_ATTRIBUTE_STANDARD_TYPE
,
1011 G_FILE_QUERY_INFO_NONE
,
1013 if (g_file_info_get_file_type (info
) != G_FILE_TYPE_DIRECTORY
)
1015 g_message ("Warning: %s is a file. \n "
1016 "It is trying to be treated as a directory.",g_file_get_path (dir
));
1017 g_object_unref (dir
);
1020 g_object_unref (info
);
1024 parent
= g_path_get_dirname (path
);
1025 if (anjuta_util_create_dir (parent
))
1028 if (!g_file_make_directory (dir
, NULL
, &err
))
1030 g_warning ("Error directory:\n %s", err
->message
);
1031 g_object_unref (dir
);
1038 g_object_unref (dir
);
1042 g_object_unref (dir
);
1048 * anjuta_util_user_shell:
1050 * Retrieves the user's preferred shell.
1052 * Returns: A newly allocated string that is the path to the shell.
1054 /* copied from deprecated gnome_util_user_shell in libgnome */
1056 anjuta_util_user_shell (void)
1062 const gchar shells
[][14] = {
1063 /* Note that on some systems shells can also
1064 * be installed in /usr/bin */
1065 "/bin/bash", "/usr/bin/bash",
1066 "/bin/zsh", "/usr/bin/zsh",
1067 "/bin/tcsh", "/usr/bin/tcsh",
1068 "/bin/ksh", "/usr/bin/ksh",
1069 "/bin/csh", "/bin/sh"
1072 if (geteuid () == getuid () &&
1073 getegid () == getgid ()) {
1074 /* only in non-setuid */
1075 if ((shell
= g_getenv ("SHELL"))){
1076 if (access (shell
, X_OK
) == 0) {
1077 return g_strdup (shell
);
1081 pw
= getpwuid(getuid());
1082 if (pw
&& pw
->pw_shell
) {
1083 if (access (pw
->pw_shell
, X_OK
) == 0) {
1084 return g_strdup (pw
->pw_shell
);
1088 for (i
= 0; i
!= G_N_ELEMENTS (shells
); i
++) {
1089 if (access (shells
[i
], X_OK
) == 0) {
1090 return g_strdup (shells
[i
]);
1094 /* If /bin/sh doesn't exist, your system is truly broken. */
1097 /* Placate compiler. */
1100 /* g_find_program_in_path() always looks also in the Windows
1101 * and System32 directories, so it should always find either cmd.exe
1104 gchar
*retval
= g_find_program_in_path ("cmd.exe");
1107 retval
= g_find_program_in_path ("command.com");
1109 g_assert (retval
!= NULL
);
1116 * anjuta_util_user_terminal:
1118 * Retrieves the user's preferred terminal.
1120 * Returns: A newly allocated strings list. The first argument is the terminal
1121 * program name. The following are the arguments needed to execute
1122 * a command. The list has to be freed with g_strfreev
1124 /* copied from deprecated gnome_execute_terminal in libgnome */
1126 anjuta_util_user_terminal (void)
1129 GConfClient
*client
;
1130 gchar
*terminal
= NULL
;
1131 gchar
**argv
= NULL
;
1132 static const gchar
*terms
[] = {
1144 client
= gconf_client_get_default ();
1145 terminal
= gconf_client_get_string (client
, "/desktop/gnome/applications/terminal/exec", NULL
);
1146 g_object_unref (client
);
1150 gchar
*command_line
;
1153 exec_flag
= gconf_client_get_string (client
, "/desktop/gnome/applications/terminal/exec_arg", NULL
);
1154 command_line
= g_strconcat (terminal
, " ", exec_flag
, NULL
);
1156 g_shell_parse_argv (command_line
, NULL
, &argv
, NULL
);
1164 /* Search for common ones */
1165 for (term
= terms
; *term
!= NULL
; term
++)
1167 terminal
= g_find_program_in_path (*term
);
1168 if (terminal
!= NULL
) break;
1172 g_warning (_("Cannot find a terminal; using "
1173 "xterm, even if it may not work"));
1174 terminal
= g_strdup ("xterm");
1176 argv
= g_new0 (char *, 3);
1178 /* Note that gnome-terminal takes -x and
1179 * as -e in gnome-terminal is broken we use that. */
1180 argv
[1] = g_strdup (term
== &terms
[2] ? "-x" : "-e");
1184 g_warning ("anjuta_util_user_terminal: Not implemented");
1190 anjuta_util_execute_shell (const gchar
*dir
, const gchar
*command
)
1196 g_return_val_if_fail (command
!= NULL
, -1);
1198 shell
= anjuta_util_user_shell ();
1204 anjuta_util_create_dir (dir
);
1207 execlp (shell
, shell
, "-c", command
, NULL
);
1208 g_warning (_("Cannot execute command: %s (using shell %s)\n"), command
, shell
);
1212 g_warning (_("Cannot execute command: %s (using shell %s)\n"), command
, shell
);
1215 // Anjuta will take care of child exit automatically.
1220 anjuta_util_execute_terminal_shell (const gchar
*dir
, const gchar
*command
)
1227 g_return_val_if_fail (command
!= NULL
, -1);
1229 shell
= anjuta_util_user_shell ();
1230 term_argv
= anjuta_util_user_terminal ();
1236 anjuta_util_create_dir (dir
);
1239 execlp (term_argv
[0], term_argv
[0], term_argv
[1], shell
, "-c", command
, NULL
);
1240 g_warning (_("Cannot execute command: %s (using shell %s)\n"), command
, shell
);
1244 g_warning (_("Cannot execute command: %s (using shell %s)\n"), command
, shell
);
1246 g_strfreev (term_argv
);
1248 // Anjuta will take care of child exit automatically.
1253 anjuta_util_convert_to_utf8 (const gchar
*str
)
1255 GError
*error
= NULL
;
1256 gchar
*utf8_msg_string
= NULL
;
1258 g_return_val_if_fail (str
!= NULL
, NULL
);
1259 g_return_val_if_fail (strlen (str
) > 0, NULL
);
1261 if (g_utf8_validate(str
, -1, NULL
))
1263 utf8_msg_string
= g_strdup (str
);
1267 gsize rbytes
, wbytes
;
1268 utf8_msg_string
= g_locale_to_utf8 (str
, -1, &rbytes
, &wbytes
, &error
);
1269 if (error
!= NULL
) {
1270 g_warning ("g_locale_to_utf8 failed: %s\n", error
->message
);
1271 g_error_free (error
);
1272 /* g_free (utf8_msg_string);
1276 return utf8_msg_string
;
1280 anjuta_util_parse_args_from_string (const gchar
* string
)
1284 gboolean is_quote
= FALSE
;
1285 gchar
* buffer
= g_new0(gchar
, strlen(string
) + 1);
1302 /* The current char was escaped */
1305 } else if (*s
== '\\') {
1306 /* Current char is an escape */
1308 } else if (is_quote
&& *s
== quote
) {
1309 /* Current char ends a quotation */
1311 if (!isspace(*(s
+1)) && (*(s
+1) != '\0')) {
1312 /* If there is no space after the quotation or it is not
1313 the end of the string */
1314 g_warning ("Parse error while parsing program arguments");
1316 } else if ((*s
== '\"' || *s
== '\'')) {
1318 /* Current char starts a quotation */
1322 /* Just a quote char inside quote */
1325 } else if (is_quote
){
1326 /* Any other char inside quote */
1328 } else if (isspace(*s
)) {
1329 /* Any white space outside quote */
1331 buffer
[idx
++] = '\0';
1332 args
= g_list_append (args
, g_strdup (buffer
));
1341 /* There are chars in the buffer. Flush as the last arg */
1342 buffer
[idx
++] = '\0';
1343 args
= g_list_append (args
, g_strdup (buffer
));
1347 g_warning ("Unclosed quotation encountered at the end of parsing");
1354 anjuta_util_escape_quotes(const gchar
* str
)
1358 const gchar
*s
= str
;
1360 g_return_val_if_fail(str
, NULL
);
1363 /* We are assuming there will be less than 2048 chars to escape */
1364 max_size
= strlen(str
) + 2048;
1365 buffer
= g_new (gchar
, max_size
);
1371 if (*s
== '\"' || *s
== '\'' || *s
== '\\')
1372 buffer
[idx
++] = '\\';
1380 /* Diff the text contained in uri with text. Return true if files
1381 differ, FALSE if they are identical.*/
1383 gboolean
anjuta_util_diff(const gchar
* uri
, const gchar
* text
)
1386 GFileInfo
*file_info
;
1388 gchar
* file_text
= NULL
;
1391 file
= g_file_new_for_uri (uri
);
1392 file_info
= g_file_query_info (file
,
1393 G_FILE_ATTRIBUTE_STANDARD_SIZE
,
1394 G_FILE_QUERY_INFO_NONE
,
1398 if (file_info
== NULL
)
1400 g_object_unref (file
);
1404 size
= g_file_info_get_attribute_uint64(file_info
,
1405 G_FILE_ATTRIBUTE_STANDARD_SIZE
);
1406 g_object_unref (file_info
);
1408 if (size
== 0 && text
== NULL
)
1410 g_object_unref (file
);
1413 else if (size
== 0 || text
== NULL
)
1415 g_object_unref (file
);
1419 if (!g_file_load_contents(file
,
1426 g_object_unref (file
);
1429 g_object_unref (file
);
1431 if (bytes_read
!= size
)
1437 /* according to g_file_load_contents's documentation
1438 * file_text is guaranteed to end with \0.
1440 if (strcmp (file_text
, text
) == 0)
1451 * anjuta_util_is_project_file:
1452 * @filename: the file name
1454 * Return TRUE if the file is an anjuta project file. It is implemented by
1455 * checking only the file extension. So it does not check the existence
1456 * of the file. But it is working on an URI if it does not containt a
1459 * Returns: TRUE if the file is a project file, else FALSE
1462 anjuta_util_is_project_file (const gchar
*filename
)
1464 gsize len
= strlen (filename
);
1465 return ((len
> 8) && (strcmp (filename
+ len
- 7, ".anjuta") == 0));
1469 * anjuta_util_is_template_file:
1470 * @filename: the file name
1472 * Return TRUE if the file is an template project file. It is implemented by
1473 * checking only the file extension. So it does not check the existence
1474 * of the file. But it is working on an URI if it does not containt a
1477 * Returns: TRUE if the file is a template file, else FALSE
1480 anjuta_util_is_template_file (const gchar
*filename
)
1482 gsize len
= strlen (filename
);
1483 return ((len
> 9) && (strcmp (filename
+ len
- 8, ".wiz.tgz") == 0));
1487 * anjuta_util_get_file_mine_type:
1490 * Check if a file exists and return its mime type.
1492 * Returns: NULL if the corresponding file doesn't exist or the mime type as a newly
1493 * allocated string that must be freed with g_free().
1496 anjuta_util_get_file_mime_type (GFile
*file
)
1499 gchar
*mime_type
= NULL
;
1501 g_return_val_if_fail (file
!= NULL
, NULL
);
1503 /* Get file information, check that the file exist at the same time */
1504 info
= g_file_query_info (file
,
1505 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
,
1506 G_FILE_QUERY_INFO_NONE
,
1512 const gchar
*extension
;
1515 /* If Anjuta is not installed in system gnome prefix, the mime types
1516 * may not have been correctly registed. In that case, we use the
1517 * following mime detection
1519 name
= g_file_get_basename (file
);
1520 extension
= strrchr(name
, '.');
1521 if (extension
!= NULL
)
1523 const static struct {gchar
*extension
; gchar
*type
;} anjuta_types
[] = {
1524 {"anjuta", "application/x-anjuta"},
1525 {"prj", "application/x-anjuta-old"},
1529 for (i
= 0; anjuta_types
[i
].extension
!= NULL
; i
++)
1531 if (strcmp(extension
+ 1, anjuta_types
[i
].extension
) == 0)
1533 mime_type
= g_strdup (anjuta_types
[i
].type
);
1540 /* Use mime database if it is not an Anjuta type */
1541 if (mime_type
== NULL
)
1543 mime_type
= g_content_type_get_mime_type (g_file_info_get_content_type(info
));
1546 g_object_unref (info
);
1553 anjuta_util_get_local_path_from_uri (const gchar
*uri
)
1558 file
= g_file_new_for_uri (uri
);
1559 local_path
= g_file_get_path (file
);
1560 g_object_unref (file
);
1565 #ifdef EMULATE_FORKPTY
1568 static int ptym_open (char *pts_name
);
1569 static int ptys_open (int fdm
, char * pts_name
);
1572 login_tty(int ttyfd
)
1584 /* First disconnect from the old controlling tty. */
1586 fd
= open("/dev/tty", O_RDWR
|O_NOCTTY
);
1589 ioctl(fd
, TIOCNOTTY
, NULL
);
1593 //syslog(LOG_WARNING, "NO CTTY");
1594 #endif /* TIOCNOTTY */
1596 /* Verify that we are successfully disconnected from the controlling tty. */
1597 fd
= open("/dev/tty", O_RDWR
|O_NOCTTY
);
1600 //syslog(LOG_WARNING, "Failed to disconnect from controlling tty.");
1604 /* Make it our controlling tty. */
1606 ioctl(ttyfd
, TIOCSCTTY
, NULL
);
1607 #endif /* TIOCSCTTY */
1609 fdname
= ttyname (ttyfd
);
1610 fd
= open(fdname
, O_RDWR
);
1612 ;//syslog(LOG_WARNING, "open %s: %s", fdname, strerror(errno));
1616 /* Verify that we now have a controlling tty. */
1617 fd
= open("/dev/tty", O_WRONLY
);
1620 //syslog(LOG_WARNING, "open /dev/tty: %s", strerror(errno));
1625 #if defined(HAVE_VHANGUP) && !defined(HAVE_REVOKE)
1627 RETSIGTYPE (*sig
)();
1628 sig
= signal(SIGHUP
, SIG_IGN
);
1630 signal(SIGHUP
, sig
);
1633 fd
= open(fdname
, O_RDWR
);
1636 //syslog(LOG_ERR, "can't reopen ctty %s: %s", fdname, strerror(errno));
1658 openpty(int *amaster
, int *aslave
, char *name
, struct termios
*termp
,
1659 struct winsize
*winp
)
1662 *amaster
= ptym_open(line
);
1665 *aslave
= ptys_open(*amaster
, line
);
1673 #define TCSAFLUSH TCSETAF
1676 (void) tcsetattr(*aslave
, TCSAFLUSH
, termp
);
1679 (void) ioctl(*aslave
, TIOCSWINSZ
, (char *)winp
);
1685 ptym_open(char * pts_name
)
1691 strcpy(pts_name
, "/dev/ptmx");
1692 fdm
= open(pts_name
, O_RDWR
);
1695 if (grantpt(fdm
) < 0) { /* grant access to slave */
1699 if (unlockpt(fdm
) < 0) { /* clear slave's lock flag */
1704 if (ptr
== NULL
) { /* get slave's name */
1708 strcpy(pts_name
, ptr
); /* return name of slave */
1709 return fdm
; /* return fd of master */
1713 strcpy(pts_name
, "/dev/ptyXY");
1714 /* array index: 012345689 (for references in following code) */
1715 for (ptr1
= "pqrstuvwxyzPQRST"; *ptr1
!= 0; ptr1
++) {
1716 pts_name
[8] = *ptr1
;
1717 for (ptr2
= "0123456789abcdef"; *ptr2
!= 0; ptr2
++) {
1718 pts_name
[9] = *ptr2
;
1719 /* try to open master */
1720 fdm
= open(pts_name
, O_RDWR
);
1722 if (errno
== ENOENT
) /* different from EIO */
1723 return -1; /* out of pty devices */
1725 continue; /* try next pty device */
1727 pts_name
[5] = 't'; /* chage "pty" to "tty" */
1728 return fdm
; /* got it, return fd of master */
1731 return -1; /* out of pty devices */
1736 ptys_open(int fdm
, char * pts_name
)
1740 /* following should allocate controlling terminal */
1741 fds
= open(pts_name
, O_RDWR
);
1746 if (ioctl(fds
, I_PUSH
, "ptem") < 0) {
1751 if (ioctl(fds
, I_PUSH
, "ldterm") < 0) {
1756 if (ioctl(fds
, I_PUSH
, "ttcompat") < 0) {
1762 if (ioctl(fdm
, I_PUSH
, "pckt") < 0) {
1768 if (ioctl(fdm
, I_SRDOPT
, RMSGN
|RPROTDAT
) < 0) {
1777 struct group
*grptr
;
1779 grptr
= getgrnam("tty");
1781 gid
= grptr
->gr_gid
;
1783 gid
= -1; /* group tty is not in the group file */
1784 /* following two functions don't work unless we're root */
1785 chown(pts_name
, getuid(), gid
);
1786 chmod(pts_name
, S_IRUSR
| S_IWUSR
| S_IWGRP
);
1787 fds
= open(pts_name
, O_RDWR
);
1797 forkpty(int *amaster
, char *name
, struct termios
*termp
, struct winsize
*winp
)
1799 int master
, slave
, pid
;
1801 if (openpty(&master
, &slave
, name
, termp
, winp
) == -1)
1803 switch (pid
= fork()) {
1822 int scandir(const char *dir
, struct dirent
***namelist
,
1823 int (*select
)(const struct dirent
*),
1824 int (*compar
)(const struct dirent
**, const struct dirent
**))
1827 struct dirent
*entry
;
1831 if ((d
=opendir(dir
)) == NULL
)
1835 while ((entry
=readdir(d
)) != NULL
)
1837 if (select
== NULL
|| (select
!= NULL
&& (*select
)(entry
)))
1839 *namelist
=(struct dirent
**)realloc((void *)(*namelist
),
1840 (size_t)((i
+1)*sizeof(struct dirent
*)));
1841 if (*namelist
== NULL
) return(-1);
1842 entrysize
=sizeof(struct dirent
)-sizeof(entry
->d_name
)+strlen(entry
->d_name
)+1;
1843 (*namelist
)[i
]=(struct dirent
*)malloc(entrysize
);
1844 if ((*namelist
)[i
] == NULL
) return(-1);
1845 memcpy((*namelist
)[i
], entry
, entrysize
);
1849 if (closedir(d
)) return(-1);
1850 if (i
== 0) return(-1);
1852 qsort((void *)(*namelist
), (size_t)i
, sizeof(struct dirent
*), compar
);
1857 #endif /* EMULATE_FORKPTY */
1860 anjuta_util_help_display (GtkWidget
*parent
,
1861 const gchar
*doc_id
,
1862 const gchar
*file_name
)
1865 GError
*error
= NULL
;
1869 const gchar
* const *langs
;
1873 g_return_if_fail (file_name
!= NULL
);
1875 langs
= g_get_language_names ();
1876 for (i
= 0; langs
[i
]; i
++)
1879 if (strchr (lang
, '.'))
1882 uri
= g_build_filename (DATADIR
, "/gnome/help/", doc_id
,
1883 lang
, file_name
, NULL
);
1885 if (g_file_test (uri
, G_FILE_TEST_EXISTS
)) {
1894 anjuta_util_dialog_error (GTK_WINDOW (parent
), _("Unable to display help. Please make sure the Anjuta "
1895 "documentation package is installed. It can be downloaded "
1896 "from http://anjuta.org."));
1901 command
= g_strconcat ("gnome-help ghelp://", uri
, NULL
);
1904 screen
= gtk_widget_get_screen (GTK_WIDGET (parent
));
1905 gdk_spawn_command_line_on_screen (screen
, command
, &error
);
1908 g_warning ("Error executing help application: %s",
1910 g_error_free (error
);
1917 /* The following functions are taken from gedit */
1919 /* Note that this function replace home dir with ~ */
1921 anjuta_util_uri_get_dirname (const gchar
*uri
)
1926 // CHECK: does it work with uri chaining? - Paolo
1927 str
= g_path_get_dirname (uri
);
1928 g_return_val_if_fail (str
!= NULL
, ".");
1930 if ((strlen (str
) == 1) && (*str
== '.'))
1937 res
= anjuta_util_replace_home_dir_with_tilde (str
);
1945 anjuta_util_replace_home_dir_with_tilde (const gchar
*uri
)
1950 g_return_val_if_fail (uri
!= NULL
, NULL
);
1952 /* Note that g_get_home_dir returns a const string */
1953 tmp
= (gchar
*)g_get_home_dir ();
1956 return g_strdup (uri
);
1958 home
= g_filename_to_utf8 (tmp
, -1, NULL
, NULL
, NULL
);
1960 return g_strdup (uri
);
1962 if (strcmp (uri
, home
) == 0)
1966 return g_strdup ("~");
1970 home
= g_strdup_printf ("%s/", tmp
);
1973 if (g_str_has_prefix (uri
, home
))
1977 res
= g_strdup_printf ("~/%s", uri
+ strlen (home
));
1986 return g_strdup (uri
);
1990 * anjuta_util_shell_expand:
1991 * @string: input string
1993 * Expand environment variables $(var_name) and tilde (~) in the input string.
1995 * Returns: a newly-allocated string that must be freed with g_free().
1998 anjuta_util_shell_expand (const gchar
*string
)
2002 if (string
== NULL
) return NULL
;
2004 expand
= g_string_sized_new (strlen (string
));
2006 for (; *string
!= '\0'; string
++)
2012 /* Variable expansion */
2017 while (isalnum (*end
) || (*end
== '_')) end
++;
2018 var_name_len
= end
- string
- 1;
2019 if (var_name_len
> 0)
2023 g_string_append_len (expand
, string
+ 1, var_name_len
);
2024 value
= g_getenv (expand
->str
+ expand
->len
- var_name_len
);
2025 g_string_truncate (expand
, expand
->len
- var_name_len
);
2026 g_string_append (expand
, value
);
2034 /* User home directory expansion */
2035 if (isspace(string
[1]) || (string
[1] == G_DIR_SEPARATOR
) || (string
[1] == '\0'))
2037 g_string_append (expand
, g_get_home_dir());
2045 g_string_append_c (expand
, *string
);
2048 return g_string_free (expand
, FALSE
);
2052 anjuta_util_str_middle_truncate (const gchar
*string
,
2053 guint truncate_length
)
2058 guint num_left_chars
;
2060 guint delimiter_length
;
2061 const gchar
*delimiter
= "\342\200\246";
2063 g_return_val_if_fail (string
!= NULL
, NULL
);
2065 length
= strlen (string
);
2067 g_return_val_if_fail (g_utf8_validate (string
, length
, NULL
), NULL
);
2069 /* It doesnt make sense to truncate strings to less than
2070 * the size of the delimiter plus 2 characters (one on each
2073 delimiter_length
= g_utf8_strlen (delimiter
, -1);
2074 if (truncate_length
< (delimiter_length
+ 2)) {
2075 return g_strdup (string
);
2078 n_chars
= g_utf8_strlen (string
, length
);
2080 /* Make sure the string is not already small enough. */
2081 if (n_chars
<= truncate_length
) {
2082 return g_strdup (string
);
2085 /* Find the 'middle' where the truncation will occur. */
2086 num_left_chars
= (truncate_length
- delimiter_length
) / 2;
2087 right_offset
= n_chars
- truncate_length
+ num_left_chars
+ delimiter_length
;
2089 truncated
= g_string_new_len (string
,
2090 g_utf8_offset_to_pointer (string
, num_left_chars
) - string
);
2091 g_string_append (truncated
, delimiter
);
2092 g_string_append (truncated
, g_utf8_offset_to_pointer (string
, right_offset
));
2094 return g_string_free (truncated
, FALSE
);
2098 * Functions to implement XDG Base Directory Specification
2099 * http://standards.freedesktop.org/basedir-spec/latest/index.html
2100 * Use this to save any config/cache/data files
2105 anjuta_util_construct_pathv (const gchar
* str
, va_list str_list
)
2108 const gchar
* tmp_str
;
2111 str_arr
= g_ptr_array_new();
2112 g_ptr_array_add (str_arr
, (gpointer
) str
);
2114 /* Extract elements from va_list */
2117 while ((tmp_str
= va_arg (str_list
, const gchar
*)) != NULL
)
2119 g_ptr_array_add (str_arr
, (gpointer
)tmp_str
);
2124 /* Terminate the list */
2125 g_ptr_array_add (str_arr
, NULL
);
2127 path
= g_build_filenamev ((gchar
**)str_arr
->pdata
);
2128 g_ptr_array_free (str_arr
, TRUE
);
2134 anjuta_util_get_user_cache_filev (const gchar
* path
, va_list list
)
2136 gchar
*uri_str
, *base_path
, *dir
;
2138 const gchar anjuta_prefix
[] = "anjuta";
2139 base_path
= g_build_filename (g_get_user_cache_dir(), anjuta_prefix
, path
, NULL
);
2141 uri_str
= anjuta_util_construct_pathv (base_path
, list
);
2144 uri
= g_file_new_for_path (uri_str
);
2145 dir
= g_path_get_dirname (uri_str
);
2147 if (!anjuta_util_create_dir (dir
)) return NULL
;
2153 anjuta_util_get_user_cache_file (const gchar
* path
, ...)
2156 va_start (list
, path
);
2157 return anjuta_util_get_user_cache_filev (path
, list
);
2161 anjuta_util_get_user_config_filev (const gchar
* path
, va_list list
)
2163 gchar
*uri_str
, *base_path
, *dir
;
2165 const gchar anjuta_prefix
[] = "anjuta";
2166 base_path
= g_build_filename (g_get_user_config_dir(), anjuta_prefix
, path
, NULL
);
2168 uri_str
= anjuta_util_construct_pathv (base_path
, list
);
2171 uri
= g_file_new_for_path (uri_str
);
2172 dir
= g_path_get_dirname (uri_str
);
2174 if (!anjuta_util_create_dir (dir
)) return NULL
;
2180 anjuta_util_get_user_config_file (const gchar
* path
, ...)
2183 va_start (list
, path
);
2184 return anjuta_util_get_user_config_filev (path
, list
);
2188 anjuta_util_get_user_data_filev (const gchar
* path
, va_list list
)
2190 gchar
*uri_str
, *base_path
, *dir
;
2192 const gchar anjuta_prefix
[] = "anjuta";
2193 base_path
= g_build_filename (g_get_user_data_dir(), anjuta_prefix
, path
, NULL
);
2195 uri_str
= anjuta_util_construct_pathv (base_path
, list
);
2198 uri
= g_file_new_for_path (uri_str
);
2199 dir
= g_path_get_dirname (uri_str
);
2201 if (!anjuta_util_create_dir (dir
)) return NULL
;
2207 anjuta_util_get_user_data_file (const gchar
* path
, ...)
2210 va_start (list
, path
);
2211 return anjuta_util_get_user_data_filev (path
, list
);
2215 anjuta_util_get_user_cache_file_path (const gchar
* path
, ...)
2220 va_start (list
, path
);
2221 file
= anjuta_util_get_user_cache_filev (path
, list
);
2222 file_path
= g_file_get_path (file
);
2223 g_object_unref (file
);
2229 anjuta_util_get_user_config_file_path (const gchar
* path
, ...)
2234 va_start (list
, path
);
2235 file
= anjuta_util_get_user_config_filev (path
, list
);
2236 file_path
= g_file_get_path (file
);
2237 g_object_unref (file
);
2243 anjuta_util_get_user_data_file_path (const gchar
* path
, ...)
2248 va_start (list
, path
);
2249 file
= anjuta_util_get_user_data_filev (path
, list
);
2250 file_path
= g_file_get_path (file
);
2251 g_object_unref (file
);
2257 anjuta_util_convert_gfile_list_to_path_list (GList
*list
)
2260 GList
*current_file
;
2265 for (current_file
= list
; current_file
!= NULL
; current_file
= g_list_next (current_file
))
2267 path
= g_file_get_path (current_file
->data
);
2269 /* Ignore files with invalid paths */
2271 path_list
= g_list_append (path_list
, path
);
2278 anjuta_util_convert_gfile_list_to_relative_path_list (GList
*list
,
2279 const gchar
*parent
)
2283 GList
*current_file
;
2286 parent_file
= g_file_new_for_path (parent
);
2291 for (current_file
= list
; current_file
!= NULL
; current_file
= g_list_next (current_file
))
2293 path
= g_file_get_relative_path (parent_file
, current_file
->data
);
2295 /* Ignore files with invalid paths */
2297 path_list
= g_list_append (path_list
, path
);
2300 g_object_unref (parent_file
);
2308 * anjuta_util_builder_new:
2309 * @filename: Builder file name to open
2310 * @error: Optional error object, if NULL display a dialog if the file is missing
2312 * Create a new GtkBuilder object and load the file in it. Display an error
2313 * if the file is missing. Use a dialog if error is NULL, just a warning
2314 * if the error can be reported.
2316 * Returns: The new GtkBuilder object
2319 anjuta_util_builder_new (const gchar
*filename
, GError
**error
)
2321 GtkBuilder
*bxml
= gtk_builder_new ();
2324 /* Load glade file */
2325 if (!gtk_builder_add_from_file (bxml
, filename
, &err
))
2327 g_object_unref (bxml
);
2330 /* Display the error to the user if it cannot be reported to the caller */
2333 anjuta_util_dialog_error (NULL
, _("Unable to load user interface file: %s"), err
->message
);
2337 g_warning ("Couldn't load builder file: %s", err
->message
);
2339 g_propagate_error (error
, err
);
2342 /* Tag the builder object with the filename to allow better error message
2343 * with the following function */
2346 g_object_set_data_full (G_OBJECT (bxml
), "filename", g_strdup (filename
), g_free
);
2353 * anjuta_util_builder_get_objects:
2354 * @builder: Builder object
2355 * @first_widget: Name of first widget to get
2356 * ...: Address to store the first widget pointer, followed optionally by
2357 * more name/pointer pairs, followed by NULL
2359 * Create a new GtkBuilder object and load the file in it. Display an error
2360 * if the file is missing. Use a dialog if error is NULL, just a warning
2361 * if the error can be reported.
2363 * Returns: TRUE is everything works as expected.
2366 anjuta_util_builder_get_objects (GtkBuilder
*builder
, const gchar
*first_widget
,...)
2370 GObject
**object_ptr
;
2371 gboolean missing
= FALSE
;
2373 va_start (args
, first_widget
);
2375 for (name
= first_widget
; name
; name
= va_arg (args
, char *))
2377 object_ptr
= va_arg (args
, void *);
2378 *object_ptr
= gtk_builder_get_object (builder
, name
);
2380 /* Object not found, display a warning */
2383 const gchar
*filename
= (const gchar
*)g_object_get_data (G_OBJECT (builder
), "filename");
2386 g_warning ("Missing widget '%s' in file %s", name
, filename
);
2390 g_warning("Missing widget '%s'", name
);
2401 * anjuta_utils_drop_get_files:
2402 * @selection_data: the #GtkSelectionData from drag_data_received
2403 * @info: the info from drag_data_received
2405 * Create a list of valid uri's from a uri-list drop.
2407 * Return value: a list of GFiles
2410 anjuta_utils_drop_get_files (GtkSelectionData
*selection_data
)
2414 GSList
* files
= NULL
;
2416 uris
= g_uri_list_extract_uris ((gchar
*) gtk_selection_data_get_data (selection_data
));
2418 for (i
= 0; uris
[i
] != NULL
; i
++)
2420 GFile
* file
= g_file_new_for_uri (uris
[i
]);
2421 files
= g_slist_append(files
, file
);