Exemple #1
0
static void remove_items(gpointer data, guint action, GtkWidget *widget)
{
	IconClass	*iclass;

	if (menu_icon)
	{
		if (menu_icon->locked)
		{
			delayed_error(_("You must unlock '%s' before removing it"),
					menu_icon->item->leafname);
			return;
		}
		icon_set_selected(menu_icon, TRUE);
	}
	
	if (!icon_selection)
	{
		delayed_error(
			_("You must first select some items to remove"));
		return;
	}

	if (any_selected_item_is_locked())
	{
		delayed_error(_("An item must be unlocked before it can be removed."));
		return;
	}

	iclass = (IconClass *)
		  G_OBJECT_GET_CLASS(G_OBJECT(icon_selection->data));

	iclass->remove_items();
}
Exemple #2
0
/* Load a file, open a directory or run an application. Or, if 'edit' is set:
 * edit a file, open an application, follow a symlink or mount a device.
 *
 * filer_window is the window to use for displaying a directory.
 * NULL will always use a new directory when needed.
 * src_window is the window to copy options from, or NULL.
 *
 * Returns TRUE on success.
 */
gboolean run_diritem(const guchar *full_path,
		     DirItem *item,
		     FilerWindow *filer_window,
		     FilerWindow *src_window,
		     gboolean edit)
{
	if (item->flags & ITEM_FLAG_SYMLINK && edit)
		return follow_symlink(full_path, filer_window, src_window);

	switch (item->base_type)
	{
		case TYPE_DIRECTORY:
			if (item->flags & ITEM_FLAG_APPDIR && !edit)
			{
				run_app(full_path);
				return TRUE;
			}

			if (item->flags & ITEM_FLAG_MOUNT_POINT)
			{
				open_mountpoint(full_path, item,
						filer_window, src_window, edit);
			}
			else if (filer_window)
				filer_change_to(filer_window, full_path, NULL);
			else
				filer_opendir(full_path, src_window, NULL);
			return TRUE;
		case TYPE_FILE:
			if (EXECUTABLE_FILE(item) && !edit)
			{
				const char *argv[] = {NULL, NULL};
				guchar	*dir = filer_window
						? filer_window->sym_path
						: NULL;

				if (item->mime_type == application_x_desktop)
					return run_desktop(full_path,
							   NULL, dir);
				else
					argv[0] = full_path;

				return rox_spawn(dir, argv) != 0;
			}

			return open_file(full_path, edit ? text_plain
						  : item->mime_type);
		case TYPE_ERROR:
			delayed_error(_("File doesn't exist, or I can't "
					  "access it: %s"), full_path);
			return FALSE;
		default:
		        delayed_error(
				_("I don't know how to open '%s'"), full_path);
			return FALSE;
	}
}
Exemple #3
0
static void drop_box_drag_data_received(GtkWidget *drop_box,
			      GdkDragContext    *context,
			      gint              x,
			      gint              y,
			      GtkSelectionData  *selection_data,
			      guint             drag_info,
			      guint32           time)
{
	GList *uris = NULL;
	guchar *path = NULL;
	gboolean success = FALSE;

	if (!selection_data->data)
		goto err; 		/* Timeout? */

	uris = uri_list_to_glist(selection_data->data);

	if (g_list_length(uris) != 1)
	{
		delayed_error(_("Sorry, you need to drop exactly one file "
				"onto the drop area."));
		goto err;
	}
		
	path = get_local_path((EscapedPath *) uris->data);

	if (!path)
	{
		delayed_error(
			_("Sorry, I can't use '%s' because it's not a local "
			  "file."), (guchar *) uris->data);
		goto err;
	}

	if (!file_exists(path))
	{
		delayed_error(_("Can't access '%s':\n%s"), path,
				g_strerror(errno));
		goto err;
	}

	g_signal_emit_by_name(drop_box, "path_dropped", path);

	success = TRUE;
err:
	if (path)
		g_free(path);
	
	if (uris)
		g_list_free(uris);
	gtk_drag_finish(context, success, FALSE, time);	/* Failure */
}
Exemple #4
0
static void open_dir_clicked(GtkWidget *button, DropBox *drop_box)
{
	if (drop_box->path)
		open_to_show(drop_box->path);
	else
		delayed_error(_("I can't show you the currently set item, "
				"because nothing is currently set. Drag "
				"something onto me!"));
}
Exemple #5
0
/* Execute this program, passing all the URIs in the list as arguments.
 * URIs that are files on the local machine will be passed as simple
 * pathnames. The uri_list should be freed after this function returns.
 */
void run_with_files(const char *path, GList *uri_list)
{
	const char	**argv;
	int		argc = 0, i;
	struct stat 	info;
	MIME_type	*type;

	if (stat(path, &info))
	{
		delayed_error(_("Program %s not found - deleted?"), path);
		return;
	}

	argv = g_malloc(sizeof(char *) * (g_list_length(uri_list) + 2));

	if (S_ISDIR(info.st_mode))
		argv[argc++] = make_path(path, "AppRun");
	else
		argv[argc++] = path;
	
	while (uri_list)
	{
		const EscapedPath *uri = uri_list->data;
		char *local;

		local = get_local_path(uri);
		if (local) 
			argv[argc++] = local;
		else
			argv[argc++] = unescape_uri(uri);
		uri_list = uri_list->next;
	}
	
	argv[argc++] = NULL;

	type = type_from_path(argv[0]);
	if (type && type == application_x_desktop)
	{
		run_desktop(argv[0], argv + 1, home_dir);
	}
	else
	{
		rox_spawn(home_dir, argv);
	}

	for (i = 1; i < argc; i++)
		g_free((gchar *) argv[i]);
	g_free(argv);
}
Exemple #6
0
/* Splits args into an argument vector, and runs the program. Must be
 * executable.
 */
void run_with_args(const char *path, DirItem *item, const char *args)
{
	GError *error = NULL;
	gchar **argv = NULL;
	int n_args = 0;

	if (item->base_type != TYPE_DIRECTORY && item->base_type != TYPE_FILE)
	{
		delayed_error("Arguments (%s) given for non-executable item %s",
				args, path);
		return;
	}

	if (!g_shell_parse_argv(args, &n_args, &argv, &error))
	{
		delayed_error("Failed to parse argument string '%s':\n%s",
				args, error->message);
		g_error_free(error);
		return;
	}

	g_return_if_fail(argv != NULL);
	g_return_if_fail(error == NULL);

	argv = g_realloc(argv, (n_args + 2) * sizeof(gchar *));
	memmove(argv + 1, argv, (n_args + 1) * sizeof(gchar *));

	if (item->base_type == TYPE_DIRECTORY)
		argv[0] = g_strconcat(path, "/AppRun", NULL);
	else
		argv[0] = g_strdup(path);

	rox_spawn(home_dir, (const gchar **) argv);

	g_strfreev(argv);
}
Exemple #7
0
static void get_shortcut(GtkWidget *button, GtkWidget *label)
{
	GtkWidget *popup, *frame, *msg;
	Window    xid;
	Display	  *dpy = GDK_DISPLAY();

	popup = gtk_window_new(GTK_WINDOW_POPUP);

	gtk_window_set_position(GTK_WINDOW(popup), GTK_WIN_POS_CENTER);

	frame = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
	gtk_container_add(GTK_CONTAINER(popup), frame);

	msg = gtk_label_new(_("Press the desired shortcut (eg, Control+F1)"));

	gtk_misc_set_padding(GTK_MISC(msg), 20, 20);
	gtk_container_add(GTK_CONTAINER(frame), msg);

	gtk_window_set_modal(GTK_WINDOW(popup), TRUE);

	gtk_widget_add_events(popup,
			GDK_KEY_RELEASE_MASK | GDK_BUTTON_PRESS_MASK);

	g_signal_connect(popup, "destroy",
			G_CALLBACK(may_set_shortcut), label);

	gtk_widget_show_all(popup);

	gdk_window_add_filter(popup->window, filter_get_key, popup);

	xid = gdk_x11_drawable_get_xid(popup->window);

	if (XGrabKeyboard(dpy, xid, False, GrabModeAsync, GrabModeAsync,
			gtk_get_current_event_time()) != Success)
	{
		delayed_error(_("Failed to get keyboard grab!"));
		gtk_widget_destroy(popup);
	}

	if (XGrabPointer(dpy, xid, False, ButtonPressMask, GrabModeAsync,
				GrabModeAsync, xid, None,
				gtk_get_current_event_time()) != Success)
	{
		g_warning("Failed to get mouse grab");
	}
}
Exemple #8
0
static void file_op(gpointer data, guint action, GtkWidget *widget)
{
	if (!menu_icon)
	{
		delayed_error(_("You must open the menu over an item"));
		return;
	}

	switch (action)
	{
		case ACTION_SHIFT:
			run_diritem(menu_icon->path, menu_icon->item,
					NULL, NULL, TRUE);
			break;
		case ACTION_EDIT:
			show_rename_box(menu_icon);
			break;
		case ACTION_LOCATION:
			open_to_show(menu_icon->path);
			break;
		case ACTION_PROPERTIES:
			infobox_new(menu_icon->path);
			break;
		case ACTION_RUN_ACTION:
			if (can_set_run_action(menu_icon->item))
				type_set_handler_dialog(
						menu_icon->item->mime_type);
			else
				report_error(
				_("You can only set the run action for a "
				"regular file"));
			break;
		case ACTION_SET_ICON:
			icon_set_handler_dialog(menu_icon->item,
						menu_icon->path);
			break;
	}
}
Exemple #9
0
/* Read in this .gmo format file; all translations found override
 * any existing translations for future calls to rox_gettext().
 */
void rox_add_translations(char *path)
{
	guint32		magic;
	char		*data, *from_base, *to_base;
	long		size;
	gboolean	swap;		/* TRUE => reverse byte-order of ints */
	int		n, n_total;
#ifdef GTK2
	char		*charset = NULL;
#endif

	if (load_file(path, &data, &size) == FALSE)
		goto out;

	if (size < 20)
	{
		delayed_error(_("Invalid .gmo translation file "
					"(too short): %s"), path);
		goto out;
	}

	magic = *((guint *) data);

	if (magic == 0x950412de)
		swap = FALSE;
	else if (magic == 0xde120495)
		swap = TRUE;
	else
	{
		delayed_error(_("Invalid .gmo translation file "
					"(GNU magic number not found): %s"),
				  path);
		goto out;
	}

	if (WORD(data + 4) != 0)
		g_warning("rox_add_translations: expected format revision 0");

	if (!translate)
	{
#ifdef GTK2
		translate = g_hash_table_new_full(g_str_hash, g_str_equal,
						  g_free, g_free);
#else
		translate = g_hash_table_new(g_str_hash, g_str_equal);
#endif
	}

	n_total = WORD(data + 8);
	from_base = data + WORD(data + 12);
	to_base = data + WORD(data + 16);

#ifdef GTK2
	/* Find the charset used, so we can convert to UTF-8 */
	for (n = 0; n < n_total; n++)
	{
		char	*from = data + WORD(from_base + (n << 3) + 4);
		char	*to_raw   = data + WORD(to_base + (n << 3) + 4);

		if (*from)
			continue;

		charset = strstr(to_raw, "charset=");
		if (charset)
		{
			char *tmp;

			charset += 8;
			tmp = strchr(charset, '\n');
			if (tmp)
				charset = g_strndup(charset, tmp - charset);
			else
				charset = g_strdup(charset);
		}
		break;
	}
	if (!charset)
	{
		g_warning("Missing charset=... in translation!");
		charset = g_strdup("ISO8859-1");
	}
#endif
	
	for (n = 0; n < n_total; n++)
	{
		char	*from = data + WORD(from_base + (n << 3) + 4);
		char	*to_raw   = data + WORD(to_base + (n << 3) + 4);
#ifdef GTK2
		char	*to;

		to = g_convert_with_fallback(to_raw, -1,
					"UTF-8",
					charset,
					"#",
					NULL, NULL, NULL);
		if (!to)
			to = g_strdup(to_raw);

		g_hash_table_insert(translate, g_strdup(from), to);
#else
		g_hash_table_insert(translate, from, to_raw);
#endif
	}

out: ;			/* (some compilers complain otherwise) */
#ifdef GTK2
	g_free(data);
	g_free(charset);
#endif
}
Exemple #10
0
/* Run the program as '<path> -', piping the data to it via stdin.
 * You can g_free() the data as soon as this returns.
 */
void run_with_data(const char *path, gpointer data, gulong length)
{
	const char	*argv[] = {NULL, "-", NULL};
	struct stat 	info;
	int		fds[2];
	PipedData	*pd;

	if (stat(path, &info))
	{
		delayed_error(_("Program %s not found - deleted?"), path);
		return;
	}

	if (S_ISDIR(info.st_mode))
		argv[0] = make_path(path, "AppRun");
	else
		argv[0] = path;
	
	if (pipe(fds))
	{
		delayed_error("pipe: %s", g_strerror(errno));
		return;
	}
	close_on_exec(fds[1], TRUE);
	close_on_exec(fds[0], TRUE);

	switch (fork())
	{
		case -1:
			delayed_error("fork: %s", g_strerror(errno));
			close(fds[1]);
			break;
		case 0:
			/* We are the child */
			chdir(home_dir);
			if (dup2(fds[0], 0) == -1)
				g_warning("dup2() failed: %s\n",
						g_strerror(errno));
			else
			{
				close_on_exec(0, FALSE);
				if (execv(argv[0], (char **) argv))
					g_warning("execv(%s) failed: %s\n",
						argv[0], g_strerror(errno));
			}
			_exit(1);
		default:
			/* We are the parent */
			set_blocking(fds[1], FALSE);
			pd = g_new(PipedData, 1);
			pd->data = g_malloc(length);
			memcpy(pd->data, data, length);
			pd->length = length;
			pd->sent = 0;
			pd->tag = gdk_input_add_full(fds[1], GDK_INPUT_WRITE,
						write_data, pd, NULL);
			break;
	}

	close(fds[0]);
}
Exemple #11
0
/* Load image 'path' in the background and insert into pixmap_cache.
 * Call callback(data, path) when done (path is NULL => error).
 * If the image is already uptodate, or being created already, calls the
 * callback right away.
 */
void
pixmap_background_thumb(const gchar *path, GFunc callback, gpointer data)
{
	gboolean	found = FALSE;

	MaskedPixmap* image = g_fscache_lookup_full(pixmap_cache, path, FSCACHE_LOOKUP_ONLY_NEW, &found);

	if (found)
	{
		dbg(0, "found");
		// Thumbnail is known, or being created
		if (image) g_object_unref(image);
		callback(data, NULL);
		return;
	}

	dbg(0, "FIXME not found");
#if 0
	pid_t		child;
	ChildThumbnail	*info;
	g_return_if_fail(image == NULL);

	GdkPixbuf* pixbuf = get_thumbnail_for(path);
	
	if (!pixbuf)
	{
		struct stat info1, info2;
		char *dir;

		dir = g_path_get_dirname(path);

		// If the image itself is in ~/.thumbnails, load it now (ie, don't create thumbnails for thumbnails!).
		if (stat(dir, &info1) != 0)
		{
			callback(data, NULL);
			g_free(dir);
			return;
		}
		g_free(dir);

		if (stat(make_path(home_dir, ".thumbnails/normal"),
			    &info2) == 0 &&
			    info1.st_dev == info2.st_dev &&
			    info1.st_ino == info2.st_ino)
		{
			pixbuf = rox_pixbuf_new_from_file_at_scale(path, PIXMAP_THUMB_SIZE, PIXMAP_THUMB_SIZE, TRUE, NULL);
			if (!pixbuf)
			{
				g_fscache_insert(pixmap_cache, path, NULL, TRUE);
				callback(data, NULL);
				return;
			}
		}
	}
		
	if (pixbuf)
	{
		MaskedPixmap *image;

		image = masked_pixmap_new(pixbuf);
		gdk_pixbuf_unref(pixbuf);
		g_fscache_insert(pixmap_cache, path, image, TRUE);
		callback(data, (gchar *) path);
		g_object_unref(G_OBJECT(image));
		return;
	}

	MIME_type* type = type_from_path(path);
	if (!type) type = text_plain;

	// Add an entry, set to NULL, so no-one else tries to load this image.
	g_fscache_insert(pixmap_cache, path, NULL, TRUE);

	gchar* thumb_prog = thumbnail_program(type);

	// Only attempt to load 'images' types ourselves
	if (thumb_prog == NULL && strcmp(type->media_type, "image") != 0)
	{
		callback(data, NULL);
		return;		// Don't know how to handle this type
	}

	child = fork();

	if (child == -1)
	{
		g_free(thumb_prog);
		delayed_error("fork(): %s", g_strerror(errno));
		callback(data, NULL);
		return;
	}

	if (child == 0)
	{
		// We are the child process.  (We are sloppy with freeing memory, but since we go away very quickly, that's ok.)
		if (thumb_prog)
		{
			DirItem *item;
			
			item = diritem_new(g_basename(thumb_prog));

			diritem_restat(thumb_prog, item, NULL);
			if (item->flags & ITEM_FLAG_APPDIR)
				thumb_prog = g_strconcat(thumb_prog, "/AppRun",
						       NULL);

			execl(thumb_prog, thumb_prog, path,
			      thumbnail_path(path),
			      g_strdup_printf("%d", PIXMAP_THUMB_SIZE),
			      NULL);
			_exit(1);
		}

		child_create_thumbnail(path);
		_exit(0);
	}

	g_free(thumb_prog);

	info = g_new(ChildThumbnail, 1);
	info->path = g_strdup(path);
	info->callback = callback;
	info->data = data;
	on_child_death(child, (CallbackFn) thumbnail_child_done, info);
#endif
}